From 00b3879f67fd0dd4aa44f37c2effdaf3769cd20f Mon Sep 17 00:00:00 2001 From: flub Date: Fri, 27 Mar 2026 11:11:26 +0000 Subject: [PATCH] deploy: d5999687065a825b79aaacebfa39c9c8046d301a --- pr/545/docs/noq/all.html | 2 +- pr/545/docs/noq/enum.ConnectionError.html | 6 +- pr/545/docs/noq/enum.SendDatagramError.html | 6 +- pr/545/docs/noq/enum.StoppedError.html | 6 +- pr/545/docs/noq/enum.WriteError.html | 6 +- .../docs/noq/event_stream/struct.Lagged.html | 11 + .../struct.NatTraversalUpdates.html | 11 + .../struct.ObservedExternalAddr.html | 11 + .../noq/event_stream/struct.PathEvents.html | 11 + pr/545/docs/noq/index.html | 4 +- pr/545/docs/noq/sidebar-items.js | 2 +- pr/545/docs/noq/struct.AcceptBi.html | 6 +- pr/545/docs/noq/struct.AcceptUni.html | 6 +- pr/545/docs/noq/struct.AddressDiscovery.html | 4 +- pr/545/docs/noq/struct.ClosedStream.html | 2 +- pr/545/docs/noq/struct.Connecting.html | 6 +- pr/545/docs/noq/struct.Connection.html | 95 +- pr/545/docs/noq/struct.Lagged.html | 34 + .../docs/noq/struct.NatTraversalUpdates.html | 174 + .../docs/noq/struct.ObservedExternalAddr.html | 175 + pr/545/docs/noq/struct.OnClosed.html | 4 +- pr/545/docs/noq/struct.OpenBi.html | 6 +- pr/545/docs/noq/struct.OpenUni.html | 6 +- pr/545/docs/noq/struct.Path.html | 24 +- pr/545/docs/noq/struct.PathEvents.html | 174 + pr/545/docs/noq/struct.ReadDatagram.html | 6 +- pr/545/docs/noq/struct.SendDatagram.html | 6 +- pr/545/docs/noq/struct.SendStream.html | 30 +- pr/545/docs/noq/struct.Stopped.html | 6 +- .../docs/noq/struct.WeakConnectionHandle.html | 10 +- pr/545/docs/noq/struct.WeakPathHandle.html | 10 +- pr/545/docs/noq/struct.ZeroRttAccepted.html | 4 +- pr/545/docs/noq/trait.NetworkChangeHint.html | 4 +- .../docs/noq_proto/enum.ClosePathError.html | 6 +- .../docs/noq_proto/enum.ConnectionError.html | 6 +- pr/545/docs/noq_proto/enum.Event.html | 4 +- pr/545/docs/noq_proto/enum.PathError.html | 6 +- pr/545/docs/noq_proto/enum.PathEvent.html | 2 +- pr/545/docs/noq_proto/struct.Connection.html | 81 +- .../struct.MultipathNotNegotiated.html | 4 +- .../docs/noq_proto/struct.TransportError.html | 2 +- .../noq_proto/trait.NetworkChangeHint.html | 4 +- pr/545/docs/search.index/0033f3568d59.js | 1 + pr/545/docs/search.index/0106b6a79629.js | 1 - pr/545/docs/search.index/0110ee2caa9d.js | 1 - pr/545/docs/search.index/016287c739af.js | 1 + pr/545/docs/search.index/01818b9a5dfd.js | 1 + pr/545/docs/search.index/01b2e5b81d3a.js | 1 - pr/545/docs/search.index/01dabba3dd0f.js | 1 + pr/545/docs/search.index/01f066683f43.js | 1 - pr/545/docs/search.index/0258058d4a15.js | 1 + pr/545/docs/search.index/03099968b016.js | 1 + pr/545/docs/search.index/036264e2cafd.js | 1 - pr/545/docs/search.index/03d8571d8861.js | 1 + pr/545/docs/search.index/04067d1944a2.js | 1 + pr/545/docs/search.index/0435c5f11e89.js | 1 + pr/545/docs/search.index/044ee5e7fc14.js | 1 - pr/545/docs/search.index/04cd208f0148.js | 1 + pr/545/docs/search.index/0530b4c13347.js | 1 + pr/545/docs/search.index/058523a6e4f8.js | 1 + pr/545/docs/search.index/05ca02aa6fd9.js | 1 - pr/545/docs/search.index/06715c7452c2.js | 1 - pr/545/docs/search.index/0697183800b7.js | 1 + pr/545/docs/search.index/06c25d8359bd.js | 1 + pr/545/docs/search.index/06c6b77500fe.js | 1 + pr/545/docs/search.index/0717d66ebc8c.js | 1 + pr/545/docs/search.index/0740e388ca16.js | 1 + pr/545/docs/search.index/0773f56876ef.js | 1 - pr/545/docs/search.index/07beea41a07f.js | 1 - pr/545/docs/search.index/080595ed9c0d.js | 1 + pr/545/docs/search.index/08c46987941a.js | 1 - pr/545/docs/search.index/08d9a5c3e851.js | 1 + pr/545/docs/search.index/09031ecd90af.js | 1 + pr/545/docs/search.index/0a28cb65ff98.js | 1 - pr/545/docs/search.index/0a8ad4b154a4.js | 1 + pr/545/docs/search.index/0bac143bcb50.js | 1 + pr/545/docs/search.index/0bca21001963.js | 1 + pr/545/docs/search.index/0bd2d0b4cbf3.js | 1 - pr/545/docs/search.index/0bd42362d0ac.js | 1 + pr/545/docs/search.index/0beec91fb1e5.js | 1 - pr/545/docs/search.index/0c5310d088a1.js | 1 - pr/545/docs/search.index/0ca93a7be19c.js | 1 + pr/545/docs/search.index/0d117775bd82.js | 1 - pr/545/docs/search.index/0d555db5d7c8.js | 1 - pr/545/docs/search.index/0d6bfa8c2af1.js | 1 + pr/545/docs/search.index/0e2aac44d870.js | 1 + pr/545/docs/search.index/0e4d0f710b2b.js | 1 + pr/545/docs/search.index/0f30d894e39f.js | 1 + pr/545/docs/search.index/0f46828f0101.js | 1 - pr/545/docs/search.index/0fa5fc027b08.js | 1 - pr/545/docs/search.index/100cd8e013cf.js | 1 + pr/545/docs/search.index/104ed5107cd6.js | 1 - pr/545/docs/search.index/1074492a6ce1.js | 1 + pr/545/docs/search.index/10e01c839a63.js | 1 - pr/545/docs/search.index/117405adffd2.js | 1 + pr/545/docs/search.index/1175a8ba9773.js | 1 - pr/545/docs/search.index/120419dec60e.js | 1 + pr/545/docs/search.index/127db5988b1f.js | 1 - pr/545/docs/search.index/12adc117b701.js | 1 - pr/545/docs/search.index/133a2aaf2619.js | 1 + pr/545/docs/search.index/13baa5793c64.js | 1 + pr/545/docs/search.index/13f6fe7b94ed.js | 1 - pr/545/docs/search.index/14272828ba1d.js | 1 - pr/545/docs/search.index/1463797a33c0.js | 1 - pr/545/docs/search.index/1507fd45a0d0.js | 1 + pr/545/docs/search.index/1540dff09ce4.js | 1 - pr/545/docs/search.index/1545022d8f5e.js | 1 - pr/545/docs/search.index/157deb90a29d.js | 1 - pr/545/docs/search.index/15883d436710.js | 1 + pr/545/docs/search.index/1593ad1b0859.js | 1 + pr/545/docs/search.index/15d820844df2.js | 1 + pr/545/docs/search.index/167471e48607.js | 1 - pr/545/docs/search.index/169d5b098f4e.js | 1 - pr/545/docs/search.index/16ea9b1933a4.js | 1 + pr/545/docs/search.index/1707a9d5b2af.js | 1 - pr/545/docs/search.index/171a39168019.js | 1 - pr/545/docs/search.index/178adcc5c30e.js | 1 - pr/545/docs/search.index/17a463b91cd9.js | 1 + pr/545/docs/search.index/17fbc7f79103.js | 1 - pr/545/docs/search.index/1854d56f88c5.js | 1 - pr/545/docs/search.index/18eec5319d0e.js | 1 + pr/545/docs/search.index/1915837c9928.js | 1 - pr/545/docs/search.index/1928b541c754.js | 1 - pr/545/docs/search.index/19baf510d15e.js | 1 + pr/545/docs/search.index/19beb5bb0c16.js | 1 - pr/545/docs/search.index/19c5f33045ce.js | 1 - pr/545/docs/search.index/19d0359d569b.js | 1 + pr/545/docs/search.index/19d4d15f26c3.js | 1 - pr/545/docs/search.index/19da7e04c741.js | 1 - pr/545/docs/search.index/1a66cd07757a.js | 1 + pr/545/docs/search.index/1b2b113ba497.js | 1 + pr/545/docs/search.index/1b7cc07f1f34.js | 1 + pr/545/docs/search.index/1bd9e21009c9.js | 1 - pr/545/docs/search.index/1bf00b4f0c44.js | 1 + pr/545/docs/search.index/1c14aa28ba9e.js | 1 - pr/545/docs/search.index/1c262f510d82.js | 1 + pr/545/docs/search.index/1d17a7bb5df0.js | 1 - pr/545/docs/search.index/1d3f2d3bd8f6.js | 1 + pr/545/docs/search.index/1d7fbea1f446.js | 1 - pr/545/docs/search.index/1d8c8f6f3340.js | 1 + pr/545/docs/search.index/1dbcf54491ae.js | 1 + pr/545/docs/search.index/1de07b6bd5ed.js | 1 + pr/545/docs/search.index/1dff5e6ecf7f.js | 1 + pr/545/docs/search.index/1e93e59e94d9.js | 1 + pr/545/docs/search.index/1ebad890e62e.js | 1 + pr/545/docs/search.index/1ee39b692949.js | 1 + pr/545/docs/search.index/1f4450a92511.js | 1 + pr/545/docs/search.index/1f8374f280ae.js | 1 + pr/545/docs/search.index/1fac5249737c.js | 1 + pr/545/docs/search.index/201011f148a9.js | 1 + pr/545/docs/search.index/2063bc13c29e.js | 1 - pr/545/docs/search.index/20a41ecff08f.js | 1 + pr/545/docs/search.index/20a57735c5a6.js | 1 - pr/545/docs/search.index/20ac1af4f5cb.js | 1 - pr/545/docs/search.index/20afefeb7ec4.js | 1 + pr/545/docs/search.index/20da1b8e8e24.js | 1 + pr/545/docs/search.index/20fbab33fc2f.js | 1 + pr/545/docs/search.index/215b5a83d39e.js | 1 - pr/545/docs/search.index/2232ff223063.js | 1 - pr/545/docs/search.index/224409c019b5.js | 1 - pr/545/docs/search.index/227000c17c1b.js | 1 + pr/545/docs/search.index/22f66fe81db4.js | 1 + pr/545/docs/search.index/230d9ae0255e.js | 1 + pr/545/docs/search.index/23daddc85a2a.js | 1 + pr/545/docs/search.index/240436689105.js | 1 + pr/545/docs/search.index/246c639fd848.js | 1 - pr/545/docs/search.index/25143dd2528f.js | 1 + pr/545/docs/search.index/25a2359dd30d.js | 1 + pr/545/docs/search.index/25a5775ae582.js | 1 - pr/545/docs/search.index/2657ace38ed9.js | 1 + pr/545/docs/search.index/26625634ad63.js | 1 + pr/545/docs/search.index/267566229927.js | 1 - pr/545/docs/search.index/26d748f5add8.js | 1 - pr/545/docs/search.index/26eaff1ecc2b.js | 1 + pr/545/docs/search.index/27b689c7cdce.js | 1 - pr/545/docs/search.index/280b57a12fe8.js | 1 + pr/545/docs/search.index/2892218972b3.js | 1 + pr/545/docs/search.index/289cef522e65.js | 1 - pr/545/docs/search.index/294c65cabea3.js | 1 - pr/545/docs/search.index/29a9ad420aea.js | 1 - pr/545/docs/search.index/2a157ff40a7a.js | 1 - pr/545/docs/search.index/2a552ae8044e.js | 1 + pr/545/docs/search.index/2a67720851d1.js | 1 + pr/545/docs/search.index/2a8e4b0e890f.js | 1 + pr/545/docs/search.index/2b4d7f4d8d3a.js | 1 - pr/545/docs/search.index/2b89b2e478bd.js | 1 - pr/545/docs/search.index/2bbd4ed026d7.js | 1 - pr/545/docs/search.index/2bbea166f1f8.js | 1 + pr/545/docs/search.index/2d92cd1657e9.js | 1 + pr/545/docs/search.index/2e2486520353.js | 1 - pr/545/docs/search.index/2e4409258cfe.js | 1 - pr/545/docs/search.index/2eaf4ab981c3.js | 1 + pr/545/docs/search.index/2eeacf2c8ee0.js | 1 + pr/545/docs/search.index/2f792e01bbed.js | 1 - pr/545/docs/search.index/2f7ecc5dbb1a.js | 1 + pr/545/docs/search.index/2ffc6423036c.js | 1 - pr/545/docs/search.index/3036a9249b54.js | 1 + pr/545/docs/search.index/31b45cf6ecff.js | 1 + pr/545/docs/search.index/320b0f4af278.js | 1 + pr/545/docs/search.index/321190b83abb.js | 1 + pr/545/docs/search.index/323be9ee8c7b.js | 1 - pr/545/docs/search.index/3289f09b047b.js | 1 + pr/545/docs/search.index/32c74d9cf3af.js | 1 - pr/545/docs/search.index/32d7ceba568b.js | 1 - pr/545/docs/search.index/3381b6452880.js | 1 + pr/545/docs/search.index/339b70d50fee.js | 1 - pr/545/docs/search.index/342a647c77a6.js | 1 + pr/545/docs/search.index/3491b6741081.js | 1 - pr/545/docs/search.index/34fdabda10df.js | 1 - pr/545/docs/search.index/351cf7b3eacb.js | 1 - pr/545/docs/search.index/355e9ccc3e7d.js | 1 + pr/545/docs/search.index/3580644ae6d8.js | 1 + pr/545/docs/search.index/3587167fe015.js | 1 - pr/545/docs/search.index/35c861889432.js | 1 - pr/545/docs/search.index/3650ebdc9bae.js | 1 + pr/545/docs/search.index/36590b411474.js | 1 + pr/545/docs/search.index/368640dd3a84.js | 1 + pr/545/docs/search.index/37122b199c40.js | 1 - pr/545/docs/search.index/3792ea5bd86e.js | 1 - pr/545/docs/search.index/37ae2f2cc265.js | 1 + pr/545/docs/search.index/37ae4ca5ac42.js | 1 - pr/545/docs/search.index/3810d433a829.js | 1 - pr/545/docs/search.index/3874f15e7771.js | 1 + pr/545/docs/search.index/38b236771a65.js | 1 + pr/545/docs/search.index/38be63c8f52d.js | 1 - pr/545/docs/search.index/38e853561a8a.js | 1 + pr/545/docs/search.index/39a52dda198c.js | 1 + pr/545/docs/search.index/3a0723146c92.js | 1 + pr/545/docs/search.index/3a65c80ab51b.js | 1 - pr/545/docs/search.index/3a7213b0a18a.js | 1 - pr/545/docs/search.index/3a93f64bc2c4.js | 1 - pr/545/docs/search.index/3ac7cfd35a72.js | 1 - pr/545/docs/search.index/3b114748649d.js | 1 + pr/545/docs/search.index/3b4e28ed9312.js | 1 + pr/545/docs/search.index/3bc3c52a55c9.js | 1 - pr/545/docs/search.index/3bf70d50c752.js | 1 - pr/545/docs/search.index/3c0f5abd09f3.js | 1 + pr/545/docs/search.index/3c17bff3a5ab.js | 1 - pr/545/docs/search.index/3c89aeb97d29.js | 1 - pr/545/docs/search.index/3c8f419d6519.js | 1 + pr/545/docs/search.index/3ccd0c7a2788.js | 1 + pr/545/docs/search.index/3d2200f2a97e.js | 1 - pr/545/docs/search.index/3d5f153390be.js | 1 + pr/545/docs/search.index/3db3d3836bf3.js | 1 - pr/545/docs/search.index/3e10313c5965.js | 1 + pr/545/docs/search.index/3e3cbb04f471.js | 1 + pr/545/docs/search.index/3e98557ba4a3.js | 1 + pr/545/docs/search.index/3f00814740bc.js | 1 - pr/545/docs/search.index/3f0b4ad53d12.js | 1 - pr/545/docs/search.index/3f1a6e1729e4.js | 1 - pr/545/docs/search.index/3f243484e57a.js | 1 + pr/545/docs/search.index/3f24cd5aa4fa.js | 1 + pr/545/docs/search.index/3f8645c00d7c.js | 1 + pr/545/docs/search.index/4031cc647b10.js | 1 + pr/545/docs/search.index/404afcce0ada.js | 1 + pr/545/docs/search.index/40b99a9f0103.js | 1 - pr/545/docs/search.index/40feefc69675.js | 1 - pr/545/docs/search.index/4100782a5d31.js | 1 + pr/545/docs/search.index/410d825e5fa8.js | 1 - pr/545/docs/search.index/4155c1291357.js | 1 - pr/545/docs/search.index/4159f6c35981.js | 1 + pr/545/docs/search.index/41a1fd12d13b.js | 1 - pr/545/docs/search.index/42be563f7543.js | 1 - pr/545/docs/search.index/42e25feb3567.js | 1 - pr/545/docs/search.index/4341bc8e4878.js | 1 - pr/545/docs/search.index/434a43cc0e07.js | 1 - pr/545/docs/search.index/4351feb790fe.js | 1 + pr/545/docs/search.index/436e158b126a.js | 1 + pr/545/docs/search.index/43ac7a9781b4.js | 1 - pr/545/docs/search.index/441e425635ce.js | 1 + pr/545/docs/search.index/446e084c83a8.js | 1 - pr/545/docs/search.index/4471155ecc0f.js | 1 - pr/545/docs/search.index/44bd10e48043.js | 1 - pr/545/docs/search.index/44d27e55c058.js | 1 - pr/545/docs/search.index/450719784301.js | 1 + pr/545/docs/search.index/45c7f13213d0.js | 1 + pr/545/docs/search.index/45cefb4b1fe7.js | 1 + pr/545/docs/search.index/460ae98fed07.js | 1 - pr/545/docs/search.index/46615455c43f.js | 1 + pr/545/docs/search.index/4663a4e119e7.js | 1 + pr/545/docs/search.index/46d02c2cf6f3.js | 1 + pr/545/docs/search.index/470732838eeb.js | 1 + pr/545/docs/search.index/474b31e6c524.js | 1 + pr/545/docs/search.index/47aa62fcbff4.js | 1 - pr/545/docs/search.index/47b9d9b13323.js | 1 - pr/545/docs/search.index/4805b324248d.js | 1 + pr/545/docs/search.index/480a31b05a4c.js | 1 - pr/545/docs/search.index/483ec6c64d5e.js | 1 - pr/545/docs/search.index/4a9458af2428.js | 1 - pr/545/docs/search.index/4aa7b4743afe.js | 1 + pr/545/docs/search.index/4c05ce7be64f.js | 1 + pr/545/docs/search.index/4c05e858ff5d.js | 1 - pr/545/docs/search.index/4c2110675ed8.js | 1 - pr/545/docs/search.index/4c8621a28a73.js | 1 - pr/545/docs/search.index/4c89ae5762cb.js | 1 + pr/545/docs/search.index/4cd916711a76.js | 1 - pr/545/docs/search.index/4cdc76f01005.js | 1 - pr/545/docs/search.index/4d88a08a2ae4.js | 1 + pr/545/docs/search.index/4dd85b55e38e.js | 1 - pr/545/docs/search.index/4e07dd0ff701.js | 1 - pr/545/docs/search.index/4e0fe03427ba.js | 1 + pr/545/docs/search.index/4e6750278d1b.js | 1 - pr/545/docs/search.index/4eac59928f18.js | 1 + pr/545/docs/search.index/4eed4a0cfe1e.js | 1 + pr/545/docs/search.index/4fae9a79a161.js | 1 + pr/545/docs/search.index/505a1a911bef.js | 1 - pr/545/docs/search.index/50abe47e037f.js | 1 + pr/545/docs/search.index/517322c0ea00.js | 1 - pr/545/docs/search.index/521c1cdfffb6.js | 1 + pr/545/docs/search.index/52548d68890f.js | 1 - pr/545/docs/search.index/52b7dbce0a40.js | 1 + pr/545/docs/search.index/536f57712388.js | 1 + pr/545/docs/search.index/538b5fc4e1ed.js | 1 + pr/545/docs/search.index/5392889fe77e.js | 1 + pr/545/docs/search.index/53fb9a760872.js | 1 - pr/545/docs/search.index/53ffa8e8252a.js | 1 + pr/545/docs/search.index/5478b18519c4.js | 1 + pr/545/docs/search.index/548eac6e4034.js | 1 + pr/545/docs/search.index/549a18f8219c.js | 1 + pr/545/docs/search.index/5535b627edd5.js | 1 + pr/545/docs/search.index/55c5b7004628.js | 1 - pr/545/docs/search.index/560e166f7c46.js | 1 - pr/545/docs/search.index/5710b3f34500.js | 1 - pr/545/docs/search.index/571482a0f60a.js | 1 + pr/545/docs/search.index/5717d266c26b.js | 1 - pr/545/docs/search.index/5724a5cd21a6.js | 1 - pr/545/docs/search.index/579677a41519.js | 1 + pr/545/docs/search.index/5802da10e9df.js | 1 + pr/545/docs/search.index/58045aae0759.js | 1 + pr/545/docs/search.index/58acc8d198d4.js | 1 - pr/545/docs/search.index/59be03fa81eb.js | 1 + pr/545/docs/search.index/59c5b0e1f8ad.js | 1 + pr/545/docs/search.index/59f79b94bb60.js | 1 - pr/545/docs/search.index/59fb890d29b8.js | 1 + pr/545/docs/search.index/5a22fd2fcd2b.js | 1 + pr/545/docs/search.index/5b27537522a3.js | 1 - pr/545/docs/search.index/5b319b8ab819.js | 1 - pr/545/docs/search.index/5b62c7da471c.js | 1 + pr/545/docs/search.index/5b6e7c005ae8.js | 1 - pr/545/docs/search.index/5bd4900427a6.js | 1 + pr/545/docs/search.index/5bf126ddcd97.js | 1 + pr/545/docs/search.index/5c0a1d01fe52.js | 1 - pr/545/docs/search.index/5ccc63e2df25.js | 1 + pr/545/docs/search.index/5d45dfdef8cc.js | 1 + pr/545/docs/search.index/5d5835d05dfa.js | 1 - pr/545/docs/search.index/5d5b1b8d153b.js | 1 + pr/545/docs/search.index/5d9c4f60b3ee.js | 1 - pr/545/docs/search.index/5dbdf61761a4.js | 1 + pr/545/docs/search.index/5e0965d74272.js | 1 - pr/545/docs/search.index/5ed9ecced0b1.js | 1 + pr/545/docs/search.index/5f0e00c10ee4.js | 1 - pr/545/docs/search.index/5f4c630285ac.js | 1 - pr/545/docs/search.index/5f940ff8b47f.js | 1 + pr/545/docs/search.index/604d10667a5a.js | 1 - pr/545/docs/search.index/6061769b899d.js | 1 - pr/545/docs/search.index/6084ac5d766b.js | 1 - pr/545/docs/search.index/616f5750f133.js | 1 - pr/545/docs/search.index/61ad89c61241.js | 1 - pr/545/docs/search.index/61fb1929c127.js | 1 - pr/545/docs/search.index/62058f24fb16.js | 1 - pr/545/docs/search.index/624a2471dcc3.js | 1 + pr/545/docs/search.index/62bb0fe614ca.js | 1 + pr/545/docs/search.index/62bd0277a025.js | 1 - pr/545/docs/search.index/62ce08268925.js | 1 + pr/545/docs/search.index/635558f41241.js | 1 + pr/545/docs/search.index/63d5d6c31ff0.js | 1 + pr/545/docs/search.index/63dfc59f4dc3.js | 1 - pr/545/docs/search.index/643d3b14fc3a.js | 1 - pr/545/docs/search.index/64f401d0105c.js | 1 + pr/545/docs/search.index/653d5783dc15.js | 1 - pr/545/docs/search.index/655cb440fbba.js | 1 + pr/545/docs/search.index/656b47c2fced.js | 1 - pr/545/docs/search.index/657959d9dfd0.js | 1 + pr/545/docs/search.index/662c4a4e5d9e.js | 1 - pr/545/docs/search.index/667f942da920.js | 1 + pr/545/docs/search.index/671a68018a40.js | 1 - pr/545/docs/search.index/671d46d3c768.js | 1 - pr/545/docs/search.index/67319b6740f3.js | 1 - pr/545/docs/search.index/6749f8fc3137.js | 1 - pr/545/docs/search.index/674eafdf622c.js | 1 - pr/545/docs/search.index/67b74bab08a8.js | 1 - pr/545/docs/search.index/680921c7e0dc.js | 1 + pr/545/docs/search.index/68704ffa368a.js | 1 - pr/545/docs/search.index/68807ca8d915.js | 1 - pr/545/docs/search.index/690e03933450.js | 1 + pr/545/docs/search.index/692a422fa077.js | 1 - pr/545/docs/search.index/693f7e452732.js | 1 - pr/545/docs/search.index/694efa293f2d.js | 1 + pr/545/docs/search.index/699c12ddce85.js | 1 - pr/545/docs/search.index/69eda39d9ee0.js | 1 - pr/545/docs/search.index/6a152aadbb4b.js | 1 + pr/545/docs/search.index/6a4e9b07d877.js | 1 + pr/545/docs/search.index/6a81a15ea6e9.js | 1 + pr/545/docs/search.index/6ab18f85802f.js | 1 - pr/545/docs/search.index/6ab71af3e20b.js | 1 + pr/545/docs/search.index/6b27a91421e7.js | 1 - pr/545/docs/search.index/6bb48ae6c164.js | 1 - pr/545/docs/search.index/6beb75a4afca.js | 1 - pr/545/docs/search.index/6c1c6140d933.js | 1 - pr/545/docs/search.index/6c530d02ab41.js | 1 + pr/545/docs/search.index/6c8b565dd978.js | 1 + pr/545/docs/search.index/6c8cfe800841.js | 1 - pr/545/docs/search.index/6d1573bdc423.js | 1 - pr/545/docs/search.index/6d3bd3237ee4.js | 1 - pr/545/docs/search.index/6d586f085b70.js | 1 - pr/545/docs/search.index/6d8cc2ed1313.js | 1 + pr/545/docs/search.index/6dfbbd7cf8df.js | 1 + pr/545/docs/search.index/6e4c3193eddd.js | 1 + pr/545/docs/search.index/6e5b40726ebe.js | 1 - pr/545/docs/search.index/6e7e72e7f0eb.js | 1 + pr/545/docs/search.index/6e98d18aefa1.js | 1 + pr/545/docs/search.index/6eb590309867.js | 1 - pr/545/docs/search.index/6ed9f9ed97a7.js | 1 - pr/545/docs/search.index/6ede7ccd0b48.js | 1 + pr/545/docs/search.index/6f1ace4f0243.js | 1 + pr/545/docs/search.index/6f3b4b773035.js | 1 + pr/545/docs/search.index/6fa3f569eb52.js | 1 + pr/545/docs/search.index/6fd276eb1c49.js | 1 - pr/545/docs/search.index/6ffa824fa9c9.js | 1 + pr/545/docs/search.index/7027d2c26d0d.js | 1 - pr/545/docs/search.index/702838801d39.js | 1 - pr/545/docs/search.index/7057f9bfeeac.js | 1 - pr/545/docs/search.index/711105b55fc6.js | 1 + pr/545/docs/search.index/715f6cda5699.js | 1 + pr/545/docs/search.index/71be7bf851dd.js | 1 - pr/545/docs/search.index/71d64997f2e2.js | 1 - pr/545/docs/search.index/71f423a61c5f.js | 1 + pr/545/docs/search.index/71fec7874d87.js | 1 - pr/545/docs/search.index/7264b73373df.js | 1 - pr/545/docs/search.index/727e7e92c106.js | 1 - pr/545/docs/search.index/72b28c2fbe41.js | 1 - pr/545/docs/search.index/731cfc3d033b.js | 1 + pr/545/docs/search.index/735698ad2cbf.js | 1 + pr/545/docs/search.index/7359d03f24c8.js | 1 + pr/545/docs/search.index/73772e5a75b7.js | 1 + pr/545/docs/search.index/73e05ea17e51.js | 1 + pr/545/docs/search.index/74acc4c6fbd6.js | 1 - pr/545/docs/search.index/74cc3e63f115.js | 1 + pr/545/docs/search.index/74d7e300323a.js | 1 - pr/545/docs/search.index/754895de9a3c.js | 1 - pr/545/docs/search.index/75c09f7fd4e5.js | 1 - pr/545/docs/search.index/7626b27789d9.js | 1 - pr/545/docs/search.index/765cffa6a271.js | 1 + pr/545/docs/search.index/766d90f1d785.js | 1 + pr/545/docs/search.index/76f703a56322.js | 1 + pr/545/docs/search.index/771f0ba905a1.js | 1 + pr/545/docs/search.index/7735e3412c3d.js | 1 - pr/545/docs/search.index/7738bacb3923.js | 1 - pr/545/docs/search.index/778c2fe91b81.js | 1 - pr/545/docs/search.index/77be044378b5.js | 1 + pr/545/docs/search.index/77bf703f157b.js | 1 + pr/545/docs/search.index/77f651e5878e.js | 1 - pr/545/docs/search.index/781f99b9d65a.js | 1 + pr/545/docs/search.index/7886cbd3ae54.js | 1 - pr/545/docs/search.index/78e0cb18a45a.js | 1 - pr/545/docs/search.index/7918be142114.js | 1 + pr/545/docs/search.index/7969e190031a.js | 1 + pr/545/docs/search.index/7995ef0dee58.js | 1 - pr/545/docs/search.index/79dd38514944.js | 1 - pr/545/docs/search.index/7a5a2af66b0c.js | 1 - pr/545/docs/search.index/7a61dea0bfb9.js | 1 + pr/545/docs/search.index/7a7d64379eb7.js | 1 - pr/545/docs/search.index/7a7e68e0fc89.js | 1 - pr/545/docs/search.index/7adb9969b6af.js | 1 - pr/545/docs/search.index/7ae266f95131.js | 1 - pr/545/docs/search.index/7b1673ee6360.js | 1 + pr/545/docs/search.index/7b18e5676a21.js | 1 - pr/545/docs/search.index/7bd7bca0a11f.js | 1 + pr/545/docs/search.index/7bea30136fcb.js | 1 - pr/545/docs/search.index/7bfb7923cdee.js | 1 - pr/545/docs/search.index/7c00a3d092bc.js | 1 - pr/545/docs/search.index/7c908b298ddc.js | 1 - pr/545/docs/search.index/7cb84881639b.js | 1 - pr/545/docs/search.index/7cba359afb0b.js | 1 - pr/545/docs/search.index/7ccfc824e9f7.js | 1 + pr/545/docs/search.index/7da29615b409.js | 1 - pr/545/docs/search.index/7dc6410c642a.js | 1 + pr/545/docs/search.index/7e1c6d203546.js | 1 - pr/545/docs/search.index/7e3b19027434.js | 1 + pr/545/docs/search.index/7e512354c707.js | 1 - pr/545/docs/search.index/7e644c6ffb35.js | 1 + pr/545/docs/search.index/7e8f175db68a.js | 1 - pr/545/docs/search.index/7ebdb25ba28a.js | 1 + pr/545/docs/search.index/7f63f5f335b2.js | 1 - pr/545/docs/search.index/7f6612368049.js | 1 + pr/545/docs/search.index/7f8ec9909a99.js | 1 - pr/545/docs/search.index/desc/59e6f7c5fb07.js | 1 + pr/545/docs/search.index/desc/e33c984a3e69.js | 1 - .../docs/search.index/entry/34c09ea0dc28.js | 1 + .../docs/search.index/entry/99ec98389808.js | 1 - .../search.index/function/37913739753b.js | 1 + .../search.index/function/46beaf101177.js | 1 - .../generic_inverted_index/5e5024c3d9da.js | 1 - .../generic_inverted_index/af48d3aa5b7a.js | 1 + pr/545/docs/search.index/name/c4d5f34d78f6.js | 1 - pr/545/docs/search.index/name/edb16650d3a7.js | 1 + .../normalizedName/54aa4310aa6d.js | 1 - .../normalizedName/de3a57d53d3b.js | 1 + pr/545/docs/search.index/path/0c408f7dccc7.js | 1 + pr/545/docs/search.index/path/9a9587e154c3.js | 1 - pr/545/docs/search.index/root.js | 2 +- pr/545/docs/search.index/type/5f2a66270ec3.js | 1 + pr/545/docs/search.index/type/f972a24a9b65.js | 1 - pr/545/docs/src-files.js | 4 +- pr/545/docs/src/noq/connection.rs.html | 3213 ++-- pr/545/docs/src/noq/event_stream.rs.html | 114 + pr/545/docs/src/noq/lib.rs.html | 190 +- pr/545/docs/src/noq/mutex.rs.html | 4 +- pr/545/docs/src/noq/path.rs.html | 583 +- pr/545/docs/src/noq/recv_stream.rs.html | 28 +- pr/545/docs/src/noq/send_stream.rs.html | 651 +- .../docs/src/noq_proto/connection/mod.rs.html | 13089 ++++++++-------- .../src/noq_proto/connection/timer.rs.html | 690 +- .../docs/trait.impl/core/clone/trait.Clone.js | 4 +- pr/545/docs/trait.impl/core/cmp/trait.Eq.js | 4 +- .../trait.impl/core/cmp/trait.PartialEq.js | 4 +- .../docs/trait.impl/core/error/trait.Error.js | 4 +- .../docs/trait.impl/core/fmt/trait.Debug.js | 4 +- .../docs/trait.impl/core/fmt/trait.Display.js | 4 +- .../trait.impl/core/marker/trait.Freeze.js | 4 +- .../docs/trait.impl/core/marker/trait.Send.js | 4 +- .../core/marker/trait.StructuralPartialEq.js | 4 +- .../docs/trait.impl/core/marker/trait.Sync.js | 4 +- .../trait.impl/core/marker/trait.Unpin.js | 4 +- .../core/marker/trait.UnsafeUnpin.js | 4 +- .../panic/unwind_safe/trait.RefUnwindSafe.js | 4 +- .../panic/unwind_safe/trait.UnwindSafe.js | 4 +- .../futures_core/stream/trait.Stream.js | 4 +- 528 files changed, 10442 insertions(+), 9629 deletions(-) create mode 100644 pr/545/docs/noq/event_stream/struct.Lagged.html create mode 100644 pr/545/docs/noq/event_stream/struct.NatTraversalUpdates.html create mode 100644 pr/545/docs/noq/event_stream/struct.ObservedExternalAddr.html create mode 100644 pr/545/docs/noq/event_stream/struct.PathEvents.html create mode 100644 pr/545/docs/noq/struct.Lagged.html create mode 100644 pr/545/docs/noq/struct.NatTraversalUpdates.html create mode 100644 pr/545/docs/noq/struct.ObservedExternalAddr.html create mode 100644 pr/545/docs/noq/struct.PathEvents.html create mode 100644 pr/545/docs/search.index/0033f3568d59.js delete mode 100644 pr/545/docs/search.index/0106b6a79629.js delete mode 100644 pr/545/docs/search.index/0110ee2caa9d.js create mode 100644 pr/545/docs/search.index/016287c739af.js create mode 100644 pr/545/docs/search.index/01818b9a5dfd.js delete mode 100644 pr/545/docs/search.index/01b2e5b81d3a.js create mode 100644 pr/545/docs/search.index/01dabba3dd0f.js delete mode 100644 pr/545/docs/search.index/01f066683f43.js create mode 100644 pr/545/docs/search.index/0258058d4a15.js create mode 100644 pr/545/docs/search.index/03099968b016.js delete mode 100644 pr/545/docs/search.index/036264e2cafd.js create mode 100644 pr/545/docs/search.index/03d8571d8861.js create mode 100644 pr/545/docs/search.index/04067d1944a2.js create mode 100644 pr/545/docs/search.index/0435c5f11e89.js delete mode 100644 pr/545/docs/search.index/044ee5e7fc14.js create mode 100644 pr/545/docs/search.index/04cd208f0148.js create mode 100644 pr/545/docs/search.index/0530b4c13347.js create mode 100644 pr/545/docs/search.index/058523a6e4f8.js delete mode 100644 pr/545/docs/search.index/05ca02aa6fd9.js delete mode 100644 pr/545/docs/search.index/06715c7452c2.js create mode 100644 pr/545/docs/search.index/0697183800b7.js create mode 100644 pr/545/docs/search.index/06c25d8359bd.js create mode 100644 pr/545/docs/search.index/06c6b77500fe.js create mode 100644 pr/545/docs/search.index/0717d66ebc8c.js create mode 100644 pr/545/docs/search.index/0740e388ca16.js delete mode 100644 pr/545/docs/search.index/0773f56876ef.js delete mode 100644 pr/545/docs/search.index/07beea41a07f.js create mode 100644 pr/545/docs/search.index/080595ed9c0d.js delete mode 100644 pr/545/docs/search.index/08c46987941a.js create mode 100644 pr/545/docs/search.index/08d9a5c3e851.js create mode 100644 pr/545/docs/search.index/09031ecd90af.js delete mode 100644 pr/545/docs/search.index/0a28cb65ff98.js create mode 100644 pr/545/docs/search.index/0a8ad4b154a4.js create mode 100644 pr/545/docs/search.index/0bac143bcb50.js create mode 100644 pr/545/docs/search.index/0bca21001963.js delete mode 100644 pr/545/docs/search.index/0bd2d0b4cbf3.js create mode 100644 pr/545/docs/search.index/0bd42362d0ac.js delete mode 100644 pr/545/docs/search.index/0beec91fb1e5.js delete mode 100644 pr/545/docs/search.index/0c5310d088a1.js create mode 100644 pr/545/docs/search.index/0ca93a7be19c.js delete mode 100644 pr/545/docs/search.index/0d117775bd82.js delete mode 100644 pr/545/docs/search.index/0d555db5d7c8.js create mode 100644 pr/545/docs/search.index/0d6bfa8c2af1.js create mode 100644 pr/545/docs/search.index/0e2aac44d870.js create mode 100644 pr/545/docs/search.index/0e4d0f710b2b.js create mode 100644 pr/545/docs/search.index/0f30d894e39f.js delete mode 100644 pr/545/docs/search.index/0f46828f0101.js delete mode 100644 pr/545/docs/search.index/0fa5fc027b08.js create mode 100644 pr/545/docs/search.index/100cd8e013cf.js delete mode 100644 pr/545/docs/search.index/104ed5107cd6.js create mode 100644 pr/545/docs/search.index/1074492a6ce1.js delete mode 100644 pr/545/docs/search.index/10e01c839a63.js create mode 100644 pr/545/docs/search.index/117405adffd2.js delete mode 100644 pr/545/docs/search.index/1175a8ba9773.js create mode 100644 pr/545/docs/search.index/120419dec60e.js delete mode 100644 pr/545/docs/search.index/127db5988b1f.js delete mode 100644 pr/545/docs/search.index/12adc117b701.js create mode 100644 pr/545/docs/search.index/133a2aaf2619.js create mode 100644 pr/545/docs/search.index/13baa5793c64.js delete mode 100644 pr/545/docs/search.index/13f6fe7b94ed.js delete mode 100644 pr/545/docs/search.index/14272828ba1d.js delete mode 100644 pr/545/docs/search.index/1463797a33c0.js create mode 100644 pr/545/docs/search.index/1507fd45a0d0.js delete mode 100644 pr/545/docs/search.index/1540dff09ce4.js delete mode 100644 pr/545/docs/search.index/1545022d8f5e.js delete mode 100644 pr/545/docs/search.index/157deb90a29d.js create mode 100644 pr/545/docs/search.index/15883d436710.js create mode 100644 pr/545/docs/search.index/1593ad1b0859.js create mode 100644 pr/545/docs/search.index/15d820844df2.js delete mode 100644 pr/545/docs/search.index/167471e48607.js delete mode 100644 pr/545/docs/search.index/169d5b098f4e.js create mode 100644 pr/545/docs/search.index/16ea9b1933a4.js delete mode 100644 pr/545/docs/search.index/1707a9d5b2af.js delete mode 100644 pr/545/docs/search.index/171a39168019.js delete mode 100644 pr/545/docs/search.index/178adcc5c30e.js create mode 100644 pr/545/docs/search.index/17a463b91cd9.js delete mode 100644 pr/545/docs/search.index/17fbc7f79103.js delete mode 100644 pr/545/docs/search.index/1854d56f88c5.js create mode 100644 pr/545/docs/search.index/18eec5319d0e.js delete mode 100644 pr/545/docs/search.index/1915837c9928.js delete mode 100644 pr/545/docs/search.index/1928b541c754.js create mode 100644 pr/545/docs/search.index/19baf510d15e.js delete mode 100644 pr/545/docs/search.index/19beb5bb0c16.js delete mode 100644 pr/545/docs/search.index/19c5f33045ce.js create mode 100644 pr/545/docs/search.index/19d0359d569b.js delete mode 100644 pr/545/docs/search.index/19d4d15f26c3.js delete mode 100644 pr/545/docs/search.index/19da7e04c741.js create mode 100644 pr/545/docs/search.index/1a66cd07757a.js create mode 100644 pr/545/docs/search.index/1b2b113ba497.js create mode 100644 pr/545/docs/search.index/1b7cc07f1f34.js delete mode 100644 pr/545/docs/search.index/1bd9e21009c9.js create mode 100644 pr/545/docs/search.index/1bf00b4f0c44.js delete mode 100644 pr/545/docs/search.index/1c14aa28ba9e.js create mode 100644 pr/545/docs/search.index/1c262f510d82.js delete mode 100644 pr/545/docs/search.index/1d17a7bb5df0.js create mode 100644 pr/545/docs/search.index/1d3f2d3bd8f6.js delete mode 100644 pr/545/docs/search.index/1d7fbea1f446.js create mode 100644 pr/545/docs/search.index/1d8c8f6f3340.js create mode 100644 pr/545/docs/search.index/1dbcf54491ae.js create mode 100644 pr/545/docs/search.index/1de07b6bd5ed.js create mode 100644 pr/545/docs/search.index/1dff5e6ecf7f.js create mode 100644 pr/545/docs/search.index/1e93e59e94d9.js create mode 100644 pr/545/docs/search.index/1ebad890e62e.js create mode 100644 pr/545/docs/search.index/1ee39b692949.js create mode 100644 pr/545/docs/search.index/1f4450a92511.js create mode 100644 pr/545/docs/search.index/1f8374f280ae.js create mode 100644 pr/545/docs/search.index/1fac5249737c.js create mode 100644 pr/545/docs/search.index/201011f148a9.js delete mode 100644 pr/545/docs/search.index/2063bc13c29e.js create mode 100644 pr/545/docs/search.index/20a41ecff08f.js delete mode 100644 pr/545/docs/search.index/20a57735c5a6.js delete mode 100644 pr/545/docs/search.index/20ac1af4f5cb.js create mode 100644 pr/545/docs/search.index/20afefeb7ec4.js create mode 100644 pr/545/docs/search.index/20da1b8e8e24.js create mode 100644 pr/545/docs/search.index/20fbab33fc2f.js delete mode 100644 pr/545/docs/search.index/215b5a83d39e.js delete mode 100644 pr/545/docs/search.index/2232ff223063.js delete mode 100644 pr/545/docs/search.index/224409c019b5.js create mode 100644 pr/545/docs/search.index/227000c17c1b.js create mode 100644 pr/545/docs/search.index/22f66fe81db4.js create mode 100644 pr/545/docs/search.index/230d9ae0255e.js create mode 100644 pr/545/docs/search.index/23daddc85a2a.js create mode 100644 pr/545/docs/search.index/240436689105.js delete mode 100644 pr/545/docs/search.index/246c639fd848.js create mode 100644 pr/545/docs/search.index/25143dd2528f.js create mode 100644 pr/545/docs/search.index/25a2359dd30d.js delete mode 100644 pr/545/docs/search.index/25a5775ae582.js create mode 100644 pr/545/docs/search.index/2657ace38ed9.js create mode 100644 pr/545/docs/search.index/26625634ad63.js delete mode 100644 pr/545/docs/search.index/267566229927.js delete mode 100644 pr/545/docs/search.index/26d748f5add8.js create mode 100644 pr/545/docs/search.index/26eaff1ecc2b.js delete mode 100644 pr/545/docs/search.index/27b689c7cdce.js create mode 100644 pr/545/docs/search.index/280b57a12fe8.js create mode 100644 pr/545/docs/search.index/2892218972b3.js delete mode 100644 pr/545/docs/search.index/289cef522e65.js delete mode 100644 pr/545/docs/search.index/294c65cabea3.js delete mode 100644 pr/545/docs/search.index/29a9ad420aea.js delete mode 100644 pr/545/docs/search.index/2a157ff40a7a.js create mode 100644 pr/545/docs/search.index/2a552ae8044e.js create mode 100644 pr/545/docs/search.index/2a67720851d1.js create mode 100644 pr/545/docs/search.index/2a8e4b0e890f.js delete mode 100644 pr/545/docs/search.index/2b4d7f4d8d3a.js delete mode 100644 pr/545/docs/search.index/2b89b2e478bd.js delete mode 100644 pr/545/docs/search.index/2bbd4ed026d7.js create mode 100644 pr/545/docs/search.index/2bbea166f1f8.js create mode 100644 pr/545/docs/search.index/2d92cd1657e9.js delete mode 100644 pr/545/docs/search.index/2e2486520353.js delete mode 100644 pr/545/docs/search.index/2e4409258cfe.js create mode 100644 pr/545/docs/search.index/2eaf4ab981c3.js create mode 100644 pr/545/docs/search.index/2eeacf2c8ee0.js delete mode 100644 pr/545/docs/search.index/2f792e01bbed.js create mode 100644 pr/545/docs/search.index/2f7ecc5dbb1a.js delete mode 100644 pr/545/docs/search.index/2ffc6423036c.js create mode 100644 pr/545/docs/search.index/3036a9249b54.js create mode 100644 pr/545/docs/search.index/31b45cf6ecff.js create mode 100644 pr/545/docs/search.index/320b0f4af278.js create mode 100644 pr/545/docs/search.index/321190b83abb.js delete mode 100644 pr/545/docs/search.index/323be9ee8c7b.js create mode 100644 pr/545/docs/search.index/3289f09b047b.js delete mode 100644 pr/545/docs/search.index/32c74d9cf3af.js delete mode 100644 pr/545/docs/search.index/32d7ceba568b.js create mode 100644 pr/545/docs/search.index/3381b6452880.js delete mode 100644 pr/545/docs/search.index/339b70d50fee.js create mode 100644 pr/545/docs/search.index/342a647c77a6.js delete mode 100644 pr/545/docs/search.index/3491b6741081.js delete mode 100644 pr/545/docs/search.index/34fdabda10df.js delete mode 100644 pr/545/docs/search.index/351cf7b3eacb.js create mode 100644 pr/545/docs/search.index/355e9ccc3e7d.js create mode 100644 pr/545/docs/search.index/3580644ae6d8.js delete mode 100644 pr/545/docs/search.index/3587167fe015.js delete mode 100644 pr/545/docs/search.index/35c861889432.js create mode 100644 pr/545/docs/search.index/3650ebdc9bae.js create mode 100644 pr/545/docs/search.index/36590b411474.js create mode 100644 pr/545/docs/search.index/368640dd3a84.js delete mode 100644 pr/545/docs/search.index/37122b199c40.js delete mode 100644 pr/545/docs/search.index/3792ea5bd86e.js create mode 100644 pr/545/docs/search.index/37ae2f2cc265.js delete mode 100644 pr/545/docs/search.index/37ae4ca5ac42.js delete mode 100644 pr/545/docs/search.index/3810d433a829.js create mode 100644 pr/545/docs/search.index/3874f15e7771.js create mode 100644 pr/545/docs/search.index/38b236771a65.js delete mode 100644 pr/545/docs/search.index/38be63c8f52d.js create mode 100644 pr/545/docs/search.index/38e853561a8a.js create mode 100644 pr/545/docs/search.index/39a52dda198c.js create mode 100644 pr/545/docs/search.index/3a0723146c92.js delete mode 100644 pr/545/docs/search.index/3a65c80ab51b.js delete mode 100644 pr/545/docs/search.index/3a7213b0a18a.js delete mode 100644 pr/545/docs/search.index/3a93f64bc2c4.js delete mode 100644 pr/545/docs/search.index/3ac7cfd35a72.js create mode 100644 pr/545/docs/search.index/3b114748649d.js create mode 100644 pr/545/docs/search.index/3b4e28ed9312.js delete mode 100644 pr/545/docs/search.index/3bc3c52a55c9.js delete mode 100644 pr/545/docs/search.index/3bf70d50c752.js create mode 100644 pr/545/docs/search.index/3c0f5abd09f3.js delete mode 100644 pr/545/docs/search.index/3c17bff3a5ab.js delete mode 100644 pr/545/docs/search.index/3c89aeb97d29.js create mode 100644 pr/545/docs/search.index/3c8f419d6519.js create mode 100644 pr/545/docs/search.index/3ccd0c7a2788.js delete mode 100644 pr/545/docs/search.index/3d2200f2a97e.js create mode 100644 pr/545/docs/search.index/3d5f153390be.js delete mode 100644 pr/545/docs/search.index/3db3d3836bf3.js create mode 100644 pr/545/docs/search.index/3e10313c5965.js create mode 100644 pr/545/docs/search.index/3e3cbb04f471.js create mode 100644 pr/545/docs/search.index/3e98557ba4a3.js delete mode 100644 pr/545/docs/search.index/3f00814740bc.js delete mode 100644 pr/545/docs/search.index/3f0b4ad53d12.js delete mode 100644 pr/545/docs/search.index/3f1a6e1729e4.js create mode 100644 pr/545/docs/search.index/3f243484e57a.js create mode 100644 pr/545/docs/search.index/3f24cd5aa4fa.js create mode 100644 pr/545/docs/search.index/3f8645c00d7c.js create mode 100644 pr/545/docs/search.index/4031cc647b10.js create mode 100644 pr/545/docs/search.index/404afcce0ada.js delete mode 100644 pr/545/docs/search.index/40b99a9f0103.js delete mode 100644 pr/545/docs/search.index/40feefc69675.js create mode 100644 pr/545/docs/search.index/4100782a5d31.js delete mode 100644 pr/545/docs/search.index/410d825e5fa8.js delete mode 100644 pr/545/docs/search.index/4155c1291357.js create mode 100644 pr/545/docs/search.index/4159f6c35981.js delete mode 100644 pr/545/docs/search.index/41a1fd12d13b.js delete mode 100644 pr/545/docs/search.index/42be563f7543.js delete mode 100644 pr/545/docs/search.index/42e25feb3567.js delete mode 100644 pr/545/docs/search.index/4341bc8e4878.js delete mode 100644 pr/545/docs/search.index/434a43cc0e07.js create mode 100644 pr/545/docs/search.index/4351feb790fe.js create mode 100644 pr/545/docs/search.index/436e158b126a.js delete mode 100644 pr/545/docs/search.index/43ac7a9781b4.js create mode 100644 pr/545/docs/search.index/441e425635ce.js delete mode 100644 pr/545/docs/search.index/446e084c83a8.js delete mode 100644 pr/545/docs/search.index/4471155ecc0f.js delete mode 100644 pr/545/docs/search.index/44bd10e48043.js delete mode 100644 pr/545/docs/search.index/44d27e55c058.js create mode 100644 pr/545/docs/search.index/450719784301.js create mode 100644 pr/545/docs/search.index/45c7f13213d0.js create mode 100644 pr/545/docs/search.index/45cefb4b1fe7.js delete mode 100644 pr/545/docs/search.index/460ae98fed07.js create mode 100644 pr/545/docs/search.index/46615455c43f.js create mode 100644 pr/545/docs/search.index/4663a4e119e7.js create mode 100644 pr/545/docs/search.index/46d02c2cf6f3.js create mode 100644 pr/545/docs/search.index/470732838eeb.js create mode 100644 pr/545/docs/search.index/474b31e6c524.js delete mode 100644 pr/545/docs/search.index/47aa62fcbff4.js delete mode 100644 pr/545/docs/search.index/47b9d9b13323.js create mode 100644 pr/545/docs/search.index/4805b324248d.js delete mode 100644 pr/545/docs/search.index/480a31b05a4c.js delete mode 100644 pr/545/docs/search.index/483ec6c64d5e.js delete mode 100644 pr/545/docs/search.index/4a9458af2428.js create mode 100644 pr/545/docs/search.index/4aa7b4743afe.js create mode 100644 pr/545/docs/search.index/4c05ce7be64f.js delete mode 100644 pr/545/docs/search.index/4c05e858ff5d.js delete mode 100644 pr/545/docs/search.index/4c2110675ed8.js delete mode 100644 pr/545/docs/search.index/4c8621a28a73.js create mode 100644 pr/545/docs/search.index/4c89ae5762cb.js delete mode 100644 pr/545/docs/search.index/4cd916711a76.js delete mode 100644 pr/545/docs/search.index/4cdc76f01005.js create mode 100644 pr/545/docs/search.index/4d88a08a2ae4.js delete mode 100644 pr/545/docs/search.index/4dd85b55e38e.js delete mode 100644 pr/545/docs/search.index/4e07dd0ff701.js create mode 100644 pr/545/docs/search.index/4e0fe03427ba.js delete mode 100644 pr/545/docs/search.index/4e6750278d1b.js create mode 100644 pr/545/docs/search.index/4eac59928f18.js create mode 100644 pr/545/docs/search.index/4eed4a0cfe1e.js create mode 100644 pr/545/docs/search.index/4fae9a79a161.js delete mode 100644 pr/545/docs/search.index/505a1a911bef.js create mode 100644 pr/545/docs/search.index/50abe47e037f.js delete mode 100644 pr/545/docs/search.index/517322c0ea00.js create mode 100644 pr/545/docs/search.index/521c1cdfffb6.js delete mode 100644 pr/545/docs/search.index/52548d68890f.js create mode 100644 pr/545/docs/search.index/52b7dbce0a40.js create mode 100644 pr/545/docs/search.index/536f57712388.js create mode 100644 pr/545/docs/search.index/538b5fc4e1ed.js create mode 100644 pr/545/docs/search.index/5392889fe77e.js delete mode 100644 pr/545/docs/search.index/53fb9a760872.js create mode 100644 pr/545/docs/search.index/53ffa8e8252a.js create mode 100644 pr/545/docs/search.index/5478b18519c4.js create mode 100644 pr/545/docs/search.index/548eac6e4034.js create mode 100644 pr/545/docs/search.index/549a18f8219c.js create mode 100644 pr/545/docs/search.index/5535b627edd5.js delete mode 100644 pr/545/docs/search.index/55c5b7004628.js delete mode 100644 pr/545/docs/search.index/560e166f7c46.js delete mode 100644 pr/545/docs/search.index/5710b3f34500.js create mode 100644 pr/545/docs/search.index/571482a0f60a.js delete mode 100644 pr/545/docs/search.index/5717d266c26b.js delete mode 100644 pr/545/docs/search.index/5724a5cd21a6.js create mode 100644 pr/545/docs/search.index/579677a41519.js create mode 100644 pr/545/docs/search.index/5802da10e9df.js create mode 100644 pr/545/docs/search.index/58045aae0759.js delete mode 100644 pr/545/docs/search.index/58acc8d198d4.js create mode 100644 pr/545/docs/search.index/59be03fa81eb.js create mode 100644 pr/545/docs/search.index/59c5b0e1f8ad.js delete mode 100644 pr/545/docs/search.index/59f79b94bb60.js create mode 100644 pr/545/docs/search.index/59fb890d29b8.js create mode 100644 pr/545/docs/search.index/5a22fd2fcd2b.js delete mode 100644 pr/545/docs/search.index/5b27537522a3.js delete mode 100644 pr/545/docs/search.index/5b319b8ab819.js create mode 100644 pr/545/docs/search.index/5b62c7da471c.js delete mode 100644 pr/545/docs/search.index/5b6e7c005ae8.js create mode 100644 pr/545/docs/search.index/5bd4900427a6.js create mode 100644 pr/545/docs/search.index/5bf126ddcd97.js delete mode 100644 pr/545/docs/search.index/5c0a1d01fe52.js create mode 100644 pr/545/docs/search.index/5ccc63e2df25.js create mode 100644 pr/545/docs/search.index/5d45dfdef8cc.js delete mode 100644 pr/545/docs/search.index/5d5835d05dfa.js create mode 100644 pr/545/docs/search.index/5d5b1b8d153b.js delete mode 100644 pr/545/docs/search.index/5d9c4f60b3ee.js create mode 100644 pr/545/docs/search.index/5dbdf61761a4.js delete mode 100644 pr/545/docs/search.index/5e0965d74272.js create mode 100644 pr/545/docs/search.index/5ed9ecced0b1.js delete mode 100644 pr/545/docs/search.index/5f0e00c10ee4.js delete mode 100644 pr/545/docs/search.index/5f4c630285ac.js create mode 100644 pr/545/docs/search.index/5f940ff8b47f.js delete mode 100644 pr/545/docs/search.index/604d10667a5a.js delete mode 100644 pr/545/docs/search.index/6061769b899d.js delete mode 100644 pr/545/docs/search.index/6084ac5d766b.js delete mode 100644 pr/545/docs/search.index/616f5750f133.js delete mode 100644 pr/545/docs/search.index/61ad89c61241.js delete mode 100644 pr/545/docs/search.index/61fb1929c127.js delete mode 100644 pr/545/docs/search.index/62058f24fb16.js create mode 100644 pr/545/docs/search.index/624a2471dcc3.js create mode 100644 pr/545/docs/search.index/62bb0fe614ca.js delete mode 100644 pr/545/docs/search.index/62bd0277a025.js create mode 100644 pr/545/docs/search.index/62ce08268925.js create mode 100644 pr/545/docs/search.index/635558f41241.js create mode 100644 pr/545/docs/search.index/63d5d6c31ff0.js delete mode 100644 pr/545/docs/search.index/63dfc59f4dc3.js delete mode 100644 pr/545/docs/search.index/643d3b14fc3a.js create mode 100644 pr/545/docs/search.index/64f401d0105c.js delete mode 100644 pr/545/docs/search.index/653d5783dc15.js create mode 100644 pr/545/docs/search.index/655cb440fbba.js delete mode 100644 pr/545/docs/search.index/656b47c2fced.js create mode 100644 pr/545/docs/search.index/657959d9dfd0.js delete mode 100644 pr/545/docs/search.index/662c4a4e5d9e.js create mode 100644 pr/545/docs/search.index/667f942da920.js delete mode 100644 pr/545/docs/search.index/671a68018a40.js delete mode 100644 pr/545/docs/search.index/671d46d3c768.js delete mode 100644 pr/545/docs/search.index/67319b6740f3.js delete mode 100644 pr/545/docs/search.index/6749f8fc3137.js delete mode 100644 pr/545/docs/search.index/674eafdf622c.js delete mode 100644 pr/545/docs/search.index/67b74bab08a8.js create mode 100644 pr/545/docs/search.index/680921c7e0dc.js delete mode 100644 pr/545/docs/search.index/68704ffa368a.js delete mode 100644 pr/545/docs/search.index/68807ca8d915.js create mode 100644 pr/545/docs/search.index/690e03933450.js delete mode 100644 pr/545/docs/search.index/692a422fa077.js delete mode 100644 pr/545/docs/search.index/693f7e452732.js create mode 100644 pr/545/docs/search.index/694efa293f2d.js delete mode 100644 pr/545/docs/search.index/699c12ddce85.js delete mode 100644 pr/545/docs/search.index/69eda39d9ee0.js create mode 100644 pr/545/docs/search.index/6a152aadbb4b.js create mode 100644 pr/545/docs/search.index/6a4e9b07d877.js create mode 100644 pr/545/docs/search.index/6a81a15ea6e9.js delete mode 100644 pr/545/docs/search.index/6ab18f85802f.js create mode 100644 pr/545/docs/search.index/6ab71af3e20b.js delete mode 100644 pr/545/docs/search.index/6b27a91421e7.js delete mode 100644 pr/545/docs/search.index/6bb48ae6c164.js delete mode 100644 pr/545/docs/search.index/6beb75a4afca.js delete mode 100644 pr/545/docs/search.index/6c1c6140d933.js create mode 100644 pr/545/docs/search.index/6c530d02ab41.js create mode 100644 pr/545/docs/search.index/6c8b565dd978.js delete mode 100644 pr/545/docs/search.index/6c8cfe800841.js delete mode 100644 pr/545/docs/search.index/6d1573bdc423.js delete mode 100644 pr/545/docs/search.index/6d3bd3237ee4.js delete mode 100644 pr/545/docs/search.index/6d586f085b70.js create mode 100644 pr/545/docs/search.index/6d8cc2ed1313.js create mode 100644 pr/545/docs/search.index/6dfbbd7cf8df.js create mode 100644 pr/545/docs/search.index/6e4c3193eddd.js delete mode 100644 pr/545/docs/search.index/6e5b40726ebe.js create mode 100644 pr/545/docs/search.index/6e7e72e7f0eb.js create mode 100644 pr/545/docs/search.index/6e98d18aefa1.js delete mode 100644 pr/545/docs/search.index/6eb590309867.js delete mode 100644 pr/545/docs/search.index/6ed9f9ed97a7.js create mode 100644 pr/545/docs/search.index/6ede7ccd0b48.js create mode 100644 pr/545/docs/search.index/6f1ace4f0243.js create mode 100644 pr/545/docs/search.index/6f3b4b773035.js create mode 100644 pr/545/docs/search.index/6fa3f569eb52.js delete mode 100644 pr/545/docs/search.index/6fd276eb1c49.js create mode 100644 pr/545/docs/search.index/6ffa824fa9c9.js delete mode 100644 pr/545/docs/search.index/7027d2c26d0d.js delete mode 100644 pr/545/docs/search.index/702838801d39.js delete mode 100644 pr/545/docs/search.index/7057f9bfeeac.js create mode 100644 pr/545/docs/search.index/711105b55fc6.js create mode 100644 pr/545/docs/search.index/715f6cda5699.js delete mode 100644 pr/545/docs/search.index/71be7bf851dd.js delete mode 100644 pr/545/docs/search.index/71d64997f2e2.js create mode 100644 pr/545/docs/search.index/71f423a61c5f.js delete mode 100644 pr/545/docs/search.index/71fec7874d87.js delete mode 100644 pr/545/docs/search.index/7264b73373df.js delete mode 100644 pr/545/docs/search.index/727e7e92c106.js delete mode 100644 pr/545/docs/search.index/72b28c2fbe41.js create mode 100644 pr/545/docs/search.index/731cfc3d033b.js create mode 100644 pr/545/docs/search.index/735698ad2cbf.js create mode 100644 pr/545/docs/search.index/7359d03f24c8.js create mode 100644 pr/545/docs/search.index/73772e5a75b7.js create mode 100644 pr/545/docs/search.index/73e05ea17e51.js delete mode 100644 pr/545/docs/search.index/74acc4c6fbd6.js create mode 100644 pr/545/docs/search.index/74cc3e63f115.js delete mode 100644 pr/545/docs/search.index/74d7e300323a.js delete mode 100644 pr/545/docs/search.index/754895de9a3c.js delete mode 100644 pr/545/docs/search.index/75c09f7fd4e5.js delete mode 100644 pr/545/docs/search.index/7626b27789d9.js create mode 100644 pr/545/docs/search.index/765cffa6a271.js create mode 100644 pr/545/docs/search.index/766d90f1d785.js create mode 100644 pr/545/docs/search.index/76f703a56322.js create mode 100644 pr/545/docs/search.index/771f0ba905a1.js delete mode 100644 pr/545/docs/search.index/7735e3412c3d.js delete mode 100644 pr/545/docs/search.index/7738bacb3923.js delete mode 100644 pr/545/docs/search.index/778c2fe91b81.js create mode 100644 pr/545/docs/search.index/77be044378b5.js create mode 100644 pr/545/docs/search.index/77bf703f157b.js delete mode 100644 pr/545/docs/search.index/77f651e5878e.js create mode 100644 pr/545/docs/search.index/781f99b9d65a.js delete mode 100644 pr/545/docs/search.index/7886cbd3ae54.js delete mode 100644 pr/545/docs/search.index/78e0cb18a45a.js create mode 100644 pr/545/docs/search.index/7918be142114.js create mode 100644 pr/545/docs/search.index/7969e190031a.js delete mode 100644 pr/545/docs/search.index/7995ef0dee58.js delete mode 100644 pr/545/docs/search.index/79dd38514944.js delete mode 100644 pr/545/docs/search.index/7a5a2af66b0c.js create mode 100644 pr/545/docs/search.index/7a61dea0bfb9.js delete mode 100644 pr/545/docs/search.index/7a7d64379eb7.js delete mode 100644 pr/545/docs/search.index/7a7e68e0fc89.js delete mode 100644 pr/545/docs/search.index/7adb9969b6af.js delete mode 100644 pr/545/docs/search.index/7ae266f95131.js create mode 100644 pr/545/docs/search.index/7b1673ee6360.js delete mode 100644 pr/545/docs/search.index/7b18e5676a21.js create mode 100644 pr/545/docs/search.index/7bd7bca0a11f.js delete mode 100644 pr/545/docs/search.index/7bea30136fcb.js delete mode 100644 pr/545/docs/search.index/7bfb7923cdee.js delete mode 100644 pr/545/docs/search.index/7c00a3d092bc.js delete mode 100644 pr/545/docs/search.index/7c908b298ddc.js delete mode 100644 pr/545/docs/search.index/7cb84881639b.js delete mode 100644 pr/545/docs/search.index/7cba359afb0b.js create mode 100644 pr/545/docs/search.index/7ccfc824e9f7.js delete mode 100644 pr/545/docs/search.index/7da29615b409.js create mode 100644 pr/545/docs/search.index/7dc6410c642a.js delete mode 100644 pr/545/docs/search.index/7e1c6d203546.js create mode 100644 pr/545/docs/search.index/7e3b19027434.js delete mode 100644 pr/545/docs/search.index/7e512354c707.js create mode 100644 pr/545/docs/search.index/7e644c6ffb35.js delete mode 100644 pr/545/docs/search.index/7e8f175db68a.js create mode 100644 pr/545/docs/search.index/7ebdb25ba28a.js delete mode 100644 pr/545/docs/search.index/7f63f5f335b2.js create mode 100644 pr/545/docs/search.index/7f6612368049.js delete mode 100644 pr/545/docs/search.index/7f8ec9909a99.js create mode 100644 pr/545/docs/search.index/desc/59e6f7c5fb07.js delete mode 100644 pr/545/docs/search.index/desc/e33c984a3e69.js create mode 100644 pr/545/docs/search.index/entry/34c09ea0dc28.js delete mode 100644 pr/545/docs/search.index/entry/99ec98389808.js create mode 100644 pr/545/docs/search.index/function/37913739753b.js delete mode 100644 pr/545/docs/search.index/function/46beaf101177.js delete mode 100644 pr/545/docs/search.index/generic_inverted_index/5e5024c3d9da.js create mode 100644 pr/545/docs/search.index/generic_inverted_index/af48d3aa5b7a.js delete mode 100644 pr/545/docs/search.index/name/c4d5f34d78f6.js create mode 100644 pr/545/docs/search.index/name/edb16650d3a7.js delete mode 100644 pr/545/docs/search.index/normalizedName/54aa4310aa6d.js create mode 100644 pr/545/docs/search.index/normalizedName/de3a57d53d3b.js create mode 100644 pr/545/docs/search.index/path/0c408f7dccc7.js delete mode 100644 pr/545/docs/search.index/path/9a9587e154c3.js create mode 100644 pr/545/docs/search.index/type/5f2a66270ec3.js delete mode 100644 pr/545/docs/search.index/type/f972a24a9b65.js create mode 100644 pr/545/docs/src/noq/event_stream.rs.html diff --git a/pr/545/docs/noq/all.html b/pr/545/docs/noq/all.html index de17cc4d7..17028e65b 100644 --- a/pr/545/docs/noq/all.html +++ b/pr/545/docs/noq/all.html @@ -1 +1 @@ -List of all items in this crate

All

List of all items

Structs

Enums

Traits

Functions

\ No newline at end of file +List of all items in this crate

All

List of all items

Structs

Enums

Traits

Functions

\ No newline at end of file diff --git a/pr/545/docs/noq/enum.ConnectionError.html b/pr/545/docs/noq/enum.ConnectionError.html index 31bf5ff81..56a4c44c7 100644 --- a/pr/545/docs/noq/enum.ConnectionError.html +++ b/pr/545/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/545/docs/noq/enum.SendDatagramError.html b/pr/545/docs/noq/enum.SendDatagramError.html index d7a834ea3..4b8a4e090 100644 --- a/pr/545/docs/noq/enum.SendDatagramError.html +++ b/pr/545/docs/noq/enum.SendDatagramError.html @@ -1,4 +1,4 @@ -SendDatagramError in noq - Rust

SendDatagramError

Enum SendDatagramError 

Source
pub enum SendDatagramError {
+SendDatagramError in noq - Rust

SendDatagramError

Enum SendDatagramError 

Source
pub enum SendDatagramError {
     UnsupportedByPeer,
     Disabled,
     TooLarge,
@@ -10,8 +10,8 @@
 

Indicates that the path MTU minus overhead or the limit advertised by the peer has been exceeded.

§

ConnectionLost(ConnectionError)

The connection was lost

-

Trait Implementations§

Source§

impl Clone for SendDatagramError

Source§

fn clone(&self) -> SendDatagramError

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 SendDatagramError

Source§

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

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

impl Display for SendDatagramError

Source§

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

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

impl Error for SendDatagramError

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 SendDatagramError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for SendDatagramError

Source§

fn eq(&self, other: &SendDatagramError) -> 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 SendDatagramError

Source§

impl StructuralPartialEq for SendDatagramError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for SendDatagramError

Source§

fn clone(&self) -> SendDatagramError

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 SendDatagramError

Source§

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

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

impl Display for SendDatagramError

Source§

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

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

impl Error for SendDatagramError

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 SendDatagramError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for SendDatagramError

Source§

fn eq(&self, other: &SendDatagramError) -> 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 SendDatagramError

Source§

impl StructuralPartialEq for SendDatagramError

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/545/docs/noq/enum.StoppedError.html b/pr/545/docs/noq/enum.StoppedError.html index 3b546f354..db56529df 100644 --- a/pr/545/docs/noq/enum.StoppedError.html +++ b/pr/545/docs/noq/enum.StoppedError.html @@ -1,4 +1,4 @@ -StoppedError in noq - Rust

StoppedError

Enum StoppedError 

Source
pub enum StoppedError {
+StoppedError in noq - Rust

StoppedError

Enum StoppedError 

Source
pub enum StoppedError {
     ConnectionLost(ConnectionError),
     ZeroRttRejected,
 }
Expand description

Errors that arise while monitoring for a send stream stop from the peer

@@ -6,8 +6,8 @@
§

ZeroRttRejected

This was a 0-RTT stream and the server rejected it

Can only occur on clients for 0-RTT streams, which can be opened using Connecting::into_0rtt().

-

Trait Implementations§

Source§

impl Clone for StoppedError

Source§

fn clone(&self) -> StoppedError

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 StoppedError

Source§

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

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

impl Display for StoppedError

Source§

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

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

impl Error for StoppedError

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 StoppedError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for Error

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for WriteError

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for StoppedError

Source§

fn eq(&self, other: &StoppedError) -> 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 StoppedError

Source§

impl StructuralPartialEq for StoppedError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for StoppedError

Source§

fn clone(&self) -> StoppedError

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 StoppedError

Source§

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

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

impl Display for StoppedError

Source§

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

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

impl Error for StoppedError

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 StoppedError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for Error

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl From<StoppedError> for WriteError

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for StoppedError

Source§

fn eq(&self, other: &StoppedError) -> 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 StoppedError

Source§

impl StructuralPartialEq for StoppedError

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/545/docs/noq/enum.WriteError.html b/pr/545/docs/noq/enum.WriteError.html index d5a81ac6c..606752321 100644 --- a/pr/545/docs/noq/enum.WriteError.html +++ b/pr/545/docs/noq/enum.WriteError.html @@ -1,4 +1,4 @@ -WriteError in noq - Rust

WriteError

Enum WriteError 

Source
pub enum WriteError {
+WriteError in noq - Rust

WriteError

Enum WriteError 

Source
pub enum WriteError {
     Stopped(VarInt),
     ConnectionLost(ConnectionError),
     ClosedStream,
@@ -11,8 +11,8 @@
 
§

ZeroRttRejected

This was a 0-RTT stream and the server rejected it

Can only occur on clients for 0-RTT streams, which can be opened using Connecting::into_0rtt().

-

Trait Implementations§

Source§

impl Clone for WriteError

Source§

fn clone(&self) -> WriteError

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 WriteError

Source§

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

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

impl Display for WriteError

Source§

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

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

impl Error for WriteError

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<ClosedStream> for WriteError

Source§

fn from(_: ClosedStream) -> 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<StoppedError> for WriteError

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl From<WriteError> for Error

Source§

fn from(x: WriteError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for WriteError

Source§

fn eq(&self, other: &WriteError) -> 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 WriteError

Source§

impl StructuralPartialEq for WriteError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for WriteError

Source§

fn clone(&self) -> WriteError

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 WriteError

Source§

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

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

impl Display for WriteError

Source§

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

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

impl Error for WriteError

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<ClosedStream> for WriteError

Source§

fn from(_: ClosedStream) -> 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<StoppedError> for WriteError

Source§

fn from(x: StoppedError) -> Self

Converts to this type from the input type.
Source§

impl From<WriteError> for Error

Source§

fn from(x: WriteError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for WriteError

Source§

fn eq(&self, other: &WriteError) -> 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 WriteError

Source§

impl StructuralPartialEq for WriteError

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/545/docs/noq/event_stream/struct.Lagged.html b/pr/545/docs/noq/event_stream/struct.Lagged.html new file mode 100644 index 000000000..d36b86d2e --- /dev/null +++ b/pr/545/docs/noq/event_stream/struct.Lagged.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../noq/struct.Lagged.html...

+ + + \ No newline at end of file diff --git a/pr/545/docs/noq/event_stream/struct.NatTraversalUpdates.html b/pr/545/docs/noq/event_stream/struct.NatTraversalUpdates.html new file mode 100644 index 000000000..edcccd603 --- /dev/null +++ b/pr/545/docs/noq/event_stream/struct.NatTraversalUpdates.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../noq/struct.NatTraversalUpdates.html...

+ + + \ No newline at end of file diff --git a/pr/545/docs/noq/event_stream/struct.ObservedExternalAddr.html b/pr/545/docs/noq/event_stream/struct.ObservedExternalAddr.html new file mode 100644 index 000000000..22ca8bf7d --- /dev/null +++ b/pr/545/docs/noq/event_stream/struct.ObservedExternalAddr.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../noq/struct.ObservedExternalAddr.html...

+ + + \ No newline at end of file diff --git a/pr/545/docs/noq/event_stream/struct.PathEvents.html b/pr/545/docs/noq/event_stream/struct.PathEvents.html new file mode 100644 index 000000000..584df6b1e --- /dev/null +++ b/pr/545/docs/noq/event_stream/struct.PathEvents.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../noq/struct.PathEvents.html...

+ + + \ No newline at end of file diff --git a/pr/545/docs/noq/index.html b/pr/545/docs/noq/index.html index 3b99b5bf6..5554daa1f 100644 --- a/pr/545/docs/noq/index.html +++ b/pr/545/docs/noq/index.html @@ -1,4 +1,4 @@ -noq - Rust

Crate noq

Crate noq 

Source
Expand description

QUIC transport protocol implementation

+noq - Rust

Crate noq

Crate noq 

Source
Expand description

QUIC transport protocol implementation

QUIC is a modern transport protocol addressing shortcomings of TCP, such as head-of-line blocking, poor security, slow handshakes, and inefficient congestion control. This crate provides a portable userspace implementation. It @@ -29,6 +29,6 @@ server, it is useful for a QUIC server to be identified by a certificate signed authority. If this is infeasible–for example, if servers are short-lived or not associated with a domain name–then as with TLS, self-signed certificates can be used to provide encryption alone.

-

Re-exports§

pub use rustls;
pub use udp;

Modules§

congestion
Logic for controlling the rate at which data is sent
crypto
Traits and implementations for the QUIC cryptography protocol

Structs§

Accept
Future produced by Endpoint::accept
AcceptBi
Future produced by Connection::accept_bi
AcceptUni
Future produced by Connection::accept_uni
AckFrequencyConfig
Parameters for controlling the peer’s acknowledgement frequency
AddressDiscovery
Stream produced by Path::observed_external_addr
ApplicationClose
Reason given by an application for closing the connection
BloomTokenLog
Bloom filter-based TokenLog
Chunk
A chunk of data from the receive stream
ClientConfig
Configuration for outgoing connections
ClosedStream
Error indicating that a stream has not been opened or has already been finished or reset
Connecting
In-progress connection attempt future
Connection
A QUIC connection.
ConnectionClose
Reason given by the transport for closing the connection
ConnectionId
Protocol-level identifier for a connection.
ConnectionStats
Connection statistics.
Endpoint
A QUIC endpoint.
EndpointConfig
Global configuration for the endpoint, affecting all connections
EndpointStats
Statistics on Endpoint activity
FrameStats
Number of frames transmitted or received of each frame type.
IdleTimeout
Maximum duration of inactivity to accept before timing out the connection
Incoming
An incoming connection for which the server has not yet begun its part of the handshake
IncomingFuture
Basic adapter to let Incoming be await-ed like a Connecting
InvalidCid
The connection ID was not recognized by the ConnectionIdGenerator
MtuDiscoveryConfig
Parameters governing MTU discovery.
NoneTokenLog
Null implementation of TokenLog, which never accepts tokens
NoneTokenStore
Null implementation of TokenStore, which does not store any tokens
OnClosed
Future returned by Connection::on_closed
OpenBi
Future produced by Connection::open_bi
OpenPath
Future produced by crate::Connection::open_path
OpenUni
Future produced by Connection::open_uni
Path
An open network transmission within a multipath-enabled connection.
PathId
Id representing different paths when using multipath extension
PathStats
Statistics related to a transmission path.
QlogConfig
Configuration for qlog trace logging.
QlogFileFactory
Enables writing qlog traces to a directory.
ReadDatagram
Future produced by Connection::read_datagram
RecvStream
A stream that can only be used to receive data
RetryError
Error for attempting to retry an Incoming which already bears a token from a previous retry
SendDatagram
Future produced by Connection::send_datagram_wait
SendStream
A stream that can only be used to send data
ServerConfig
Parameters governing incoming connections
SmolRuntime
A noq runtime for smol
StdSystemTime
Default implementation of TimeSource
Stopped
Future returned from SendStream::stopped.
StreamId
Identifier for a stream within a particular connection
TokenMemoryCache
TokenStore implementation that stores up to N tokens per server name for up to a +

Re-exports§

pub use rustls;
pub use udp;

Modules§

congestion
Logic for controlling the rate at which data is sent
crypto
Traits and implementations for the QUIC cryptography protocol

Structs§

Accept
Future produced by Endpoint::accept
AcceptBi
Future produced by Connection::accept_bi
AcceptUni
Future produced by Connection::accept_uni
AckFrequencyConfig
Parameters for controlling the peer’s acknowledgement frequency
AddressDiscovery
Stream produced by Path::observed_external_addr
ApplicationClose
Reason given by an application for closing the connection
BloomTokenLog
Bloom filter-based TokenLog
Chunk
A chunk of data from the receive stream
ClientConfig
Configuration for outgoing connections
ClosedStream
Error indicating that a stream has not been opened or has already been finished or reset
Connecting
In-progress connection attempt future
Connection
A QUIC connection.
ConnectionClose
Reason given by the transport for closing the connection
ConnectionId
Protocol-level identifier for a connection.
ConnectionStats
Connection statistics.
Endpoint
A QUIC endpoint.
EndpointConfig
Global configuration for the endpoint, affecting all connections
EndpointStats
Statistics on Endpoint activity
FrameStats
Number of frames transmitted or received of each frame type.
IdleTimeout
Maximum duration of inactivity to accept before timing out the connection
Incoming
An incoming connection for which the server has not yet begun its part of the handshake
IncomingFuture
Basic adapter to let Incoming be await-ed like a Connecting
InvalidCid
The connection ID was not recognized by the ConnectionIdGenerator
Lagged
The receiver lagged too far behind.
MtuDiscoveryConfig
Parameters governing MTU discovery.
NatTraversalUpdates
A stream of NAT traversal updates for a connection.
NoneTokenLog
Null implementation of TokenLog, which never accepts tokens
NoneTokenStore
Null implementation of TokenStore, which does not store any tokens
ObservedExternalAddr
Watches the external address reported by the peer for this connection.
OnClosed
Future returned by Connection::on_closed
OpenBi
Future produced by Connection::open_bi
OpenPath
Future produced by crate::Connection::open_path
OpenUni
Future produced by Connection::open_uni
Path
An open network transmission within a multipath-enabled connection.
PathEvents
A stream of PathEvents for all paths in a connection.
PathId
Id representing different paths when using multipath extension
PathStats
Statistics related to a transmission path.
QlogConfig
Configuration for qlog trace logging.
QlogFileFactory
Enables writing qlog traces to a directory.
ReadDatagram
Future produced by Connection::read_datagram
RecvStream
A stream that can only be used to receive data
RetryError
Error for attempting to retry an Incoming which already bears a token from a previous retry
SendDatagram
Future produced by Connection::send_datagram_wait
SendStream
A stream that can only be used to send data
ServerConfig
Parameters governing incoming connections
SmolRuntime
A noq runtime for smol
StdSystemTime
Default implementation of TimeSource
Stopped
Future returned from SendStream::stopped.
StreamId
Identifier for a stream within a particular connection
TokenMemoryCache
TokenStore implementation that stores up to N tokens per server name for up to a limited number of server names, in-memory
TokenReuseError
Error for when a validation token may have been reused
TokioRuntime
A noq runtime for Tokio
Transmit
An outgoing packet
TransportConfig
Parameters governing the core QUIC state machine
TransportErrorCode
Transport-level error code
UdpStats
Statistics about UDP datagrams transmitted or received on a connection.
UnorderedRecvStream
A stream that can be used to receive data out-of-order.
ValidationTokenConfig
Configuration for sending and handling validation tokens in incoming connections
VarInt
An integer less than 2^62
VarIntBoundsExceeded
Error returned when constructing a VarInt from a value >= 2^62
WeakConnectionHandle
A handle to some connection internals, use with care.
WeakPathHandle
Weak handle for a Path that does not keep the connection alive.
Written
Indicates how many bytes and chunks had been transferred in a write operation
ZeroRttAccepted
Future that completes when a connection is fully established

Enums§

ConfigError
Errors in the configuration of an endpoint
ConnectError
Errors in the parameters being used to create a new connection
ConnectionError
Reasons why a connection might be lost
Dir
Whether a stream communicates data in both directions or only from the initiator
EcnCodepoint
Explicit congestion notification codepoint
FrameType
ReadError
Errors that arise from reading from a stream.
ReadExactError
Errors that arise from reading from a stream.
ReadToEndError
Errors from RecvStream::read_to_end
ResetError
Errors that arise while waiting for a stream to be reset
SendDatagramError
Errors that can arise when sending a datagram
Side
Whether an endpoint was the initiator of a connection
StoppedError
Errors that arise while monitoring for a send stream stop from the peer
WriteError
Errors that arise from writing to a stream

Traits§

AsyncTimer
Abstract implementation of an async timer for runtime independence
AsyncUdpSocket
Abstract implementation of a UDP socket for runtime independence
ConnectionIdGenerator
Generates connection IDs for incoming connections
NetworkChangeHint
Hints when the caller identifies a network change.
QlogFactory
Constructs a QlogConfig for individual connections.
Runtime
Abstracts I/O and timer operations for runtime independence
TimeSource
Object to get current SystemTime
TokenLog
Responsible for limiting clients’ ability to reuse validation tokens
TokenStore
Responsible for storing validation tokens received from servers and retrieving them for use in subsequent connections
UdpSender
An object for asynchronously writing to an associated AsyncUdpSocket.

Functions§

default_runtime
Automatically select an appropriate runtime from those enabled at compile time
\ No newline at end of file diff --git a/pr/545/docs/noq/sidebar-items.js b/pr/545/docs/noq/sidebar-items.js index 9f506426c..831f580ce 100644 --- a/pr/545/docs/noq/sidebar-items.js +++ b/pr/545/docs/noq/sidebar-items.js @@ -1 +1 @@ -window.SIDEBAR_ITEMS = {"enum":["ConfigError","ConnectError","ConnectionError","Dir","EcnCodepoint","FrameType","ReadError","ReadExactError","ReadToEndError","ResetError","SendDatagramError","Side","StoppedError","WriteError"],"fn":["default_runtime"],"mod":["congestion","crypto"],"struct":["Accept","AcceptBi","AcceptUni","AckFrequencyConfig","AddressDiscovery","ApplicationClose","BloomTokenLog","Chunk","ClientConfig","ClosedStream","Connecting","Connection","ConnectionClose","ConnectionId","ConnectionStats","Endpoint","EndpointConfig","EndpointStats","FrameStats","IdleTimeout","Incoming","IncomingFuture","InvalidCid","MtuDiscoveryConfig","NoneTokenLog","NoneTokenStore","OnClosed","OpenBi","OpenPath","OpenUni","Path","PathId","PathStats","QlogConfig","QlogFileFactory","ReadDatagram","RecvStream","RetryError","SendDatagram","SendStream","ServerConfig","SmolRuntime","StdSystemTime","Stopped","StreamId","TokenMemoryCache","TokenReuseError","TokioRuntime","Transmit","TransportConfig","TransportErrorCode","UdpStats","UnorderedRecvStream","ValidationTokenConfig","VarInt","VarIntBoundsExceeded","WeakConnectionHandle","WeakPathHandle","Written","ZeroRttAccepted"],"trait":["AsyncTimer","AsyncUdpSocket","ConnectionIdGenerator","NetworkChangeHint","QlogFactory","Runtime","TimeSource","TokenLog","TokenStore","UdpSender"]}; \ No newline at end of file +window.SIDEBAR_ITEMS = {"enum":["ConfigError","ConnectError","ConnectionError","Dir","EcnCodepoint","FrameType","ReadError","ReadExactError","ReadToEndError","ResetError","SendDatagramError","Side","StoppedError","WriteError"],"fn":["default_runtime"],"mod":["congestion","crypto"],"struct":["Accept","AcceptBi","AcceptUni","AckFrequencyConfig","AddressDiscovery","ApplicationClose","BloomTokenLog","Chunk","ClientConfig","ClosedStream","Connecting","Connection","ConnectionClose","ConnectionId","ConnectionStats","Endpoint","EndpointConfig","EndpointStats","FrameStats","IdleTimeout","Incoming","IncomingFuture","InvalidCid","Lagged","MtuDiscoveryConfig","NatTraversalUpdates","NoneTokenLog","NoneTokenStore","ObservedExternalAddr","OnClosed","OpenBi","OpenPath","OpenUni","Path","PathEvents","PathId","PathStats","QlogConfig","QlogFileFactory","ReadDatagram","RecvStream","RetryError","SendDatagram","SendStream","ServerConfig","SmolRuntime","StdSystemTime","Stopped","StreamId","TokenMemoryCache","TokenReuseError","TokioRuntime","Transmit","TransportConfig","TransportErrorCode","UdpStats","UnorderedRecvStream","ValidationTokenConfig","VarInt","VarIntBoundsExceeded","WeakConnectionHandle","WeakPathHandle","Written","ZeroRttAccepted"],"trait":["AsyncTimer","AsyncUdpSocket","ConnectionIdGenerator","NetworkChangeHint","QlogFactory","Runtime","TimeSource","TokenLog","TokenStore","UdpSender"]}; \ No newline at end of file diff --git a/pr/545/docs/noq/struct.AcceptBi.html b/pr/545/docs/noq/struct.AcceptBi.html index 792b03cea..180bbe0f8 100644 --- a/pr/545/docs/noq/struct.AcceptBi.html +++ b/pr/545/docs/noq/struct.AcceptBi.html @@ -1,6 +1,6 @@ -AcceptBi in noq - Rust

AcceptBi

Struct AcceptBi 

Source
pub struct AcceptBi<'a> { /* private fields */ }
Expand description

Future produced by Connection::accept_bi

-

Trait Implementations§

Source§

impl Future for AcceptBi<'_>

Source§

type Output = Result<(SendStream, RecvStream), ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for AcceptBi<'a>
where +AcceptBi in noq - Rust

AcceptBi

Struct AcceptBi 

Source
pub struct AcceptBi<'a> { /* private fields */ }
Expand description

Future produced by Connection::accept_bi

+

Trait Implementations§

Source§

impl Future for AcceptBi<'_>

Source§

type Output = Result<(SendStream, RecvStream), ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for AcceptBi<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for AcceptBi<'a>

§

impl<'a> !RefUnwindSafe for AcceptBi<'a>

§

impl<'a> Send for AcceptBi<'a>

§

impl<'a> Sync for AcceptBi<'a>

§

impl<'a> !UnwindSafe for AcceptBi<'a>

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/545/docs/noq/struct.AcceptUni.html b/pr/545/docs/noq/struct.AcceptUni.html index b6a80f534..0e6b55eaa 100644 --- a/pr/545/docs/noq/struct.AcceptUni.html +++ b/pr/545/docs/noq/struct.AcceptUni.html @@ -1,6 +1,6 @@ -AcceptUni in noq - Rust

AcceptUni

Struct AcceptUni 

Source
pub struct AcceptUni<'a> { /* private fields */ }
Expand description

Future produced by Connection::accept_uni

-

Trait Implementations§

Source§

impl Future for AcceptUni<'_>

Source§

type Output = Result<RecvStream, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for AcceptUni<'a>
where +AcceptUni in noq - Rust

AcceptUni

Struct AcceptUni 

Source
pub struct AcceptUni<'a> { /* private fields */ }
Expand description

Future produced by Connection::accept_uni

+

Trait Implementations§

Source§

impl Future for AcceptUni<'_>

Source§

type Output = Result<RecvStream, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for AcceptUni<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for AcceptUni<'a>

§

impl<'a> !RefUnwindSafe for AcceptUni<'a>

§

impl<'a> Send for AcceptUni<'a>

§

impl<'a> Sync for AcceptUni<'a>

§

impl<'a> !UnwindSafe for AcceptUni<'a>

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/545/docs/noq/struct.AddressDiscovery.html b/pr/545/docs/noq/struct.AddressDiscovery.html index f5148c46b..f4b48f499 100644 --- a/pr/545/docs/noq/struct.AddressDiscovery.html +++ b/pr/545/docs/noq/struct.AddressDiscovery.html @@ -1,7 +1,7 @@ -AddressDiscovery in noq - Rust

AddressDiscovery

Struct AddressDiscovery 

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

Stream produced by Path::observed_external_addr

+AddressDiscovery in noq - Rust

AddressDiscovery

Struct AddressDiscovery 

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

Stream produced by Path::observed_external_addr

This will always return the external address most recently reported by the remote over this path. If the extension is not negotiated, this stream will never return.

-

Trait Implementations§

Source§

impl Stream for AddressDiscovery

Source§

type Item = SocketAddr

Values yielded by the stream.
Source§

fn poll_next( +

Trait Implementations§

Source§

impl Stream for AddressDiscovery

Source§

type Item = SocketAddr

Values yielded by the stream.
Source§

fn poll_next( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the diff --git a/pr/545/docs/noq/struct.ClosedStream.html b/pr/545/docs/noq/struct.ClosedStream.html index 8eb864ca2..0453153c1 100644 --- a/pr/545/docs/noq/struct.ClosedStream.html +++ b/pr/545/docs/noq/struct.ClosedStream.html @@ -1,5 +1,5 @@ ClosedStream in noq - Rust

ClosedStream

Struct ClosedStream 

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

Error indicating that a stream has not been opened or has already been finished or reset

-

Trait Implementations§

Source§

impl Clone for ClosedStream

Source§

fn clone(&self) -> ClosedStream

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 ClosedStream

Source§

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

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

impl Default for ClosedStream

Source§

fn default() -> ClosedStream

Returns the “default value” for a type. Read more
Source§

impl Display for ClosedStream

Source§

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

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

impl Error for ClosedStream

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<ClosedStream> for WriteError

Source§

fn from(_: ClosedStream) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for ClosedStream

Source§

fn eq(&self, other: &ClosedStream) -> 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 ClosedStream

Source§

fn clone(&self) -> ClosedStream

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 ClosedStream

Source§

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

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

impl Default for ClosedStream

Source§

fn default() -> ClosedStream

Returns the “default value” for a type. Read more
Source§

impl Display for ClosedStream

Source§

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

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

impl Error for ClosedStream

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<ClosedStream> for WriteError

Source§

fn from(_: ClosedStream) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for ClosedStream

Source§

fn eq(&self, other: &ClosedStream) -> 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 ClosedStream

Source§

impl StructuralPartialEq for ClosedStream

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/545/docs/noq/struct.Connecting.html b/pr/545/docs/noq/struct.Connecting.html index 313d9b851..347289200 100644 --- a/pr/545/docs/noq/struct.Connecting.html +++ b/pr/545/docs/noq/struct.Connecting.html @@ -1,5 +1,5 @@ Connecting in noq - Rust

Connecting

Struct Connecting 

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

In-progress connection attempt future

-

Implementations§

Source§

impl Connecting

Source

pub fn into_0rtt(self) -> Result<(Connection, ZeroRttAccepted), Self>

Convert into a 0-RTT or 0.5-RTT connection at the cost of weakened security

+

Implementations§

Source§

impl Connecting

Source

pub fn into_0rtt(self) -> Result<(Connection, ZeroRttAccepted), Self>

Convert into a 0-RTT or 0.5-RTT connection at the cost of weakened security

Returns Ok immediately if the local endpoint is able to attempt sending 0/0.5-RTT data. If so, the returned Connection can be used to send application data without waiting for the rest of the handshake to complete, at the cost of weakened cryptographic security @@ -45,9 +45,9 @@ the endpoint is bound to a wildcard address like 0.0.0.0 or : information. See noq_udp::RecvMeta::dst_ip for a list of supported platforms when using noq_udp for I/O, which is the default.

Will panic if called after poll has returned Ready.

-
Source

pub fn remote_address(&self) -> SocketAddr

The peer’s UDP addresses

+
Source

pub fn remote_address(&self) -> SocketAddr

The peer’s UDP addresses

Will panic if called after poll has returned Ready.

-

Trait Implementations§

Source§

impl Debug for Connecting

Source§

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

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

impl Future for Connecting

Source§

type Output = Result<Connection, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +

Trait Implementations§

Source§

impl Debug for Connecting

Source§

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

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

impl Future for Connecting

Source§

type Output = Result<Connection, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

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/545/docs/noq/struct.Connection.html b/pr/545/docs/noq/struct.Connection.html index 0e5eafb54..7a59936d7 100644 --- a/pr/545/docs/noq/struct.Connection.html +++ b/pr/545/docs/noq/struct.Connection.html @@ -1,4 +1,4 @@ -Connection in noq - Rust

Connection

Struct Connection 

Source
pub struct Connection(/* private fields */);
Expand description

A QUIC connection.

+Connection in noq - Rust

Connection

Struct Connection 

Source
pub struct Connection(/* private fields */);
Expand description

A QUIC connection.

If all references to a connection (including every clone of the Connection handle, streams of incoming streams, and the various stream types) have been dropped, then the connection will be automatically closed with an error_code of 0 and an empty reason. You can also close the @@ -8,29 +8,29 @@ receiving CONNECTION_CLOSE the peer may drop any stream data not yet de application. Connection::close() describes in more detail how to gracefully close a connection without losing application data.

May be cloned to obtain another handle to the same connection.

-

Implementations§

Source§

impl Connection

Source

pub fn weak_handle(&self) -> WeakConnectionHandle

Returns a weak reference to the inner connection struct.

-
Source

pub fn open_uni(&self) -> OpenUni<'_> ⓘ

Initiate a new outgoing unidirectional stream.

+

Implementations§

Source§

impl Connection

Source

pub fn weak_handle(&self) -> WeakConnectionHandle

Returns a weak reference to the inner connection struct.

+
Source

pub fn open_uni(&self) -> OpenUni<'_> ⓘ

Initiate a new outgoing unidirectional stream.

Streams are cheap and instantaneous to open unless blocked by flow control. As a consequence, the peer won’t be notified that a stream has been opened until the stream is actually used.

-
Source

pub fn open_bi(&self) -> OpenBi<'_> ⓘ

Initiate a new outgoing bidirectional stream.

+
Source

pub fn open_bi(&self) -> OpenBi<'_> ⓘ

Initiate a new outgoing bidirectional stream.

Streams are cheap and instantaneous to open unless blocked by flow control. As a consequence, the peer won’t be notified that a stream has been opened until the stream is actually used. Calling open_bi() then waiting on the RecvStream without writing anything to SendStream will never succeed.

-
Source

pub fn accept_uni(&self) -> AcceptUni<'_> ⓘ

Accept the next incoming uni-directional stream

-
Source

pub fn accept_bi(&self) -> AcceptBi<'_> ⓘ

Accept the next incoming bidirectional stream

+
Source

pub fn accept_uni(&self) -> AcceptUni<'_> ⓘ

Accept the next incoming uni-directional stream

+
Source

pub fn accept_bi(&self) -> AcceptBi<'_> ⓘ

Accept the next incoming bidirectional stream

Important Note: The Connection that calls open_bi() must write to its SendStream before the other Connection is able to accept_bi(). Calling open_bi() then waiting on the RecvStream without writing anything to SendStream will never succeed.

-
Source

pub fn read_datagram(&self) -> ReadDatagram<'_> ⓘ

Receive an application datagram

-
Source

pub fn open_path_ensure( +

Source

pub fn read_datagram(&self) -> ReadDatagram<'_> ⓘ

Receive an application datagram

+
Source

pub fn open_path_ensure( &self, addr: SocketAddr, initial_status: PathStatus, ) -> OpenPath ⓘ

Opens a new path if no path exists yet for the remote address.

Otherwise behaves exactly as open_path.

-
Source

pub fn open_path( +

Source

pub fn open_path( &self, addr: SocketAddr, initial_status: PathStatus, @@ -45,23 +45,30 @@ path opens. The P future, or at a later time. If the failure is immediate OpenPath::path_id will return None and the future will be ready immediately. If the failure happens later, a PathEvent will be emitted.

-

Source

pub fn path(&self, id: PathId) -> Option<Path>

Returns the Path structure of an open path

-
Source

pub fn path_events(&self) -> Receiver<PathEvent>

A broadcast receiver of PathEvents for all paths in this connection

-
Source

pub fn nat_traversal_updates(&self) -> Receiver<Event>

A broadcast receiver of n0_nat_traversal::Events for updates about server addresses

-
Source

pub async fn closed(&self) -> ConnectionError

Wait for the connection to be closed for any reason

+
Source

pub fn path(&self, id: PathId) -> Option<Path>

Returns the Path structure of an open path

+
Source

pub fn path_events(&self) -> PathEvents

A stream of PathEvents for all paths in this connection.

+

The stream will yield a PathEvent whenever there is a change in the state of any path in this connection. +The events need to be processed immediately, since there isn’t an unbounded buffer for them.

+

If processing of events lags behind too much, you will get an error of type crate::Lagged indicating +how many events were lost. The stream continues after a lag, delivering the oldest retained message next.

+
Source

pub fn nat_traversal_updates(&self) -> NatTraversalUpdates

A stream of NAT traversal updates for this connection.

+

The events need to be processed immediately, since there isn’t an unbounded buffer for them.

+

If processing of events lags behind too much, you will get an error of type crate::Lagged indicating +how many events were lost. The stream continues after a lag, delivering the oldest retained message next.

+
Source

pub async fn closed(&self) -> ConnectionError

Wait for the connection to be closed for any reason

Despite the return type’s name, closed connections are often not an error condition at the application layer. Cases that might be routine include ConnectionError::LocallyClosed and ConnectionError::ApplicationClosed.

-
Source

pub fn on_closed(&self) -> OnClosed ⓘ

Wait for the connection to be closed without keeping a strong reference to the connection

+
Source

pub fn on_closed(&self) -> OnClosed ⓘ

Wait for the connection to be closed without keeping a strong reference to the connection

Returns a future that resolves, once the connection is closed, to a tuple of (ConnectionError, ConnectionStats).

Calling Self::closed keeps the connection alive until it is either closed locally via Connection::close or closed by the remote peer. This function instead does not keep the connection itself alive, so if all other clones of the connection are dropped, the connection will be closed implicitly even if there are futures returned from this function still being awaited.

-
Source

pub fn close_reason(&self) -> Option<ConnectionError>

If the connection is closed, the reason why.

+
Source

pub fn close_reason(&self) -> Option<ConnectionError>

If the connection is closed, the reason why.

Returns None if the connection is still open.

-
Source

pub fn close(&self, error_code: VarInt, reason: &[u8])

Close the connection immediately.

+
Source

pub fn close(&self, error_code: VarInt, reason: &[u8])

Close the connection immediately.

Pending operations will fail immediately with ConnectionError::LocallyClosed. No more data is sent to the peer and the peer may drop buffered data upon receiving the CONNECTION_CLOSE frame.

@@ -82,7 +89,7 @@ endpoint. Once the local side sends a CONNECTION_CLOSE frame in response to call close() the remote endpoint may drop any data it received but is as yet undelivered to the application, including data that was acknowledged as received to the local endpoint.

-
Source

pub async fn handshake_confirmed(&self) -> Result<(), ConnectionError>

Wait for the handshake to be confirmed.

+
Source

pub async fn handshake_confirmed(&self) -> Result<(), ConnectionError>

Wait for the handshake to be confirmed.

As a server, who must be authenticated by clients, this happens when the handshake completes upon receiving a TLS Finished message from the client. @@ -90,56 +97,56 @@ In return, the server send a HANDSHAKE_DONE frame.

As a client, this happens when receiving a HANDSHAKE_DONE frame. At this point, the server has either accepted our authentication, or, if client authentication is not required, accepted our lack of authentication.

-
Source

pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError>

Transmit data as an unreliable, unordered application datagram

+
Source

pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError>

Transmit data as an unreliable, unordered application datagram

Application datagrams are a low-level primitive. They may be lost or delivered out of order, and data must both fit inside a single QUIC packet and be smaller than the maximum dictated by the peer.

Previously queued datagrams which are still unsent may be discarded to make space for this datagram, in order of oldest to newest.

-
Source

pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_> ⓘ

Transmit data as an unreliable, unordered application datagram

+
Source

pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_> ⓘ

Transmit data as an unreliable, unordered application datagram

Unlike send_datagram(), this method will wait for buffer space during congestion conditions, which effectively prioritizes old datagrams over new datagrams.

See send_datagram() for details.

-
Source

pub fn max_datagram_size(&self) -> Option<usize>

Compute the maximum size of datagrams that may be passed to send_datagram().

+
Source

pub fn max_datagram_size(&self) -> Option<usize>

Compute the maximum size of datagrams that may be passed to send_datagram().

Returns None if datagrams are unsupported by the peer or disabled locally.

This may change over the lifetime of a connection according to variation in the path MTU estimate. The peer can also enforce an arbitrarily small fixed limit, but if the peer’s limit is large this is guaranteed to be a little over a kilobyte at minimum.

Not necessarily the maximum size of received datagrams.

-
Source

pub fn datagram_send_buffer_space(&self) -> usize

Bytes available in the outgoing datagram buffer

+
Source

pub fn datagram_send_buffer_space(&self) -> usize

Bytes available in the outgoing datagram buffer

When greater than zero, calling send_datagram() with a datagram of at most this size is guaranteed not to cause older datagrams to be dropped.

-
Source

pub fn side(&self) -> Side

The side of the connection (client or server)

-
Source

pub fn remote_address(&self) -> SocketAddr

The peer’s UDP address

+
Source

pub fn side(&self) -> Side

The side of the connection (client or server)

+
Source

pub fn remote_address(&self) -> SocketAddr

The peer’s UDP address

If ServerConfig::migration is true, clients may change addresses at will, e.g. when switching to a cellular internet connection.

If multipath is enabled this will return the address of any path, and may not be consistent. Prefer Path::remote_address instead.

-
Source

pub fn local_ip(&self) -> Option<IpAddr>

The local IP address which was used when the peer established +

Source

pub fn local_ip(&self) -> Option<IpAddr>

The local IP address which was used when the peer established the connection

This can be different from the address the endpoint is bound to, in case the endpoint is bound to a wildcard address like 0.0.0.0 or ::.

This will return None for clients, or when the platform does not expose this information. See noq_udp::RecvMeta::dst_ip for a list of supported platforms when using noq_udp for I/O, which is the default.

-
Source

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

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

-
Source

pub fn stats(&self) -> ConnectionStats

Returns connection statistics

-
Source

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

Returns path statistics

-
Source

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

Current state of the congestion control algorithm, for debugging purposes

-
Source

pub fn handshake_data(&self) -> Option<Box<dyn Any>>

Parameters negotiated during the handshake

+
Source

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

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

+
Source

pub fn stats(&self) -> ConnectionStats

Returns connection statistics

+
Source

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

Returns path statistics

+
Source

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

Current state of the congestion control algorithm, for debugging purposes

+
Source

pub fn handshake_data(&self) -> Option<Box<dyn Any>>

Parameters negotiated during the handshake

Guaranteed to return Some on fully established connections or after Connecting::handshake_data() succeeds. See that method’s documentations for details on the returned value.

-
Source

pub fn peer_identity(&self) -> Option<Box<dyn Any>>

Cryptographic identity of the peer

+
Source

pub fn peer_identity(&self) -> Option<Box<dyn Any>>

Cryptographic identity of the peer

The dynamic type returned is determined by the configured Session. For the default rustls session, the return value can be downcast to a Vec<[rustls::pki_types::CertificateDer]>

-
Source

pub fn stable_id(&self) -> usize

A stable identifier for this connection

+
Source

pub fn stable_id(&self) -> usize

A stable identifier for this connection

Peer addresses and connection IDs can change, but this value will remain fixed for the lifetime of the connection.

-
Source

pub fn force_key_update(&self)

Update traffic keys spontaneously

+
Source

pub fn force_key_update(&self)

Update traffic keys spontaneously

This primarily exists for testing purposes.

-
Source

pub fn export_keying_material( +

Source

pub fn export_keying_material( &self, output: &mut [u8], label: &[u8], @@ -150,17 +157,17 @@ arguments and output buffers of equal length, they will get the same sequence of bytes in output. These bytes are cryptographically strong and pseudorandom, and are suitable for use as keying material.

See RFC5705 for more information.

-

Source

pub fn set_max_concurrent_uni_streams(&self, count: VarInt)

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

+
Source

pub fn set_max_concurrent_uni_streams(&self, count: VarInt)

Modify the number of remotely initiated unidirectional 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_send_window(&self, send_window: u64)

Source

pub fn set_receive_window(&self, receive_window: VarInt)

Source

pub fn set_max_concurrent_bi_streams(&self, count: VarInt)

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

+
Source

pub fn set_send_window(&self, send_window: u64)

Source

pub fn set_receive_window(&self, receive_window: VarInt)

Source

pub fn set_max_concurrent_bi_streams(&self, count: VarInt)

Modify the number of remotely initiated bidirectional 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 observed_external_addr(&self) -> Receiver<Option<SocketAddr>>

Track changed on our external address as reported by the peer.

+
Source

pub fn observed_external_addr(&self) -> ObservedExternalAddr

Track changes on our external address as reported by the peer.

Source

pub fn is_multipath_enabled(&self) -> bool

Is multipath enabled?

-
Source

pub fn add_nat_traversal_address( +

Source

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

Registers one address at which this endpoint might be reachable

@@ -168,7 +175,7 @@ strong and pseudorandom, and are suitable for use as keying material.

ADD_ADDRESS frames. This allows clients to obtain server address candidates to initiate NAT traversal attempts. Clients provide their own reachable addresses in REACH_OUT frames when Self::initiate_nat_traversal_round is called.

-
Source

pub fn remove_nat_traversal_address( +

Source

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

Removes one or more addresses from the set of addresses at which this endpoint is reachable

@@ -177,18 +184,18 @@ clients in REMOVE_ADDRESS frames. This allows clients to stop using server address candidates that are no longer valid for NAT traversal.

For clients, removed addresses will no longer be advertised in REACH_OUT frames.

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(&self) -> Result<Vec<SocketAddr>, Error>

Initiates a new nat traversal round

+
Source

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

Initiates a new nat traversal round

A nat traversal round involves advertising the client’s local addresses in REACH_OUT frames, and initiating probing of the known remote addresses. When a new round is initiated, the previous one is cancelled, and paths that have not been opened are closed.

Returns the server addresses that are now being probed.

-

Trait Implementations§

Source§

impl Clone for Connection

Source§

fn clone(&self) -> Connection

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 Connection

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for Connection

Source§

fn clone(&self) -> Connection

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 Connection

Source§

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

Formats the value using the given formatter. Read more

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/545/docs/noq/struct.Lagged.html b/pr/545/docs/noq/struct.Lagged.html new file mode 100644 index 000000000..711b8f45f --- /dev/null +++ b/pr/545/docs/noq/struct.Lagged.html @@ -0,0 +1,34 @@ +Lagged in noq - Rust

Lagged

Struct Lagged 

Source
pub struct Lagged(pub u64);
Expand description

The receiver lagged too far behind.

+

Attempting to receive again will return the oldest message still retained +by the channel.

+

Tuple Fields§

§0: u64

Trait Implementations§

Source§

impl Clone for Lagged

Source§

fn clone(&self) -> Lagged

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 Lagged

Source§

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

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

impl Display for Lagged

Source§

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

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

impl Error for Lagged

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 Lagged

Source§

fn eq(&self, other: &Lagged) -> 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 Lagged

Source§

impl StructuralPartialEq for Lagged

Auto Trait Implementations§

§

impl Freeze for Lagged

§

impl RefUnwindSafe for Lagged

§

impl Send for Lagged

§

impl Sync for Lagged

§

impl Unpin for Lagged

§

impl UnwindSafe for Lagged

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 + T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where + U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> +if into_left is true. +Converts self into a Right variant of Either<Self, Self> +otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where + F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> +if into_left(&self) returns true. +Converts self into a Right variant of Either<Self, Self> +otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where + T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where + T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/pr/545/docs/noq/struct.NatTraversalUpdates.html b/pr/545/docs/noq/struct.NatTraversalUpdates.html new file mode 100644 index 000000000..d28398c9b --- /dev/null +++ b/pr/545/docs/noq/struct.NatTraversalUpdates.html @@ -0,0 +1,174 @@ +NatTraversalUpdates in noq - Rust

NatTraversalUpdates

Struct NatTraversalUpdates 

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

A stream of NAT traversal updates for a connection.

+

Trait Implementations§

Source§

impl Debug for NatTraversalUpdates

Source§

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

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

impl Stream for NatTraversalUpdates

Source§

type Item = Result<Event, Lagged>

Values yielded by the stream.
Source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where + U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> +if into_left is true. +Converts self into a Right variant of Either<Self, Self> +otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where + F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> +if into_left(&self) returns true. +Converts self into a Right variant of Either<Self, Self> +otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<S> StreamExt for S
where + S: Stream + ?Sized,

§

fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience for calling [Stream::poll_next()] on !Unpin types.
§

fn next(&mut self) -> NextFuture<'_, Self>
where + Self: Unpin,

Retrieves the next item in the stream. Read more
§

fn try_next<T, E>(&mut self) -> TryNextFuture<'_, Self>
where + Self: Stream<Item = Result<T, E>> + Unpin,

Retrieves the next item in the stream. Read more
§

fn count(self) -> CountFuture<Self>
where + Self: Sized,

Counts the number of items in the stream. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> T,

Maps items of the stream to new values using a closure. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: Stream, + F: FnMut(Self::Item) -> U,

Maps items to streams and then concatenates them. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self: Sized, + Self::Item: Stream,

Concatenates inner streams. Read more
§

fn then<F, Fut>(self, f: F) -> Then<Self, F, Fut>
where + Self: Sized, + F: FnMut(Self::Item) -> Fut, + Fut: Future,

Maps items of the stream to new values using an async closure. Read more
§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Keeps items of the stream for which predicate returns true. Read more
§

fn filter_map<T, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<T>,

Filters and maps items of the stream using a closure. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Takes only the first n items of the stream. Read more
§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Takes items while predicate returns true. Read more
§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Maps items while predicate returns Some. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Skips the first n items of the stream. Read more
§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Skips items while predicate returns true. Read more
§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Yields every stepth item. Read more
§

fn chain<U>(self, other: U) -> Chain<Self, U>
where + Self: Sized, + U: Stream<Item = Self::Item>,

Appends another stream to the end of this one. Read more
§

fn cloned<'a, T>(self) -> Cloned<Self>
where + Self: Sized + Stream<Item = &'a T>, + T: Clone + 'a,

Clones all items. Read more
§

fn copied<'a, T>(self) -> Copied<Self>
where + Self: Sized + Stream<Item = &'a T>, + T: Copy + 'a,

Copies all items. Read more
§

fn collect<C>(self) -> CollectFuture<Self, C>
where + Self: Sized, + C: Default + Extend<Self::Item>,

Collects all items in the stream into a collection. Read more
§

fn try_collect<T, E, C>(self) -> TryCollectFuture<Self, C>
where + Self: Sized + Stream<Item = Result<T, E>>, + C: Default + Extend<T>,

Collects all items in the fallible stream into a collection. Read more
§

fn partition<B, P>(self, predicate: P) -> PartitionFuture<Self, P, B>
where + Self: Sized, + B: Default + Extend<Self::Item>, + P: FnMut(&Self::Item) -> bool,

Partitions items into those for which predicate is true and those for which it is +false, and then collects them into two collections. Read more
§

fn fold<T, F>(self, init: T, f: F) -> FoldFuture<Self, F, T>
where + Self: Sized, + F: FnMut(T, Self::Item) -> T,

Accumulates a computation over the stream. Read more
§

fn try_fold<T, E, F, B>( + &mut self, + init: B, + f: F, +) -> TryFoldFuture<'_, Self, F, B>
where + Self: Sized + Stream<Item = Result<T, E>> + Unpin, + F: FnMut(B, T) -> Result<B, E>,

Accumulates a fallible computation over the stream. Read more
§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

Maps items of the stream to new values using a state value and a closure. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuses the stream so that it stops yielding items after the first None. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats the stream from beginning to end, forever. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Enumerates items, mapping them to (index, item). Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Calls a closure on each item and passes it on. Read more
§

fn nth(&mut self, n: usize) -> NthFuture<'_, Self>
where + Self: Unpin,

Gets the nth item of the stream. Read more
§

fn last(self) -> LastFuture<Self>
where + Self: Sized,

Returns the last item in the stream. Read more
§

fn find<P>(&mut self, predicate: P) -> FindFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(&Self::Item) -> bool,

Finds the first item of the stream for which predicate returns true. Read more
§

fn find_map<F, B>(&mut self, f: F) -> FindMapFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> Option<B>,

Applies a closure to items in the stream and returns the first Some result. Read more
§

fn position<P>(&mut self, predicate: P) -> PositionFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Finds the index of the first item of the stream for which predicate returns true. Read more
§

fn all<P>(&mut self, predicate: P) -> AllFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Tests if predicate returns true for all items in the stream. Read more
§

fn any<P>(&mut self, predicate: P) -> AnyFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Tests if predicate returns true for any item in the stream. Read more
§

fn for_each<F>(self, f: F) -> ForEachFuture<Self, F>
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each item of the stream. Read more
§

fn try_for_each<F, E>(&mut self, f: F) -> TryForEachFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> Result<(), E>,

Calls a fallible closure on each item of the stream, stopping on first error. Read more
§

fn zip<U>(self, other: U) -> Zip<Self, U>
where + Self: Sized, + U: Stream,

Zips up two streams into a single stream of pairs. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> UnzipFuture<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Collects a stream of pairs into a pair of collections. Read more
§

fn or<S>(self, other: S) -> Or<Self, S>
where + Self: Sized, + S: Stream<Item = Self::Item>,

Merges with other stream, preferring items from self whenever both streams are ready. Read more
§

fn race<S>(self, other: S) -> Race<Self, S>
where + Self: Sized, + S: Stream<Item = Self::Item>,

Merges with other stream, with no preference for either stream when both are ready. Read more
§

fn drain(&mut self) -> Drain<'_, Self>

Yields all immediately available values from a stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Boxes the stream and changes its type to dyn Stream + Send + 'a. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Boxes the stream and changes its type to dyn Stream + 'a. Read more
§

impl<St> StreamExt for St
where + St: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Consumes and returns the next value in the stream or None if the +stream is finished. Read more
§

fn try_next<T, E>(&mut self) -> TryNext<'_, Self>
where + Self: Stream<Item = Result<T, E>> + Unpin,

Consumes and returns the next item in the stream. If an error is +encountered before the next item, the error is returned instead. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn map_while<T, F>(self, f: F) -> MapWhile<Self, F>
where + F: FnMut(Self::Item) -> Option<T>, + Self: Sized,

Map this stream’s items to a different type for as long as determined by +the provided closure. A stream of the target type will be returned, +which will yield elements until the closure returns None. Read more
§

fn then<F, Fut>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Maps this stream’s items asynchronously to a different type, returning a +new stream of the resulting type. Read more
§

fn merge<U>(self, other: U) -> Merge<Self, U>
where + U: Stream<Item = Self::Item>, + Self: Sized,

Combine two streams into one by interleaving the output of both as it +is produced. Read more
§

fn filter<F>(self, f: F) -> Filter<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Filters the values produced by this stream according to the provided +predicate. Read more
§

fn filter_map<T, F>(self, f: F) -> FilterMap<Self, F>
where + F: FnMut(Self::Item) -> Option<T>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided closure. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates a stream which ends after the first None. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn take_while<F>(self, f: F) -> TakeWhile<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Take elements from this stream while the provided predicate +resolves to true. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream that will skip the n first items of the +underlying stream. Read more
§

fn skip_while<F>(self, f: F) -> SkipWhile<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Skip elements from the underlying stream while the provided predicate +resolves to true. Read more
§

fn all<F>(&mut self, f: F) -> AllFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> bool,

Tests if every element of the stream matches a predicate. Read more
§

fn any<F>(&mut self, f: F) -> AnyFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> bool,

Tests if any element of the stream matches a predicate. Read more
§

fn chain<U>(self, other: U) -> Chain<Self, U>
where + U: Stream<Item = Self::Item>, + Self: Sized,

Combine two streams into one by first returning all values from the +first stream then all values from the second stream. Read more
§

fn fold<B, F>(self, init: B, f: F) -> FoldFuture<Self, B, F>
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

A combinator that applies a function to every element in a stream +producing a single, final value. Read more
§

fn collect<T>(self) -> Collect<Self, T>
where + T: FromStream<Self::Item>, + Self: Sized,

Drain stream pushing all emitted values into a collection. Read more
§

fn timeout(self, duration: Duration) -> Timeout<Self>
where + Self: Sized,

Applies a per-item timeout to the passed stream. Read more
§

fn timeout_repeating(self, interval: Interval) -> TimeoutRepeating<Self>
where + Self: Sized,

Applies a per-item timeout to the passed stream. Read more
§

fn throttle(self, duration: Duration) -> Throttle<Self>
where + Self: Sized,

Slows down a stream by enforcing a delay between items. Read more
§

fn chunks_timeout( + self, + max_size: usize, + duration: Duration, +) -> ChunksTimeout<Self>
where + Self: Sized,

Batches the items in the given stream using a maximum duration and size for each batch. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Turns the stream into a peekable stream, whose next element can be peeked at without being +consumed. Read more
Source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = Result<T, E>> + ?Sized,

§

type Ok = T

The type of successful values yielded by this future
§

type Error = E

The type of failures yielded by this future
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_>, +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/pr/545/docs/noq/struct.ObservedExternalAddr.html b/pr/545/docs/noq/struct.ObservedExternalAddr.html new file mode 100644 index 000000000..7e5f62e37 --- /dev/null +++ b/pr/545/docs/noq/struct.ObservedExternalAddr.html @@ -0,0 +1,175 @@ +ObservedExternalAddr in noq - Rust

ObservedExternalAddr

Struct ObservedExternalAddr 

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

Watches the external address reported by the peer for this connection.

+

Implements [Stream] yielding SocketAddr on each change. +Use get to read the current value without waiting.

+

Implementations§

Source§

impl ObservedExternalAddr

Source

pub fn get(&self) -> Option<SocketAddr>

Returns the most recently observed external address.

+

None is returned if the peer has not yet reported an address. Retains +the last value even after the stream is closed.

+

Trait Implementations§

Source§

impl Debug for ObservedExternalAddr

Source§

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

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

impl Stream for ObservedExternalAddr

Source§

type Item = SocketAddr

Values yielded by the stream.
Source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where + U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> +if into_left is true. +Converts self into a Right variant of Either<Self, Self> +otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where + F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> +if into_left(&self) returns true. +Converts self into a Right variant of Either<Self, Self> +otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<S> StreamExt for S
where + S: Stream + ?Sized,

§

fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience for calling [Stream::poll_next()] on !Unpin types.
§

fn next(&mut self) -> NextFuture<'_, Self>
where + Self: Unpin,

Retrieves the next item in the stream. Read more
§

fn try_next<T, E>(&mut self) -> TryNextFuture<'_, Self>
where + Self: Stream<Item = Result<T, E>> + Unpin,

Retrieves the next item in the stream. Read more
§

fn count(self) -> CountFuture<Self>
where + Self: Sized,

Counts the number of items in the stream. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> T,

Maps items of the stream to new values using a closure. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: Stream, + F: FnMut(Self::Item) -> U,

Maps items to streams and then concatenates them. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self: Sized, + Self::Item: Stream,

Concatenates inner streams. Read more
§

fn then<F, Fut>(self, f: F) -> Then<Self, F, Fut>
where + Self: Sized, + F: FnMut(Self::Item) -> Fut, + Fut: Future,

Maps items of the stream to new values using an async closure. Read more
§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Keeps items of the stream for which predicate returns true. Read more
§

fn filter_map<T, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<T>,

Filters and maps items of the stream using a closure. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Takes only the first n items of the stream. Read more
§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Takes items while predicate returns true. Read more
§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Maps items while predicate returns Some. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Skips the first n items of the stream. Read more
§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Skips items while predicate returns true. Read more
§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Yields every stepth item. Read more
§

fn chain<U>(self, other: U) -> Chain<Self, U>
where + Self: Sized, + U: Stream<Item = Self::Item>,

Appends another stream to the end of this one. Read more
§

fn cloned<'a, T>(self) -> Cloned<Self>
where + Self: Sized + Stream<Item = &'a T>, + T: Clone + 'a,

Clones all items. Read more
§

fn copied<'a, T>(self) -> Copied<Self>
where + Self: Sized + Stream<Item = &'a T>, + T: Copy + 'a,

Copies all items. Read more
§

fn collect<C>(self) -> CollectFuture<Self, C>
where + Self: Sized, + C: Default + Extend<Self::Item>,

Collects all items in the stream into a collection. Read more
§

fn try_collect<T, E, C>(self) -> TryCollectFuture<Self, C>
where + Self: Sized + Stream<Item = Result<T, E>>, + C: Default + Extend<T>,

Collects all items in the fallible stream into a collection. Read more
§

fn partition<B, P>(self, predicate: P) -> PartitionFuture<Self, P, B>
where + Self: Sized, + B: Default + Extend<Self::Item>, + P: FnMut(&Self::Item) -> bool,

Partitions items into those for which predicate is true and those for which it is +false, and then collects them into two collections. Read more
§

fn fold<T, F>(self, init: T, f: F) -> FoldFuture<Self, F, T>
where + Self: Sized, + F: FnMut(T, Self::Item) -> T,

Accumulates a computation over the stream. Read more
§

fn try_fold<T, E, F, B>( + &mut self, + init: B, + f: F, +) -> TryFoldFuture<'_, Self, F, B>
where + Self: Sized + Stream<Item = Result<T, E>> + Unpin, + F: FnMut(B, T) -> Result<B, E>,

Accumulates a fallible computation over the stream. Read more
§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

Maps items of the stream to new values using a state value and a closure. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuses the stream so that it stops yielding items after the first None. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats the stream from beginning to end, forever. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Enumerates items, mapping them to (index, item). Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Calls a closure on each item and passes it on. Read more
§

fn nth(&mut self, n: usize) -> NthFuture<'_, Self>
where + Self: Unpin,

Gets the nth item of the stream. Read more
§

fn last(self) -> LastFuture<Self>
where + Self: Sized,

Returns the last item in the stream. Read more
§

fn find<P>(&mut self, predicate: P) -> FindFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(&Self::Item) -> bool,

Finds the first item of the stream for which predicate returns true. Read more
§

fn find_map<F, B>(&mut self, f: F) -> FindMapFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> Option<B>,

Applies a closure to items in the stream and returns the first Some result. Read more
§

fn position<P>(&mut self, predicate: P) -> PositionFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Finds the index of the first item of the stream for which predicate returns true. Read more
§

fn all<P>(&mut self, predicate: P) -> AllFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Tests if predicate returns true for all items in the stream. Read more
§

fn any<P>(&mut self, predicate: P) -> AnyFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Tests if predicate returns true for any item in the stream. Read more
§

fn for_each<F>(self, f: F) -> ForEachFuture<Self, F>
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each item of the stream. Read more
§

fn try_for_each<F, E>(&mut self, f: F) -> TryForEachFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> Result<(), E>,

Calls a fallible closure on each item of the stream, stopping on first error. Read more
§

fn zip<U>(self, other: U) -> Zip<Self, U>
where + Self: Sized, + U: Stream,

Zips up two streams into a single stream of pairs. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> UnzipFuture<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Collects a stream of pairs into a pair of collections. Read more
§

fn or<S>(self, other: S) -> Or<Self, S>
where + Self: Sized, + S: Stream<Item = Self::Item>,

Merges with other stream, preferring items from self whenever both streams are ready. Read more
§

fn race<S>(self, other: S) -> Race<Self, S>
where + Self: Sized, + S: Stream<Item = Self::Item>,

Merges with other stream, with no preference for either stream when both are ready. Read more
§

fn drain(&mut self) -> Drain<'_, Self>

Yields all immediately available values from a stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Boxes the stream and changes its type to dyn Stream + Send + 'a. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Boxes the stream and changes its type to dyn Stream + 'a. Read more
§

impl<St> StreamExt for St
where + St: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Consumes and returns the next value in the stream or None if the +stream is finished. Read more
§

fn try_next<T, E>(&mut self) -> TryNext<'_, Self>
where + Self: Stream<Item = Result<T, E>> + Unpin,

Consumes and returns the next item in the stream. If an error is +encountered before the next item, the error is returned instead. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn map_while<T, F>(self, f: F) -> MapWhile<Self, F>
where + F: FnMut(Self::Item) -> Option<T>, + Self: Sized,

Map this stream’s items to a different type for as long as determined by +the provided closure. A stream of the target type will be returned, +which will yield elements until the closure returns None. Read more
§

fn then<F, Fut>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Maps this stream’s items asynchronously to a different type, returning a +new stream of the resulting type. Read more
§

fn merge<U>(self, other: U) -> Merge<Self, U>
where + U: Stream<Item = Self::Item>, + Self: Sized,

Combine two streams into one by interleaving the output of both as it +is produced. Read more
§

fn filter<F>(self, f: F) -> Filter<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Filters the values produced by this stream according to the provided +predicate. Read more
§

fn filter_map<T, F>(self, f: F) -> FilterMap<Self, F>
where + F: FnMut(Self::Item) -> Option<T>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided closure. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates a stream which ends after the first None. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn take_while<F>(self, f: F) -> TakeWhile<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Take elements from this stream while the provided predicate +resolves to true. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream that will skip the n first items of the +underlying stream. Read more
§

fn skip_while<F>(self, f: F) -> SkipWhile<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Skip elements from the underlying stream while the provided predicate +resolves to true. Read more
§

fn all<F>(&mut self, f: F) -> AllFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> bool,

Tests if every element of the stream matches a predicate. Read more
§

fn any<F>(&mut self, f: F) -> AnyFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> bool,

Tests if any element of the stream matches a predicate. Read more
§

fn chain<U>(self, other: U) -> Chain<Self, U>
where + U: Stream<Item = Self::Item>, + Self: Sized,

Combine two streams into one by first returning all values from the +first stream then all values from the second stream. Read more
§

fn fold<B, F>(self, init: B, f: F) -> FoldFuture<Self, B, F>
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

A combinator that applies a function to every element in a stream +producing a single, final value. Read more
§

fn collect<T>(self) -> Collect<Self, T>
where + T: FromStream<Self::Item>, + Self: Sized,

Drain stream pushing all emitted values into a collection. Read more
§

fn timeout(self, duration: Duration) -> Timeout<Self>
where + Self: Sized,

Applies a per-item timeout to the passed stream. Read more
§

fn timeout_repeating(self, interval: Interval) -> TimeoutRepeating<Self>
where + Self: Sized,

Applies a per-item timeout to the passed stream. Read more
§

fn throttle(self, duration: Duration) -> Throttle<Self>
where + Self: Sized,

Slows down a stream by enforcing a delay between items. Read more
§

fn chunks_timeout( + self, + max_size: usize, + duration: Duration, +) -> ChunksTimeout<Self>
where + Self: Sized,

Batches the items in the given stream using a maximum duration and size for each batch. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Turns the stream into a peekable stream, whose next element can be peeked at without being +consumed. Read more
Source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/pr/545/docs/noq/struct.OnClosed.html b/pr/545/docs/noq/struct.OnClosed.html index 10305d018..530c1e14e 100644 --- a/pr/545/docs/noq/struct.OnClosed.html +++ b/pr/545/docs/noq/struct.OnClosed.html @@ -1,6 +1,6 @@ -OnClosed in noq - Rust

OnClosed

Struct OnClosed 

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

Future returned by Connection::on_closed

+OnClosed in noq - Rust

OnClosed

Struct OnClosed 

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

Future returned by Connection::on_closed

Resolves to a tuple of (ConnectionError, ConnectionStats).

-

Trait Implementations§

Source§

impl Drop for OnClosed

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Future for OnClosed

Source§

type Output = (ConnectionError, ConnectionStats)

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +

Trait Implementations§

Source§

impl Drop for OnClosed

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Future for OnClosed

Source§

type Output = (ConnectionError, ConnectionStats)

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

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/545/docs/noq/struct.OpenBi.html b/pr/545/docs/noq/struct.OpenBi.html index 3c3e3aae7..c878e5abb 100644 --- a/pr/545/docs/noq/struct.OpenBi.html +++ b/pr/545/docs/noq/struct.OpenBi.html @@ -1,6 +1,6 @@ -OpenBi in noq - Rust

OpenBi

Struct OpenBi 

Source
pub struct OpenBi<'a> { /* private fields */ }
Expand description

Future produced by Connection::open_bi

-

Trait Implementations§

Source§

impl Future for OpenBi<'_>

Source§

type Output = Result<(SendStream, RecvStream), ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for OpenBi<'a>
where +OpenBi in noq - Rust

OpenBi

Struct OpenBi 

Source
pub struct OpenBi<'a> { /* private fields */ }
Expand description

Future produced by Connection::open_bi

+

Trait Implementations§

Source§

impl Future for OpenBi<'_>

Source§

type Output = Result<(SendStream, RecvStream), ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for OpenBi<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for OpenBi<'a>

§

impl<'a> !RefUnwindSafe for OpenBi<'a>

§

impl<'a> Send for OpenBi<'a>

§

impl<'a> Sync for OpenBi<'a>

§

impl<'a> !UnwindSafe for OpenBi<'a>

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/545/docs/noq/struct.OpenUni.html b/pr/545/docs/noq/struct.OpenUni.html index 87f96fe45..dbe517c1f 100644 --- a/pr/545/docs/noq/struct.OpenUni.html +++ b/pr/545/docs/noq/struct.OpenUni.html @@ -1,6 +1,6 @@ -OpenUni in noq - Rust

OpenUni

Struct OpenUni 

Source
pub struct OpenUni<'a> { /* private fields */ }
Expand description

Future produced by Connection::open_uni

-

Trait Implementations§

Source§

impl Future for OpenUni<'_>

Source§

type Output = Result<SendStream, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for OpenUni<'a>
where +OpenUni in noq - Rust

OpenUni

Struct OpenUni 

Source
pub struct OpenUni<'a> { /* private fields */ }
Expand description

Future produced by Connection::open_uni

+

Trait Implementations§

Source§

impl Future for OpenUni<'_>

Source§

type Output = Result<SendStream, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for OpenUni<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for OpenUni<'a>

§

impl<'a> !RefUnwindSafe for OpenUni<'a>

§

impl<'a> Send for OpenUni<'a>

§

impl<'a> Sync for OpenUni<'a>

§

impl<'a> !UnwindSafe for OpenUni<'a>

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/545/docs/noq/struct.Path.html b/pr/545/docs/noq/struct.Path.html index de3922f3b..a786c9318 100644 --- a/pr/545/docs/noq/struct.Path.html +++ b/pr/545/docs/noq/struct.Path.html @@ -1,35 +1,35 @@ Path in noq - Rust

Path

Struct Path 

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

An open network transmission within a multipath-enabled connection.

As long as a Path or WeakPathHandle is alive, it is ensured that the PathStats for this path are not dropped even after the path is abandoned.

-

Implementations§

Source§

impl Path

Source

pub fn weak_handle(&self) -> WeakPathHandle

Returns a WeakPathHandle for this path.

+

Implementations§

Source§

impl Path

Source

pub fn weak_handle(&self) -> WeakPathHandle

Returns a WeakPathHandle for this path.

Holding a WeakPathHandle does not keep a connection alive, but ensures that the path’s stats are not dropped until the underlying connection is dropped, even if the path is abandoned.

-
Source

pub fn id(&self) -> PathId

The PathId of this path.

-
Source

pub fn status(&self) -> Result<PathStatus, ClosedPath>

The current local PathStatus of this path.

-
Source

pub fn set_status(&self, status: PathStatus) -> Result<(), SetPathStatusError>

Sets the PathStatus of this path.

-
Source

pub fn stats(&self) -> PathStats

Returns the PathStats for this path.

-
Source

pub fn close(&self) -> Result<(), ClosePathError>

Closes this path.

+
Source

pub fn id(&self) -> PathId

The PathId of this path.

+
Source

pub fn status(&self) -> Result<PathStatus, ClosedPath>

The current local PathStatus of this path.

+
Source

pub fn set_status(&self, status: PathStatus) -> Result<(), SetPathStatusError>

Sets the PathStatus of this path.

+
Source

pub fn stats(&self) -> PathStats

Returns the PathStats for this path.

+
Source

pub fn close(&self) -> Result<(), ClosePathError>

Closes this path.

The path is immediately considered closed by the local endpoint. Once the state is removed, after a short period of time for any in-flight packets, a PathEvent::Abandoned is returned.

-
Source

pub fn set_max_idle_timeout( +

Source

pub fn set_max_idle_timeout( &self, timeout: Option<Duration>, ) -> Result<Option<Duration>, ClosedPath>

Sets the max idle timeout for a specific path

See TransportConfig::default_path_max_idle_timeout for details.

Returns the previous value of the setting.

-
Source

pub fn set_keep_alive_interval( +

Source

pub fn set_keep_alive_interval( &self, interval: Option<Duration>, ) -> 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 observed_external_addr(&self) -> Result<AddressDiscovery, ClosedPath>

Track changes on our external address as reported by the peer.

+
Source

pub fn observed_external_addr(&self) -> Result<AddressDiscovery, ClosedPath>

Track changes on our external address as reported by the peer.

If the address-discovery extension is not negotiated, the stream will never return.

-
Source

pub fn remote_address(&self) -> Result<SocketAddr, ClosedPath>

The peer’s UDP address for this path.

-
Source

pub fn ping(&self) -> Result<(), ClosedPath>

Ping the remote endpoint over this path.

-

Trait Implementations§

Source§

impl Clone for Path

Source§

fn clone(&self) -> Self

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 Path

Source§

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

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

impl Drop for Path

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl PartialEq for Path

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, +
Source

pub fn remote_address(&self) -> Result<SocketAddr, ClosedPath>

The peer’s UDP address for this path.

+
Source

pub fn ping(&self) -> Result<(), ClosedPath>

Ping the remote endpoint over this path.

+

Trait Implementations§

Source§

impl Clone for Path

Source§

fn clone(&self) -> Self

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 Path

Source§

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

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

impl Drop for Path

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl PartialEq for Path

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.

Auto Trait Implementations§

§

impl Freeze for Path

§

impl RefUnwindSafe for Path

§

impl Send for Path

§

impl Sync for Path

§

impl Unpin for Path

§

impl UnwindSafe for Path

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/545/docs/noq/struct.PathEvents.html b/pr/545/docs/noq/struct.PathEvents.html new file mode 100644 index 000000000..e0f317942 --- /dev/null +++ b/pr/545/docs/noq/struct.PathEvents.html @@ -0,0 +1,174 @@ +PathEvents in noq - Rust

PathEvents

Struct PathEvents 

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

A stream of PathEvents for all paths in a connection.

+

Trait Implementations§

Source§

impl Debug for PathEvents

Source§

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

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

impl Stream for PathEvents

Source§

type Item = Result<PathEvent, Lagged>

Values yielded by the stream.
Source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where + U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> +if into_left is true. +Converts self into a Right variant of Either<Self, Self> +otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where + F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> +if into_left(&self) returns true. +Converts self into a Right variant of Either<Self, Self> +otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<S> StreamExt for S
where + S: Stream + ?Sized,

§

fn poll_next(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience for calling [Stream::poll_next()] on !Unpin types.
§

fn next(&mut self) -> NextFuture<'_, Self>
where + Self: Unpin,

Retrieves the next item in the stream. Read more
§

fn try_next<T, E>(&mut self) -> TryNextFuture<'_, Self>
where + Self: Stream<Item = Result<T, E>> + Unpin,

Retrieves the next item in the stream. Read more
§

fn count(self) -> CountFuture<Self>
where + Self: Sized,

Counts the number of items in the stream. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> T,

Maps items of the stream to new values using a closure. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: Stream, + F: FnMut(Self::Item) -> U,

Maps items to streams and then concatenates them. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self: Sized, + Self::Item: Stream,

Concatenates inner streams. Read more
§

fn then<F, Fut>(self, f: F) -> Then<Self, F, Fut>
where + Self: Sized, + F: FnMut(Self::Item) -> Fut, + Fut: Future,

Maps items of the stream to new values using an async closure. Read more
§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Keeps items of the stream for which predicate returns true. Read more
§

fn filter_map<T, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<T>,

Filters and maps items of the stream using a closure. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Takes only the first n items of the stream. Read more
§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Takes items while predicate returns true. Read more
§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Maps items while predicate returns Some. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Skips the first n items of the stream. Read more
§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Skips items while predicate returns true. Read more
§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Yields every stepth item. Read more
§

fn chain<U>(self, other: U) -> Chain<Self, U>
where + Self: Sized, + U: Stream<Item = Self::Item>,

Appends another stream to the end of this one. Read more
§

fn cloned<'a, T>(self) -> Cloned<Self>
where + Self: Sized + Stream<Item = &'a T>, + T: Clone + 'a,

Clones all items. Read more
§

fn copied<'a, T>(self) -> Copied<Self>
where + Self: Sized + Stream<Item = &'a T>, + T: Copy + 'a,

Copies all items. Read more
§

fn collect<C>(self) -> CollectFuture<Self, C>
where + Self: Sized, + C: Default + Extend<Self::Item>,

Collects all items in the stream into a collection. Read more
§

fn try_collect<T, E, C>(self) -> TryCollectFuture<Self, C>
where + Self: Sized + Stream<Item = Result<T, E>>, + C: Default + Extend<T>,

Collects all items in the fallible stream into a collection. Read more
§

fn partition<B, P>(self, predicate: P) -> PartitionFuture<Self, P, B>
where + Self: Sized, + B: Default + Extend<Self::Item>, + P: FnMut(&Self::Item) -> bool,

Partitions items into those for which predicate is true and those for which it is +false, and then collects them into two collections. Read more
§

fn fold<T, F>(self, init: T, f: F) -> FoldFuture<Self, F, T>
where + Self: Sized, + F: FnMut(T, Self::Item) -> T,

Accumulates a computation over the stream. Read more
§

fn try_fold<T, E, F, B>( + &mut self, + init: B, + f: F, +) -> TryFoldFuture<'_, Self, F, B>
where + Self: Sized + Stream<Item = Result<T, E>> + Unpin, + F: FnMut(B, T) -> Result<B, E>,

Accumulates a fallible computation over the stream. Read more
§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

Maps items of the stream to new values using a state value and a closure. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuses the stream so that it stops yielding items after the first None. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats the stream from beginning to end, forever. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Enumerates items, mapping them to (index, item). Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Calls a closure on each item and passes it on. Read more
§

fn nth(&mut self, n: usize) -> NthFuture<'_, Self>
where + Self: Unpin,

Gets the nth item of the stream. Read more
§

fn last(self) -> LastFuture<Self>
where + Self: Sized,

Returns the last item in the stream. Read more
§

fn find<P>(&mut self, predicate: P) -> FindFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(&Self::Item) -> bool,

Finds the first item of the stream for which predicate returns true. Read more
§

fn find_map<F, B>(&mut self, f: F) -> FindMapFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> Option<B>,

Applies a closure to items in the stream and returns the first Some result. Read more
§

fn position<P>(&mut self, predicate: P) -> PositionFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Finds the index of the first item of the stream for which predicate returns true. Read more
§

fn all<P>(&mut self, predicate: P) -> AllFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Tests if predicate returns true for all items in the stream. Read more
§

fn any<P>(&mut self, predicate: P) -> AnyFuture<'_, Self, P>
where + Self: Unpin, + P: FnMut(Self::Item) -> bool,

Tests if predicate returns true for any item in the stream. Read more
§

fn for_each<F>(self, f: F) -> ForEachFuture<Self, F>
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each item of the stream. Read more
§

fn try_for_each<F, E>(&mut self, f: F) -> TryForEachFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> Result<(), E>,

Calls a fallible closure on each item of the stream, stopping on first error. Read more
§

fn zip<U>(self, other: U) -> Zip<Self, U>
where + Self: Sized, + U: Stream,

Zips up two streams into a single stream of pairs. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> UnzipFuture<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Collects a stream of pairs into a pair of collections. Read more
§

fn or<S>(self, other: S) -> Or<Self, S>
where + Self: Sized, + S: Stream<Item = Self::Item>,

Merges with other stream, preferring items from self whenever both streams are ready. Read more
§

fn race<S>(self, other: S) -> Race<Self, S>
where + Self: Sized, + S: Stream<Item = Self::Item>,

Merges with other stream, with no preference for either stream when both are ready. Read more
§

fn drain(&mut self) -> Drain<'_, Self>

Yields all immediately available values from a stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Boxes the stream and changes its type to dyn Stream + Send + 'a. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Boxes the stream and changes its type to dyn Stream + 'a. Read more
§

impl<St> StreamExt for St
where + St: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Consumes and returns the next value in the stream or None if the +stream is finished. Read more
§

fn try_next<T, E>(&mut self) -> TryNext<'_, Self>
where + Self: Stream<Item = Result<T, E>> + Unpin,

Consumes and returns the next item in the stream. If an error is +encountered before the next item, the error is returned instead. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn map_while<T, F>(self, f: F) -> MapWhile<Self, F>
where + F: FnMut(Self::Item) -> Option<T>, + Self: Sized,

Map this stream’s items to a different type for as long as determined by +the provided closure. A stream of the target type will be returned, +which will yield elements until the closure returns None. Read more
§

fn then<F, Fut>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Maps this stream’s items asynchronously to a different type, returning a +new stream of the resulting type. Read more
§

fn merge<U>(self, other: U) -> Merge<Self, U>
where + U: Stream<Item = Self::Item>, + Self: Sized,

Combine two streams into one by interleaving the output of both as it +is produced. Read more
§

fn filter<F>(self, f: F) -> Filter<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Filters the values produced by this stream according to the provided +predicate. Read more
§

fn filter_map<T, F>(self, f: F) -> FilterMap<Self, F>
where + F: FnMut(Self::Item) -> Option<T>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided closure. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates a stream which ends after the first None. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn take_while<F>(self, f: F) -> TakeWhile<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Take elements from this stream while the provided predicate +resolves to true. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream that will skip the n first items of the +underlying stream. Read more
§

fn skip_while<F>(self, f: F) -> SkipWhile<Self, F>
where + F: FnMut(&Self::Item) -> bool, + Self: Sized,

Skip elements from the underlying stream while the provided predicate +resolves to true. Read more
§

fn all<F>(&mut self, f: F) -> AllFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> bool,

Tests if every element of the stream matches a predicate. Read more
§

fn any<F>(&mut self, f: F) -> AnyFuture<'_, Self, F>
where + Self: Unpin, + F: FnMut(Self::Item) -> bool,

Tests if any element of the stream matches a predicate. Read more
§

fn chain<U>(self, other: U) -> Chain<Self, U>
where + U: Stream<Item = Self::Item>, + Self: Sized,

Combine two streams into one by first returning all values from the +first stream then all values from the second stream. Read more
§

fn fold<B, F>(self, init: B, f: F) -> FoldFuture<Self, B, F>
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

A combinator that applies a function to every element in a stream +producing a single, final value. Read more
§

fn collect<T>(self) -> Collect<Self, T>
where + T: FromStream<Self::Item>, + Self: Sized,

Drain stream pushing all emitted values into a collection. Read more
§

fn timeout(self, duration: Duration) -> Timeout<Self>
where + Self: Sized,

Applies a per-item timeout to the passed stream. Read more
§

fn timeout_repeating(self, interval: Interval) -> TimeoutRepeating<Self>
where + Self: Sized,

Applies a per-item timeout to the passed stream. Read more
§

fn throttle(self, duration: Duration) -> Throttle<Self>
where + Self: Sized,

Slows down a stream by enforcing a delay between items. Read more
§

fn chunks_timeout( + self, + max_size: usize, + duration: Duration, +) -> ChunksTimeout<Self>
where + Self: Sized,

Batches the items in the given stream using a maximum duration and size for each batch. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Turns the stream into a peekable stream, whose next element can be peeked at without being +consumed. Read more
Source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = Result<T, E>> + ?Sized,

§

type Ok = T

The type of successful values yielded by this future
§

type Error = E

The type of failures yielded by this future
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_>, +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/pr/545/docs/noq/struct.ReadDatagram.html b/pr/545/docs/noq/struct.ReadDatagram.html index 6bb134ade..cac5d37c3 100644 --- a/pr/545/docs/noq/struct.ReadDatagram.html +++ b/pr/545/docs/noq/struct.ReadDatagram.html @@ -1,6 +1,6 @@ -ReadDatagram in noq - Rust

ReadDatagram

Struct ReadDatagram 

Source
pub struct ReadDatagram<'a> { /* private fields */ }
Expand description

Future produced by Connection::read_datagram

-

Trait Implementations§

Source§

impl Future for ReadDatagram<'_>

Source§

type Output = Result<Bytes, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for ReadDatagram<'a>
where +ReadDatagram in noq - Rust

ReadDatagram

Struct ReadDatagram 

Source
pub struct ReadDatagram<'a> { /* private fields */ }
Expand description

Future produced by Connection::read_datagram

+

Trait Implementations§

Source§

impl Future for ReadDatagram<'_>

Source§

type Output = Result<Bytes, ConnectionError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for ReadDatagram<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for ReadDatagram<'a>

§

impl<'a> !RefUnwindSafe for ReadDatagram<'a>

§

impl<'a> Send for ReadDatagram<'a>

§

impl<'a> Sync for ReadDatagram<'a>

§

impl<'a> !UnwindSafe for ReadDatagram<'a>

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/545/docs/noq/struct.SendDatagram.html b/pr/545/docs/noq/struct.SendDatagram.html index 493cf4a77..04c0cba2f 100644 --- a/pr/545/docs/noq/struct.SendDatagram.html +++ b/pr/545/docs/noq/struct.SendDatagram.html @@ -1,6 +1,6 @@ -SendDatagram in noq - Rust

SendDatagram

Struct SendDatagram 

Source
pub struct SendDatagram<'a> { /* private fields */ }
Expand description

Future produced by Connection::send_datagram_wait

-

Trait Implementations§

Source§

impl Future for SendDatagram<'_>

Source§

type Output = Result<(), SendDatagramError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for SendDatagram<'a>
where +SendDatagram in noq - Rust

SendDatagram

Struct SendDatagram 

Source
pub struct SendDatagram<'a> { /* private fields */ }
Expand description

Future produced by Connection::send_datagram_wait

+

Trait Implementations§

Source§

impl Future for SendDatagram<'_>

Source§

type Output = Result<(), SendDatagramError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin, 'a> Unpin for SendDatagram<'a>
where PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,

Auto Trait Implementations§

§

impl<'a> !Freeze for SendDatagram<'a>

§

impl<'a> !RefUnwindSafe for SendDatagram<'a>

§

impl<'a> Send for SendDatagram<'a>

§

impl<'a> Sync for SendDatagram<'a>

§

impl<'a> !UnwindSafe for SendDatagram<'a>

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/545/docs/noq/struct.SendStream.html b/pr/545/docs/noq/struct.SendStream.html index 540865dff..b6a413534 100644 --- a/pr/545/docs/noq/struct.SendStream.html +++ b/pr/545/docs/noq/struct.SendStream.html @@ -8,7 +8,7 @@ ready will always result in no data being written to the stream. This is true of succeed immediately when any progress is made, and is not true of methods which might need to perform multiple writes internally before succeeding. Each write method documents whether it is cancel-safe.

-

Implementations§

Source§

impl SendStream

Source

pub async fn write(&mut self, buf: &[u8]) -> Result<usize, WriteError>

Write a buffer into this stream, returning how many bytes were written

+

Implementations§

Source§

impl SendStream

Source

pub async fn write(&mut self, buf: &[u8]) -> Result<usize, WriteError>

Write a buffer into this stream, returning how many bytes were written

Unless this method errors, it waits until some amount of buf can be written into this stream, and then writes as much as it can without waiting again. Due to congestion and flow control, this may be shorter than buf.len(). On success this yields the length of the @@ -58,7 +58,7 @@ or an error occurs. This method mutates bufs by mutating all chunks

§Cancel safety

This method is not cancellation safe. Even if this does not resolve, some bytes may have been written when previously polled.

-
Source

pub fn finish(&mut self) -> Result<(), ClosedStream>

Notify the peer that no more data will ever be written to this stream

+
Source

pub fn finish(&mut self) -> Result<(), ClosedStream>

Notify the peer that no more data will ever be written to this stream

It is an error to write to a SendStream after finish()ing it. reset() may still be called after finish to abandon transmission of any stream data that might still be buffered.

@@ -66,21 +66,21 @@ still be buffered.

May fail if finish() or reset() was previously called. This error is harmless and serves only to indicate that the caller may have incorrect assumptions about the stream’s state.

-
Source

pub fn reset(&mut self, error_code: VarInt) -> Result<(), ClosedStream>

Close the send stream immediately.

+
Source

pub fn reset(&mut self, error_code: VarInt) -> Result<(), ClosedStream>

Close the send stream immediately.

No new data can be written after calling this method. Locally buffered data is dropped, and previously transmitted data will no longer be retransmitted if lost. If an attempt has already been made to finish the stream, the peer may still receive all written data.

May fail if finish() or reset() was previously called. This error is harmless and serves only to indicate that the caller may have incorrect assumptions about the stream’s state.

-
Source

pub fn set_priority(&self, priority: i32) -> Result<(), ClosedStream>

Set the priority of the send stream

+
Source

pub fn set_priority(&self, priority: i32) -> Result<(), ClosedStream>

Set the priority of the send stream

Every send stream has an initial priority of 0. Locally buffered data from streams with higher priority will be transmitted before data from streams with lower priority. Changing the priority of a stream with pending data may only take effect after that data has been transmitted. Using many different priority levels per connection may have a negative impact on performance.

-
Source

pub fn priority(&self) -> Result<i32, ClosedStream>

Get the priority of the send stream

-
Source

pub fn stopped(&self) -> Stopped ⓘ

Completes when the peer stops the stream or reads the stream to completion

+
Source

pub fn priority(&self) -> Result<i32, ClosedStream>

Get the priority of the send stream

+
Source

pub fn stopped(&self) -> Stopped ⓘ

Completes when the peer stops the stream or reads the stream to completion

Yields Some with the stop error code if the peer stops the stream. Yields None if the local side finish()es the stream and then the peer acknowledges receipt of all stream data (although not necessarily the processing of it), after which the peer @@ -88,8 +88,8 @@ closing the stream is no longer meaningful.

For a variety of reasons, the peer may not send acknowledgements immediately upon receiving data. As such, relying on stopped to know when the peer has read a stream to completion may introduce more latency than using an application-level response of some sort.

-
Source

pub fn id(&self) -> StreamId

Get the identity of this stream

-
Source

pub fn poll_write( +

Source

pub fn id(&self) -> StreamId

Get the identity of this stream

+
Source

pub fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], @@ -98,22 +98,22 @@ may introduce more latency than using an application-level response of some sort

If the stream is not ready for writing, the method returns Poll::Pending and arranges for the current task (via cx.waker().wake_by_ref()) to receive a notification when the stream becomes writable or is closed.

-

Trait Implementations§

Source§

impl AsyncWrite for SendStream

Available on crate feature futures-io only.

Trait Implementations§

Source§

impl AsyncWrite for SendStream

Available on crate feature futures-io only.
Source§

fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], -) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to flush the object, ensuring that any buffered data reach -their destination. Read more
Source§

fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to close the object. Read more
§

fn poll_write_vectored( +) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to flush the object, ensuring that any buffered data reach +their destination. Read more
Source§

fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempt to close the object. Read more
§

fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>

Attempt to write bytes from bufs into the object using vectored -IO operations. Read more
Source§

impl AsyncWrite for SendStream

Source§

fn poll_write( +IO operations. Read more

Source§

impl AsyncWrite for SendStream

Source§

fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], -) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempts to flush the object, ensuring that any buffered data reach -their destination. Read more
Source§

fn poll_shutdown( +) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
Source§

fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<()>>

Attempts to flush the object, ensuring that any buffered data reach +their destination. Read more
Source§

fn poll_shutdown( self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll<Result<()>>

Initiates or attempts to shut down this writer, returning success when @@ -122,7 +122,7 @@ the I/O connection has completely shut down. Read more
Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored -implementation. Read more
Source§

impl Debug for SendStream

Source§

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

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

impl Drop for SendStream

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +implementation. Read more

Source§

impl Debug for SendStream

Source§

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

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

impl Drop for SendStream

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

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
§

impl<W> AsyncWriteExt for W
where W: AsyncWrite + ?Sized,

§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where Self: Unpin,

Writes a buffer into this writer, returning how many bytes were diff --git a/pr/545/docs/noq/struct.Stopped.html b/pr/545/docs/noq/struct.Stopped.html index a90b38c9f..4bb4f74f6 100644 --- a/pr/545/docs/noq/struct.Stopped.html +++ b/pr/545/docs/noq/struct.Stopped.html @@ -1,6 +1,6 @@ -Stopped in noq - Rust

Stopped

Struct Stopped 

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

Future returned from SendStream::stopped.

-

Trait Implementations§

Source§

impl Debug for Stopped

Source§

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

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

impl Future for Stopped

Source§

type Output = Result<Option<VarInt>, StoppedError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering -the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin> Unpin for Stopped
where +Stopped in noq - Rust

Stopped

Struct Stopped 

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

Future returned from SendStream::stopped.

+

Trait Implementations§

Source§

impl Debug for Stopped

Source§

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

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

impl Future for Stopped

Source§

type Output = Result<Option<VarInt>, StoppedError>

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
Source§

impl<'__pin> Unpin for Stopped
where PinnedFieldsOf<__Origin<'__pin>>: Unpin,

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/545/docs/noq/struct.WeakConnectionHandle.html b/pr/545/docs/noq/struct.WeakConnectionHandle.html index adee37c70..68daf3016 100644 --- a/pr/545/docs/noq/struct.WeakConnectionHandle.html +++ b/pr/545/docs/noq/struct.WeakConnectionHandle.html @@ -1,10 +1,10 @@ -WeakConnectionHandle in noq - Rust

WeakConnectionHandle

Struct WeakConnectionHandle 

Source
pub struct WeakConnectionHandle(/* private fields */);
Expand description

A handle to some connection internals, use with care.

+WeakConnectionHandle in noq - Rust

WeakConnectionHandle

Struct WeakConnectionHandle 

Source
pub struct WeakConnectionHandle(/* private fields */);
Expand description

A handle to some connection internals, use with care.

This contains a weak reference to the connection so will not itself keep the connection alive.

-

Implementations§

Source§

impl WeakConnectionHandle

Source

pub fn is_alive(&self) -> bool

Returns true if the Connection associated with this handle is still alive.

-
Source

pub fn upgrade(&self) -> Option<Connection>

Upgrade the handle to a full Connection

-
Source

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

Returns true if the two WeakConnectionHandle point at the same connection.

-

Trait Implementations§

Source§

impl Clone for WeakConnectionHandle

Source§

fn clone(&self) -> WeakConnectionHandle

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 WeakConnectionHandle

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Implementations§

Source§

impl WeakConnectionHandle

Source

pub fn is_alive(&self) -> bool

Returns true if the Connection associated with this handle is still alive.

+
Source

pub fn upgrade(&self) -> Option<Connection>

Upgrade the handle to a full Connection

+
Source

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

Returns true if the two WeakConnectionHandle point at the same connection.

+

Trait Implementations§

Source§

impl Clone for WeakConnectionHandle

Source§

fn clone(&self) -> WeakConnectionHandle

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 WeakConnectionHandle

Source§

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

Formats the value using the given formatter. Read more

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/545/docs/noq/struct.WeakPathHandle.html b/pr/545/docs/noq/struct.WeakPathHandle.html index 5016e3251..d7a9ad9a1 100644 --- a/pr/545/docs/noq/struct.WeakPathHandle.html +++ b/pr/545/docs/noq/struct.WeakPathHandle.html @@ -1,12 +1,12 @@ -WeakPathHandle in noq - Rust

WeakPathHandle

Struct WeakPathHandle 

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

Weak handle for a Path that does not keep the connection alive.

+WeakPathHandle in noq - Rust

WeakPathHandle

Struct WeakPathHandle 

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

Weak handle for a Path that does not keep the connection alive.

As long as a WeakPathHandle for a path exists, that path’s final stats will not be dropped even if the path was abandoned.

The WeakPathHandle can be upgraded to a Path as long as its Connection has not been dropped.

-

Implementations§

Source§

impl WeakPathHandle

Source

pub fn id(&self) -> PathId

Returns the PathId of this path.

-
Source

pub fn upgrade(&self) -> Option<Path>

Upgrades to a Path.

+

Implementations§

Source§

impl WeakPathHandle

Source

pub fn id(&self) -> PathId

Returns the PathId of this path.

+
Source

pub fn upgrade(&self) -> Option<Path>

Upgrades to a Path.

Returns None if the connection was dropped.

-

Trait Implementations§

Source§

impl Clone for WeakPathHandle

Source§

fn clone(&self) -> Self

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 WeakPathHandle

Source§

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

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

impl Drop for WeakPathHandle

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl PartialEq for WeakPathHandle

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 WeakPathHandle

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for WeakPathHandle

Source§

fn clone(&self) -> Self

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 WeakPathHandle

Source§

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

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

impl Drop for WeakPathHandle

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl PartialEq for WeakPathHandle

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 WeakPathHandle

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/545/docs/noq/struct.ZeroRttAccepted.html b/pr/545/docs/noq/struct.ZeroRttAccepted.html index f22efa639..1849df0f8 100644 --- a/pr/545/docs/noq/struct.ZeroRttAccepted.html +++ b/pr/545/docs/noq/struct.ZeroRttAccepted.html @@ -1,7 +1,7 @@ -ZeroRttAccepted in noq - Rust

ZeroRttAccepted

Struct ZeroRttAccepted 

Source
pub struct ZeroRttAccepted(/* private fields */);
Expand description

Future that completes when a connection is fully established

+ZeroRttAccepted in noq - Rust

ZeroRttAccepted

Struct ZeroRttAccepted 

Source
pub struct ZeroRttAccepted(/* private fields */);
Expand description

Future that completes when a connection is fully established

For clients, the resulting value indicates if 0-RTT was accepted. For servers, the resulting value is meaningless.

-

Trait Implementations§

Source§

impl Future for ZeroRttAccepted

Source§

type Output = bool

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering +

Trait Implementations§

Source§

impl Future for ZeroRttAccepted

Source§

type Output = bool

The type of value produced on completion.
Source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempts to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

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/545/docs/noq/trait.NetworkChangeHint.html b/pr/545/docs/noq/trait.NetworkChangeHint.html index 7d5061053..a5aca6651 100644 --- a/pr/545/docs/noq/trait.NetworkChangeHint.html +++ b/pr/545/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/545/docs/noq_proto/enum.ClosePathError.html b/pr/545/docs/noq_proto/enum.ClosePathError.html index 6464dc897..4d95693b6 100644 --- a/pr/545/docs/noq_proto/enum.ClosePathError.html +++ b/pr/545/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/545/docs/noq_proto/enum.ConnectionError.html b/pr/545/docs/noq_proto/enum.ConnectionError.html index 4e02d01a2..7a7780c8a 100644 --- a/pr/545/docs/noq_proto/enum.ConnectionError.html +++ b/pr/545/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/545/docs/noq_proto/enum.Event.html b/pr/545/docs/noq_proto/enum.Event.html index 75ce13cf3..851c93c42 100644 --- a/pr/545/docs/noq_proto/enum.Event.html +++ b/pr/545/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/545/docs/noq_proto/enum.PathError.html b/pr/545/docs/noq_proto/enum.PathError.html index 9c6d5f6b6..39f8935ba 100644 --- a/pr/545/docs/noq_proto/enum.PathError.html +++ b/pr/545/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/545/docs/noq_proto/enum.PathEvent.html b/pr/545/docs/noq_proto/enum.PathEvent.html index b48682e46..c0044b0ac 100644 --- a/pr/545/docs/noq_proto/enum.PathEvent.html +++ b/pr/545/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/545/docs/noq_proto/struct.Connection.html b/pr/545/docs/noq_proto/struct.Connection.html index 329031338..fd1f7f224 100644 --- a/pr/545/docs/noq_proto/struct.Connection.html +++ b/pr/545/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
  • @@ -93,21 +93,24 @@ when receiving a PATH_ABANDON from the peer for a path that was never opened loc ) -> Result<PathStatus, SetPathStatusError>

Sets the PathStatus for a known PathId

Returns the previous path status on success.

Source

pub fn remote_path_status(&self, path_id: PathId) -> Option<PathStatus>

Returns the remote path status

-
Source

pub fn set_path_max_idle_timeout( +

Source

pub fn set_path_max_idle_timeout( &mut self, + now: Instant, path_id: PathId, timeout: Option<Duration>, -) -> Result<Option<Duration>, ClosedPath>

Sets the max_idle_timeout for a specific path

+) -> Result<Option<Duration>, ClosedPath>

Sets the max_idle_timeout for a specific path.

+

The PathIdle timer is immediately re-armed accounting for already-elapsed +idle time. Setting None disables the timeout and stops the timer.

See TransportConfig::default_path_max_idle_timeout for details.

Returns the previous value of the setting.

-
Source

pub fn set_path_keep_alive_interval( +

Source

pub fn set_path_keep_alive_interval( &mut self, path_id: PathId, interval: Option<Duration>, ) -> 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, @@ -121,60 +124,60 @@ when receiving a PATH_ABANDON from the peer for a path that was never opened loc

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.

-
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, @@ -185,16 +188,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, @@ -209,26 +212,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

@@ -238,7 +241,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§

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§

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/545/docs/noq_proto/struct.MultipathNotNegotiated.html b/pr/545/docs/noq_proto/struct.MultipathNotNegotiated.html index 85c9e92a6..42b55c8f3 100644 --- a/pr/545/docs/noq_proto/struct.MultipathNotNegotiated.html +++ b/pr/545/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/545/docs/noq_proto/struct.TransportError.html b/pr/545/docs/noq_proto/struct.TransportError.html index ccd7ad0e2..fae17743c 100644 --- a/pr/545/docs/noq_proto/struct.TransportError.html +++ b/pr/545/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/545/docs/noq_proto/trait.NetworkChangeHint.html b/pr/545/docs/noq_proto/trait.NetworkChangeHint.html index 33ec43eca..d4f17d762 100644 --- a/pr/545/docs/noq_proto/trait.NetworkChangeHint.html +++ b/pr/545/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/545/docs/search.index/0033f3568d59.js b/pr/545/docs/search.index/0033f3568d59.js new file mode 100644 index 000000000..bb8d36b85 --- /dev/null +++ b/pr/545/docs/search.index/0033f3568d59.js @@ -0,0 +1 @@ +rn_("AQgBoIAAABQSZgEAEwAAE4ACoOAAABPaYnABAwGwABOWAExz9m0PAAABAL8AKQABAOkCAYACsEASKwABoBAAABCTcHIBgQOgAAAAEQWwAA9YAR6gEAAAD1Blc3XzgANhb3IBAgD1WRAAAAEAAQBLAgEAAQQAOzAAAAEAAAkAAQDKEAkAAYECoJAAABNZsFASEwABYnejgISwUBN1AAGwkBKeAAFAIANXAwAAhqBwAAATUKBAAAATvzBBDDowAAABAAAAAAA7ABAAAACkBKUEYwVkBWUFZgVnBWgFaQVqBWsFbAVRB/UI9gj7COAL4QsDDAQMBQyQDJEMngw2DkMPRA9FD1gPdw94D70PNhBEEEUQYxBkEHYQmxCcEAkRVhFfEWARZBFcEpQSlRJEE0UTSxN1E3YTlBOVE6wTDxQQFBoUGxQ=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0106b6a79629.js b/pr/545/docs/search.index/0106b6a79629.js deleted file mode 100644 index 2b41bcc1a..000000000 --- a/pr/545/docs/search.index/0106b6a79629.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsAAQygABsAAQzAABNDYBBAGgoAAAE/B38uATAAABAAELAPRSEwAAAQABAAEAI4ACoIAAABN6ZW9jAgOgYAAAExBlbnABuQsAAPMAAmF2AZ8GAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0110ee2caa9d.js b/pr/545/docs/search.index/0110ee2caa9d.js deleted file mode 100644 index dfbe0aafd..000000000 --- a/pr/545/docs/search.index/0110ee2caa9d.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9AgSAAABAKQAAQABCAD0wRIAAAEAhAABADMBA7BAEpEAAWFiZTowAAABAAAAAAAJABAAAADvBvAGegx7DCMPkQ/dD94P4RGwEgEAADswAAABAAAfAA4AlQQBAFMFCQDeCAEAwQsBAGwMAQAMDgAAFg8CACsPAABKDwEANRABAEgQAADZEAAALxEBADQRAAABgQKwABDKAAGwABDMAAE0NiOAArCAE7gAAW9wAQABsEASjQABZfPVEAAASgEBALcBAICFoGAAABBzEAEL") \ No newline at end of file diff --git a/pr/545/docs/search.index/016287c739af.js b/pr/545/docs/search.index/016287c739af.js new file mode 100644 index 000000000..e38ce7f6e --- /dev/null +++ b/pr/545/docs/search.index/016287c739af.js @@ -0,0 +1 @@ +rn_("AQACoDAAABCXoJAAABL7MGj1dxEAAIwBAQABAAEAE4ACoDAAAA9VZHIjAISwEAjGAySwIAu7AP+gMAAAD3oSABj1dgUAAC4AAQABAAEAAQIA9A8UAAABAAoAAQABAgDz9A8AAAEAAQDzgAJpcgEBArBAEN0AAaBQAAAS4WVz9DEOAADCAgEAfgIBCwD2ChMAAAEAowBUABYAAQDzgAJsdNOAhKCQAAASuQFEBA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/01818b9a5dfd.js b/pr/545/docs/search.index/01818b9a5dfd.js new file mode 100644 index 000000000..7d2cf82a1 --- /dev/null +++ b/pr/545/docs/search.index/01818b9a5dfd.js @@ -0,0 +1 @@ +rn_("AQUA9DkSAAABAKQAAQABCAD08xIAAAEAhQABADMBA7BAEsIAAWFiZTowAAABAAAAAAAJABAAAAAEBwUHnwygDFAPvg8KEAsQEhLhEgEAADswAAABAAAfAA4ApAQBAGMFCQD1CAEA4AsBAJAMAQA2DgAAQw8CAFgPAAB3DwEAYxABAHYQAAAJEQAAXxEBAGQRAAABgQKwABD6AAGwABD8AAE0NiOAArCAE+sAAW9wAQABsEASvgABZfMFEQAASwEBALcBAICFoGAAABChEAEL") \ No newline at end of file diff --git a/pr/545/docs/search.index/01b2e5b81d3a.js b/pr/545/docs/search.index/01b2e5b81d3a.js deleted file mode 100644 index 7764373ba..000000000 --- a/pr/545/docs/search.index/01b2e5b81d3a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQgA9C8TAAABAIIABQATAAOwkBORAAGwUBJ5AVdnbHA7MAAAAQAAEgAJAMEPAgAyEQEAaBIBAIkSAQC/EgEAIBMBAFcTAQBmEwEAoxMBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/01dabba3dd0f.js b/pr/545/docs/search.index/01dabba3dd0f.js new file mode 100644 index 000000000..c604ac4dd --- /dev/null +++ b/pr/545/docs/search.index/01dabba3dd0f.js @@ -0,0 +1 @@ +rn_("AYACoGAAABNyoKAAABNkYWkBCwD0AxMAAAEAAQABAAEEAPQpEAAAAQABAAEAI4ACsEAQgQABbHLzAANjZHMBdxAAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/01f066683f43.js b/pr/545/docs/search.index/01f066683f43.js deleted file mode 100644 index 06ff841a8..000000000 --- a/pr/545/docs/search.index/01f066683f43.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOzAAAAEAAAUAAQC8EwUA8w0BbTswAAABAAAFAAEAfBMFACMDhLBAEgEAAaEAAAATwqAAAAATRDAIAjswAAABAAAUAAUAgBAHACMSAQCeEgQAdBMEAN8TAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0258058d4a15.js b/pr/545/docs/search.index/0258058d4a15.js new file mode 100644 index 000000000..3098d5aaf --- /dev/null +++ b/pr/545/docs/search.index/0258058d4a15.js @@ -0,0 +1 @@ +rn_("AQEA9DkHAAAtCNwAAQABBQD0pBIAAAEAkQABAPMCAWP12w8AAAEAvAABAAEAYwAEoDAAAAvpoHAAABFWZW5zdvP5DwAAlQATAg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/03099968b016.js b/pr/545/docs/search.index/03099968b016.js new file mode 100644 index 000000000..6b3fa5854 --- /dev/null +++ b/pr/545/docs/search.index/03099968b016.js @@ -0,0 +1 @@ +rn_("AYkCsCAT0gABoDAAABPcaXATAAOgIAAAEpiggAAAEqtlaXX1yQsAADQAAQABAAEAAYYCsJAT9wABoAAAABIoYmQBgAKwMBKMAAGgMAAAEHRydtcAAACFoDAAAA/xoDAAABLiEAETOjAAAAEAAAAAAAkAEAAAAMoIywjMCPwI/QgJEA4QxBDFEGkS") \ No newline at end of file diff --git a/pr/545/docs/search.index/036264e2cafd.js b/pr/545/docs/search.index/036264e2cafd.js deleted file mode 100644 index 13468601f..000000000 --- a/pr/545/docs/search.index/036264e2cafd.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9fcQAAABAAEAAQABAAGAArBgElEAAaAgAAAQTm95AQABoMAAABNtafSnEgAACAAaABsAAQMA9MoSAAABAAEAAQABBgD00RMAAAEAAQABAAECAPRMEAAAAQCYAAEAAQIBoEAAABJ+cjswAAABAAAHAAIAShABAN8QBQDzgAJhb2cHAACHsIASfQBYsKAS8gABDDAHOzAAAAEAAA4ABABmBAUAsgsAAAoRAwDqEQMApwAAgIWg8AAAEwKwUA+nAAGgkAAAENaUgQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/03d8571d8861.js b/pr/545/docs/search.index/03d8571d8861.js new file mode 100644 index 000000000..8c8df5e4f --- /dev/null +++ b/pr/545/docs/search.index/03d8571d8861.js @@ -0,0 +1 @@ +rn_("AQIBsEAT3QABdDswAAABAAANAAYAahIDANQSAQBBEwEAWBMBANITAQD3EwEAE4ACsDASnQE/aXABBQDzGBMAAAEAAQATgAKgMAAAE3FleVMBA7BwE34AAWJlcwHFDwAAE4ADsDAT6wABsCAG0QABZWxz") \ No newline at end of file diff --git a/pr/545/docs/search.index/04067d1944a2.js b/pr/545/docs/search.index/04067d1944a2.js new file mode 100644 index 000000000..e4352dbc5 --- /dev/null +++ b/pr/545/docs/search.index/04067d1944a2.js @@ -0,0 +1 @@ +rn_("AQAAOjAAAAEAAAAAAAoAEAAAAGsPbA9UEFUQ3xBpEWoRfhJ/EggUCRTzAQF58nMTAAABACMAA6BAAAAQ/qBQAAATv2Vvc/JPDwAAwAI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0435c5f11e89.js b/pr/545/docs/search.index/0435c5f11e89.js new file mode 100644 index 000000000..49cddb36f --- /dev/null +++ b/pr/545/docs/search.index/0435c5f11e89.js @@ -0,0 +1 @@ +rn_("AYACsHARUwABsCAPbwDpaHkBBQD0sQwAAAEAGwMBAAEAAPQTDAAAAQABAGoAAQIAOjAAAAEAAAAAAAkAEAAAAGQPZQ9TEA4RXRJeElcT2RMKFAsUAQMA8+oIAAABAAEA1wMAAIagQAAAEW4YQAc6MAAAAQAAAAAAFwAQAAAAOgc7B8kH9wgrCSwJsAxRD1IPcg8YEB8QIBAhECIQXRBeEJQQlRAEElUTVhOBE4IT") \ No newline at end of file diff --git a/pr/545/docs/search.index/044ee5e7fc14.js b/pr/545/docs/search.index/044ee5e7fc14.js deleted file mode 100644 index d74c853fe..000000000 --- a/pr/545/docs/search.index/044ee5e7fc14.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQoBoIAAABPfZgHOEgAAAQgA9XQTAAABAAEAAQABAPMDAWb17Q8AAAEAAQABAAEA84MCYXMBAgKgIAAAESKgMAAAEeZiaAEmDwAAI4ACoIAAABKEYXDzAAJobQF3BAAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/04cd208f0148.js b/pr/545/docs/search.index/04cd208f0148.js new file mode 100644 index 000000000..3b98ad075 --- /dev/null +++ b/pr/545/docs/search.index/04cd208f0148.js @@ -0,0 +1 @@ +rn_("AQMA8y8SAAABAAEAI4ECsSAUFgABY2sBBAGgQAAAEW5l87AMAADkAwEAAQAA9W8QAAABAAEAAQCDAnOAhKAwAAATnwgwAQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/0530b4c13347.js b/pr/545/docs/search.index/0530b4c13347.js new file mode 100644 index 000000000..b7fecce4d --- /dev/null +++ b/pr/545/docs/search.index/0530b4c13347.js @@ -0,0 +1 @@ +rn_("AQMBoEAAABOfZfLJEwAAAQABAAD0ehIAAAEAAQABAPMEAWT0IBIAAAEAAQABAKcAAAKFsKATtwABsEASeAABsHATZQABFYgAAY0TAAABAAGwgBOhAAFw8p0TAAABAEMAA6AgAAAQ3KBAAAASJGRlc/N+DwAAMwMBAPOAAmVp") \ No newline at end of file diff --git a/pr/545/docs/search.index/058523a6e4f8.js b/pr/545/docs/search.index/058523a6e4f8.js new file mode 100644 index 000000000..1e553e4bc --- /dev/null +++ b/pr/545/docs/search.index/058523a6e4f8.js @@ -0,0 +1 @@ +rn_("AQsA9NUTAAAMAB4ADwABCgA6MAAAAQAAAAAABwAQAAAAuhK7ElMTVBOKE4sT1hPXE/OBAm90EwCEsCASrgBZsDAQxgABoFAAABCtEDACOzAAAAEAAAgABAB9AAEAqAADACoHAQA9CQAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/05ca02aa6fd9.js b/pr/545/docs/search.index/05ca02aa6fd9.js deleted file mode 100644 index e2246d789..000000000 --- a/pr/545/docs/search.index/05ca02aa6fd9.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYQCoCAAABB0oDAAABDZaXQBAQA7MAAAAQAAhgACADAHAAAsCYUA8wACZWz1iAQAAKwCXgk9AgEAAQIAOzAAAAEAAOMAAgClCwAAngziAMcAAACFsLASewABoBAAABL9sDAMnAABFDACOzAAAAEAAA8BCwDLAQYAbAUAAJcF4gD/BgcAmw8CAOgQDQAPEQIA4hEBAGUSAQC2EgEASBMCAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/06715c7452c2.js b/pr/545/docs/search.index/06715c7452c2.js deleted file mode 100644 index fe9d60dc0..000000000 --- a/pr/545/docs/search.index/06715c7452c2.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQsA9KITAAAMAB4ADwABCgA6MAAAAQAAAAAABwAQAAAAiRKKEiATIRNXE1gToxOkE/OBAm90EwCEsCASfQBYsDAQmAABoFAAABB/EDACOzAAAAEAAAgABAB8AAEApwADABUHAQAmCQAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0697183800b7.js b/pr/545/docs/search.index/0697183800b7.js new file mode 100644 index 000000000..03a11cb16 --- /dev/null +++ b/pr/545/docs/search.index/0697183800b7.js @@ -0,0 +1 @@ +rn_("AYQCoCAAABCioDAAABEJaXQBAQA7MAAAAQAAhwACAEUHAABDCYYA8wACZWz1lwQAALICdwlBAgEAAQIAOzAAAAEAAOcAAgDFCwAAwwzmAMcAAACFsLASrAABoBAAABMwsDAMwQABFDACOzAAAAEAABMBCwDSAQYAfAUAAKgF5gAUBwcAyA8CABgRDQA/EQIAExIBAJYSAQDnEgEAexMCAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/06c25d8359bd.js b/pr/545/docs/search.index/06c25d8359bd.js new file mode 100644 index 000000000..df1605b7a --- /dev/null +++ b/pr/545/docs/search.index/06c25d8359bd.js @@ -0,0 +1 @@ +rn_("AQIAOzAAAAEAAAYAAgCTBQUAAREAAAEEAbAAEpQAAXM7MAAAAQAACwACAA4TBwD7EwMARwAAAYaggAAAEu+xABQIAAGwQBJQAAGwgBQWAAGwUBKWAAEVABb0Mg4AAAEAAQABAAEFAPOEDwAAAQABAGOAA7BAEAwAAW1ubwGBArAADJAAAbAQEAoAAXN18wACYWk6MAAAAQAAAAAABwAQAAAAOQdmD0IQQxD8Ev0S/hL/EgGAA7AAE0wAAbAAE04AAbBwE8AAATQ2YQEEAPQPFAAAAQAKAAEAI4ECoEAAABDabXABAgA7MAAAAQAADgAEADwHAQCzDAEAyhAJAAgRAAABAQA7MAAAAQAACAADAEQSAAC1EgAAHBQGAAEBADswAAABAAAKAAMA7hACACYTAwAEFAMAI4ACoDAAAA/dZGfXAwAAxqCAAAASH0BGgAg7MAAAAQAAGAAJAHsPAQCREAEAxhABANYQAwBFEQYAKhMCAHgTAADQEwEAABQBAAEDAPbnCAAAVwDHBgEAsAABABOAArBwE6EAAW9yAQQBsLAT6AABbPSxDAAAAQAbAwEAAQIAOzAAAAEAAAwAAwDHCAAAOhMFAO8TBQABAQDzww8AAAEASgIjgAKgsAAAE6BnegECADowAAABAAAAAAAJABAAAABTEVQRZxJoElETUhOlE6YTFhQXFPMAAW/yQQkAAAEAAQUA9G0PAAABAOgAAQCDAISgQAAADKawcBLaAAGwIAwrAAEQBQI7MAAAAQAACQADAJsEAwBaBQIAQhECAAGAAqAgAAAQoLAgE6EAAWR0AYQCsLAT6wABsAATRAABYXPTgISgsAAAE9RAKAQBgAKgMAAAEW2wYA+CAAFockf/AQDNoCAAAAV5oCAAAAV6sHATOAABA2c0BzswAAABAAA4ABkAfgQAALUEBQA3CQAAfgwAAD4PAQAuEAMA6RAAAEQSAABWEgUAtRIBANgSAADgEgAA8BIAAPsSAAAMEwEAFhMAABgTAgAcEwEAcRMAAHcTAACDEwEAnRMBAK8TBQDDEwAAHBQGAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/06c6b77500fe.js b/pr/545/docs/search.index/06c6b77500fe.js new file mode 100644 index 000000000..416fb8a5a --- /dev/null +++ b/pr/545/docs/search.index/06c6b77500fe.js @@ -0,0 +1 @@ +rn_("AQIBoKAAABLYZPLIBgAAAQABgQKgMAAAE9SgUAAAE2RjcwEEA7AgEMgAAaBQAAARbaBAAAAToGxzdvKbEwAAAQDzAANhZW87MAAAAQAACAADAGsEAQC8CwAAuwwFAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/0717d66ebc8c.js b/pr/545/docs/search.index/0717d66ebc8c.js new file mode 100644 index 000000000..3d5ceee14 --- /dev/null +++ b/pr/545/docs/search.index/0717d66ebc8c.js @@ -0,0 +1 @@ +rn_("AQQBoEAAABOJZfL5EwAAAQABAQA7MAAAAQAABgABABwUBgDzBgFl9NATAAABAC8AAQBTAISgIAAACSqwYBLwAIcBAQnz/w8AAGICAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0740e388ca16.js b/pr/545/docs/search.index/0740e388ca16.js new file mode 100644 index 000000000..b4815041d --- /dev/null +++ b/pr/545/docs/search.index/0740e388ca16.js @@ -0,0 +1 @@ +rn_("AYACoCAAAA9YoDAAABNAYXLzAAF0AVEHAAABBAGgQAAAE8Zl8uYTAAABAAEFADswAAABAAALAAUA3g8FAD4SAQBnEwEAuRMAANgTAADjAISgMAAAD1aFAAI7MAAAAQAACwAFAH8FAgCSBgQACgwBAAcRAABPEgAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0773f56876ef.js b/pr/545/docs/search.index/0773f56876ef.js deleted file mode 100644 index 1a1799fb4..000000000 --- a/pr/545/docs/search.index/0773f56876ef.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9AgSAAABAKQAAQABCAD0wRIAAAEAhAABADMBA7BAEpEAAWFiZfV6DAAAAQAWA1ACzwABAAD1wQsAAAEAVAMBAAEA84ACc3UjgQKwgBK8AAFydAGAArBwEkQAAaAQAAAMXm56AQYA9NoPAAABAK8AAQBzAISgoAAAE/ACART1RQUAAAEASQ5RAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/07beea41a07f.js b/pr/545/docs/search.index/07beea41a07f.js deleted file mode 100644 index 0cf4d849c..000000000 --- a/pr/545/docs/search.index/07beea41a07f.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMA9MYIAAABAC8DAQABAwDz8wsAAAEAAQDzgAJpbwEBAbBQEFoAAWP0GgcAAAEAAQACAiOBAqBQAAAQHmNuAQQAOzAAAAEAAAcAAwAPEQIAthIBAEgTAgABAQA6MAAAAQAAAAAABwAQAAAAMhEzEWgSaRK/EsASZhNnE/MJAWkBWRAAANcCAACHsMASqwABoFAAAA8ToRAAABOMFAEXOzAAAAEAACQAAQCjASQA") \ No newline at end of file diff --git a/pr/545/docs/search.index/080595ed9c0d.js b/pr/545/docs/search.index/080595ed9c0d.js new file mode 100644 index 000000000..8d6e23374 --- /dev/null +++ b/pr/545/docs/search.index/080595ed9c0d.js @@ -0,0 +1 @@ +rn_("AQIA9JASAAABAI8AAQABAwD0xBIAAAEAlQABAPMFAmJ1OjAAAAEAAAAAAAcAEAAAAAcQCBC4ELkQZRFmEZsSnBIBAgD08RAAAAEAbQEBAAEFAPP3EAAAAQABAAEEAPQ5EgAAAQCkAAEA84CEEQkA") \ No newline at end of file diff --git a/pr/545/docs/search.index/08c46987941a.js b/pr/545/docs/search.index/08c46987941a.js deleted file mode 100644 index 2eac1838f..000000000 --- a/pr/545/docs/search.index/08c46987941a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQkBoIAAABPfZgHOEgAAAQIA9SsQAAABAAEASAIBAPMAAml1OjAAAAEAAAAAAAcAEAAAAAgQKxIRExITQhNDE2ETYhMBCAD1dBMAAAEAAQABAAEA8wIBZvXtDwAAAQABAAEAAQATgAKwoBO4AAFydPMCAmFz8xoQAAABAAEAAQQBsEATlAABZfVcEwAAAQABAAEAAQABAgA7MAAAAQAACwACAAcTBQC8EwUA8wMBbTswAAABAAANAAQAWgwAALkQAAAlEgUAfBMFAPOBAmNl84ACYWU=") \ No newline at end of file diff --git a/pr/545/docs/search.index/08d9a5c3e851.js b/pr/545/docs/search.index/08d9a5c3e851.js new file mode 100644 index 000000000..0137afb5a --- /dev/null +++ b/pr/545/docs/search.index/08d9a5c3e851.js @@ -0,0 +1 @@ +rn_("AQMA9N8IAAABADYDAQABAwDzEwwAAAEAAQDzgAJpbwEBAbBQEIgAAWP0LwcAAAEAAQAEAiOBAqBQAAAQTGNuAQQAOzAAAAEAAAcAAwA/EQIA5xIBAHsTAgABAQA6MAAAAQAAAAAABwAQAAAAYhFjEZkSmhLxEvISmROaE/MJAWkBhxAAANcCAACHsMAS3AABoFAAAA9AoRAAABO/FAEXOzAAAAEAACQAAQCqASQA") \ No newline at end of file diff --git a/pr/545/docs/search.index/09031ecd90af.js b/pr/545/docs/search.index/09031ecd90af.js new file mode 100644 index 000000000..1e7250d2e --- /dev/null +++ b/pr/545/docs/search.index/09031ecd90af.js @@ -0,0 +1 @@ +rn_("AQMBsEAQ3QABZQExDgAAAQUAOzAAAAEAAAYAAQDkDwYAAQMA9IMMAAABAAEAAQDzAAJwczowAAABAAAAAAAMABAAAACCBZcG4QgMDBkMgRCCECUSJhJ6EnsSfBJ9EjMAA7BQD1kAymRwcjswAAABAAAPAAYAggQAAEMFAwBGDwAAVxEDACASAwBSEgEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0a28cb65ff98.js b/pr/545/docs/search.index/0a28cb65ff98.js deleted file mode 100644 index 94ef4c82e..000000000 --- a/pr/545/docs/search.index/0a28cb65ff98.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOzAAAAEAAAYAAgCCBQUA0RAAAAEEAbAAEmMAAXM7MAAAAQAACwACANwSBwDIEwMARwAAAYaggAAAEr6xABPVAAGwQBIfAAGwgBPjAAGwUBJlAAEVABb0CA4AAAEAAQABAAEFAPNXDwAAAQABAGOAA7BAD98AAW1ubwGBArAADGwAAbAQD90AAXN18wACYWk6MAAAAQAAAAAABwAQAAAAJAc5DxQQFRDKEssSzBLNEgGAA7AAExkAAbAAExsAAbBwE40AATQ2YQEEAPTcEwAAAQAKAAEAI4ECoEAAABCqbXABAgA7MAAAAQAADgAEACcHAQCODAEAnBAJANgQAAABAQA7MAAAAQAACAADABMSAACEEgAA6RMGAAEBADswAAABAAAKAAMAvhACAPQSAwDREwMAI4ACoDAAAA+wZGfXAwAAxqCAAAAR7kBGgAg7MAAAAQAAGAAJAE4PAQBjEAEAmBABAKYQAwAVEQYA+BICAEUTAACdEwEAzRMBAAEDAPbQCAAAVwCxBgEArwABABOAArBwE24AAW9yAQQBsLATtQABbPSMDAAAAQATAwEAAQIAOzAAAAEAAAwAAwCuCAAABxMFALwTBQABAQDzlg8AAAEARgIjgAKgsAAAE21negECADowAAABAAAAAAAJABAAAAAjESQRNhI3Eh4THxNyE3MT4xPkE/MAAW/yKgkAAAEAAQUA9EAPAAABAOcAAQCDAISgQAAADIGwcBKpAAGwIAwIAAEQBQI7MAAAAQAACQADAIwEAwBKBQIAEhECAAGAAqAgAAAQcrAgE24AAWR0AYQCsLATuAABsAATEQABYXPTgISgsAAAE6FAKAQBgAKgMAAAET2wYA9VAAFockf/AQDNoCAAAAVpoCAAAAVqsHATBQABA2c0BzswAAABAAA3ABgAbwQAAKYEBQAgCQAAWgwAABEPAQAAEAMAuRAAABMSAAAlEgUAhBIBAKcSAACvEgAAyRIAANoSAQDkEgAA5hICAOoSAQA+EwAARBMAAFATAQBqEwEAfBMFAJATAADpEwYA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0a8ad4b154a4.js b/pr/545/docs/search.index/0a8ad4b154a4.js new file mode 100644 index 000000000..35f8d54f8 --- /dev/null +++ b/pr/545/docs/search.index/0a8ad4b154a4.js @@ -0,0 +1 @@ +rn_("AYACsFAQgQABoLAAABNkY3MBBADzSQ8AAAEAAQABgAKgUAAAEFOgYAAAEMFpcgGAAqAgAAAMJ6BgAAAQwGVoAQEBoCAAABC/YvMjDAAAAQABABOBAqAQAAAMJmFjAYACoBAAABMwsDAMwQABZXMjAAKgQAAAE8Zld/LmEwAAAQABAwA7MAAAAQAABQACAB8MAwDUEAEAAQYA9H4SAAABAIkBAQATAAKwYBKAAAFmbfKMDAAAAQABAQD0jBAAAAEAqQABACOAAqCwAAATS2RnAYICoKAAABKwoEAAAA/5b3bzgANnbnIBgAKgQAAAEnegMAAAD0ZobLc/AACKsEAPRwABNGBXOzAAAAEAABoABAD6AQAATAQOAKoLCQB9DAAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0bac143bcb50.js b/pr/545/docs/search.index/0bac143bcb50.js new file mode 100644 index 000000000..169f369b7 --- /dev/null +++ b/pr/545/docs/search.index/0bac143bcb50.js @@ -0,0 +1 @@ +rn_("AQkA898TAAABADUAAYACoEAAABLGsCATgQABaGkBDAGgoAAAFCN38hMUAAABAAEBAPN/DwAAAQABAPOAAnR1AYECsIAT7QABoGAAABQRZHM3AwCDhqBAAAATwrBgE5YATAKQDgESAPT7EwAAAQABAAEAAQDGoFAAABJPoAAAABAZsCAQyAABoFAAABFtoQAAABP2oEAAABOgAAMCCzswAAABAAAVAAcAhgUAAOULAACSDAAAjw8NAOwQAABlEgEAmxMBAAEBAbCwE+gAAWw7MAAAAQAADAADAPgGCACxDAEAzQ8BAAEBAaAwAAAQo2jz0AgAAC4AVwgBAgD0TBEAAAEAAQABABOBArAgEVAAAWFz84ICbm/3AQCAh6AgAAAFhaBAAAALzxUBBw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/0bca21001963.js b/pr/545/docs/search.index/0bca21001963.js new file mode 100644 index 000000000..a4edb28c8 --- /dev/null +++ b/pr/545/docs/search.index/0bca21001963.js @@ -0,0 +1 @@ +rn_("AQMBoAAAABK2c/RXDwAA1gMBAAMAAQECsGATowABsEAT3QABZHQ7MAAAAQAADQAGAGoSAwDUEgEAQRMBAFgTAQDSEwEA9xMBAAEBA7BwEXUAAbCAEkcAAYAS6QAQ8G1uczswAAABAAALAAIAwAgFAMkSBQCjgISgsAAAEzCxcBQWAAEIQIIBAISgcAAAEg6gcAAAEIqxABOjAAGwABKqAVkCIQHyUwUAAAEAZwQAAIc7EUdIZJ2gEAAABYWwMBKdAT+gQAAAEK0RwQw7MAAAAQAABgACAPYSAABcEwUA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0bd2d0b4cbf3.js b/pr/545/docs/search.index/0bd2d0b4cbf3.js deleted file mode 100644 index 0e09c1349..000000000 --- a/pr/545/docs/search.index/0bd2d0b4cbf3.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsIASRAABsKASvAABaXQBgAKw4BOwAAGwQA+rAAFscgEGAPQ3EAAAAQABAAEARwUAAIeg0AAAE4ywUA+pAAGgAAAAEr6w8BNqAAEFkQPyTQ8AAKoA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0bd42362d0ac.js b/pr/545/docs/search.index/0bd42362d0ac.js new file mode 100644 index 000000000..502a52f11 --- /dev/null +++ b/pr/545/docs/search.index/0bd42362d0ac.js @@ -0,0 +1 @@ +rn_("AQcA9HgRAAABAAEAAQAjAQKgcAAAEXdhcgFMBwAAAQMAOzAAAAEAAAgAAgAvDwYAxxIBAPMAAmN0OzAAAAEAAFYAJwCIBAsASgUAAN0IAQDdCwAA4gsCAJoMAACmDAIAuAwBAFUPAABaDwEAXQ8BAGMPAADrDwIA8g8BAPcPAQAXEAAAihAAAJAQAADdEAEA6hABAP4QAQACEQIAWxEBAG4RAgB0EQAAJBIAAC0SAQAyEgEAeBIBAIgSAQCMEgEArBIBALwSAwDCEgEAIhMBADQTAACfEwAAxBMEAM0TAgA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0beec91fb1e5.js b/pr/545/docs/search.index/0beec91fb1e5.js deleted file mode 100644 index 51bca2420..000000000 --- a/pr/545/docs/search.index/0beec91fb1e5.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIBoDAAAA/PYQHpCwAAAYECoCAAABBIsFAR+gABYW8BAwGgAAAAExhzAUcQAAAjgAKgAAAAB7NydmMAA7BQELcAAWNlczswAAABAAAIAAQAuAgCAOgIAQDHDwIA4BEAAAcBAICFsFAQeAABoKAAABLksPAS+wABsCAPCwABRCEE84ACbnQ=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0c5310d088a1.js b/pr/545/docs/search.index/0c5310d088a1.js deleted file mode 100644 index d5f5703a7..000000000 --- a/pr/545/docs/search.index/0c5310d088a1.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsFAQUwABoLAAABMxY3MBBADzHA8AAAEAAQABgAKgUAAAECWgYAAAEJNpcgGAAqAgAAAMBKBgAAAQkmVoAQEBoCAAABCRYvMADAAAAQABABOBAqAQAAAMA2FjAYACoBAAABL9sDAMnAABZXMjAAKgQAAAE5Nld/KzEwAAAQABBgD0TRIAAAEAhwEBABMAArBgEk8AAWZt8mgMAAABAAEBAPReEAAAAQCnAAEAI4ACoLAAABMYZGcBggKgoAAAEn+gQAAAD8xvdvOAA2ducgGAAqBAAAASRqAwAAAPGWhsNz8AAIqwQA8aAAGgMAAAC/80YFc7MAAAAQAAGgAEAPMBAAA9BA4AigsJAFkMAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0ca93a7be19c.js b/pr/545/docs/search.index/0ca93a7be19c.js new file mode 100644 index 000000000..9f0b27b33 --- /dev/null +++ b/pr/545/docs/search.index/0ca93a7be19c.js @@ -0,0 +1 @@ +rn_("AQMA8+sPAAABAAEAAYACoLAAABOMsDAS3AABbnRDAAOgIAAAEJawUBFnAAFlaGk7MAAAAQAABgADAMcLAAB4EQMAOBMBAPOAAmRy") \ No newline at end of file diff --git a/pr/545/docs/search.index/0d117775bd82.js b/pr/545/docs/search.index/0d117775bd82.js deleted file mode 100644 index 89b435085..000000000 --- a/pr/545/docs/search.index/0d117775bd82.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQA9KITAAAMAB4ADwABAgGwQBH8AAFlAScPAAABgAKgkAAAE2igkAAAE2kyM5cCAADGoCAAAAwEoGAAABCSsGAMjgABAWQAAzswAAABAAAKAAMA1wYFANMLAACyEgMA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0d555db5d7c8.js b/pr/545/docs/search.index/0d555db5d7c8.js deleted file mode 100644 index b7438356b..000000000 --- a/pr/545/docs/search.index/0d555db5d7c8.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQoA9NoSAAABAA8AAQABgwKgIAAAD6SgMAAAEDZpdAEAAPRJEgAAAQABAAEA8wQBZPTvEQAAAQABAAEAI4aEsKAThAABsEASRwABsHATMgABFYAAAQACsDAPlgABsBAS8gABc3TyYQUAAE4GAYACsMATsAABoAAAAAcNdHnzgIURwQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0d6bfa8c2af1.js b/pr/545/docs/search.index/0d6bfa8c2af1.js new file mode 100644 index 000000000..e16e6edf4 --- /dev/null +++ b/pr/545/docs/search.index/0d6bfa8c2af1.js @@ -0,0 +1 @@ +rn_("AQEA9XsFAAC+DAEApAABAAEAADswAAABAAAHAAMAAgIBABwMAQCiDwMAAYMCsHATAQABsIATOAABY3MBBQD0pBIAAAEAkQABAPMIAWP12w8AAAEAvAABAAEAAQABoDAAABEFdPJEEAAAAQABgAKgAAAAEBWgAAAAEBY0NvMDAXYBrQwAAJcAAACFsKASiAABsCAL2gABsIASZwABCQQGOjAAAAEAAAAAAAkAEAAAANsG3AbdBugLfQ/bEBgSGRIaEr8TAQIA9JASAAABAI8AAQABAwD0xBIAAAEAlQABAPMAAmJ1OjAAAAEAAAAAABUAEAAAABwHHQceB2EPYg8HEAgQJhAnELgQuRBlEWYRjhKPEpsSnBKrEtYS1xIeEx8TAQEA9HcFAAABACQHAQC3AACAhbEAE6UAAbAAByYAAQwIRAEIADswAAABAAAFAAEASRIFANcNAACIsEAQqAABoCAAAAy3uQALOzAAAAEAAA8ABQByAAEA0wYHADUHAQD6DwEApBABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/0e2aac44d870.js b/pr/545/docs/search.index/0e2aac44d870.js new file mode 100644 index 000000000..e0ea83a05 --- /dev/null +++ b/pr/545/docs/search.index/0e2aac44d870.js @@ -0,0 +1 @@ +rn_("AQAA9AwJAAABALUHAQABCQGggAAAFBJmAQATAAABAgD1WRAAAAEAAQBLAgEA8wACaXU6MAAAAQAAAAAABwAQAAAANhBcEkQTRRN1E3YTlBOVEwEIAPWnEwAAAQABAAEAAQDzAgFm9RoQAAABAAEAAQABABOAArCgE+sAAXJ08wACYXPzSBAAAAEAAQDzgAJ0dg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/0e4d0f710b2b.js b/pr/545/docs/search.index/0e4d0f710b2b.js new file mode 100644 index 000000000..df57f1ea5 --- /dev/null +++ b/pr/545/docs/search.index/0e4d0f710b2b.js @@ -0,0 +1 @@ +rn_("AQMA9qwMAADFAloAAQC4AgEAAQQAOzAAAAEAAAoABAAPEAUAQBIBAJ4SAQC6EwAAAYYCoAAAABLAoAAAABLBZHLzAgF2AewSAADzgAJlbycBAADHoDAAAA9woHAAABIRoIAAABONoNAAABMwoLAAABONQEUICTswAAABAAAJAAMAmQUCAPIGBAANDAEAI4ACU5KIn+d+ZHIBAAA6MAAAAQAAAAAACgAQAAAAIAkhCaYP2hLbEgoTCxOuEwIUGBQZFBOAAqAwAAAQJWx084ACYWU=") \ No newline at end of file diff --git a/pr/545/docs/search.index/0f30d894e39f.js b/pr/545/docs/search.index/0f30d894e39f.js new file mode 100644 index 000000000..48b803886 --- /dev/null +++ b/pr/545/docs/search.index/0f30d894e39f.js @@ -0,0 +1 @@ +rn_("AYYCoAAAABLAoAAAABLBZHIBgAKgcAAAE1CgMAAAEJNmdAELAaBAAAATn2XyyRMAAAEAI4ECsFAQawABY3YBAAGwgBOhAAFw8p0TAAABAEMGA6AgAAAQ3KBAAAASJGRlc/N+DwAAMwMBAPMABGlyc3Y7MAAAAQAADwAFAMoGBQBJEgUAdRIBAOwSAADUEwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/0f46828f0101.js b/pr/545/docs/search.index/0f46828f0101.js deleted file mode 100644 index 47dc25efc..000000000 --- a/pr/545/docs/search.index/0f46828f0101.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9AgSAAABAKQAAQABCAD0wRIAAAEAhAABADMAA7BAEpEAAWFiZTowAAABAAAAAAAJABAAAADvBvAGegx7DCMPkQ/dD94P4RGwEg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/0fa5fc027b08.js b/pr/545/docs/search.index/0fa5fc027b08.js deleted file mode 100644 index 1fe709b0c..000000000 --- a/pr/545/docs/search.index/0fa5fc027b08.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBoEAAABNWZfLGEwAAAQABAQA7MAAAAQAABgABAOkTBgDzBgFl9J0TAAABAC8AAQAzAQOgYAAAE0RhcnXz0g8AAF4CAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/100cd8e013cf.js b/pr/545/docs/search.index/100cd8e013cf.js new file mode 100644 index 000000000..638ecb111 --- /dev/null +++ b/pr/545/docs/search.index/100cd8e013cf.js @@ -0,0 +1 @@ +rn_("AQQBoEAAABOJZfL5EwAAAQABAQA7MAAAAQAABgABABwUBgDzBgFl9NATAAABAC8AAQAzBQOwYBLwAIdhcnXz/w8AAGICAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/104ed5107cd6.js b/pr/545/docs/search.index/104ed5107cd6.js deleted file mode 100644 index 6f9da0cfd..000000000 --- a/pr/545/docs/search.index/104ed5107cd6.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYMCoJAAABNooJAAABNpMjMBgAKgUAAAE5CggAAAErtjZfMAAnN08v0GAAABAAEAAaCwAAATAWLzkBIAACABAQAjgAKwAA9MA0NkcgEAAbCAE24AAXDyahMAAAEAQwADoCAAABCsoEAAABHzZGVz81EPAAAvAwEAE4ICoCAAABNaZWnzgAJjZQEEADswAAABAAAJAAQAFAkBAPIPAwAvEAEAIhMBALOAhKCQAAATwhABQg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1074492a6ce1.js b/pr/545/docs/search.index/1074492a6ce1.js new file mode 100644 index 000000000..303d4f5fe --- /dev/null +++ b/pr/545/docs/search.index/1074492a6ce1.js @@ -0,0 +1 @@ +rn_("AQMAOzAAAAEAAD8AAgDtCAAANww+AAGAArBQEEQAAbCwEwwAAWFsYwAEsEAPPgABoBAAAA/9YnBydjswAAABAAAGAAEA4BAGAAGAArCAEI4CE7DgE3MAAWlyAQMBsEAQ3QABZQExDgAAAQUAOzAAAAEAAAYAAQDkDwYAAQMA9IMMAAABAAEAAQDzAAJwczowAAABAAAAAAAMABAAAACCBZcG4QgMDBkMgRCCECUSJhJ6EnsSfBJ9ElcAAACFsFAQNgImsFAPWQDKoEAAABEISIADOzAAAAEAAA8ABgCCBAAAQwUDAEYPAABXEQMAIBIDAFISAQDTAISgYAAADJUQCAbzoAEAAAEA1wo=") \ No newline at end of file diff --git a/pr/545/docs/search.index/10e01c839a63.js b/pr/545/docs/search.index/10e01c839a63.js deleted file mode 100644 index be942f033..000000000 --- a/pr/545/docs/search.index/10e01c839a63.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQkA86wTAAABADUAAYACoEAAABKVsCATTgABaGkBDAGgoAAAE/B38uATAAABAAEBAPNSDwAAAQABAPOAAnR1AYECsIATugABoGAAABPeZHM3AwCAhqBAAAATj7BgE2MATAKQDgEAAbBQEFoAAWP0GgcAAAEAAQACAsOAhKAQAAAMB6BQAAAR4AxABA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/117405adffd2.js b/pr/545/docs/search.index/117405adffd2.js new file mode 100644 index 000000000..d38754ec4 --- /dev/null +++ b/pr/545/docs/search.index/117405adffd2.js @@ -0,0 +1 @@ +rn_("AQ0A9UYTAAABAAEAcwABAAECAPSFEAAAAQCGAQEAAQMA9PEQAAABAG0BAQDzAAJidQGfDwAAAQMA9IMQAAABAIYBAQDzhAJkcwECAPPbCAAAAQBYAPOAAml0ARgA8yAUAAABAAEAI4ECsMATRAABY20BBQGgYAAAEjRy9NcLAAABAMUDAQABCQD2XRIAAAEA+QCCADEAAQATgAKwYBBGAAFkbgEDAaBwAAASmGf0LQcAAAEABAIBAAEJAPPfEwAAAQA1AAGBArCAE+0AAaBgAAAUEWRzFwEAiYWw0BQTAAGgQAAAE8KwYBOWAEwCkApnXgAAi7BwEKgAAbCwEqYAAaCgAAASXLDwE3UAAW2BD/SAAAAAAQABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/1175a8ba9773.js b/pr/545/docs/search.index/1175a8ba9773.js deleted file mode 100644 index 2d04c2aaf..000000000 --- a/pr/545/docs/search.index/1175a8ba9773.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9FcQAAABAIMBAQAjgQKgYAAAEnpiaQEAAPRKDwAAAQDqAP8AI4ICsFASjQABZXMBiQKwIBOfAAGgMAAAE6lpcAECAPRfEgAAAQCOAAEAAQMA9JMSAAABAJMAAQDzhQJidQECAPTBEAAAAQBsAQEA84ACaWy3AQAAhaAgAAASZxIBDDowAAABAAAAAAAUABAAAAAvB7wHvQe+B78HqQvdC94L3wvgC3IPLhDlEmMTrBOtE68TuhO7E94T4hMBBQDzSBMAAAEAAQBDhgOwkBPEAAGgAAAAEfdiZHcBgAKwAAjRAAGwIAyJAztkbgEDAPNIDwAAAQD9AAECAPawCwAAAQBYAwEAvAMBAAEAAPTvCAAAAQABAAEAAQAAOzAAAAEAAAYAAgDEEgAAKRMFACOBArBAE5oAAWVz84ADZXh5AQAA9OsIAAABAAEAAQBDgAOgQAAAE8KwIBJbAAFlcngBgAKgQAAADHSwQA9zAAFnbCcaAADJoJAAABKosMAS8AABoBAAABC9oDAAABM/sEAMbAABAEegCzowAAABAAAAAAAJABAAAAA7BTwFcgxzDIcMRA+eD58PUxJUEgEGAPRdEgAAAQCOAAEA8wMBYvRVEAAAAQCDAQEAtwwAAImgcAAAEeWwkBKLAAGwYA+WAAGgMAAAErE4iRM6MAAAAQAAAAAALQAQAAAAiwWMBY0FjgXxBvIGsQiyCLMI5QjmCLULfgx/DIAMhAyFDIYMQA9BD5QPlQ+ZD5oPtw+4D7kPug+7D7wPvQ/cD+EP+w8oECkQlhCXEDgSxRLpEg0TohOuE8wT2xM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/120419dec60e.js b/pr/545/docs/search.index/120419dec60e.js new file mode 100644 index 000000000..e087520fa --- /dev/null +++ b/pr/545/docs/search.index/120419dec60e.js @@ -0,0 +1 @@ +rn_("AQABsIAToQABcPKdEwAAAQBDBQOgIAAAENygQAAAEiRkZXPzfg8AADMDAQABAgA7MAAAAQAAEwABAKkPEwATgYSgUAAAEIugEAAAC9ygIAAADJscQAAzgAOwUBLtAAFhZm4=") \ No newline at end of file diff --git a/pr/545/docs/search.index/127db5988b1f.js b/pr/545/docs/search.index/127db5988b1f.js deleted file mode 100644 index 18b1169a6..000000000 --- a/pr/545/docs/search.index/127db5988b1f.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBoAAAABKFc/QqDwAA0QMBAAIAAQECsGATcAABsEATqgABZHQ7MAAAAQAADQAGADkSAwCjEgEADhMBACUTAQCfEwEAxBMBAAEBA7BwEUUAAbCAEhYAAYASuAAQ7m1uczswAAABAAALAAIApwgFAJgSBQCjgISgsAAAEv2xcBPjAAEIQIIBAISgcAAAEd2gcAAAEFyxABNwAAGwABJ5AVcCIQHyQwUAAAEAZwQAAIcPpfwCewigEAAABXWwMBJsAT2gQAAAEH8RwQw7MAAAAQAABgACAMQSAAApEwUA") \ No newline at end of file diff --git a/pr/545/docs/search.index/12adc117b701.js b/pr/545/docs/search.index/12adc117b701.js deleted file mode 100644 index 256d7aba5..000000000 --- a/pr/545/docs/search.index/12adc117b701.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIBoQAAABOuZPIdBwAABAIBBgGgMAAAETR0AeUSAAABAwGwUBI0AAFl9MkIAAAxAwEA1gMBAQD0egUAAAEAAQABAAEBAaEAAAATomTyeQUAADgClwcAAIewoBIyAAGg4AAAE3kegArzMwQAAAEAAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/133a2aaf2619.js b/pr/545/docs/search.index/133a2aaf2619.js new file mode 100644 index 000000000..84f8e1255 --- /dev/null +++ b/pr/545/docs/search.index/133a2aaf2619.js @@ -0,0 +1 @@ +rn_("AQUAOzAAAAEAAAcAAwA/EQIA5xIBAHsTAgABBADzQhEAAAEAAQAjAAKgYAAAEmlhcvNrEAAAAQC8AQGAAqEQAAAT/7CAE/cAAWl1NwQAgYexUBQaAAGgAAAAEEywcBNEAAGhMAAAFA4KQBsjgAKgMAAAEgludg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/13baa5793c64.js b/pr/545/docs/search.index/13baa5793c64.js new file mode 100644 index 000000000..2b775e4bb --- /dev/null +++ b/pr/545/docs/search.index/13baa5793c64.js @@ -0,0 +1 @@ +rn_("AQABsKASQAABZTswAAABAAAJAAIAtwcHAIASAQABAAGgIAAADJVtAV8FAAABgAKwoBI+AAGwQA9fAAFsbwEAAPR6EgAAAQABAAEA8wQBZPQgEgAAAQABAAEAIwKEsKATtwABsEASeAABsHATZQABFYAAAY0TAAABAAGwgBOhAAFw8p0TAAABAEMAA6AgAAAQ3KBAAAASJGRlc/N+DwAAMwMBAPOBAmVp1wIAAIawIBIFAAGw0BOlAAEXAQL0gwQAAAEAAQDCAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/13f6fe7b94ed.js b/pr/545/docs/search.index/13f6fe7b94ed.js deleted file mode 100644 index 61dcd1c8d..000000000 --- a/pr/545/docs/search.index/13f6fe7b94ed.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAAOjAAAAEAAAAAAAoAEAAAAD4PPw8mECcQrxA5EToRTRJOEtUT1hMBBADzOQ8AANsAAQDzAAFx95AMAAABABEDAQDCAGAAAQDzAAJleTowAAABAAAAAAAOABAAAAC/COYL5wvPD98P4A9vEHAQcRAvEzATQBNBE7ITtxM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/14272828ba1d.js b/pr/545/docs/search.index/14272828ba1d.js deleted file mode 100644 index f3696153e..000000000 --- a/pr/545/docs/search.index/14272828ba1d.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsRATxgABsBAL5gABZW8BBQA7MAAAAQAADQABAOgQDQABAgDzXw8AAAEAAQABAgD0Ww8AAAEAAQABAAEDADswAAABAAAIAAEACxAIAIcHAACHsKAS+wABsNATigABoFAAABNZjBQROzAAAAEAAAYAAwATBwAANxADAPgRAQDzgQJsdPMAAWk7MAAAAQAAhwADAG0EAABFEAAATRGFAAEFAPOsEwAAAQA1AAEAAaBAAAAQSWXzuwgAAAEAKQkTgAKgMAAADzZkcvMAAWXzrQYAAAEAAQDzgAJodAEBADswAAABAACGAAIARRAAAE0RhQATgAKgUAAAD3lpdAEIAPQvEwAAAQCCAAUAEwCEsPATrgAtsJATkQABsFASeQFXQIkAOzAAAAEAABIACQDBDwIAMhEBAGgSAQCJEgEAvxIBACATAQBXEwEAZhMBAKMTAQDXAQAAhrCAEQAAAaBAAAAI4AgwJjowAAABAAAAAAANABAAAACJAIoAHQchCZsLlQxXEFgQ2xHcEV8SYBLuEu8S") \ No newline at end of file diff --git a/pr/545/docs/search.index/1463797a33c0.js b/pr/545/docs/search.index/1463797a33c0.js deleted file mode 100644 index 55bc3eab7..000000000 --- a/pr/545/docs/search.index/1463797a33c0.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMAOzAAAAEAAAkABAAUCQEA8g8DAC8QAQAiEwEAAQIBsEATqgABdDswAAABAAANAAYAORIDAKMSAQAOEwEAJRMBAJ8TAQDEEwEAE4ACsDASbAE9aXABiAKwABMZAAGwABMbAAE0NhOBAqAwAAAQ0WRzAYACoCAAAAwHsGATSwABbngBBQDz5hIAAAEAAQATgAKgMAAAEz5lefMAhBIAA/KYDwAA2wDzgAJydA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1507fd45a0d0.js b/pr/545/docs/search.index/1507fd45a0d0.js new file mode 100644 index 000000000..ebf3252a2 --- /dev/null +++ b/pr/545/docs/search.index/1507fd45a0d0.js @@ -0,0 +1 @@ +rn_("AQsBoEAAABOfZfLJEwAAAQABBQD0eBEAAAEAAQABAAGDArAAEGsAAbBQEucAAWR3E4ACoKAAABNYZXYBAgD0hRAAAAEAhgEBAAEAAPR3DwAAAQDrAAEBI4ICsFASvgABZXMBAgD0kBIAAAEAjwABAAEDAPTEEgAAAQCVAAEA84UCYnUBAgD08RAAAAEAbQEBAPOAAmls8wADYnR1OjAAAAEAAAAAAA8AEAAAAEQH0QfSB9MH1AefD1wQFxOWE98T4BPiE+0T7hMRFBUUAQwA83sTAAABAAEAAYACsAAI6AABoCAAAAyuZG4BBgD0jhIAAAEAjwABAPMDAWL0gxAAAAEAhgEBAJcGAACHsEAPdQABoHAAABIWsJASvAABOAkDOjAAAAEAAAAAACQAEAAAAJwFnQWeBZ8FBgcHB+YLowykDKUMqQyqDKsMbQ9uD8EPwg/GD8cP5A/lD+YP5w/oD+kP6g8oEC0QVhBXEPcSGxNAE9UT4RP/Ew4UAQMA9KISAAABAEUBAQDzgAJjbXcBAIDFsYAUHgABQIEECA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1540dff09ce4.js b/pr/545/docs/search.index/1540dff09ce4.js deleted file mode 100644 index 8f77c19cf..000000000 --- a/pr/545/docs/search.index/1540dff09ce4.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9LUIAAABAFoK4AAnAAAAyqEQAAATqKBAAAAQYrBgE5gAAaAQAAAME7BQEzYAAbAwEMMAAaAAAAAL1LEgE7gAAbBAEGACEEBOsAk6MAAAAQAAAAAAEwAQAAAAywjMCOEI4gigC6ELoguqC60LYwzfEQoSCxIMEsESwhLWEtcSRhNHEw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1545022d8f5e.js b/pr/545/docs/search.index/1545022d8f5e.js deleted file mode 100644 index 5d3d2651e..000000000 --- a/pr/545/docs/search.index/1545022d8f5e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQgBoIAAABPfZgHOEgAAE4ACoOAAABOnYnABAwGwABNjAExz9UAPAAABAOcAAQDkAgGAArBAEfoAAaAQAAAQZXByAYEDoAAAABDVsAAPKwEdoBAAAA8jZXN184ADYW9yAQIA9SsQAAABAAEASAIBAAEEADswAAABAAAJAAEAnBAJAAGBAqCQAAATJrBQEeIAAWJ3o4CEsFATQgABsJASbQABQCADVwMAAIagcAAAEx2gQAAAE4wwQQw6MAAAAQAAAAAAOgAQAAAAlQSWBFMFVAVVBVYFVwVYBVkFWgVbBVwFPAfeCN8I5AjBC8IL4wvkC+ULbAxtDAwOFg8XDxgPKw9KD0sPkA8IEBYQFxA1EDYQSBBtEG4Q2RAmES8RMBE0ESsSYxJkEhETEhMYE0ITQxNhE2ITeRPcE90T5xPoEw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/157deb90a29d.js b/pr/545/docs/search.index/157deb90a29d.js deleted file mode 100644 index 01446c46b..000000000 --- a/pr/545/docs/search.index/157deb90a29d.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYICsEASBAABsEASBgABNDYBBgD03BMAAAEACgABAPMCAXIBRRMAAPMDAWX01g8AAAEApgABAFOAA7CwE2QAAWFlaQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/15883d436710.js b/pr/545/docs/search.index/15883d436710.js new file mode 100644 index 000000000..184d98bca --- /dev/null +++ b/pr/545/docs/search.index/15883d436710.js @@ -0,0 +1 @@ +rn_("AYECoBAAABKwoHAAABL3YWMBhwKwABNMAAGwABNOAAE0NlMAhKCQAAAS2LCwE3MAAYEACfX3BgAANQDtCA0BGAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/1593ad1b0859.js b/pr/545/docs/search.index/1593ad1b0859.js new file mode 100644 index 000000000..5c0f977d5 --- /dev/null +++ b/pr/545/docs/search.index/1593ad1b0859.js @@ -0,0 +1 @@ +rn_("AYACoFAAABDBoFAAABIEYXUBgwKxABQYAAGw0BQKAAFrbQEEAaCgAAAUI3fyExQAAAEAAQsA9IUTAAABAAEAAQAjgAKggAAAE61lb2MDA6BgAAATQ2VucAHZCwAAI4ACoEAAABBTbXABCgDzZxMAAAEAcAATgAKiEAAAFCNsb/cAAACFoQAAABPaBIEDOzAAAAEAADsABACTBQUAIQcAAHQHMwABEQAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/15d820844df2.js b/pr/545/docs/search.index/15d820844df2.js new file mode 100644 index 000000000..af028a449 --- /dev/null +++ b/pr/545/docs/search.index/15d820844df2.js @@ -0,0 +1 @@ +rn_("AQABsIATUQABdAHjCAAAAQkA8zsSAAABAAEA84ACY2cBgwKgkAAAE5ugkAAAE5wyMwGAAqBQAAATw6CAAAAS7GNl8wACc3TyEgcAAAEAAQABoLAAABM0YvPBEgAAIgEBACOAAqAAAAASwGRyI4ACoFAAABONY2XzgAJpeQEGAPW6EAAAAQABAAEAAQABAQGwQBPHAAFl9Y8TAAABAAEAAQABAPcAAICFoBAAAAvIKWAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/167471e48607.js b/pr/545/docs/search.index/167471e48607.js deleted file mode 100644 index fb5d0d4cd..000000000 --- a/pr/545/docs/search.index/167471e48607.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQA8xIRAAABAAEAAYICsEASBAABsEASBgABNDYBBgD03BMAAAEACgABAPMCAXIBRRMAAPMCAWX01g8AAAEApgABABOAAqBQAAASOGR00wCEsLATZAABEQEB9z0QAAABAGwAHQABAAEALgE=") \ No newline at end of file diff --git a/pr/545/docs/search.index/169d5b098f4e.js b/pr/545/docs/search.index/169d5b098f4e.js deleted file mode 100644 index 1658ab7e5..000000000 --- a/pr/545/docs/search.index/169d5b098f4e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBsAASYwABczswAAABAAALAAIA3BIHAMgTAwBHAAABhqCAAAASvrEAE9UAAbBAEh8AAbCAE+MAAbBQEmUAARUAFvQIDgAAAQABAAEAAQUA81cPAAABAAEAY4CEsEAP3wABoAAAAAafAPAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/16ea9b1933a4.js b/pr/545/docs/search.index/16ea9b1933a4.js new file mode 100644 index 000000000..dd302a4db --- /dev/null +++ b/pr/545/docs/search.index/16ea9b1933a4.js @@ -0,0 +1 @@ +rn_("AQYA9H4SAAABAIkBAQATAgKwYBKAAAFmbfKMDAAAAQAjggKwQBKsAAFlbAEFAPRrEwAAAQBJAAEA8wMBY/JzEgAAAQABgQKgAAAACPugMAAAD1xzdBOAAqAQAAAHIG5404CEsHAUFgABkEAB") \ No newline at end of file diff --git a/pr/545/docs/search.index/1707a9d5b2af.js b/pr/545/docs/search.index/1707a9d5b2af.js deleted file mode 100644 index 8c5d8f41e..000000000 --- a/pr/545/docs/search.index/1707a9d5b2af.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIBsEATqgABdDswAAABAAANAAYAORIDAKMSAQAOEwEAJRMBAJ8TAQDEEwEAE4ACsDASbAE9aXABBQDz5hIAAAEAAQATgAKgMAAAEz5leVMAA7BwE0sAAWJlcwGYDwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/171a39168019.js b/pr/545/docs/search.index/171a39168019.js deleted file mode 100644 index 387f780fd..000000000 --- a/pr/545/docs/search.index/171a39168019.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQACoCAAABLIsDARLwABaXTyMhIAAAEAAQMAOzAAAAEAAAYAAQCwEAYAAQgA9C8TAAABAIIABQATAQOwkBORAAGwUBJ5AVdnbHA7MAAAAQAAEgAJAMEPAgAyEQEAaBIBAIkSAQC/EgEAIBMBAFcTAQBmEwEAoxMBAAGAArAwESsAAbAwES0AAXJ2AQQBsAAR9AABZDswAAABAAAFAAIAJxEDACESAQC3BQABh7BQEfYBDLBgEncAAZQJAzowAAABAAAAAAALABAAAABlDGYMZwwNDg4OWRDaENsQ3BDdEG8SqBIjgAKgEAAADGRubwEDAPO+DwAAAQABACOAAqAAAAALp2RyYwCEoFAAABDXoDAAAA/3FAEQ8lcHAAABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/178adcc5c30e.js b/pr/545/docs/search.index/178adcc5c30e.js deleted file mode 100644 index 1620167a7..000000000 --- a/pr/545/docs/search.index/178adcc5c30e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMAOzAAAAEAAAUAAQAYEgUAAQQBoFAAABNZaPL4EQAAAQABAAKwQBLwAAGgoAAAE3llcjowAAABAAAAAAAHABAAAACDBoQGHgcfB0YPRw8zEDQQ84ADZ2lz") \ No newline at end of file diff --git a/pr/545/docs/search.index/17a463b91cd9.js b/pr/545/docs/search.index/17a463b91cd9.js new file mode 100644 index 000000000..d93bc1b09 --- /dev/null +++ b/pr/545/docs/search.index/17a463b91cd9.js @@ -0,0 +1 @@ +rn_("AYMCoJAAABOboJAAABOcMjMBgAKgUAAAE8OggAAAEuxjZfMAAnN08hIHAAABAAEAAaCwAAATNGLzwRIAACIBAQAjgAKwAA95A0dkcgEAAbCAE6EAAXDynRMAAAEAQwADoCAAABDcoEAAABIkZGVz834PAAAzAwEAE4ICoCAAABONZWnzgAJjZQEEADswAAABAAAJAAQAKwkBAB8QAwBdEAEAVRMBALOAhKCQAAAT9RABQg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/17fbc7f79103.js b/pr/545/docs/search.index/17fbc7f79103.js deleted file mode 100644 index a0463480d..000000000 --- a/pr/545/docs/search.index/17fbc7f79103.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsHARIwABsCAPQgDoaHkBBQD0jAwAAAEAEwMBAAEAAPTzCwAAAQABAGYAAQIAOjAAAAEAAAAAAAkAEAAAADcPOA8lEN4QLBItEiQTphPXE9gTAQMA89MIAAABAAEA1wMAAIagQAAAET4YQAc6MAAAAQAAAAAAFwAQAAAAJQcmB7QH4AgUCRUJiwwkDyUPRQ/rD/IP8w/0D/UPLxAwEGYQZxDTESITIxNOE08T") \ No newline at end of file diff --git a/pr/545/docs/search.index/1854d56f88c5.js b/pr/545/docs/search.index/1854d56f88c5.js deleted file mode 100644 index bb069cb5f..000000000 --- a/pr/545/docs/search.index/1854d56f88c5.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEBoEAAABDVc/XICwAA4wQ8AQEAAQATggKgIAAADJJlcgECAPRGDwAAAQDsAAEAI4ECoBAAAAvHZWkTgAKg8AAAE1pucjMAA7AwCN4AAWVvdAEiEQAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/18eec5319d0e.js b/pr/545/docs/search.index/18eec5319d0e.js new file mode 100644 index 000000000..15b31f5ef --- /dev/null +++ b/pr/545/docs/search.index/18eec5319d0e.js @@ -0,0 +1 @@ +rn_("AQkA898TAAABADUAAQ0BoKAAABQjd/ITFAAAAQABgQKwgBPtAAGgYAAAFBFkczcBAIaFoEAAABPCsGATlgBMApAK") \ No newline at end of file diff --git a/pr/545/docs/search.index/1915837c9928.js b/pr/545/docs/search.index/1915837c9928.js deleted file mode 100644 index 41e4aea6a..000000000 --- a/pr/545/docs/search.index/1915837c9928.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYAOzAAAAEAAAkAAQCcEAkAI4ADsGASvAABsDAPJAABaXN0AQgA9XQTAAABAAEAAQABAPMBAWb17Q8AAAEAAQABAAEAY4ADoDAAABJ+ZWd0") \ No newline at end of file diff --git a/pr/545/docs/search.index/1928b541c754.js b/pr/545/docs/search.index/1928b541c754.js deleted file mode 100644 index a9721c735..000000000 --- a/pr/545/docs/search.index/1928b541c754.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQwBoKAAABPwd/LgEwAAAQABAQDzUg8AAAEAAQABiYSggAAAE96gQAAAE4+gYAAAE6+gkAAAE+ICgAoTgYSgoAAAEySxoBPuAAGw0BOIAAEEAQnzgANhdHU=") \ No newline at end of file diff --git a/pr/545/docs/search.index/19baf510d15e.js b/pr/545/docs/search.index/19baf510d15e.js new file mode 100644 index 000000000..20caee6c1 --- /dev/null +++ b/pr/545/docs/search.index/19baf510d15e.js @@ -0,0 +1 @@ +rn_("AQABoEAAABAtdPWeDAAAHwPXAgEAtgDzAAFzOzAAAAEAABgACACUBAIA3gsBAHUPAQA3EAEAdBABAF0RAQAOEwcA+xMDACOAArEQFAAAAWF0") \ No newline at end of file diff --git a/pr/545/docs/search.index/19beb5bb0c16.js b/pr/545/docs/search.index/19beb5bb0c16.js deleted file mode 100644 index dfd610cdd..000000000 --- a/pr/545/docs/search.index/19beb5bb0c16.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBoAAAABMYcwFHEAAAAYACsDAP3QABsFAP3wABYWkBgAKgsAAAE6GgMAAAEHJsbhcBAACFoCAAABHdoCAAAAiusIATbgABEJEEOjAAAAEAAAAAABAAEAAAAG8EpgSnBKgEqQSqBKsEIAkRDxIPhRI+E0QTUBNRE2oTaxMBAgA6MAAAAQAAAAAACgAQAAAACQkKCXkPqRKqEtgS2RJ7E88T5RPmEwEAADswAAABAAAGAAIAxBIAACkTBQABAgGwMBKWAAFjOjAAAAEAAAAAABMAEAAAAIEMKA++D78PwA/FD8YPyg/LD1wQzhDSENMQ1BBEEYsSjBJsE5ETkhMBgQKwMBNkAAGwQBC6AAFhZROAAqCwAAATqGFlAQEBsEATlAABZfVcEwAAAQABAAEAAQATgAKgEAAAC6hhb4cPAADIsDAIvwcQsEATmgABoIAAABHYQEyICfOzBwAA+wM7AAGAAqCAAAASsKCQAAASiGFrAQMA8/4RAAABAAEAI4CEsSAT4wABoAAAAAjkoDAAAA8vBAQGAQgA9esTAAABAAEAAQABABOKArBAE8YAAWFykwCEoMAAABKEoQAAABNNAUAG8jUHAAABAAEDAaBAAAARPmXziwwAANsDAQABBQD09BIAAAEAAQABAFOAA7AAEqsAAWVzdAEGAPTREwAAAQABAAEA8wgBbfTqEQAAAQABAAEAAQIAOzAAAAEAAAUAAQC8EwUA8w0BbTswAAABAAAFAAEAfBMFAAEEAPeTDAAAAQBfBQ4AAQCLAAEAAQMBgBK4ABDuczswAAABAAAFAAEAmBIFACOCAqCQAAATkGlzAQUBoFAAABNZaPL4EQAAAQATgAKwMBKrAAFudAGAAqCAAAASybBAETcAAWFlAYACoBAAABBooAAAABCsbnIBCQGgQAAAE5Nl8rMTAAABACOAAqCQAAAS/mlsxyMAAAqgMAAAEGmwUBJhAAGw8BPZAAGwcBLGAAGg0AAAE5wwYmNlaGlrbm92OzAAAAEAABoACwCnCwAAQRADAEcRBADDEgAA0RIDAAUTAQBNEwAAUhMDAG4TAQB6EwAAjRMBAAECAqCwAAAThqCwAAATh2Nz8x8QAAABAFwAAQECsFARNwABoMAAABNZaGnyBRMAAAEA84ACZWkBAQGgkAAAEsNz9AQQAAABAAEAAQABAwGwABA7AAFzAa0PAADzgANoaXQBAQGgUAAAEkZjAVkMAAABBQGwgBONAAF2OzAAAAEAAAcAAgAVEQQA+BICAAEBAPTNDwAAAQCoAAEA44CEsHAROwABDggA92UPANGwkBHWAAGgUAAAEGGhAAAAE8KgoAAAEuWgEAAABwtAP78pOzAAAAEAADgAGACXBAAAmQQAAGMFAgDUBgIAlQsDAFwMAQAcDwIAKg8AAFEPAABaDwAAeg8BAH8QCADVEAAAFhIBAB8SAQAjEgEAgBIBAJ4SBADyEgEA+xIBAP4SAAB0EwQAwhMAAN8TAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/19c5f33045ce.js b/pr/545/docs/search.index/19c5f33045ce.js deleted file mode 100644 index ec03fa512..000000000 --- a/pr/545/docs/search.index/19c5f33045ce.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIBsEATqgABdDswAAABAAANAAYAORIDAKMSAQAOEwEAJRMBAJ8TAQDEEwEAE4ACsDASbAE9aXABBQDz5hIAAAEAAQATgAKgMAAAEz5leVMBA7BwE0sAAWJlcwGYDwAAE4ADsDATuAABsCAGvAABZWxz") \ No newline at end of file diff --git a/pr/545/docs/search.index/19d0359d569b.js b/pr/545/docs/search.index/19d0359d569b.js new file mode 100644 index 000000000..94eb07afc --- /dev/null +++ b/pr/545/docs/search.index/19d0359d569b.js @@ -0,0 +1 @@ +rn_("AQEBoEAAABPGZfLmEwAAAQABgAOgMAAAEhCw4BOlAAGwkBPoAAFhY22HAQCAhrAQEKgAAbAQEMgAAaCgAAAT1KDwAAAT9TFJAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/19d4d15f26c3.js b/pr/545/docs/search.index/19d4d15f26c3.js deleted file mode 100644 index ba0360356..000000000 --- a/pr/545/docs/search.index/19d4d15f26c3.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABsPAT2QABa/ZNEwAABQABAAEAAQAlABMAArEAE8YAAWRu8hYSAAABABOAArAQC+YAAWVvAQUAOzAAAAEAAA0AAQDoEA0AAQIA818PAAABAAEAAQIA9FsPAAABAAEAAQABAwA7MAAAAQAACAABAAsQCAABgAKgQAAAEF2wwBOKAAFlcwEBADswAAABAAATAAEAfA8TACOAArCQEvsAAWltNzYAAIqgEAAAC7ygUAAAE1mwcBM6AAGgIAAADHecVRE7MAAAAQAABgADABMHAAA3EAMA+BEBAPOAAmx0") \ No newline at end of file diff --git a/pr/545/docs/search.index/19da7e04c741.js b/pr/545/docs/search.index/19da7e04c741.js deleted file mode 100644 index 5febf214b..000000000 --- a/pr/545/docs/search.index/19da7e04c741.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9PgGAAABAAEAAQABhQKwcBNLAAGwMBKjAAFlcxMAA7BADzAAAaBgAAAQ2GJlczswAAABAAASAAQAcwUBAIcGCgCpDwEA/A8DAAECAPN+BQAA1wkBAAEDAPUoDwAAnQABAAQAAQABCgGgQAAAE5Nl8rMTAAABACMABKAwAAAQaaCQAAASybBgEfgAATBjaGn1RxEAAIoBAQABAAEA84ACZHLnBAAAh7AQCK0DHbAgC5sA+qAwAAAPTRJBODswAAABAAASAAYAhAACAGYFAACTBQMAWQcFAJwHAwCmCwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/1a66cd07757a.js b/pr/545/docs/search.index/1a66cd07757a.js new file mode 100644 index 000000000..bde846ae8 --- /dev/null +++ b/pr/545/docs/search.index/1a66cd07757a.js @@ -0,0 +1 @@ +rn_("AQQBoEAAABD/ZQHADwAAAQgA9DoRAAABAAEAAQABAwGgQAAAEP5lAU8PAAABAgDz4gsAAAEAAQAjAAKwIAvTAAFrcvbGBgAAAQC5CecAAQAkAvOAAnJ4AQMBsIATwAABdjswAAABAAALAAMAkRABAEURBgAqEwIAI4ACsGAQCQC7YXIBAwGgAAAAD79z8k0PAAABACOAAqCwAAATUGVoAQMBoEAAABCQZfLkCAAAAQDXCwAAirAgBzgJh7CwEqIAAaCAAAARPqAAAAASr58ITDowAAABAAAAAAAKABAAAAD7AVwEXQReBL4LvwsjDCQMJQywEsYS") \ No newline at end of file diff --git a/pr/545/docs/search.index/1b2b113ba497.js b/pr/545/docs/search.index/1b2b113ba497.js new file mode 100644 index 000000000..4c86a3eb8 --- /dev/null +++ b/pr/545/docs/search.index/1b2b113ba497.js @@ -0,0 +1 @@ +rn_("AQYAOzAAAAEAAAkAAQDKEAkAAQIAOzAAAAEAABMAAQCpDxMAE4GEoFAAABCLoBAAAAvcoCAAAAybHEAAE4ACsFAS7QABYW4zgAOwMA9RAAFpc3Q=") \ No newline at end of file diff --git a/pr/545/docs/search.index/1b7cc07f1f34.js b/pr/545/docs/search.index/1b7cc07f1f34.js new file mode 100644 index 000000000..8031a5eef --- /dev/null +++ b/pr/545/docs/search.index/1b7cc07f1f34.js @@ -0,0 +1 @@ +rn_("AYkCsCAT0gABoDAAABPcaXATAAOgIAAAEpiggAAAEqtlaXX1yQsAADQAAQABAAEAAYYCsJAT9wABoAAAABIoYmQBgAKwMBKMAAGgMAAAEHRydtcAAAKFoDAAAA/xoDAAABLiEAETOjAAAAEAAAAAAAkAEAAAAMoIywjMCPwI/QgJEA4QxBDFEGkSAQMBsDASpgABc/NIEAAAAQABAAEAADswAAABAAAKAAMA7hACACYTAwAEFAMAlwEAAIWgIAAABYmwIAfVAAFQGAH1LQwAAAEAAQABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/1bd9e21009c9.js b/pr/545/docs/search.index/1bd9e21009c9.js deleted file mode 100644 index f04644aaf..000000000 --- a/pr/545/docs/search.index/1bd9e21009c9.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQcA9EgRAAABAAEAAQAjAQKgcAAAEUdhcgE3BwAAAQMAOzAAAAEAAAgAAgACDwYAlhIBAPMAAmN0OzAAAAEAAFYAJwB5BAsAOgUAAMQIAQC9CwAAwwsCAHYMAACBDAIAkwwBACgPAAAtDwEAMA8BADYPAAC+DwIAxQ8BAMoPAQDqDwAAXBAAAGIQAACtEAEAuhABAM4QAQDSEAIAKxEBAD4RAgBEEQAA8xEAAPwRAQABEgEARxIBAFcSAQBbEgEAexIBAIsSAwCREgEA8BIBAAETAABsEwAAkRMEAJoTAgA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/1bf00b4f0c44.js b/pr/545/docs/search.index/1bf00b4f0c44.js new file mode 100644 index 000000000..be881b667 --- /dev/null +++ b/pr/545/docs/search.index/1bf00b4f0c44.js @@ -0,0 +1 @@ +rn_("AYMCsQAUGAABsNAUCgABa20BCgDzZxMAAAEAcAATgAKiEAAAFCNsbzMChKBgAAASBKEAAAAT2gSAAzswAAABAAA0AAIAIQcAAHQHMwA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/1c14aa28ba9e.js b/pr/545/docs/search.index/1c14aa28ba9e.js deleted file mode 100644 index 2de2a1e95..000000000 --- a/pr/545/docs/search.index/1c14aa28ba9e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsHAR1gABsCAT2QABaW8BAAGw8BPZAAFr9k0TAAAFAAEAAQABACUA8wUBZPIWEgAAAQABAgDzKxAAAAEAAQDzAAFpOjAAAAEAAAAAAAcAEAAAAAgQKxIRExITQhNDE2ETYhMjgwKwsBO4AAFhcwGBAqCgAAASf6BAAAAPzG9284CEAVAB") \ No newline at end of file diff --git a/pr/545/docs/search.index/1c262f510d82.js b/pr/545/docs/search.index/1c262f510d82.js new file mode 100644 index 000000000..a323c4011 --- /dev/null +++ b/pr/545/docs/search.index/1c262f510d82.js @@ -0,0 +1 @@ +rn_("AQEBoGAAABP2c/JQEQAAAQABCAD1pxMAAAEAAQABAAEAowCEsCAJPwABoIAAABJcMEAIOzAAAAEAAAUAAgDkAQAAGhAEAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1d17a7bb5df0.js b/pr/545/docs/search.index/1d17a7bb5df0.js deleted file mode 100644 index c3a792cf4..000000000 --- a/pr/545/docs/search.index/1d17a7bb5df0.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUAOzAAAAEAAAcAAwAPEQIAthIBAEgTAgABBADzEhEAAAEAAQAjAAKgYAAAEjhhcvM9EAAAAQC5AQGAAqEQAAATzLCAE8QAAWl1NwQAgoexUBPnAAGACM0AF1CwcBMRAAGhMAAAE9sKQBsTgAKwEBJEAAFpcg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1d3f2d3bd8f6.js b/pr/545/docs/search.index/1d3f2d3bd8f6.js new file mode 100644 index 000000000..af8545e4e --- /dev/null +++ b/pr/545/docs/search.index/1d3f2d3bd8f6.js @@ -0,0 +1 @@ +rn_("AQMBoAAAABK2c/RXDwAA1gMBAAMAAQECsGATowABsEAT3QABZHQ7MAAAAQAADQAGAGoSAwDUEgEAQRMBAFgTAQDSEwEA9xMBAAEBA7BwEXUAAbCAEkcAAYAS6QAQ8G1uczswAAABAAALAAIAwAgFAMkSBQCjgISgsAAAEzCxcBQWAAEIQIJHAQAAhTsRR0hknbEQE6MAAbAwEp0BPxGBCDswAAABAAAGAAIA9hIAAFwTBQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/1d7fbea1f446.js b/pr/545/docs/search.index/1d7fbea1f446.js deleted file mode 100644 index 04101e713..000000000 --- a/pr/545/docs/search.index/1d7fbea1f446.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYICoFAAABIeoQAAABPDY3QjAAKwQA8tAAFldTswAAABAAA3ABYAhQYBAKMLAQB8DAEAMg8BALEPBQDiDwUAWhABALcQAQBBEQIADRIDAD0SBABtEgEAcxIBAIISAQADEwEAFhMBADQTAQA4EwEAWxMAAIITAQCGEwEApRMAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1d8c8f6f3340.js b/pr/545/docs/search.index/1d8c8f6f3340.js new file mode 100644 index 000000000..0aad66da1 --- /dev/null +++ b/pr/545/docs/search.index/1d8c8f6f3340.js @@ -0,0 +1 @@ +rn_("AQMBsDASxwABY/MCEQAAAQABAAEDAYAS6QAQ8HM7MAAAAQAABQABAMkSBQAjggKgkAAAE8NpcwcBAIDFsFASkgABoKAAABMxsHAS+AABoNAAABPPgAEYCPOAAmRy") \ No newline at end of file diff --git a/pr/545/docs/search.index/1dbcf54491ae.js b/pr/545/docs/search.index/1dbcf54491ae.js new file mode 100644 index 000000000..032eb5f2c --- /dev/null +++ b/pr/545/docs/search.index/1dbcf54491ae.js @@ -0,0 +1 @@ +rn_("AQEA9A0HAAABAAEAAQABAQGgQAAAEQVz9egLAADzBD0BAQABABOCAqAgAAAMt2VyI4ADoEAAAAvnsDAI9QABZW90AQAA9AkHAAABAAEAAQABAgD0DBMAAAEADwABABOAArBAE70AAWJ284ACb3gBCgD1RhMAAAEAAQBzAAEAAYECoCAAABB2sFASKwABYW8BBAGgAAAAE0tzAXUQAABjAwOwUBDnAAFjZXP20QgAAAEAAQAsAAEAEQkBAQD0gwwAAAEAAQABACOAArAwEqoBWXJ08wCGAcAH8uMBAADeBQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1de07b6bd5ed.js b/pr/545/docs/search.index/1de07b6bd5ed.js new file mode 100644 index 000000000..0b2e4a6f0 --- /dev/null +++ b/pr/545/docs/search.index/1de07b6bd5ed.js @@ -0,0 +1 @@ +rn_("AYACsAAPpwABsCAMEQABZWkBiQKwIBPSAAGgMAAAE9xpcBMAA6AgAAASmKCAAAASq2VpdfXJCwAANAABAAEAAQABhgKwkBP3AAGgAAAAEihiZAGAArAwEowAAaAwAAAQdHJ21wAAAIWgMAAAD/GgMAAAEuIQARM6MAAAAQAAAAAACgAQAAAAygjLCMwI/Aj9CNULCRAOEMQQxRBpEmOAA7AQCL4AAWRtdA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1dff5e6ecf7f.js b/pr/545/docs/search.index/1dff5e6ecf7f.js new file mode 100644 index 000000000..b0cc7a764 --- /dev/null +++ b/pr/545/docs/search.index/1dff5e6ecf7f.js @@ -0,0 +1 @@ +rn_("AQAAOjAAAAEAAAAAAAoAEAAAAGsPbA9UEFUQ3xBpEWoRfhJ/EggUCRQBBADzZg8AANwAAQDzAAFx97UMAAABABkDAQDDAGIAAQDzAAJleTowAAABAAAAAAAOABAAAADYCAYMBwz8DwwQDRCdEJ4QnxBiE2MTcxN0E+UT6hM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/1e93e59e94d9.js b/pr/545/docs/search.index/1e93e59e94d9.js new file mode 100644 index 000000000..1e17c6d75 --- /dev/null +++ b/pr/545/docs/search.index/1e93e59e94d9.js @@ -0,0 +1 @@ +rn_("AQIBsEAT3QABdDswAAABAAANAAYAahIDANQSAQBBEwEAWBMBANITAQD3EwEAE4ACsDASnQE/aXABBQDzGBMAAAEAAQATgAKgMAAAE3FleVMAA7BwE34AAWJlcwHFDwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/1ebad890e62e.js b/pr/545/docs/search.index/1ebad890e62e.js new file mode 100644 index 000000000..39b6ba28a --- /dev/null +++ b/pr/545/docs/search.index/1ebad890e62e.js @@ -0,0 +1 @@ +rn_("AQEAOjAAAAEAAAAAAAgAEAAAANgI/A+dEJ4QnxBiE2MT5RPqEwECAPQyEAAAAQABAAEAE4ACoNAAABPUY3NTgAOgcAAAE89laW+DgISwIBMIAAGgIAAAD3CwAAckAAEKCAQ=") \ No newline at end of file diff --git a/pr/545/docs/search.index/1ee39b692949.js b/pr/545/docs/search.index/1ee39b692949.js new file mode 100644 index 000000000..0b61e66b9 --- /dev/null +++ b/pr/545/docs/search.index/1ee39b692949.js @@ -0,0 +1 @@ +rn_("AQUAOzAAAAEAAAYAAQDkDwYAAQMA9IMMAAABAAEAAQBjAAOgkAAAEuBocHM6MAAAAQAAAAAADgAQAAAAggWXBuEIDAwZDIEQghAlEiYSehJ7EnwSfRKoEqkS") \ No newline at end of file diff --git a/pr/545/docs/search.index/1f4450a92511.js b/pr/545/docs/search.index/1f4450a92511.js new file mode 100644 index 000000000..e10c427e1 --- /dev/null +++ b/pr/545/docs/search.index/1f4450a92511.js @@ -0,0 +1 @@ +rn_("AQMAOzAAAAEAAIcAAgBzEAAAfRGGAAEAAbBwEzIAAWXyZw8AAAEAIwACoEAAABOJZXP00g8AAAEAJgQBADOAA6BgAAARJmRpbw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1f8374f280ae.js b/pr/545/docs/search.index/1f8374f280ae.js new file mode 100644 index 000000000..8248652c2 --- /dev/null +++ b/pr/545/docs/search.index/1f8374f280ae.js @@ -0,0 +1 @@ +rn_("AQYA9CYTAAABAAEAAQABDwD0BBQAAAEAAQABAAEAAbDwFAwAAWv2gBMAAAUAAQABAAEAJQABAgD0+g8AAAEAqQABAPcAAACFsQAT+QABiTAA8kcSAAABABOAArAQDAYAAWVvAQUAOzAAAAEAAA0AAQAYEQ0AAQIA84wPAAABAAEAAQIA9IgPAAABAAEAAQABAwA7MAAAAQAACAABADkQCAABgAKgAAAAC9ywMBPHAAFxcgGAAqBAAAAQi7DAE70AAWVzAQEAOzAAAAEAABMAAQCpDxMAI4ACsJATLQABaW13NgAAiqBQAAATjLBwE20AAaAgAAAMm5xVETswAAABAAALAAQAKAcAAGUQAwApEgEAjxMEAAECAbAwEPMAAXABEBIAALOAhKAgAAARVgIoBA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/1fac5249737c.js b/pr/545/docs/search.index/1fac5249737c.js new file mode 100644 index 000000000..cd94d35ad --- /dev/null +++ b/pr/545/docs/search.index/1fac5249737c.js @@ -0,0 +1 @@ +rn_("AQEA950QAAABAAEAwwIBAIIABQABAgD0MhAAAAEAAQABABOAAqDQAAAT1GNz84ACZW8jgQKwAAckAAFsdAEAAPSLBQAAAQABAAEAU4CEoFAAABQjsKATbwABCCAF") \ No newline at end of file diff --git a/pr/545/docs/search.index/201011f148a9.js b/pr/545/docs/search.index/201011f148a9.js new file mode 100644 index 000000000..7f0281bf0 --- /dev/null +++ b/pr/545/docs/search.index/201011f148a9.js @@ -0,0 +1 @@ +rn_("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") \ No newline at end of file diff --git a/pr/545/docs/search.index/2063bc13c29e.js b/pr/545/docs/search.index/2063bc13c29e.js deleted file mode 100644 index 251c6bd17..000000000 --- a/pr/545/docs/search.index/2063bc13c29e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAEoAAAAA/ssCAQmgABoFAAABE9oEAAABNtZGxzdjswAAABAAATAAYAdgUAAMYLAABuDAAAYg8NALwQAABoEwEAAQIA9BwRAAABAAEAAQAThAKwIBEgAAFhc/OAAmFl") \ No newline at end of file diff --git a/pr/545/docs/search.index/20a41ecff08f.js b/pr/545/docs/search.index/20a41ecff08f.js new file mode 100644 index 000000000..5ef389029 --- /dev/null +++ b/pr/545/docs/search.index/20a41ecff08f.js @@ -0,0 +1 @@ +rn_("AQIA9WwSAAABAOwAeQABABOAArAwEp0BP2lwAQYA8xgTAAABAAEA8wICYnMBxQ8AAPMBAWbyOAcAAIcJAQIA9MQSAAABAJUAAQAzgAOwQBKSAAFpdXk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/20a57735c5a6.js b/pr/545/docs/search.index/20a57735c5a6.js deleted file mode 100644 index 73f20d9d6..000000000 --- a/pr/545/docs/search.index/20a57735c5a6.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsFATSwABoAAAAAjAY3QBAQD0yhIAAAEAAQABAAEDAPR2DAAAiwaZAAEAAYACoBAAAAwHoFAAABHgY2QBAgDztAgAAC0DAQDzAAFt83gEAADAAAEAAYECoBAAABJ/oHAAABLFYWPzAAFy8xcHAADfCRgAZw8AgIiwMA8sAMqgMAAAE8IpMCM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/20ac1af4f5cb.js b/pr/545/docs/search.index/20ac1af4f5cb.js deleted file mode 100644 index 6d0e782a5..000000000 --- a/pr/545/docs/search.index/20ac1af4f5cb.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBoEAAABE+ZfOLDAAA2wMBAAEGAPRjEAAAAQC2AAEAE4EDoAAAABCqsSATzQABYWRuARQA9esTAAABAAEAAQABAAEFAbCAE40AAXY7MAAAAQAABwACABURBAD4EgIAI4ACsHAROwABYmRXAAABhqDAAAASw6CgAAAS5aCQAAASsLBQD90AAQXgAvXUBgAAAQABAIQIaAQBBgDzERIAAAEAqADzgANydHYBAwA7MAAAAQAABwACAPQSAwDREwMA8wABcwGQEwAA8wABcwE9EQAAZwEAgIagMAAAC9SwABKrAAGgEAAADHESQA4=") \ No newline at end of file diff --git a/pr/545/docs/search.index/20afefeb7ec4.js b/pr/545/docs/search.index/20afefeb7ec4.js new file mode 100644 index 000000000..bb1e97cef --- /dev/null +++ b/pr/545/docs/search.index/20afefeb7ec4.js @@ -0,0 +1 @@ +rn_("AQIBoQAAABPhZPIyBwAABgIBBgGgMAAAEWR0ARcTAAABAwGwUBJlAAFl9OIIAAA4AwEA4wMBAQD0iwUAAAEAAQABAAEBAaEAAAAT1WTyigUAADwClwcAAIewoBJjAAGg4AAAE6wegArzQgQAAAEAAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/20da1b8e8e24.js b/pr/545/docs/search.index/20da1b8e8e24.js new file mode 100644 index 000000000..926b71b4d --- /dev/null +++ b/pr/545/docs/search.index/20da1b8e8e24.js @@ -0,0 +1 @@ +rn_("AQEA9boQAAABAAEAAQABACOBArCQE20AAWF0Q4ADsRAT5gABoIAAABMwY290EwACsAATvQABbnL2/QEAAAEAawIBAJ4C8gs=") \ No newline at end of file diff --git a/pr/545/docs/search.index/20fbab33fc2f.js b/pr/545/docs/search.index/20fbab33fc2f.js new file mode 100644 index 000000000..592d56661 --- /dev/null +++ b/pr/545/docs/search.index/20fbab33fc2f.js @@ -0,0 +1 @@ +rn_("AQQBoFAAABO/cwEPEgAAAYICsEASNQABsEASNwABNDYBCwDzLxMAAGgAAQABBgD0DxQAAAEACgABAPMCAXIBeBMAAPMDAWX0AxAAAAEApwABAPOEA2FlaWOAA6BQAAAT9mNldA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/215b5a83d39e.js b/pr/545/docs/search.index/215b5a83d39e.js deleted file mode 100644 index e50381ca5..000000000 --- a/pr/545/docs/search.index/215b5a83d39e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYkCsCATnwABoDAAABOpaXATAAOgIAAAEmeggAAAEnplaXX1qQsAADQAAQABAAEAAYYCsJATxAABoAAAABH3YmQBgAKwMBJbAAGgMAAAEEZydtcAAACFoDAAAA/EoDAAABKxEAETOjAAAAEAAAAAAAkAEAAAALEIsgizCOUI5gjcD+EPlhCXEDgS") \ No newline at end of file diff --git a/pr/545/docs/search.index/2232ff223063.js b/pr/545/docs/search.index/2232ff223063.js deleted file mode 100644 index 8c0a36187..000000000 --- a/pr/545/docs/search.index/2232ff223063.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9DgTAAABAEkAAQDzAwFj8kISAAABACOAArBwE+MAAWhvAYICsAASHwABsAARLwABZXNDAAOgoAAAE4egIAAAEshlaXT1MhIAAAEAhQABAO4AAYACsHASFgABoLAAABNNZW8BAgA7MAAAAQAABgABALAQBgABAgGgQAAAE2xl8pYTAAABAPOAAmlvAQgA9C8TAAABAIIABQATAQOwkBORAAGwUBJ5AVdnbHA7MAAAAQAAEgAJAMEPAgAyEQEAaBIBAIkSAQC/EgEAIBMBAFcTAQBmEwEAoxMBAAGAArBAEfYBDKAgAAAQdWFpAYECsDATQAABsDASFAABY2kBAwGwABJjAAFzOzAAAAEAAA0AAwAtEQEA3BIHAMgTAwABAwD1KxEAAAEAGwEBAFQB84ACcnYBAAA7MAAAAQAABQACAPQRAQBJEgMA8wIBZDswAAABAAAJAAMAJxEDAO8RAwAhEgEAI4ACoJAAABOGaW8TgAKw8BPVAAFsbwEFAPSiEwAADAAeAA8AI4ACoGAAABK+Z3MjgAKwkBOEAAFibPcXAwCPsHARRQABsGATuAABsHATMgABsGASdwABsFASZQABtfkXOzAAAAEAADwAGAB+BQAAJwcBAKcIBQC3CAAA5wgAAKgLAADxCwEAZQwCAI4MAQAIDgMADQ4BAFUPBAAfEAEAWRAAAHwQAACcEAkA2BAAANoQAwAlEQAAbxIAAIYSAQCYEgUAqBIAAFoTAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/224409c019b5.js b/pr/545/docs/search.index/224409c019b5.js deleted file mode 100644 index c72b8a3b1..000000000 --- a/pr/545/docs/search.index/224409c019b5.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEBsFAPMgABY/R0BAAAAQABAMEAAQABoIAAABPfZgHOEgAA8wYBc/KKDAAAXQQzAAOgYAAAE8NjaXPyIBEAAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/227000c17c1b.js b/pr/545/docs/search.index/227000c17c1b.js new file mode 100644 index 000000000..669a76959 --- /dev/null +++ b/pr/545/docs/search.index/227000c17c1b.js @@ -0,0 +1 @@ +rn_("AQUBsEASMgABZfJUEgAAAQABAAA7MAAAAQAAEQAEAPABAQA5EAgAMhEDAC8SAgABCgGwQBPHAAFl9Y8TAAABAAEAAQABAEcGAACHsCAQjwIqsMAUDAABoCAAAAbQsDAHKgABGIkKOjAAAAEAAAAAAAwAEAAAACYHJwcOCdML1AvaC9sLKwwsDHYMdwyCEoMS") \ No newline at end of file diff --git a/pr/545/docs/search.index/22f66fe81db4.js b/pr/545/docs/search.index/22f66fe81db4.js new file mode 100644 index 000000000..e0bef0582 --- /dev/null +++ b/pr/545/docs/search.index/22f66fe81db4.js @@ -0,0 +1 @@ +rn_("AQMAOzAAAAEAAIcAAgBFBwAAQwmGAAGEArBwE50AAaBAAAAQk2lzAQcA820QAAABAA4BI4ACoLAAABJEYXQBAAOwMAjwAAGwMBMBAAGgIAAAB0ZhZG8BBgIAADcDAICGoMAAABOVsAATaQABAJgV") \ No newline at end of file diff --git a/pr/545/docs/search.index/230d9ae0255e.js b/pr/545/docs/search.index/230d9ae0255e.js new file mode 100644 index 000000000..0d0dbd079 --- /dev/null +++ b/pr/545/docs/search.index/230d9ae0255e.js @@ -0,0 +1 @@ +rn_("AQMBgBLpABDwczswAAABAAAFAAEAyRIFACOCAqCQAAATw2lzAQEA9JASAAABAI8AAQAjgAKwoBNzAAFjbgGEArCgE4EAAbCgE4MAAWNyAQIAOzAAAAEAAAYAAQDkDwYAE4ICoCAAABNkZXUBAgDzQhEAAAEAAQABgAKwIBOjAAGgYAAAEvdvdmOBA6AQAAASsGFjcwEDAPSDDAAAAQABAAEAAQEA8+oIAAABAAEAAQEA9HoQAAABAJoAAQBTgAOgwAAAE89ucHUBgAKwMA+gAAGhYAAAFANhZQGBArBAEjUAAbBAEjcAATQ2AQUBoFAAABOMaPIpEgAAAQABBQD0+g8AAAEAqQABAHOAhLAwEtwAAQGgBAEIAPPYEgAACAAbABOAArBAEWcAAWFlAQoA8y8TAABoAAEAAQABoCAAABAXcgHcEAAAAQAA9DITAAABAEsAAQCnAQCAhaAwAAAQd6AQAAAQlgkgIQEJAaBAAAATxmXy5hMAAAEAQ4CEoCAAABPUoJAAABMxoTAAABPlEEkAAQIA9MQSAAABAJUAAQATgAKwQBKSAAFpeQEBAqAwAAASaaBAAAASr2dyOzAAAAEAAAcAAgB4EAEADxEFAAGAArAAE0wAAbAAE04AATQ2AQYA9A8UAAABAAoAAQDzAgJydgF4EwAA8wIBZfQDEAAAAQCnAAEA84ACZHTnrT8AEqAwAAAQl6BAAAAMmLDwFAwAAbBwEvgAATBhYmNlZ2hpa2xub3Byc3R1djswAAABAAAHAUYAowQAAIIFAACJBQAAiwUDAJcGAAD3BgAAHAcCACwHAAA+BwUARQcAAKgHAADPBwEAzggBANQIAQDhCAAAPwkBAEMJhgC5CwEAxwsAAMsLAQDWCwAADAwAABkMAAA6DwEAYQ8BAHkPAADdDwAABxABABkQAAAmEAEAaxABAG8QAwCBEAEAuBABANoQAAD3EAIAJhEAAD4RAABhEQAAZREBAGsRAQB3EQQAFhIAACUSAQAoEgAANBIAAEUSAQB6EgMAjhIBAJsSAQCiEgEAqBIBAKsSAACuEgAAwBIAANYSAQD1EgAAAxMEAB4TAQAwEwAAMhMBADgTAQBDEwAAfhMCAIUTBAChEwEArRMAAMATAQDoEwEAIxQAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/23daddc85a2a.js b/pr/545/docs/search.index/23daddc85a2a.js new file mode 100644 index 000000000..2fb4f07a7 --- /dev/null +++ b/pr/545/docs/search.index/23daddc85a2a.js @@ -0,0 +1 @@ +rn_("AQABoDAAAAx8aQHiEgAAAQABsDAQxgABbvIqBwAAAQABAQDzqAcAAJIHAQATAAKgUAAAEChlc/U7BAAAAQABAAEAAQABhAKwoBOBAAGwoBODAAFjcvMBAXTzYREAAOQAAQABAwGwYBPLAAFmOzAAAAEAAAYAAwDACwIA8xIBAHkTAQDzgAJhZfOAhAAoBQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/240436689105.js b/pr/545/docs/search.index/240436689105.js new file mode 100644 index 000000000..a4e34eeb2 --- /dev/null +++ b/pr/545/docs/search.index/240436689105.js @@ -0,0 +1 @@ +rn_("AQEBsIAS1gABdfITCQAAAQAjgAKwEAkRAAEzNgECAPMjBwAA7AEBAAECAPQMCQAAAQC1BwEAAQIA8wMMAAABAAEAE4ACsBAJCgABaXUBAgA7MAAAAQAACwACADoTBQDvEwUA8wkBbTswAAABAAAMAAMA6RAAAFYSBQCvEwUAdzAAAIqgMAAAE1CgcAAAEXSgIAAACQ6wMBE4AAGgUAAAD4czhQs7MAAAAQAAJgIEAO0BAAATAisBRwcAAMoJ+AA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/246c639fd848.js b/pr/545/docs/search.index/246c639fd848.js deleted file mode 100644 index 015249243..000000000 --- a/pr/545/docs/search.index/246c639fd848.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9DgTAAABAEkAAQDzAwFj8kISAAABACOAArBwE+MAAWhvAYICsAASHwABsAARLwABZXNDAAOgoAAAE4egIAAAEshlaXTyMhIAAAEAAQIAOzAAAAEAAAYAAQCwEAYAAQIBoEAAABNsZfKWEwAAAQDzgAJpbwEIAPQvEwAAAQCCAAUAEwEDsJATkQABsFASeQFXZ2xwOzAAAAEAABIACQDBDwIAMhEBAGgSAQCJEgEAvxIBACATAQBXEwEAZhMBAKMTAQABgAKwQBH2AQygIAAAEHVhaQGBArAwE0AAAbAwEhQAAWNpAQMBsAASYwABczswAAABAAANAAMALREBANwSBwDIEwMAAQMA9SsRAAABABsBAQBUAfOAAnJ2AQAAOzAAAAEAAAUAAgD0EQEASRIDAPMCAWQ7MAAAAQAACQADACcRAwDvEQMAIRIBACOAAqCQAAAThmlvE4ACsPAT1QABbG8BBQD0ohMAAAwAHgAPACOAAqBgAAASvmdzI4ACsJAThAABYmz3xwAAjbBgE7gAAbBwEzIAAbBgEncAAbBQEmUAAbXJFzowAAABAAAAAAAgABAAAAB+BbcI5wjxC/ILZQxmDGcMCA4JDgoOCw4NDg4OVQ9WD1cPWA9ZDx8QIBBZEHwQ2hDbENwQ3RAlEW8ShhKHEqgSWhM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/25143dd2528f.js b/pr/545/docs/search.index/25143dd2528f.js new file mode 100644 index 000000000..380d928c0 --- /dev/null +++ b/pr/545/docs/search.index/25143dd2528f.js @@ -0,0 +1 @@ +rn_("AYADsAATTAABsAATTgABsHATwAABNDZhAQQA9A8UAAABAAoAAQAjgQKgQAAAENptcAEBADswAAABAAAIAAMARBIAALUSAAAcFAYAxwEAAMWgQAAAD92ggAAAEh9ABoAIOzAAAAEAABYACAB7DwEAkRABANYQAwBFEQYAKhMCAHgTAADQEwEAABQBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/25a2359dd30d.js b/pr/545/docs/search.index/25a2359dd30d.js new file mode 100644 index 000000000..63dc01182 --- /dev/null +++ b/pr/545/docs/search.index/25a2359dd30d.js @@ -0,0 +1 @@ +rn_("AQUA9GsTAAABAEkAAQDzAwFj8nMSAAABACOAArBwFBYAAWhvAYICsAASUAABsAARXwABZXNDAAOgoAAAE7qgIAAAEvplaXTyYxIAAAEAAQIAOzAAAAEAAAYAAQDgEAYAAQIBoEAAABOfZfLJEwAAAQDzgAJpbwEIAPRiEwAAAQCCAAUAEwEDsJATxAABsFASqgFZZ2xwOzAAAAEAABIACQDuDwIAYhEBAJkSAQC6EgEA8RIBAFMTAQCKEwEAmRMBANYTAQABgAKwQBInAQ6gIAAAEKNhaQGBArAwE3MAAbAwEkUAAWNpAQMBsAASlAABczswAAABAAANAAMAXREBAA4TBwD7EwMAAQMA9VsRAAABABwBAQBWAfOAAnJ2AQAAOzAAAAEAAAUAAgAlEgEAehIDAPMCAWQ7MAAAAQAACQADAFcRAwAgEgMAUhIBACOAAqCQAAATuWlvE4ACsPAUCAABbG8BBQD01RMAAAwAHgAPACOAAqBgAAAS72dzI4ACsJATtwABYmz3xwAAjbBgE+sAAbBwE2UAAbBgEqgAAbBQEpYAAbXJFzowAAABAAAAAAAgABAAAACPBdAI/ggRDBIMiQyKDIsMMg4zDjQONQ43DjgOgg+DD4QPhQ+GD00QThCHEKoQChELEQwRDRFVEaAStxK4EtkSjRM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/25a5775ae582.js b/pr/545/docs/search.index/25a5775ae582.js deleted file mode 100644 index 344d95e19..000000000 --- a/pr/545/docs/search.index/25a5775ae582.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABoLAAABMBYvOQEgAAIAEBAAGAAqAgAAAPK6AwAAATDWFy8wABdAE8BwAAAQQBoEAAABOTZfKzEwAAAQABBQA7MAAAAQAACwAFALEPBQANEgEANBMBAIYTAAClEwAA4wGEoDAAAA8phQACOzAAAAEAAAsABQBvBQIAfQYEAOoLAQDXEAAAHhIAAGOAA7AAD0wDQ2Rucg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/2657ace38ed9.js b/pr/545/docs/search.index/2657ace38ed9.js new file mode 100644 index 000000000..c0f52d63d --- /dev/null +++ b/pr/545/docs/search.index/2657ace38ed9.js @@ -0,0 +1 @@ +rn_("AQkA898TAAABADUAAYADoEAAABLGsCATgQABoCAAAA9caGl5AQkBoIAAABQSZgEAEwAAAQMBsAATlgBMc/ItEAAAEwMjgAKgIAAAD1hhcgECAPVZEAAAAQABAEsCAQDzAANpdHU6MAAAAQAAAAAADgAQAAAAUQf7CJ4MvQ82EFwSlBKVEkQTRRNLE3UTdhOUE5UTAYACoDAAABPCsLATHAABYWwBDAGgoAAAFCN38hMUAAABAAEBAPN/DwAAAQABAPOAAnR1AQMA8y8SAAABAAEAAQEA9boQAAABAAEAAQABACOAArCQE20AAWF0AQQBoEAAABPGZfLmEwAAAQABAgA7MAAAAQAACwAFAN4PBQA+EgEAZxMBALkTAADYEwAAE4ICsPAUFgABZmcBgQKwgBPtAAGgYAAAFBFkcwEIAPWnEwAAAQABAAEAAQDzAgFm9RoQAAABAAEAAQABACOAA6AgAAAPVrCgE+sAAWRydHfvAQCNsBAToQABsOATowABl9UOOzAAAAEAACUBEgBnBAEAlAQCAH8FAgCSBgQAwgcDAN4LAQAKDAEAjgwBADkO9QB1DwEANxABAEgQAgB0EAEABxEAAF0RAQBPEgAADhMHAPsTAwA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/26625634ad63.js b/pr/545/docs/search.index/26625634ad63.js new file mode 100644 index 000000000..207639749 --- /dev/null +++ b/pr/545/docs/search.index/26625634ad63.js @@ -0,0 +1 @@ +rn_("AQMBoAAAABNLcwF1EAAAAYACsDAQCgABsFAQDAABYWkBgAKgsAAAE9SgMAAAEKBsbhcBAACFoCAAABIOoCAAAAjHsIAToQABEJEEOjAAAAEAAAAAABEAEAAAAH4EtQS2BLcEuAS5BLoENwk+Dz8PthLwEnETdxODE4QTnROeEwECADowAAABAAAAAAAKABAAAAAgCSEJpg/aEtsSChMLE64TAhQYFBkUAQAAOzAAAAEAAAYAAgD2EgAAXBMFAAECAbAwEscAAWM6MAAAAQAAAAAAEwAQAAAApgxVD+sP7A/tD/IP8w/3D/gPihD+EAIRAxEEEXQRvBK9Ep8TxBPFEwEDAPMvEwAAaAABABOBArBAEOoAAWFlE4ACoLAAABPbYWUBAQGwQBPHAAFl9Y8TAAABAAEAAQABABOAAqAQAAALyGFvhw8AAMiwMAjYBySwQBPNAAGggAAAEglATIgJ88gHAAAGBDsAAYACoIAAABLhoJAAABK5YWsBAwDzLxIAAAEAAQAjgISxIBQWAAGgAAAACPugMAAAD1wEBAYBCAD1HhQAAAEAAQABAAEAE4oCsEAT+QABYXKTAISgwAAAErWhAAAAE4ABQAbySgcAAAEAAQMBoEAAABFuZfOwDAAA5AMBAAEFAPQmEwAAAQABAAEAU4ADsAAS3AABZXN0AQYA9AQUAAABAAEAAQDzCAFt9BsSAAABAAEAAQABAgA7MAAAAQAABQABAO8TBQDzDQFtOzAAAAEAAAUAAQCvEwUAAQQA97gMAAABAGsFDgABAIsAAQABAwGAEukAEPBzOzAAAAEAAAUAAQDJEgUAI4ICoJAAABPDaXMBBQGgUAAAE4xo8ikSAAABABOAArAwEtwAAW50AYACoIAAABL7sEARZwABYWUBgAKgEAAAEJagAAAAENxucgEJAaBAAAATxmXy5hMAAAEAI4ACoJAAABMxaWzHIwAACqAwAAAQl7BQEpIAAbDwFAwAAbBwEvgAAaDQAAATzzBiY2VoaWtub3Y7MAAAAQAAGgALAMcLAABvEAMAdxEEAPUSAAADEwMAOBMBAIATAACFEwMAoRMBAK0TAADAEwEAAQICoLAAABO5oLAAABO6Y3PzTRAAAAEAXAABAQKwUBFnAAGgwAAAE4xoafI4EwAAAQDzgAJlaQEBAaCQAAAS9XP0MhAAAAEAAQABAAEDAbAAEGkAAXMB2g8AAPOAA2hpdAEBAaBQAAASd2MBfQwAAAEFAbCAE8AAAXY7MAAAAQAABwACAEURBAAqEwIAAQEA9PoPAAABAKkAAQDjgISwcBFrAAEOCAD3ZQ8A0bCQEgcAAaBQAAAQj6EAAAAT9aCgAAATF6AQAAAHIEA/vyk7MAAAAQAAOAAYAKYEAACoBAAAcwUCAOkGAgC1CwMAgAwBAEkPAgBXDwAAfg8AAIcPAACnDwEArRAIAAURAABHEgEAUBIBAFQSAQCxEgEAzxIEACQTAQAtEwEAMRMAAKcTBAD1EwAAEhQAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/267566229927.js b/pr/545/docs/search.index/267566229927.js deleted file mode 100644 index 624b72887..000000000 --- a/pr/545/docs/search.index/267566229927.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYA9B4TAAABAFMAAQAjgAKhEAAAE9BjchOAAqAgAAAIwWh5AQEBoGAAABPDc/IgEQAAAQAjgAKwIAkoAAFldQGAArAgD3oAAaCQAAATeWFlAQcBsEATlAABZfVcEwAAAQABAAEAAQABBAGwABJjAAFzOzAAAAEAAAsAAgDcEgcAyBMDAEcAAASGoIAAABK+sQAT1QABsEASHwABsIAT4wABsFASZQABFQAW9AgOAAABAAEAAQCDAISwQBPZAAGwMBJVAAGwMBLwAAHAAAM6MAAAAQAAAAAACQAQAAAAiwReEF8QABEBEQYRBxE8Ez0TqBMBAwGwQBOqAAF08g4TAAABACOFAqBAAAATPmJzAYACoAAAAAjjoCAAABBRZ3ABAQD0HBEAAAEAAQABAPOAAmRst+gAAIyg0AAAEsigUAAAELygkAAAEuSwUBJEAAGgMAAAC/63mAc7MAAAAQAAYAATAOsBAQDxAQEAOQQDAI8FAACDBgEAHgcBADEHAAC9CAEAyggAANYIAAAICQAAFAw9AGQMAABGDwEAGBABADMQAQB4EAEA9xAEAPoRAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/26d748f5add8.js b/pr/545/docs/search.index/26d748f5add8.js deleted file mode 100644 index 6a88d4594..000000000 --- a/pr/545/docs/search.index/26d748f5add8.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9MoSAAABAAEAAQABAAD1CgwAAAEAAQABAAEA84ACZ2sTgAKwsBMiAAFhbwGFArBwE0sAAbAwEqMAAWVzEwADsEAPMAABoGAAABDYYmVzOzAAAAEAABIABABzBQEAhwYKAKkPAQD8DwMAAQMA9MUPAAABAAQAAQABCgGgQAAAE5Nl8rMTAAABABOAArBgEfgAAWNp84ACZHLzAAJlbzswAAABAAAJAAIAWQcFAJwHAwABAgA7MAAAAQAACQABAIoLCQDzgAJvdAEDADswAAABAADjAAIAMwcAAKcK4gABAgGgcAAAEURpOzAAAAEAAPUAAgAyBwAAsgn0ABOAAqBAAAALxnJ1AQQA9IISAAABAJMAAQABAwDzERIAAAEAqADzgAJhb9cFAACIsEAMggABoDAAAAuUsTATsAABNIEWOzAAAAEAAB4ADQCQBAEATQUBAJ0LAADLCwcA7wsBAD4PAQAmEAEArxAAAPwQAwA5EQEA7hEAAE0SAQDVEwEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/26eaff1ecc2b.js b/pr/545/docs/search.index/26eaff1ecc2b.js new file mode 100644 index 000000000..a55b2e9ef --- /dev/null +++ b/pr/545/docs/search.index/26eaff1ecc2b.js @@ -0,0 +1 @@ +rn_("AQAAOzAAAAEAAAYAAgD2EgAAXBMFACOIArBAE80AAWVzAQQBsDASxwABY/MCEQAAAQABAAEFADswAAABAAAIAAMAcRECAG4SBACOEwAA8wMDY2Vw83kMAAABAAEAAQABsGATdQABZQGsEwAA8wIBc/byCAAAAQABAM0HPwAVAQECAaBQAAARAXIBoRAAAPOAA2ZtcA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/27b689c7cdce.js b/pr/545/docs/search.index/27b689c7cdce.js deleted file mode 100644 index 907dc2608..000000000 --- a/pr/545/docs/search.index/27b689c7cdce.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEAOjAAAAEAAAAAAAcAEAAAAIkSihIgEyETVxNYE6MTpBPzBgFpAagSAAAjgAKwUBJ9AFhmbgEAAbBAElcAAWU7MAAAAQAADQACAJIGDABdEAAAI4ACoDAAAAuqYWU3AACAxbBQEs8AAbAQE3AAAbBgEtYAAQACmAg=") \ No newline at end of file diff --git a/pr/545/docs/search.index/280b57a12fe8.js b/pr/545/docs/search.index/280b57a12fe8.js new file mode 100644 index 000000000..c3a679506 --- /dev/null +++ b/pr/545/docs/search.index/280b57a12fe8.js @@ -0,0 +1 @@ +rn_("AYMCsQAUGAABsNAUCgABa20BCgDzZxMAAAEAcAATgAKiEAAAFCNsbzMBhKBgAAASBKEAAAAT2gSAAzswAAABAAA0AAIAIQcAAHQHMwA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2892218972b3.js b/pr/545/docs/search.index/2892218972b3.js new file mode 100644 index 000000000..7be5a9a3f --- /dev/null +++ b/pr/545/docs/search.index/2892218972b3.js @@ -0,0 +1 @@ +rn_("AQUAOzAAAAEAAAcAAwA/EQIA5xIBAHsTAgABBADzQhEAAAEAAQAjAAKgYAAAEmlhcvNrEAAAAQC8AQGAAqEQAAAT/7CAE/cAAWl1NwQAgYexUBQaAAGgAAAAEEywcBNEAAGhMAAAFA4KQBsBAAA7MAAAAQAAhgABAKoNhgABAgD2ChMAAAEAowBUABYAAQAjgQKgIAAAEIpydvOAAmVvI4ACoCAAABIJZHQBAAA7MAAAAQAA6QAEAKEFAADXB+YANgwAAO0QAADzgANkbnY=") \ No newline at end of file diff --git a/pr/545/docs/search.index/289cef522e65.js b/pr/545/docs/search.index/289cef522e65.js deleted file mode 100644 index 03683385e..000000000 --- a/pr/545/docs/search.index/289cef522e65.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBoEAAABNWZfLGEwAAAQABAQA7MAAAAQAABgABAOkTBgDzBgFl9J0TAAABAC8AAQAzAwOgYAAAE0RhcnXz0g8AAF4CAQAjgAKAEMcAEAFkcg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/294c65cabea3.js b/pr/545/docs/search.index/294c65cabea3.js deleted file mode 100644 index 41992269d..000000000 --- a/pr/545/docs/search.index/294c65cabea3.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYQCsAAQygABsAAQzAABNDbzAgFh8gUMAAABAAEAAPUDEgAAbgABAEMBAQDzAAFk8xESAAABAKgAY4ADoCAAAAivYWVv") \ No newline at end of file diff --git a/pr/545/docs/search.index/29a9ad420aea.js b/pr/545/docs/search.index/29a9ad420aea.js deleted file mode 100644 index 93d2feb1f..000000000 --- a/pr/545/docs/search.index/29a9ad420aea.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQA9pAMAAABABEDAQAiAQEAAQoA8xESAAABAKgAAQEA99cIAAABAPwGAQBqAAEADAEjgAKwYBMiAAFpbwECAPRSDAAAAQD+BQEAAQUA9DgTAAABAEkAAQD3BAAAh6AgAAAMVLCQET8AAQScAzowAAABAAAAAAAIABAAAABfBcYIxwj2C/cLTxBQEEISQxI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2a157ff40a7a.js b/pr/545/docs/search.index/2a157ff40a7a.js deleted file mode 100644 index 7d5019249..000000000 --- a/pr/545/docs/search.index/2a157ff40a7a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOjAAAAEAAAAAAAgAEAAAALALsQsJDwoPQg8qEE4QxhLHEgEAAPTvCAAAAQABAAEAAQUBsDASVQABaPM8EwAAAQBrABODAqAwAAAQHWNwAQMA9EAPAAABAOcAAQABgQKgAAAAENWgEAAADyNldfOAAmFyAYECoJAAABMmsFAR4gABYncTgAKwkBJtAAFucvMAAmV08hYQAAABAAEBAPUKDAAAAQABAAEAAQATgAKwsBMiAAFhbyMAArBADIIAAWV0OzAAAAEAAAkABACQBAEATQUBAO8LAQD8EAMAAQIAOzAAAAEAAAkAAgCiBwcATxIBAAGAArCQErYAAaCgAAATJWV2E4ACsYAT6wABY20BggKwQBNQAAGgUAAAETFiZhOAAqBAAAATeWRzI4ACoNAAABPDY27zgIQRAUABBQGwQBKRAAFlAeERAABDggOhAAAAE8+g0AAAE6ZrbXMTgAKwYBAxAAFhcgEFADswAAABAACGAAIARRAAAE0RhQABggOwIBJRAAGwIA/UAAGwQBDFAAFrbHNTgAOwIBOqAAFrdHUBiYSggAAAE96gQAAAE4+gYAAAE6+gkAAAE+ICgAoTgoSgoAAAEySxoBPuAAGw0BOIAAEEAQkBgAKxcBPpAAGg0AAAE2JjbyOAArBgEC8AAWlvAQAA9LoLAAABAE0AAQAjgQKg4AAAE3tleQENADowAAABAAAAAAAHABAAAACJEooSIBMhE1cTWBOjE6QTAYECsEASqQABoMAAABNhZW8BAgA6MAAAAQAAAAAACAAQAAAANw84D94QLBItEiQTphPXE9gT8wEBbzswAAABAAAJAAQAFAkBAPIPAwAvEAEAIhMBAPOAA21ucgEAADswAAABAAAGAAIAxBIAACkTBQBDgAOwQBOaAAGgIAAADIFlcnMjAAKwMBMFAAFjcvLyEgAAAQABgQKwgBJXAAGhAAAAE6VjZgELAPSyEgAAAQABAAEAAYACoAAAAA/ooAAAAA/pNDbzAgF2AYgMAADzAAJkbAHPCAAA1/45AJKwoBNOAAGwcBEjAAGwgBI2AAGgsAAAEm+d3X87MAAAAQAAFgALAJYBAACMBAMASgUCALwGAQDGBgIAyAsAAFAPAACrEAAAEhECAOcRAgCMEwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/2a552ae8044e.js b/pr/545/docs/search.index/2a552ae8044e.js new file mode 100644 index 000000000..6c2e37553 --- /dev/null +++ b/pr/545/docs/search.index/2a552ae8044e.js @@ -0,0 +1 @@ +rn_("AQEAOjAAAAEAAAAAAAkAEAAAAGQPZQ9TEA4RXRJeElcT2RMKFAsUAYACsOATUQABsDATaQABZHDDgISxQBQaAAGgkAAAExcCgAk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2a67720851d1.js b/pr/545/docs/search.index/2a67720851d1.js new file mode 100644 index 000000000..89ca98e84 --- /dev/null +++ b/pr/545/docs/search.index/2a67720851d1.js @@ -0,0 +1 @@ +rn_("AQgA9FETAAABAFMAAQABAgGgYAAAE/Zz8lARAAABAAGAArAgD6cAAaCQAAATrGFlAQcBsEATxwABZfWPEwAAAQABAAEAAQABAwGwQBPdAAF08kETAAABACOFAqBAAAATcWJzAQEA9EwRAAABAAEAAQATgAKgMAAAEH9kbDd0AACLsEATIgABoFAAABDsoJAAABMWsFASdQABoDAAAAwes5gHOzAAAAEAAF4AEQD4AQEASAQDAKAFAACYBgEAMwcBANYIAQDjCAAA7QgAAB8JAAA3DD4AiAwAAHMPAQBGEAEAYRABAKYQAQAnEQQAKxIBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/2a8e4b0e890f.js b/pr/545/docs/search.index/2a8e4b0e890f.js new file mode 100644 index 000000000..6ec846f98 --- /dev/null +++ b/pr/545/docs/search.index/2a8e4b0e890f.js @@ -0,0 +1 @@ +rn_("AQUA9DkSAAABAKQAAQABCAD08xIAAAEAhQABADMAA7BAEsIAAWFiZTowAAABAAAAAAAJABAAAAAEBwUHnwygDFAPvg8KEAsQEhLhEg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/2b4d7f4d8d3a.js b/pr/545/docs/search.index/2b4d7f4d8d3a.js deleted file mode 100644 index 762e36065..000000000 --- a/pr/545/docs/search.index/2b4d7f4d8d3a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9LISAAABAAEAAQATAgKwgBKGAAFzdvQkCQAAAQANCgEA8wABYwH4CwAAAQICoLAAABOGoLAAABOHY3PzHxAAAAEAXAABgQKwUBE3AAGgwAAAE1loafOCAmVp84ACZW8=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2b89b2e478bd.js b/pr/545/docs/search.index/2b89b2e478bd.js deleted file mode 100644 index de0739e8d..000000000 --- a/pr/545/docs/search.index/2b89b2e478bd.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYQCoCAAABB0oDAAABDZaXQBAQA7MAAAAQAAhgACADAHAAAsCYUAYwADsAACAgABZGVsOjAAAAEAAAAAAAcAEAAAAIgEUAVRBVIFNAeSEM8S0BI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2bbd4ed026d7.js b/pr/545/docs/search.index/2bbd4ed026d7.js deleted file mode 100644 index 0b93684c1..000000000 --- a/pr/545/docs/search.index/2bbd4ed026d7.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACoFAAABCToFAAABHTYXUBgwKxABPlAAGw0BPXAAFrbQEEAaCgAAAT8Hfy4BMAAAEAAQsA9FITAAABAAEAAQAjgAKggAAAE3plb2MDA6BgAAATEGVucAG5CwAAI4ACoEAAABAlbXABCgDzNBMAAAEAcAATgAKiEAAAE/Bsb/cAAACFoQAAABOnBIEDOzAAAAEAADsABACCBQUADAcAAF8HMwDREAAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/2bbea166f1f8.js b/pr/545/docs/search.index/2bbea166f1f8.js new file mode 100644 index 000000000..abe4b0a17 --- /dev/null +++ b/pr/545/docs/search.index/2bbea166f1f8.js @@ -0,0 +1 @@ +rn_("AQABoCAAAAyVbQFfBQAAAQAA9HoSAAABAAEAAQDzBAFk9CASAAABAAEAAQAjhISwoBO3AAGwQBJ4AAGwcBNlAAEVgAAzgAOw0BOlAAFhZWk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2d92cd1657e9.js b/pr/545/docs/search.index/2d92cd1657e9.js new file mode 100644 index 000000000..1a0e5a44c --- /dev/null +++ b/pr/545/docs/search.index/2d92cd1657e9.js @@ -0,0 +1 @@ +rn_("AQIBsEAT3QABdDswAAABAAANAAYAahIDANQSAQBBEwEAWBMBANITAQD3EwEAE4ACsDASnQE/aXABBQDzGBMAAAEAAQATgAKgMAAAE3FleVMCA7BwE34AAWJlcwHFDwAAEwACoCAAAAV9Zm32ewAAALwGAQDSAQEAtAc=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2e2486520353.js b/pr/545/docs/search.index/2e2486520353.js deleted file mode 100644 index 09a917f60..000000000 --- a/pr/545/docs/search.index/2e2486520353.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYAOzAAAAEAAAUAAQCYEgUAg4YEsFASYQABsHASxgABoNAAABOcYm5vdhOAArAQEjQAAXByAQABoDAAABE0dAHlEgAA8wIBc/L7DwAA7gITgAKgYAAAD+xldQECAPaQDAAAAQARAwEAIgEBAAGAArAAEh8AAYAODDIwAWVzAQEA8xQHAACoCwEAY4ADsIATNgABYm5084ADYW9yARQA9MgTAAABAAEAAQABAAA7MAAAAQAABgACAMQSAAApEwUAI4gCsEATmgABZXMBBAGwMBKWAAFj89IQAAABAAEAAQUAOzAAAAEAAAgAAwBBEQIAPRIEAFsTAADzAgNjZXDzVQwAAAEAAQBjgAOgYAAAD0xlb3UBAAGwYBNCAAFlAXkTAADzAgFz9tsIAAABAAEAtgc9ABQBAQgA8/4RAAABAAEAQ4ADoBAAABLIoOAAABNNZG9zAQIBoFAAABDRcgFzEAAAAYACoEAAAA/4oHAAABOHYWUBAAA7MAAAAQAACwACALUGBQAYEgUA84ACdHYBAQD0rQcAAAEAAQABAPMAAm5y9tAIAABXALEGAQCvAAEA8wCHMJEM95oEAAC3C+EBAQCFAAEA7gA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2e4409258cfe.js b/pr/545/docs/search.index/2e4409258cfe.js deleted file mode 100644 index 4d3b90dd2..000000000 --- a/pr/545/docs/search.index/2e4409258cfe.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYICsEATkQABsGAScQABZXIBBQD08g8AAAEAAQABAPOAAmZtAQYAOjAAAAEAAAAAAAgAEAAAADcPOA/eECwSLRIkE6YT1xPYEwEAArCwEzwAAaFAAAAT0GVn9DgHAAABAAEAAQDDAISgsAAAEw2wQBAJAAEUIAT3sAYAAKgFTwMBAC4BIAEMAWOAA7AwD3MAAWFlaQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/2eaf4ab981c3.js b/pr/545/docs/search.index/2eaf4ab981c3.js new file mode 100644 index 000000000..570d27443 --- /dev/null +++ b/pr/545/docs/search.index/2eaf4ab981c3.js @@ -0,0 +1 @@ +rn_("ARMA9R4UAAABAAEAAQABABOAAqDAAAAStWFvAQICoLAAABO5oLAAABO6Y3PzTRAAAAEAXAABgQKwUBFnAAGgwAAAE4xoafOAAmVpI4ACoLAAABL1aXQBBQGwgBPAAAF2OzAAAAEAAAcAAgBFEQQAKhMCACOAArBwEWsAAWJkdwAAAIagoAAAExegkAAAEuGwUBAKAAEF4AL16QYAAAEAAQCcCG4E") \ No newline at end of file diff --git a/pr/545/docs/search.index/2eeacf2c8ee0.js b/pr/545/docs/search.index/2eeacf2c8ee0.js new file mode 100644 index 000000000..439deff84 --- /dev/null +++ b/pr/545/docs/search.index/2eeacf2c8ee0.js @@ -0,0 +1 @@ +rn_("AYQCoCAAABCioDAAABEJaXQBAQA7MAAAAQAAhwACAEUHAABDCYYAYwADsAACCQABZGVsOjAAAAEAAAAAAAcAEAAAAJcEYAVhBWIFSQfAEAETAhM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/2f792e01bbed.js b/pr/545/docs/search.index/2f792e01bbed.js deleted file mode 100644 index 395fde40e..000000000 --- a/pr/545/docs/search.index/2f792e01bbed.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQ0A9RMTAAABAAEAcwABAAECAPRXEAAAAQCDAQEAAQMA9MEQAAABAGwBAQDzAAJidQFyDwAAAQMA9FUQAAABAIMBAQDzhAJkcwECAPPCCAAAAQBaAPOAAml0ARgA8+0TAAABAAEAI4ECsMATEQABY20BBQGgYAAAEgNy9LcLAAABALgDAQABCQD2LBIAAAEA9wCCADEAAQATgAKwYBAYAAFkbgEDAaBwAAASZ2f0GAcAAAEAAgIBAAEJAPOsEwAAAQA1AAGBArCAE7oAAaBgAAAT3mRzFwEAiYWw0BPgAAGgQAAAE4+wYBNjAEwCkApnXgAAi7BwEHoAAbCwEnUAAaCgAAASK7DwE0IAAW2BD/R/AAAAAQABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/2f7ecc5dbb1a.js b/pr/545/docs/search.index/2f7ecc5dbb1a.js new file mode 100644 index 000000000..37e6348f3 --- /dev/null +++ b/pr/545/docs/search.index/2f7ecc5dbb1a.js @@ -0,0 +1 @@ +rn_("AQUA9cgPAAABAAEASQIBAAEEAaAAAAAQXHP1qQwAAAEAAQAbAwEAAQIA9ScRAAABAAEAAQABAAGAArBgEoIAAaAgAAAQfG95AQABoMAAABOgafTYEgAACAAbABsAAQYA9AQUAAABAAEAAQABAgD0ehAAAAEAmgABAAECAaBAAAASr3I7MAAAAQAABwACAHgQAQAPEQUA84ACYW9nAwAAhrCAEq4AWbCgEyQAAQwwBjswAAABAAAIAAMA0gsAADoRAwAbEgMA84ICZWlHAQAAhbBwEzIAAaCAAAAUEqBAAAAPfbBABPTJCAAAngYBAJgDAYECoCAAABB2sFASKwABYW8BBAGgAAAAE0tzAXUQAABjBAOwUBDnAAFjZXP20QgAAAEAAQAsAAEAEQkBAAA7MAAAAQAAJAAIABQHBwDIDwIAGBENAD8RAgATEgEAlhIBAOcSAQB7EwIAAQEA9LkLAAABALEFAQATAAOwMBO3AAGwUBKKAAFlcHL0aQ8AAAEA5wABAAEAA7BAE4MAAaFAAAAT6qBQAAARYWJjZgHeBgAA44CEsUAUDwABAjAQAQGEoLAAABNAsEAQNwABsMATbwABoGAAABEOFCAE9sUGAAAPCQEAMQEhAQ4BAQMAOzAAAAEAAAUAAQBJEgUAAQABoKAAABOscvRzDwAAAQDtAAEA84ECZ3MBBwD1zxIAAAEAAQABAAEAAYACoEAAABDfsFAQxgABY2nzgAJhbwEAAaAgAAAQ/3Lz5wsAAFkDYAFDgISgAAAAE4mgMAAAE4mABU0AHLsIICEBAwKwQBKMAAGgMAAAEuJld/IOEAAAtwATgwKgcAAAExtnbwECAPVsEgAAAQDsAHkAAQATgAKwMBKdAT9pcAEGAPMYEwAAAQABAPMFAmJzAcUPAAABAgD0og8AAAEAAQABACOAAqBgAAASD2Jj978AAIygkAAAEhA7yRo6MAAAAQAAAAAAFwAQAAAA/AEJAgoCZARlBGYE5gYfB1IHUwdUB1UHVgdXB7QLJwyvDMAP0g/TD5YQFxH5E/oT") \ No newline at end of file diff --git a/pr/545/docs/search.index/2ffc6423036c.js b/pr/545/docs/search.index/2ffc6423036c.js deleted file mode 100644 index e435aedc2..000000000 --- a/pr/545/docs/search.index/2ffc6423036c.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQkA86wTAAABADUAAYADoEAAABKVsCATTgABoCAAAA8vaGl5AQkBoIAAABPfZgHOEgAAAQMBsAATYwBMcwENEwAAQ4ADsCAPKwEdsFAR+gABYW9yAQIA9SsQAAABAAEASAIBAPMAA2l0dTowAAABAAAAAAAOABAAAAA8B+QIkA8IECYRKxJjEmQSERMSExgTQhNDE2ETYhMBBgD0TRIAAAEAhwEBABMCArBgEk8AAWZt8mgMAAABACOCArBAEnsAAWVsAYACoDAAABOPsLAS6gABYWwBBgDzOQ8AANsAAQABBQD0OBMAAAEASQABAPMCAWPyQhIAAAEAAQIBoDAAAA/PYQHpCwAAAYACsFAQeAABsCAPCwABY27zgAJudAEFADswAAABAAAOAAIAbgwAAGIPDQABAgA7MAAAAQAABwABAAsJBwDnBQAACaAwAAAL6KCwAAATYaCAAAAQ9rDQE3AAATBhZmlrbXJ1djswAAABAABNAgUA6AEAAEkD4gAzBwAApwriAIENhQABDAGgoAAAE/B38uATAAABAAEBAPNSDwAAAQABAPOAAnR1AQMA8/4RAAABAAEAAQEA9YwQAAABAAEAAQABAAEBAbAwD0IA6HT2JQcAAAEAjgCRB6YA6AFjgAOwkBM6AAFhbXQBAwGgQAAAE5Nl8rMTAAABABOAArBgE+MAAWVyAQMBoAAAABMYcwFHEAAAAQIAOjAAAAEAAAAAAAoAEAAAAAkJCgl5D6kSqhLYEtkSexPPE+UT5hODAASggAAAEdiwcBC6AAGwIBBcAOhmbnJ2AbMHAAABgQKgAAAACOSgMAAADy9zdMcBAIDGsAATbgABsJAR1gABoBAAAAcLABKIKAECADswAAABAAANAAYAsQ8FALcQAQANEgEANBMBAIYTAAClEwAAE4ICsPAT4wABZmcBgAKwgBO6AAGgYAAAE95kcxOAArDAEv8AAWlvAQgA9XQTAAABAAEAAQABAPMCAWb17Q8AAAEAAQABAAEAI4ADoCAAAA8psKATuAABZHJ09/sHAI+gMAAADx+X1w87MAAAAQAAOwEdAFgEAQCFBAIARwUCAG8FAgCRBQEAfQYEAPwGAAAUBwAArQcDALgIAgDoCAEAvgsCAOoLAQAPDAMAagwBAA8O8gBIDwEAxw8CAAkQAQAaEAIARhABANcQAAAtEQEA4BEAAB4SAABVEgEAvBIBANwSBwDIEwMA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3036a9249b54.js b/pr/545/docs/search.index/3036a9249b54.js new file mode 100644 index 000000000..8f9354bf5 --- /dev/null +++ b/pr/545/docs/search.index/3036a9249b54.js @@ -0,0 +1 @@ +rn_("AQEAOzAAAAEAAAYAAQDgEAYAAQAA9+4IAAABABIHAQBrAAEADgEBggKgIAAAEKKgMAAAEQlpdPOAA2FncwEBAaBAAAATn2XyyRMAAAEAI4ACsFATVQABZnPzgAJpbw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/31b45cf6ecff.js b/pr/545/docs/search.index/31b45cf6ecff.js new file mode 100644 index 000000000..f81d2dbe0 --- /dev/null +++ b/pr/545/docs/search.index/31b45cf6ecff.js @@ -0,0 +1 @@ +rn_("AQEA9coHAAABAAEAAQABAAEAAqAwAAAQl6CQAAAS+zBo9XcRAACMAQEAAQABABOAAqAwAAAPVWRyIwKEsBAIxgMksCALuwD/oDAAAA96EgAY9XYFAAAuAAEAAQABADOAhLCgEj4AAbBAD18AARBJAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/320b0f4af278.js b/pr/545/docs/search.index/320b0f4af278.js new file mode 100644 index 000000000..439a4a533 --- /dev/null +++ b/pr/545/docs/search.index/320b0f4af278.js @@ -0,0 +1 @@ +rn_("AQQA9rUMAAABABkDAQAlAQEAAQoA80ISAAABAKgAAQEA9+4IAAABABIHAQBrAAEADgEjgAKwYBNVAAFpbwECAPR2DAAAAQALBgEAAQUA9GsTAAABAEkAAQD3CAAAiLCQEyQAAaAgAAAMeLCQEW8AAQTcAzowAAABAAAAAAAIABAAAABvBd8I4AgWDBcMfRB+EHMSdBI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/321190b83abb.js b/pr/545/docs/search.index/321190b83abb.js new file mode 100644 index 000000000..9d8fdf7f6 --- /dev/null +++ b/pr/545/docs/search.index/321190b83abb.js @@ -0,0 +1 @@ +rn_("AQAA9IUQAAABAIYBAQAjgQKgYAAAEqtiaQEAAPR3DwAAAQDrAAEBI4ICsFASvgABZXMBiQKwIBPSAAGgMAAAE9xpcAECAPSQEgAAAQCPAAEAAQMA9MQSAAABAJUAAQDzhQJidQECAPTxEAAAAQBtAQEA84ACaWy3AQAAhaAgAAASmBIBDDowAAABAAAAAAAUABAAAABEB9EH0gfTB9QHyQv9C/4L/wsADJ8PXBAXE5YT3xPgE+IT7RPuExEUFRQBBQDzexMAAAEAAQBDhgOwkBP3AAGgAAAAEihiZHcBgAKwAAjoAAGwIAyuA0NkbgEDAPN1DwAAAQD+AAECAPbQCwAAAQBlAwEAwQMBAAEAAPQGCQAAAQABAAEAAQAAOzAAAAEAAAYAAgD2EgAAXBMFACOBArBAE80AAWVz84ADZXh5AQAA9AIJAAABAAEAAQBDgAOgQAAAE/WwIBKMAAFlcngBgAKgQAAADJiwQA+gAAFnbCcaAADJoJAAABLZsMATIgABoBAAABDtoDAAABNysEAMkAABAEegCzowAAABAAAAAAAJABAAAABLBUwFlgyXDKwMcQ/LD8wPhBKFEgEGAPSOEgAAAQCPAAEA8wMBYvSDEAAAAQCGAQEAtwwAAImgcAAAEhawkBK8AAGwYA/DAAGgMAAAEuI4iRM6MAAAAQAAAAAALwAQAAAAnAWdBZ4FnwUGBwcHygjLCMwI/Aj9CNUL5gujDKQMpQypDKoMqwxtD24PwQ/CD8YPxw/kD+UP5g/nD+gP6Q/qDwkQDhAoEC0QVhBXEMQQxRBpEvcSGxNAE9UT4RP/Ew4U") \ No newline at end of file diff --git a/pr/545/docs/search.index/323be9ee8c7b.js b/pr/545/docs/search.index/323be9ee8c7b.js deleted file mode 100644 index 07849cda2..000000000 --- a/pr/545/docs/search.index/323be9ee8c7b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9HMSAAABAI8AAQDzAAFj9a4PAAABALsAAQABAAEJAPOsEwAAAQA1AAENAaCgAAAT8Hfy4BMAAAEAAYECsIATugABoGAAABPeZHM3AQCEhaBAAAATj7BgE2MATAKQCiOAAqBwAAAQq2RyAQsBoEAAABOTZfKzEwAAAQATgAKwMA/KAAFkcvMCAWX0nAcAAAEAAQABACOAArAgC54AAWV5AQoA8/4RAAABAAEAAQsAOzAAAAEAAAcAAQDcEgcAAQIA9DgTAAABAEkAAQC3AACAhbBwEjIAAbDQE9UAAWAgBgEGAPMKEgAAAQABAAEDAbBAE6oAAXTyDhMAAAEAI4UCoEAAABM+YnMjAgOgQAAAEFGgUAAAELxhYmb3vQgAAAEASgAQBwEAXwABAPOAAmlwAQQA88cPAAABAAEA8wABcDswAAABAAAMAAEAoAYMACOAA6AwAAALrbBwEvAAAWFlafOAA2RtbgEAADowAAABAAAAAAAHABAAAADICPkL9BH1EUkSShJLEkwS8wIBZDswAAABAAAJAAMAJxEDAO8RAwAhEgEAI4ACoJAAABOGaW8BgAOwMBKlAAGAEuYAEAGwUBBtAAFjc3jzAAFlAZwEAADnFQAAiaAAAAAMB6BAAAAMW7BADFwAAZBIXQH4AQAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3289f09b047b.js b/pr/545/docs/search.index/3289f09b047b.js new file mode 100644 index 000000000..286cebe8e --- /dev/null +++ b/pr/545/docs/search.index/3289f09b047b.js @@ -0,0 +1 @@ +rn_("AYICoFAAABJPoQAAABP2Y3QjAAKwQA9aAAFldTswAAABAAA3ABYAmgYBAMMLAQChDAEAXw8BAN4PBQAPEAUAiBABAOcQAQBxEQIAPhIDAG4SBACeEgEApBIBALMSAQA2EwEASRMBAGcTAQBrEwEAjhMAALUTAQC5EwEA2BMAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/32c74d9cf3af.js b/pr/545/docs/search.index/32c74d9cf3af.js deleted file mode 100644 index 9b5a4dd23..000000000 --- a/pr/545/docs/search.index/32c74d9cf3af.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEBsIASpQABdfL8CAAAAQAjgAKwEAj6AAEzNgECAPMOBwAA6gEBAAECAPT1CAAAAQCeBwEAAQIA8+MLAAABAAEAE4ACsBAI8wABaXUBAgA7MAAAAQAACwACAAcTBQC8EwUA8wkBbTswAAABAAAMAAMAuRAAACUSBQB8EwUAdzAAAIqgMAAAEx2gcAAAEUSgIAAACPewMBEIAAGgUAAAD1ozhQs7MAAAAQAAHgIEAOYBAAAMAicBMgcAALIJ9AA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/32d7ceba568b.js b/pr/545/docs/search.index/32d7ceba568b.js deleted file mode 100644 index bf77ecca1..000000000 --- a/pr/545/docs/search.index/32d7ceba568b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQgA9XQTAAABAAEAAQABAPMAAWY7MAAAAQAABQACAN0BAADtDwQAAQIAOzAAAAEAAAsAAgAHEwUAvBMFAPMGAW07MAAAAQAADQAEAFoMAAC5EAAAJRIFAHwTBQBjgAOwAAjZAAFlbXM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/3381b6452880.js b/pr/545/docs/search.index/3381b6452880.js new file mode 100644 index 000000000..041ac6cbe --- /dev/null +++ b/pr/545/docs/search.index/3381b6452880.js @@ -0,0 +1 @@ +rn_("AQIBsEATIgABZfKYBgAAAQABBADz9A8AAAEAAQBDAAOwQBKIAAGxABNnAAFlZnA7MAAAAQAAJAAGAAgCAACnBgwAtQYMAC8PBgCLEAAAxxIBAGOAA7AwC8oAA2FlaQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/339b70d50fee.js b/pr/545/docs/search.index/339b70d50fee.js deleted file mode 100644 index 913651502..000000000 --- a/pr/545/docs/search.index/339b70d50fee.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOjAAAAEAAAAAAA4AEAAAAJMMlAxiED4RPxFAEfMR/BH9EQESAhJXElgSjRKOEgEJAPPHEAAAAQABAAEKAPMKEgAAAQABAAEGAPWMEAAAAQABAAEAAQDzgAJkbnMAhLEgE3AAAQARA/JhEgAAAQABDQD22BIAAAEAogBUABYAAQABgAKwoBLwAAGgEAAAC8ljdQEBAPT/EgAAAQBLAAEA8wABZfIoCQAAAQD3AACAxbAwEAkAAQACqAg=") \ No newline at end of file diff --git a/pr/545/docs/search.index/342a647c77a6.js b/pr/545/docs/search.index/342a647c77a6.js new file mode 100644 index 000000000..7baa88421 --- /dev/null +++ b/pr/545/docs/search.index/342a647c77a6.js @@ -0,0 +1 @@ +rn_("AQAA9psQAAABAHMDAQAKAAEAAQAAOzAAAAEAAAYAAgD2EgAAXBMFACOIArBAE80AAWVzAQ0BsEATxwABZfWPEwAAAQABAAEAAQABBQA7MAAAAQAACAADAHERAgBuEgQAjhMAANcBAACFHYyPbzNAFIQC83kMAAABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3491b6741081.js b/pr/545/docs/search.index/3491b6741081.js deleted file mode 100644 index 34d05d69c..000000000 --- a/pr/545/docs/search.index/3491b6741081.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAAOjAAAAEAAAAAAAoAEAAAAD4PPw8mECcQrxA5EToRTRJOEtUT1hPzAQF58kATAAABACMAA6BAAAAQzqBQAAATjGVvc/IiDwAAvAI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/34fdabda10df.js b/pr/545/docs/search.index/34fdabda10df.js deleted file mode 100644 index 226e65747..000000000 --- a/pr/545/docs/search.index/34fdabda10df.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEA9bUHAAABAAEAAQABAAEAAqAwAAAQaaCQAAASyTBo9UcRAACKAQEAAQABABOAAqAwAAAPKGRyIwKEsBAIrQMdsCALmwD6oDAAAA9NEgAY9WYFAAAtAAEAAQABADOAhLCgEg0AAbBADzIAARBJAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/351cf7b3eacb.js b/pr/545/docs/search.index/351cf7b3eacb.js deleted file mode 100644 index 432fb3be7..000000000 --- a/pr/545/docs/search.index/351cf7b3eacb.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABsIATbgABcPJqEwAAAQBDBQOgIAAAEKygQAAAEfNkZXPzUQ8AAC8DAQABAgA7MAAAAQAAEwABAHwPEwATgYSgUAAAEF2gEAAAC7ygIAAADHccQAAzgAOwUBK8AAFhZm4=") \ No newline at end of file diff --git a/pr/545/docs/search.index/355e9ccc3e7d.js b/pr/545/docs/search.index/355e9ccc3e7d.js new file mode 100644 index 000000000..bc1b1f5c1 --- /dev/null +++ b/pr/545/docs/search.index/355e9ccc3e7d.js @@ -0,0 +1 @@ +rn_("AQcA9goTAAABAKMAVAAWAAEA8wEBaQEqCQAAAQAA9S0JAAABAAEAAQABAEcBAIDGP4ZFwA18oKAAABP1sGATbQABoBAAAAkBAAogig==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3580644ae6d8.js b/pr/545/docs/search.index/3580644ae6d8.js new file mode 100644 index 000000000..d9bc29d48 --- /dev/null +++ b/pr/545/docs/search.index/3580644ae6d8.js @@ -0,0 +1 @@ +rn_("AQIBoDAAAA/8YQEJDAAAAYECoCAAABB2sFASKwABYW8BAwGgAAAAE0tzAXUQAAAjgAKgAAAAB8hydmMAA7BQEOcAAWNlczswAAABAAAIAAQA0QgCAP8IAQD0DwIAERIAAAcBAICFsFAQpgABoKAAABMWsPATLQABsCAPOAABRCEE84ACbnQ=") \ No newline at end of file diff --git a/pr/545/docs/search.index/3587167fe015.js b/pr/545/docs/search.index/3587167fe015.js deleted file mode 100644 index 57bb04f22..000000000 --- a/pr/545/docs/search.index/3587167fe015.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABsKASDwABZTswAAABAAAJAAIAogcHAE8SAQABAAGgIAAADHFtAU8FAAABgAKwoBINAAGwQA8yAAFsbwEAAPRJEgAAAQABAAEA8wQBZPTvEQAAAQABAAEAIwKEsKAThAABsEASRwABsHATMgABFYAAAVoTAAABAAGwgBNuAAFw8moTAAABAEMAA6AgAAAQrKBAAAAR82Rlc/NRDwAALwMBAPOBAmVp1wIAAIawIBHUAAGw0BNyAAEXAQL0dAQAAAEAAQDBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/35c861889432.js b/pr/545/docs/search.index/35c861889432.js deleted file mode 100644 index cb40f4548..000000000 --- a/pr/545/docs/search.index/35c861889432.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQA9qwTAAABAA0AAQAjAAQAAQMA8/4RAAABAAEAI4ECsSAT4wABY2sTgAKgMAAAE2xuclMAA6BAAAALtWVvcvR1EAAAcQGwAQEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3650ebdc9bae.js b/pr/545/docs/search.index/3650ebdc9bae.js new file mode 100644 index 000000000..5f74a8cc9 --- /dev/null +++ b/pr/545/docs/search.index/3650ebdc9bae.js @@ -0,0 +1 @@ +rn_("AQEAOjAAAAEAAAAAAAcAEAAAALoSuxJTE1QTihOLE9YT1xPzBgFpAdkSAAAjgAKwUBKuAFlmbgEAAbBAEogAAWU7MAAAAQAADQACAKcGDACLEAAAI4ACoDAAAAvKYWU3AACAxbBQEwEAAbAQE6MAAbBgEwgAAQACmAg=") \ No newline at end of file diff --git a/pr/545/docs/search.index/36590b411474.js b/pr/545/docs/search.index/36590b411474.js new file mode 100644 index 000000000..9e676b0c4 --- /dev/null +++ b/pr/545/docs/search.index/36590b411474.js @@ -0,0 +1 @@ +rn_("AYQCsCARAAEVoJAAABOObXABgAKgMAAAEIugUAAAEzRjcpcAAACFsCATAQABsMATvQABoGAAABFVEEAOOzAAAAEAABIABgCsBAgAUxEBAGcSAQBREwEApRMBABYUAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/368640dd3a84.js b/pr/545/docs/search.index/368640dd3a84.js new file mode 100644 index 000000000..adaf64363 --- /dev/null +++ b/pr/545/docs/search.index/368640dd3a84.js @@ -0,0 +1 @@ +rn_("AQAA9C4QAAABAAEAAQDzAgFz9RUJAAABAAEAAQBEBgEGAPR4EQAAAQABAAEAAQQBoEAAABOJZfL5EwAAAQABAQA7MAAAAQAABgABABwUBgDzBgFl9NATAAABAC8AAQAzBgOwYBLwAIdhcnXz/w8AAGICAQDzgAJhZQEDAPQyEQAAAQABAAEAAQIA9FEPAAABAC8EAQABggKgEAAAEsawQBJnAAFhcwGAA7AAB0oAAaAAAAALzrBwEAwAAW5yc+cHAACHoHAAABF3kQVBOjAAAAEAAAAAAAwAEAAAANkB2gHbAdwBTAe1B7YHHgkIDIwPjQ+OD5cQ") \ No newline at end of file diff --git a/pr/545/docs/search.index/37122b199c40.js b/pr/545/docs/search.index/37122b199c40.js deleted file mode 100644 index 888c989f9..000000000 --- a/pr/545/docs/search.index/37122b199c40.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEA9PgGAAABAAEAAQABAQGgQAAAENVz9cgLAADjBDwBAQABABOCAqAgAAAMkmVyI4ADoEAAAAvHsDAI3gABZW90AQAA9PQGAAABAAEAAQABAgD02hIAAAEADwABABOAArBAE4oAAWJ284ACb3gBCgD1ExMAAAEAAQBzAAEAAYECoCAAABBIsFAR+gABYW8BBAGgAAAAExhzAUcQAABjAwOwUBC3AAFjZXP2uAgAAAEAAQAuAAEA9wgBAQD0XwwAAAEAAQABACOAArAwEnkBV3J08wCGAcAH8twBAADQBQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3792ea5bd86e.js b/pr/545/docs/search.index/3792ea5bd86e.js deleted file mode 100644 index e65e95a1f..000000000 --- a/pr/545/docs/search.index/3792ea5bd86e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsEASqQABoMAAABNhZW8BAgD0HBEAAAEAAQABABMAA7AgESAAAbCAE3IAAWFzdAFkDAAAAQQA81cPAAABAAEAs4CEsEASvAABQQAG") \ No newline at end of file diff --git a/pr/545/docs/search.index/37ae2f2cc265.js b/pr/545/docs/search.index/37ae2f2cc265.js new file mode 100644 index 000000000..7e096b382 --- /dev/null +++ b/pr/545/docs/search.index/37ae2f2cc265.js @@ -0,0 +1 @@ +rn_("AYECsDAPwwABsBATJAABc3QBAwDzOxIAAAEAAQAjgAKwABE4AAFoaQEAADswAAABAAATAAEAWAcTACOAAqAwAAAMh2Fl84ACcnTzAAJhbDswAAABAAAoAAMAlAATAJ8BAACpDxMA") \ No newline at end of file diff --git a/pr/545/docs/search.index/37ae4ca5ac42.js b/pr/545/docs/search.index/37ae4ca5ac42.js deleted file mode 100644 index e43a74bf6..000000000 --- a/pr/545/docs/search.index/37ae4ca5ac42.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQACoCAAABLIsDARLwABaXTyMhIAAAEAAQMAOzAAAAEAAAYAAQCwEAYAAQgA9C8TAAABAIIABQATAQOwkBORAAGwUBJ5AVdnbHA7MAAAAQAAEgAJAMEPAgAyEQEAaBIBAIkSAQC/EgEAIBMBAFcTAQBmEwEAoxMBAAGAArAwESsAAbAwES0AAXJ2AQQBsAAR9AABZDswAAABAAAFAAIAJxEDACESAQC3BQABh7BQEfYBDLBgEncAAZQJAzowAAABAAAAAAALABAAAABlDGYMZwwNDg4OWRDaENsQ3BDdEG8SqBIjgAKgEAAADGRubwEDAPO+DwAAAQABACOAAqAAAAALp2RyYwGEoFAAABDXoDAAAA/3FAEQ8lcHAAABABOAA7BgEhYAAbAADwsAAWNnchOAA6CwAAATTaBAAAAODGVvcw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3810d433a829.js b/pr/545/docs/search.index/3810d433a829.js deleted file mode 100644 index 8ff8aa525..000000000 --- a/pr/545/docs/search.index/3810d433a829.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABsGATQgABZQF5EwAAAQYA9HESAAABAEMBAQABBAD0ixIAAAEABQEBAPMAA2VyczowAAABAAAAAAAJABAAAADbCNwI3QiTENAQ1hHXEeQROhM7Ew==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3874f15e7771.js b/pr/545/docs/search.index/3874f15e7771.js new file mode 100644 index 000000000..2592ec0a1 --- /dev/null +++ b/pr/545/docs/search.index/3874f15e7771.js @@ -0,0 +1 @@ +rn_("AQMA9qwMAADFAloAAQC4AgEAAQQAOzAAAAEAAAoABAAPEAUAQBIBAJ4SAQC6EwAAAYYCoAAAABLAoAAAABLBZHLzAgF2AewSAADzgAJlbycBAADHoDAAAA9woHAAABIRoIAAABONoNAAABMwoLAAABONQEUICTswAAABAAAJAAMAmQUCAPIGBAANDAEAI4ACU5KIn+d+ZHIBAAA6MAAAAQAAAAAACgAQAAAAIAkhCaYP2hLbEgoTCxOuEwIUGBQZFBOAAqAwAAAQJWx0w4AEoAAAABAVoAAAABAWNDZhZQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/38b236771a65.js b/pr/545/docs/search.index/38b236771a65.js new file mode 100644 index 000000000..9354b1f19 --- /dev/null +++ b/pr/545/docs/search.index/38b236771a65.js @@ -0,0 +1 @@ +rn_("AQQA9NUTAAAMAB4ADwABAgGwQBItAAFlAVQPAAABgAKgkAAAE5ugkAAAE5wyM5cCAADGoCAAAAwnoGAAABDAsGAMswABAWQAAzswAAABAAAKAAMA7AYFAPMLAADjEgMA") \ No newline at end of file diff --git a/pr/545/docs/search.index/38be63c8f52d.js b/pr/545/docs/search.index/38be63c8f52d.js deleted file mode 100644 index 91375a085..000000000 --- a/pr/545/docs/search.index/38be63c8f52d.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsHAQwwABsCATigABYWQBBQD0ghIAAAEAkwABAPMAAWMB7hEAAEOAA7AwEtYAAbCgE3AAAWFzeQEGAPRjEAAAAQC2AAEAk4CEoAAAABCqsSATzQABCSAB84ACZWk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/38e853561a8a.js b/pr/545/docs/search.index/38e853561a8a.js new file mode 100644 index 000000000..a52df7590 --- /dev/null +++ b/pr/545/docs/search.index/38e853561a8a.js @@ -0,0 +1 @@ +rn_("AQQBsEATxwABZfWPEwAAAQABAAEAAQABAgA7MAAAAQAACwACADoTBQDvEwUA8wEBbTswAAABAAANAAQAfgwAAOkQAABWEgUArxMFAPMBAWXydREAAAEAM4CEsBAQDAABoCAAAAvOFEAE") \ No newline at end of file diff --git a/pr/545/docs/search.index/39a52dda198c.js b/pr/545/docs/search.index/39a52dda198c.js new file mode 100644 index 000000000..9ec0123fc --- /dev/null +++ b/pr/545/docs/search.index/39a52dda198c.js @@ -0,0 +1 @@ +rn_("AQQBsEATxwABZfWPEwAAAQABAAEAAQABAgA7MAAAAQAACwACADoTBQDvEwUA8wMBbTswAAABAAANAAQAfgwAAOkQAABWEgUArxMFAPOAAmNl") \ No newline at end of file diff --git a/pr/545/docs/search.index/3a0723146c92.js b/pr/545/docs/search.index/3a0723146c92.js new file mode 100644 index 000000000..62b7bb9f1 --- /dev/null +++ b/pr/545/docs/search.index/3a0723146c92.js @@ -0,0 +1 @@ +rn_("AYMCsCARAAEVoJAAABOObXABggKwoBOBAAGwoBODAAFjcgECAaBAAAAQ/2UBwA8AADOAhLAgEH0AAbAgD0EAAVAUAPOAAm9y") \ No newline at end of file diff --git a/pr/545/docs/search.index/3a65c80ab51b.js b/pr/545/docs/search.index/3a65c80ab51b.js deleted file mode 100644 index 342fca870..000000000 --- a/pr/545/docs/search.index/3a65c80ab51b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQACoDAAABBpoJAAABLJMGj1RxEAAIoBAQABAAEAE4ACoDAAAA8oZHIjAISwEAitAx2wIAubAPqgMAAAD00SABj1ZgUAAC0AAQABAAEAAQIA9NwTAAABAAoAAQABAgDzxw8AAAEAAQDzgAJpcgEBArBAEK0AAaBQAAASsGVz9AcOAAC8AgEAewIBCwD22BIAAAEAogBUABYAAQDzgAJsdNOAhKCQAAASiAFEBA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3a7213b0a18a.js b/pr/545/docs/search.index/3a7213b0a18a.js deleted file mode 100644 index ff1b3e42c..000000000 --- a/pr/545/docs/search.index/3a7213b0a18a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEA818PAAABAAEAAQMBoEAAABNWZfLGEwAAAQABAQGgIAAAEJFi8wAMAAABAAEAE4ACoBAAAAwDYWNzgISgUAAAD0UQQAw=") \ No newline at end of file diff --git a/pr/545/docs/search.index/3a93f64bc2c4.js b/pr/545/docs/search.index/3a93f64bc2c4.js deleted file mode 100644 index 5e65521e5..000000000 --- a/pr/545/docs/search.index/3a93f64bc2c4.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQkA86wTAAABADUAAQ0BoKAAABPwd/LgEwAAAQABgQKwgBO6AAGgYAAAE95kczcBAIaFoEAAABOPsGATYwBMApAK") \ No newline at end of file diff --git a/pr/545/docs/search.index/3ac7cfd35a72.js b/pr/545/docs/search.index/3ac7cfd35a72.js deleted file mode 100644 index cf848ebc0..000000000 --- a/pr/545/docs/search.index/3ac7cfd35a72.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBsEAQrQABZQEHDgAAAQUAOzAAAAEAAAYAAQC3DwYAAQMA9F8MAAABAAEAAQDzAAJwczowAAABAAAAAAAMABAAAAByBYIGyAjsC/kLUxBUEPQR9RFJEkoSSxJMEjMAA7BQDywAymRwcjswAAABAAAPAAYAcwQAADMFAwAZDwAAJxEDAO8RAwAhEgEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3b114748649d.js b/pr/545/docs/search.index/3b114748649d.js new file mode 100644 index 000000000..f8c1badf1 --- /dev/null +++ b/pr/545/docs/search.index/3b114748649d.js @@ -0,0 +1 @@ +rn_("AQQBoEAAABOJZfL5EwAAAQABAQA7MAAAAQAABgABABwUBgDzBgFl9NATAAABAC8AAQAzAQOwYBLwAIdhcnXz/w8AAGICAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/3b4e28ed9312.js b/pr/545/docs/search.index/3b4e28ed9312.js new file mode 100644 index 000000000..fbfe67c34 --- /dev/null +++ b/pr/545/docs/search.index/3b4e28ed9312.js @@ -0,0 +1 @@ +rn_("AYACsIASdQABsKAS7QABaXQBgAKw4BPjAAGwQA/YAAFscgEGAPRlEAAAAQABAAEARwUAAIeg0AAAE7+wUA/WAAGgAAAAEu+w8BOdAAEFkQPyeg8AAKoA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3bc3c52a55c9.js b/pr/545/docs/search.index/3bc3c52a55c9.js deleted file mode 100644 index 399113700..000000000 --- a/pr/545/docs/search.index/3bc3c52a55c9.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABoJAAABKvaPJ3EgAAAQDzAgFk8tIGAAABAAECADswAAABAAAFAAEAvBMFAPMLAW07MAAAAQAABQABAHwTBQAjgAKwIAxyAAFhbwECAPO0CAAALQMBAAGKArAAExkAAbAAExsAATQ2I4ECoDAAAAwHZXIBgAKwQBE5AAF6Wir2awxjdbcGAACHsBAPqwABsFATmAABEVEJ9W4EAAAKAMAAAQBZBw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3bf70d50c752.js b/pr/545/docs/search.index/3bf70d50c752.js deleted file mode 100644 index d668a364f..000000000 --- a/pr/545/docs/search.index/3bf70d50c752.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQwA8/gSAAABAAEAAQYA874QAAABAAEAAYICsGASgAABsNATlgABaXITgAKwEAxvAAFlaRcDAIOIsTATswABoGAAABC9oFAAABBSsJASUwABsEAQTwABtBAH8wABYfT1CAAAAQCeBwEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3c0f5abd09f3.js b/pr/545/docs/search.index/3c0f5abd09f3.js new file mode 100644 index 000000000..dc41dcf6f --- /dev/null +++ b/pr/545/docs/search.index/3c0f5abd09f3.js @@ -0,0 +1 @@ +rn_("AQAA9A0HAAABAAEAAQABhQKwcBN+AAGwMBLUAAFlcxMAA7BAD10AAaBgAAARCGJlczswAAABAAASAAQAgwUBAJwGCgDWDwEAKRADAAECAPOPBQAA8wkBAAEDAPVVDwAAnQABAAQAAQABCgGgQAAAE8Zl8uYTAAABACMABKAwAAAQl6CQAAAS+7BgEikAATBjaGn1dxEAAIwBAQABAAEA84ACZHLnBAAAh7AQCMYDJLAgC7sA/6AwAAAPehJBODswAAABAAASAAYAhQACAHYFAACkBQMAbgcFALEHAwDGCwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3c17bff3a5ab.js b/pr/545/docs/search.index/3c17bff3a5ab.js deleted file mode 100644 index 4c3c49141..000000000 --- a/pr/545/docs/search.index/3c17bff3a5ab.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsAAPegABsCAL8QABZWkBiQKwIBOfAAGgMAAAE6lpcBMAA6AgAAASZ6CAAAASemVpdfWpCwAANAABAAEAAQABhgKwkBPEAAGgAAAAEfdiZAGAArAwElsAAaAwAAAQRnJ21wAAAIWgMAAAD8SgMAAAErEQARM6MAAAAQAAAAAACgAQAAAAsQiyCLMI5QjmCLUL3A/hD5YQlxA4EmOAA7AQCKUAAWRtdA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3c89aeb97d29.js b/pr/545/docs/search.index/3c89aeb97d29.js deleted file mode 100644 index cb4901978..000000000 --- a/pr/545/docs/search.index/3c89aeb97d29.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9FcQAAABAIMBAQABAAD0Sg8AAAEA6gD/ACOCArBQEo0AAWVzAQIA9F8SAAABAI4AAQABAwD0kxIAAAEAkwABAPOFAmJ1AQIA9MEQAAABAGwBAQDzgAJpbPMAA2J0dTowAAABAAAAAAAPABAAAAAvB7wHvQe+B78Hcg8uEOUSYxOsE60TrxO6E7sT3hPiEwEMAPNIEwAAAQABAAGAArAACNEAAaAgAAAMiWRuAQYA9F0SAAABAI4AAQDzAwFi9FUQAAABAIMBAQCXBgAAh7BAD0gAAaBwAAAR5bCQEosAATgJAzswAAABAAAiABEAiwUDAPEGAQB+DAIAhAwCAEAPAQCUDwEAmQ8BALcPBgD7DwAAKBABAMUSAADpEgAADRMAAKITAACuEwAAzBMAANsTAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/3c8f419d6519.js b/pr/545/docs/search.index/3c8f419d6519.js new file mode 100644 index 000000000..69ea2bae2 --- /dev/null +++ b/pr/545/docs/search.index/3c8f419d6519.js @@ -0,0 +1 @@ +rn_("AQACoCAAABL6sDARXwABaXTyYxIAAAEAAQMAOzAAAAEAAAYAAQDgEAYAAQgA9GITAAABAIIABQATAQOwkBPEAAGwUBKqAVlnbHA7MAAAAQAAEgAJAO4PAgBiEQEAmRIBALoSAQDxEgEAUxMBAIoTAQCZEwEA1hMBAAGAArAwEVsAAbAwEV0AAXJ2AQQBsAASJQABZDswAAABAAAFAAIAVxEDAFISAQC3BQABh7BQEicBDrBgEqgAAZQJAzowAAABAAAAAAALABAAAACJDIoMiww3DjgOhxAKEQsRDBENEaAS2RIjgAKgEAAADIhubwEDAPPrDwAAAQABACOAAqAAAAALx2RyYwGEoFAAABEHoDAAABAkFAEQ8mwHAAABABOAA7BgEkcAAbAADzgAAWNnchOAA6CwAAATgKBAAAAONmVvcw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3ccd0c7a2788.js b/pr/545/docs/search.index/3ccd0c7a2788.js new file mode 100644 index 000000000..37bd94be5 --- /dev/null +++ b/pr/545/docs/search.index/3ccd0c7a2788.js @@ -0,0 +1 @@ +rn_("AQQAOjAAAAEAAAAAAAcAEAAAAGEPYg8mECcQjhKPEh4THxMBAAD0zggAAAEAdArgACcAAACIoRAAABPboEAAABCQsGATywABoBAAAAw2sFATaQABsDAQ8wABsSAT6wABOcECOjAAAAEAAAAAABAAEAAAAOQI5Qj4CPkIwAvBC8ILygvNC4cMEBLzEvQSCBMJE3kTehMzgAOggAAAE3Jlb3k=") \ No newline at end of file diff --git a/pr/545/docs/search.index/3d2200f2a97e.js b/pr/545/docs/search.index/3d2200f2a97e.js deleted file mode 100644 index 735bfd171..000000000 --- a/pr/545/docs/search.index/3d2200f2a97e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQgA9B4TAAABAFMAAQABAgGgYAAAE8Nz8iARAAABAAGAArAgD3oAAaCQAAATeWFlAQcBsEATlAABZfVcEwAAAQABAAEAAQABAwGwQBOqAAF08g4TAAABACOFAqBAAAATPmJzAQEA9BwRAAABAAEAAQATgAKgMAAAEFFkbDd0AACLsEAS8AABoFAAABC8oJAAABLksFASRAABoDAAAAv+s5gHOzAAAAEAAF0AEQDxAQEAOQQDAI8FAACDBgEAHgcBAL0IAQDKCAAA1ggAAAgJAAAUDD0AZAwAAEYPAQAYEAEAMxABAHgQAQD3EAQA+hEBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3d5f153390be.js b/pr/545/docs/search.index/3d5f153390be.js new file mode 100644 index 000000000..81a24667c --- /dev/null +++ b/pr/545/docs/search.index/3d5f153390be.js @@ -0,0 +1 @@ +rn_("AQUAOzAAAAEAAAcAAwA/EQIA5xIBAHsTAgABBwD2ChMAAAEAowBUABYAAQABBADzQhEAAAEAAQAjAAKgYAAAEmlhcvNrEAAAAQC8AQGAAqEQAAAT/7CAE/cAAWl1dwgAAIixUBQaAAGgAAAAEEywcBNEAAGhMAAAFA4KQRvyKgkAAPsGAYECoFAAABCPoKAAABK5a3ABAwA7MAAAAQAA9wACAI4MAQA5DvUA84ACbHTzgAJhZQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3db3d3836bf3.js b/pr/545/docs/search.index/3db3d3836bf3.js deleted file mode 100644 index 477522123..000000000 --- a/pr/545/docs/search.index/3db3d3836bf3.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYkCsCATnwABoDAAABOpaXATAAOgIAAAEmeggAAAEnplaXX1qQsAADQAAQABAAEAAYYCsJATxAABoAAAABH3YmQBAgD0sAsAAAEAWAMBAAEAAPTvCAAAAQABAAEAAQAAOzAAAAEAAAYAAgDEEgAAKRMFACOBArBAE5oAAWVz84ADZXh5AQAA9OsIAAABAAEAAQAjgAKwIBJbAAFyeEcBAADGsMAS8AABoBAAABC9sEAMbAABoDAAABBGAESAC/Q7BQAAAQA2BwEA1wAAAIWgMAAAD8SgMAAAErEQARM6MAAAAQAAAAAACgAQAAAAsQiyCLMI5QjmCLUL3A/hD5YQlxA4Eg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3e10313c5965.js b/pr/545/docs/search.index/3e10313c5965.js new file mode 100644 index 000000000..044978936 --- /dev/null +++ b/pr/545/docs/search.index/3e10313c5965.js @@ -0,0 +1 @@ +rn_("AQYA9FETAAABAFMAAQAjgAKhEAAAFANjchOAAqAgAAAI2mh5AQEBoGAAABP2c/JQEQAAAQAjgAKwIAk/AAFldQGAArAgD6cAAaCQAAATrGFlAQcBsEATxwABZfWPEwAAAQABAAEAAQABBAGwABKUAAFzOzAAAAEAAAsAAgAOEwcA+xMDAEcAAASGoIAAABLvsQAUCAABsEASUAABsIAUFgABsFASlgABFQAW9DIOAAABAAEAAQCDAISwQBQMAAGwMBKGAAGwMBMiAAHAAAM6MAAAAQAAAAAACQAQAAAAmgSMEI0QMBExETYRNxFvE3AT2xMBAwGwQBPdAAF08kETAAABACOFAqBAAAATcWJzAYACoAAAAAj6oCAAABB/Z3ABAQD0TBEAAAEAAQABAPOAAmRst+gAAIyg0AAAEvqgUAAAEOygkAAAExawUBJ1AAGgMAAADB63mAc7MAAAAQAAYQATAPIBAQD4AQEASAQDAKAFAACYBgEAMwcBAEYHAADWCAEA4wgAAO0IAAAfCQAANww+AIgMAABzDwEARhABAGEQAQCmEAEAJxEEACsSAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/3e3cbb04f471.js b/pr/545/docs/search.index/3e3cbb04f471.js new file mode 100644 index 000000000..27f235dfb --- /dev/null +++ b/pr/545/docs/search.index/3e3cbb04f471.js @@ -0,0 +1 @@ +rn_("AQUA9KQSAAABAJEAAQDzAAFj9dsPAAABALwAAQABAAEJAPPfEwAAAQA1AAENAaCgAAAUI3fyExQAAAEAAYECsIAT7QABoGAAABQRZHM3AQCEhaBAAAATwrBgE5YATAKQCiOAAqBwAAAQ22RyAQsBoEAAABPGZfLmEwAAAQATgAKwMA/3AAFkcvMCAWX0sQcAAAEAAQABACOAArAgC74AAWV5AQoA8y8SAAABAAEAAQsAOzAAAAEAAAcAAQAOEwcAAQIA9GsTAAABAEkAAQC3AACAhbBwEmMAAbDQFAgAAWAgBgEGAPM7EgAAAQABAAEDAbBAE90AAXTyQRMAAAEAI4UCoEAAABNxYnMjAgOgQAAAEH+gUAAAEOxhYmb31ggAAAEASAAnBwEAXwABAPOAAmlwAQQA8/QPAAABAAEA8wABcDswAAABAAAMAAEAtQYMACOAA6AwAAALzbBwEyIAAWFlafOAA2RtbgEAADowAAABAAAAAAAHABAAAADhCBkMJRImEnoSexJ8En0S8wIBZDswAAABAAAJAAMAVxEDACASAwBSEgEAI4ACoJAAABO5aW8BgAOwMBLWAAGAExgAEAGwUBCbAAFjc3jzAAFlAasEAADnFQAAiaAAAAAMKqBAAAAMf7BADIAAAZBIXQH/AQAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/3e98557ba4a3.js b/pr/545/docs/search.index/3e98557ba4a3.js new file mode 100644 index 000000000..49f684ba0 --- /dev/null +++ b/pr/545/docs/search.index/3e98557ba4a3.js @@ -0,0 +1 @@ +rn_("AQkA898TAAABADUAAYACoEAAABLGsCATgQABaGkBDAGgoAAAFCN38hMUAAABAAEBAPN/DwAAAQABAPOAAnR1AYECsIAT7QABoGAAABQRZHM3AwCAhqBAAAATwrBgE5YATAKQDgEAAbBQEIgAAWP0LwcAAAEAAQAEAsOAhKAQAAAMKqBQAAASEQxABA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3f00814740bc.js b/pr/545/docs/search.index/3f00814740bc.js deleted file mode 100644 index 7617cd4b7..000000000 --- a/pr/545/docs/search.index/3f00814740bc.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQgA9M0PAAABAKgAAQABAAGggAAAE99m8rAIAAAeCgEHAPWeEgAAAQABAAEAAQAjgAKgUAAAEK9hb/MCAmZzOzAAAAEAAAgABAAKBwAAPQcFAIoMAADnEAAAM4ADoEAAAAumYWVv") \ No newline at end of file diff --git a/pr/545/docs/search.index/3f0b4ad53d12.js b/pr/545/docs/search.index/3f0b4ad53d12.js deleted file mode 100644 index 37a30c377..000000000 --- a/pr/545/docs/search.index/3f0b4ad53d12.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9AAQAAABAAEAAQDzAgFz9f4IAAABAAEAAQAuBgEGAPRIEQAAAQABAAEAAQQBoEAAABNWZfLGEwAAAQABAQA7MAAAAQAABgABAOkTBgDzBgFl9J0TAAABAC8AAQAzBgOgYAAAE0RhcnXz0g8AAF4CAQDzgAJhZQEDAPQCEQAAAQABAAEAAQIA9CQPAAABACkEAQABggKgEAAAEpWwQBI2AAFhcwGAA7AABzUAAaAAAAALrrBwD98AAW5yc+cHAACHoHAAABFHkQVBOjAAAAEAAAAAAAwAEAAAANIB0wHUAdUBNwegB6EHBwnoC18PYA9hD2kQ") \ No newline at end of file diff --git a/pr/545/docs/search.index/3f1a6e1729e4.js b/pr/545/docs/search.index/3f1a6e1729e4.js deleted file mode 100644 index c88f251b6..000000000 --- a/pr/545/docs/search.index/3f1a6e1729e4.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYA9PQSAAABAAEAAQABDwD00RMAAAEAAQABAAEAAbDwE9kAAWv2TRMAAAUAAQABAAEAJQABAgD0zQ8AAAEAqAABAPcAAACFsQATxgABiTAA8hYSAAABABOAArAQC+YAAWVvAQUAOzAAAAEAAA0AAQDoEA0AAQIA818PAAABAAEAAQIA9FsPAAABAAEAAQABAwA7MAAAAQAACAABAAsQCAABgAKgAAAAC7ywMBOUAAFxcgGAAqBAAAAQXbDAE4oAAWVzAQEAOzAAAAEAABMAAQB8DxMAI4ACsJAS+wABaW13NgAAiqBQAAATWbBwEzoAAaAgAAAMd5xVETswAAABAAALAAQAEwcAADcQAwD4EQEAXBMEAAECAbAwEMMAAXAB3xEAALOAhKAgAAARJgIoBA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3f243484e57a.js b/pr/545/docs/search.index/3f243484e57a.js new file mode 100644 index 000000000..51d7cfa7a --- /dev/null +++ b/pr/545/docs/search.index/3f243484e57a.js @@ -0,0 +1 @@ +rn_("AYACsHAT9wABoAAAAASGZmcBAQA7MAAAAQAABwABAPULBwABAQGgcAAAEg9hAeYGAAAjgAKhAAAAE/9kbnOAhKBgAAASDgBBSA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/3f24cd5aa4fa.js b/pr/545/docs/search.index/3f24cd5aa4fa.js new file mode 100644 index 000000000..ad2bb5df2 --- /dev/null +++ b/pr/545/docs/search.index/3f24cd5aa4fa.js @@ -0,0 +1 @@ +rn_("AQYAOzAAAAEAAAUAAQDJEgUAg4YEsFASkgABsHAS+AABoNAAABPPYm5vdhOAArAQEmUAAXByAQABoDAAABFkdAEXEwAA8wIBc/IoEAAA8wITgAKgYAAAEBlldQECAPa1DAAAAQAZAwEAJQEBAAGAArAAElAAAYAONjKQAWVzAQEA8ykHAADECwEAY4ADsIATaQABYm5084ADYW9yARQA9PsTAAABAAEAAQABAAA7MAAAAQAABgACAPYSAABcEwUAI4gCsEATzQABZXMBBAGwMBLHAAFj8wIRAAABAAEAAQUAOzAAAAEAAAgAAwBxEQIAbhIEAI4TAADzAgNjZXDzeQwAAAEAAQBjgAOgYAAAD3llb3UBAAGwYBN1AAFlAawTAADzAgFz9vIIAAABAAEAzQc/ABUBAQgA8y8SAAABAAEAQ4ADoBAAABL6oOAAABOAZG9zAQIBoFAAABEBcgGhEAAAAYACoEAAABAloHAAABO6YWUBAAA7MAAAAQAACwACAMoGBQBJEgUA84ACdHYBAQD0wgcAAAEAAQABAPMAAm5y9ucIAABXAMcGAQCwAAEA8wCHMJEM96kEAADWC+QBAQCFAAEA8AA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/3f8645c00d7c.js b/pr/545/docs/search.index/3f8645c00d7c.js new file mode 100644 index 000000000..f1fe4a621 --- /dev/null +++ b/pr/545/docs/search.index/3f8645c00d7c.js @@ -0,0 +1 @@ +rn_("AQIA9CwRAAABAAEAAQABCgDzKhMAAAEAAQDzgQJtdAEGAPPuEAAAAQABAAGCArBgErEAAbDQE8kAAWlyE4ACsBAMkwABZWkBBQD0axMAAAEASQABAPMEAWPycxIAAAEAI4ICsFASRQABZnQBAAGwABPAAAFk9LULAAABAAEAAQDzgQJlaTcGAACJsTAT5gABoGAAABDtoFAAABCAsJAShAABsEAQfQABtRAHAaATAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4031cc647b10.js b/pr/545/docs/search.index/4031cc647b10.js new file mode 100644 index 000000000..940904594 --- /dev/null +++ b/pr/545/docs/search.index/4031cc647b10.js @@ -0,0 +1 @@ +rn_("AQUAOzAAAAEAAPcAAgCODAEAOQ71AAEBAaAAAAAStnP1pgQAALEK1gMBAAMAAQECoGAAABM0oOAAABOOZXQ7MAAAAQAACAABAKwECAABgAOwIBIFAAGwsBI+AAGwsBJAAAFiY3PzgARjbHR2") \ No newline at end of file diff --git a/pr/545/docs/search.index/404afcce0ada.js b/pr/545/docs/search.index/404afcce0ada.js new file mode 100644 index 000000000..c3c579fe4 --- /dev/null +++ b/pr/545/docs/search.index/404afcce0ada.js @@ -0,0 +1 @@ +rn_("AQgA9PoPAAABAKkAAQABAAGggAAAFBJm8skIAAA3CgEHAPXPEgAAAQABAAEAAQAjgAKgUAAAEN9hb/MCAmZzOzAAAAEAAAgABAAfBwAAUgcFAK8MAAAXEQAAM4ADoEAAAAvGYWVv") \ No newline at end of file diff --git a/pr/545/docs/search.index/40b99a9f0103.js b/pr/545/docs/search.index/40b99a9f0103.js deleted file mode 100644 index fcfeff846..000000000 --- a/pr/545/docs/search.index/40b99a9f0103.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQcAOzAAAAEAAIYAAgBFEAAATRGFAAEDADswAAABAACFAAEAgQ2FAAECADswAAABAAAHAAEA1QsHAPMAA2JpdDswAAABAACGAAIAcgQAAK0EhQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/40feefc69675.js b/pr/545/docs/search.index/40feefc69675.js deleted file mode 100644 index 4892e6c0e..000000000 --- a/pr/545/docs/search.index/40feefc69675.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMA9A8MAAABAAEAAQABAAGwUBNwAAFyAZQEAABTAYSwQBH8AAGwQBOqAAGYAAQ6MAAAAQAAAAAAKAAQAAAAXgRfBGAEYgXCCMMI6ggdCV4MJw+WD5cPpA/TDysQLBAtEHQQ3RE5EjoSOxI8EmcSdRJ2EqMSpBIOEw8TExMUExUTJRMmE4gTiROfE6ATxBPFEw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/4100782a5d31.js b/pr/545/docs/search.index/4100782a5d31.js new file mode 100644 index 000000000..9bb908fa5 --- /dev/null +++ b/pr/545/docs/search.index/4100782a5d31.js @@ -0,0 +1 @@ +rn_("AQIAOzAAAAEAAAUAAQDvEwUA8w0BbTswAAABAAAFAAEArxMFAEcAAACFsAATwAABsEASMgABoQAAABP1sAAS8ACHOAgCOzAAAAEAABgABgC1CwMArhAHAFQSAQDPEgQApxMEABIUAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/410d825e5fa8.js b/pr/545/docs/search.index/410d825e5fa8.js deleted file mode 100644 index b8453ad11..000000000 --- a/pr/545/docs/search.index/410d825e5fa8.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMA9ocMAAC9AloAAQC0AgEAAQQAOzAAAAEAAAoABADiDwUADxIBAG0SAQCHEwAAAYYCoAAAABKPoAAAABKQZHLzAgF2AbsSAADzgAJlbycBAADHoDAAAA9DoHAAABHgoIAAABNaoNAAABL9oLAAABNaQEUICTswAAABAAAJAAMAiAUCAN0GBADtCwEAI4ACFX3rkKKdZHIBAAA6MAAAAQAAAAAACgAQAAAACQkKCXkPqRKqEtgS2RJ7E88T5RPmExOAAqAwAAAP+Gx0w4AEoAAAAA/ooAAAAA/pNDZhZQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/4155c1291357.js b/pr/545/docs/search.index/4155c1291357.js deleted file mode 100644 index ddf03542e..000000000 --- a/pr/545/docs/search.index/4155c1291357.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEA928QAAABAAEAvgIBAIIABQABAgD0BBAAAAEAAQABABOAAqDQAAAToWNz84ACZW8jgQKwAAcPAAFsdAEAAPR6BQAAAQABAAEAU4CEoFAAABPwsKATPAABCCAF") \ No newline at end of file diff --git a/pr/545/docs/search.index/4159f6c35981.js b/pr/545/docs/search.index/4159f6c35981.js new file mode 100644 index 000000000..9ee2a28d9 --- /dev/null +++ b/pr/545/docs/search.index/4159f6c35981.js @@ -0,0 +1 @@ +rn_("AYICsCAQwgABsDAROAABZXABBQD0aw8AAAEA6AABAFOAA7CQEWkAAWFpcgGBArCgE4EAAbCgE4MAAWNyxwAAAIWwUAyhAAGgIAAACT2gIAAAC9U8AAE6MAAAAQAAAAAACgAQAAAApgGnAVsE0AbuCO8IARACEG0QbhB8EQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/41a1fd12d13b.js b/pr/545/docs/search.index/41a1fd12d13b.js deleted file mode 100644 index 63365ac20..000000000 --- a/pr/545/docs/search.index/41a1fd12d13b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUAOzAAAAEAAAcAAwAPEQIAthIBAEgTAgABBADzEhEAAAEAAQAjAAKgYAAAEjhhcvM9EAAAAQC5AQGAAqEQAAATzLCAE8QAAWl1NwQAgYexUBPnAAGACM0AF1CwcBMRAAGhMAAAE9sKQBsjgAKgMAAAEdhudg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/42be563f7543.js b/pr/545/docs/search.index/42be563f7543.js deleted file mode 100644 index a6a0f964d..000000000 --- a/pr/545/docs/search.index/42be563f7543.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9FcQAAABAIMBAQAjgQKgYAAAEnpiaQEAAPRKDwAAAQDqAP8AI4ECsFASjQABZXMTgAKABw4eoAFhcgGJArAgE58AAaAwAAATqWlwAQIA9F8SAAABAI4AAQABAwD0kxIAAAEAkwABAPOFAmJ1AQIA9MEQAAABAGwBAQDzgAJpbLcBAACFoCAAABJnEgEMOjAAAAEAAAAAABYAEAAAAC8HvAe9B74HvwepC90L3gvfC+ALcg8uEKsSrBLlEmMTrBOtE68TuhO7E94T4hM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/42e25feb3567.js b/pr/545/docs/search.index/42e25feb3567.js deleted file mode 100644 index bf0ac5613..000000000 --- a/pr/545/docs/search.index/42e25feb3567.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsHATxAABoAAAAAR3ZmcBAQA7MAAAAQAABwABANULBwABAQGgcAAAEd5hAdEGAAAjgAKhAAAAE8xkbnOAhKBgAAAR3QBBSA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/4341bc8e4878.js b/pr/545/docs/search.index/4341bc8e4878.js deleted file mode 100644 index f1e606bba..000000000 --- a/pr/545/docs/search.index/4341bc8e4878.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9JAPAADTAgEAtADzAAFzOzAAAAEAABkACACFBAIAvgsCAEgPAQAJEAEARhABAC0RAQDcEgcAyBMDACOAArEQE80AAWF0") \ No newline at end of file diff --git a/pr/545/docs/search.index/434a43cc0e07.js b/pr/545/docs/search.index/434a43cc0e07.js deleted file mode 100644 index 769357d3f..000000000 --- a/pr/545/docs/search.index/434a43cc0e07.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAAOzAAAAEAAAYAAgDEEgAAKRMFACOIArBAE5oAAWVzAQQBsDASlgABY/PSEAAAAQABAAEFADswAAABAAAIAAMAQRECAD0SBABbEwAA8wEDY2Vw81UMAAABAAEAAQIA9tAIAABXALEGAQCvAAEA84ACbnI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4351feb790fe.js b/pr/545/docs/search.index/4351feb790fe.js new file mode 100644 index 000000000..683f19891 --- /dev/null +++ b/pr/545/docs/search.index/4351feb790fe.js @@ -0,0 +1 @@ +rn_("AQYA9JEQAAABALgAAQATgQOgAAAAENqxIBQAAAFhZG4BFAD1HhQAAAEAAQABAAEAAQUBsIATwAABdjswAAABAAAHAAIARREEACoTAgAjgAKwcBFrAAFiZFcAAAGGoMAAABL1oKAAABMXoJAAABLhsFAQCgABBeAC9ekGAAABAAEAnAhuBAEGAPNCEgAAAQCoAAEAAaBgAAAPcnIBcAQAANcBAIDFoDAAAAvGAACKCg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/436e158b126a.js b/pr/545/docs/search.index/436e158b126a.js new file mode 100644 index 000000000..fb740fc36 --- /dev/null +++ b/pr/545/docs/search.index/436e158b126a.js @@ -0,0 +1 @@ +rn_("AYACsHASBwABsCAUDAABaW8BAAGw8BQMAAFr9oATAAAFAAEAAQABACUA8wUBZPJHEgAAAQABAgDzWRAAAAEAAQDzAAFpOjAAAAEAAAAAAAcAEAAAADYQXBJEE0UTdRN2E5QTlRMjgwKwsBPrAAFhcwGBAqCgAAASsKBAAAAP+W9284CEAVAB") \ No newline at end of file diff --git a/pr/545/docs/search.index/43ac7a9781b4.js b/pr/545/docs/search.index/43ac7a9781b4.js deleted file mode 100644 index 57328eb16..000000000 --- a/pr/545/docs/search.index/43ac7a9781b4.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOzAAAAEAABEABQB2BQAAxgsAAG4MAABiDw0AvBAAAAGEArAAEMoAAbAAEMwAATQ2FwgAAIigIAAAESKgMAAAEJKg4AAAEuSgMAAAEeawcA86AAGgIAAABX/LwAg7MAAAAQAABwEVAKIBAABtBQAAfwUAAK4IAAC0CAAA0wgCAKULAADhCwEABQwBAHEMAACeDOIAJg8AADcPAQAlEAAA3hAAACwSAQAHEwUAJBMAAKYTAAC8EwUA1xMBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/441e425635ce.js b/pr/545/docs/search.index/441e425635ce.js new file mode 100644 index 000000000..78b84ee21 --- /dev/null +++ b/pr/545/docs/search.index/441e425635ce.js @@ -0,0 +1 @@ +rn_("AYACsRAT+QABsBAMBgABZW8BBQA7MAAAAQAADQABABgRDQABAgDzjA8AAAEAAQABAgD0iA8AAAEAAQABAAEDADswAAABAAAIAAEAORAIAIcHAACHsKATLQABsNATvQABoFAAABOMjBQROzAAAAEAAAYAAwAoBwAAZRADACkSAQDzgAJsdBOAA6AgAAAMfLCgE6UAAWFkbg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/446e084c83a8.js b/pr/545/docs/search.index/446e084c83a8.js deleted file mode 100644 index 802ba1ec7..000000000 --- a/pr/545/docs/search.index/446e084c83a8.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQACoDAAABBpoJAAABLJMGj1RxEAAIoBAQABAAEAE4ACoDAAAA8oZHIjAYSwEAitAx2wIAubAPqgMAAAD00SABj1ZgUAAC0AAQABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/4471155ecc0f.js b/pr/545/docs/search.index/4471155ecc0f.js deleted file mode 100644 index 215ee3492..000000000 --- a/pr/545/docs/search.index/4471155ecc0f.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIBoKAAABKnZPKzBgAAAQABgQKgMAAAE6GgUAAAEzFjcwEEA7AgEJoAAaBQAAARPaBAAAATbWxzdvJoEwAAAQDzAANhZW87MAAAAQAACAADAFwEAQCcCwAAlgwFAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/44bd10e48043.js b/pr/545/docs/search.index/44bd10e48043.js deleted file mode 100644 index 2fae58e54..000000000 --- a/pr/545/docs/search.index/44bd10e48043.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOzAAAAEAAOMAAgClCwAAngziAPMAAW07MAAAAQAA4wACAGwFAACXBeIAAQMAOzAAAAEAAAgAAgACDwYAlhIBAPMAAWM7MAAAAQAAVgAnAHkECwA6BQAAxAgBAL0LAADDCwIAdgwAAIEMAgCTDAEAKA8AAC0PAQAwDwEANg8AAL4PAgDFDwEAyg8BAOoPAABcEAAAYhAAAK0QAQC6EAEAzhABANIQAgArEQEAPhECAEQRAADzEQAA/BEBAAESAQBHEgEAVxIBAFsSAQB7EgEAixIDAJESAQDwEgEAARMAAGwTAACREwQAmhMCAPOAAnJ3AQkA86wTAAABADUAAYACoEAAABKVsCATTgABaGkBDAGgoAAAE/B38uATAAABAAEBAPNSDwAAAQABAPOAAnR1AYECsIATugABoGAAABPeZHM3AwCBhqBAAAATj7BgE2MATAKQDgGIArAAExkAAbAAExsAATQ2M4ADoDAAABDRZG5zYwADoBAAAASbYWVvAX4AAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/44d27e55c058.js b/pr/545/docs/search.index/44d27e55c058.js deleted file mode 100644 index 353ab3963..000000000 --- a/pr/545/docs/search.index/44d27e55c058.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBgBK4ABDuczswAAABAAAFAAEAmBIFACOCAqCQAAATkGlzAQEA9F8SAAABAI4AAQAjgAKwoBNAAAFjbgGEArCgE04AAbCgE1AAAWNyAQIAOzAAAAEAAAYAAQC3DwYAE4ICoCAAABMxZXUBAgDzEhEAAAEAAQABgAKwIBNwAAGgYAAAEsVvdmOBA6AQAAASf2FjcwEDAPRfDAAAAQABAAEAAQEA89MIAAABAAEAAQEA9EwQAAABAJgAAQBTgAOgwAAAE5xucHUBgAKwMA9zAAGhYAAAE9BhZQGBArBAEgQAAbBAEgYAATQ2AQUBoFAAABNZaPL4EQAAAQABBQD0zQ8AAAEAqAABAHOAhLAwEqsAAQGgBAEIAPOnEgAACAAaABOAArBAETcAAWFlAQABoCAAAA/qcgGsEAAAAQAA9P8SAAABAEsAAQCnAACAhaAwAAAQSaAQAAAQaLCgE2QAAQkgIQEJAaBAAAATk2XysxMAAAEAQ4CEoCAAABOhoJAAABL+oTAAABOyEEkAAQIA9JMSAAABAJMAAQATgAKwQBJhAAFpeQEBAqAwAAASOKBAAAASfmdyOzAAAAEAAAcAAgBKEAEA3xAFAAGAArAAExkAAbAAExsAATQ2AQYA9NwTAAABAAoAAQDzAgJydgFFEwAA8wIBZfTWDwAAAQCmAAEA84ACZHTnrT8AEqAwAAAQaaBAAAAMdLDwE9kAAbBwEsYAATBhYmNlZ2hpa2xub3Byc3R1djswAAABAAAFAUUAlAQAAHIFAAB6BQMAggYAAOIGAAAHBwIAFwcAACkHBQAwBwAAkwcAALoHAQC1CAEAuwgBAMgIAAAoCQEALAmFAJkLAQCnCwAAqwsBALYLAADsCwAA+QsAAA0PAQA0DwEATA8AALAPAADaDwEA7A8AAPkPAQA9EAEAQRADAFMQAQCKEAEAqhAAAMcQAgD2EAAADhEAADERAAA1EQEAOxEBAEcRBADlEQAA9BEBAPcRAAADEgAAFBIBAEkSAwBdEgEAahIBAHESAQB3EgEAehIAAH0SAACPEgAApRIBAMMSAADREgQA7BIBAP0SAAD/EgEABRMBABATAABLEwIAUhMEAG4TAQB6EwAAjRMBALUTAQDwEwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/450719784301.js b/pr/545/docs/search.index/450719784301.js new file mode 100644 index 000000000..6b700b79a --- /dev/null +++ b/pr/545/docs/search.index/450719784301.js @@ -0,0 +1 @@ +rn_("AQUAOzAAAAEAAAcAAwA/EQIA5xIBAHsTAgABBADzQhEAAAEAAQAjAAKgYAAAEmlhcvNrEAAAAQC8AQGAAqEQAAAT/7CAE/cAAWl1NwQAgoexUBQaAAGgAAAAEEywcBNEAAGhMAAAFA4KQBsTgAKwEBJ1AAFpcg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/45c7f13213d0.js b/pr/545/docs/search.index/45c7f13213d0.js new file mode 100644 index 000000000..d211fd540 --- /dev/null +++ b/pr/545/docs/search.index/45c7f13213d0.js @@ -0,0 +1 @@ +rn_("AQcAOzAAAAEAAIcAAgBzEAAAfRGGAAEDADswAAABAACGAAEAqg2GAAECADswAAABAAAHAAEA9QsHAPMAA2JpdDswAAABAACHAAIAgQQAALwEhgA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/45cefb4b1fe7.js b/pr/545/docs/search.index/45cefb4b1fe7.js new file mode 100644 index 000000000..337471401 --- /dev/null +++ b/pr/545/docs/search.index/45cefb4b1fe7.js @@ -0,0 +1 @@ +rn_("AQAA9OMSAAABAAEAAQATAAKwgBK3AAFzdvQ7CQAAAQApCgEAE4ACsDAQiAABbG4BgAKgAAAAEBWgAAAAEBY0NvMDAXYBrQwAABMAAqBAAAARBWFz9+gLAACVA14BPQEBAAEApQEBAgD0kBIAAAEAjwABAAEDAPTEEgAAAQCVAAEA8wACYnU6MAAAAQAAAAAAEwAQAAAAHAcdBx4HYQ9iDwcQCBAmECcQuBC5EGURZhGOEo8SmxKcEqsSHhMfE/OAAmR0E4ACoCAAAAy3ZXIBBwGgQAAAE59l8skTAAABAAEAAPUtCQAAAQABAAEAAQAjgAKgoAAAE/VmcEcAAACFsDAPPAABoFAAAA/9sHAQgQABsUAUHAABgSkA8lEFAAABAPOAAmx0lwEAgIaxMBOhAAGxEBPLAAGgsAAAEsYRRQg=") \ No newline at end of file diff --git a/pr/545/docs/search.index/460ae98fed07.js b/pr/545/docs/search.index/460ae98fed07.js deleted file mode 100644 index 870992638..000000000 --- a/pr/545/docs/search.index/460ae98fed07.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYA9PQSAAABAAEAAQABDwD00RMAAAEAAQABAPOHAmhtAQAA9EkSAAABAAEAAQDzBAFk9O8RAAABAAEAAQAjh4SwoBOEAAGwQBJHAAGwcBMyAAEVgAABAAGgQAAAD+plOzAAAAEAAAcAAgApBwUAugcBABOAArBQD6UAAWRyAQkA9RMTAAABAAEAcwABALcCAICGsCAR+gABYGF2m4mdEUkB") \ No newline at end of file diff --git a/pr/545/docs/search.index/46615455c43f.js b/pr/545/docs/search.index/46615455c43f.js new file mode 100644 index 000000000..10648baa7 --- /dev/null +++ b/pr/545/docs/search.index/46615455c43f.js @@ -0,0 +1 @@ +rn_("AQMAOzAAAAEAAAkABAArCQEAHxADAF0QAQBVEwEAAQIBsEAT3QABdDswAAABAAANAAYAahIDANQSAQBBEwEAWBMBANITAQD3EwEAE4ACsDASnQE/aXABiAKwABNMAAGwABNOAAE0NhOBAqAwAAARAWRzAYACoCAAAAwqsGATfgABbngBBQDzGBMAAAEAAQATgAKgMAAAE3FlefMAhBIAA/LFDwAA3ADzgAJydA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/4663a4e119e7.js b/pr/545/docs/search.index/4663a4e119e7.js new file mode 100644 index 000000000..07b00ae8e --- /dev/null +++ b/pr/545/docs/search.index/4663a4e119e7.js @@ -0,0 +1 @@ +rn_("AQUBsEASMgABZfJUEgAAAQABggKgkAAAE5ugkAAAE5wyMwEAAqAgAAASDqAgAAAIx2ltOzAAAAEAAAwABgB+BAAAtQQFADcJAAA+DwEAcRMAAIMTAQDzAAFzAa0QAAABBQD0/BIAAAEAAQABAAEAAPUtDAAAAQABAAEAAQDzgAJna3OAhLCwE1UAARFIAAEFAaBAAAARbmXzsAwAAOQDAQATgAKgMAAAC+ZlcgGAA7BQE5QAAaAQAAALtKBwAAAS7GduckcBAACFoGAAABNyoFAAABPDoKAAABNkFQEEOzAAAAEAABEABADwAQEAORAIADIRAwAvEgIAAYUCsHATfgABsDAS1AABZXMTAAOwQA9dAAGgYAAAEQhiZXM7MAAAAQAAEgAEAIMFAQCcBgoA1g8BACkQAwABAwD08g8AAAEABAABAAEKAaBAAAATxmXy5hMAAAEAE4ACsGASKQABY2nzgAJkcvMAAmVvOzAAAAEAAAkAAgBuBwUAsQcDAAECAbAwENQAAW47MAAAAQAACQABAKoLCQABAAD0LhAAAAEAAQABAAEBADswAAABAADnAAIAoQUAANcH5gBjAAOwEBKSAAFlaXM6MAAAAQAAAAAADgAQAAAA2ggVCRYJFwkYCdAL0Qs2DzcPXA9vD1gQfBD4EvkS44CEsCAHKgABEUAEAQGEsDALvgABoEAAAAx/oIAAABDbsEAMgAABAAAdAf8BAAABBQD1RhMAAAEAAQBzAAEAE4ACoAAAAAbQYWcBAwD0BxIAAAEAZQEBAPOAAmlvAQEAOzAAAAEAAOcAAgBIBwAAwwrmAAEIAbBAE8cAAWX1jxMAAAEAAQABAAEA84ECZ3QBAQGgcAAAEXRpOzAAAAEAAPkAAgBHBwAAygn4AAEFAPNIEAAAAQABAPOAAmFvE4ACoEAAAAvlcnUBgAKgAAAAByygEAAACNlkeBMAArAgDKcAAWVy8qAPAAABABOAArCwFAwAAXJ4AQoA9AMTAAABAAEAAQATgAKwEBCPAiphZQEEAPQpEAAAAQABAAEAAQQAOjAAAAEAAAAAAAcAEAAAAKQSpRKzErQSNhM3E0kTShMBAwDzQhIAAAEAqADTgISwQBCBAAEBSAHHvwMAj6CAAAASRLBgDJYAAbBADA8AAbEwE+MAAT+pHzswAAABAABLACIAcAAAAHUAAACfBAEAqgQAAF0FAQASBwEAIgcAACYHAQAOCQAAIgkHADkJAQC9CwAA0wsBANoLAQDrCwcADwwBACsMAQB2DAEAaw8BANsPAQBUEAEAXxABAHcQAACYEAIAqBABALoQBADfEAAALBEDAGkRAQAfEgAAfhIBAIISAQCvEgAACBQBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/46d02c2cf6f3.js b/pr/545/docs/search.index/46d02c2cf6f3.js new file mode 100644 index 000000000..a4bf8ae1c --- /dev/null +++ b/pr/545/docs/search.index/46d02c2cf6f3.js @@ -0,0 +1 @@ +rn_("AQIA9ScRAAABAAEAAQABAAGAArBgEoIAAaAgAAAQfG95AQABoMAAABOgafTYEgAACAAbABsAAQYA9AQUAAABAAEAAQABAgD0ehAAAAEAmgABAAECAaBAAAASr3I7MAAAAQAABwACAHgQAQAPEQUA84ACYW9nAwAAhrCAEq4AWbCgEyQAAQwwBjswAAABAAAIAAMA0gsAADoRAwAbEgMA84ACZWk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/470732838eeb.js b/pr/545/docs/search.index/470732838eeb.js new file mode 100644 index 000000000..95e7818d5 --- /dev/null +++ b/pr/545/docs/search.index/470732838eeb.js @@ -0,0 +1 @@ +rn_("AQkA898TAAABADUAAQ0BoKAAABQjd/ITFAAAAQABgQKwgBPtAAGgYAAAFBFkczcBAIWFoEAAABPCsGATlgBMApAK") \ No newline at end of file diff --git a/pr/545/docs/search.index/474b31e6c524.js b/pr/545/docs/search.index/474b31e6c524.js new file mode 100644 index 000000000..5f815b2ce --- /dev/null +++ b/pr/545/docs/search.index/474b31e6c524.js @@ -0,0 +1 @@ +rn_("AQwA8yoTAAABAAEAAQYA8+4QAAABAAEAAYICsGASsQABsNATyQABaXITgAKwEAyTAAFlaRcDAIOIsTAT5gABoGAAABDtoFAAABCAsJAShAABsEAQfQABtBAH8wABYfQMCQAAAQC1BwEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/47aa62fcbff4.js b/pr/545/docs/search.index/47aa62fcbff4.js deleted file mode 100644 index be6286c29..000000000 --- a/pr/545/docs/search.index/47aa62fcbff4.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYQCsCAQ0AEUoJAAABNbbXABgAKgMAAAEF2gUAAAEwFjcpcAAACFsCASzwABsMATigABoGAAABElEEAOOzAAAAEAABIABgCdBAgAIxEBADYSAQAeEwEAchMBAOMTAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/47b9d9b13323.js b/pr/545/docs/search.index/47b9d9b13323.js deleted file mode 100644 index 86b08d34e..000000000 --- a/pr/545/docs/search.index/47b9d9b13323.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQACoCAAABLIsDARLwABaXTyMhIAAAEAAQMAOzAAAAEAAAYAAQCwEAYAAQgA9C8TAAABAIIABQATAQOwkBORAAGwUBJ5AVdnbHA7MAAAAQAAEgAJAMEPAgAyEQEAaBIBAIkSAQC/EgEAIBMBAFcTAQBmEwEAoxMBAAGAArAwESsAAbAwES0AAXJ2AQQBsAAR9AABZDswAAABAAAFAAIAJxEDACESAQC3BQABh7BQEfYBDLBgEncAAZQJAzowAAABAAAAAAALABAAAABlDGYMZwwNDg4OWRDaENsQ3BDdEG8SqBIjgAKgEAAADGRubwEDAPO+DwAAAQABACOAAqAAAAALp2RyYwGEoFAAABDXoDAAAA/3FAEQ8lcHAAABABOAArBgEhYAAWNnE4ADoLAAABNNoEAAAA4MZW9z") \ No newline at end of file diff --git a/pr/545/docs/search.index/4805b324248d.js b/pr/545/docs/search.index/4805b324248d.js new file mode 100644 index 000000000..50ce1fac8 --- /dev/null +++ b/pr/545/docs/search.index/4805b324248d.js @@ -0,0 +1 @@ +rn_("AQEA9RkJAAABAAEAAQABAPMAAWnzmAwAAHQHAQABAQGgQAAAE4ll8vkTAAABAAEEAqAgAAARUqAwAAASF2JoAVMPAADnAACAxaAQAAAMmaAwAAAQAAQQKAE=") \ No newline at end of file diff --git a/pr/545/docs/search.index/480a31b05a4c.js b/pr/545/docs/search.index/480a31b05a4c.js deleted file mode 100644 index cd9709952..000000000 --- a/pr/545/docs/search.index/480a31b05a4c.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOzAAAAEAABYACQCxDwUAtxABAEERAgANEgEAPRIEADQTAQBbEwAAhhMAAKUTAAAjgAOh8AAAE/Cw8BPjAAFjZmcjgAKwUBLyAAFtbgEFAPM0EwAAAQBwAPMEAWMB1xAAAAEBAbBwE4oAAXA7MAAAAQAACQACAJQHBwAhEAEAAQIAOzAAAAEAAAsAAgAHEwUAvBMFAPMBAW07MAAAAQAADQAEAFoMAAC5EAAAJRIFAHwTBQATAAKgMAAADF5lc/JFEQAAAQABggKwcBNqAAGgQAAAEGVpc/cBAICGsJATTgABkEkI") \ No newline at end of file diff --git a/pr/545/docs/search.index/483ec6c64d5e.js b/pr/545/docs/search.index/483ec6c64d5e.js deleted file mode 100644 index d4d18fd7d..000000000 --- a/pr/545/docs/search.index/483ec6c64d5e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYECoBAAABJ/oHAAABLFYWMBhwKwABMZAAGwABMbAAE0NlMAhKCQAAASp7CwE0AAAYEACfXiBgAANQDVCAoBGAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4a9458af2428.js b/pr/545/docs/search.index/4a9458af2428.js deleted file mode 100644 index fb845d8eb..000000000 --- a/pr/545/docs/search.index/4a9458af2428.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBsAASYwABczswAAABAAALAAIA3BIHAMgTAwBHAAAEhqCAAAASvrEAE9UAAbBAEh8AAbCAE+MAAbBQEmUAARUAFvQIDgAAAQABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/4aa7b4743afe.js b/pr/545/docs/search.index/4aa7b4743afe.js new file mode 100644 index 000000000..9f79cee80 --- /dev/null +++ b/pr/545/docs/search.index/4aa7b4743afe.js @@ -0,0 +1 @@ +rn_("AQQA9t8TAAABAA0AAQAjAAQAAQMA8y8SAAABAAEAI4ECsSAUFgABY2sTgAKgMAAAE59uclMAA6BAAAAL1WVvcvSjEAAAdAGyAQEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/4c05ce7be64f.js b/pr/545/docs/search.index/4c05ce7be64f.js new file mode 100644 index 000000000..9b545b5fc --- /dev/null +++ b/pr/545/docs/search.index/4c05ce7be64f.js @@ -0,0 +1 @@ +rn_("AQoA9AwTAAABAA8AAQABgwKgIAAAD9GgMAAAEGRpdAEAAPR6EgAAAQABAAEA8wQBZPQgEgAAAQABAAEAI4aEsKATtwABsEASeAABsHATZQABFYAAAQACsDAPwwABsBATJAABc3TycQUAAF4GAYACsMAT4wABoAAAAAcidHnzgIURwQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4c05e858ff5d.js b/pr/545/docs/search.index/4c05e858ff5d.js deleted file mode 100644 index cf09ad19e..000000000 --- a/pr/545/docs/search.index/4c05e858ff5d.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACoIAAABITsHATYQABYXMBAAGggAAAE99m8rAIAAAeCgEHAPWeEgAAAQABAAEAAQAjgAKgUAAAEK9hb/MAAmZzOzAAAAEAAAgABAAKBwAAPQcFAIoMAADnEAAA84ACZHk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4c2110675ed8.js b/pr/545/docs/search.index/4c2110675ed8.js deleted file mode 100644 index 4fad1e4ff..000000000 --- a/pr/545/docs/search.index/4c2110675ed8.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBsDASlgABY/PSEAAAAQABAAEDAYASuAAQ7nM7MAAAAQAABQABAJgSBQAjggKgkAAAE5BpcwcBAIDFsFASYQABoKAAABL+sHASxgABoNAAABOcgAEYCPOAAmRy") \ No newline at end of file diff --git a/pr/545/docs/search.index/4c8621a28a73.js b/pr/545/docs/search.index/4c8621a28a73.js deleted file mode 100644 index f06eadddd..000000000 --- a/pr/545/docs/search.index/4c8621a28a73.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEA9YwQAAABAAEAAQABACOBArCQEzoAAWF0Q4ADsRATswABoIAAABL9Y290EwACsAATigABbnL29gEAAAEAYwIBAJgC1Qs=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4c89ae5762cb.js b/pr/545/docs/search.index/4c89ae5762cb.js new file mode 100644 index 000000000..f5adf7143 --- /dev/null +++ b/pr/545/docs/search.index/4c89ae5762cb.js @@ -0,0 +1 @@ +rn_("AQIAOzAAAAEAABEABQCGBQAA5QsAAJIMAACPDw0A7BAAAAGEArAAEPoAAbAAEPwAATQ2FwgAAIigIAAAEVKgMAAAEMCg4AAAExagMAAAEhewcA9nAAGgIAAABZDLwAg7MAAAAQAACwEVAKkBAAB9BQAAkAUAAMcIAADNCAAA6ggCAMULAAABDAEAKAwBAJUMAADDDOYAUw8AAGQPAQBTEAAADhEAAF0SAQA6EwUAVxMAANkTAADvEwUAChQBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/4cd916711a76.js b/pr/545/docs/search.index/4cd916711a76.js deleted file mode 100644 index b17301b3b..000000000 --- a/pr/545/docs/search.index/4cd916711a76.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEBoGAAABPDc/IgEQAAAQABCAD1dBMAAAEAAQABAAEAowCEsCAJKAABoIAAABIrMEAIOzAAAAEAAAUAAgDdAQAA7Q8EAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/4cdc76f01005.js b/pr/545/docs/search.index/4cdc76f01005.js deleted file mode 100644 index be9328b6e..000000000 --- a/pr/545/docs/search.index/4cdc76f01005.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9fcQAAABAAEAAQABAAGAArBgElEAAaAgAAAQTm95AQABoMAAABNtafSnEgAACAAaABsAAQYA9NETAAABAAEAAQABAgD0TBAAAAEAmAABAAECAaBAAAASfnI7MAAAAQAABwACAEoQAQDfEAUA84ACYW9nAwAAhrCAEn0AWLCgEvIAAQwwBjswAAABAAAIAAMAsgsAAAoRAwDqEQMA84ACZWk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4d88a08a2ae4.js b/pr/545/docs/search.index/4d88a08a2ae4.js new file mode 100644 index 000000000..1f3be335a --- /dev/null +++ b/pr/545/docs/search.index/4d88a08a2ae4.js @@ -0,0 +1 @@ +rn_("AQQA80IRAAABAAEAAYICsEASNQABsEASNwABNDYBCwDzLxMAAGgAAQABBgD0DxQAAAEACgABAPMCAXIBeBMAAPMCAWX0AxAAAAEApwABABOAAqBQAAASaWR08wCEEQEB92sQAAABAG4AHQABAAEALwE=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4dd85b55e38e.js b/pr/545/docs/search.index/4dd85b55e38e.js deleted file mode 100644 index 88fa995fe..000000000 --- a/pr/545/docs/search.index/4dd85b55e38e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsRATxgABsBAL5gABZW8BBQA7MAAAAQAADQABAOgQDQABAgDzXw8AAAEAAQABAgD0Ww8AAAEAAQABAAEDADswAAABAAAIAAEACxAIAIcHAACHsKAS+wABsNATigABoFAAABNZjBQROzAAAAEAAAYAAwATBwAANxADAPgRAQDzgAJsdBOAA6AgAAAMWLCgE3IAAWFkbg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/4e07dd0ff701.js b/pr/545/docs/search.index/4e07dd0ff701.js deleted file mode 100644 index f317d3b7b..000000000 --- a/pr/545/docs/search.index/4e07dd0ff701.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEA9QIJAAABAAEAAQABAPMAAWnzdAwAAGUHAQABAQGgQAAAE1Zl8sYTAAABAAEEAqAgAAARIqAwAAAR5mJoASYPAADnAACAxaAQAAAMdaAwAAAP0wQQKAE=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4e0fe03427ba.js b/pr/545/docs/search.index/4e0fe03427ba.js new file mode 100644 index 000000000..bc31630d9 --- /dev/null +++ b/pr/545/docs/search.index/4e0fe03427ba.js @@ -0,0 +1 @@ +rn_("AQAA9OMSAAABAAEAAQATAgKwgBK3AAFzdvQ7CQAAAQApCgEA8wABYwEYDAAAAQICoLAAABO5oLAAABO6Y3PzTRAAAAEAXAABgQKwUBFnAAGgwAAAE4xoafOCAmVp84ACZW8=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4e6750278d1b.js b/pr/545/docs/search.index/4e6750278d1b.js deleted file mode 100644 index 793f90f7a..000000000 --- a/pr/545/docs/search.index/4e6750278d1b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEAOzAAAAEAAAcAAQALCQcAAQIA96QPAADQAJ8CAQABAHMAAQATgAKwMBA2AKNpdPMAAXPyuBMAAAEAM4ADsRATMgABZG5w") \ No newline at end of file diff --git a/pr/545/docs/search.index/4eac59928f18.js b/pr/545/docs/search.index/4eac59928f18.js new file mode 100644 index 000000000..bc6c14aed --- /dev/null +++ b/pr/545/docs/search.index/4eac59928f18.js @@ -0,0 +1 @@ +rn_("AQMBgBLpABDwczswAAABAAAFAAEAyRIFACOCAqCQAAATw2lzBwEAhMWwUBKSAAGgoAAAEzGwcBL4AAGg0AAAE8+AARgI") \ No newline at end of file diff --git a/pr/545/docs/search.index/4eed4a0cfe1e.js b/pr/545/docs/search.index/4eed4a0cfe1e.js new file mode 100644 index 000000000..1d0c38cc8 --- /dev/null +++ b/pr/545/docs/search.index/4eed4a0cfe1e.js @@ -0,0 +1 @@ +rn_("AYACsHAQ8wABsCATvQABYWQBBQD0sxIAAAEAlQABAPMAAWMBHxIAAEOAA7AwEwgAAbCgE6MAAWFzeQEGAPSREAAAAQC4AAEAk4CEoAAAABDasSAUAAABCSAB84ACZWk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/4fae9a79a161.js b/pr/545/docs/search.index/4fae9a79a161.js new file mode 100644 index 000000000..b16d153ce --- /dev/null +++ b/pr/545/docs/search.index/4fae9a79a161.js @@ -0,0 +1 @@ +rn_("AQUA9GsTAAABAEkAAQDzAwFj8nMSAAABACOAArBwFBYAAWhvAYICsAASUAABsAARXwABZXNDAAOgoAAAE7qgIAAAEvplaXT1YxIAAAEAhQABAPAAAYACsHASRwABoLAAABOAZW8BAgA7MAAAAQAABgABAOAQBgABAgGgQAAAE59l8skTAAABAPOAAmlvAQgA9GITAAABAIIABQATAQOwkBPEAAGwUBKqAVlnbHA7MAAAAQAAEgAJAO4PAgBiEQEAmRIBALoSAQDxEgEAUxMBAIoTAQCZEwEA1hMBAAGAArBAEicBDqAgAAAQo2FpAYECsDATcwABsDASRQABY2kBAwGwABKUAAFzOzAAAAEAAA0AAwBdEQEADhMHAPsTAwABAwD1WxEAAAEAHAEBAFYB84ACcnYBAAA7MAAAAQAABQACACUSAQB6EgMA8wIBZDswAAABAAAJAAMAVxEDACASAwBSEgEAI4ACoJAAABO5aW8TgAKw8BQIAAFsbwEFAPTVEwAADAAeAA8AI4ACoGAAABLvZ3MjgAKwkBO3AAFibPcXAwCPsHARdQABsGAT6wABsHATZQABsGASqAABsFASlgABtfkXOzAAAAEAADwAGACPBQAAPAcBAMAIBQDQCAAA/ggAAMgLAAARDAEAiQwCALMMAQAyDgMANw4BAIIPBABNEAEAhxAAAKoQAADKEAkACBEAAAoRAwBVEQAAoBIAALcSAQDJEgUA2RIAAI0TAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/505a1a911bef.js b/pr/545/docs/search.index/505a1a911bef.js deleted file mode 100644 index 375f70524..000000000 --- a/pr/545/docs/search.index/505a1a911bef.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOzAAAAEAAAUAAgAPDAMAVRIBAAECAPPHEAAAAQABAAEGAPTREwAAAQABAAEA8wYBbfTqEQAAAQABAAEA84ACbnbzgAJhaQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/50abe47e037f.js b/pr/545/docs/search.index/50abe47e037f.js new file mode 100644 index 000000000..29ecb46be --- /dev/null +++ b/pr/545/docs/search.index/50abe47e037f.js @@ -0,0 +1 @@ +rn_("AQEAOjAAAAEAAAAAAAgAEAAAANgI/A+dEJ4QnxBiE2MT5RPqEwEBAqBAAAATz6AwAAAQo2Vo9dAIAAAuABMDAQBDBQECAPRMEQAAAQABAAEAE4ECsCARUAABYXPzgAJubwECAPQyEAAAAQABAAEAEwACoNAAABPUY3Pypw8AAAEA84ADZWlv") \ No newline at end of file diff --git a/pr/545/docs/search.index/517322c0ea00.js b/pr/545/docs/search.index/517322c0ea00.js deleted file mode 100644 index b9d89162e..000000000 --- a/pr/545/docs/search.index/517322c0ea00.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9LISAAABAAEAAQABBADzHA8AAAEAAQABgAKgUAAAECWgYAAAEJNpcgGAAqAgAAAMBKBgAAAQkmVoAQEBoCAAABCRYvMADAAAAQABABOBAqAQAAAMA2FjAQYA9E0SAAABAIcBAQATAAKwYBJPAAFmbfJoDAAAAQAjgAKgwAAAExhucicPAACIoEAAAA8ZsEAPGgABoDAAAAv/NCAXOzAAAAEAABkAAwDzAQAAPQQOAIoLCQABgAOwcBLPAAGwMBJ7AAGwgBMFAAFjcnMBAAGwIBLPAAFvOjAAAAEAAAAAAAkAEAAAACMRJBE2EjcSHhMfE3ITcxPjE+QTAYACsCAI2QABsDAShgABcnT3BAAAyKAgAAAHMaBgAAAPRbCAEoYAAUAGkgn2/wEAAGICwwQBAA0KAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/521c1cdfffb6.js b/pr/545/docs/search.index/521c1cdfffb6.js new file mode 100644 index 000000000..e6a406d0a --- /dev/null +++ b/pr/545/docs/search.index/521c1cdfffb6.js @@ -0,0 +1 @@ +rn_("AYACsAAQ+gABsAAQ/AABNDYBBAGgoAAAFCN38hMUAAABAAELAPSFEwAAAQABAAEAI4ACoIAAABOtZW9jAgOgYAAAE0NlbnAB2QsAAPMAAmF2AbQGAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/52548d68890f.js b/pr/545/docs/search.index/52548d68890f.js deleted file mode 100644 index 978bfb84a..000000000 --- a/pr/545/docs/search.index/52548d68890f.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9ZsPAAABAAEARQIBAAEEAaAAAAAQLnP1hAwAAAEAAQATAwEAAQIA9fcQAAABAAEAAQABAAGAArBgElEAAaAgAAAQTm95AQABoMAAABNtafSnEgAACAAaABsAAQYA9NETAAABAAEAAQABAgD0TBAAAAEAmAABAAECAaBAAAASfnI7MAAAAQAABwACAEoQAQDfEAUA84ACYW9nAwAAhrCAEn0AWLCgEvIAAQwwBjswAAABAAAIAAMAsgsAAAoRAwDqEQMA84ICZWlHAQAAhbBwEv8AAaCAAAAT36BAAAAPULBABPSwCAAAigYBAJMDAYECoCAAABBIsFAR+gABYW8BBAGgAAAAExhzAUcQAABjBAOwUBC3AAFjZXP2uAgAAAEAAQAuAAEA9wgBAAA7MAAAAQAAJAAIAP8GBwCbDwIA6BANAA8RAgDiEQEAZRIBALYSAQBIEwIAAQEA9JkLAAABAKEFAQATAAOwMBOEAAGwUBJZAAFlcHL0PA8AAAEA5gABAAEAA7BAE1AAAaFAAAATt6BQAAARMWJjZgHJBgAA44CEsUAT3AABAjAQAQGEoLAAABMNsEAQCQABsMATPAABoGAAABDeFCAE9rAGAAD3CAEALgEgAQwBAQMAOzAAAAEAAAUAAQAYEgUAAQABoKAAABN5cvRGDwAAAQDsAAEA84ECZ3MBBwD1nhIAAAEAAQABAAEAAYACoEAAABCvsFAQmAABY2nzgAJhbwEAAaAgAAAQz3LzxwsAAEwDXwFDgISgAAAAE1agMAAAE1aABT0AHJoIICEBAwKwQBJbAAGgMAAAErFld/LhDwAAtgATgwKgcAAAEulnbwECAPU7EgAAAQDqAHkAAQATgAKwMBJsAT1pcAEGAPPmEgAAAQABAPMFAmJzAZgPAAABAgD0dQ8AAAEAAQABACOAAqBgAAAR3mJj978AAIygkAAAEd87yRo6MAAAAQAAAAAAFwAQAAAA9QECAgMCVQRWBFcE0QYKBz0HPgc/B0AHQQdCB5QLBAyKDJMPpQ+mD2gQ5xDGE8cT") \ No newline at end of file diff --git a/pr/545/docs/search.index/52b7dbce0a40.js b/pr/545/docs/search.index/52b7dbce0a40.js new file mode 100644 index 000000000..934c019b8 --- /dev/null +++ b/pr/545/docs/search.index/52b7dbce0a40.js @@ -0,0 +1 @@ +rn_("AQYA9CYTAAABAAEAAQABDwD0BBQAAAEAAQABAPOHAmhtAQAA9HoSAAABAAEAAQDzBAFk9CASAAABAAEAAQAjh4SwoBO3AAGwQBJ4AAGwcBNlAAEVgAABAAGgQAAAEBdlOzAAAAEAAAcAAgA+BwUAzwcBABOAArBQD9IAAWRyAQkA9UYTAAABAAEAcwABALcCAICGsCASKwABTqxZko8YEUkB") \ No newline at end of file diff --git a/pr/545/docs/search.index/536f57712388.js b/pr/545/docs/search.index/536f57712388.js new file mode 100644 index 000000000..e2510eeb0 --- /dev/null +++ b/pr/545/docs/search.index/536f57712388.js @@ -0,0 +1 @@ +rn_("AQIA9ScRAAABAAEAAQABAAGAArBgEoIAAaAgAAAQfG95AQABoMAAABOgafTYEgAACAAbABsAAQYA9AQUAAABAAEAAQABAgD0ehAAAAEAmgABAAECAaBAAAASr3I7MAAAAQAABwACAHgQAQAPEQUA84ACYW9nAwAAhrCAEq4AWbCgEyQAAQwwBjswAAABAAAIAAMA0gsAADoRAwAbEgMA84ICZWkjAAKggAAAFBJmaPLJCAAANwoBAQD0uQsAAAEAsQUBABMAA7AwE7cAAbBQEooAAWVwcvRpDwAAAQDnAAEAAQADsEATgwABoUAAABPqoFAAABFhYmNmAd4GAADzgAJtbgEBhKCwAAATQLBAEDcAAbDAE28AAaBgAAARDhQgBPbFBgAADwkBADEBIQEOAQEFADswAAABAAAFAAEASRIFAAEHAPXPEgAAAQABAAEAAQAjgAKgUAAAEN9hb/MAhSBJAjswAAABAAAIAAQAHwcAAFIHBQCvDAAAFxEAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/538b5fc4e1ed.js b/pr/545/docs/search.index/538b5fc4e1ed.js new file mode 100644 index 000000000..5ba20b562 --- /dev/null +++ b/pr/545/docs/search.index/538b5fc4e1ed.js @@ -0,0 +1 @@ +rn_("AQIA9CwRAAABAAEAAQABAQDzQhEAAAEAAQATgAIlFD3SUo9lcwEKAPMqEwAAAQABAAGAArAgE6MAAaBgAAAS9292AYACoDAAABI0oAAAABKwY2TzgIUFEAY=") \ No newline at end of file diff --git a/pr/545/docs/search.index/5392889fe77e.js b/pr/545/docs/search.index/5392889fe77e.js new file mode 100644 index 000000000..b851be4e1 --- /dev/null +++ b/pr/545/docs/search.index/5392889fe77e.js @@ -0,0 +1 @@ +rn_("AYICsEASNQABsEASNwABNDYBCwDzLxMAAGgAAQABBgD0DxQAAAEACgABAPMCAXIBeBMAAPMDAWX0AxAAAAEApwABAPOAA2FlaQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/53fb9a760872.js b/pr/545/docs/search.index/53fb9a760872.js deleted file mode 100644 index eb46082a0..000000000 --- a/pr/545/docs/search.index/53fb9a760872.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9SsRAAABABsBAQBUAQEBAPdvEAAAAQABAL4CAQCCAAUAAQIA9AQQAAABAAEAAQATgAKg0AAAE6Fjc/OAAmVvI4ACsAAHDwABbHTzAAJhcvILDwAAAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/53ffa8e8252a.js b/pr/545/docs/search.index/53ffa8e8252a.js new file mode 100644 index 000000000..12a588128 --- /dev/null +++ b/pr/545/docs/search.index/53ffa8e8252a.js @@ -0,0 +1 @@ +rn_("AQAA9M4IAAABAHQK4AAnAAAAyqEQAAAT26BAAAAQkLBgE8sAAaAQAAAMNrBQE2kAAbAwEPMAAaAAAAAL9LEgE+sAAbBAEI4CE0BOsAk6MAAAAQAAAAAAEwAQAAAA5AjlCPgI+QjAC8ELwgvKC80LhwwQEjsSPBI9EvMS9BIIEwkTeRN6Ew==") \ No newline at end of file diff --git a/pr/545/docs/search.index/5478b18519c4.js b/pr/545/docs/search.index/5478b18519c4.js new file mode 100644 index 000000000..b22d92500 --- /dev/null +++ b/pr/545/docs/search.index/5478b18519c4.js @@ -0,0 +1 @@ +rn_("AQIAOjAAAAEAAAAAAA4AEAAAALgMuQyQEG4RbxFwESQSLRIuEjISMxKIEokSvhK/EgEJAPP3EAAAAQABAAEKAPM7EgAAAQABAAEGAPW6EAAAAQABAAEAAQDzgAJkbnMAhLEgE6MAAQARA/KSEgAAAQABDQD2ChMAAAEAowBUABYAAQABgAKwoBMiAAGgEAAAC+ljdQEBAPQyEwAAAQBLAAEA8wABZfI/CQAAAQD3AACAxbAwEDcAAQACqAg=") \ No newline at end of file diff --git a/pr/545/docs/search.index/548eac6e4034.js b/pr/545/docs/search.index/548eac6e4034.js new file mode 100644 index 000000000..611bccd33 --- /dev/null +++ b/pr/545/docs/search.index/548eac6e4034.js @@ -0,0 +1 @@ +rn_("AQ0A9UYTAAABAAEAcwABAAEHAPMvEwAAaAABACOAAqEQAAATgG5yAQcA9DIRAAABAAEAAQAzAASgIAAACPew4BN1AAExZWlyOjAAAAEAAAAAAAkAEAAAAEAEQQQgB9kIHwwgDCEMIgzUENUQAQIA9IUQAAABAIYBAQABAwD08RAAAAEAbQEBAPMAAmJ1AZ8PAAABAwD0gxAAAAEAhgEBAPOEAmRzAQIA89sIAAABAFgA84ACaXQBGADzIBQAAAEAAQAjgQKwwBNEAAFjbQENAbBAE8cAAWX1jxMAAAEAAQABAAEAE4ICsAAQmwABa3MBBAD0LhAAAAEAAQABAAGBAqAgAAAQlrBAEtwAAWVp84ICZXQBBAGgYAAAEjRy9NcLAAABAMUDAQDzgANhZW8BCQD2XRIAAAEA+QCCADEAAQATgAKwYBBGAAFkbgEGAPVvEAAAAQABAAEAgwIBAwGgcAAAEphn9C0HAAABAAQCAQABCQDz3xMAAAEANQABgQKwgBPtAAGgYAAAFBFkcxcBAIiFsNAUEwABoEAAABPCsGATlgBMApAKAQQA9DITAAABAEsAAQBTgAOwkBQMAAFlaG8BAAGgQAAAEP5lAU8PAAAjgQKwUBCoAAFrdHf8AQCNoZAAABQDsLASpgABoKAAABJc/YEPOzAAAAEAACEACAB6AAAAgAADAE0FAQAJBwcAAgkHAPULBwDYDwEACRIAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/549a18f8219c.js b/pr/545/docs/search.index/549a18f8219c.js new file mode 100644 index 000000000..cef0ef2de --- /dev/null +++ b/pr/545/docs/search.index/549a18f8219c.js @@ -0,0 +1 @@ +rn_("AQIBsIATUQABdAHjCAAAAYECoBAAABKwoHAAABL3YWPzAQFy8iYRAAAYAPOAAmVpI4ACsAALywABZHLzAAFl9IgAAAATDAgHAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/5535b627edd5.js b/pr/545/docs/search.index/5535b627edd5.js new file mode 100644 index 000000000..ee1fe0d0e --- /dev/null +++ b/pr/545/docs/search.index/5535b627edd5.js @@ -0,0 +1 @@ +rn_("AQYA9AoRAAABAAEAAQABAgA7MAAAAQAADAAFAMMLAQAPEAUAQBIBAJ4SAQC6EwAA84ACZm4BAQA7MAAAAQAACAACAC8PBgDHEgEA84ACZG4BAQDzAQcAAAEAAQABhgKgAAAAEsCgAAAAEsFkcvMBAXYB7BIAAEMAA7CAElQAAbCwE+gAAWtscjswAAABAAAMAAMA+AYIALEMAQDNDwEAAQIA9coHAAABAAEAAQABAPMAhBRBAAF2AAAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/55c5b7004628.js b/pr/545/docs/search.index/55c5b7004628.js deleted file mode 100644 index 391b470ce..000000000 --- a/pr/545/docs/search.index/55c5b7004628.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACoAAAAA/ooAAAAA/pNDYBgAOwABMZAAGwABMbAAGwcBONAAE0NmEBBAD03BMAAAEACgABACOBAqBAAAAQqm1wAQEAOzAAAAEAAAgAAwATEgAAhBIAAOkTBgDHAQACxaBAAAAPsKCAAAAR7kAGgAg7MAAAAQAAFgAIAE4PAQBjEAEAphADABURBgD4EgIARRMAAJ0TAQDNEwEA8wACZXY6MAAAAQAAAAAAEQAQAAAA/QH+AXgFiAwPDxAPKQ9DD9YP1w99EH4QBBIFEgYSBxJkE2UTAYECsHAQpgABsHAQqAABNDYjgAKwEAceAAFucAEDArBAElsAAaAwAAASsWV39NwPAAAFALUAAQATgQKgcAAAEulnbwEEADswAAABAAAGAAIAnAsAAJYMBQBjgAOwUA9OAAFkc3RXAQAAhaAQAAAPsLEgE50AAREhATswAAABAAAKAAMAcwAAAIwABQAcEQMA") \ No newline at end of file diff --git a/pr/545/docs/search.index/560e166f7c46.js b/pr/545/docs/search.index/560e166f7c46.js deleted file mode 100644 index d1f1a9e24..000000000 --- a/pr/545/docs/search.index/560e166f7c46.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUAOzAAAAEAAAcAAwAPEQIAthIBAEgTAgABBwD22BIAAAEAogBUABYAAQABBADzEhEAAAEAAQAjAAKgYAAAEjhhcvM9EAAAAQC5AQGAAqEQAAATzLCAE8QAAWl1dwgAAIixUBPnAAGACM0AF1CwcBMRAAGhMAAAE9sKQRvyEwkAAOUGAYECoFAAABBhoKAAABKIa3ABAwA7MAAAAQAA9AACAGoMAQAPDvIA84ACbHTzgAJhZQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/5710b3f34500.js b/pr/545/docs/search.index/5710b3f34500.js deleted file mode 100644 index 46f492fdc..000000000 --- a/pr/545/docs/search.index/5710b3f34500.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQsBoEAAABNsZfKWEwAAAQABBQD0SBEAAAEAAQABAAGDArAAED0AAbBQErYAAWR3E4ACoKAAABMlZXYBAgD0VxAAAAEAgwEBAAEAAPRKDwAAAQDqAP8AI4ICsFASjQABZXMBAgD0XxIAAAEAjgABAAEDAPSTEgAAAQCTAAEA84UCYnUBAgD0wRAAAAEAbAEBAPOAAmls8wADYnR1OjAAAAEAAAAAAA8AEAAAAC8HvAe9B74HvwdyDy4Q5RJjE6wTrROvE7oTuxPeE+ITAQwA80gTAAABAAEAAYACsAAI0QABoCAAAAyJZG4BBgD0XRIAAAEAjgABAPMDAWL0VRAAAAEAgwEBAJcGAACHsEAPSAABoHAAABHlsJASiwABOAkDOzAAAAEAACIAEQCLBQMA8QYBAH4MAgCEDAIAQA8BAJQPAQCZDwEAtw8GAPsPAAAoEAEAxRIAAOkSAAANEwAAohMAAK4TAADMEwAA2xMAAAEDAPRxEgAAAQBDAQEA84ACY213AQCAxbGAE+sAAUCBBAg=") \ No newline at end of file diff --git a/pr/545/docs/search.index/571482a0f60a.js b/pr/545/docs/search.index/571482a0f60a.js new file mode 100644 index 000000000..fa4510055 --- /dev/null +++ b/pr/545/docs/search.index/571482a0f60a.js @@ -0,0 +1 @@ +rn_("AQcA9PwSAAABAAEAAQDzBQF0OzAAAAEAAAgAAgC9CwAA6wsHAAEFAPMYEwAAAQABADcAAICFsDAP0gABoKAAABM0oDAAABNxEEFI") \ No newline at end of file diff --git a/pr/545/docs/search.index/5717d266c26b.js b/pr/545/docs/search.index/5717d266c26b.js deleted file mode 100644 index a6ef7185f..000000000 --- a/pr/545/docs/search.index/5717d266c26b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYA9NoQAAABAAEAAQABAgA7MAAAAQAADAAFAKMLAQDiDwUADxIBAG0SAQCHEwAA84ACZm4BAQA7MAAAAQAACAACAAIPBgCWEgEA84ACZG4BAQDz7AYAAAEAAQABhgKgAAAAEo+gAAAAEpBkcvMBAXYBuxIAAEMAA7CAEiMAAbCwE7UAAWtscjswAAABAAAMAAMA4wYIAIwMAQCgDwEAAQIA9bUHAAABAAEAAQABAPMAhBRBAAF1AAAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/5724a5cd21a6.js b/pr/545/docs/search.index/5724a5cd21a6.js deleted file mode 100644 index 9b2a50eea..000000000 --- a/pr/545/docs/search.index/5724a5cd21a6.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9AgSAAABAKQAAQABCAD0wRIAAAEAhAABADMBA7BAEpEAAWFiZfV6DAAAAQAWA1ACzwABAAD1wQsAAAEAVAMBAAEA84ACc3UjgQKwgBK8AAFydAEGAPTaDwAAAQCvAAEAUwCEsIASRAABoKAAABPwAgEU9UUFAAABAEkOUQABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/579677a41519.js b/pr/545/docs/search.index/579677a41519.js new file mode 100644 index 000000000..e7b677928 --- /dev/null +++ b/pr/545/docs/search.index/579677a41519.js @@ -0,0 +1 @@ +rn_("AQUA9DkSAAABAKQAAQABCAD08xIAAAEAhQABADMBA7BAEsIAAWFiZfWfDAAAAQAeA1QCzwABAAD14AsAAAEAYgMBAAEA84ACc3UjgQKwgBLtAAFydAGAArBwEnUAAaAQAAAMgm56AQYA9AcQAAABALAAAQBzAISgoAAAFCMCART1VQUAAAEAbA5RAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/5802da10e9df.js b/pr/545/docs/search.index/5802da10e9df.js new file mode 100644 index 000000000..2eef7d2b0 --- /dev/null +++ b/pr/545/docs/search.index/5802da10e9df.js @@ -0,0 +1 @@ +rn_("AQEAOzAAAAEAAAcAAQAiCQcAAQIA99EPAADRAKQCAQABAHMAAQATgAKwMBBkAKVpdPMAAXPy6xMAAAEAM4ADsRATZQABZG5w") \ No newline at end of file diff --git a/pr/545/docs/search.index/58045aae0759.js b/pr/545/docs/search.index/58045aae0759.js new file mode 100644 index 000000000..402d9900b --- /dev/null +++ b/pr/545/docs/search.index/58045aae0759.js @@ -0,0 +1 @@ +rn_("AYECoCAAABP2sEAPggABYnABBQD0sxIAAAEAlQABAPMDAWMBHxIAAAEMAPT7EwAAAQABAAEA84ACbnYBgAKwMAwKAAGgMAAADAxpbwEDAaAAAAATw3MBbREAAMcDAICGsEALywABsAAFTwABkUgB") \ No newline at end of file diff --git a/pr/545/docs/search.index/58acc8d198d4.js b/pr/545/docs/search.index/58acc8d198d4.js deleted file mode 100644 index 39102822b..000000000 --- a/pr/545/docs/search.index/58acc8d198d4.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYECoCAAABPDsEAPVQABYnABBQD0ghIAAAEAkwABAPMDAWMB7hEAAAEMAPTIEwAAAQABAAEA84ACbnYBgAKwMAvqAAGgMAAAC+xpbwEDAaAAAAATkHMBPREAAMcDAICGsEALqwABsAAFPwABkUgB") \ No newline at end of file diff --git a/pr/545/docs/search.index/59be03fa81eb.js b/pr/545/docs/search.index/59be03fa81eb.js new file mode 100644 index 000000000..012493ef2 --- /dev/null +++ b/pr/545/docs/search.index/59be03fa81eb.js @@ -0,0 +1 @@ +rn_("AQsA9AwTAAABAA8AAQABBAGwQBLCAAFlARISAADzAAF0AcITAAABDQDz2RMAADEAAQABEADzAhQAABYAAQDzgQNrbXMBAAA7MAAAAQAABgACAPYSAABcEwUAI4YCsEATzQABZXNjgAOwQBBEAAFjcnQzgISwYBBfAAGgEAAABZABCAk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/59c5b0e1f8ad.js b/pr/545/docs/search.index/59c5b0e1f8ad.js new file mode 100644 index 000000000..a10b55957 --- /dev/null +++ b/pr/545/docs/search.index/59c5b0e1f8ad.js @@ -0,0 +1 @@ +rn_("AYICsEATxAABsGASogABZXIBBQD0HxAAAAEAAQABAPOAAmZtAQYAOjAAAAEAAAAAAAgAEAAAAGQPZQ8OEV0SXhJXE9kTChQLFAEAArCwE28AAaFAAAAUA2Vn9E0HAAABAAEAAQDDAISgsAAAE0CwQBA3AAEUIAT3xQYAALcFWAMBADEBIQEOAWOAA7AwD6AAAWFlaQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/59f79b94bb60.js b/pr/545/docs/search.index/59f79b94bb60.js deleted file mode 100644 index 8e4ea4e10..000000000 --- a/pr/545/docs/search.index/59f79b94bb60.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9PUIAAABAJ4HAQABCQGggAAAE99mAc4SAAABAgD1KxAAAAEAAQBIAgEA8wACaXU6MAAAAQAAAAAABwAQAAAACBArEhETEhNCE0MTYRNiEwEIAPV0EwAAAQABAAEAAQDzAgFm9e0PAAABAAEAAQABABOAArCgE7gAAXJ08wACYXPzGhAAAAEAAQDzgAJ0dg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/59fb890d29b8.js b/pr/545/docs/search.index/59fb890d29b8.js new file mode 100644 index 000000000..a1fae09c6 --- /dev/null +++ b/pr/545/docs/search.index/59fb890d29b8.js @@ -0,0 +1 @@ +rn_("AQABsPAUDAABa/aAEwAABQABAAEAAQAlABMAArEAE/kAAWRu8kcSAAABABOAArAQDAYAAWVvAQUAOzAAAAEAAA0AAQAYEQ0AAQIA84wPAAABAAEAAQIA9IgPAAABAAEAAQABAwA7MAAAAQAACAABADkQCAABgAKgQAAAEIuwwBO9AAFlcwEBADswAAABAAATAAEAqQ8TACOAArCQEy0AAWltNzYAAIqgEAAAC9ygUAAAE4ywcBNtAAGgIAAADJucVRE7MAAAAQAABgADACgHAABlEAMAKRIBAPOAAmx0") \ No newline at end of file diff --git a/pr/545/docs/search.index/5a22fd2fcd2b.js b/pr/545/docs/search.index/5a22fd2fcd2b.js new file mode 100644 index 000000000..fa1d07e65 --- /dev/null +++ b/pr/545/docs/search.index/5a22fd2fcd2b.js @@ -0,0 +1 @@ +rn_("AYQCsAAQ+gABsAAQ/AABNDbzAAFh8igMAAABACOAArCQEQABFWx0AYACsHATAQABsIATOAABY3MBAAA6MAAAAQAAAAAACQAQAAAAUxFUEWcSaBJRE1ITpROmExYUFxTzgAJkZScBAICFoNAAABN4sBAEoQABoDAAAA/9AggL") \ No newline at end of file diff --git a/pr/545/docs/search.index/5b27537522a3.js b/pr/545/docs/search.index/5b27537522a3.js deleted file mode 100644 index 69a93b7e3..000000000 --- a/pr/545/docs/search.index/5b27537522a3.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMAOzAAAAEAAIYAAgAwBwAALAmFAAGEArBwE2oAAaBAAAAQZWlzAQcA8z8QAAABAAwBI4ACoLAAABITYXQBAAOwMAjZAAGwMBLPAAGgIAAABzFhZG8B/wEAADcDAICGoMAAABNisAATNgABAJgV") \ No newline at end of file diff --git a/pr/545/docs/search.index/5b319b8ab819.js b/pr/545/docs/search.index/5b319b8ab819.js deleted file mode 100644 index 08dd6e0ae..000000000 --- a/pr/545/docs/search.index/5b319b8ab819.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIBsIATHgABdAHKCAAAAYECoBAAABJ/oHAAABLFYWPzAQFy8vYQAAAYAPOAAmVpI4ACsAALqwABZHLzAAFl9IcAAADwC/kGAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/5b62c7da471c.js b/pr/545/docs/search.index/5b62c7da471c.js new file mode 100644 index 000000000..95a617a99 --- /dev/null +++ b/pr/545/docs/search.index/5b62c7da471c.js @@ -0,0 +1 @@ +rn_("AQMBoEAAABFuZfOwDAAA5AMBAAEGAPSREAAAAQC4AAEAE4EDoAAAABDasSAUAAABYWRuARQA9R4UAAABAAEAAQABAAEFAbCAE8AAAXY7MAAAAQAABwACAEURBAAqEwIAI4ACsHARawABYmRXAAABhqDAAAAS9aCgAAATF6CQAAAS4bBQEAoAAQXgAvXpBgAAAQABAJwIbgQBBgDzQhIAAAEAqADzgANydHYBAwA7MAAAAQAABwACACYTAwAEFAMA8wABcwHDEwAA8wABcwFtEQAAZwEAgIagMAAAC/SwABLcAAGgEAAADJUSQA4=") \ No newline at end of file diff --git a/pr/545/docs/search.index/5b6e7c005ae8.js b/pr/545/docs/search.index/5b6e7c005ae8.js deleted file mode 100644 index 83f481544..000000000 --- a/pr/545/docs/search.index/5b6e7c005ae8.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBoAAAABKFc/QqDwAA0QMBAAIAAQECsGATcAABsEATqgABZHQ7MAAAAQAADQAGADkSAwCjEgEADhMBACUTAQCfEwEAxBMBAAEBA7BwEUUAAbCAEhYAAYASuAAQ7m1uczswAAABAAALAAIApwgFAJgSBQCjgISgsAAAEv2xcBPjAAEIQIJHAQAAhQ+l/AJ7CLEQE3AAAbAwEmwBPRGBCDswAAABAAAGAAIAxBIAACkTBQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/5bd4900427a6.js b/pr/545/docs/search.index/5bd4900427a6.js new file mode 100644 index 000000000..e5b4a6710 --- /dev/null +++ b/pr/545/docs/search.index/5bd4900427a6.js @@ -0,0 +1 @@ +rn_("AQkA898TAAABADUAAYADoEAAABLGsCATgQABoCAAAA9caGl5AQkBoIAAABQSZgEAEwAAAQMBsAATlgBMc/ItEAAAEwNDgAOwIA9YAR6wUBIrAAFhb3IBAgD1WRAAAAEAAQBLAgEA8wADaXR1OjAAAAEAAAAAAA8AEAAAAFEH+wieDL0PNhBWEVwSlBKVEkQTRRNLE3UTdhOUE5UTAQYA9H4SAAABAIkBAQATAgKwYBKAAAFmbfKMDAAAAQAjggKwQBKsAAFlbAGAAqAwAAATwrCwExwAAWFsAQYA82YPAADcAAEAAQUA9GsTAAABAEkAAQDzAgFj8nMSAAABAAECAaAwAAAP/GEBCQwAAAGAArBQEKYAAbAgDzgAAWNu84ACbnQBBQA7MAAAAQAADgACAJIMAACPDw0AAQIAOzAAAAEAAAcAAQAiCQcA5wUAAAmgMAAADAigsAAAE5SggAAAESaw0BOjAAEwYWZpa21ydXY7MAAAAQAAVgIFAO8BAABUA+YASAcAAMMK5gCqDYYAAQwBoKAAABQjd/ITFAAAAQABAQDzfw8AAAEAAQDzgAJ0dQEDAPMvEgAAAQABAAEBAPW6EAAAAQABAAEAAQABAQGwMA9vAOl09joHAAABAI4AqQemAOwBY4ADsJATbQABYW10AQMBoEAAABPGZfLmEwAAAQATgAKwYBQWAAFlcgEDAaAAAAATS3MBdRAAAAECADowAAABAAAAAAAKABAAAAAgCSEJpg/aEtsSChMLE64TAhQYFBkUgwAEoIAAABIJsHAQ6gABsCAQigDqZm5ydgHIBwAAAYECoAAAAAj7oDAAAA9cc3THAQCAxrAAE6EAAbCQEgcAAaAQAAAHIAASiCgBAgA7MAAAAQAADQAGAN4PBQDnEAEAPhIBAGcTAQC5EwAA2BMAABOCArDwFBYAAWZnAYACsIAT7QABoGAAABQRZHMTgAKwwBMyAAFpbwEIAPWnEwAAAQABAAEAAQDzAgFm9RoQAAABAAEAAQABACOAA6AgAAAPVrCgE+sAAWRydPf7BwCPoDAAAA9Ml9cPOzAAAAEAAD0BHQBnBAEAlAQCAFcFAgB/BQIAogUBAJIGBAARBwAAKQcAAMIHAwDRCAIA/wgBAN4LAQAKDAEAMgwDAI4MAQA5DvUAdQ8BAPQPAgA3EAEASBACAHQQAQAHEQAAXREBABESAABPEgAAhhIBAO0SAQAOEwcA+xMDAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/5bf126ddcd97.js b/pr/545/docs/search.index/5bf126ddcd97.js new file mode 100644 index 000000000..bfe32641a --- /dev/null +++ b/pr/545/docs/search.index/5bf126ddcd97.js @@ -0,0 +1 @@ +rn_("AQQBsAASlAABczswAAABAAALAAIADhMHAPsTAwBHAAAEhqCAAAAS77EAFAgAAbBAElAAAbCAFBYAAbBQEpYAARUAFvQyDgAAAQABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/5c0a1d01fe52.js b/pr/545/docs/search.index/5c0a1d01fe52.js deleted file mode 100644 index fb75e2989..000000000 --- a/pr/545/docs/search.index/5c0a1d01fe52.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABoDAAABDVdPIWEAAAAQABgAKgAAAAD+igAAAAD+k0NvMDAXYBiAwAABcBAACHsKASVwABsCALugABsGASUQABsIASNgABoCAAABBOCURGOjAAAAEAAAAAAAkAEAAAAMYGxwbIBsgLUA+rEOcR6BHpEYwT") \ No newline at end of file diff --git a/pr/545/docs/search.index/5ccc63e2df25.js b/pr/545/docs/search.index/5ccc63e2df25.js new file mode 100644 index 000000000..d3483aeff --- /dev/null +++ b/pr/545/docs/search.index/5ccc63e2df25.js @@ -0,0 +1 @@ +rn_("AQIAOzAAAAEAAOcAAgDFCwAAwwzmAPMAAW07MAAAAQAA5wACAHwFAACoBeYAAQMAOzAAAAEAAAgAAgAvDwYAxxIBAPMAAWM7MAAAAQAAVgAnAIgECwBKBQAA3QgBAN0LAADiCwIAmgwAAKYMAgC4DAEAVQ8AAFoPAQBdDwEAYw8AAOsPAgDyDwEA9w8BABcQAACKEAAAkBAAAN0QAQDqEAEA/hABAAIRAgBbEQEAbhECAHQRAAAkEgAALRIBADISAQB4EgEAiBIBAIwSAQCsEgEAvBIDAMISAQAiEwEANBMAAJ8TAADEEwQAzRMCAPOAAnJ3AQkA898TAAABADUAAYACoEAAABLGsCATgQABaGkBDAGgoAAAFCN38hMUAAABAAEBAPN/DwAAAQABAPOAAnR1AYECsIAT7QABoGAAABQRZHM3AwCBhqBAAAATwrBgE5YATAKQDgGIArAAE0wAAbAAE04AATQ2M4ADoDAAABEBZG5zYwADoBAAAASqYWVvAX8AAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/5d45dfdef8cc.js b/pr/545/docs/search.index/5d45dfdef8cc.js new file mode 100644 index 000000000..cec8a307d --- /dev/null +++ b/pr/545/docs/search.index/5d45dfdef8cc.js @@ -0,0 +1 @@ +rn_("AQACoCAAABL6sDARXwABaXTyYxIAAAEAAQMAOzAAAAEAAAYAAQDgEAYAAQgA9GITAAABAIIABQATAQOwkBPEAAGwUBKqAVlnbHA7MAAAAQAAEgAJAO4PAgBiEQEAmRIBALoSAQDxEgEAUxMBAIoTAQCZEwEA1hMBAAGAArAwEVsAAbAwEV0AAXJ2AQQBsAASJQABZDswAAABAAAFAAIAVxEDAFISAQC3BQABh7BQEicBDrBgEqgAAZQJAzowAAABAAAAAAALABAAAACJDIoMiww3DjgOhxAKEQsRDBENEaAS2RIjgAKgEAAADIhubwEDAPPrDwAAAQABACOAAqAAAAALx2RyYwCEoFAAABEHoDAAABAkFAEQ8mwHAAABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/5d5835d05dfa.js b/pr/545/docs/search.index/5d5835d05dfa.js deleted file mode 100644 index 1b2ae6df7..000000000 --- a/pr/545/docs/search.index/5d5835d05dfa.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQkA86wTAAABADUAAQ0BoKAAABPwd/LgEwAAAQABgQKwgBO6AAGgYAAAE95kczcBAIWFoEAAABOPsGATYwBMApAK") \ No newline at end of file diff --git a/pr/545/docs/search.index/5d5b1b8d153b.js b/pr/545/docs/search.index/5d5b1b8d153b.js new file mode 100644 index 000000000..4dc4d979a --- /dev/null +++ b/pr/545/docs/search.index/5d5b1b8d153b.js @@ -0,0 +1 @@ +rn_("AQIAOzAAAAEAAAUAAgAyDAMAhhIBAAECAPP3EAAAAQABAAEGAPQEFAAAAQABAAEA8wYBbfQbEgAAAQABAAEA84ACbnbzgAJhaQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/5d9c4f60b3ee.js b/pr/545/docs/search.index/5d9c4f60b3ee.js deleted file mode 100644 index 5c98c7ed3..000000000 --- a/pr/545/docs/search.index/5d9c4f60b3ee.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEA9WsFAACdDAEApAABAAEAADswAAABAAAHAAMA+wEBAPwLAQB1DwMAAYMCsHASzwABsIATBQABY3MBBQD0cxIAAAEAjwABAPMIAWP1rg8AAAEAuwABAAEAAQABoDAAABDVdPIWEAAAAQABgAKgAAAAD+igAAAAD+k0NvMDAXYBiAwAAJcAAACFsKASVwABsCALugABsIASNgABCQQGOjAAAAEAAAAAAAkAEAAAAMYGxwbIBsgLUA+rEOcR6BHpEYwTAQIA9F8SAAABAI4AAQABAwD0kxIAAAEAkwABAPMAAmJ1OjAAAAEAAAAAABUAEAAAAAcHCAcJBzQPNQ/aD9sP+Q/6D4oQixA1ETYRXRJeEmoSaxJ6EqUSphLsEu0SAQEA9GcFAAABABAHAQC3AACAhbEAE3IAAbAABxEAAQwIRAEIADswAAABAAAFAAEAGBIFANcNAACIsEAQegABoCAAAAySuQALOzAAAAEAAA8ABQBxAAEAvgYHACAHAQDNDwEAdhABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/5dbdf61761a4.js b/pr/545/docs/search.index/5dbdf61761a4.js new file mode 100644 index 000000000..26687ad77 --- /dev/null +++ b/pr/545/docs/search.index/5dbdf61761a4.js @@ -0,0 +1 @@ +rn_("AQgA9GITAAABAIIABQATAAOwkBPEAAGwUBKqAVlnbHA7MAAAAQAAEgAJAO4PAgBiEQEAmRIBALoSAQDxEgEAUxMBAIoTAQCZEwEA1hMBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/5e0965d74272.js b/pr/545/docs/search.index/5e0965d74272.js deleted file mode 100644 index 2decd5449..000000000 --- a/pr/545/docs/search.index/5e0965d74272.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBoEAAABNsZfKWEwAAAQABAAD0SRIAAAEAAQABAPMEAWT07xEAAAEAAQABAKcAAAKFsKAThAABsEASRwABsHATMgABFYgAAVoTAAABAAGwgBNuAAFw8moTAAABAEMAA6AgAAAQrKBAAAAR82Rlc/NRDwAALwMBAPOAAmVp") \ No newline at end of file diff --git a/pr/545/docs/search.index/5ed9ecced0b1.js b/pr/545/docs/search.index/5ed9ecced0b1.js new file mode 100644 index 000000000..3e89ec63f --- /dev/null +++ b/pr/545/docs/search.index/5ed9ecced0b1.js @@ -0,0 +1 @@ +rn_("AYQCsAAQ+gABsAAQ/AABNDbzAgFh8igMAAABAAEAAPU0EgAAbgABAEUBAQDzAAFk80ISAAABAKgAY4ADoCAAAAjIYWVv") \ No newline at end of file diff --git a/pr/545/docs/search.index/5f0e00c10ee4.js b/pr/545/docs/search.index/5f0e00c10ee4.js deleted file mode 100644 index c43bb8dd2..000000000 --- a/pr/545/docs/search.index/5f0e00c10ee4.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9LISAAABAAEAAQATAAKwgBKGAAFzdvQkCQAAAQANCgEAE4ACsDAQWgABbG4BgAKgAAAAD+igAAAAD+k0NvMDAXYBiAwAABMAAqBAAAAQ1WFz98gLAACIA1sBPAEBAAEAowEBAgD0XxIAAAEAjgABAAEDAPSTEgAAAQCTAAEA8wACYnU6MAAAAQAAAAAAEwAQAAAABwcIBwkHNA81D9oP2w/5D/oPihCLEDURNhFdEl4SahJrEnoS7BLtEvOAAmR0E4ACoCAAAAySZXIBBwGgQAAAE2xl8pYTAAABAAEAAPUWCQAAAQABAAEAAQAjgAKgoAAAE8JmcEcAAACFsDAPDwABoFAAAA/QsHAQUwABsUAT6QABgSkA8kEFAAABAPOAAmx0lwEAgIaxMBNuAAGxEBOYAAGgsAAAEpURRQg=") \ No newline at end of file diff --git a/pr/545/docs/search.index/5f4c630285ac.js b/pr/545/docs/search.index/5f4c630285ac.js deleted file mode 100644 index 828f236bd..000000000 --- a/pr/545/docs/search.index/5f4c630285ac.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYA9GMQAAABALYAAQATgQOgAAAAEKqxIBPNAAFhZG4BFAD16xMAAAEAAQABAAEAAQUBsIATjQABdjswAAABAAAHAAIAFREEAPgSAgAjgAKwcBE7AAFiZFcAAAGGoMAAABLDoKAAABLloJAAABKwsFAP3QABBeAC9dQGAAABAAEAhAhoBAEGAPMREgAAAQCoAAEAAaBgAAAPRXIBYQQAANcBAIDFoDAAAAumAACKCg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/5f940ff8b47f.js b/pr/545/docs/search.index/5f940ff8b47f.js new file mode 100644 index 000000000..10b11a5de --- /dev/null +++ b/pr/545/docs/search.index/5f940ff8b47f.js @@ -0,0 +1 @@ +rn_("AYMCsQAUGAABsNAUCgABa20BBAGgoAAAFCN38hMUAAABAAELAPSFEwAAAQABAAEAI4ACoIAAABOtZW9jBAOgYAAAE0NlbnAB2QsAAAEKAPNnEwAAAQBwABOAAqIQAAAUI2xvdwAAAIWgYAAAEgShAAAAE9oEgQM7MAAAAQAAOwAEAJMFBQAhBwAAdAczAAERAABDgAOwgBEAARWgAAAAAgdka3Q=") \ No newline at end of file diff --git a/pr/545/docs/search.index/604d10667a5a.js b/pr/545/docs/search.index/604d10667a5a.js deleted file mode 100644 index 672e0b33a..000000000 --- a/pr/545/docs/search.index/604d10667a5a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("ARMA9esTAAABAAEAAQABABOAAqDAAAAShGFvAQICoLAAABOGoLAAABOHY3PzHxAAAAEAXAABgQKwUBE3AAGgwAAAE1loafOAAmVpI4ACoLAAABLDaXQBBQGwgBONAAF2OzAAAAEAAAcAAgAVEQQA+BICACOAArBwETsAAWJkdwAAAIagoAAAEuWgkAAAErCwUA/dAAEF4AL11AYAAAEAAQCECGgE") \ No newline at end of file diff --git a/pr/545/docs/search.index/6061769b899d.js b/pr/545/docs/search.index/6061769b899d.js deleted file mode 100644 index f2d5849fc..000000000 --- a/pr/545/docs/search.index/6061769b899d.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBgBK4ABDuczswAAABAAAFAAEAmBIFACOCAqCQAAATkGlzBwEAhMWwUBJhAAGgoAAAEv6wcBLGAAGg0AAAE5yAARgI") \ No newline at end of file diff --git a/pr/545/docs/search.index/6084ac5d766b.js b/pr/545/docs/search.index/6084ac5d766b.js deleted file mode 100644 index 1802e3612..000000000 --- a/pr/545/docs/search.index/6084ac5d766b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("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") \ No newline at end of file diff --git a/pr/545/docs/search.index/616f5750f133.js b/pr/545/docs/search.index/616f5750f133.js deleted file mode 100644 index 19ff1e2b1..000000000 --- a/pr/545/docs/search.index/616f5750f133.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMA8/4RAAABAAEAI4ECsSAT4wABY2sBBAGgQAAAET5l84sMAADbAwEAAQAA9UEQAAABAAEAAQB/AnOAhKAwAAATbAgwAQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/61ad89c61241.js b/pr/545/docs/search.index/61ad89c61241.js deleted file mode 100644 index 865fd15b3..000000000 --- a/pr/545/docs/search.index/61ad89c61241.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACoCAAAA8roDAAABMNYXLzAAF0ATwHAAABBAGgQAAAE5Nl8rMTAAABAAEFADswAAABAAALAAUAsQ8FAA0SAQA0EwEAhhMAAKUTAADjAISgMAAADymFAAI7MAAAAQAACwAFAG8FAgB9BgQA6gsBANcQAAAeEgAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/61fb1929c127.js b/pr/545/docs/search.index/61fb1929c127.js deleted file mode 100644 index c4769e932..000000000 --- a/pr/545/docs/search.index/61fb1929c127.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYkCsCATnwABoDAAABOpaXATAAOgIAAAEmeggAAAEnplaXX1qQsAADQAAQABAAEAAYYCsJATxAABoAAAABH3YmQBgAKwMBJbAAGgMAAAEEZydtcAAAKFoDAAAA/EoDAAABKxEAETOjAAAAEAAAAAAAkAEAAAALEIsgizCOUI5gjcD+EPlhCXEDgSAQMBsDASdQABc/MaEAAAAQABAAEAADswAAABAAAKAAMAvhACAPQSAwDREwMA0wCEsCAHwAABEBgB9QoMAAABAAEAAQABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/62058f24fb16.js b/pr/545/docs/search.index/62058f24fb16.js deleted file mode 100644 index 057feaf32..000000000 --- a/pr/545/docs/search.index/62058f24fb16.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQkA86wTAAABADUAAYADoEAAABKVsCATTgABoCAAAA8vaGl5AQkBoIAAABPfZgHOEgAAAQMBsAATYwBMcwENEwAAI4ACoCAAAA8rYXIBAgD1KxAAAAEAAQBIAgEA8wADaXR1OjAAAAEAAAAAAA0AEAAAADwH5AiQDwgQKxJjEmQSERMSExgTQhNDE2ETYhMBgAKgMAAAE4+wsBLqAAFhbAEMAaCgAAAT8Hfy4BMAAAEAAQEA81IPAAABAAEA84ACdHUBAwDz/hEAAAEAAQABAQD1jBAAAAEAAQABAAEAI4ACsJATOgABYXQBBAGgQAAAE5Nl8rMTAAABAAECADswAAABAAALAAUAsQ8FAA0SAQA0EwEAhhMAAKUTAAATggKw8BPjAAFmZwGBArCAE7oAAaBgAAAT3mRzAQgA9XQTAAABAAEAAQABAPMCAWb17Q8AAAEAAQABAAEAI4ADoCAAAA8psKATuAABZHJ0d+8BAI2wEBNuAAGw4BNwAAGX1Q47MAAAAQAAIwESAFgEAQCFBAIAbwUCAH0GBACtBwMAvgsCAOoLAQBqDAEADw7yAEgPAQAJEAEAGhACAEYQAQDXEAAALREBAB4SAADcEgcAyBMDAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/624a2471dcc3.js b/pr/545/docs/search.index/624a2471dcc3.js new file mode 100644 index 000000000..4cfcd8c61 --- /dev/null +++ b/pr/545/docs/search.index/624a2471dcc3.js @@ -0,0 +1 @@ +rn_("AQUA9PwSAAABAAEAAQABAAD1LQwAAAEAAQABAAEA84ACZ2sTgAKwsBNVAAFhbwGAAqAgAAALtKBAAAAL5mV0AYUCsHATfgABsDAS1AABZXMTAAOwQA9dAAGgYAAAEQhiZXM7MAAAAQAAEgAEAIMFAQCcBgoA1g8BACkQAwABAwD08g8AAAEABAABAAEKAaBAAAATxmXy5hMAAAEAE4ACsGASKQABY2nzgAJkcvMAAmVvOzAAAAEAAAkAAgBuBwUAsQcDAAECAbAwENQAAW47MAAAAQAACQABAKoLCQDzgAJvdAEDADswAAABAADnAAIASAcAAMMK5gABAgGgcAAAEXRpOzAAAAEAAPkAAgBHBwAAygn4ABOAAqBAAAAL5XJ1AQQA9LMSAAABAJUAAQABAwDzQhIAAAEAqADzgAJhb9cHAACIsEAMpwABsTAT4wABNIEWOzAAAAEAAB4ADQCfBAEAXQUBAL0LAADrCwcADwwBAGsPAQBUEAEA3xAAACwRAwBpEQEAHxIAAH4SAQAIFAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/62bb0fe614ca.js b/pr/545/docs/search.index/62bb0fe614ca.js new file mode 100644 index 000000000..9392d5001 --- /dev/null +++ b/pr/545/docs/search.index/62bb0fe614ca.js @@ -0,0 +1 @@ +rn_("AQQA9C4QAAABAAEAAQABAAA6MAAAAQAAAAAACgAQAAAAaw9sD1QQVRDfEGkRahF+En8SCBQJFPMBAXnycxMAAAEAAQADoKAAABO6oCAAABL6sDARXwABZWl08mMSAAABAAEDADswAAABAAAGAAEA4BAGAAEIAPRiEwAAAQCCAAUAEwEDsJATxAABsFASqgFZZ2xwOzAAAAEAABIACQDuDwIAYhEBAJkSAQC6EgEA8RIBAFMTAQCKEwEAmRMBANYTAQABgAKwMBFbAAGwMBFdAAFydgECAbAAEiUAAWQ7MAAAAQAABQACAFcRAwBSEgEAI4ECoJAAABO5aW8BBwD01RMAAAwAHgAPAHcWAAGJsFATcwABsFASJwEOsGASqAABtQkDOjAAAAEAAAAAAA4AEAAAAIkMigyLDDcOOA5NEE4QhxCqEAoRCxEMEQ0RoBLZEkOAA6AgAAAMf6AQAAAMiG1ubwEDAPTrDwAAAQABABEBAYACoLAAABOMsDAS3AABbnRDAAOgIAAAEJawUBFnAAFlaGk7MAAAAQAABgADAMcLAAB4EQMAOBMBAPOAAmRyhwsAAAqAAecAEAGAAeoAEAGgUAAAEQegUAAAE7+gMAAAEBmgMAAAECQwMWNlaW9zdHV39WwHAAABAOIHwAJVAQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/62bd0277a025.js b/pr/545/docs/search.index/62bd0277a025.js deleted file mode 100644 index de32f6e3e..000000000 --- a/pr/545/docs/search.index/62bd0277a025.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQ8A9FcTAAABAEsAAQABBAD02A8AAAEArwABAAECADowAAABAAAAAAAJABAAAAAjESQRNhI3Eh4THxNyE3MT4xPkE/MAAW/yKgkAAAEAU4ADsQATtQABaG9ww4CEoBAAABKVsIAS1gABBQAG") \ No newline at end of file diff --git a/pr/545/docs/search.index/62ce08268925.js b/pr/545/docs/search.index/62ce08268925.js new file mode 100644 index 000000000..86a152354 --- /dev/null +++ b/pr/545/docs/search.index/62ce08268925.js @@ -0,0 +1 @@ +rn_("AQwBoKAAABQjd/ITFAAAAQABAQDzfw8AAAEAAQABiYSggAAAFBGgQAAAE8KgYAAAE+KgkAAAFBUCgAoTgYSgoAAAE1exoBQhAAGw0BO7AAEEAQnzgANhdHU=") \ No newline at end of file diff --git a/pr/545/docs/search.index/635558f41241.js b/pr/545/docs/search.index/635558f41241.js new file mode 100644 index 000000000..25d15c547 --- /dev/null +++ b/pr/545/docs/search.index/635558f41241.js @@ -0,0 +1 @@ +rn_("AQABoJAAABLgaPKoEgAAAQDzAgFk8ucGAAABAAECADswAAABAAAFAAEA7xMFAPMLAW07MAAAAQAABQABAK8TBQAjgAKwIAyWAAFhbwECAPPNCAAANAMBAAGKArAAE0wAAbAAE04AATQ2I4ECoDAAAAwqZXIBgAKwQBFpAAEb8AtPDERjdbcGAACHsBAP2AABsFATywABEVEJ9X0EAAAKAMEAAQBuBw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/63d5d6c31ff0.js b/pr/545/docs/search.index/63d5d6c31ff0.js new file mode 100644 index 000000000..e7bb838f0 --- /dev/null +++ b/pr/545/docs/search.index/63d5d6c31ff0.js @@ -0,0 +1 @@ +rn_("AQ8A9IoTAAABAEsAAQABBAD0BRAAAAEAsAABAAECADowAAABAAAAAAAJABAAAABTEVQRZxJoElETUhOlE6YTFhQXFPMAAW/yQQkAAAEAU4ADsQAT6AABaG9ww4CEoBAAABLGsIATCAABBQAG") \ No newline at end of file diff --git a/pr/545/docs/search.index/63dfc59f4dc3.js b/pr/545/docs/search.index/63dfc59f4dc3.js deleted file mode 100644 index cc646fe37..000000000 --- a/pr/545/docs/search.index/63dfc59f4dc3.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIBsEAS8AABZfKDBgAAAQABBADzxw8AAAEAAQBDAAOwQBJXAAGxABM0AAFlZnA7MAAAAQAAJAAGAAECAACSBgwAoAYMAAIPBgBdEAAAlhIBAGOAA7AwC6oAA2FlaQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/643d3b14fc3a.js b/pr/545/docs/search.index/643d3b14fc3a.js deleted file mode 100644 index fc3303389..000000000 --- a/pr/545/docs/search.index/643d3b14fc3a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYMCoFAAABBhoKAAABKIa3ABAAGwQBHWAAFs9CIJAAABAA4HAQABCAD06hEAAAEAAQABAAEEAbAAEDsAAXMBrQ8AAAECAaBQAAASRmMBWQwAALcAAACFsEAMkwABoDAAAAuolQABOzAAAAEAAAgABACZBAAAYwUCAFwMAQAcDwIAJwEAgIWwMAjhAAGgEAAAEr6wIAc1AAGRAEQBEAD0yBMAAAEAAQABAAEDAPQiCQAAAQAOBwEAY4ADoAAAAAuobnJ1AQACsNAS/wABoDAAAA8fYmr2RwUAAAEAAQBIAAEAagEBAAGwgBMeAAF0OzAAAAEAAEAABACPBQAAyggAANYIAAAUDD0AAQkA8woSAAABAAEA84ADY2d0AYMCoJAAABNooJAAABNpMjMBgAKgUAAAE5CggAAAErtjZfMAAnN08v0GAAABAAEAAaCwAAATAWLzkBIAACABAQAjgAKgAAAAEo9kciOAAqBQAAATWmNl84ACaXkBBAD1jBAAAAEAAQABAAEA8wEBbgHzBgAAAQEAOzAAAAEAAAkAAgCiBwcATxIBAAEGAPT0EgAAAQABAAEAAQ8A9NETAAABAAEAAQDzgQJobQEAAbBAE5QAAWX1XBMAAAEAAQABAAEAU4ADoCAAABEmbG50120AgMugIAAAE8OwYBAhAAGwQA9VAAHAGzgK") \ No newline at end of file diff --git a/pr/545/docs/search.index/64f401d0105c.js b/pr/545/docs/search.index/64f401d0105c.js new file mode 100644 index 000000000..c44133ce1 --- /dev/null +++ b/pr/545/docs/search.index/64f401d0105c.js @@ -0,0 +1 @@ +rn_("AQAA9IUQAAABAIYBAQAjgQKgYAAAEqtiaQEAAPR3DwAAAQDrAAEBI4ECsFASvgABZXMTgAKAByMewAFhcgGJArAgE9IAAaAwAAAT3GlwAQIA9JASAAABAI8AAQABAwD0xBIAAAEAlQABAPOFAmJ1AQIA9PEQAAABAG0BAQDzgAJpbLcBAACFoCAAABKYEgEMOjAAAAEAAAAAABYAEAAAAEQH0QfSB9MH1AfJC/0L/gv/CwAMnw9cENwS3RIXE5YT3xPgE+IT7RPuExEUFRQ=") \ No newline at end of file diff --git a/pr/545/docs/search.index/653d5783dc15.js b/pr/545/docs/search.index/653d5783dc15.js deleted file mode 100644 index 688728b4c..000000000 --- a/pr/545/docs/search.index/653d5783dc15.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUAOzAAAAEAAPQAAgBqDAEADw7yAAEBAaAAAAAShXP1lwQAAJMK0QMBAAIAAQECoGAAABMBoOAAABNbZXQ7MAAAAQAACAABAJ0ECAABgAOwIBHUAAGwsBINAAGwsBIPAAFiY3PzgARjbHR2") \ No newline at end of file diff --git a/pr/545/docs/search.index/655cb440fbba.js b/pr/545/docs/search.index/655cb440fbba.js new file mode 100644 index 000000000..01baf5ae0 --- /dev/null +++ b/pr/545/docs/search.index/655cb440fbba.js @@ -0,0 +1 @@ +rn_("AQEBsIAS1gABdfITCQAAAQAjgAKwEAkRAAEzNgEGAPNtEAAAAQAOAROAArAAD0EAAW91AQIA8yMHAADsAQEAAQMA8zsSAAABAAEAI4ACsAAROAABaGkBAAA7MAAAAQAAEwABAFgHEwAjgAKgMAAADIdhZfOAAnJ0E4ACsDATJAABYWwBAAGggAAAFBJm8skIAAA3CgEHAPXPEgAAAQABAAEAAQAjgAKgUAAAEN9hb/MCAmZzOzAAAAEAAAgABAAfBwAAUgcFAK8MAAAXEQAAE4ACoEAAAAvGYW8BAwGwQBPdAAF08kETAAABACOFAqBAAAATcWJzIwADoEAAABB/oFAAABDsYWJm99YIAAABAEgAJwcBAF8AAQATgQKgUAAAEXRndAGAAqBAAAARYaAgAAATUGFpAQIA9AwJAAABALUHAQABAgDzAwwAAAEAAQATgAOwEAkKAAGwMBODAAFpdXkBAgA7MAAAAQAACwACADoTBQDvEwUA8wgBbTswAAABAAAMAAMA6RAAAFYSBQCvEwUAAYECoIAAABJEoHAAABOUYXPzgAJucrfbAQCNoUAAABPqoCAAAAkOoFAAAA+HN5UPOzAAAAEAACcCBQDtAQAAEwIrAd4GAABHBwAAygn4AA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/656b47c2fced.js b/pr/545/docs/search.index/656b47c2fced.js deleted file mode 100644 index 0a0667c1b..000000000 --- a/pr/545/docs/search.index/656b47c2fced.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYMCsQAT5QABsNAT1wABa20BBAGgoAAAE/B38uATAAABAAELAPRSEwAAAQABAAEAI4ACoIAAABN6ZW9jBAOgYAAAExBlbnABuQsAAAEKAPM0EwAAAQBwABOAAqIQAAAT8GxvdwAAAIWgYAAAEdOhAAAAE6cEgQM7MAAAAQAAOwAEAIIFBQAMBwAAXwczANEQAABDgAOwgBDQARSgAAAAAgBka3Q=") \ No newline at end of file diff --git a/pr/545/docs/search.index/657959d9dfd0.js b/pr/545/docs/search.index/657959d9dfd0.js new file mode 100644 index 000000000..505d334ea --- /dev/null +++ b/pr/545/docs/search.index/657959d9dfd0.js @@ -0,0 +1 @@ +rn_("AQMBsAAMngMfc/LeCwAAAQABAgDz3QsAAAAFAQAjAAKgQAAADJplcvKYBAAAAQABgAKgQAAAE0OwMBJlAAFhcwECAaBAAAATxmXy5hMAAAEA84AEbG5ydg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/662c4a4e5d9e.js b/pr/545/docs/search.index/662c4a4e5d9e.js deleted file mode 100644 index 3770e9580..000000000 --- a/pr/545/docs/search.index/662c4a4e5d9e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQA9AAQAAABAAEAAQABAAA6MAAAAQAAAAAACgAQAAAAPg8/DyYQJxCvEDkROhFNEk4S1RPWE/MBAXnyQBMAAAEAAYABfLhIgWObbkOAA6AgAAAMW6AQAAAMZG1ubwEDAPS+DwAAAQABAA4BAYACoLAAABNZsDASqwABbnRDAAOgIAAAEGiwUBE3AAFlaGk7MAAAAQAABgADAKcLAABIEQMABRMBAPOAAmRyhwsAAAqAAeAAEAGAAeMAEAGgUAAAENegUAAAE4ygMAAAD+ygMAAAD/cwMWNlaW9zdHV39VcHAAABAMoHvAJTAQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/667f942da920.js b/pr/545/docs/search.index/667f942da920.js new file mode 100644 index 000000000..a4d3e2664 --- /dev/null +++ b/pr/545/docs/search.index/667f942da920.js @@ -0,0 +1 @@ +rn_("AQABsGATdQABZQGsEwAAAQYA9KISAAABAEUBAQABBAD0vBIAAAEABwEBAPMAA2VyczowAAABAAAAAAAJABAAAADyCPMI9AjBEAARBxIIEhUSbRNuEw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/671a68018a40.js b/pr/545/docs/search.index/671a68018a40.js deleted file mode 100644 index 260d3c496..000000000 --- a/pr/545/docs/search.index/671a68018a40.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9RYJAAABAAEAAQABACOAAqCgAAATwmZwRwAAAIWwMA8PAAGgUAAAD9CwcBBTAAGxQBPpAAGBKQDyQQUAAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/671d46d3c768.js b/pr/545/docs/search.index/671d46d3c768.js deleted file mode 100644 index 94bbdd0d8..000000000 --- a/pr/545/docs/search.index/671d46d3c768.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBsEATlAABZfVcEwAAAQABAAEAAQABAgA7MAAAAQAACwACAAcTBQC8EwUA8wEBbTswAAABAAANAAQAWgwAALkQAAAlEgUAfBMFAPMBAWXyRREAAAEAM4CEsBAP3wABoCAAAAuuFEAE") \ No newline at end of file diff --git a/pr/545/docs/search.index/67319b6740f3.js b/pr/545/docs/search.index/67319b6740f3.js deleted file mode 100644 index dc4bbb0bd..000000000 --- a/pr/545/docs/search.index/67319b6740f3.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACsHASFgABoLAAABNNZW8jAQOwcBFFAAGAErgAEO5tbnM7MAAAAQAAGgAGACcHAQCnCAUAjgwBAJwQCQDYEAAAmBIFAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/6749f8fc3137.js b/pr/545/docs/search.index/6749f8fc3137.js deleted file mode 100644 index 512a8b127..000000000 --- a/pr/545/docs/search.index/6749f8fc3137.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMA9ocMAAC9AloAAQC0AgEAAQQAOzAAAAEAAAoABADiDwUADxIBAG0SAQCHEwAAAYYCoAAAABKPoAAAABKQZHLzAgF2AbsSAADzgAJlbycBAADHoDAAAA9DoHAAABHgoIAAABNaoNAAABL9oLAAABNaQEUICTswAAABAAAJAAMAiAUCAN0GBADtCwEAI4ACFX3rkKKdZHIBAAA6MAAAAQAAAAAACgAQAAAACQkKCXkPqRKqEtgS2RJ7E88T5RPmExOAAqAwAAAP+Gx084ACYWU=") \ No newline at end of file diff --git a/pr/545/docs/search.index/674eafdf622c.js b/pr/545/docs/search.index/674eafdf622c.js deleted file mode 100644 index 9954997b9..000000000 --- a/pr/545/docs/search.index/674eafdf622c.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEBoEAAABOTZfKzEwAAAQABgAOgMAAAEd+w4BNyAAGwkBO1AAFhY22HAQCAhrAQEHoAAbAQEJoAAaCgAAAToaDwAAATwjFJAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/67b74bab08a8.js b/pr/545/docs/search.index/67b74bab08a8.js deleted file mode 100644 index e6cb94d47..000000000 --- a/pr/545/docs/search.index/67b74bab08a8.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYAOzAAAAEAAAkAAQCcEAkAAQIAOzAAAAEAABMAAQB8DxMAE4GEoFAAABBdoBAAAAu8oCAAAAx3HEAAE4ACsFASvAABYW4zgAOwMA8kAAFpc3Q=") \ No newline at end of file diff --git a/pr/545/docs/search.index/680921c7e0dc.js b/pr/545/docs/search.index/680921c7e0dc.js new file mode 100644 index 000000000..102a5159b --- /dev/null +++ b/pr/545/docs/search.index/680921c7e0dc.js @@ -0,0 +1 @@ +rn_("AYACsEAS2gABoMAAABOUZW8BAgD0TBEAAAEAAQABABMAA7AgEVAAAbCAE6UAAWFzdAGIDAAAAQQA84QPAAABAAEAs4CEsEAS7QABQQAG") \ No newline at end of file diff --git a/pr/545/docs/search.index/68704ffa368a.js b/pr/545/docs/search.index/68704ffa368a.js deleted file mode 100644 index 441885c26..000000000 --- a/pr/545/docs/search.index/68704ffa368a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYYCoAAAABKPoAAAABKQZHIBgAKgcAAAEx2gMAAAEGVmdAELAaBAAAATbGXylhMAAAEAI4ECsFAQPQABY3YBAAGwgBNuAAFw8moTAAABAEMGA6AgAAAQrKBAAAAR82Rlc/NRDwAALwMBAPMABGlyc3Y7MAAAAQAADwAFALUGBQAYEgUARBIBALsSAAChEwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/68807ca8d915.js b/pr/545/docs/search.index/68807ca8d915.js deleted file mode 100644 index 6350d9172..000000000 --- a/pr/545/docs/search.index/68807ca8d915.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9M0PAAABAKgAAQABhAKwABDKAAGwABDMAAE0NvMCAWHyBQwAAAEAAQEA9QMSAABuAAEAQwEBAPOAAmVv84ACaGs=") \ No newline at end of file diff --git a/pr/545/docs/search.index/690e03933450.js b/pr/545/docs/search.index/690e03933450.js new file mode 100644 index 000000000..ceac190b6 --- /dev/null +++ b/pr/545/docs/search.index/690e03933450.js @@ -0,0 +1 @@ +rn_("AQAEoAAAABAZsCAQyAABoFAAABFtoEAAABOgZGxzdjswAAABAAATAAYAhgUAAOULAACSDAAAjw8NAOwQAACbEwEAAQIA9EwRAAABAAEAAQAThAKwIBFQAAFhc/OAAmFl") \ No newline at end of file diff --git a/pr/545/docs/search.index/692a422fa077.js b/pr/545/docs/search.index/692a422fa077.js deleted file mode 100644 index dcb2141b3..000000000 --- a/pr/545/docs/search.index/692a422fa077.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYQCsAAQygABsAAQzAABNDbzAAFh8gUMAAABACOAArCQENABFGx0AYACsHASzwABsIATBQABY3MBAAA6MAAAAQAAAAAACQAQAAAAIxEkETYSNxIeEx8TchNzE+MT5BPzgAJkZScBAICFoNAAABNFsBAEkgABoDAAAA/QAggL") \ No newline at end of file diff --git a/pr/545/docs/search.index/693f7e452732.js b/pr/545/docs/search.index/693f7e452732.js deleted file mode 100644 index da451bd09..000000000 --- a/pr/545/docs/search.index/693f7e452732.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEA9CQHAAAVCNsAAQABBQD0cxIAAAEAjwABAPMCAWP1rg8AAAEAuwABAAEAYwAEoDAAAAvJoHAAABEmZW5zdvPMDwAAlAAQAg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/694efa293f2d.js b/pr/545/docs/search.index/694efa293f2d.js new file mode 100644 index 000000000..57f6b6772 --- /dev/null +++ b/pr/545/docs/search.index/694efa293f2d.js @@ -0,0 +1 @@ +rn_("AQUA9DkSAAABAKQAAQABCAD08xIAAAEAhQABADMBA7BAEsIAAWFiZfWfDAAAAQAeA1QCzwABAAD14AsAAAEAYgMBAAEA84ACc3UjgQKwgBLtAAFydAEGAPQHEAAAAQCwAAEAUwCEsIASdQABoKAAABQjAgEU9VUFAAABAGwOUQABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/699c12ddce85.js b/pr/545/docs/search.index/699c12ddce85.js deleted file mode 100644 index 321482266..000000000 --- a/pr/545/docs/search.index/699c12ddce85.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9fcQAAABAAEAAQABAAGAArBgElEAAaAgAAAQTm95AQABoMAAABNtafSnEgAACAAaABsAAQYA9NETAAABAAEAAQABAgD0TBAAAAEAmAABAAECAaBAAAASfnI7MAAAAQAABwACAEoQAQDfEAUA84ACYW9nAwAAhrCAEn0AWLCgEvIAAQwwBjswAAABAAAIAAMAsgsAAAoRAwDqEQMA84ICZWkjAAKggAAAE99maPKwCAAAHgoBAQD0mQsAAAEAoQUBABMAA7AwE4QAAbBQElkAAWVwcvQ8DwAAAQDmAAEAAQADsEATUAABoUAAABO3oFAAABExYmNmAckGAADzgAJtbgEBhKCwAAATDbBAEAkAAbDAEzwAAaBgAAAQ3hQgBPawBgAA9wgBAC4BIAEMAQEFADswAAABAAAFAAEAGBIFAAEHAPWeEgAAAQABAAEAAQAjgAKgUAAAEK9hb/MAhSBJAjswAAABAAAIAAQACgcAAD0HBQCKDAAA5xAAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/69eda39d9ee0.js b/pr/545/docs/search.index/69eda39d9ee0.js deleted file mode 100644 index 7c33abcdd..000000000 --- a/pr/545/docs/search.index/69eda39d9ee0.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBsAASYwABczswAAABAAALAAIA3BIHAMgTAwBHAAAFhqCAAAASvrEAE9UAAbBAEh8AAbCAE+MAAbBQEmUAARUAFvQIDgAAAQABAAEAQwCEoCAAAAjjoNAAABLIoDAAAAjBFQAE8+sBAAABAEUF") \ No newline at end of file diff --git a/pr/545/docs/search.index/6a152aadbb4b.js b/pr/545/docs/search.index/6a152aadbb4b.js new file mode 100644 index 000000000..2b346bbd2 --- /dev/null +++ b/pr/545/docs/search.index/6a152aadbb4b.js @@ -0,0 +1 @@ +rn_("AQIA9JASAAABAI8AAQABAwD0xBIAAAEAlQABAPMCAmJ1OjAAAAEAAAAAABMAEAAAABwHHQceB2EPYg8HEAgQJhAnELgQuRBlEWYRjhKPEpsSnBKrEh4THxM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/6a4e9b07d877.js b/pr/545/docs/search.index/6a4e9b07d877.js new file mode 100644 index 000000000..5ec50ab37 --- /dev/null +++ b/pr/545/docs/search.index/6a4e9b07d877.js @@ -0,0 +1 @@ +rn_("AYACsHASRwABoLAAABOAZW8jAQOwcBF1AAGAEukAEPBtbnM7MAAAAQAAGgAGADwHAQDACAUAswwBAMoQCQAIEQAAyRIFAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/6a81a15ea6e9.js b/pr/545/docs/search.index/6a81a15ea6e9.js new file mode 100644 index 000000000..a35fc8dc3 --- /dev/null +++ b/pr/545/docs/search.index/6a81a15ea6e9.js @@ -0,0 +1 @@ +rn_("AQAAOzAAAAEAAAYAAgAyEQMALxICAAEKAbBAE8cAAWX1jxMAAAEAAQABAAEA8wACaXP02gsAAAEAUAABACOBAqDgAAATrmV5") \ No newline at end of file diff --git a/pr/545/docs/search.index/6ab18f85802f.js b/pr/545/docs/search.index/6ab18f85802f.js deleted file mode 100644 index b5775da7b..000000000 --- a/pr/545/docs/search.index/6ab18f85802f.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYECsDAPlgABsBAS8gABc3QBAwDzChIAAAEAAQAjgAKwABEIAAFoaQEAADswAAABAAATAAEAQwcTACOAAqAwAAAMY2Fl84ACcnTzAAJhbDswAAABAAAoAAMAkwATAJgBAAB8DxMA") \ No newline at end of file diff --git a/pr/545/docs/search.index/6ab71af3e20b.js b/pr/545/docs/search.index/6ab71af3e20b.js new file mode 100644 index 000000000..d796e6255 --- /dev/null +++ b/pr/545/docs/search.index/6ab71af3e20b.js @@ -0,0 +1 @@ +rn_("AQIA9VsRAAABABwBAQBWAQEBAPedEAAAAQABAMMCAQCCAAUAAQIA9DIQAAABAAEAAQATgAKg0AAAE9Rjc/OAAmVvI4ACsAAHJAABbHTzAAJhcvI4DwAAAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/6b27a91421e7.js b/pr/545/docs/search.index/6b27a91421e7.js deleted file mode 100644 index e4aa0f366..000000000 --- a/pr/545/docs/search.index/6b27a91421e7.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBoEAAABDPZQGTDwAAAQgA9AoRAAABAAEAAQABAwGgQAAAEM5lASIPAAABAgDzwwsAAAEAAQAjAAKwIAuzAAFrcvaxBgAAAQCgCeUAAQAhAvOAAnJ4AQMBsIATjQABdjswAAABAAALAAMAYxABABURBgD4EgIAI4ACsGAP3AC6YXIBAwGgAAAAD5Jz8iAPAAABACOAAqCwAAATHWVoAQMBoEAAABBiZfLLCAAAAQDXCwAAirAgByMJbrCwEnEAAaCAAAARDqAAAAASfp8ITDowAAABAAAAAAAKABAAAAD0AU0ETgRPBJ4LnwsADAEMAgx/EpUS") \ No newline at end of file diff --git a/pr/545/docs/search.index/6bb48ae6c164.js b/pr/545/docs/search.index/6bb48ae6c164.js deleted file mode 100644 index 05eca2b1f..000000000 --- a/pr/545/docs/search.index/6bb48ae6c164.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQcA9RMTAAABAAEAcwABAAEHAPMaEAAAAQABAAGAAqAAAAAHF6AQAAAIwGR48wEBZfJzDwAAAQDnAAAAhbBgDHIAAbBAC+8AATIIAfSbBAAAcgJtCQEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/6beb75a4afca.js b/pr/545/docs/search.index/6beb75a4afca.js deleted file mode 100644 index a554a39dd..000000000 --- a/pr/545/docs/search.index/6beb75a4afca.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEAOzAAAAEAAAYAAQCwEAYAAQAA99cIAAABAPwGAQBqAAEADAEBggKgIAAAEHSgMAAAENlpdPOAA2FncwEBAaBAAAATbGXylhMAAAEAI4ACsFATIgABZnPzgAJpbw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/6c1c6140d933.js b/pr/545/docs/search.index/6c1c6140d933.js deleted file mode 100644 index 0defa4395..000000000 --- a/pr/545/docs/search.index/6c1c6140d933.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQADoKAAABOHoCAAABLIsDARLwABZWl08jISAAABAAEDADswAAABAAAGAAEAsBAGAAEIAPQvEwAAAQCCAAUAEwEDsJATkQABsFASeQFXZ2xwOzAAAAEAABIACQDBDwIAMhEBAGgSAQCJEgEAvxIBACATAQBXEwEAZhMBAKMTAQABgAKwMBErAAGwMBEtAAFydgECAbAAEfQAAWQ7MAAAAQAABQACACcRAwAhEgEAI4ECoJAAABOGaW8BBwD0ohMAAAwAHgAPAHcLAAGIsFAR9gEMsGASdwABlQkDOjAAAAEAAAAAAA4AEAAAAGUMZgxnDA0ODg4fECAQWRB8ENoQ2xDcEN0QbxKoEiOAAqAQAAAMZG5v") \ No newline at end of file diff --git a/pr/545/docs/search.index/6c530d02ab41.js b/pr/545/docs/search.index/6c530d02ab41.js new file mode 100644 index 000000000..c2f73879e --- /dev/null +++ b/pr/545/docs/search.index/6c530d02ab41.js @@ -0,0 +1 @@ +rn_("AYACsFATfgABoAAAAAjZY3QBAQD0/BIAAAEAAQABAAEDAPSaDAAAmgaZAAEAAYACoBAAAAwqoFAAABIRY2QBAgDzzQgAADQDAQDzAAFt84cEAADBAAEAAYECoBAAABKwoHAAABL3YWPzAAFy8ywHAAD6CRgAZw8AgIiwMA9ZAMqgMAAAE/UpMCM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/6c8b565dd978.js b/pr/545/docs/search.index/6c8b565dd978.js new file mode 100644 index 000000000..8047c7b30 --- /dev/null +++ b/pr/545/docs/search.index/6c8b565dd978.js @@ -0,0 +1 @@ +rn_("AQAA9S0JAAABAAEAAQABACOAAqCgAAAT9WZwRwAAAIWwMA88AAGgUAAAD/2wcBCBAAGxQBQcAAGBKQDyUQUAAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/6c8cfe800841.js b/pr/545/docs/search.index/6c8cfe800841.js deleted file mode 100644 index affbd126e..000000000 --- a/pr/545/docs/search.index/6c8cfe800841.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQsA9NoSAAABAA8AAQABBAGwQBKRAAFlAeERAADzAAF0AY8TAAABDQDzphMAADEAAQABEADzzxMAABYAAQDzgQNrbXMBAAA7MAAAAQAABgACAMQSAAApEwUAI4YCsEATmgABZXNjgAOwQBAWAAFjcnQzgISwYBAxAAGgEAAABX8BCAk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/6d1573bdc423.js b/pr/545/docs/search.index/6d1573bdc423.js deleted file mode 100644 index b4ac737ae..000000000 --- a/pr/545/docs/search.index/6d1573bdc423.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAA9m0QAAABAG4DAQAKAAEAAQAAOzAAAAEAAAYAAgDEEgAAKRMFACOIArBAE5oAAWVzAQ0BsEATlAABZfVcEwAAAQABAAEAAQABBQA7MAAAAQAACAADAEERAgA9EgQAWxMAANcBAACFTCEQZ17YFIQC81UMAAABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/6d3bd3237ee4.js b/pr/545/docs/search.index/6d3bd3237ee4.js deleted file mode 100644 index 4a271e14e..000000000 --- a/pr/545/docs/search.index/6d3bd3237ee4.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9F8SAAABAI4AAQABAwD0kxIAAAEAkwABAPMCAmJ1OjAAAAEAAAAAABMAEAAAAAcHCAcJBzQPNQ/aD9sP+Q/6D4oQixA1ETYRXRJeEmoSaxJ6EuwS7RI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/6d586f085b70.js b/pr/545/docs/search.index/6d586f085b70.js deleted file mode 100644 index 4b8d8533c..000000000 --- a/pr/545/docs/search.index/6d586f085b70.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9PwQAAABAAEAAQABAQDzEhEAAAEAAQATgAJ1SJXemjxlcwEKAPP4EgAAAQABAAGAArAgE3AAAaBgAAASxW92AYACoDAAABIDoAAAABJ/Y2TzgIUFEAY=") \ No newline at end of file diff --git a/pr/545/docs/search.index/6d8cc2ed1313.js b/pr/545/docs/search.index/6d8cc2ed1313.js new file mode 100644 index 000000000..cfef3db39 --- /dev/null +++ b/pr/545/docs/search.index/6d8cc2ed1313.js @@ -0,0 +1 @@ +rn_("AQADoKAAABO6oCAAABL6sDARXwABZWl08mMSAAABAAEDADswAAABAAAGAAEA4BAGAAEIAPRiEwAAAQCCAAUAEwEDsJATxAABsFASqgFZZ2xwOzAAAAEAABIACQDuDwIAYhEBAJkSAQC6EgEA8RIBAFMTAQCKEwEAmRMBANYTAQABgAKwMBFbAAGwMBFdAAFydgECAbAAEiUAAWQ7MAAAAQAABQACAFcRAwBSEgEAI4ECoJAAABO5aW8BBwD01RMAAAwAHgAPAHcLAAGIsFASJwEOsGASqAABlQkDOjAAAAEAAAAAAA4AEAAAAIkMigyLDDcOOA5NEE4QhxCqEAoRCxEMEQ0RoBLZEiOAAqAQAAAMiG5v") \ No newline at end of file diff --git a/pr/545/docs/search.index/6dfbbd7cf8df.js b/pr/545/docs/search.index/6dfbbd7cf8df.js new file mode 100644 index 000000000..f6531ae59 --- /dev/null +++ b/pr/545/docs/search.index/6dfbbd7cf8df.js @@ -0,0 +1 @@ +rn_("AQABoDAAABEFdPJEEAAAAQABgAKgAAAAEBWgAAAAEBY0NvMDAXYBrQwAABcBAACHsKASiAABsCAL2gABsGASggABsIASZwABoCAAABB8CURGOjAAAAEAAAAAAAkAEAAAANsG3AbdBugLfQ/bEBgSGRIaEr8T") \ No newline at end of file diff --git a/pr/545/docs/search.index/6e4c3193eddd.js b/pr/545/docs/search.index/6e4c3193eddd.js new file mode 100644 index 000000000..f33a6610b --- /dev/null +++ b/pr/545/docs/search.index/6e4c3193eddd.js @@ -0,0 +1 @@ +rn_("AQIAOjAAAAEAAAAAAAgAEAAAANAL0Qs2DzcPbw9YEHwQ+BL5EgEAAPQGCQAAAQABAAEAAQUBsDAShgABaPNvEwAAAQBrABODAqAwAAAQS2NwAQMA9G0PAAABAOgAAQABgQKgAAAAEQWgEAAAD1BldfOAAmFyAYECoJAAABNZsFASEwABYncTgAKwkBKeAAFucvMAAmV08kQQAAABAAEBAPUtDAAAAQABAAEAAQATgAKwsBNVAAFhbyMAArBADKcAAWV0OzAAAAEAAAkABACfBAEAXQUBAA8MAQAsEQMAAQIAOzAAAAEAAAkAAgC3BwcAgBIBAAGAArCQEucAAaCgAAATWGV2E4ACsYAUHgABY20BggKwQBODAAGgUAAAEWFiZhOAAqBAAAATrGRzI4ACoNAAABP2Y27zgIQRAUABBQGwQBLCAAFlARISAABDggOhAAAAFAKg0AAAE9lrbXMTgAKwYBBfAAFhcgEFADswAAABAACHAAIAcxAAAH0RhgABggOwIBKCAAGwIBABAAGwQBD1AAFrbHNTgAOwIBPdAAFrdHUBiYSggAAAFBGgQAAAE8KgYAAAE+KgkAAAFBUCgAoTgoSgoAAAE1exoBQhAAGw0BO7AAEEAQkBgAKxcBQcAAGg0AAAE5VjbyOAArBgEF0AAWlvAQAA9NoLAAABAFAAAQAjgQKg4AAAE65leQENADowAAABAAAAAAAHABAAAAC6ErsSUxNUE4oTixPWE9cTAYECsEAS2gABoMAAABOUZW8BAgA6MAAAAQAAAAAACAAQAAAAZA9lDw4RXRJeElcT2RMKFAsU8wEBbzswAAABAAAJAAQAKwkBAB8QAwBdEAEAVRMBAPOAA21ucgEAADswAAABAAAGAAIA9hIAAFwTBQBDgAOwQBPNAAGgIAAADKZlcnMjAAKwMBM4AAFjcvIkEwAAAQABgQKwgBKIAAGhAAAAE9hjZgELAPTjEgAAAQABAAEAAYACoAAAABAVoAAAABAWNDbzAgF2Aa0MAADzAAJkbAHmCAAA1/45AJKwoBOBAAGwcBFTAAGwgBJnAAGgsAAAEqCd3X87MAAAAQAAFwALAJwBAQCbBAMAWgUCANEGAQDbBgIA6AsAAH0PAADbEAAAQhECABgSAgC/EwAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/6e5b40726ebe.js b/pr/545/docs/search.index/6e5b40726ebe.js deleted file mode 100644 index fe48d0ce0..000000000 --- a/pr/545/docs/search.index/6e5b40726ebe.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYMCsCAQ0AEUoJAAABNbbXABggKwoBNOAAGwoBNQAAFjcgECAaBAAAAQz2UBkw8AADOAhLAgEE8AAbAgDxQAAVAUAPOAAm9y") \ No newline at end of file diff --git a/pr/545/docs/search.index/6e7e72e7f0eb.js b/pr/545/docs/search.index/6e7e72e7f0eb.js new file mode 100644 index 000000000..3848409ec --- /dev/null +++ b/pr/545/docs/search.index/6e7e72e7f0eb.js @@ -0,0 +1 @@ +rn_("AQAA9PoPAAABAKkAAQABhAKwABD6AAGwABD8AAE0NvMCAWHyKAwAAAEAAQEA9TQSAABuAAEARQEBAPOAAmVv84ACaGs=") \ No newline at end of file diff --git a/pr/545/docs/search.index/6e98d18aefa1.js b/pr/545/docs/search.index/6e98d18aefa1.js new file mode 100644 index 000000000..59bed4121 --- /dev/null +++ b/pr/545/docs/search.index/6e98d18aefa1.js @@ -0,0 +1 @@ +rn_("AYkCsCAT0gABoDAAABPcaXATAAOgIAAAEpiggAAAEqtlaXX1yQsAADQAAQABAAEAAYYCsJAT9wABoAAAABIoYmQBAgD00AsAAAEAZQMBAAEAAPQGCQAAAQABAAEAAQAAOzAAAAEAAAYAAgD2EgAAXBMFACOBArBAE80AAWVz84ADZXh5AQAA9AIJAAABAAEAAQAjgAKwIBKMAAFyeEcBAADGsMATIgABoBAAABDtsEAMkAABoDAAABB0AESAC/RLBQAAAQBKBwEA1wAAAIWgMAAAD/GgMAAAEuIQARM6MAAAAQAAAAAACgAQAAAAygjLCMwI/Aj9CNULCRAOEMQQxRBpEg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/6eb590309867.js b/pr/545/docs/search.index/6eb590309867.js deleted file mode 100644 index 596b49527..000000000 --- a/pr/545/docs/search.index/6eb590309867.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBoFAAABOMcwHeEQAAAYICsEASBAABsEASBgABNDYBBgD03BMAAAEACgABAPMCAXIBRRMAAPMDAWX01g8AAAEApgABAFOEA7CwE2QAAWFlaWOAA6BQAAATw2NldA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/6ed9f9ed97a7.js b/pr/545/docs/search.index/6ed9f9ed97a7.js deleted file mode 100644 index b898d8c8a..000000000 --- a/pr/545/docs/search.index/6ed9f9ed97a7.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQ0A9RMTAAABAAEAcwABAAGAAqEQAAATTbBwE2QAAW5yAQcA9AIRAAABAAEAAQAzAASgIAAACOCw4BNCAAExZWly9TEEAAABANkCtQE/AwECAPRXEAAAAQCDAQEAAQMA9MEQAAABAGwBAQDzAAJidQFyDwAAAQMA9FUQAAABAIMBAQDzhAJkcwECAPPCCAAAAQBaAPOAAml0ARgA8+0TAAABAAEAI4ECsMATEQABY20BDQGwQBOUAAFl9VwTAAABAAEAAQABABOCArAAEG0AAWtzAQQA9AAQAAABAAEAAQABgQKgIAAAEGiwQBKrAAFlafOCAmV0AQQBoGAAABIDcvS3CwAAAQC4AwEA84ADYWVvAQkA9iwSAAABAPcAggAxAAEAE4ACsGAQGAABZG4BBgD1QRAAAAEAAQABAH8CAQMBoHAAABJnZ/QYBwAAAQACAgEAAQkA86wTAAABADUAAYECsIATugABoGAAABPeZHMXAQCIhbDQE+AAAaBAAAATj7BgE2MATAKQCgEEAPT/EgAAAQBLAAEAU4ADsJAT2QABZWhvAQABoEAAABDOZQEiDwAAI4ECsFAQegABa3R3/AEAjaGQAAAT0LCwEnUAAaCgAAASK/2BDzswAAABAAAhAAgAeQAAAH8AAwA9BQEA9AYHAOsIBwDVCwcAqw8BANgRAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/6ede7ccd0b48.js b/pr/545/docs/search.index/6ede7ccd0b48.js new file mode 100644 index 000000000..62f2e1e94 --- /dev/null +++ b/pr/545/docs/search.index/6ede7ccd0b48.js @@ -0,0 +1 @@ +rn_("AQMA9DIMAAABAAEAAQABAAGwUBOjAAFyAaMEAABTAYSwQBItAAGwQBPdAAGYAAQ6MAAAAQAAAAAAKAAQAAAAbQRuBG8EcgXbCNwIAQk0CYIMVA/DD8QP0Q8AEFkQWhBbEKIQDhJqEmsSbBJtEpgSphKnEtQS1RJBE0ITRhNHE0gTWBNZE7sTvBPSE9MT9xP4Ew==") \ No newline at end of file diff --git a/pr/545/docs/search.index/6f1ace4f0243.js b/pr/545/docs/search.index/6f1ace4f0243.js new file mode 100644 index 000000000..ff2209179 --- /dev/null +++ b/pr/545/docs/search.index/6f1ace4f0243.js @@ -0,0 +1 @@ +rn_("AQACoCAAABL6sDARXwABaXTyYxIAAAEAAQMAOzAAAAEAAAYAAQDgEAYAAQgA9GITAAABAIIABQATAQOwkBPEAAGwUBKqAVlnbHA7MAAAAQAAEgAJAO4PAgBiEQEAmRIBALoSAQDxEgEAUxMBAIoTAQCZEwEA1hMBAAGAArAwEVsAAbAwEV0AAXJ2AQQBsAASJQABZDswAAABAAAFAAIAVxEDAFISAQC3BQABh7BQEicBDrBgEqgAAZQJAzowAAABAAAAAAALABAAAACJDIoMiww3DjgOhxAKEQsRDBENEaAS2RIjgAKgEAAADIhubwEDAPPrDwAAAQABACOAAqAAAAALx2RyYwGEoFAAABEHoDAAABAkFAEQ8mwHAAABABOAArBgEkcAAWNnE4ADoLAAABOAoEAAAA42ZW9z") \ No newline at end of file diff --git a/pr/545/docs/search.index/6f3b4b773035.js b/pr/545/docs/search.index/6f3b4b773035.js new file mode 100644 index 000000000..513a9dc5a --- /dev/null +++ b/pr/545/docs/search.index/6f3b4b773035.js @@ -0,0 +1 @@ +rn_("AQkBoIAAABQSZgEAEwAAAQIA9VkQAAABAAEASwIBAPMAAml1OjAAAAEAAAAAAAcAEAAAADYQXBJEE0UTdRN2E5QTlRMBCAD1pxMAAAEAAQABAAEA8wIBZvUaEAAAAQABAAEAAQATgAKwoBPrAAFydPMCAmFz80gQAAABAAEAAYABOaUt2hmMdPOAAmFl") \ No newline at end of file diff --git a/pr/545/docs/search.index/6fa3f569eb52.js b/pr/545/docs/search.index/6fa3f569eb52.js new file mode 100644 index 000000000..f93017e86 --- /dev/null +++ b/pr/545/docs/search.index/6fa3f569eb52.js @@ -0,0 +1 @@ +rn_("AQoBoIAAABQSZgEAEwAAAQgA9acTAAABAAEAAQABAPMDAWb1GhAAAAEAAQABAAEA84MCYXMBAgKgIAAAEVKgMAAAEhdiaAFTDwAAI4ACoIAAABK1YXDzAAJobQGGBAAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/6fd276eb1c49.js b/pr/545/docs/search.index/6fd276eb1c49.js deleted file mode 100644 index fde17e0d6..000000000 --- a/pr/545/docs/search.index/6fd276eb1c49.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQYA9E0SAAABAIcBAQATAgKwYBJPAAFmbfJoDAAAAQAjggKwQBJ7AAFlbAEFAPQ4EwAAAQBJAAEA8wMBY/JCEgAAAQABgQKgAAAACOSgMAAADy9zdBOAAqAQAAAHC25404CEsHAT4wABkEAB") \ No newline at end of file diff --git a/pr/545/docs/search.index/6ffa824fa9c9.js b/pr/545/docs/search.index/6ffa824fa9c9.js new file mode 100644 index 000000000..3cd8948ba --- /dev/null +++ b/pr/545/docs/search.index/6ffa824fa9c9.js @@ -0,0 +1 @@ +rn_("AQIAOzAAAAEAABYACQDeDwUA5xABAHERAgA+EgEAbhIEAGcTAQCOEwAAuRMAANgTAAAjgAOh8AAAFCOw8BQWAAFjZmcjgAKwUBMkAAFtbgEFAPNnEwAAAQBwAPMEAWMBBxEAAAEBAbBwE70AAXA7MAAAAQAACQACAKkHBwBPEAEAAQIAOzAAAAEAAAsAAgA6EwUA7xMFAPMBAW07MAAAAQAADQAEAH4MAADpEAAAVhIFAK8TBQATAAKgMAAADIJlc/J1EQAAAQABggKwcBOdAAGgQAAAEJNpc/cBAICGsJATgQABkEkI") \ No newline at end of file diff --git a/pr/545/docs/search.index/7027d2c26d0d.js b/pr/545/docs/search.index/7027d2c26d0d.js deleted file mode 100644 index eacb1c1a2..000000000 --- a/pr/545/docs/search.index/7027d2c26d0d.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYICsCAQlAABsDARCAABZXABBQD0Pg8AAAEA5wABAFOAA7CQETkAAWFpcgGBArCgE04AAbCgE1AAAWNyxwAAAIWwUAx8AAGgIAAACSagIAAAC7U8AAE6MAAAAQAAAAAACgAQAAAAnwGgAUwEuwbXCNgI1A/VDz8QQBBMEQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/702838801d39.js b/pr/545/docs/search.index/702838801d39.js deleted file mode 100644 index 5c6442d78..000000000 --- a/pr/545/docs/search.index/702838801d39.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUA9DgTAAABAEkAAQDzBAFj8kISAAABACOCArBQEhQAAWZ0AQABsAATjQABZPSVCwAAAQABAAEA84ACZWkTgAKw4BOYAAF0dg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7057f9bfeeac.js b/pr/545/docs/search.index/7057f9bfeeac.js deleted file mode 100644 index ba029d33e..000000000 --- a/pr/545/docs/search.index/7057f9bfeeac.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABsIATHgABdAHKCAAAAQkA8woSAAABAAEA84ACY2cBgwKgkAAAE2igkAAAE2kyMwGAAqBQAAATkKCAAAASu2Nl8wACc3Ty/QYAAAEAAQABoLAAABMBYvOQEgAAIAEBACOAAqAAAAASj2RyI4ACoFAAABNaY2XzgAJpeQEGAPWMEAAAAQABAAEAAQABAQGwQBOUAAFl9VwTAAABAAEAAQABAPcAAICFoBAAAAuoKWAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/711105b55fc6.js b/pr/545/docs/search.index/711105b55fc6.js new file mode 100644 index 000000000..a4d5bf986 --- /dev/null +++ b/pr/545/docs/search.index/711105b55fc6.js @@ -0,0 +1 @@ +rn_("AQACoDAAABCXoJAAABL7MGj1dxEAAIwBAQABAAEAE4ACoDAAAA9VZHIjAYSwEAjGAySwIAu7AP+gMAAAD3oSABj1dgUAAC4AAQABAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/715f6cda5699.js b/pr/545/docs/search.index/715f6cda5699.js new file mode 100644 index 000000000..cc481f37a --- /dev/null +++ b/pr/545/docs/search.index/715f6cda5699.js @@ -0,0 +1 @@ +rn_("AQYAOzAAAAEAAAkAAQDKEAkAI4ADsGAS7QABsDAPUQABaXN0AQgA9acTAAABAAEAAQABAPMBAWb1GhAAAAEAAQABAAEAY4ADoDAAABKvZWd0") \ No newline at end of file diff --git a/pr/545/docs/search.index/71be7bf851dd.js b/pr/545/docs/search.index/71be7bf851dd.js deleted file mode 100644 index e5c849c08..000000000 --- a/pr/545/docs/search.index/71be7bf851dd.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQkBoEAAABOTZfKzEwAAAQABgAKwAAxvAAGggAAAEv5kcAEDAaAAAAAPknPyIA8AAAEAAQIDsGASgAABsNATlgABoIAAABMdaXJzAaETAAD3AACAhaEwAAATspBJAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/71d64997f2e2.js b/pr/545/docs/search.index/71d64997f2e2.js deleted file mode 100644 index 83fc8e75e..000000000 --- a/pr/545/docs/search.index/71d64997f2e2.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYACoGAAABM/oKAAABMxYWkBCwD00RIAAAEAAQABAAEEAPT8DwAAAQABAAEAI4ACsEAQUwABbHLzAANjZHMBSRAAAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/71f423a61c5f.js b/pr/545/docs/search.index/71f423a61c5f.js new file mode 100644 index 000000000..576e1236a --- /dev/null +++ b/pr/545/docs/search.index/71f423a61c5f.js @@ -0,0 +1 @@ +rn_("AQgA9acTAAABAAEAAQABAPMAAWY7MAAAAQAABQACAOQBAAAaEAQAAQIAOzAAAAEAAAsAAgA6EwUA7xMFAPMGAW07MAAAAQAADQAEAH4MAADpEAAAVhIFAK8TBQBjgAOwAAjwAAFlbXM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/71fec7874d87.js b/pr/545/docs/search.index/71fec7874d87.js deleted file mode 100644 index 67ab43d4e..000000000 --- a/pr/545/docs/search.index/71fec7874d87.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBoEAAABNWZfLGEwAAAQABAQA7MAAAAQAABgABAOkTBgDzBgFl9J0TAAABAC8AAQAzBQOgYAAAE0RhcnXz0g8AAF4CAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7264b73373df.js b/pr/545/docs/search.index/7264b73373df.js deleted file mode 100644 index a996b8e62..000000000 --- a/pr/545/docs/search.index/7264b73373df.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUBsEASAQABZfIjEgAAAQABggKgkAAAE2igkAAAE2kyMwEAAqAgAAAR3aAgAAAIrmltOzAAAAEAAAwABgBvBAAApgQFACAJAAARDwEAPhMAAFATAQDzAAFzAX8QAAABBQD0yhIAAAEAAQABAAEAAPUKDAAAAQABAAEAAQDzgAJna3OAhLCwEyIAARFIAAEGAaBAAAARPmXziwwAANsDAQABgAOwUBNhAAGgEAAAC5SgcAAAErtnbnJHAQAAhaBgAAATP6BQAAATkKCgAAATMRUBBDswAAABAAARAAQA6QEBAAsQCAACEQMA/hECAAGFArBwE0sAAbAwEqMAAWVzEwADsEAPMAABoGAAABDYYmVzOzAAAAEAABIABABzBQEAhwYKAKkPAQD8DwMAAQMA9MUPAAABAAQAAQABCgGgQAAAE5Nl8rMTAAABABOAArBgEfgAAWNp84ACZHLzAAJlbzswAAABAAAJAAIAWQcFAJwHAwABAgA7MAAAAQAACQABAIoLCQABAAD0ABAAAAEAAQABAAEBADswAAABAADjAAIAkAUAAMIH4gBjAAOwEBJhAAFlaXM6MAAAAQAAAAAADgAQAAAAwQj+CP8IAAkBCbALsQsJDwoPLw9CDyoQThDGEscS44CEsCAHFQABEUAEAQGEsDALngABoEAAAAxboIAAABCrsEAMXAABAAAdAfgBAAABBQD1ExMAAAEAAQBzAAEAE4ACoAAAAAa7YWcBAwD01hEAAAEAYwEBAPOAAmlvAQEAOzAAAAEAAOMAAgAzBwAApwriAAEIAbBAE5QAAWX1XBMAAAEAAQABAAEA84ECZ3QBAQGgcAAAEURpOzAAAAEAAPUAAgAyBwAAsgn0AAEFAPMaEAAAAQABAPOAAmFvE4ACoEAAAAvGcnUBgAKgAAAABxegEAAACMBkeBMAArAgDIIAAWVy8nMPAAABABOAArCwE9kAAXJ4AQoA9NESAAABAAEAAQATgAKwEBBhAidhZQEEAPT8DwAAAQABAAEAAQQAOjAAAAEAAAAAAAcAEAAAAHMSdBKCEoMSAxMEExYTFxMBAwDzERIAAAEAqADTgISwQBBTAAEBSAHHvwMAj6CAAAASE7BgDHIAAbBAC+8AAbEwE7AAAT+pHzswAAABAABLACIAbwAAAHQAAACQBAEAmwQAAE0FAQD9BgEADQcAABEHAQD3CAAACwkHACIJAQCdCwAAswsBALoLAQDLCwcA7wsBAAgMAQBSDAEAPg8BAK4PAQAmEAEAMRABAEkQAABqEAIAehABAIwQBACvEAAA/BADADkRAQDuEQAATRIBAFESAQB+EgAA1RMBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/727e7e92c106.js b/pr/545/docs/search.index/727e7e92c106.js deleted file mode 100644 index 613a75c17..000000000 --- a/pr/545/docs/search.index/727e7e92c106.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEBsIASpQABdfL8CAAAAQAjgAKwEAj6AAEzNgEGAPM/EAAAAQAMAROAArAADxQAAW91AQIA8w4HAADqAQEAAQMA8woSAAABAAEAI4ACsAARCAABaGkBAAA7MAAAAQAAEwABAEMHEwAjgAKgMAAADGNhZfOAAnJ0E4ACsDAS8gABYWwBAAGggAAAE99m8rAIAAAeCgEHAPWeEgAAAQABAAEAAQAjgAKgUAAAEK9hb/MCAmZzOzAAAAEAAAgABAAKBwAAPQcFAIoMAADnEAAAE4ACoEAAAAumYW8BAwGwQBOqAAF08g4TAAABACOFAqBAAAATPmJzIwADoEAAABBRoFAAABC8YWJm970IAAABAEoAEAcBAF8AAQATgQKgUAAAEURndAGAAqBAAAARMaAgAAATHWFpAQIA9PUIAAABAJ4HAQABAgDz4wsAAAEAAQATgAOwEAjzAAGwMBNQAAFpdXkBAgA7MAAAAQAACwACAAcTBQC8EwUA8wgBbTswAAABAAAMAAMAuRAAACUSBQB8EwUAAYECoIAAABIToHAAABNhYXPzgAJucrfbAQCNoUAAABO3oCAAAAj3oFAAAA9aN5UPOzAAAAEAAB8CBQDmAQAADAInAckGAAAyBwAAsgn0AA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/72b28c2fbe41.js b/pr/545/docs/search.index/72b28c2fbe41.js deleted file mode 100644 index f8785272f..000000000 --- a/pr/545/docs/search.index/72b28c2fbe41.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMAOzAAAAEAAD4AAgDWCAAAFAw9AAGAArBQEBYAAbCwEtoAAWFsYwAEsEAPEQABoBAAAA/QYnBydjswAAABAAAGAAEAsBAGAAGAArCAEGACELDgE0AAAWlyAQMBsEAQrQABZQEHDgAAAQUAOzAAAAEAAAYAAQC3DwYAAQMA9F8MAAABAAEAAQDzAAJwczowAAABAAAAAAAMABAAAAByBYIGyAjsC/kLUxBUEPQR9RFJEkoSSxJMElcAAACFsFAQCAIjsFAPLADKoEAAABDYSIADOzAAAAEAAA8ABgBzBAAAMwUDABkPAAAnEQMA7xEDACESAQDTAISgYAAADHEQCAbzmQEAAAEAugo=") \ No newline at end of file diff --git a/pr/545/docs/search.index/731cfc3d033b.js b/pr/545/docs/search.index/731cfc3d033b.js new file mode 100644 index 000000000..a6c4c5cd1 --- /dev/null +++ b/pr/545/docs/search.index/731cfc3d033b.js @@ -0,0 +1 @@ +rn_("AYACoAAAABAVoAAAABAWNDYBgAOwABNMAAGwABNOAAGwcBPAAAE0NmEBBAD0DxQAAAEACgABACOBAqBAAAAQ2m1wAQEAOzAAAAEAAAgAAwBEEgAAtRIAABwUBgDHAQACxaBAAAAP3aCAAAASH0AGgAg7MAAAAQAAFgAIAHsPAQCREAEA1hADAEURBgAqEwIAeBMAANATAQAAFAEA8wACZXY6MAAAAQAAAAAAEgAQAAAABAIFAogFrQw8Dz0PVg9wDwMQBBCrEKwQNRI2EjcSOBIvE5cTmBMBgQKwcBDWAAGwcBDYAAE0NiOAArAQBzMAAW5wAQMCsEASjAABoDAAABLiZXf0CRAAAAUAtgABABOBAqBwAAATG2dvAQQAOzAAAAEAAAYAAgC8CwAAuwwFAGOAA7BQD3sAAWRzdFcBAACFoBAAAA/dsSAT0AABESEBOzAAAAEAAAoAAwB0AAAAjQAFAEwRAwA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/735698ad2cbf.js b/pr/545/docs/search.index/735698ad2cbf.js new file mode 100644 index 000000000..3b0c9a7d9 --- /dev/null +++ b/pr/545/docs/search.index/735698ad2cbf.js @@ -0,0 +1 @@ +rn_("AQABoLAAABM0YvPBEgAAIgEBAAGAAqAgAAAPWKAwAAATQGFy8wABdAFRBwAAAQQBoEAAABPGZfLmEwAAAQABBQA7MAAAAQAACwAFAN4PBQA+EgEAZxMBALkTAADYEwAA4wGEoDAAAA9WhQACOzAAAAEAAAsABQB/BQIAkgYEAAoMAQAHEQAATxIAAGOAA7AAD3kDR2Rucg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7359d03f24c8.js b/pr/545/docs/search.index/7359d03f24c8.js new file mode 100644 index 000000000..39bb80bb4 --- /dev/null +++ b/pr/545/docs/search.index/7359d03f24c8.js @@ -0,0 +1 @@ +rn_("AQMAOzAAAAEAAAUAAQBJEgUAAQQBoFAAABOMaPIpEgAAAQABAAKwQBMiAAGgoAAAE6xlcjowAAABAAAAAAAHABAAAACYBpkGMwc0B3MPdA9hEGIQ84ADZ2lz") \ No newline at end of file diff --git a/pr/545/docs/search.index/73772e5a75b7.js b/pr/545/docs/search.index/73772e5a75b7.js new file mode 100644 index 000000000..42b149371 --- /dev/null +++ b/pr/545/docs/search.index/73772e5a75b7.js @@ -0,0 +1 @@ +rn_("AQQBsAASlAABczswAAABAAALAAIADhMHAPsTAwBHAAABhqCAAAAS77EAFAgAAbBAElAAAbCAFBYAAbBQEpYAARUAFvQyDgAAAQABAAEAAQUA84QPAAABAAEAY4CEsEAQDAABoAAAAAa0APAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/73e05ea17e51.js b/pr/545/docs/search.index/73e05ea17e51.js new file mode 100644 index 000000000..31fa802f0 --- /dev/null +++ b/pr/545/docs/search.index/73e05ea17e51.js @@ -0,0 +1 @@ +rn_("AQIAOzAAAAEAAAUAAQDvEwUA8w0BbTswAAABAAAFAAEArxMFACMDhLBAEjIAAaEAAAAT9bAAEvAAhzAIAjswAAABAAAUAAUArhAHAFQSAQDPEgQApxMEABIUAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/74acc4c6fbd6.js b/pr/545/docs/search.index/74acc4c6fbd6.js deleted file mode 100644 index 7ca3168a3..000000000 --- a/pr/545/docs/search.index/74acc4c6fbd6.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAAOzAAAAEAAAYAAgACEQMA/hECAAEKAbBAE5QAAWX1XBMAAAEAAQABAAEA8wACaXP0ugsAAAEATQABACOBAqDgAAATe2V5") \ No newline at end of file diff --git a/pr/545/docs/search.index/74cc3e63f115.js b/pr/545/docs/search.index/74cc3e63f115.js new file mode 100644 index 000000000..15577ccb5 --- /dev/null +++ b/pr/545/docs/search.index/74cc3e63f115.js @@ -0,0 +1 @@ +rn_("AQIA9IUQAAABAIYBAQABAAD0dw8AAAEA6wABASOCArBQEr4AAWVzAQIA9JASAAABAI8AAQABAwD0xBIAAAEAlQABAPOFAmJ1AQIA9PEQAAABAG0BAQDzgAJpbPMAA2J0dTowAAABAAAAAAAPABAAAABEB9EH0gfTB9QHnw9cEBcTlhPfE+AT4hPtE+4TERQVFAEMAPN7EwAAAQABAAGAArAACOgAAaAgAAAMrmRuAQYA9I4SAAABAI8AAQDzAwFi9IMQAAABAIYBAQCXBgAAh7BAD3UAAaBwAAASFrCQErwAATgJAzowAAABAAAAAAAkABAAAACcBZ0FngWfBQYHBwfmC6MMpAylDKkMqgyrDG0Pbg/BD8IPxg/HD+QP5Q/mD+cP6A/pD+oPKBAtEFYQVxD3EhsTQBPVE+ET/xMOFA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/74d7e300323a.js b/pr/545/docs/search.index/74d7e300323a.js deleted file mode 100644 index 6d25d693d..000000000 --- a/pr/545/docs/search.index/74d7e300323a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBoEAAABDOZQEiDwAAAQIA88MLAAABAAEAIwACsCALswABa3L2sQYAAAEAoAnlAAEAIQLzAAJyePKlCAAAAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/754895de9a3c.js b/pr/545/docs/search.index/754895de9a3c.js deleted file mode 100644 index 86b3e5c15..000000000 --- a/pr/545/docs/search.index/754895de9a3c.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYADsAATGQABsAATGwABsHATjQABNDZhAQQA9NwTAAABAAoAAQAjgQKgQAAAEKptcAEBADswAAABAAAIAAMAExIAAIQSAADpEwYAxwEAAMWgQAAAD7CggAAAEe5ABoAIOzAAAAEAABYACABODwEAYxABAKYQAwAVEQYA+BICAEUTAACdEwEAzRMBAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/75c09f7fd4e5.js b/pr/545/docs/search.index/75c09f7fd4e5.js deleted file mode 100644 index 7f5e76729..000000000 --- a/pr/545/docs/search.index/75c09f7fd4e5.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIAOzAAAAEAAAUAAQC8EwUA8w0BbTswAAABAAAFAAEAfBMFAEcAAACFsAATjQABsEASAQABoQAAABPCoAAAABNEOAgCOzAAAAEAABgABgCVCwMAgBAHACMSAQCeEgQAdBMEAN8TAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7626b27789d9.js b/pr/545/docs/search.index/7626b27789d9.js deleted file mode 100644 index c7a71741f..000000000 --- a/pr/545/docs/search.index/7626b27789d9.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9TsSAAABAOoAeQABABOAArAwEmwBPWlwAQYA8+YSAAABAAEA8wICYnMBmA8AAPMBAWbyIwcAAG4JAQIA9JMSAAABAJMAAQAzgAOwQBJhAAFpdXk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/765cffa6a271.js b/pr/545/docs/search.index/765cffa6a271.js new file mode 100644 index 000000000..13f37077f --- /dev/null +++ b/pr/545/docs/search.index/765cffa6a271.js @@ -0,0 +1 @@ +rn_("AQAA9OMSAAABAAEAAQABBADzSQ8AAAEAAQABgAKgUAAAEFOgYAAAEMFpcgGAAqAgAAAMJ6BgAAAQwGVoAQEBoCAAABC/YvMjDAAAAQABABOBAqAQAAAMJmFjAQMAOzAAAAEAAAUAAgAfDAMA1BABAAEGAPR+EgAAAQCJAQEAEwACsGASgAABZm3yjAwAAAEAI4ACoMAAABNLbnKnDwAAiKBAAAAPRrBAD0cAATQgFzswAAABAAAZAAMA+gEAAEwEDgCqCwkAAYADsHATAQABsDASrAABsIATOAABY3JzAQABsCATAQABbzowAAABAAAAAAAJABAAAABTEVQRZxJoElETUhOlE6YTFhQXFAGAArAgCPAAAbAwErcAAXJ09wQAAMigIAAAB0agYAAAD3KwgBK3AAFABpIJ9gYCAABqAssEAQApCgEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/766d90f1d785.js b/pr/545/docs/search.index/766d90f1d785.js new file mode 100644 index 000000000..699962e9e --- /dev/null +++ b/pr/545/docs/search.index/766d90f1d785.js @@ -0,0 +1 @@ +rn_("AQIA9JASAAABAI8AAQABAgD0ehAAAAEAmgABAAEDAPTEEgAAAQCVAAEAAQIBoEAAABKvcjswAAABAAAHAAIAeBABAA8RBQDzAIQDQAg6MAAAAQAAAAAAFQAQAAAAHAcdBx4HYQ9iDwcQCBAmECcQuBC5EGURZhGOEo8SmxKcEqsS1hLXEh4THxM=") \ No newline at end of file diff --git a/pr/545/docs/search.index/76f703a56322.js b/pr/545/docs/search.index/76f703a56322.js new file mode 100644 index 000000000..ab6bd2ee0 --- /dev/null +++ b/pr/545/docs/search.index/76f703a56322.js @@ -0,0 +1 @@ +rn_("AYACoIAAABJEsHATlAABYXMBAAGggAAAFBJm8skIAAA3CgEHAPXPEgAAAQABAAEAAQAjgAKgUAAAEN9hb/MAAmZzOzAAAAEAAAgABAAfBwAAUgcFAK8MAAAXEQAA84ACZHk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/771f0ba905a1.js b/pr/545/docs/search.index/771f0ba905a1.js new file mode 100644 index 000000000..be1e870ad --- /dev/null +++ b/pr/545/docs/search.index/771f0ba905a1.js @@ -0,0 +1 @@ +rn_("AQcA9HgRAAABAAEAAQAjAAKgcAAAEXdhcgFMBwAAAQAA9psQAAABAHMDAQAKAAEAAQAAOzAAAAEAAAYAAgD2EgAAXBMFACOIArBAE80AAWVzAQ0BsEATxwABZfWPEwAAAQABAAEAAQABBQA7MAAAAQAACAADAHERAgBuEgQAjhMAANcDAACGHYyPbzNAFIQG9aEEAAABANcHAQABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7735e3412c3d.js b/pr/545/docs/search.index/7735e3412c3d.js deleted file mode 100644 index 11366f8c1..000000000 --- a/pr/545/docs/search.index/7735e3412c3d.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9PwQAAABAAEAAQABCgDz+BIAAAEAAQDzgQJtdAEGAPO+EAAAAQABAAGCArBgEoAAAbDQE5YAAWlyE4ACsBAMbwABZWkBBQD0OBMAAAEASQABAPMEAWPyQhIAAAEAI4ICsFASFAABZnQBAAGwABONAAFk9JULAAABAAEAAQDzgQJlaTcGAACJsTATswABoGAAABC9oFAAABBSsJASUwABsEAQTwABtRAHAW0TAAA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7738bacb3923.js b/pr/545/docs/search.index/7738bacb3923.js deleted file mode 100644 index a4ac3d755..000000000 --- a/pr/545/docs/search.index/7738bacb3923.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9F8SAAABAI4AAQABAgD0TBAAAAEAmAABAAEDAPSTEgAAAQCTAAEAAQIBoEAAABJ+cjswAAABAAAHAAIAShABAN8QBQDzAIQDQAg6MAAAAQAAAAAAFQAQAAAABwcIBwkHNA81D9oP2w/5D/oPihCLEDURNhFdEl4SahJrEnoSpRKmEuwS7RI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/778c2fe91b81.js b/pr/545/docs/search.index/778c2fe91b81.js deleted file mode 100644 index bab7c9944..000000000 --- a/pr/545/docs/search.index/778c2fe91b81.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEAOjAAAAEAAAAAAAkAEAAAADcPOA8lEN4QLBItEiQTphPXE9gTAYACsOATHgABsDATNgABZHDDgISxQBPnAAGgkAAAEuUCgAk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/77be044378b5.js b/pr/545/docs/search.index/77be044378b5.js new file mode 100644 index 000000000..070edfc34 --- /dev/null +++ b/pr/545/docs/search.index/77be044378b5.js @@ -0,0 +1 @@ +rn_("AQEA84wPAAABAAEAAQMBoEAAABOJZfL5EwAAAQABAQGgIAAAEL9i8yMMAAABAAEAE4ACoBAAAAwmYWNzgISgUAAAD3IQQAw=") \ No newline at end of file diff --git a/pr/545/docs/search.index/77bf703f157b.js b/pr/545/docs/search.index/77bf703f157b.js new file mode 100644 index 000000000..20adbccd7 --- /dev/null +++ b/pr/545/docs/search.index/77bf703f157b.js @@ -0,0 +1 @@ +rn_("AQQBoEAAABOJZfL5EwAAAQABAQA7MAAAAQAABgABABwUBgDzBgFl9NATAAABAC8AAQAzAwOwYBLwAIdhcnXz/w8AAGICAQAjgAKAEPcAEAFkcg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/77f651e5878e.js b/pr/545/docs/search.index/77f651e5878e.js deleted file mode 100644 index 87c272cc8..000000000 --- a/pr/545/docs/search.index/77f651e5878e.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMA874PAAABAAEAAYACoLAAABNZsDASqwABbnRDAAOgIAAAEGiwUBE3AAFlaGk7MAAAAQAABgADAKcLAABIEQMABRMBAPOAAmRy") \ No newline at end of file diff --git a/pr/545/docs/search.index/781f99b9d65a.js b/pr/545/docs/search.index/781f99b9d65a.js new file mode 100644 index 000000000..bb96d917e --- /dev/null +++ b/pr/545/docs/search.index/781f99b9d65a.js @@ -0,0 +1 @@ +rn_("AQEBsFAPXwABY/SDBAAAAQABAMIAAQABoIAAABQSZgEAEwAA8wYBc/KvDAAAaAQzAAOgYAAAE/ZjaXPyUBEAAAEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/7886cbd3ae54.js b/pr/545/docs/search.index/7886cbd3ae54.js deleted file mode 100644 index 2a8905d88..000000000 --- a/pr/545/docs/search.index/7886cbd3ae54.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUBsEASAQABZfIjEgAAAQABAAA7MAAAAQAAEQAEAOkBAQALEAgAAhEDAP4RAgABCgGwQBOUAAFl9VwTAAABAAEAAQABAEcGAACHsCAQYQInsMAT2QABoCAAAAa7sDAHFQABGIkKOjAAAAEAAAAAAAwAEAAAABEHEgf3CLMLtAu6C7sLCAwJDFIMUwxRElIS") \ No newline at end of file diff --git a/pr/545/docs/search.index/78e0cb18a45a.js b/pr/545/docs/search.index/78e0cb18a45a.js deleted file mode 100644 index 9d9a3a891..000000000 --- a/pr/545/docs/search.index/78e0cb18a45a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYMCsQAT5QABsNAT1wABa20BCgDzNBMAAAEAcAATgAKiEAAAE/BsbzMBhKBgAAAR06EAAAATpwSAAzswAAABAAA0AAIADAcAAF8HMwA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7918be142114.js b/pr/545/docs/search.index/7918be142114.js new file mode 100644 index 000000000..263426016 --- /dev/null +++ b/pr/545/docs/search.index/7918be142114.js @@ -0,0 +1 @@ +rn_("AQIA9ScRAAABAAEAAQABAAGAArBgEoIAAaAgAAAQfG95AQABoMAAABOgafTYEgAACAAbABsAAQMA9PwSAAABAAEAAQABBgD0BBQAAAEAAQABAAECAPR6EAAAAQCaAAEAAQIBoEAAABKvcjswAAABAAAHAAIAeBABAA8RBQDzgAJhb2cHAACHsIASrgBZsKATJAABDDAHOzAAAAEAAA4ABAB1BAUA0gsAADoRAwAbEgMApwAAgIWg8AAAEzWwUA/UAAGgkAAAEQaUgQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7969e190031a.js b/pr/545/docs/search.index/7969e190031a.js new file mode 100644 index 000000000..47aca549c --- /dev/null +++ b/pr/545/docs/search.index/7969e190031a.js @@ -0,0 +1 @@ +rn_("AYACsRAT+QABsBAMBgABZW8BBQA7MAAAAQAADQABABgRDQABAgDzjA8AAAEAAQABAgD0iA8AAAEAAQABAAEDADswAAABAAAIAAEAORAIAIcHAACHsKATLQABsNATvQABoFAAABOMjBQROzAAAAEAAAYAAwAoBwAAZRADACkSAQDzgQJsdPMAAWk7MAAAAQAAiAADAHwEAABzEAAAfRGGAAEFAPPfEwAAAQA1AAEAAaBAAAAQd2Xz1AgAAAEAQQkTgAKgMAAAD2NkcvMAAWXzwgYAAAEAAQDzgAJodAEBADswAAABAACHAAIAcxAAAH0RhgATgAKgUAAAD6ZpdAEIAPRiEwAAAQCCAAUAEwCEsPAT4QAtsJATxAABsFASqgFZQIkAOzAAAAEAABIACQDuDwIAYhEBAJkSAQC6EgEA8RIBAFMTAQCKEwEAmRMBANYTAQDXAQAAhrCAETAAAaBAAAAI9wgwJjowAAABAAAAAAANABAAAACKAIsAMgc4CbsLugyFEIYQDBINEpASkRIgEyET") \ No newline at end of file diff --git a/pr/545/docs/search.index/7995ef0dee58.js b/pr/545/docs/search.index/7995ef0dee58.js deleted file mode 100644 index 089ab367f..000000000 --- a/pr/545/docs/search.index/7995ef0dee58.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQAOjAAAAEAAAAAAAcAEAAAADQPNQ/5D/oPXRJeEuwS7RIBAAD0tQgAAAEAWgrgACcAAACIoRAAABOooEAAABBisGATmAABoBAAAAwTsFATNgABsDAQwwABsSATuAABOcECOjAAAAEAAAAAABAAEAAAAMsIzAjhCOIIoAuhC6ILqgutC2MM3xHBEsIS1hLXEkYTRxMzgAOggAAAEz9lb3k=") \ No newline at end of file diff --git a/pr/545/docs/search.index/79dd38514944.js b/pr/545/docs/search.index/79dd38514944.js deleted file mode 100644 index 208358349..000000000 --- a/pr/545/docs/search.index/79dd38514944.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQcA9MoSAAABAAEAAQDzBQF0OzAAAAEAAAgAAgCdCwAAywsHAAEFAPPmEgAAAQABADcAAICFsDAPpQABoKAAABMBoDAAABM+EEFI") \ No newline at end of file diff --git a/pr/545/docs/search.index/7a5a2af66b0c.js b/pr/545/docs/search.index/7a5a2af66b0c.js deleted file mode 100644 index a896d06b3..000000000 --- a/pr/545/docs/search.index/7a5a2af66b0c.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AYMCsQAT5QABsNAT1wABa20BCgDzNBMAAAEAcAATgAKiEAAAE/BsbzMChKBgAAAR06EAAAATpwSAAzswAAABAAA0AAIADAcAAF8HMwA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7a61dea0bfb9.js b/pr/545/docs/search.index/7a61dea0bfb9.js new file mode 100644 index 000000000..82d8961cd --- /dev/null +++ b/pr/545/docs/search.index/7a61dea0bfb9.js @@ -0,0 +1 @@ +rn_("AQMBoEAAABD+ZQFPDwAAAQIA8+ILAAABAAEAIwACsCAL0wABa3L2xgYAAAEAuQnnAAEAJALzAAJyePK+CAAAAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7a7d64379eb7.js b/pr/545/docs/search.index/7a7d64379eb7.js deleted file mode 100644 index 6b366a18d..000000000 --- a/pr/545/docs/search.index/7a7d64379eb7.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEAOjAAAAEAAAAAAAgAEAAAAL8Izw9vEHAQcRAvEzATshO3EwEBAqBAAAATnKAwAAAQdWVo9bcIAAAwAAoDAQAzBQECAPQcEQAAAQABAAEAE4ECsCARIAABYXPzgAJubwECAPQEEAAAAQABAAEAEwACoNAAABOhY3Pyeg8AAAEA84ADZWlv") \ No newline at end of file diff --git a/pr/545/docs/search.index/7a7e68e0fc89.js b/pr/545/docs/search.index/7a7e68e0fc89.js deleted file mode 100644 index a6b9c5c2f..000000000 --- a/pr/545/docs/search.index/7a7e68e0fc89.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMAOzAAAAEAAIYAAgBFEAAATRGFAAEAAbBwEv8AAWXyOg8AAAEAIwACoEAAABNWZXP0pQ8AAAEAIAQBADOAA6BgAAAQ9mRpbw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7adb9969b6af.js b/pr/545/docs/search.index/7adb9969b6af.js deleted file mode 100644 index 43cac1e2a..000000000 --- a/pr/545/docs/search.index/7adb9969b6af.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQkA86wTAAABADUAAYACoEAAABKVsCATTgABaGkBDAGgoAAAE/B38uATAAABAAEBAPNSDwAAAQABAPOAAnR1AYECsIATugABoGAAABPeZHM3AwCDhqBAAAATj7BgE2MATAKQDgESAPTIEwAAAQABAAEAAQDGoFAAABIeoAAAAA/ssCAQmgABoFAAABE9oQAAABPDoEAAABNtAAMCCzswAAABAAAVAAcAdgUAAMYLAABuDAAAYg8NALwQAAA0EgEAaBMBAAEBAbCwE7UAAWw7MAAAAQAADAADAOMGCACMDAEAoA8BAAEBAaAwAAAQdWjztwgAADAAPggBAgD0HBEAAAEAAQABABOBArAgESAAAWFz84ICbm/3AQCAh6AgAAAFdaBAAAALrxUBBw==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7ae266f95131.js b/pr/545/docs/search.index/7ae266f95131.js deleted file mode 100644 index 2999fdf2f..000000000 --- a/pr/545/docs/search.index/7ae266f95131.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQcA9EgRAAABAAEAAQAjAAKgcAAAEUdhcgE3BwAAAQAA9m0QAAABAG4DAQAKAAEAAQAAOzAAAAEAAAYAAgDEEgAAKRMFACOIArBAE5oAAWVzAQ0BsEATlAABZfVcEwAAAQABAAEAAQABBQA7MAAAAQAACAADAEERAgA9EgQAWxMAANcDAACGTCEQZ17YFIQG9ZIEAAABAMIHAQABAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7b1673ee6360.js b/pr/545/docs/search.index/7b1673ee6360.js new file mode 100644 index 000000000..261ad288b --- /dev/null +++ b/pr/545/docs/search.index/7b1673ee6360.js @@ -0,0 +1 @@ +rn_("AQQBsAASlAABczswAAABAAALAAIADhMHAPsTAwBHAAAFhqCAAAAS77EAFAgAAbBAElAAAbCAFBYAAbBQEpYAARUAFvQyDgAAAQABAAEAQwCEoCAAAAj6oNAAABL6oDAAAAjaFQAE8/IBAAABAFMF") \ No newline at end of file diff --git a/pr/545/docs/search.index/7b18e5676a21.js b/pr/545/docs/search.index/7b18e5676a21.js deleted file mode 100644 index 4d79c5637..000000000 --- a/pr/545/docs/search.index/7b18e5676a21.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQAAOzAAAAEAAAYAAgDEEgAAKRMFACOIArBAE5oAAWVzAQQBsDASlgABY/PSEAAAAQABAAEFADswAAABAAAIAAMAQRECAD0SBABbEwAA8wMDY2Vw81UMAAABAAEAAQABsGATQgABZQF5EwAA8wIBc/bbCAAAAQABALYHPQAUAQECAaBQAAAQ0XIBcxAAAPOAA2ZtcA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7bd7bca0a11f.js b/pr/545/docs/search.index/7bd7bca0a11f.js new file mode 100644 index 000000000..87559b73f --- /dev/null +++ b/pr/545/docs/search.index/7bd7bca0a11f.js @@ -0,0 +1 @@ +rn_("AQAAOzAAAAEAAAYAAgD2EgAAXBMFACOIArBAE80AAWVzAQQBsDASxwABY/MCEQAAAQABAAEFADswAAABAAAIAAMAcRECAG4SBACOEwAA8wEDY2Vw83kMAAABAAEAAQIA9ucIAABXAMcGAQCwAAEA84ACbnI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7bea30136fcb.js b/pr/545/docs/search.index/7bea30136fcb.js deleted file mode 100644 index c92523812..000000000 --- a/pr/545/docs/search.index/7bea30136fcb.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQcA9tgSAAABAKIAVAAWAAEA8wEBaQETCQAAAQAA9RYJAAABAAEAAQABAEcBAIDGdzXjQSw9oKAAABPCsGATOgABoBAAAAjqAAogig==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7bfb7923cdee.js b/pr/545/docs/search.index/7bfb7923cdee.js deleted file mode 100644 index 2547777db..000000000 --- a/pr/545/docs/search.index/7bfb7923cdee.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIBsEATqgABdDswAAABAAANAAYAORIDAKMSAQAOEwEAJRMBAJ8TAQDEEwEAE4ACsDASbAE9aXABBQDz5hIAAAEAAQATgAKgMAAAEz5leVMCA7BwE0sAAWJlcwGYDwAAEwACoCAAAAVtZm32egAAAKgGAQDQAQEAnQc=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7c00a3d092bc.js b/pr/545/docs/search.index/7c00a3d092bc.js deleted file mode 100644 index 8ce0d0ebb..000000000 --- a/pr/545/docs/search.index/7c00a3d092bc.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQBoEAAABNWZfLGEwAAAQABAQA7MAAAAQAABgABAOkTBgDzBgFl9J0TAAABAC8AAQBTAISgIAAACROgYAAAE0QBAQnz0g8AAF4CAQA=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7c908b298ddc.js b/pr/545/docs/search.index/7c908b298ddc.js deleted file mode 100644 index 8549f3a42..000000000 --- a/pr/545/docs/search.index/7c908b298ddc.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQMBoAAAAA+Qc/O+CwAAAQABAAECAPO9CwAA8AQBACMAAqBAAAAMdmVy8okEAAABAAGAAqBAAAATELAwEjQAAWFzAQIBoEAAABOTZfKzEwAAAQDzgARsbnJ2") \ No newline at end of file diff --git a/pr/545/docs/search.index/7cb84881639b.js b/pr/545/docs/search.index/7cb84881639b.js deleted file mode 100644 index c49b6a054..000000000 --- a/pr/545/docs/search.index/7cb84881639b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQADoKAAABOHoCAAABLIsDARLwABZWl08jISAAABAAEDADswAAABAAAGAAEAsBAGAAEIAPQvEwAAAQCCAAUAEwEDsJATkQABsFASeQFXZ2xwOzAAAAEAABIACQDBDwIAMhEBAGgSAQCJEgEAvxIBACATAQBXEwEAZhMBAKMTAQABgAKwMBErAAGwMBEtAAFydgECAbAAEfQAAWQ7MAAAAQAABQACACcRAwAhEgEAI4ECoJAAABOGaW8BBwD0ohMAAAwAHgAPAHcWAACJsFATQAABsFAR9gEMsGASdwABtQkDOjAAAAEAAAAAAA4AEAAAAGUMZgxnDA0ODg4fECAQWRB8ENoQ2xDcEN0QbxKoEg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7cba359afb0b.js b/pr/545/docs/search.index/7cba359afb0b.js deleted file mode 100644 index 71f3a6c3e..000000000 --- a/pr/545/docs/search.index/7cba359afb0b.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUAOzAAAAEAAAYAAQC3DwYAAQMA9F8MAAABAAEAAQBjAAOgkAAAEq9ocHM6MAAAAQAAAAAADgAQAAAAcgWCBsgI7Av5C1MQVBD0EfURSRJKEksSTBJ3EngS") \ No newline at end of file diff --git a/pr/545/docs/search.index/7ccfc824e9f7.js b/pr/545/docs/search.index/7ccfc824e9f7.js new file mode 100644 index 000000000..5efc2f249 --- /dev/null +++ b/pr/545/docs/search.index/7ccfc824e9f7.js @@ -0,0 +1 @@ +rn_("AYMCoFAAABCPoKAAABK5a3ABAAGwQBIHAAFs9DkJAAABACUHAQABCAD0GxIAAAEAAQABAAEEAbAAEGkAAXMB2g8AAAECAaBQAAASd2MBfQwAALcAAACFsEAMuAABoDAAAAvIlQABOzAAAAEAAAgABACoBAAAcwUCAIAMAQBJDwIAJwEAgIWwMAj4AAGgEAAAEu+wIAdKAAGRAEQBEAD0+xMAAAEAAQABAAEDAPQ5CQAAAQAlBwEAY4ADoAAAAAvIbnJ1AQACsNATMgABoDAAAA9MYmr2VwUAAAEAAQBJAAEAbgEBAAGwgBNRAAF0OzAAAAEAAEEABACgBQAA4wgAAO0IAAA3DD4AAQkA8zsSAAABAAEA84ADY2d0AYMCoJAAABOboJAAABOcMjMBgAKgUAAAE8OggAAAEuxjZfMAAnN08hIHAAABAAEAAaCwAAATNGLzwRIAACIBAQAjgAKgAAAAEsBkciOAAqBQAAATjWNl84ACaXkBBAD1uhAAAAEAAQABAAEA8wEBbgEIBwAAAQEAOzAAAAEAAAkAAgC3BwcAgBIBAAEGAPQmEwAAAQABAAEAAQ8A9AQUAAABAAEAAQDzgQJobQEAAbBAE8cAAWX1jxMAAAEAAQABAAEAU4ADoCAAABFWbG50120AgMugIAAAE/awYBBPAAGwQA+CAAHAGzgK") \ No newline at end of file diff --git a/pr/545/docs/search.index/7da29615b409.js b/pr/545/docs/search.index/7da29615b409.js deleted file mode 100644 index 8fc1be914..000000000 --- a/pr/545/docs/search.index/7da29615b409.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQIA9F8SAAABAI4AAQABAwD0kxIAAAEAkwABAPMFAmJ1OjAAAAEAAAAAAAcAEAAAANoP2w+KEIsQNRE2EWoSaxIBAgD0wRAAAAEAbAEBAAEFAPPHEAAAAQABAAEEAPQIEgAAAQCkAAEA84CEEQkA") \ No newline at end of file diff --git a/pr/545/docs/search.index/7dc6410c642a.js b/pr/545/docs/search.index/7dc6410c642a.js new file mode 100644 index 000000000..781db7b6c --- /dev/null +++ b/pr/545/docs/search.index/7dc6410c642a.js @@ -0,0 +1 @@ +rn_("AQcA9UYTAAABAAEAcwABAAEHAPNIEAAAAQABAAGAAqAAAAAHLKAQAAAI2WR48wEBZfKgDwAAAQDnAAAAhbBgDJYAAbBADA8AATIIAfSqBAAAeAKGCQEA") \ No newline at end of file diff --git a/pr/545/docs/search.index/7e1c6d203546.js b/pr/545/docs/search.index/7e1c6d203546.js deleted file mode 100644 index 8d7bc97db..000000000 --- a/pr/545/docs/search.index/7e1c6d203546.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABoCAAAAxxbQFPBQAAAQAA9EkSAAABAAEAAQDzBAFk9O8RAAABAAEAAQAjhISwoBOEAAGwQBJHAAGwcBMyAAEVgAAzgAOw0BNyAAFhZWk=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7e3b19027434.js b/pr/545/docs/search.index/7e3b19027434.js new file mode 100644 index 000000000..59c6ec1f5 --- /dev/null +++ b/pr/545/docs/search.index/7e3b19027434.js @@ -0,0 +1 @@ +rn_("AQEBoEAAABEFc/XoCwAA8wQ9AQEAAQATggKgIAAADLdlcgECAPRzDwAAAQDtAAEAI4ECoBAAAAvnZWkTgAKg8AAAE41ucjMAA7AwCPUAAWVvdAFSEQAA") \ No newline at end of file diff --git a/pr/545/docs/search.index/7e512354c707.js b/pr/545/docs/search.index/7e512354c707.js deleted file mode 100644 index 352b1739c..000000000 --- a/pr/545/docs/search.index/7e512354c707.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQEAOjAAAAEAAAAAAAgAEAAAAL8Izw9vEHAQcRAvEzATshO3EwECAPQEEAAAAQABAAEAE4ACoNAAABOhY3NTgAOgcAAAE5xlaW+DgISwIBLWAAGgIAAAD0OwAAcPAAEKCAQ=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7e644c6ffb35.js b/pr/545/docs/search.index/7e644c6ffb35.js new file mode 100644 index 000000000..4ba1fce49 --- /dev/null +++ b/pr/545/docs/search.index/7e644c6ffb35.js @@ -0,0 +1 @@ +rn_("AQQA9rUMAAABABkDAQAlAQEAAQoA80ISAAABAKgAAQEA9+4IAAABABIHAQBrAAEADgEjgAKwYBNVAAFpbwECAPR2DAAAAQALBgEAAQUA9GsTAAABAEkAAQD3BAAAh6AgAAAMeLCQEW8AAQScAzowAAABAAAAAAAIABAAAABvBd8I4AgWDBcMfRB+EHMSdBI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7e8f175db68a.js b/pr/545/docs/search.index/7e8f175db68a.js deleted file mode 100644 index 3f9f2a734..000000000 --- a/pr/545/docs/search.index/7e8f175db68a.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQQA9pAMAAABABEDAQAiAQEAAQoA8xESAAABAKgAAQEA99cIAAABAPwGAQBqAAEADAEjgAKwYBMiAAFpbwECAPRSDAAAAQD+BQEAAQUA9DgTAAABAEkAAQD3CAAAiLCQEvIAAaAgAAAMVLCQET8AAQTcAzowAAABAAAAAAAIABAAAABfBcYIxwj2C/cLTxBQEEISQxI=") \ No newline at end of file diff --git a/pr/545/docs/search.index/7ebdb25ba28a.js b/pr/545/docs/search.index/7ebdb25ba28a.js new file mode 100644 index 000000000..0ceddae56 --- /dev/null +++ b/pr/545/docs/search.index/7ebdb25ba28a.js @@ -0,0 +1 @@ +rn_("AQUA9GsTAAABAEkAAQDzBAFj8nMSAAABACOCArBQEkUAAWZ0AQABsAATwAABZPS1CwAAAQABAAEA84ACZWkTgAKw4BPLAAF0dg==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7f63f5f335b2.js b/pr/545/docs/search.index/7f63f5f335b2.js deleted file mode 100644 index 2caef16dc..000000000 --- a/pr/545/docs/search.index/7f63f5f335b2.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQABoDAAAAxYaQGxEgAAAQABsDAQmAABbvIVBwAAAQABAQDzkwcAAHoHAQATAAKgUAAAD/tlc/UsBAAAAQABAAEAAQABhAKwoBNOAAGwoBNQAAFjcvMBAXTzMREAAOMAAQABAwGwYBOYAAFmOzAAAAEAAAYAAwCgCwIAwRIBAEYTAQDzgAJhZfOAhAAoBQ==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7f6612368049.js b/pr/545/docs/search.index/7f6612368049.js new file mode 100644 index 000000000..4be9dcc7f --- /dev/null +++ b/pr/545/docs/search.index/7f6612368049.js @@ -0,0 +1 @@ +rn_("AQkBoEAAABPGZfLmEwAAAQABgAKwAAyTAAGggAAAEzFkcAEDAaAAAAAPv3PyTQ8AAAEAAQIDsGASsQABsNATyQABoIAAABNQaXJzAdQTAAD3AACAhaEwAAAT5ZBJAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/7f8ec9909a99.js b/pr/545/docs/search.index/7f8ec9909a99.js deleted file mode 100644 index 08bc1b269..000000000 --- a/pr/545/docs/search.index/7f8ec9909a99.js +++ /dev/null @@ -1 +0,0 @@ -rn_("AQUAOzAAAAEAAAcAAwAPEQIAthIBAEgTAgABBADzEhEAAAEAAQAjAAKgYAAAEjhhcvM9EAAAAQC5AQGAAqEQAAATzLCAE8QAAWl1NwQAgYexUBPnAAGACM0AF1CwcBMRAAGhMAAAE9sKQBsBAAA7MAAAAQAAhQABAIENhQABAgD22BIAAAEAogBUABYAAQAjgQKgIAAAEFxydvOAAmVvI4ACoCAAABHYZHQBAAA7MAAAAQAA5QAEAJAFAADCB+IAEwwAAL0QAADzgANkbnY=") \ No newline at end of file diff --git a/pr/545/docs/search.index/desc/59e6f7c5fb07.js b/pr/545/docs/search.index/desc/59e6f7c5fb07.js new file mode 100644 index 000000000..499a4a444 --- /dev/null +++ b/pr/545/docs/search.index/desc/59e6f7c5fb07.js @@ -0,0 +1 @@ +rd_("AmData flows in both directions0CdThe CE codepoint, signalling that congestion was \xe2\x80\xa600AjContains the success valueBeThe PathId of this path.BmReturns the PathId of this path.AoGet the identity of this stream00AfWhich path is now openAhWith path was abandoned.B`Which path had its state droppedAmPath which has changed statusCfPath over which the observed address was reported, \xe2\x80\xa6AlWhich stream is now readableAlWhich stream is now writableAnWhich stream has been finishedAmWhich stream has been stoppedAnType of the Long header packetBcExperimental! Use at your own risk.0ClWhether a stream communicates data in both directions or \xe2\x80\xa60AhContains the error valueAoThe largest representable valueAlThe maximum path ID allowed.10ClConnects to a QUIC perf server and maintains a specified \xe2\x80\xa6BmData flows only from the stream\xe2\x80\x99s initiator0AnWhich directions data flows in0CaDirectionality for which streams have been openedCdDirectionality for which streams are newly availableCjExplicit congestion notification bits to set on the packet0CeThe Explicit Congestion Notification bits for the \xe2\x80\xa61CdReturns the most recently observed external address.B`The current best RTT estimation.BfThe number of I/O operations executed.0BcLength of QUIC packet being decodedAlLength of the packet payload0BmThe number of bytes the associated buffer hasBbSet a custom TokenLog0CaMinimum RTT registered so far for this estimator.ClConstruct with an approximate maximum memory usage and a \xe2\x80\xa6CjConstruct an endpoint with arbitrary configuration and \xe2\x80\xa6DiCreates a new QlogConfig that writes a qlog trace to the \xe2\x80\xa6CiCreates a new qlog factory that writes files into the \xe2\x80\xa6D`Create a default config with a particular reset_keyCmCreate a default config with a particular handshake token \xe2\x80\xa6CkCreate a default config with a particular cryptographic \xe2\x80\xa6AmConstruct cid from byte arrayoConstruct emptyAeCreate a new StreamIdDjConstruct a state using the given config and current time \xe2\x80\xa600:8AeCreate a new endpointDcCreate a new instance of FixedLengthConnectionIdParserBdCreate a generator with a random key:987DgBegin decoding a QUIC packet from bytes, returning any \xe2\x80\xa67BkConstruct an error with a code and a reasonCgInitialize Random CID generator with a fixed CID length87BeCreates a new FourTuple.777BfQUIC transport protocol implementationCkGet SystemTime::now() or the mocked equivalentAhLook up the current time01ChCurrent best estimate of this connection\xe2\x80\x99s latency \xe2\x80\xa6000ChThe ECT(0) codepoint, indicating that an endpoint is \xe2\x80\xa600ChThe ECT(1) codepoint, indicating that an endpoint is \xe2\x80\xa600CaA complete set of keys for a certain packet space0CbA Long packet header, as used during the handshakeChNot attributed to any particular FrameType.CkAn open network transmission within a multipath-enabled \xe2\x80\xa6Ab(Multi)Path eventsB`An error occurred during readingCeWhether an endpoint was the initiator of a connection0nThe 0 path id.0CaThe address observed by the remote over this pathCjThe source address of the datagram(s) contained in the \xe2\x80\xa6mType of errorBlCurrent congestion window of the connection.0gPayloadAoReturns the argument unchanged.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BaCalls U::from(self).00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dNextCoMethod for opening a sealed message data in-place.B`Open a single stream if possible1CgReturns the Path structure of an open pathBhPing the remote endpoint over this path.AhPing the remote endpointCkCheck whether the timer has expired, and register to be \xe2\x80\xa6BaReturns application-facing eventsBgRead data contiguously from the stream.AoRead from the given recv streamCcDecode TransportParameters from bufferBiReceive an unreliable, unordered datagramBdMethod for sealing a token in-place.0CiQueue an unreliable, unordered datagram for immediate \xe2\x80\xa6CbSends a Transmit on the given socket.CmNumber of address validation tokens sent to a client when \xe2\x80\xa60BmThe side of the connection (client or server)ChLook up whether we\xe2\x80\x99re the client or server of this \xe2\x80\xa6AlMethod for signing a message0CdAmount of data written to the caller-supplied buffer0hSpin bitAcStop accepting data0BoStop accepting data on the given receive streamCiTry to find and take a token that was stored with the \xe2\x80\xa60BgA chunk of data from the receive stream0CiThe RFC8312 congestion controller, as widely used for TCP0Borustls reports protocol errors using this type.0DbErrors encountered while decoding TransportParametersCdErrors that the nat traversal state might encounter.BeEvents of interest to the applicationCiEvent emitted when the client receives ADD_ADDRESS or \xe2\x80\xa6CjAttributed to a specific FrameType, never \xe2\x80\xa6A`Any other error.0CcThe peer abandoned transmitting data on this streamCnThe peer is unable to continue processing this connection, \xe2\x80\xa6CdThe peer abandoned transmitting data on this stream.1AeA Retry packet headerCdA short packet header, as used during the data phaseCmBest-effort extraction of the ALPN protocols from the TLS \xe2\x80\xa6BiConstruct a fresh Controller0AiThe contents of the chunkCiThe total amount of bytes which have been transferred \xe2\x80\xa6BjThe amount of bytes which had been written210BnUnderlying error describing reason for failureBaClose the connection immediately.CnClose all of this endpoint\xe2\x80\x99s connections immediately and \xe2\x80\xa6AaCloses this path.AnClose a connection immediatelyBcFrame type that triggered the errorCcDistinguishes streams of the same initiator and \xe2\x80\xa60CjReturns whether the codepoint is a CE, signalling that \xe2\x80\xa60AgKey for encrypting data0BgParse a connection id from given bufferAhReturns all known paths.BlUpdate the timer to expire at iBbClose the send stream immediately.BeAbandon transmitting data on a streamCnRespond with a retry packet, requiring the client to retry \xe2\x80\xa60CiDrive future to completion in the backgroundCeShow connection stats the at the end of the benchmarkAmReturns connection statisticsBiReturns relevant stats from this EndpointCaReturns the PathStats for this path.2BcTitle to record in the qlog capture0CmWrite a buffer into this stream, returning how many bytes \xe2\x80\xa6AmSend data on the given streamCcEncode TransportParameters into bufferC`Future produced by Endpoint::acceptClPaths marked as backup will only be used if there are no \xe2\x80\xa6CeChunks returned from RecvStream::read().AmThe initiator of a connectionAdRun as a perf client1CgAttempted to initiate NAT traversal on a closed, or \xe2\x80\xa6BcThe receiver lagged too far behind.CcFuture produced by Connection::open_biAjA new path has been openedChOne or more new streams has been opened and might be \xe2\x80\xa6ChId representing different paths when using multipath \xe2\x80\xa60AbCoding result typeAlThe acceptor of a connectionAdRun as a perf server1mStream eventsAiAn integer less than 2^620CfGet the next incoming connection attempt from a clientClAttempt to accept this incoming connection (an error may \xe2\x80\xa6CcAccept a remotely initiated stream of a certain \xe2\x80\xa61C`The amount of full chunks which had been written0BlAllows to configure the desired cipher suiteCiHelper to construct an endpoint for use with outgoing \xe2\x80\xa6CcWait for the connection to be closed for any reasonAfCoding related traits.BnAccess the configuration used by this endpointChTraits and implementations for the QUIC cryptography \xe2\x80\xa6BjCreate QUIC error code from TLS alert codeBoTLS configuration used for incoming connections210BkAn underlying crypto (e.g. TLS) layer errorCgDecode a plain header from given buffer, with given \xe2\x80\xa6DiDecode a Self from the provided buffer, if the buffer is \xe2\x80\xa6ChThe destination IP address which was encoded in this \xe2\x80\xa6D`Append the encoding of self to the provided buffer.CmNotify the peer that no more data will ever be written to \xe2\x80\xa6CnFinish a send stream, signalling that no more data will be \xe2\x80\xa6B`Process an incoming UDP datagramAfHeader protection keys0ClIgnore this incoming connection attempt, not sending any \xe2\x80\xa60C`Potentially store a token for later one-time use0CfPerform NSS-compatible TLS key logging to the file \xe2\x80\xa6AhThe offset in the stream0B`Packet deliveries were confirmed0AfPacket protection keys0lRandom valueBcHuman-readable reason for the close000BhHuman-readable explanation of the reasonBeReason that the connection was closedBcReason why this path was abandoned.AjSwitch to a new UDP socketBgReject this incoming connection attempt0AgKey for decrypting dataBoReturns the remote address of the network path.1AmTLS interface based on rustls0CnHelper to construct an endpoint for use with both incoming \xe2\x80\xa6BkOptional source IP address for the datagram00CgThe current local PathStatus of this path.B`The new status set by the remoteCfThe size of a single datagram in the associated bufferCkStatistics about datagrams and bytes received on this path.ChStatistics about UDP datagrams received on a connection.10CgStatistics about datagrams and bytes sent on this path.CkStatistics about UDP datagrams transmitted on a connection.10AnMethod for verifying a message0CcNumber of ack-eliciting bytes that may be in flight0A`Send would blockCcNo more data is currently available on this stream.CjThe peer is not able to accept additional data, or the \xe2\x80\xa6BfA catch-all error for unlikely errors.0BlA key for signing with HMAC-based algorithms0AhAn Initial packet headerBnA pair of keys for bidirectional communication0BhA simple, standard congestion controller0CdFuture produced by Connection::open_uniCkAbstracts I/O and timer operations for runtime independenceBfA cryptographic session (commonly TLS)0CcThe peer is no longer accepting data on this streamCfFuture returned from SendStream::stopped.ClThe peer is no longer accepting data on this stream, and \xe2\x80\xa6CkThe peer is no longer accepting data on this stream. No \xe2\x80\xa6CgThe peer asked us to stop sending on an outgoing streamAaAccess to streamsCaThe stream is larger than the user-supplied limitCnAttributed to some frame type this implementation does not \xe2\x80\xa6ClIndicates how many bytes and chunks had been transferred \xe2\x80\xa60l0-RTT packetCjReturns the length of a CID for connections created by \xe2\x80\xa60CdProvide the length of dst_cid in short header packetCcThe total number of clients which should be createdAlConnect to a remote endpointAeInitiate a connectionBbDecrypt the Initial packet payloadCgDecrypt the packet payload with the given packet numberBcDecrypt the given packet\xe2\x80\x99s header210ClConstructs a value with arbitrary fields, intended to be \xe2\x80\xa6DjConstruct an event that indicating that a Connection will \xe2\x80\xa6BkThe destination connection ID of the packetBkThe destination Connection ID of the packetAiDestination Connection ID00000CgEncrypt the packet payload with the given packet numberBcEncrypt the given packet\xe2\x80\x99s header10CbCheck if this stream has been opened during 0-RTT.0CmRetrieve implementation-specific metrics used to populate \xe2\x80\xa60CnThe maximum UDP payload size guaranteed to be supported by \xe2\x80\xa60CjUniform interface to send and receive UDP packets with \xe2\x80\xa6BbOne or more packets were just sent0BmInitiate a new outgoing bidirectional stream.CaReturns the path ID of the new path being opened.AdSource Connection ID0000CiCompletes when the peer stops the stream or reads the \xe2\x80\xa6CjCheck if this stream was stopped, get the reason if it wasCcThe total number of streams which should be createdAlProvide control over streamsCeThe length of the AEAD tag appended to packets on \xe2\x80\xa60CdUpgrade the handle to a full ConnectionB`Upgrades to a Path.AkSet the QUIC version to use0lQUIC versionB`The version that was unsupported11CeFuture produced by Connection::accept_biAfAn unreliable datagramBdDatagram support is disabled locally0A`A QUIC endpoint.BcThe main entry point to the libraryChA finished stream has been fully acknowledged or stoppedCkAn incoming connection for which the server has not yet \xe2\x80\xa60BoLong packet types with uniform header structureB`The largest encoded value length0Cmthe connection is being closed abruptly in the absence of \xe2\x80\xa60CeFuture returned by Connection::on_closedClFuture produced by crate::Connection::open_pathCmA currently open stream likely has data or errors waiting \xe2\x80\xa6CkMetadata for a single buffer filled with bytes received \xe2\x80\xa6BkResponse generated directly by the endpointCfIdentifier for a stream within a particular connection0CnCommunication with the peer has lapsed for longer than the \xe2\x80\xa6CkWe didn\xe2\x80\x99t receive any data from the remote within the \xe2\x80\xa61ChResponsible for limiting clients\xe2\x80\x99 ability to reuse \xe2\x80\xa60ClThe datagram is larger than the connection can currently \xe2\x80\xa60AbAn outgoing packet00CmStatistics about UDP datagrams transmitted or received on \xe2\x80\xa60CnA formerly write-blocked stream might be ready for a write \xe2\x80\xa6AkCongestion algorithm to useAhContents of the datagramBoMark the read data as consumed from the stream.BnStatistics about frames received on this path.CaStatistics about frames received on a connection.10CaStatistics about frames transmitted on this path.CdStatistics about frames transmitted on a connection.10DhConstructs cid by reading len bytes from a Buf0DkCreates a new qlog factory that writes files into QLOGDIR, \xe2\x80\xa60BfCreate a generator with a specific keyBjConstruct a VarInt infallibly0BeSucceeds iff x < 2^620AeWhat type we receivedAoWhat handshake type we received10CbWhether 0-RTT is/was possible during the handshakeCmSpecifies the time to wait after completing MTU discovery \xe2\x80\xa60CcReturns Self for use in down-casting to extract \xe2\x80\xa60EhReturns true if the Connection associated with this handle \xe2\x80\xa6CmDuration after an address validation token was issued for \xe2\x80\xa60CeThe local IP address which was used when the peer \xe2\x80\xa6000BnReturns the local address of the network path.ClCompute the maximum size of datagrams that may be passed \xe2\x80\xa6BnInitiate a new outgoing unidirectional stream.BcGet the priority of the send streamAlGet the priority of a streamCfThe negotiated application protocol, if ALPN is in use0Aeqlog output directoryBbOptional response to transmit backCiOptional seed to be used internally for random number \xe2\x80\xa60AlSlow start threshold (bytes)0BeSucceeds iff x < 2^6200000DaSends a Transmit on the given socket without any \xe2\x80\xa6DkQuickly determine whether cid could have been generated by \xe2\x80\xa600BmA path was abandoned and is no longer usable.CfFuture produced by Connection::accept_uniCdPaths marked with as available will be used when \xe2\x80\xa6CnAt least one new stream of a certain directionality may be \xe2\x80\xa6ClConfiguration for the Bbr congestion controller0BkThe connection was successfully establishedAoAPI to control datagram trafficAlDecoding of QUIC primitives.CkA path was discarded and all remaining state for it has \xe2\x80\xa6BgInfallible encoding of QUIC primitives.CnIdentifies a network path by the combination of remote and \xe2\x80\xa6A`Handshake packetBcKeys used to protect packet headers0CiCatch-all error for problems while decoding transport \xe2\x80\xa6CeNat traversal attempt failed due to a multipath errorBdKeys used to protect packet payloads0BmErrors that might trigger a path being closedAnApplication events about pathsBjStatistics related to a transmission path.0AeA read error occurredBmErrors that arise from reading from a stream.C`Errors triggered when reading from a recv streamCiAn object for asynchronously writing to an associated \xe2\x80\xa6BmAccept the next incoming bidirectional streamBbDuplicate the controller\xe2\x80\x99s state0BeThe number of UDP datagrams observed.AaControl datagrams1BeCreate new object from the given bits00BoWhich side of a connection initiated the stream0CmConvert into a 0-RTT or 0.5-RTT connection at the cost of \xe2\x80\xa6BoShorthand for self == Side::Client0B`Whether the connection is closedBoShorthand for self == Side::Server0CbWhether it is legal to respond with a retry packet0CdWhether to allow clients to migrate to new addresses0CdConstruct a timer that will expire at iBoLow-level protocol logic for the QUIC protoocolCjWait for the connection to be closed without keeping a \xe2\x80\xa6CjOpens an additional path if the multipath extension is \xe2\x80\xa6A`Opens a new pathBmPing the remote endpoint over a specific pathCiAttempts to read from the stream into the provided bufferCeReceive UDP datagrams, or register to be woken if \xe2\x80\xa6CkSend a UDP datagram, or register to be woken if sending \xe2\x80\xa6ClPrivate key used to send authenticated connection resets \xe2\x80\xa60BmGenerate the integrity tag for a retry packet0BgA stable identifier for this connectionCePrivate key used to authenticate data included in \xe2\x80\xa60BlThe position of a token in the packet bufferCgTransport configuration to use for incoming connections0CjWait for all connections on the endpoint to be cleanly \xe2\x80\xa6BoWrite a buffer into this stream in its entiretyCiAbstract implementation of an async timer for runtime \xe2\x80\xa6BoNumber of UDP packets to send/receive at a timeCkError indicating that a path has not been opened or has \xe2\x80\xa6BnThe path is already closed or was never opened1BeIn-progress connection attempt futureAbA QUIC connection.CeProtocol state and logic for a single QUIC connectionCeCommon interface for different congestion controllers0CjNumber of frames transmitted or received of each frame \xe2\x80\xa60BoThe connection ID was not recognized by the \xe2\x80\xa60DdThe type used to refer to FrameTypes in closing and \xe2\x80\xa6DbA stream of PathEvents for all paths in a connection.AnThe QUIC-MULTIPATH path statusBeConfiguration for qlog trace logging.0BnA stream that can only be used to receive dataAaAccess to streamsChErrors that arise while waiting for a stream to be resetDhError for attempting to retry an Incoming which already \xe2\x80\xa60BkA stream that can only be used to send data3BmObject to get current SystemTime0AdA rustls TLS session0CkResponsible for storing validation tokens received from \xe2\x80\xa60AeA borrowed UDP socketBjErrors that arise from writing to a streamBoErrors triggered while writing to a send streamBoAccept the next incoming uni-directional streamCkWhether the implementation is permitted to set the spin \xe2\x80\xa60CiCloses a path and sends a PATH_ABANDON frame with the \xe2\x80\xa6CdLogic for controlling the rate at which data is sent0BfWhether to print connection statisticsBnClass of error as encoded in the specificationB`Application-specific reason code10CaThe error code to be sent with the abandon frame.BoThe error that was sent with the abandon frame.AoError code supplied by the peerBcType of frame that caused the close0AiExtract the integer value0CnWhether there is no longer any need to keep the connection \xe2\x80\xa6DkDetermine whether this is the last event a Connection will \xe2\x80\xa6CiLook up the local IP address and port used by this socketDgGet the local SocketAddr the underlying socket is bound toBfThe amount of bytes lost on this path.0CjPad UDP datagrams carrying application data to current \xe2\x80\xa60AgReturns path statistics0CjThe final path stats, they are no longer available via \xe2\x80\xa6C`Attempt to write bytes from buf into the stream.AmRead the next segment of dataAoReads the next segment of data.CkRead an exact number of bytes contiguously from the stream.BnSets the PathStatus of this path.BoEpoch qlog event times are recorded relative to0ClError type for attempting to accept an IncomingBjErrors in the configuration of an endpoint0AeGeneric crypto errors0CnConfiguration for the Cubic congestion controller0CdReasons why attempting to finish a stream might failCnMaximum duration of inactivity to accept before timing out \xe2\x80\xa60AnValue exceeds supported bounds0D`Constructs a QlogConfig for individual connections.0AfA noq runtime for smolB`Application events about streamsCbAccept this incoming connection using a custom \xe2\x80\xa6CeLargest UDP payload size the path currently supports.ClStorage size required for the largest packet that can be \xe2\x80\xa61BiDescription to record in the qlog capture0BjThe socket this datagram should be sent to00DcCreates a new FourTuple without a known local address.BkStarting guess for maximum UDP payload sizeCkThe initial value to be used as the maximum UDP payload \xe2\x80\xa60ChUDP payload size that the network must be capable of \xe2\x80\xa6BjThe RTT used before an RTT sample is taken0BfThe initial round-trip-time (in msecs)CeThe amount of concurrent streams which should be usedDdPackets are acked in batches, all with the same now \xe2\x80\xa60AdPacing rate (bits/s)0DeA stream of PathEvents for all paths in this connection.DfGets the local PathStatus for a known PathIdAnRead the next segments of dataCkConvenience method to read all remaining data into a bufferAlProvide control over streamsBoThe sample size used for this key\xe2\x80\x99s algorithm01CiMaximum number of bytes to transmit to a peer without \xe2\x80\xa600BoThe server name specified by the client, if any0BmObject to get current SystemTime0BdSet a custom TokenStore0CaNumber of bytes to transmit from client to serverCnSpecifies the upper bound to the max UDP payload size that \xe2\x80\xa60ChReturns a weak reference to the inner connection struct.CdReturns a WeakPathHandle for this path.DgCreate a server config with the given crypto::ServerConfig0CeSets a prefix to the filename of the generated files.0DbWrite a single Bytes into this stream in its entiretyBbAn ADD_ADDRESS frame was received.BfConfiguration for outgoing connectionsCaClient-side configuration for the crypto protocol10CgThe stream has already been stopped, finished, or resetBmThe stream has already been finished or resetCmError indicating that a stream has not been opened or has \xe2\x80\xa6CjThe stream has not been opened or was already stopped, \xe2\x80\xa6CfThe stream has not been opened or has already been \xe2\x80\xa6CmThe stream has not been opened or was already finished or \xe2\x80\xa63CgErrors in the parameters being used to create a new \xe2\x80\xa60BkProtocol-level identifier for a connection.0CkWe couldn\xe2\x80\x99t decrypt a message. This is invariably fatal.0BjExplicit congestion notification codepoint00CnWe couldn\xe2\x80\x99t encrypt a message because it was larger than \xe2\x80\xa60BhParameters that are semantically invalidCkCannot close the last remaining open path via the local \xe2\x80\xa6Akn0\xe2\x80\x99s nat traversal eventsDhNull implementation of TokenLog, which never accepts tokens0ClReceived an observation of our external address from the \xe2\x80\xa6CiFuture produced by Connection::read_datagramBiThe remote changed the status of the pathBlRTT estimation for a particular network pathCnFuture produced by Connection::send_datagram_waitBiParameters governing incoming connectionsCaServer-side configuration for the crypto protocol10CmErrors that arise while monitoring for a send stream stop \xe2\x80\xa6AgA noq runtime for TokioC`Returns the lifetime of generated Connection IDs0BlIf the connection is closed, the reason why.CjConnect to a remote endpoint using a custom configuration.AlConservative estimate of RTTBnGet the 0-RTT keys if available (clients only)0AgWhich types we expectedB`Which handshake type we expected10AcGenerates a new CID0ClThe number of segments to read when GRO is enabled. Used \xe2\x80\xa6DeProcess ConnectionEvents generated by the associated \xe2\x80\xa6EaProcess EndpointEvents emitted from related ConnectionsCgCreate the initial set of keys given the client\xe2\x80\x99s \xe2\x80\xa6000BhThe amount of packets lost on this path.0DcMaximum number of Incoming to allow to exist at a time0CjWhether datagrams might get fragmented into multiple parts0CmWhether transmitted datagrams might get fragmented by the \xe2\x80\xa6CkReturns the path\xe2\x80\x99s network path represented as a 4-tuple.CkThe original destination CID when initiating the connectionCiThe original destination connection ID sent by the clientDhReturns the next time at which handle_timeout should be \xe2\x80\xa6D`Configures qlog capturing by setting a QlogFactory.0AgThe runtime type to useCkThe segment size if this transmission contains multiple \xe2\x80\xa600ChThe number of streams that may have unacknowledged data.CbSet the lifetime of CIDs created by this generator0BcSet the priority of the send streamAlSet the priority of a streamCnInitialize a QUIC-compatible TLS client configuration with \xe2\x80\xa6000DgWrite a slice of Bytes into this stream, returning how \xe2\x80\xa6AmSend data on the given streamCkWe received a fatal alert. This means the peer is unhappy.0BhBloom filter-based TokenLog0CmThe connection could not be created because not enough of \xe2\x80\xa6000CaEvent resulting from processing a single datagramBlEvents sent from a Connection to an EndpointAoStatistics on Endpoint activityBnThe stream finished before all bytes were readBlAuthentication data for (rustls) TLS session0Ccreceived an invalid Retry Token in a client Initial0ChIterator over ALPN protocol names from a TLS ClientHelloAlThe packet header is invalidBkThe local application closed the connection0DaThe datagram may result in starting a new ConnectionD`Configuration for the NewReno congestion controller0BjDecodes a QUIC packet\xe2\x80\x99s invariant headerCgErrors triggered when opening a recv stream for readingCaDefault implementation of TimeSource0CgError indicating that the provided buffer was too smallChFor clients, if the peer accepted the 0-RTT data packetsAbAck Frequency modeAfExports for benchmarksBoSupply a custom connection ID generator factory0DgCreate a UdpSender that can register a single task for \xe2\x80\xa6CaNumber of bytes to transmit from server to clientAmGet the Incoming0CnThe max_ack_delay we will request the peer to use0CgDisable packet encryption/decryption (for debugging \xe2\x80\xa6CkThe known MTU for the current network path has been updated0BbCryptographic identity of the peerBgGet the peer\xe2\x80\x99s identity, if availableDhFor the rustls TlsSession, the Any type is \xe2\x80\xa610CnAttempts to read from the stream into the provided buffer, \xe2\x80\xa6AkReturns packets to transmitDjConfigures qlog capturing through the QLOGDIR environment \xe2\x80\xa60AoReceive an application datagramDfTransmit data as an unreliable, unordered application \xe2\x80\xa6CmWhether to implement fair queuing for send streams having \xe2\x80\xa60BfLength of sign\xe2\x80\x99s output0BnStart a client session with this configurationBnStart a server session with this configuration10BdA REMOVE_ADDRESS frame was received.CgAbstract implementation of a UDP socket for runtime \xe2\x80\xa6BgErrors triggered when abandoning a pathAgThe connection was lost00000ChGlobal configuration for the endpoint, affecting all \xe2\x80\xa60Cithe endpoint encountered an internal error and cannot \xe2\x80\xa60FbBasic adapter to let Incoming be await-ed like a ConnectingBhEncounter a frame ID that was not valid.CeThe peer sent us a TLS message with invalid contents.0Amno viable network path exists0DhNull implementation of TokenStore, which does not store \xe2\x80\xa60CiThe peer deviated from the standard TLS protocol. The \xe2\x80\xa60BmErrors that arise from reading from a stream.C`Errors from RecvStream::read_to_endCaIndicates whether a frame needs to be transmittedCmThe peer violated the QUIC specification as understood by \xe2\x80\xa60CiTransport-level errors occur when a peer violates the \xe2\x80\xa6C`Tokio-compatible UDP socket with some useful \xe2\x80\xa6DiWeak handle for a Path that does not keep the connection \xe2\x80\xa6BnCreate a client endpoint and client connectionAgGet a session referenceDiReturns a QlogConfig for a connection, if logging should \xe2\x80\xa60AiProcess timer expirationsBjParameters negotiated during the handshake0CfGet data negotiated during the handshake, if available0AiInitial congestion windowCiDefault limit on the amount of outstanding data in bytes.001000BnConverts this stream into an unordered stream.DdReturns true until the connection is fully established.CeWhether the connection is in the process of being \xe2\x80\xa61BfVerify the integrity of a retry packet0CnSpecifies the minimum MTU change to stop the MTU discovery \xe2\x80\xa60BdCompute keys for the next key update0BkConfigures qlog capturing into a directory.0AlRead bytes of handshake data0BeWhether to use the unordered read APIClMaximum number of bytes the peer may transmit across all \xe2\x80\xa600CkCompletes when the stream has been reset by the peer or \xe2\x80\xa60CiCheck whether this stream has been reset by the peer, \xe2\x80\xa6AjThe peer\xe2\x80\x99s UDP addressesAhThe peer\xe2\x80\x99s UDP address0BgThe peer\xe2\x80\x99s UDP address for this path.1CeSaturating integer addition. Computes self + rhs, \xe2\x80\xa6000ChSaturating integer subtraction. Computes self - rhs, \xe2\x80\xa60CkMaximum reordering in time space before time based loss \xe2\x80\xa60ChReason given by the transport for closing the connection0BfReasons why a connection might be lost0CiThe datagram is redirected to its ConnectionBlEvents sent from an Endpoint to a ConnectionAfConnection statistics.0BiStatistics for the currently open streamsAcPlain packet headerBkEnables writing qlog traces to a directory.0AkThe remote closed the path.CfError for when a validation token may have been reused0C`Parameters governing the core QUIC state machine0CbThe peer doesn\xe2\x80\x99t implement any supported version0CdFuture that completes when a connection is fully \xe2\x80\xa6CbThis was a 0-RTT stream and the server rejected it000CjAutomatically select an appropriate runtime from those \xe2\x80\xa6CkWhether to accept QUIC packets containing any value for \xe2\x80\xa60CdMaximum number of incoming packets that may fail \xe2\x80\xa60CnThe interface index of the interface on which the datagram \xe2\x80\xa6AjSwitch to a new UDP socketCiCreates a server endpoint which runs on the given runtimeD`Sets the PathStatus for a known PathIdCfSee proto::TransportConfig::send_window()BoSee TransportConfig::send_window()BmReturns whether a frame should be transmittedD`Convert t into the socket type used by this runtimeCdWrites handshake bytes into the given buffer and \xe2\x80\xa60ClStream produced by Path::observed_external_addrCiReason given by an application for closing the connection0CbThe peer\xe2\x80\x99s QUIC stack aborted the connection \xe2\x80\xa60DjInternal identifier for a Connection currently associated \xe2\x80\xa6CdOne or more application datagrams have been receivedBjDecrypted payload of a QUIC Initial packetCaThe endpoint can no longer create new connections0Cnreceived a STREAM frame or a RESET_STREAM frame containing \xe2\x80\xa60ClSpecific failure cases from keys_match or a \xe2\x80\xa60A`key update error0CaCurrent limits do not allow us to open more pathsClThe peer doesn\xe2\x80\x99t support a protocol version/feature we \xe2\x80\xa60BjA QUIC-compatible TLS client configuration0BjA QUIC-compatible TLS server configuration0EfTokenStore implementation that stores up to N tokens per \xe2\x80\xa60CgAn endpoint (local or remote) tried to add too many \xe2\x80\xa6CmWe didn\xe2\x80\x99t receive a path response in time after opening \xe2\x80\xa6CaPath could not be validated and will be abandonedBcA Version Negotiation packet headerCiRecord that the token was used and, ideally, return a \xe2\x80\xa60CjCurrent state of the congestion control algorithm, for \xe2\x80\xa6CcCurrent state of this connection\xe2\x80\x99s congestion \xe2\x80\xa6BaUpdate traffic keys spontaneously0CnThe maximum amount of segments which can be transmitted if \xe2\x80\xa6CnMaximum duration of inactivity to accept before timing out \xe2\x80\xa60Cgn0\xe2\x80\x99s (https://n0.computer) NAT Traversal protocol \xe2\x80\xa6CeGet the number of connections that are currently openBmNumber of connections that are currently openCiOpens a new path if no path exists yet for the remote \xe2\x80\xa6CmOpens a new path only if no path on the same network path \xe2\x80\xa6CiMaximum reordering in packet number space before FACK \xe2\x80\xa60CfGet the size of the socket receive bufferAlReceive buffer size in bytesCcGet the size of the socket send bufferAiSend buffer size in bytesBiSet a custom TransportConfig000ChConfiguration for sending and handling validation tokens0CnCreate a server config with the given certificate chain to \xe2\x80\xa60DdWrite a slice of Bytes into this stream in its entiretyCfthe application or application protocol caused the \xe2\x80\xa60AnThe peer closed the connectionBoThe path was closed locally by the application.1B`Constructs controllers on demand0BdCommon congestion controller metrics0ClThe trait for encrypting tokens that power retry packets \xe2\x80\xa60BcThe given server name was malformed0CbHints when the caller identifies a network change.0AcPacket decode errorBdReason for why a path was abandoned.BmErrors that can arise when sending a datagram0CcThe peer does not support receiving datagram frames0BdCongestion events on the connection.0AiCongestion window (bytes)0ClCompute the maximum size of datagrams that may be passed \xe2\x80\xa6BoBytes available in the outgoing datagram bufferClReplace the server configuration, affecting new incoming \xe2\x80\xa60Cmthe endpoint has reached the confidentiality or integrity \xe2\x80\xa60CkParameters for controlling the peer\xe2\x80\x99s acknowledgement \xe2\x80\xa60DjThe max_fragment_size value supplied in configuration was \xe2\x80\xa60Bmthe server refused to accept a new connection0BjParse connection id in short header packetCjOne or more application datagrams have been sent after \xe2\x80\xa6Ckreceived more data than permitted in advertised data limits0AoThe TLS handshake was confirmedBjThe connection\xe2\x80\x99s handshake data is readyCeAttempted an ordered read following an unordered readAnWe saw an invalid certificate.0BcParameters governing MTU discovery.0BnNot enough addresses to complete the operationCkdetected an error with protocol compliance that was not \xe2\x80\xa60Cjreceived a frame for a stream identifier that exceeded \xe2\x80\xa60Cnreceived a frame for a stream that was not in a state that \xe2\x80\xa60AnError from setting path statusAjTransport-level error code0ChThe local endpoint does not support the QUIC version \xe2\x80\xa6CkError indicating that the specified QUIC version is not \xe2\x80\xa61C`Packet uses a QUIC version that is not supported1CiMaximum quantity of out-of-order crypto layer data to \xe2\x80\xa60C`Create a VarInt without ensuring it\xe2\x80\x99s in range0ChCumulative number of Quic handshakes ignored on this \xe2\x80\xa6EgReturns true if the two WeakConnectionHandle point at the \xe2\x80\xa6CiMinimum interval between outgoing stateless reset packets0CjConstruct with an approximate maximum memory usage and \xe2\x80\xa60ChCumulative number of Quic handshakes refused on this \xe2\x80\xa6AnReturns the remote path statusDfTransmit data as an unreliable, unordered application \xe2\x80\xa6CnUpdates the set of ALPN protocols configured in the client \xe2\x80\xa6CnUpdates the set of ALPN protocols configured in the server \xe2\x80\xa610CiSee proto::TransportConfig::receive_window()CbSee TransportConfig::receive_window()B`Override supported QUIC versions0CiOverride the instant relative to which all events are \xe2\x80\xa60CcA stream of NAT traversal updates for a connection.BkNo remote CIDs available to open a new pathCkTransport parameters used to negotiate connection-level \xe2\x80\xa6CgA stream that can be used to receive data out-of-order.CmThe certificate verifier doesn\xe2\x80\x99t support the given type \xe2\x80\xa60CfThe operation is not allowed for this endpoint\xe2\x80\x99s \xe2\x80\xa6CiCumulative number of Quic handshakes accepted by this \xe2\x80\xa6CjSpecifies the amount of time that MTU discovery should \xe2\x80\xa60CiIf the 0-RTT-encrypted data has been accepted by the peer0BgWait for the handshake to be confirmed.CgInform the connection if a path may recover after a \xe2\x80\xa60CgPeriod of inactivity before sending a keep-alive packet0CfThe number of PLPMTUD probe packets lost on this path.0BlPackets were deemed lost or marked congested0CgCumulative number of Quic handshakes sent from this \xe2\x80\xa6CnThe number of remotely initiated open streams of a certain \xe2\x80\xa6AhBench fns for SendBufferCfThe number of PLPMTUD probe packets sent on this path.0Bireceived a frame that was badly formatted0CkThis function doesn\xe2\x80\x99t work until the TLS handshake is \xe2\x80\xa60CkWe received a TLS message that isn\xe2\x80\x99t valid right now. \xe2\x80\xa60CiThe remote SocketAddr supplied was malformedCkThe remote address for the path is not supported by the \xe2\x80\xa61ChThe initial cipher suite (AES-128-GCM-SHA256) is not \xe2\x80\xa60CnWatches the external address reported by the peer for this \xe2\x80\xa6BdPaths can only be opened client-sideDmError returned when constructing a VarInt from a value >= \xe2\x80\xa60CeA handle to some connection internals, use with care.DkSpecifies the ACK frequency config (see AckFrequencyConfig \xe2\x80\xa60CjThe number of times a black hole was detected in the path.0CgMaximum number of received bytes to buffer for each \xe2\x80\xa60AeIs multipath enabled?ClMaximum number of datagrams that might be described by a \xe2\x80\xa60CkMaximum UDP payload size accepted from peers (excluding \xe2\x80\xa60AmMax UDP payload size in bytesDkSpecifies the MTU discovery config (see MtuDiscoveryConfig \xe2\x80\xa60AmReturn endpoint-facing eventsCkThe preferred IPv4 address that will be communicated to \xe2\x80\xa60CkThe preferred IPv6 address that will be communicated to \xe2\x80\xa60ChThe reordering threshold we will request the peer to use0ClDuration after a retry token was issued for which it\xe2\x80\x99s \xe2\x80\xa60BmSets the max idle timeout for a specific pathDfResize the receive buffer of socket to bytesDcResize the send buffer of socket to bytesBfThe peer\xe2\x80\x99s QUIC transport parametersBdQUIC connection transport parameters1CaGenerates connection IDs for incoming connections0CdAn incoming connection did not support any known \xe2\x80\xa60BjNo default client configuration was set up0BiPath abandoned due to unstable interfaces0ClConfiguration for sending and handling validation tokens \xe2\x80\xa60CmMaximum number of packets that may be sent using a single \xe2\x80\xa60CiNotify connections that the local network address has \xe2\x80\xa6ChHandle a change in the local address, i.e. an active \xe2\x80\xa6CiCounter for the number of bytes currently used in the \xe2\x80\xa6CgReturns whether we think the other address probably \xe2\x80\xa6CkReduction in congestion window when a new loss event is \xe2\x80\xa60DdMaximum number of datagrams that a Transmit may encode.0CfA stream of NAT traversal updates for this connection.CjGet the address observed by the remote over the given pathCiMaximum number of bytes the peer may transmit without \xe2\x80\xa600Chreceived more data in CRYPTO frames than can be buffered0B`The extension was not negotiatedCbWe failed to figure out what time it currently is.0CbWe failed to acquire random bytes from the system.0CnError indicating that this operation requires multipath to \xe2\x80\xa6BnThe extension was not negotiated with the peerAkMultipath is not negotiatedCnError when the multipath extension was not negotiated, but \xe2\x80\xa6CjThe path was opened in a NAT traversal round which was \xe2\x80\xa6BnHeader of an Initial packet, before decryptionCgDerive keying material from this connection\xe2\x80\x99s TLS \xe2\x80\xa6EdFill output with output.len() bytes of keying material \xe2\x80\xa60BnPathological case: many segments, get from endCfGet segments in the old way, using a loop of get callsClCurrent number of remotely initiated streams that may be \xe2\x80\xa6ClTrack changes on our external address as reported by the \xe2\x80\xa60CmCreate a client configuration that trusts specified trust \xe2\x80\xa60BkThe peer didn\xe2\x80\x99t give us any certificates.0BkThe peer sent an oversized record/fragment.0CkThe ack-eliciting threshold we will request the peer to use0BiWhether there are any pending retransmitsCdWhether the Multipath for QUIC extension is enabled.C`Sets the keep_alive_interval for a specific pathBoSet a custom ValidationTokenConfig0BmPath abandoned at the application\xe2\x80\x99s request0CjGet the current value of max_udp_payload_size0ChConfigure how to populate the destination CID of the \xe2\x80\xa60CjConstruct an endpoint with arbitrary configuration and \xe2\x80\xa6CfWhether the socket address that is initiating this \xe2\x80\xa60CmModify the number of open paths allowed when multipath is \xe2\x80\xa6Cmthe number of connection IDs provided by the peer exceeds \xe2\x80\xa60CbError returned by Session::export_keying_material.0CiA provided certificate revocation list (CRL) was invalid.0CmPath abandoned due to no available connection IDs for the \xe2\x80\xa60Clreceived transport parameters that were badly formatted, \xe2\x80\xa60CiRegisters one address at which this endpoint might be \xe2\x80\xa6ClAdd addresses the local endpoint considers are reachable \xe2\x80\xa6ClMaximum number of outgoing application datagram bytes to \xe2\x80\xa60CiSet the client configuration used by connectBnSets the max_idle_timeout for a specific path.BfThe QUIC protocol version implemented.CfThe path became unusable after a local network change.BoBytes available in the outgoing datagram bufferDhMaximum number of received bytes to buffer for all Incoming0DaVariant of max_concurrent_bidi_streams affecting \xe2\x80\xa60ClModify the number of remotely initiated streams that may \xe2\x80\xa6CnCreate a client configuration that trusts the platform\xe2\x80\x99s \xe2\x80\xa60CkGenerates 8-byte connection IDs that can be efficiently \xe2\x80\xa6CkAn error occurred while handling Encrypted Client Hello \xe2\x80\xa60CkPath abandoned due to resource limitations in the transport0CiGenerates purely random connection IDs of a specified \xe2\x80\xa6ChWhether to use \xe2\x80\x9cGeneric Segmentation Offload\xe2\x80\x9d to \xe2\x80\xa60CmMaximum number of incoming bidirectional streams that may \xe2\x80\xa60BhUpdates this tuple\xe2\x80\x99s local address iffClMaximum number of incoming application datagram bytes to \xe2\x80\xa60BcInitiates a new nat traversal round0BdPackets were incorrectly deemed lost0CnRemoves one or more addresses from the set of addresses at \xe2\x80\xa6CgRemoves an address the endpoing no longer considers \xe2\x80\xa6C`Sets the keep_alive_interval for a specific pathDeA ConnectionIdParser implementation that assumes the \xe2\x80\xa6CjWe received a TLS handshake message that isn\xe2\x80\x99t valid \xe2\x80\xa60CiHow to construct new congestion::Controllers0BlSets a default per-path maximum idle timeout0BoThe key exchange group negotiated with the peer0CbWhether to send observed address reports to peers.0CiModify the number of remotely initiated bidirectional \xe2\x80\xa6BiEnables the Multipath Extension for QUIC.0CjModify the number of remotely initiated unidirectional \xe2\x80\xa6CeNumber of consecutive PTOs after which network is \xe2\x80\xa60BkSets a default per-path keep alive interval0CjWhether to receive observed address reports from other \xe2\x80\xa60BmGet the current local nat traversal addresses0CkGet the currently advertised nat traversal addresses by \xe2\x80\xa60AcNat traversal draftCkSets the maximum number of nat traversal addresses this \xe2\x80\xa60CjWhen multipath is required and has not been explicitly \xe2\x80\xa6") \ No newline at end of file diff --git a/pr/545/docs/search.index/desc/e33c984a3e69.js b/pr/545/docs/search.index/desc/e33c984a3e69.js deleted file mode 100644 index 5a5334aaa..000000000 --- a/pr/545/docs/search.index/desc/e33c984a3e69.js +++ /dev/null @@ -1 +0,0 @@ -rd_("AmData flows in both directions0CdThe CE codepoint, signalling that congestion was \xe2\x80\xa600AjContains the success valueBeThe PathId of this path.BmReturns the PathId of this path.AoGet the identity of this stream00AfWhich path is now openAhWith path was abandoned.B`Which path had its state droppedAmPath which has changed statusCfPath over which the observed address was reported, \xe2\x80\xa6AlWhich stream is now readableAlWhich stream is now writableAnWhich stream has been finishedAmWhich stream has been stoppedAnType of the Long header packetBcExperimental! Use at your own risk.0ClWhether a stream communicates data in both directions or \xe2\x80\xa60AhContains the error valueAoThe largest representable valueAlThe maximum path ID allowed.10ClConnects to a QUIC perf server and maintains a specified \xe2\x80\xa6BmData flows only from the stream\xe2\x80\x99s initiator0AnWhich directions data flows in0CaDirectionality for which streams have been openedCdDirectionality for which streams are newly availableCjExplicit congestion notification bits to set on the packet0CeThe Explicit Congestion Notification bits for the \xe2\x80\xa61B`The current best RTT estimation.BfThe number of I/O operations executed.0BcLength of QUIC packet being decodedAlLength of the packet payload0BmThe number of bytes the associated buffer hasBbSet a custom TokenLog0CaMinimum RTT registered so far for this estimator.ClConstruct with an approximate maximum memory usage and a \xe2\x80\xa6CjConstruct an endpoint with arbitrary configuration and \xe2\x80\xa6DiCreates a new QlogConfig that writes a qlog trace to the \xe2\x80\xa6CiCreates a new qlog factory that writes files into the \xe2\x80\xa6D`Create a default config with a particular reset_keyCmCreate a default config with a particular handshake token \xe2\x80\xa6CkCreate a default config with a particular cryptographic \xe2\x80\xa6AmConstruct cid from byte arrayoConstruct emptyAeCreate a new StreamIdDjConstruct a state using the given config and current time \xe2\x80\xa600:8AeCreate a new endpointDcCreate a new instance of FixedLengthConnectionIdParserBdCreate a generator with a random key:987DgBegin decoding a QUIC packet from bytes, returning any \xe2\x80\xa67BkConstruct an error with a code and a reasonCgInitialize Random CID generator with a fixed CID length87BeCreates a new FourTuple.777BfQUIC transport protocol implementationCkGet SystemTime::now() or the mocked equivalentAhLook up the current time01ChCurrent best estimate of this connection\xe2\x80\x99s latency \xe2\x80\xa6000ChThe ECT(0) codepoint, indicating that an endpoint is \xe2\x80\xa600ChThe ECT(1) codepoint, indicating that an endpoint is \xe2\x80\xa600CaA complete set of keys for a certain packet space0CbA Long packet header, as used during the handshakeChNot attributed to any particular FrameType.CkAn open network transmission within a multipath-enabled \xe2\x80\xa6Ab(Multi)Path eventsB`An error occurred during readingCeWhether an endpoint was the initiator of a connection0nThe 0 path id.0CaThe address observed by the remote over this pathCjThe source address of the datagram(s) contained in the \xe2\x80\xa6mType of errorBlCurrent congestion window of the connection.0gPayloadAoReturns the argument unchanged.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BaCalls U::from(self).0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dNextCoMethod for opening a sealed message data in-place.B`Open a single stream if possible1CgReturns the Path structure of an open pathBhPing the remote endpoint over this path.AhPing the remote endpointCkCheck whether the timer has expired, and register to be \xe2\x80\xa6BaReturns application-facing eventsBgRead data contiguously from the stream.AoRead from the given recv streamCcDecode TransportParameters from bufferBiReceive an unreliable, unordered datagramBdMethod for sealing a token in-place.0CiQueue an unreliable, unordered datagram for immediate \xe2\x80\xa6CbSends a Transmit on the given socket.CmNumber of address validation tokens sent to a client when \xe2\x80\xa60BmThe side of the connection (client or server)ChLook up whether we\xe2\x80\x99re the client or server of this \xe2\x80\xa6AlMethod for signing a message0CdAmount of data written to the caller-supplied buffer0hSpin bitAcStop accepting data0BoStop accepting data on the given receive streamCiTry to find and take a token that was stored with the \xe2\x80\xa60BgA chunk of data from the receive stream0CiThe RFC8312 congestion controller, as widely used for TCP0Borustls reports protocol errors using this type.0DbErrors encountered while decoding TransportParametersCdErrors that the nat traversal state might encounter.BeEvents of interest to the applicationCiEvent emitted when the client receives ADD_ADDRESS or \xe2\x80\xa6CjAttributed to a specific FrameType, never \xe2\x80\xa6A`Any other error.0CcThe peer abandoned transmitting data on this streamCnThe peer is unable to continue processing this connection, \xe2\x80\xa6CdThe peer abandoned transmitting data on this stream.1AeA Retry packet headerCdA short packet header, as used during the data phaseCmBest-effort extraction of the ALPN protocols from the TLS \xe2\x80\xa6BiConstruct a fresh Controller0AiThe contents of the chunkCiThe total amount of bytes which have been transferred \xe2\x80\xa6BjThe amount of bytes which had been written210BnUnderlying error describing reason for failureBaClose the connection immediately.CnClose all of this endpoint\xe2\x80\x99s connections immediately and \xe2\x80\xa6AaCloses this path.AnClose a connection immediatelyBcFrame type that triggered the errorCcDistinguishes streams of the same initiator and \xe2\x80\xa60CjReturns whether the codepoint is a CE, signalling that \xe2\x80\xa60AgKey for encrypting data0BgParse a connection id from given bufferAhReturns all known paths.BlUpdate the timer to expire at iBbClose the send stream immediately.BeAbandon transmitting data on a streamCnRespond with a retry packet, requiring the client to retry \xe2\x80\xa60CiDrive future to completion in the backgroundCeShow connection stats the at the end of the benchmarkAmReturns connection statisticsBiReturns relevant stats from this EndpointCaReturns the PathStats for this path.2BcTitle to record in the qlog capture0CmWrite a buffer into this stream, returning how many bytes \xe2\x80\xa6AmSend data on the given streamCcEncode TransportParameters into bufferC`Future produced by Endpoint::acceptClPaths marked as backup will only be used if there are no \xe2\x80\xa6CeChunks returned from RecvStream::read().AmThe initiator of a connectionAdRun as a perf client1CgAttempted to initiate NAT traversal on a closed, or \xe2\x80\xa6CcFuture produced by Connection::open_biAjA new path has been openedChOne or more new streams has been opened and might be \xe2\x80\xa6ChId representing different paths when using multipath \xe2\x80\xa60AbCoding result typeAlThe acceptor of a connectionAdRun as a perf server1mStream eventsAiAn integer less than 2^620CfGet the next incoming connection attempt from a clientClAttempt to accept this incoming connection (an error may \xe2\x80\xa6CcAccept a remotely initiated stream of a certain \xe2\x80\xa61C`The amount of full chunks which had been written0BlAllows to configure the desired cipher suiteCiHelper to construct an endpoint for use with outgoing \xe2\x80\xa6CcWait for the connection to be closed for any reasonAfCoding related traits.BnAccess the configuration used by this endpointChTraits and implementations for the QUIC cryptography \xe2\x80\xa6BjCreate QUIC error code from TLS alert codeBoTLS configuration used for incoming connections210BkAn underlying crypto (e.g. TLS) layer errorCgDecode a plain header from given buffer, with given \xe2\x80\xa6DiDecode a Self from the provided buffer, if the buffer is \xe2\x80\xa6ChThe destination IP address which was encoded in this \xe2\x80\xa6D`Append the encoding of self to the provided buffer.CmNotify the peer that no more data will ever be written to \xe2\x80\xa6CnFinish a send stream, signalling that no more data will be \xe2\x80\xa6B`Process an incoming UDP datagramAfHeader protection keys0ClIgnore this incoming connection attempt, not sending any \xe2\x80\xa60C`Potentially store a token for later one-time use0CfPerform NSS-compatible TLS key logging to the file \xe2\x80\xa6AhThe offset in the stream0B`Packet deliveries were confirmed0AfPacket protection keys0lRandom valueBcHuman-readable reason for the close000BhHuman-readable explanation of the reasonBeReason that the connection was closedBcReason why this path was abandoned.AjSwitch to a new UDP socketBgReject this incoming connection attempt0AgKey for decrypting dataBoReturns the remote address of the network path.1AmTLS interface based on rustls0CnHelper to construct an endpoint for use with both incoming \xe2\x80\xa6BkOptional source IP address for the datagram00CgThe current local PathStatus of this path.B`The new status set by the remoteCfThe size of a single datagram in the associated bufferCkStatistics about datagrams and bytes received on this path.ChStatistics about UDP datagrams received on a connection.10CgStatistics about datagrams and bytes sent on this path.CkStatistics about UDP datagrams transmitted on a connection.10AnMethod for verifying a message0CcNumber of ack-eliciting bytes that may be in flight0A`Send would blockCcNo more data is currently available on this stream.CjThe peer is not able to accept additional data, or the \xe2\x80\xa6BfA catch-all error for unlikely errors.0BlA key for signing with HMAC-based algorithms0AhAn Initial packet headerBnA pair of keys for bidirectional communication0BhA simple, standard congestion controller0CdFuture produced by Connection::open_uniCkAbstracts I/O and timer operations for runtime independenceBfA cryptographic session (commonly TLS)0CcThe peer is no longer accepting data on this streamCfFuture returned from SendStream::stopped.ClThe peer is no longer accepting data on this stream, and \xe2\x80\xa6CkThe peer is no longer accepting data on this stream. No \xe2\x80\xa6CgThe peer asked us to stop sending on an outgoing streamAaAccess to streamsCaThe stream is larger than the user-supplied limitCnAttributed to some frame type this implementation does not \xe2\x80\xa6ClIndicates how many bytes and chunks had been transferred \xe2\x80\xa60l0-RTT packetCjReturns the length of a CID for connections created by \xe2\x80\xa60CdProvide the length of dst_cid in short header packetCcThe total number of clients which should be createdAlConnect to a remote endpointAeInitiate a connectionBbDecrypt the Initial packet payloadCgDecrypt the packet payload with the given packet numberBcDecrypt the given packet\xe2\x80\x99s header210ClConstructs a value with arbitrary fields, intended to be \xe2\x80\xa6DjConstruct an event that indicating that a Connection will \xe2\x80\xa6BkThe destination connection ID of the packetBkThe destination Connection ID of the packetAiDestination Connection ID00000CgEncrypt the packet payload with the given packet numberBcEncrypt the given packet\xe2\x80\x99s header10CbCheck if this stream has been opened during 0-RTT.0CmRetrieve implementation-specific metrics used to populate \xe2\x80\xa60CnThe maximum UDP payload size guaranteed to be supported by \xe2\x80\xa60CjUniform interface to send and receive UDP packets with \xe2\x80\xa6BbOne or more packets were just sent0BmInitiate a new outgoing bidirectional stream.CaReturns the path ID of the new path being opened.AdSource Connection ID0000CiCompletes when the peer stops the stream or reads the \xe2\x80\xa6CjCheck if this stream was stopped, get the reason if it wasCcThe total number of streams which should be createdAlProvide control over streamsCeThe length of the AEAD tag appended to packets on \xe2\x80\xa60CdUpgrade the handle to a full ConnectionB`Upgrades to a Path.AkSet the QUIC version to use0lQUIC versionB`The version that was unsupported11CeFuture produced by Connection::accept_biAfAn unreliable datagramBdDatagram support is disabled locally0A`A QUIC endpoint.BcThe main entry point to the libraryChA finished stream has been fully acknowledged or stoppedCkAn incoming connection for which the server has not yet \xe2\x80\xa60BoLong packet types with uniform header structureB`The largest encoded value length0Cmthe connection is being closed abruptly in the absence of \xe2\x80\xa60CeFuture returned by Connection::on_closedClFuture produced by crate::Connection::open_pathCmA currently open stream likely has data or errors waiting \xe2\x80\xa6CkMetadata for a single buffer filled with bytes received \xe2\x80\xa6BkResponse generated directly by the endpointCfIdentifier for a stream within a particular connection0CnCommunication with the peer has lapsed for longer than the \xe2\x80\xa6CkWe didn\xe2\x80\x99t receive any data from the remote within the \xe2\x80\xa61ChResponsible for limiting clients\xe2\x80\x99 ability to reuse \xe2\x80\xa60ClThe datagram is larger than the connection can currently \xe2\x80\xa60AbAn outgoing packet00CmStatistics about UDP datagrams transmitted or received on \xe2\x80\xa60CnA formerly write-blocked stream might be ready for a write \xe2\x80\xa6AkCongestion algorithm to useAhContents of the datagramBoMark the read data as consumed from the stream.BnStatistics about frames received on this path.CaStatistics about frames received on a connection.10CaStatistics about frames transmitted on this path.CdStatistics about frames transmitted on a connection.10DhConstructs cid by reading len bytes from a Buf0DkCreates a new qlog factory that writes files into QLOGDIR, \xe2\x80\xa60BfCreate a generator with a specific keyBjConstruct a VarInt infallibly0BeSucceeds iff x < 2^620AeWhat type we receivedAoWhat handshake type we received10CbWhether 0-RTT is/was possible during the handshakeCmSpecifies the time to wait after completing MTU discovery \xe2\x80\xa60CcReturns Self for use in down-casting to extract \xe2\x80\xa60EhReturns true if the Connection associated with this handle \xe2\x80\xa6CmDuration after an address validation token was issued for \xe2\x80\xa60CeThe local IP address which was used when the peer \xe2\x80\xa6000BnReturns the local address of the network path.ClCompute the maximum size of datagrams that may be passed \xe2\x80\xa6BnInitiate a new outgoing unidirectional stream.BcGet the priority of the send streamAlGet the priority of a streamCfThe negotiated application protocol, if ALPN is in use0Aeqlog output directoryBbOptional response to transmit backCiOptional seed to be used internally for random number \xe2\x80\xa60AlSlow start threshold (bytes)0BeSucceeds iff x < 2^6200000DaSends a Transmit on the given socket without any \xe2\x80\xa6DkQuickly determine whether cid could have been generated by \xe2\x80\xa600BmA path was abandoned and is no longer usable.CfFuture produced by Connection::accept_uniCdPaths marked with as available will be used when \xe2\x80\xa6CnAt least one new stream of a certain directionality may be \xe2\x80\xa6ClConfiguration for the Bbr congestion controller0BkThe connection was successfully establishedAoAPI to control datagram trafficAlDecoding of QUIC primitives.CkA path was discarded and all remaining state for it has \xe2\x80\xa6BgInfallible encoding of QUIC primitives.CnIdentifies a network path by the combination of remote and \xe2\x80\xa6A`Handshake packetBcKeys used to protect packet headers0CiCatch-all error for problems while decoding transport \xe2\x80\xa6CeNat traversal attempt failed due to a multipath errorBdKeys used to protect packet payloads0BmErrors that might trigger a path being closedAnApplication events about pathsBjStatistics related to a transmission path.0AeA read error occurredBmErrors that arise from reading from a stream.C`Errors triggered when reading from a recv streamCiAn object for asynchronously writing to an associated \xe2\x80\xa6BmAccept the next incoming bidirectional streamBbDuplicate the controller\xe2\x80\x99s state0BeThe number of UDP datagrams observed.AaControl datagrams1BeCreate new object from the given bits00BoWhich side of a connection initiated the stream0CmConvert into a 0-RTT or 0.5-RTT connection at the cost of \xe2\x80\xa6BoShorthand for self == Side::Client0B`Whether the connection is closedBoShorthand for self == Side::Server0CbWhether it is legal to respond with a retry packet0CdWhether to allow clients to migrate to new addresses0CdConstruct a timer that will expire at iBoLow-level protocol logic for the QUIC protoocolCjWait for the connection to be closed without keeping a \xe2\x80\xa6CjOpens an additional path if the multipath extension is \xe2\x80\xa6A`Opens a new pathBmPing the remote endpoint over a specific pathCiAttempts to read from the stream into the provided bufferCeReceive UDP datagrams, or register to be woken if \xe2\x80\xa6CkSend a UDP datagram, or register to be woken if sending \xe2\x80\xa6ClPrivate key used to send authenticated connection resets \xe2\x80\xa60BmGenerate the integrity tag for a retry packet0BgA stable identifier for this connectionCePrivate key used to authenticate data included in \xe2\x80\xa60BlThe position of a token in the packet bufferCgTransport configuration to use for incoming connections0CjWait for all connections on the endpoint to be cleanly \xe2\x80\xa6BoWrite a buffer into this stream in its entiretyCiAbstract implementation of an async timer for runtime \xe2\x80\xa6BoNumber of UDP packets to send/receive at a timeCkError indicating that a path has not been opened or has \xe2\x80\xa6BnThe path is already closed or was never opened1BeIn-progress connection attempt futureAbA QUIC connection.CeProtocol state and logic for a single QUIC connectionCeCommon interface for different congestion controllers0CjNumber of frames transmitted or received of each frame \xe2\x80\xa60BoThe connection ID was not recognized by the \xe2\x80\xa60DdThe type used to refer to FrameTypes in closing and \xe2\x80\xa6AnThe QUIC-MULTIPATH path statusBeConfiguration for qlog trace logging.0BnA stream that can only be used to receive dataAaAccess to streamsChErrors that arise while waiting for a stream to be resetDhError for attempting to retry an Incoming which already \xe2\x80\xa60BkA stream that can only be used to send data3BmObject to get current SystemTime0AdA rustls TLS session0CkResponsible for storing validation tokens received from \xe2\x80\xa60AeA borrowed UDP socketBjErrors that arise from writing to a streamBoErrors triggered while writing to a send streamBoAccept the next incoming uni-directional streamCkWhether the implementation is permitted to set the spin \xe2\x80\xa60CiCloses a path and sends a PATH_ABANDON frame with the \xe2\x80\xa6CdLogic for controlling the rate at which data is sent0BfWhether to print connection statisticsBnClass of error as encoded in the specificationB`Application-specific reason code10CaThe error code to be sent with the abandon frame.BoThe error that was sent with the abandon frame.AoError code supplied by the peerBcType of frame that caused the close0AiExtract the integer value0CnWhether there is no longer any need to keep the connection \xe2\x80\xa6DkDetermine whether this is the last event a Connection will \xe2\x80\xa6CiLook up the local IP address and port used by this socketDgGet the local SocketAddr the underlying socket is bound toBfThe amount of bytes lost on this path.0CjPad UDP datagrams carrying application data to current \xe2\x80\xa60AgReturns path statistics0CjThe final path stats, they are no longer available via \xe2\x80\xa6C`Attempt to write bytes from buf into the stream.AmRead the next segment of dataAoReads the next segment of data.CkRead an exact number of bytes contiguously from the stream.BnSets the PathStatus of this path.BoEpoch qlog event times are recorded relative to0ClError type for attempting to accept an IncomingBjErrors in the configuration of an endpoint0AeGeneric crypto errors0CnConfiguration for the Cubic congestion controller0CdReasons why attempting to finish a stream might failCnMaximum duration of inactivity to accept before timing out \xe2\x80\xa60AnValue exceeds supported bounds0D`Constructs a QlogConfig for individual connections.0AfA noq runtime for smolB`Application events about streamsCbAccept this incoming connection using a custom \xe2\x80\xa6CeLargest UDP payload size the path currently supports.ClStorage size required for the largest packet that can be \xe2\x80\xa61BiDescription to record in the qlog capture0BjThe socket this datagram should be sent to00DcCreates a new FourTuple without a known local address.BkStarting guess for maximum UDP payload sizeCkThe initial value to be used as the maximum UDP payload \xe2\x80\xa60ChUDP payload size that the network must be capable of \xe2\x80\xa6BjThe RTT used before an RTT sample is taken0BfThe initial round-trip-time (in msecs)CeThe amount of concurrent streams which should be usedDdPackets are acked in batches, all with the same now \xe2\x80\xa60AdPacing rate (bits/s)0DiA broadcast receiver of PathEvents for all paths in this \xe2\x80\xa6DfGets the local PathStatus for a known PathIdAnRead the next segments of dataCkConvenience method to read all remaining data into a bufferAlProvide control over streamsBoThe sample size used for this key\xe2\x80\x99s algorithm01CiMaximum number of bytes to transmit to a peer without \xe2\x80\xa600BoThe server name specified by the client, if any0BmObject to get current SystemTime0BdSet a custom TokenStore0CaNumber of bytes to transmit from client to serverCnSpecifies the upper bound to the max UDP payload size that \xe2\x80\xa60ChReturns a weak reference to the inner connection struct.CdReturns a WeakPathHandle for this path.DgCreate a server config with the given crypto::ServerConfig0CeSets a prefix to the filename of the generated files.0DbWrite a single Bytes into this stream in its entiretyBbAn ADD_ADDRESS frame was received.BfConfiguration for outgoing connectionsCaClient-side configuration for the crypto protocol10CgThe stream has already been stopped, finished, or resetBmThe stream has already been finished or resetCmError indicating that a stream has not been opened or has \xe2\x80\xa6CjThe stream has not been opened or was already stopped, \xe2\x80\xa6CfThe stream has not been opened or has already been \xe2\x80\xa6CmThe stream has not been opened or was already finished or \xe2\x80\xa63CgErrors in the parameters being used to create a new \xe2\x80\xa60BkProtocol-level identifier for a connection.0CkWe couldn\xe2\x80\x99t decrypt a message. This is invariably fatal.0BjExplicit congestion notification codepoint00CnWe couldn\xe2\x80\x99t encrypt a message because it was larger than \xe2\x80\xa60BhParameters that are semantically invalidCkCannot close the last remaining open path via the local \xe2\x80\xa6Akn0\xe2\x80\x99s nat traversal eventsDhNull implementation of TokenLog, which never accepts tokens0ClReceived an observation of our external address from the \xe2\x80\xa6CiFuture produced by Connection::read_datagramBiThe remote changed the status of the pathBlRTT estimation for a particular network pathCnFuture produced by Connection::send_datagram_waitBiParameters governing incoming connectionsCaServer-side configuration for the crypto protocol10CmErrors that arise while monitoring for a send stream stop \xe2\x80\xa6AgA noq runtime for TokioC`Returns the lifetime of generated Connection IDs0BlIf the connection is closed, the reason why.CjConnect to a remote endpoint using a custom configuration.AlConservative estimate of RTTBnGet the 0-RTT keys if available (clients only)0AgWhich types we expectedB`Which handshake type we expected10AcGenerates a new CID0ClThe number of segments to read when GRO is enabled. Used \xe2\x80\xa6DeProcess ConnectionEvents generated by the associated \xe2\x80\xa6EaProcess EndpointEvents emitted from related ConnectionsCgCreate the initial set of keys given the client\xe2\x80\x99s \xe2\x80\xa6000BhThe amount of packets lost on this path.0DcMaximum number of Incoming to allow to exist at a time0CjWhether datagrams might get fragmented into multiple parts0CmWhether transmitted datagrams might get fragmented by the \xe2\x80\xa6CkReturns the path\xe2\x80\x99s network path represented as a 4-tuple.CkThe original destination CID when initiating the connectionCiThe original destination connection ID sent by the clientDhReturns the next time at which handle_timeout should be \xe2\x80\xa6D`Configures qlog capturing by setting a QlogFactory.0AgThe runtime type to useCkThe segment size if this transmission contains multiple \xe2\x80\xa600ChThe number of streams that may have unacknowledged data.CbSet the lifetime of CIDs created by this generator0BcSet the priority of the send streamAlSet the priority of a streamCnInitialize a QUIC-compatible TLS client configuration with \xe2\x80\xa6000DgWrite a slice of Bytes into this stream, returning how \xe2\x80\xa6AmSend data on the given streamCkWe received a fatal alert. This means the peer is unhappy.0BhBloom filter-based TokenLog0CmThe connection could not be created because not enough of \xe2\x80\xa6000CaEvent resulting from processing a single datagramBlEvents sent from a Connection to an EndpointAoStatistics on Endpoint activityBnThe stream finished before all bytes were readBlAuthentication data for (rustls) TLS session0Ccreceived an invalid Retry Token in a client Initial0ChIterator over ALPN protocol names from a TLS ClientHelloAlThe packet header is invalidBkThe local application closed the connection0DaThe datagram may result in starting a new ConnectionD`Configuration for the NewReno congestion controller0BjDecodes a QUIC packet\xe2\x80\x99s invariant headerCgErrors triggered when opening a recv stream for readingCaDefault implementation of TimeSource0CgError indicating that the provided buffer was too smallChFor clients, if the peer accepted the 0-RTT data packetsAbAck Frequency modeAfExports for benchmarksBoSupply a custom connection ID generator factory0DgCreate a UdpSender that can register a single task for \xe2\x80\xa6CaNumber of bytes to transmit from server to clientAmGet the Incoming0CnThe max_ack_delay we will request the peer to use0CgDisable packet encryption/decryption (for debugging \xe2\x80\xa6CkThe known MTU for the current network path has been updated0BbCryptographic identity of the peerBgGet the peer\xe2\x80\x99s identity, if availableDhFor the rustls TlsSession, the Any type is \xe2\x80\xa610CnAttempts to read from the stream into the provided buffer, \xe2\x80\xa6AkReturns packets to transmitDjConfigures qlog capturing through the QLOGDIR environment \xe2\x80\xa60AoReceive an application datagramDfTransmit data as an unreliable, unordered application \xe2\x80\xa6CmWhether to implement fair queuing for send streams having \xe2\x80\xa60BfLength of sign\xe2\x80\x99s output0BnStart a client session with this configurationBnStart a server session with this configuration10BdA REMOVE_ADDRESS frame was received.CgAbstract implementation of a UDP socket for runtime \xe2\x80\xa6BgErrors triggered when abandoning a pathAgThe connection was lost00000ChGlobal configuration for the endpoint, affecting all \xe2\x80\xa60Cithe endpoint encountered an internal error and cannot \xe2\x80\xa60FbBasic adapter to let Incoming be await-ed like a ConnectingBhEncounter a frame ID that was not valid.CeThe peer sent us a TLS message with invalid contents.0Amno viable network path exists0DhNull implementation of TokenStore, which does not store \xe2\x80\xa60CiThe peer deviated from the standard TLS protocol. The \xe2\x80\xa60BmErrors that arise from reading from a stream.C`Errors from RecvStream::read_to_endCaIndicates whether a frame needs to be transmittedCmThe peer violated the QUIC specification as understood by \xe2\x80\xa60CiTransport-level errors occur when a peer violates the \xe2\x80\xa6C`Tokio-compatible UDP socket with some useful \xe2\x80\xa6DiWeak handle for a Path that does not keep the connection \xe2\x80\xa6BnCreate a client endpoint and client connectionAgGet a session referenceDiReturns a QlogConfig for a connection, if logging should \xe2\x80\xa60AiProcess timer expirationsBjParameters negotiated during the handshake0CfGet data negotiated during the handshake, if available0AiInitial congestion windowCiDefault limit on the amount of outstanding data in bytes.001000BnConverts this stream into an unordered stream.DdReturns true until the connection is fully established.CeWhether the connection is in the process of being \xe2\x80\xa61BfVerify the integrity of a retry packet0CnSpecifies the minimum MTU change to stop the MTU discovery \xe2\x80\xa60BdCompute keys for the next key update0BkConfigures qlog capturing into a directory.0AlRead bytes of handshake data0BeWhether to use the unordered read APIClMaximum number of bytes the peer may transmit across all \xe2\x80\xa600CkCompletes when the stream has been reset by the peer or \xe2\x80\xa60CiCheck whether this stream has been reset by the peer, \xe2\x80\xa6AjThe peer\xe2\x80\x99s UDP addressesAhThe peer\xe2\x80\x99s UDP address0BgThe peer\xe2\x80\x99s UDP address for this path.1CeSaturating integer addition. Computes self + rhs, \xe2\x80\xa6000ChSaturating integer subtraction. Computes self - rhs, \xe2\x80\xa60CkMaximum reordering in time space before time based loss \xe2\x80\xa60ChReason given by the transport for closing the connection0BfReasons why a connection might be lost0CiThe datagram is redirected to its ConnectionBlEvents sent from an Endpoint to a ConnectionAfConnection statistics.0BiStatistics for the currently open streamsAcPlain packet headerBkEnables writing qlog traces to a directory.0AkThe remote closed the path.CfError for when a validation token may have been reused0C`Parameters governing the core QUIC state machine0CbThe peer doesn\xe2\x80\x99t implement any supported version0CdFuture that completes when a connection is fully \xe2\x80\xa6CbThis was a 0-RTT stream and the server rejected it000CjAutomatically select an appropriate runtime from those \xe2\x80\xa6CkWhether to accept QUIC packets containing any value for \xe2\x80\xa60CdMaximum number of incoming packets that may fail \xe2\x80\xa60CnThe interface index of the interface on which the datagram \xe2\x80\xa6AjSwitch to a new UDP socketCiCreates a server endpoint which runs on the given runtimeD`Sets the PathStatus for a known PathIdCfSee proto::TransportConfig::send_window()BoSee TransportConfig::send_window()BmReturns whether a frame should be transmittedD`Convert t into the socket type used by this runtimeCdWrites handshake bytes into the given buffer and \xe2\x80\xa60ClStream produced by Path::observed_external_addrCiReason given by an application for closing the connection0CbThe peer\xe2\x80\x99s QUIC stack aborted the connection \xe2\x80\xa60DjInternal identifier for a Connection currently associated \xe2\x80\xa6CdOne or more application datagrams have been receivedBjDecrypted payload of a QUIC Initial packetCaThe endpoint can no longer create new connections0Cnreceived a STREAM frame or a RESET_STREAM frame containing \xe2\x80\xa60ClSpecific failure cases from keys_match or a \xe2\x80\xa60A`key update error0CaCurrent limits do not allow us to open more pathsClThe peer doesn\xe2\x80\x99t support a protocol version/feature we \xe2\x80\xa60BjA QUIC-compatible TLS client configuration0BjA QUIC-compatible TLS server configuration0EfTokenStore implementation that stores up to N tokens per \xe2\x80\xa60CgAn endpoint (local or remote) tried to add too many \xe2\x80\xa6CmWe didn\xe2\x80\x99t receive a path response in time after opening \xe2\x80\xa6CaPath could not be validated and will be abandonedBcA Version Negotiation packet headerCiRecord that the token was used and, ideally, return a \xe2\x80\xa60CjCurrent state of the congestion control algorithm, for \xe2\x80\xa6CcCurrent state of this connection\xe2\x80\x99s congestion \xe2\x80\xa6BaUpdate traffic keys spontaneously0CnThe maximum amount of segments which can be transmitted if \xe2\x80\xa6CnMaximum duration of inactivity to accept before timing out \xe2\x80\xa60Cgn0\xe2\x80\x99s (https://n0.computer) NAT Traversal protocol \xe2\x80\xa6CeGet the number of connections that are currently openBmNumber of connections that are currently openCiOpens a new path if no path exists yet for the remote \xe2\x80\xa6CmOpens a new path only if no path on the same network path \xe2\x80\xa6CiMaximum reordering in packet number space before FACK \xe2\x80\xa60CfGet the size of the socket receive bufferAlReceive buffer size in bytesCcGet the size of the socket send bufferAiSend buffer size in bytesBiSet a custom TransportConfig000ChConfiguration for sending and handling validation tokens0CnCreate a server config with the given certificate chain to \xe2\x80\xa60DdWrite a slice of Bytes into this stream in its entiretyCfthe application or application protocol caused the \xe2\x80\xa60AnThe peer closed the connectionBoThe path was closed locally by the application.1B`Constructs controllers on demand0BdCommon congestion controller metrics0ClThe trait for encrypting tokens that power retry packets \xe2\x80\xa60BcThe given server name was malformed0CbHints when the caller identifies a network change.0AcPacket decode errorBdReason for why a path was abandoned.BmErrors that can arise when sending a datagram0CcThe peer does not support receiving datagram frames0BdCongestion events on the connection.0AiCongestion window (bytes)0ClCompute the maximum size of datagrams that may be passed \xe2\x80\xa6BoBytes available in the outgoing datagram bufferClReplace the server configuration, affecting new incoming \xe2\x80\xa60Cmthe endpoint has reached the confidentiality or integrity \xe2\x80\xa60CkParameters for controlling the peer\xe2\x80\x99s acknowledgement \xe2\x80\xa60DjThe max_fragment_size value supplied in configuration was \xe2\x80\xa60Bmthe server refused to accept a new connection0BjParse connection id in short header packetCjOne or more application datagrams have been sent after \xe2\x80\xa6Ckreceived more data than permitted in advertised data limits0AoThe TLS handshake was confirmedBjThe connection\xe2\x80\x99s handshake data is readyCeAttempted an ordered read following an unordered readAnWe saw an invalid certificate.0BcParameters governing MTU discovery.0BnNot enough addresses to complete the operationCkdetected an error with protocol compliance that was not \xe2\x80\xa60Cjreceived a frame for a stream identifier that exceeded \xe2\x80\xa60Cnreceived a frame for a stream that was not in a state that \xe2\x80\xa60AnError from setting path statusAjTransport-level error code0ChThe local endpoint does not support the QUIC version \xe2\x80\xa6CkError indicating that the specified QUIC version is not \xe2\x80\xa61C`Packet uses a QUIC version that is not supported1CiMaximum quantity of out-of-order crypto layer data to \xe2\x80\xa60C`Create a VarInt without ensuring it\xe2\x80\x99s in range0ChCumulative number of Quic handshakes ignored on this \xe2\x80\xa6EgReturns true if the two WeakConnectionHandle point at the \xe2\x80\xa6CiMinimum interval between outgoing stateless reset packets0CjConstruct with an approximate maximum memory usage and \xe2\x80\xa60ChCumulative number of Quic handshakes refused on this \xe2\x80\xa6AnReturns the remote path statusDfTransmit data as an unreliable, unordered application \xe2\x80\xa6CnUpdates the set of ALPN protocols configured in the client \xe2\x80\xa6CnUpdates the set of ALPN protocols configured in the server \xe2\x80\xa610CiSee proto::TransportConfig::receive_window()CbSee TransportConfig::receive_window()B`Override supported QUIC versions0CiOverride the instant relative to which all events are \xe2\x80\xa60BkNo remote CIDs available to open a new pathCkTransport parameters used to negotiate connection-level \xe2\x80\xa6CgA stream that can be used to receive data out-of-order.CmThe certificate verifier doesn\xe2\x80\x99t support the given type \xe2\x80\xa60CfThe operation is not allowed for this endpoint\xe2\x80\x99s \xe2\x80\xa6CiCumulative number of Quic handshakes accepted by this \xe2\x80\xa6CjSpecifies the amount of time that MTU discovery should \xe2\x80\xa60CiIf the 0-RTT-encrypted data has been accepted by the peer0BgWait for the handshake to be confirmed.CgInform the connection if a path may recover after a \xe2\x80\xa60CgPeriod of inactivity before sending a keep-alive packet0CfThe number of PLPMTUD probe packets lost on this path.0BlPackets were deemed lost or marked congested0CgCumulative number of Quic handshakes sent from this \xe2\x80\xa6CnThe number of remotely initiated open streams of a certain \xe2\x80\xa6AhBench fns for SendBufferCfThe number of PLPMTUD probe packets sent on this path.0Bireceived a frame that was badly formatted0CkThis function doesn\xe2\x80\x99t work until the TLS handshake is \xe2\x80\xa60CkWe received a TLS message that isn\xe2\x80\x99t valid right now. \xe2\x80\xa60CiThe remote SocketAddr supplied was malformedCkThe remote address for the path is not supported by the \xe2\x80\xa61ChThe initial cipher suite (AES-128-GCM-SHA256) is not \xe2\x80\xa60BdPaths can only be opened client-sideDmError returned when constructing a VarInt from a value >= \xe2\x80\xa60CeA handle to some connection internals, use with care.DkSpecifies the ACK frequency config (see AckFrequencyConfig \xe2\x80\xa60CjThe number of times a black hole was detected in the path.0CgMaximum number of received bytes to buffer for each \xe2\x80\xa60AeIs multipath enabled?ClMaximum number of datagrams that might be described by a \xe2\x80\xa60CkMaximum UDP payload size accepted from peers (excluding \xe2\x80\xa60AmMax UDP payload size in bytesDkSpecifies the MTU discovery config (see MtuDiscoveryConfig \xe2\x80\xa60AmReturn endpoint-facing eventsCkThe preferred IPv4 address that will be communicated to \xe2\x80\xa60CkThe preferred IPv6 address that will be communicated to \xe2\x80\xa60ChThe reordering threshold we will request the peer to use0ClDuration after a retry token was issued for which it\xe2\x80\x99s \xe2\x80\xa60BmSets the max idle timeout for a specific pathDfResize the receive buffer of socket to bytesDcResize the send buffer of socket to bytesBfThe peer\xe2\x80\x99s QUIC transport parametersBdQUIC connection transport parameters1CaGenerates connection IDs for incoming connections0CdAn incoming connection did not support any known \xe2\x80\xa60BjNo default client configuration was set up0BiPath abandoned due to unstable interfaces0ClConfiguration for sending and handling validation tokens \xe2\x80\xa60CmMaximum number of packets that may be sent using a single \xe2\x80\xa60CiNotify connections that the local network address has \xe2\x80\xa6ChHandle a change in the local address, i.e. an active \xe2\x80\xa6CiCounter for the number of bytes currently used in the \xe2\x80\xa6CgReturns whether we think the other address probably \xe2\x80\xa6CkReduction in congestion window when a new loss event is \xe2\x80\xa60DdMaximum number of datagrams that a Transmit may encode.0DeA broadcast receiver of n0_nat_traversal::Events for \xe2\x80\xa6CjGet the address observed by the remote over the given pathCiMaximum number of bytes the peer may transmit without \xe2\x80\xa600Chreceived more data in CRYPTO frames than can be buffered0B`The extension was not negotiatedCbWe failed to figure out what time it currently is.0CbWe failed to acquire random bytes from the system.0CnError indicating that this operation requires multipath to \xe2\x80\xa6BnThe extension was not negotiated with the peerAkMultipath is not negotiatedCnError when the multipath extension was not negotiated, but \xe2\x80\xa6CjThe path was opened in a NAT traversal round which was \xe2\x80\xa6BnHeader of an Initial packet, before decryptionCgDerive keying material from this connection\xe2\x80\x99s TLS \xe2\x80\xa6EdFill output with output.len() bytes of keying material \xe2\x80\xa60BnPathological case: many segments, get from endCfGet segments in the old way, using a loop of get callsClCurrent number of remotely initiated streams that may be \xe2\x80\xa6ClTrack changed on our external address as reported by the \xe2\x80\xa6ClTrack changes on our external address as reported by the \xe2\x80\xa6CmCreate a client configuration that trusts specified trust \xe2\x80\xa60BkThe peer didn\xe2\x80\x99t give us any certificates.0BkThe peer sent an oversized record/fragment.0CkThe ack-eliciting threshold we will request the peer to use0BiWhether there are any pending retransmitsCdWhether the Multipath for QUIC extension is enabled.C`Sets the keep_alive_interval for a specific pathBoSet a custom ValidationTokenConfig0BmPath abandoned at the application\xe2\x80\x99s request0CjGet the current value of max_udp_payload_size0ChConfigure how to populate the destination CID of the \xe2\x80\xa60CjConstruct an endpoint with arbitrary configuration and \xe2\x80\xa6CfWhether the socket address that is initiating this \xe2\x80\xa60CmModify the number of open paths allowed when multipath is \xe2\x80\xa6Cmthe number of connection IDs provided by the peer exceeds \xe2\x80\xa60CbError returned by Session::export_keying_material.0CiA provided certificate revocation list (CRL) was invalid.0CmPath abandoned due to no available connection IDs for the \xe2\x80\xa60Clreceived transport parameters that were badly formatted, \xe2\x80\xa60CiRegisters one address at which this endpoint might be \xe2\x80\xa6ClAdd addresses the local endpoint considers are reachable \xe2\x80\xa6ClMaximum number of outgoing application datagram bytes to \xe2\x80\xa60CiSet the client configuration used by connectBmSets the max_idle_timeout for a specific pathBfThe QUIC protocol version implemented.CfThe path became unusable after a local network change.BoBytes available in the outgoing datagram bufferDhMaximum number of received bytes to buffer for all Incoming0DaVariant of max_concurrent_bidi_streams affecting \xe2\x80\xa60ClModify the number of remotely initiated streams that may \xe2\x80\xa6CnCreate a client configuration that trusts the platform\xe2\x80\x99s \xe2\x80\xa60CkGenerates 8-byte connection IDs that can be efficiently \xe2\x80\xa6CkAn error occurred while handling Encrypted Client Hello \xe2\x80\xa60CkPath abandoned due to resource limitations in the transport0CiGenerates purely random connection IDs of a specified \xe2\x80\xa6ChWhether to use \xe2\x80\x9cGeneric Segmentation Offload\xe2\x80\x9d to \xe2\x80\xa60CmMaximum number of incoming bidirectional streams that may \xe2\x80\xa60BhUpdates this tuple\xe2\x80\x99s local address iffClMaximum number of incoming application datagram bytes to \xe2\x80\xa60BcInitiates a new nat traversal round0BdPackets were incorrectly deemed lost0CnRemoves one or more addresses from the set of addresses at \xe2\x80\xa6CgRemoves an address the endpoing no longer considers \xe2\x80\xa6C`Sets the keep_alive_interval for a specific pathDeA ConnectionIdParser implementation that assumes the \xe2\x80\xa6CjWe received a TLS handshake message that isn\xe2\x80\x99t valid \xe2\x80\xa60CiHow to construct new congestion::Controllers0BlSets a default per-path maximum idle timeout0BoThe key exchange group negotiated with the peer0CbWhether to send observed address reports to peers.0CiModify the number of remotely initiated bidirectional \xe2\x80\xa6BiEnables the Multipath Extension for QUIC.0CjModify the number of remotely initiated unidirectional \xe2\x80\xa6CeNumber of consecutive PTOs after which network is \xe2\x80\xa60BkSets a default per-path keep alive interval0CjWhether to receive observed address reports from other \xe2\x80\xa60BmGet the current local nat traversal addresses0CkGet the currently advertised nat traversal addresses by \xe2\x80\xa60AcNat traversal draftCkSets the maximum number of nat traversal addresses this \xe2\x80\xa60CjWhen multipath is required and has not been explicitly \xe2\x80\xa6") \ No newline at end of file diff --git a/pr/545/docs/search.index/entry/34c09ea0dc28.js b/pr/545/docs/search.index/entry/34c09ea0dc28.js new file mode 100644 index 000000000..7719f8455 --- /dev/null +++ b/pr/545/docs/search.index/entry/34c09ea0dc28.js @@ -0,0 +1 @@ +rd_("Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ag[463,15,464,0,4085,0,0]Al[3096,15,3097,1784,4086,0,0]Al[1985,15,1986,1986,4087,0,0]Al[3096,15,1689,1689,1433,0,0]Ao[1195,13,1196,1196,3928,3037,0]Am[463,13,464,3640,4749,3037,0]Am[463,13,464,4142,1418,3037,0]Al[463,13,464,1094,503,3037,0]Am[463,13,464,1094,4359,3037,0]Am[463,13,464,4034,4352,3037,0]Am[463,13,464,4034,3044,3037,0]Am[463,13,464,4034,3239,3037,0]Am[463,13,464,4034,4351,3037,0]Am[463,13,464,4039,3257,3037,0]Am[463,13,464,4039,4120,3037,0]Aj[463,13,464,0,1443,3037,0]Aj[463,13,464,0,4915,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,4071,3037,0]Aj[463,13,464,0,4444,3037,0]Aj[463,13,464,0,3941,3037,0]Aj[463,13,464,0,3931,3037,0]Aj[463,13,464,0,3025,3037,0]Aj[463,13,464,0,4441,3037,0]Aj[463,13,464,0,4642,3037,0]Aj[463,13,464,0,4077,3037,0]Aj[463,13,464,0,4080,3037,0]Aj[463,13,464,0,4085,3037,0]Aj[463,13,464,0,4808,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,5064,3037,0]Ak[463,13,1773,0,1169,3037,0]Ao[3096,13,3097,1810,1444,3037,0]Ao[3096,13,3097,1810,4916,3037,0]Ao[3096,13,3097,3061,1153,3037,0]Ao[3096,13,3097,3070,4750,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,4748,3037,0]Ao[3096,13,3097,1366,4804,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,4241,3037,0]Ao[3096,13,3097,1125,1868,3037,0]Ao[3096,13,3097,1125,3258,3037,0]Ao[3096,13,3097,1125,3940,3037,0]Ao[3096,13,3097,2002,3959,3037,0]Ao[3096,13,3097,2002,4353,3037,0]Ao[3096,13,3097,2002,4075,3037,0]Ao[3096,13,3097,3641,4445,3037,0]Ao[3096,13,3097,3641,3038,3037,0]Ao[3096,13,3097,3641,4319,3037,0]Ao[3096,13,3097,3194,3942,3037,0]Ao[3096,13,3097,1691,3932,3037,0]Ao[3096,13,3097,1356,3026,3037,0]Ao[3096,13,3097,1356,4334,3037,0]Ao[3096,13,3097,1356,3224,3037,0]Ao[3096,13,3097,1356,3247,3037,0]Ao[3096,13,3097,1356,4082,3037,0]Ao[3096,13,3097,1356,4443,3037,0]Ao[3096,13,3097,1356,4644,3037,0]Ao[3096,13,3097,2305,4648,3037,0]Ao[3096,13,3097,2305,4078,3037,0]Ao[3096,13,3097,1756,2267,3037,0]Ao[3096,13,3097,1756,4746,3037,0]Ao[3096,13,3097,1784,4081,3037,0]Ao[3096,13,3097,1784,4086,3037,0]Al[3096,13,3097,0,4357,3037,0]Al[3096,13,3097,0,4809,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,4247,3037,0]Ao[3096,13,4957,4957,4855,3037,0]Ao[3096,13,4957,4957,1171,3037,0]Ao[3096,13,1694,1694,5065,3037,0]Al[3096,13,1774,0,1170,3037,0]Ao[1985,13,1986,1986,4087,3037,0]Ai[463,13,464,1094,503,0,0]Aj[463,13,464,1094,4359,0,0]Aj[463,13,464,4034,3237,0,0]Aj[463,13,464,4034,4856,0,0]Aj[463,13,464,4039,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,4107,0,0]Ai[3096,14,3039,0,4100,0,0]Ai[3096,14,3958,0,2277,0,0]Ai[3096,14,3958,0,2297,0,0]Ai[3096,14,3958,0,2261,0,0]Ai[3096,14,3958,0,1855,0,0]Ae[1195,7,1196,0,0,0,0]Ah[3096,14,4456,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,4848,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,4448,117,0]An[3096,13,3097,1382,2295,117,0]An[3096,13,3097,1382,3218,117,0]An[3096,13,3097,1382,4449,117,0]Ai[463,13,464,0,1443,137,0]Ai[463,13,464,0,1426,137,0]Ai[463,13,464,0,3941,137,0]Ai[463,13,464,0,4080,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,4750,137,0]An[3096,13,3097,1366,1427,137,0]An[3096,13,3097,1120,3045,137,0]An[3096,13,3097,1120,4241,137,0]An[3096,13,3097,1125,3258,137,0]An[3096,13,3097,3194,3942,137,0]An[3096,13,3097,2305,4648,137,0]An[3096,13,3097,1756,4746,137,0]An[3096,13,3097,1784,4081,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,3958,0,1421,0,0]Ai[3096,14,3958,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,3952,1159,0]Ao[1195,13,1196,1196,3928,1159,0]Ao[1195,13,1380,1380,4354,1159,0]Ao[3966,13,3967,3967,5006,1159,0]Am[463,13,464,4142,4912,1159,0]Am[463,13,464,3640,3209,1159,0]Am[463,13,464,3640,3211,1159,0]Am[463,13,464,3640,4918,1159,0]D`[463,13,464,3640,4749,1159,0,\"impl-Debug-for-SendDatagramError\"]Db[463,13,464,3640,4749,1827,0,\"impl-Display-for-SendDatagramError\"]Am[463,13,464,2304,2259,1159,0]Am[463,13,464,2304,4215,1159,0]Cg[463,13,464,4142,1418,1827,0,\"impl-Display-for-Lagged\"]Ce[463,13,464,4142,1418,1159,0,\"impl-Debug-for-Lagged\"]Am[463,13,464,4142,3231,1159,0]Am[463,13,464,4142,4849,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,4333,1159,0]Al[463,13,464,1094,503,1159,0]Am[463,13,464,1094,4359,1159,0]Am[463,13,464,4034,3237,1159,0]Am[463,13,464,4034,4856,1159,0]Co[463,13,464,4034,4352,1827,0,\"impl-Display-for-ReadToEndError\"]Cm[463,13,464,4034,4352,1159,0,\"impl-Debug-for-ReadToEndError\"]Cj[463,13,464,4034,3044,1827,0,\"impl-Display-for-ReadError\"]Ch[463,13,464,4034,3044,1159,0,\"impl-Debug-for-ReadError\"]Ci[463,13,464,4034,3239,1159,0,\"impl-Debug-for-ResetError\"]Ck[463,13,464,4034,3239,1827,0,\"impl-Display-for-ResetError\"]Cm[463,13,464,4034,4351,1159,0,\"impl-Debug-for-ReadExactError\"]Co[463,13,464,4034,4351,1827,0,\"impl-Display-for-ReadExactError\"]Am[463,13,464,1393,4121,1159,0]Am[463,13,464,1137,3955,1159,0]Am[463,13,464,4039,3243,1159,0]Ci[463,13,464,4039,3257,1159,0,\"impl-Debug-for-WriteError\"]Ck[463,13,464,4039,3257,1827,0,\"impl-Display-for-WriteError\"]Cm[463,13,464,4039,4120,1827,0,\"impl-Display-for-StoppedError\"]Ck[463,13,464,4039,4120,1159,0,\"impl-Debug-for-StoppedError\"]Am[463,13,464,4039,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\"]D`[463,13,464,0,4915,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Db[463,13,464,0,4915,1827,0,\"impl-Display-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,4448,1159,0]Aj[463,13,464,0,1867,1159,0]Cj[463,13,464,0,4071,1827,0,\"impl-Display-for-ClosedStream\"]Ch[463,13,464,0,4071,1159,0,\"impl-Debug-for-ClosedStream\"]Ck[463,13,464,0,4444,1159,0,\"impl-Debug-for-ConnectionError\"]Cm[463,13,464,0,4444,1827,0,\"impl-Display-for-ConnectionError\"]Aj[463,13,464,0,4458,1159,0]Aj[463,13,464,0,4467,1159,0]Aj[463,13,464,0,4773,1159,0]Aj[463,13,464,0,4788,1159,0]Aj[463,13,464,0,3941,1159,0]Aj[463,13,464,0,4328,1159,0]Aj[463,13,464,0,4114,1159,0]Aj[463,13,464,0,4972,1159,0]Aj[463,13,464,0,4065,1159,0]Cg[463,13,464,0,3931,1159,0,\"impl-Debug-for-ConfigError\"]Ci[463,13,464,0,3931,1827,0,\"impl-Display-for-ConfigError\"]Cg[463,13,464,0,3025,1827,0,\"impl-Display-for-FrameType\"]Ce[463,13,464,0,3025,1159,0,\"impl-Debug-for-FrameType\"]Cm[463,13,464,0,4441,1827,0,\"impl-Display-for-ConnectionClose\"]Ck[463,13,464,0,4441,1159,0,\"impl-Debug-for-ConnectionClose\"]Cn[463,13,464,0,4642,1827,0,\"impl-Display-for-ApplicationClose\"]Cl[463,13,464,0,4642,1159,0,\"impl-Debug-for-ApplicationClose\"]Ch[463,13,464,0,4077,1159,0,\"impl-Debug-for-ConnectError\"]Cj[463,13,464,0,4077,1827,0,\"impl-Display-for-ConnectError\"]Cj[463,13,464,0,4080,1827,0,\"impl-Display-for-ConnectionId\"]Ch[463,13,464,0,4080,1159,0,\"impl-Debug-for-ConnectionId\"]Aj[463,13,464,0,4085,1159,0]Cn[463,13,464,0,4808,1159,0,\"impl-Debug-for-TransportErrorCode\"]D`[463,13,464,0,4808,1827,0,\"impl-Display-for-TransportErrorCode\"]Aj[463,13,464,0,3220,1159,0]Aj[463,13,464,0,4675,1159,0]Ai[463,13,464,0,510,1159,0]C`[463,13,464,0,126,1827,0,\"impl-Display-for-Dir\"]Bn[463,13,464,0,126,1159,0,\"impl-Debug-for-Dir\"]Cf[463,13,464,0,2281,1827,0,\"impl-Display-for-StreamId\"]Cd[463,13,464,0,2281,1159,0,\"impl-Debug-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,3936,1159,0]Ak[463,13,3635,0,1840,1159,0]Ak[463,13,3635,0,4233,1159,0]Ak[463,13,3635,0,4737,1159,0]Ak[463,13,1693,0,5064,1159,0]Ak[463,13,1693,0,3934,1159,0]Ak[463,13,1693,0,4812,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\"]Da[463,13,1773,0,4910,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Dc[463,13,1773,0,4910,1827,0,\"impl-Display-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,4916,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Dg[3096,13,3097,1810,4916,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]Ao[3096,13,3097,3061,1153,1159,0]Db[3096,13,3097,3070,4750,1159,0,\"impl-Debug-for-SendDatagramError\"]Dd[3096,13,3097,3070,4750,1827,0,\"impl-Display-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,4110,1159,0]Ao[3096,13,3097,1366,3233,1159,0]Ao[3096,13,3097,1366,3040,1159,0]Ao[3096,13,3097,1366,4748,1159,0]Dc[3096,13,3097,1366,4804,1159,0,\"impl-Debug-for-SetPathStatusError\"]De[3096,13,3097,1366,4804,1827,0,\"impl-Display-for-SetPathStatusError\"]Cm[3096,13,3097,1366,3207,1827,0,\"impl-Display-for-ClosedPath\"]Ck[3096,13,3097,1366,3207,1159,0,\"impl-Debug-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,4449,1159,0]Cj[3096,13,3097,1120,3045,1159,0,\"impl-Debug-for-ReadError\"]Cl[3096,13,3097,1120,3045,1827,0,\"impl-Display-for-ReadError\"]D`[3096,13,3097,1120,4241,1827,0,\"impl-Display-for-ReadableError\"]Cn[3096,13,3097,1120,4241,1159,0,\"impl-Debug-for-ReadableError\"]Ao[3096,13,3097,1125,1868,1159,0]Cm[3096,13,3097,1125,3258,1827,0,\"impl-Display-for-WriteError\"]Ck[3096,13,3097,1125,3258,1159,0,\"impl-Debug-for-WriteError\"]Cn[3096,13,3097,1125,3940,1827,0,\"impl-Display-for-FinishError\"]Cl[3096,13,3097,1125,3940,1159,0,\"impl-Debug-for-FinishError\"]Ao[3096,13,3097,2002,3959,1159,0]Ao[3096,13,3097,2002,4353,1159,0]Co[3096,13,3097,2002,4075,1827,0,\"impl-Display-for-ClosedStream\"]Cm[3096,13,3097,2002,4075,1159,0,\"impl-Debug-for-ClosedStream\"]Db[3096,13,3097,3641,4445,1827,0,\"impl-Display-for-ConnectionError\"]D`[3096,13,3097,3641,4445,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\"]Da[3096,13,3097,3641,4319,1827,0,\"impl-Display-for-ClosePathError\"]Co[3096,13,3097,3641,4319,1159,0,\"impl-Debug-for-ClosePathError\"]Dg[3096,13,3097,3641,5001,1159,0,\"impl-Debug-for-MultipathNotNegotiated\"]Di[3096,13,3097,3641,5001,1827,0,\"impl-Display-for-MultipathNotNegotiated\"]Ao[3096,13,3097,3641,1174,1159,0]Ao[3096,13,3097,1116,4459,1159,0]Ao[3096,13,3097,3194,4468,1159,0]Ao[3096,13,3097,3194,4774,1159,0]Ao[3096,13,3097,3194,4789,1159,0]Ao[3096,13,3097,3194,3942,1159,0]Ao[3096,13,3097,1691,4329,1159,0]Ao[3096,13,3097,1691,4116,1159,0]Ao[3096,13,3097,1691,4973,1159,0]Ao[3096,13,3097,1691,4067,1159,0]Cl[3096,13,3097,1691,3932,1159,0,\"impl-Debug-for-ConfigError\"]Cn[3096,13,3097,1691,3932,1827,0,\"impl-Display-for-ConfigError\"]Cl[3096,13,3097,1356,3026,1827,0,\"impl-Display-for-FrameType\"]Cj[3096,13,3097,1356,3026,1159,0,\"impl-Debug-for-FrameType\"]Da[3096,13,3097,1356,4334,1827,0,\"impl-Display-for-InvalidFrameId\"]Co[3096,13,3097,1356,4334,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\"]Cm[3096,13,3097,1356,3247,1827,0,\"impl-Display-for-StreamInfo\"]Ck[3096,13,3097,1356,3247,1159,0,\"impl-Debug-for-StreamInfo\"]Cm[3096,13,3097,1356,4082,1159,0,\"impl-Debug-for-DatagramInfo\"]Co[3096,13,3097,1356,4082,1827,0,\"impl-Display-for-DatagramInfo\"]Db[3096,13,3097,1356,4443,1827,0,\"impl-Display-for-ConnectionClose\"]D`[3096,13,3097,1356,4443,1159,0,\"impl-Debug-for-ConnectionClose\"]Dc[3096,13,3097,1356,4644,1827,0,\"impl-Display-for-ApplicationClose\"]Da[3096,13,3097,1356,4644,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,4648,1159,0]Ao[3096,13,3097,2305,2264,1159,0]Co[3096,13,3097,2305,4078,1827,0,\"impl-Display-for-ConnectError\"]Cm[3096,13,3097,2305,4078,1159,0,\"impl-Debug-for-ConnectError\"]Ao[3096,13,3097,2305,3926,1159,0]Cm[3096,13,3097,2305,3241,1827,0,\"impl-Display-for-RetryError\"]Ck[3096,13,3097,2305,3241,1159,0,\"impl-Debug-for-RetryError\"]Ao[3096,13,3097,1756,4236,1159,0]Ao[3096,13,3097,1756,4457,1159,0]Ao[3096,13,3097,1756,5005,1159,0]Ao[3096,13,3097,1756,2267,1159,0]Dd[3096,13,3097,1756,4746,1827,0,\"impl-Display-for-PacketDecodeError\"]Db[3096,13,3097,1756,4746,1159,0,\"impl-Debug-for-PacketDecodeError\"]Ao[3096,13,3097,1784,4447,1159,0]Ao[3096,13,3097,1784,4214,1159,0]Co[3096,13,3097,1784,4081,1827,0,\"impl-Display-for-ConnectionId\"]Cm[3096,13,3097,1784,4081,1159,0,\"impl-Debug-for-ConnectionId\"]Ao[3096,13,3097,1784,4086,1159,0]Ce[3096,13,3097,0,4357,1827,0,\"impl-Display-for-Error\"]Cc[3096,13,3097,0,4357,1159,0,\"impl-Debug-for-Error\"]Cd[3096,13,3097,0,4809,1827,0,\"impl-Display-for-Code\"]Cb[3096,13,3097,0,4809,1159,0,\"impl-Debug-for-Code\"]Ao[3096,13,3097,4254,3221,1159,0]Ao[3096,13,3097,4254,5099,1159,0]Ao[3096,13,3097,4844,4676,1159,0]An[3096,13,3097,3097,511,1159,0]Cc[3096,13,3097,3097,127,1159,0,\"impl-Debug-for-Dir\"]Ce[3096,13,3097,3097,127,1827,0,\"impl-Display-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]Cl[3096,13,3097,3097,3024,1827,0,\"impl-Display-for-FourTuple\"]Cj[3096,13,3097,3097,3024,1159,0,\"impl-Debug-for-FourTuple\"]Cn[3096,13,1689,1689,4247,1159,0,\"impl-Debug-for-UnexpectedEnd\"]D`[3096,13,1689,1689,4247,1827,0,\"impl-Display-for-UnexpectedEnd\"]Ao[3096,13,4957,4957,4855,1159,0]Ch[3096,13,4957,4957,1171,1827,0,\"impl-Display-for-Error\"]Cf[3096,13,4957,4957,1171,1159,0,\"impl-Debug-for-Error\"]Ao[3096,13,1694,1694,5065,1159,0]Ao[3096,13,1694,1694,3935,1159,0]Ao[3096,13,1694,1694,4815,1159,0]Cc[3096,13,1774,0,1170,1159,0,\"impl-Debug-for-Error\"]Ce[3096,13,1774,0,1170,1827,0,\"impl-Display-for-Error\"]Dg[3096,13,1774,1774,4911,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]De[3096,13,1774,1774,4911,1159,0,\"impl-Debug-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,3937,1159,0]Ao[3096,13,3636,2358,1841,1159,0]Ao[3096,13,3636,2358,4234,1159,0]Ao[3096,13,3636,3636,4738,1159,0]Ch[3096,13,4706,4706,1172,1827,0,\"impl-Display-for-Error\"]Cf[3096,13,4706,4706,1172,1159,0,\"impl-Debug-for-Error\"]Ao[3096,13,4706,4706,1175,1159,0]An[1985,13,1986,416,4358,1159,0]Ao[1985,13,1986,1986,2279,1159,0]Ao[1985,13,1986,1986,2293,1159,0]Ao[1985,13,1986,1986,4087,1159,0]Aj[463,13,464,4142,4912,0,0]Al[3096,13,3097,1366,4110,0,0]Ag[463,14,464,0,2294,0,0]Al[3096,14,3097,1382,2295,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,14,3097,1756,5005,0,0]Ah[3096,14,4456,0,499,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,13,464,0,4972,0,0]Al[3096,13,3097,1691,4973,0,0]8Al[1195,13,1380,1380,4354,0,0]Al[3966,13,3967,3967,5006,0,0]Ag[463,13,464,0,4206,0,0]Aj[463,13,464,2304,2259,0,0]Ag[463,13,464,0,3234,0,0]Ag[463,13,464,0,4458,0,0]Ag[463,13,464,0,4328,0,0]Ag[463,13,464,0,4114,0,0]Ag[463,13,464,0,4065,0,0]Ag[463,13,464,0,4080,0,0]Ag[463,13,464,0,4675,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,4477,4207,0,0]Al[3096,13,3097,1116,3235,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,1756,5124,0,0]Al[3096,13,3097,4254,5094,0,0]Al[3096,13,3097,1116,4459,0,0]Al[3096,13,3097,1691,4329,0,0]Al[3096,13,3097,1691,4116,0,0]Al[3096,13,3097,1691,4067,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,13,3097,1784,4081,0,0]Ai[3096,13,3097,0,4357,0,0]Al[3096,13,3097,4254,5099,0,0]Al[3096,13,3097,4844,4676,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,4358,0,0]Al[1095,13,4174,4174,5050,0,0]Al[1095,13,4174,4174,5051,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,4121,1852,0]Aj[463,13,464,0,4245,3250,0]Al[3096,12,3097,1691,3251,0,0]Ao[3096,13,3097,1691,4246,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,4085,0,0]Al[3096,15,3097,1784,4086,0,0]Al[1985,15,1986,1986,4087,0,0]210Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Al[3096,15,3097,1756,4457,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,4034,4352,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,4100,0,0]Al[1985,14,1986,1986,2279,0,0]Aa[519,3,0,0,0,0,0]Ai[3096,14,3097,0,4357,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,4359,487,0]Al[463,13,464,4034,3237,487,0]Al[463,13,464,4039,3243,487,0]An[3096,13,3097,1120,1407,487,0]Am[1195,13,1196,1196,134,494,0]An[1195,13,1196,1196,3952,494,0]An[1195,13,1196,1196,3928,494,0]An[1195,13,1380,1380,3960,494,0]An[1195,13,1380,1380,1189,494,0]An[1195,13,1380,1380,4354,494,0]Ak[519,13,520,520,3929,494,0]An[3966,13,3967,3967,5006,494,0]Al[463,13,464,3640,4472,494,0]Al[463,13,464,3640,2274,494,0]Ai[463,13,464,0,4206,494,0]Al[463,13,464,4142,4912,494,0]Al[463,13,464,1094,2275,494,0]Al[463,13,464,1094,4640,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,4106,494,0]Al[463,13,464,3640,4111,494,0]Al[463,13,464,3640,4918,494,0]Al[463,13,464,3640,4749,494,0]0Al[463,13,464,2304,2259,494,0]Al[463,13,464,2304,4215,494,0]Al[463,13,464,2304,1399,494,0]Al[463,13,464,4142,1418,494,0]Al[463,13,464,4142,3231,494,0]Al[463,13,464,4142,4849,494,0]Al[463,13,464,2336,2263,494,0]Al[463,13,464,2336,3240,494,0]Al[463,13,464,2336,4333,494,0]Ak[463,13,464,1094,503,494,0]Al[463,13,464,1094,4359,494,0]Al[463,13,464,4034,3237,494,0]Al[463,13,464,4034,4856,494,0]Al[463,13,464,4034,4352,494,0]0Al[463,13,464,4034,3044,494,0]Df[463,13,464,4034,3044,494,0,\"impl-From%3CResetError%3E-for-ReadError\"]Dk[463,13,464,4034,3044,494,0,\"impl-From%3CConnectionError%3E-for-ReadError\"]Al[463,13,464,4034,3239,494,0]0Al[463,13,464,4034,4351,494,0]0Al[463,13,464,1393,4121,494,0]Al[463,13,464,1137,3955,494,0]Al[463,13,464,4039,3243,494,0]Di[463,13,464,4039,3257,494,0,\"impl-From%3CStoppedError%3E-for-WriteError\"]Di[463,13,464,4039,3257,494,0,\"impl-From%3CClosedStream%3E-for-WriteError\"]Dl[463,13,464,4039,3257,494,0,\"impl-From%3CConnectionError%3E-for-WriteError\"]Al[463,13,464,4039,3257,494,0]Al[463,13,464,4039,4120,494,0]0Al[463,13,464,4039,1857,494,0]Ai[463,13,464,0,3234,494,0]Ai[463,13,464,0,4245,494,0]Ai[463,13,464,0,4464,494,0]Ai[463,13,464,0,4098,494,0]Ai[463,13,464,0,4342,494,0]Dh[463,13,464,0,1443,494,0,\"impl-From%3CTransportErrorCode%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\"]Cn[463,13,464,0,1443,494,0,\"impl-From%3CStreamId%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,4915,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,4448,494,0]Ai[463,13,464,0,1867,494,0]Ai[463,13,464,0,4071,494,0]Dm[463,13,464,0,4444,494,0,\"impl-From%3CTransportError%3E-for-ConnectionError\"]Dd[463,13,464,0,4444,494,0,\"impl-From%3CClose%3E-for-ConnectionError\"]Ai[463,13,464,0,4444,494,0]Dj[463,13,464,0,4444,494,0,\"impl-From%3CCloseReason%3E-for-ConnectionError\"]Ai[463,13,464,0,4458,494,0]Ai[463,13,464,0,4467,494,0]Ai[463,13,464,0,4773,494,0]Ai[463,13,464,0,4788,494,0]Ai[463,13,464,0,3941,494,0]0Ai[463,13,464,0,4328,494,0]Ai[463,13,464,0,4114,494,0]Ai[463,13,464,0,4972,494,0]Ai[463,13,464,0,4065,494,0]Ai[463,13,464,0,3931,494,0]Do[463,13,464,0,3931,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]Dj[463,13,464,0,3931,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ai[463,13,464,0,3025,494,0]Ai[463,13,464,0,4441,494,0]0Ai[463,13,464,0,4642,494,0]Ai[463,13,464,0,4077,494,0]0Ai[463,13,464,0,4080,494,0]Ai[463,13,464,0,4085,494,0]Ai[463,13,464,0,4808,494,0]0Ai[463,13,464,0,3220,494,0]Ai[463,13,464,0,4675,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,3936,494,0]Aj[463,13,3635,0,1840,494,0]Aj[463,13,3635,0,4233,494,0]Aj[463,13,3635,0,4737,494,0]Aj[463,13,1693,0,1835,494,0]Ai[463,13,1693,0,497,494,0]Aj[463,13,1693,0,5064,494,0]Aj[463,13,1693,0,3934,494,0]0Aj[463,13,1693,0,4812,494,0]Aj[463,13,1773,0,3252,494,0]Aj[463,13,1773,0,4217,494,0]Df[463,13,1773,0,1169,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]De[463,13,1773,0,1169,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]De[463,13,1773,0,1169,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]Dm[463,13,1773,0,1169,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]D`[463,13,1773,0,1169,494,0,\"impl-From%3COtherError%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Aj[463,13,1773,0,1169,494,0]Aj[463,13,1773,0,4671,494,0]Aj[463,13,1773,0,4910,494,0]Aj[463,13,1773,0,4673,494,0]Am[2358,13,2359,2359,125,494,0]An[2358,13,2359,2359,2250,494,0]An[3096,13,3097,4477,4207,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,4246,494,0]An[3096,13,3097,2305,2260,494,0]An[3096,13,3097,2305,4213,494,0]An[3096,13,3097,2305,4651,494,0]An[3096,13,3097,2305,4224,494,0]An[3096,13,3097,1756,5124,494,0]An[3096,13,3097,4254,5094,494,0]An[3096,13,3097,1392,4465,494,0]An[3096,13,3097,1392,4099,494,0]An[3096,13,3097,1392,4343,494,0]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Dc[3096,13,3097,1810,1444,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Cm[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]An[3096,13,3097,1810,1444,494,0]Co[3096,13,3097,1810,1444,494,0,\"impl-From%3CCode%3E-for-VarInt\"]An[3096,13,3097,1810,4916,494,0]An[3096,13,3097,3061,1153,494,0]An[3096,13,3097,3070,4750,494,0]An[3096,13,3097,1366,1427,494,0]0An[3096,13,3097,1366,4110,494,0]An[3096,13,3097,1366,3233,494,0]An[3096,13,3097,1366,3040,494,0]An[3096,13,3097,1366,4748,494,0]An[3096,13,3097,1366,4804,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,4449,494,0]An[3096,13,3097,1120,3045,494,0]An[3096,13,3097,1120,4241,494,0]An[3096,13,3097,1125,1868,494,0]An[3096,13,3097,1125,3258,494,0]An[3096,13,3097,1125,3940,494,0]An[3096,13,3097,2002,3959,494,0]An[3096,13,3097,2002,4353,494,0]An[3096,13,3097,2002,4075,494,0]An[3096,13,3097,3641,4445,494,0]0An[3096,13,3097,3641,3038,494,0]An[3096,13,3097,3641,4319,494,0]An[3096,13,3097,3641,5001,494,0]An[3096,13,3097,3641,1174,494,0]0An[3096,13,3097,1116,4459,494,0]An[3096,13,3097,3194,4468,494,0]An[3096,13,3097,3194,4774,494,0]An[3096,13,3097,3194,4789,494,0]An[3096,13,3097,3194,3942,494,0]0An[3096,13,3097,1691,4329,494,0]An[3096,13,3097,1691,4116,494,0]An[3096,13,3097,1691,4973,494,0]An[3096,13,3097,1691,4067,494,0]An[3096,13,3097,1691,3932,494,0]Do[3096,13,3097,1691,3932,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ed[3096,13,3097,1691,3932,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]An[3096,13,3097,1356,3026,494,0]An[3096,13,3097,1356,4334,494,0]An[3096,13,3097,1356,3224,494,0]An[3096,13,3097,1356,3247,494,0]An[3096,13,3097,1356,4082,494,0]An[3096,13,3097,1356,4443,494,0]0An[3096,13,3097,1356,4644,494,0]An[3096,13,3097,1356,2253,494,0]An[3096,13,3097,2305,4648,494,0]An[3096,13,3097,2305,2264,494,0]An[3096,13,3097,2305,4078,494,0]0An[3096,13,3097,2305,3926,494,0]An[3096,13,3097,2305,3241,494,0]An[3096,13,3097,1756,4236,494,0]An[3096,13,3097,1756,4457,494,0]An[3096,13,3097,1756,5005,494,0]An[3096,13,3097,1756,2267,494,0]An[3096,13,3097,1756,4746,494,0]0An[3096,13,3097,1784,4447,494,0]An[3096,13,3097,1784,4214,494,0]An[3096,13,3097,1784,4081,494,0]An[3096,13,3097,1784,4086,494,0]Ak[3096,13,3097,0,4357,494,0]0Ak[3096,13,3097,0,4809,494,0]0An[3096,13,3097,4254,3221,494,0]An[3096,13,3097,4254,5099,494,0]An[3096,13,3097,4844,4676,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,4247,494,0]An[3096,13,4957,4957,4855,494,0]An[3096,13,4957,4957,1171,494,0]0An[3096,13,1694,1694,1836,494,0]Am[3096,13,1694,1694,498,494,0]An[3096,13,1694,1694,5065,494,0]An[3096,13,1694,1694,3935,494,0]0An[3096,13,1694,1694,4815,494,0]An[3096,13,1774,1774,3253,494,0]An[3096,13,1774,1774,4218,494,0]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Da[3096,13,1774,0,1170,494,0,\"impl-From%3COtherError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Ak[3096,13,1774,0,1170,494,0]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dn[3096,13,1774,0,1170,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]An[3096,13,1774,1774,4672,494,0]An[3096,13,1774,1774,4911,494,0]An[3096,13,1774,1774,4674,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,3937,494,0]An[3096,13,3636,2358,1841,494,0]An[3096,13,3636,2358,4234,494,0]An[3096,13,3636,3636,4738,494,0]An[3096,13,4706,4706,1172,494,0]An[3096,13,4706,4706,1175,494,0]An[1985,13,1986,1986,3256,494,0]0Am[1985,13,1986,416,4358,494,0]An[1985,13,1986,1986,2279,494,0]An[1985,13,1986,1986,2293,494,0]An[1985,13,1986,1986,4087,494,0]An[1095,13,1096,1096,3015,494,0]An[1095,13,1096,1096,4848,494,0]Am[1095,13,1683,1683,135,494,0]An[1095,13,1381,1381,1190,494,0]An[1095,13,1381,1381,3961,494,0]An[1095,13,1381,1381,4453,494,0]An[1095,13,4174,4174,5050,494,0]An[1095,13,4174,4174,5051,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,3941,495,0]Ai[463,13,464,0,4080,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,4750,495,0]An[3096,13,3097,1366,1427,495,0]An[3096,13,3097,1120,3045,495,0]An[3096,13,3097,1120,4241,495,0]An[3096,13,3097,1125,3258,495,0]An[3096,13,3097,3194,3942,495,0]An[3096,13,3097,2305,4648,495,0]An[3096,13,3097,1756,4746,495,0]An[3096,13,3097,1784,4081,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,3952,496,0]An[1195,13,1196,1196,3928,496,0]An[1195,13,1380,1380,3960,496,0]An[1195,13,1380,1380,1189,496,0]An[1195,13,1380,1380,4354,496,0]Ak[519,13,520,520,3929,496,0]An[3966,13,3967,3967,5006,496,0]Al[463,13,464,3640,4472,496,0]Al[463,13,464,3640,2274,496,0]Ai[463,13,464,0,4206,496,0]Al[463,13,464,4142,4912,496,0]Al[463,13,464,1094,2275,496,0]Al[463,13,464,1094,4640,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,4106,496,0]Al[463,13,464,3640,4111,496,0]Al[463,13,464,3640,4918,496,0]Al[463,13,464,3640,4749,496,0]Al[463,13,464,2304,2259,496,0]Al[463,13,464,2304,4215,496,0]Al[463,13,464,2304,1399,496,0]Al[463,13,464,4142,1418,496,0]Al[463,13,464,4142,3231,496,0]Al[463,13,464,4142,4849,496,0]Al[463,13,464,2336,2263,496,0]Al[463,13,464,2336,3240,496,0]Al[463,13,464,2336,4333,496,0]Ak[463,13,464,1094,503,496,0]Al[463,13,464,1094,4359,496,0]Al[463,13,464,4034,3237,496,0]Al[463,13,464,4034,4856,496,0]Al[463,13,464,4034,4352,496,0]Al[463,13,464,4034,3044,496,0]Al[463,13,464,4034,3239,496,0]Al[463,13,464,4034,4351,496,0]Al[463,13,464,1393,4121,496,0]Al[463,13,464,1137,3955,496,0]Al[463,13,464,4039,3243,496,0]Al[463,13,464,4039,3257,496,0]Al[463,13,464,4039,4120,496,0]Al[463,13,464,4039,1857,496,0]Ai[463,13,464,0,3234,496,0]Ai[463,13,464,0,4245,496,0]Ai[463,13,464,0,4464,496,0]Ai[463,13,464,0,4098,496,0]Ai[463,13,464,0,4342,496,0]Ai[463,13,464,0,1443,496,0]Ai[463,13,464,0,4915,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,4448,496,0]Ai[463,13,464,0,1867,496,0]Ai[463,13,464,0,4071,496,0]Ai[463,13,464,0,4444,496,0]Ai[463,13,464,0,4458,496,0]Ai[463,13,464,0,4467,496,0]Ai[463,13,464,0,4773,496,0]Ai[463,13,464,0,4788,496,0]Ai[463,13,464,0,3941,496,0]Ai[463,13,464,0,4328,496,0]Ai[463,13,464,0,4114,496,0]Ai[463,13,464,0,4972,496,0]Ai[463,13,464,0,4065,496,0]Ai[463,13,464,0,3931,496,0]Ai[463,13,464,0,3025,496,0]Ai[463,13,464,0,4441,496,0]Ai[463,13,464,0,4642,496,0]Ai[463,13,464,0,4077,496,0]Ai[463,13,464,0,4080,496,0]Ai[463,13,464,0,4085,496,0]Ai[463,13,464,0,4808,496,0]Ai[463,13,464,0,3220,496,0]Ai[463,13,464,0,4675,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,3936,496,0]Aj[463,13,3635,0,1840,496,0]Aj[463,13,3635,0,4233,496,0]Aj[463,13,3635,0,4737,496,0]Aj[463,13,1693,0,1835,496,0]Ai[463,13,1693,0,497,496,0]Aj[463,13,1693,0,5064,496,0]Aj[463,13,1693,0,3934,496,0]Aj[463,13,1693,0,4812,496,0]Aj[463,13,1773,0,3252,496,0]Aj[463,13,1773,0,4217,496,0]Aj[463,13,1773,0,1169,496,0]Aj[463,13,1773,0,4671,496,0]Aj[463,13,1773,0,4910,496,0]Aj[463,13,1773,0,4673,496,0]Am[2358,13,2359,2359,125,496,0]An[2358,13,2359,2359,2250,496,0]An[3096,13,3097,4477,4207,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,4246,496,0]An[3096,13,3097,2305,2260,496,0]An[3096,13,3097,2305,4213,496,0]An[3096,13,3097,2305,4651,496,0]An[3096,13,3097,2305,4224,496,0]An[3096,13,3097,1756,5124,496,0]An[3096,13,3097,4254,5094,496,0]An[3096,13,3097,1392,4465,496,0]An[3096,13,3097,1392,4099,496,0]An[3096,13,3097,1392,4343,496,0]An[3096,13,3097,1810,1444,496,0]An[3096,13,3097,1810,4916,496,0]An[3096,13,3097,3061,1153,496,0]An[3096,13,3097,3070,4750,496,0]An[3096,13,3097,1366,1427,496,0]An[3096,13,3097,1366,4110,496,0]An[3096,13,3097,1366,3233,496,0]An[3096,13,3097,1366,3040,496,0]An[3096,13,3097,1366,4748,496,0]An[3096,13,3097,1366,4804,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,4449,496,0]An[3096,13,3097,1120,3045,496,0]An[3096,13,3097,1120,4241,496,0]An[3096,13,3097,1125,1868,496,0]An[3096,13,3097,1125,3258,496,0]An[3096,13,3097,1125,3940,496,0]An[3096,13,3097,2002,3959,496,0]An[3096,13,3097,2002,4353,496,0]An[3096,13,3097,2002,4075,496,0]An[3096,13,3097,3641,4445,496,0]An[3096,13,3097,3641,3038,496,0]An[3096,13,3097,3641,4319,496,0]An[3096,13,3097,3641,5001,496,0]An[3096,13,3097,3641,1174,496,0]An[3096,13,3097,1116,4459,496,0]An[3096,13,3097,3194,4468,496,0]An[3096,13,3097,3194,4774,496,0]An[3096,13,3097,3194,4789,496,0]An[3096,13,3097,3194,3942,496,0]An[3096,13,3097,1691,4329,496,0]An[3096,13,3097,1691,4116,496,0]An[3096,13,3097,1691,4973,496,0]An[3096,13,3097,1691,4067,496,0]An[3096,13,3097,1691,3932,496,0]An[3096,13,3097,1356,3026,496,0]An[3096,13,3097,1356,4334,496,0]An[3096,13,3097,1356,3224,496,0]An[3096,13,3097,1356,3247,496,0]An[3096,13,3097,1356,4082,496,0]An[3096,13,3097,1356,4443,496,0]An[3096,13,3097,1356,4644,496,0]An[3096,13,3097,1356,2253,496,0]An[3096,13,3097,2305,4648,496,0]An[3096,13,3097,2305,2264,496,0]An[3096,13,3097,2305,4078,496,0]An[3096,13,3097,2305,3926,496,0]An[3096,13,3097,2305,3241,496,0]An[3096,13,3097,1756,4236,496,0]An[3096,13,3097,1756,4457,496,0]An[3096,13,3097,1756,5005,496,0]An[3096,13,3097,1756,2267,496,0]An[3096,13,3097,1756,4746,496,0]An[3096,13,3097,1784,4447,496,0]An[3096,13,3097,1784,4214,496,0]An[3096,13,3097,1784,4081,496,0]An[3096,13,3097,1784,4086,496,0]Ak[3096,13,3097,0,4357,496,0]Ak[3096,13,3097,0,4809,496,0]An[3096,13,3097,4254,3221,496,0]An[3096,13,3097,4254,5099,496,0]An[3096,13,3097,4844,4676,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,4247,496,0]An[3096,13,4957,4957,4855,496,0]An[3096,13,4957,4957,1171,496,0]An[3096,13,1694,1694,1836,496,0]Am[3096,13,1694,1694,498,496,0]An[3096,13,1694,1694,5065,496,0]An[3096,13,1694,1694,3935,496,0]An[3096,13,1694,1694,4815,496,0]An[3096,13,1774,1774,3253,496,0]An[3096,13,1774,1774,4218,496,0]Ak[3096,13,1774,0,1170,496,0]An[3096,13,1774,1774,4672,496,0]An[3096,13,1774,1774,4911,496,0]An[3096,13,1774,1774,4674,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,3937,496,0]An[3096,13,3636,2358,1841,496,0]An[3096,13,3636,2358,4234,496,0]An[3096,13,3636,3636,4738,496,0]An[3096,13,4706,4706,1172,496,0]An[3096,13,4706,4706,1175,496,0]An[1985,13,1986,1986,3256,496,0]Am[1985,13,1986,416,4358,496,0]An[1985,13,1986,1986,2279,496,0]An[1985,13,1986,1986,2293,496,0]An[1985,13,1986,1986,4087,496,0]An[1095,13,1096,1096,3015,496,0]An[1095,13,1096,1096,4848,496,0]Am[1095,13,1683,1683,135,496,0]An[1095,13,1381,1381,1190,496,0]An[1095,13,1381,1381,3961,496,0]An[1095,13,1381,1381,4453,496,0]An[1095,13,4174,4174,5050,496,0]An[1095,13,4174,4174,5051,496,0]Am[1095,13,1779,1779,136,496,0]Ac[519,7,520,0,0,0,0]Ae[3966,7,3967,0,0,0,0]Ae[4257,7,4258,0,0,0,0]Ae[2358,7,2359,0,0,0,0]Ae[4768,7,4769,0,0,0,0]Al[3096,13,3097,1120,1407,0,0]Ao[3096,13,3097,2305,4224,2265,0]Ah[463,12,1693,0,4739,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,12,1694,1694,4740,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,4472,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,4106,1415,0]Am[463,13,464,3640,4111,1415,0]Am[463,13,464,2304,1399,1415,0]Am[463,13,464,2336,4333,1415,0]Am[463,13,464,4039,1857,1415,0]?Aj[463,13,464,4034,3237,0,0]Al[3096,13,3097,2002,3238,0,0]Al[3096,13,4957,4957,4855,0,0]Al[3096,13,3097,3070,3018,0,0]Ak[1985,13,1986,416,4358,0,0]Ah[463,12,1693,0,4739,0,0]Al[3096,12,1694,1694,4740,0,0]32Ag[463,13,464,0,4972,0,0]Al[3096,13,3097,1691,4973,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,4354,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Ai[3096,14,4456,0,1186,0,0]Aj[463,13,464,4034,3237,0,0]Aj[463,13,464,4034,4856,0,0]Al[3096,13,3097,2002,3238,0,0]Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4342,3254,0]Aj[463,13,464,0,4675,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4343,3255,0]Ao[3096,13,3097,4844,4676,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,4848,0,0]Ag[463,6,1773,1355,0,0,0]Ah[3096,6,1774,1355,0,0,0]Ae[3096,6,4957,0,0,0,0]Ae[3096,6,4706,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,4034,3044,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,3641,4445,0,0]Al[3096,15,3097,1756,4457,0,0]0Ae[1195,5,1380,0,0,0,0]Ae[1095,5,1381,0,0,0,0]Al[1195,15,1196,1196,3952,0,0]Al[3096,13,3097,2305,4651,0,0]Ab[1195,3,0,0,0,0,0]Ah[463,12,3635,0,4735,0,0]Ak[463,13,3635,0,3012,4735,0]Ak[463,13,3635,0,3936,4735,0]Ak[463,13,3635,0,4233,4735,0]Al[3096,12,3636,3636,4736,0,0]An[3096,13,3636,148,3013,4736,0]Ao[3096,13,3636,1352,3937,4736,0]Ao[3096,13,3636,2358,4234,4736,0]Al[1095,13,1096,1096,4848,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,3926,0,0]An[1195,13,1196,1196,134,1154,0]Ao[1195,13,1196,1196,3952,1154,0]Ao[1195,13,1196,1196,3928,1154,0]Am[463,13,464,3640,3211,1154,0]Am[463,13,464,3640,4918,1154,0]Am[463,13,464,3640,4749,1154,0]Am[463,13,464,2304,2259,1154,0]Am[463,13,464,2304,4215,1154,0]Am[463,13,464,4142,1418,1154,0]Al[463,13,464,1094,503,1154,0]Am[463,13,464,1094,4359,1154,0]Am[463,13,464,4034,4352,1154,0]Am[463,13,464,4034,3044,1154,0]Am[463,13,464,4034,3239,1154,0]Am[463,13,464,4034,4351,1154,0]Am[463,13,464,4039,3257,1154,0]Am[463,13,464,4039,4120,1154,0]Aj[463,13,464,0,1443,1154,0]Aj[463,13,464,0,4915,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,4448,1154,0]Aj[463,13,464,0,1867,1154,0]Aj[463,13,464,0,4071,1154,0]Aj[463,13,464,0,4444,1154,0]Aj[463,13,464,0,4467,1154,0]Aj[463,13,464,0,4773,1154,0]Aj[463,13,464,0,4788,1154,0]Aj[463,13,464,0,3941,1154,0]Aj[463,13,464,0,4328,1154,0]Aj[463,13,464,0,4114,1154,0]Aj[463,13,464,0,4972,1154,0]Aj[463,13,464,0,4065,1154,0]Aj[463,13,464,0,3931,1154,0]Aj[463,13,464,0,3025,1154,0]Aj[463,13,464,0,4441,1154,0]Aj[463,13,464,0,4642,1154,0]Aj[463,13,464,0,4077,1154,0]Aj[463,13,464,0,4080,1154,0]Aj[463,13,464,0,4085,1154,0]Aj[463,13,464,0,4808,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,3936,1154,0]Ak[463,13,3635,0,1840,1154,0]Ak[463,13,3635,0,4233,1154,0]Ak[463,13,1773,0,1169,1154,0]Ak[463,13,1773,0,4671,1154,0]Ak[463,13,1773,0,4910,1154,0]Ak[463,13,1773,0,4673,1154,0]Ao[3096,13,3097,1810,1444,1154,0]Ao[3096,13,3097,1810,4916,1154,0]Ao[3096,13,3097,3070,4750,1154,0]Ao[3096,13,3097,1366,1427,1154,0]Ao[3096,13,3097,1366,4110,1154,0]Ao[3096,13,3097,1366,3233,1154,0]Ao[3096,13,3097,1366,3040,1154,0]Ao[3096,13,3097,1366,4748,1154,0]Ao[3096,13,3097,1366,4804,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,4449,1154,0]Ao[3096,13,3097,1120,3045,1154,0]Ao[3096,13,3097,1120,4241,1154,0]Ao[3096,13,3097,1125,1868,1154,0]Ao[3096,13,3097,1125,3258,1154,0]Ao[3096,13,3097,1125,3940,1154,0]Ao[3096,13,3097,2002,4353,1154,0]Ao[3096,13,3097,2002,4075,1154,0]Ao[3096,13,3097,3641,4445,1154,0]Ao[3096,13,3097,3641,3038,1154,0]Ao[3096,13,3097,3641,4319,1154,0]Ao[3096,13,3097,3641,5001,1154,0]Ao[3096,13,3097,3194,4468,1154,0]Ao[3096,13,3097,3194,4774,1154,0]Ao[3096,13,3097,3194,4789,1154,0]Ao[3096,13,3097,3194,3942,1154,0]Ao[3096,13,3097,1691,4329,1154,0]Ao[3096,13,3097,1691,4116,1154,0]Ao[3096,13,3097,1691,4973,1154,0]Ao[3096,13,3097,1691,4067,1154,0]Ao[3096,13,3097,1691,3932,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,4082,1154,0]Ao[3096,13,3097,1356,4443,1154,0]Ao[3096,13,3097,1356,4644,1154,0]Ao[3096,13,3097,1356,2253,1154,0]Ao[3096,13,3097,2305,4648,1154,0]Ao[3096,13,3097,2305,4078,1154,0]Ao[3096,13,3097,1756,4457,1154,0]Ao[3096,13,3097,1756,5005,1154,0]Ao[3096,13,3097,1756,2267,1154,0]Ao[3096,13,3097,1756,4746,1154,0]Ao[3096,13,3097,1784,4081,1154,0]Ao[3096,13,3097,1784,4086,1154,0]Al[3096,13,3097,0,4357,1154,0]Al[3096,13,3097,0,4809,1154,0]Ao[3096,13,3097,4254,3221,1154,0]Ao[3096,13,3097,4254,5099,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,4247,1154,0]Ao[3096,13,4957,4957,4855,1154,0]Ao[3096,13,4957,4957,1171,1154,0]Al[3096,13,1774,0,1170,1154,0]Ao[3096,13,1774,1774,4672,1154,0]Ao[3096,13,1774,1774,4911,1154,0]Ao[3096,13,1774,1774,4674,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,3937,1154,0]Ao[3096,13,3636,2358,1841,1154,0]Ao[3096,13,3636,2358,4234,1154,0]Ao[3096,13,4706,4706,1175,1154,0]Ao[1985,13,1986,1986,2279,1154,0]Ao[1985,13,1986,1986,2293,1154,0]Ao[1985,13,1986,1986,4087,1154,0]Ao[1095,13,1096,1096,4848,1154,0]Ao[1095,13,1381,1381,4453,1154,0]Ao[1095,13,4174,4174,5050,1154,0]Ao[1095,13,4174,4174,5051,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,4080,1160,0]Ao[3096,13,3097,1784,4081,1160,0]Ai[3096,14,3097,0,4357,0,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ag[463,13,464,0,4085,0,0]Al[3096,13,3097,1784,4086,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,14,1694,1694,1836,0,0]Al[3096,12,3097,1756,4779,0,0]Ao[3096,13,3097,1756,5124,4779,0];Al[1195,13,1380,1380,1189,0,0]Ai[519,13,520,520,3929,0,0]Al[1095,13,1381,1381,1190,0,0]Aj[463,12,464,1994,3200,0,0]Aj[463,13,464,4039,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,4121,1852,0]Am[463,13,464,1137,3955,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,4957,4957,4855,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,3928,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,4706,4706,1172,0,0]87Af[463,5,464,4142,0,0,0]Af[463,5,464,3640,0,0,0]Al[3096,15,3097,1366,3040,0,0]Al[3096,15,3097,2002,3959,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,3952,1405,0]Ao[1195,13,1196,1196,3928,1405,0]Ao[1195,13,1380,1380,3960,1405,0]Ao[1195,13,1380,1380,1189,1405,0]Ao[1195,13,1380,1380,4354,1405,0]Al[519,13,520,520,3929,1405,0]Ao[3966,13,3967,3967,5006,1405,0]Am[463,13,464,3640,4472,1405,0]Am[463,13,464,3640,2274,1405,0]Aj[463,13,464,0,4206,1405,0]Am[463,13,464,4142,4912,1405,0]Am[463,13,464,1094,2275,1405,0]Am[463,13,464,1094,4640,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,4106,1405,0]Am[463,13,464,3640,4111,1405,0]Am[463,13,464,3640,4918,1405,0]Am[463,13,464,3640,4749,1405,0]Am[463,13,464,2304,2259,1405,0]Am[463,13,464,2304,4215,1405,0]Am[463,13,464,2304,1399,1405,0]Am[463,13,464,4142,1418,1405,0]Am[463,13,464,4142,3231,1405,0]Am[463,13,464,4142,4849,1405,0]Am[463,13,464,2336,2263,1405,0]Am[463,13,464,2336,3240,1405,0]Am[463,13,464,2336,4333,1405,0]Al[463,13,464,1094,503,1405,0]Am[463,13,464,1094,4359,1405,0]Am[463,13,464,4034,3237,1405,0]Am[463,13,464,4034,4856,1405,0]Am[463,13,464,4034,4352,1405,0]Am[463,13,464,4034,3044,1405,0]Am[463,13,464,4034,3239,1405,0]Am[463,13,464,4034,4351,1405,0]Am[463,13,464,1393,4121,1405,0]Am[463,13,464,1137,3955,1405,0]Am[463,13,464,4039,3243,1405,0]Am[463,13,464,4039,3257,1405,0]Am[463,13,464,4039,4120,1405,0]Am[463,13,464,4039,1857,1405,0]Aj[463,13,464,0,3234,1405,0]Aj[463,13,464,0,4245,1405,0]Aj[463,13,464,0,4464,1405,0]Aj[463,13,464,0,4098,1405,0]Aj[463,13,464,0,4342,1405,0]Aj[463,13,464,0,1443,1405,0]Aj[463,13,464,0,4915,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,4448,1405,0]Aj[463,13,464,0,1867,1405,0]Aj[463,13,464,0,4071,1405,0]Aj[463,13,464,0,4444,1405,0]Aj[463,13,464,0,4458,1405,0]Aj[463,13,464,0,4467,1405,0]Aj[463,13,464,0,4773,1405,0]Aj[463,13,464,0,4788,1405,0]Aj[463,13,464,0,3941,1405,0]Aj[463,13,464,0,4328,1405,0]Aj[463,13,464,0,4114,1405,0]Aj[463,13,464,0,4972,1405,0]Aj[463,13,464,0,4065,1405,0]Aj[463,13,464,0,3931,1405,0]Aj[463,13,464,0,3025,1405,0]Aj[463,13,464,0,4441,1405,0]Aj[463,13,464,0,4642,1405,0]Aj[463,13,464,0,4077,1405,0]Aj[463,13,464,0,4080,1405,0]Aj[463,13,464,0,4085,1405,0]Aj[463,13,464,0,4808,1405,0]Aj[463,13,464,0,3220,1405,0]Aj[463,13,464,0,4675,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,3936,1405,0]Ak[463,13,3635,0,1840,1405,0]Ak[463,13,3635,0,4233,1405,0]Ak[463,13,3635,0,4737,1405,0]Ak[463,13,1693,0,1835,1405,0]Aj[463,13,1693,0,497,1405,0]Ak[463,13,1693,0,5064,1405,0]Ak[463,13,1693,0,3934,1405,0]Ak[463,13,1693,0,4812,1405,0]Ak[463,13,1773,0,3252,1405,0]Ak[463,13,1773,0,4217,1405,0]Ak[463,13,1773,0,1169,1405,0]Ak[463,13,1773,0,4671,1405,0]Ak[463,13,1773,0,4910,1405,0]Ak[463,13,1773,0,4673,1405,0]An[2358,13,2359,2359,125,1405,0]Ao[2358,13,2359,2359,2250,1405,0]Ao[3096,13,3097,4477,4207,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,4246,1405,0]Ao[3096,13,3097,2305,2260,1405,0]Ao[3096,13,3097,2305,4213,1405,0]Ao[3096,13,3097,2305,4651,1405,0]Ao[3096,13,3097,2305,4224,1405,0]Ao[3096,13,3097,1756,5124,1405,0]Ao[3096,13,3097,4254,5094,1405,0]Ao[3096,13,3097,1392,4465,1405,0]Ao[3096,13,3097,1392,4099,1405,0]Ao[3096,13,3097,1392,4343,1405,0]Ao[3096,13,3097,1810,1444,1405,0]Ao[3096,13,3097,1810,4916,1405,0]Ao[3096,13,3097,3061,1153,1405,0]Ao[3096,13,3097,3070,4750,1405,0]Ao[3096,13,3097,1366,1427,1405,0]Ao[3096,13,3097,1366,4110,1405,0]Ao[3096,13,3097,1366,3233,1405,0]Ao[3096,13,3097,1366,3040,1405,0]Ao[3096,13,3097,1366,4748,1405,0]Ao[3096,13,3097,1366,4804,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,4449,1405,0]Ao[3096,13,3097,1120,3045,1405,0]Ao[3096,13,3097,1120,4241,1405,0]Ao[3096,13,3097,1125,1868,1405,0]Ao[3096,13,3097,1125,3258,1405,0]Ao[3096,13,3097,1125,3940,1405,0]Ao[3096,13,3097,2002,3959,1405,0]Ao[3096,13,3097,2002,4353,1405,0]Ao[3096,13,3097,2002,4075,1405,0]Ao[3096,13,3097,3641,4445,1405,0]Ao[3096,13,3097,3641,3038,1405,0]Ao[3096,13,3097,3641,4319,1405,0]Ao[3096,13,3097,3641,5001,1405,0]Ao[3096,13,3097,3641,1174,1405,0]Ao[3096,13,3097,1116,4459,1405,0]Ao[3096,13,3097,3194,4468,1405,0]Ao[3096,13,3097,3194,4774,1405,0]Ao[3096,13,3097,3194,4789,1405,0]Ao[3096,13,3097,3194,3942,1405,0]Ao[3096,13,3097,1691,4329,1405,0]Ao[3096,13,3097,1691,4116,1405,0]Ao[3096,13,3097,1691,4973,1405,0]Ao[3096,13,3097,1691,4067,1405,0]Ao[3096,13,3097,1691,3932,1405,0]Ao[3096,13,3097,1356,3026,1405,0]Ao[3096,13,3097,1356,4334,1405,0]Ao[3096,13,3097,1356,3224,1405,0]Ao[3096,13,3097,1356,3247,1405,0]Ao[3096,13,3097,1356,4082,1405,0]Ao[3096,13,3097,1356,4443,1405,0]Ao[3096,13,3097,1356,4644,1405,0]Ao[3096,13,3097,1356,2253,1405,0]Ao[3096,13,3097,2305,4648,1405,0]Ao[3096,13,3097,2305,2264,1405,0]Ao[3096,13,3097,2305,4078,1405,0]Ao[3096,13,3097,2305,3926,1405,0]Ao[3096,13,3097,2305,3241,1405,0]Ao[3096,13,3097,1756,4236,1405,0]Ao[3096,13,3097,1756,4457,1405,0]Ao[3096,13,3097,1756,5005,1405,0]Ao[3096,13,3097,1756,2267,1405,0]Ao[3096,13,3097,1756,4746,1405,0]Ao[3096,13,3097,1784,4447,1405,0]Ao[3096,13,3097,1784,4214,1405,0]Ao[3096,13,3097,1784,4081,1405,0]Ao[3096,13,3097,1784,4086,1405,0]Al[3096,13,3097,0,4357,1405,0]Al[3096,13,3097,0,4809,1405,0]Ao[3096,13,3097,4254,3221,1405,0]Ao[3096,13,3097,4254,5099,1405,0]Ao[3096,13,3097,4844,4676,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,4247,1405,0]Ao[3096,13,4957,4957,4855,1405,0]Ao[3096,13,4957,4957,1171,1405,0]Ao[3096,13,1694,1694,1836,1405,0]An[3096,13,1694,1694,498,1405,0]Ao[3096,13,1694,1694,5065,1405,0]Ao[3096,13,1694,1694,3935,1405,0]Ao[3096,13,1694,1694,4815,1405,0]Ao[3096,13,1774,1774,3253,1405,0]Ao[3096,13,1774,1774,4218,1405,0]Al[3096,13,1774,0,1170,1405,0]Ao[3096,13,1774,1774,4672,1405,0]Ao[3096,13,1774,1774,4911,1405,0]Ao[3096,13,1774,1774,4674,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,3937,1405,0]Ao[3096,13,3636,2358,1841,1405,0]Ao[3096,13,3636,2358,4234,1405,0]Ao[3096,13,3636,3636,4738,1405,0]Ao[3096,13,4706,4706,1172,1405,0]Ao[3096,13,4706,4706,1175,1405,0]Ao[1985,13,1986,1986,3256,1405,0]An[1985,13,1986,416,4358,1405,0]Ao[1985,13,1986,1986,2279,1405,0]Ao[1985,13,1986,1986,2293,1405,0]Ao[1985,13,1986,1986,4087,1405,0]Ao[1095,13,1096,1096,3015,1405,0]Ao[1095,13,1096,1096,4848,1405,0]An[1095,13,1683,1683,135,1405,0]Ao[1095,13,1381,1381,1190,1405,0]Ao[1095,13,1381,1381,3961,1405,0]Ao[1095,13,1381,1381,4453,1405,0]Ao[1095,13,4174,4174,5050,1405,0]Ao[1095,13,4174,4174,5051,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[4768,7,4769,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,4808,0,0]Ag[463,14,464,0,3217,0,0]Ag[463,14,464,0,4114,0,0]5Ai[3096,13,3097,0,4809,0,0]Al[3096,14,3097,1382,3218,0,0]Al[3096,14,3097,1691,4116,0,0]Ai[3096,14,3097,0,4357,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,4808,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,4457,0,0]Al[3096,13,3097,0,4809,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,4808,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,4809,3022,0]Ao[3096,13,3097,3097,2282,3022,0]Al[3096,12,1689,1689,3022,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Al[1095,13,1381,1381,3961,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,4342,3254,0]Aj[463,13,464,0,4675,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4343,3255,0]Ao[3096,13,3097,4844,4676,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,4456,0,4680,0,0]Ag[463,14,464,0,4441,0,0]Ag[463,14,464,0,4642,0,0]Al[3096,14,3097,1356,4443,0,0]Al[3096,14,3097,1356,4644,0,0]Ai[3096,14,3097,0,4357,0,0]Ai[3096,14,1173,0,4321,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[4768,7,4769,0,0,0,0]Am[463,13,464,3640,4749,1162,0]Am[463,13,464,4034,4352,1162,0]Am[463,13,464,4034,3044,1162,0]Am[463,13,464,4034,3239,1162,0]Am[463,13,464,4034,4351,1162,0]Am[463,13,464,4039,3257,1162,0]Am[463,13,464,4039,4120,1162,0]Aj[463,13,464,0,4444,1162,0]Ao[3096,13,3097,3641,4445,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,4107,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,4448,0,0]Al[3096,14,3097,1382,3042,0,0]Al[3096,14,3097,1382,4449,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,4750,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,4457,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,4848,0,0]Af[463,5,464,3640,0,0,0]5454Ag[463,10,464,1994,0,0,0];:Aj[463,15,464,4039,3257,0,0]Af[463,5,464,4039,0,0,0]Al[3096,15,3097,1125,3258,0,0]Al[3096,15,3097,1125,3940,0,0]Al[3096,15,3097,2002,3959,0,0]Ah[3096,5,3097,2002,0,0,0]Aj[463,15,464,4034,4352,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,4963,0,0]Al[3096,12,3097,4254,4964,0,0]Ao[3096,13,3097,4254,5094,4964,0]Ao[3096,13,3097,4254,5099,4964,0]Ak[1195,14,1196,1196,134,0,0]An[1195,13,1196,1196,134,4320,0]An[2358,13,2359,2359,125,4320,0]Ak[2358,14,2359,2359,125,0,0]Ao[1095,13,1096,1096,3015,4320,0]An[1095,13,1683,1683,135,4320,0]An[1095,13,1779,1779,136,4320,0]Aj[463,13,464,0,1443,3208,0]Aj[463,13,464,0,1426,3208,0]Aj[463,13,464,0,3941,3208,0]Aj[463,13,464,0,4080,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,4750,3208,0]Ao[3096,13,3097,1366,1427,3208,0]Ao[3096,13,3097,1120,3045,3208,0]Ao[3096,13,3097,1120,4241,3208,0]Ao[3096,13,3097,1125,3258,3208,0]Ao[3096,13,3097,3194,3942,3208,0]Ao[3096,13,3097,2305,4648,3208,0]Ao[3096,13,3097,1756,4746,3208,0]Ao[3096,13,3097,1784,4081,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,3960,1826,0]Ao[1195,13,1380,1380,1189,1826,0]Al[519,13,520,520,3929,1826,0]Aj[463,13,464,0,4206,1826,0]Am[463,13,464,2304,4215,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,4448,1826,0]Aj[463,13,464,0,1867,1826,0]Aj[463,13,464,0,4071,1826,0]Aj[463,13,464,0,4467,1826,0]Aj[463,13,464,0,4773,1826,0]Aj[463,13,464,0,4788,1826,0]Aj[463,13,464,0,3941,1826,0]Aj[463,13,464,0,4328,1826,0]Aj[463,13,464,0,4972,1826,0]Aj[463,13,464,0,4675,1826,0]Ak[463,13,3635,0,3012,1826,0]Ak[463,13,3635,0,3936,1826,0]Ak[463,13,3635,0,4233,1826,0]Ak[463,13,3635,0,4737,1826,0]Ao[3096,13,3097,4477,4207,1826,0]Ao[3096,13,3097,4254,5094,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,4449,1826,0]Ao[3096,13,3097,1125,1868,1826,0]Ao[3096,13,3097,2002,4353,1826,0]Ao[3096,13,3097,2002,4075,1826,0]Ao[3096,13,3097,3194,4468,1826,0]Ao[3096,13,3097,3194,4774,1826,0]Ao[3096,13,3097,3194,4789,1826,0]Ao[3096,13,3097,3194,3942,1826,0]Ao[3096,13,3097,1691,4329,1826,0]Ao[3096,13,3097,1691,4973,1826,0]Ao[3096,13,3097,4254,5099,1826,0]Ao[3096,13,3097,4844,4676,1826,0]An[3096,13,3636,148,3013,1826,0]Ao[3096,13,3636,1352,3937,1826,0]Ao[3096,13,3636,2358,4234,1826,0]Ao[3096,13,3636,3636,4738,1826,0]Ao[1985,13,1986,1986,2279,1826,0]Ao[1095,13,1381,1381,1190,1826,0]Ao[1095,13,1381,1381,4453,1826,0]Al[3096,13,3097,1784,4214,0,0]Al[3096,13,3097,1756,4236,0,0]Al[3096,13,3097,1756,4457,0,0]Al[3096,14,3097,1756,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Ai[3096,14,4456,0,1186,0,0]Ai[3096,14,4456,0,4680,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,4034,3237,0,0]Aj[463,13,464,4034,4856,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,4467,0,0]Al[3096,13,3097,3194,4468,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,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Ai[3096,14,4456,0,4680,0,0]Aj[463,13,464,4039,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,3952,118,0]An[1195,13,1196,1196,3928,118,0]An[1195,13,1380,1380,3960,118,0]An[1195,13,1380,1380,1189,118,0]An[1195,13,1380,1380,4354,118,0]Ak[519,13,520,520,3929,118,0]An[3966,13,3967,3967,5006,118,0]Al[463,13,464,3640,4472,118,0]Al[463,13,464,3640,2274,118,0]Ai[463,13,464,0,4206,118,0]Al[463,13,464,4142,4912,118,0]Al[463,13,464,1094,2275,118,0]Al[463,13,464,1094,4640,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,4106,118,0]Al[463,13,464,3640,4111,118,0]Al[463,13,464,3640,4918,118,0]Al[463,13,464,3640,4749,118,0]Al[463,13,464,2304,2259,118,0]Al[463,13,464,2304,4215,118,0]Al[463,13,464,2304,1399,118,0]Al[463,13,464,4142,1418,118,0]Al[463,13,464,4142,3231,118,0]Al[463,13,464,4142,4849,118,0]Al[463,13,464,2336,2263,118,0]Al[463,13,464,2336,3240,118,0]Al[463,13,464,2336,4333,118,0]Ak[463,13,464,1094,503,118,0]Al[463,13,464,1094,4359,118,0]Al[463,13,464,4034,3237,118,0]Al[463,13,464,4034,4856,118,0]Al[463,13,464,4034,4352,118,0]Al[463,13,464,4034,3044,118,0]Al[463,13,464,4034,3239,118,0]Al[463,13,464,4034,4351,118,0]Al[463,13,464,1393,4121,118,0]Al[463,13,464,1137,3955,118,0]Al[463,13,464,4039,3243,118,0]Al[463,13,464,4039,3257,118,0]Al[463,13,464,4039,4120,118,0]Al[463,13,464,4039,1857,118,0]Ai[463,13,464,0,3234,118,0]Ai[463,13,464,0,4245,118,0]Ai[463,13,464,0,4464,118,0]Ai[463,13,464,0,4098,118,0]Ai[463,13,464,0,4342,118,0]Ai[463,13,464,0,1443,118,0]Ai[463,13,464,0,4915,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,4448,118,0]Ai[463,13,464,0,1867,118,0]Ai[463,13,464,0,4071,118,0]Ai[463,13,464,0,4444,118,0]Ai[463,13,464,0,4458,118,0]Ai[463,13,464,0,4467,118,0]Ai[463,13,464,0,4773,118,0]Ai[463,13,464,0,4788,118,0]Ai[463,13,464,0,3941,118,0]Ai[463,13,464,0,4328,118,0]Ai[463,13,464,0,4114,118,0]Ai[463,13,464,0,4972,118,0]Ai[463,13,464,0,4065,118,0]Ai[463,13,464,0,3931,118,0]Ai[463,13,464,0,3025,118,0]Ai[463,13,464,0,4441,118,0]Ai[463,13,464,0,4642,118,0]Ai[463,13,464,0,4077,118,0]Ai[463,13,464,0,4080,118,0]Ai[463,13,464,0,4085,118,0]Ai[463,13,464,0,4808,118,0]Ai[463,13,464,0,3220,118,0]Ai[463,13,464,0,4675,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,3936,118,0]Aj[463,13,3635,0,1840,118,0]Aj[463,13,3635,0,4233,118,0]Aj[463,13,3635,0,4737,118,0]Aj[463,13,1693,0,1835,118,0]Ai[463,13,1693,0,497,118,0]Aj[463,13,1693,0,5064,118,0]Aj[463,13,1693,0,3934,118,0]Aj[463,13,1693,0,4812,118,0]Aj[463,13,1773,0,3252,118,0]Aj[463,13,1773,0,4217,118,0]Aj[463,13,1773,0,1169,118,0]Aj[463,13,1773,0,4671,118,0]Aj[463,13,1773,0,4910,118,0]Aj[463,13,1773,0,4673,118,0]Am[2358,13,2359,2359,125,118,0]An[2358,13,2359,2359,2250,118,0]An[3096,13,3097,4477,4207,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,4246,118,0]An[3096,13,3097,2305,2260,118,0]An[3096,13,3097,2305,4213,118,0]An[3096,13,3097,2305,4651,118,0]An[3096,13,3097,2305,4224,118,0]An[3096,13,3097,1756,5124,118,0]An[3096,13,3097,4254,5094,118,0]An[3096,13,3097,1392,4465,118,0]An[3096,13,3097,1392,4099,118,0]An[3096,13,3097,1392,4343,118,0]An[3096,13,3097,1810,1444,118,0]An[3096,13,3097,1810,4916,118,0]An[3096,13,3097,3061,1153,118,0]An[3096,13,3097,3070,4750,118,0]An[3096,13,3097,1366,1427,118,0]An[3096,13,3097,1366,4110,118,0]An[3096,13,3097,1366,3233,118,0]An[3096,13,3097,1366,3040,118,0]An[3096,13,3097,1366,4748,118,0]An[3096,13,3097,1366,4804,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,4449,118,0]An[3096,13,3097,1120,3045,118,0]An[3096,13,3097,1120,4241,118,0]An[3096,13,3097,1125,1868,118,0]An[3096,13,3097,1125,3258,118,0]An[3096,13,3097,1125,3940,118,0]An[3096,13,3097,2002,3959,118,0]An[3096,13,3097,2002,4353,118,0]An[3096,13,3097,2002,4075,118,0]An[3096,13,3097,3641,4445,118,0]An[3096,13,3097,3641,3038,118,0]An[3096,13,3097,3641,4319,118,0]An[3096,13,3097,3641,5001,118,0]An[3096,13,3097,3641,1174,118,0]An[3096,13,3097,1116,4459,118,0]An[3096,13,3097,3194,4468,118,0]An[3096,13,3097,3194,4774,118,0]An[3096,13,3097,3194,4789,118,0]An[3096,13,3097,3194,3942,118,0]An[3096,13,3097,1691,4329,118,0]An[3096,13,3097,1691,4116,118,0]An[3096,13,3097,1691,4973,118,0]An[3096,13,3097,1691,4067,118,0]An[3096,13,3097,1691,3932,118,0]An[3096,13,3097,1356,3026,118,0]An[3096,13,3097,1356,4334,118,0]An[3096,13,3097,1356,3224,118,0]An[3096,13,3097,1356,3247,118,0]An[3096,13,3097,1356,4082,118,0]An[3096,13,3097,1356,4443,118,0]An[3096,13,3097,1356,4644,118,0]An[3096,13,3097,1356,2253,118,0]An[3096,13,3097,2305,4648,118,0]An[3096,13,3097,2305,2264,118,0]An[3096,13,3097,2305,4078,118,0]An[3096,13,3097,2305,3926,118,0]An[3096,13,3097,2305,3241,118,0]An[3096,13,3097,1756,4236,118,0]An[3096,13,3097,1756,4457,118,0]An[3096,13,3097,1756,5005,118,0]An[3096,13,3097,1756,2267,118,0]An[3096,13,3097,1756,4746,118,0]An[3096,13,3097,1784,4447,118,0]An[3096,13,3097,1784,4214,118,0]An[3096,13,3097,1784,4081,118,0]An[3096,13,3097,1784,4086,118,0]Ak[3096,13,3097,0,4357,118,0]Ak[3096,13,3097,0,4809,118,0]An[3096,13,3097,4254,3221,118,0]An[3096,13,3097,4254,5099,118,0]An[3096,13,3097,4844,4676,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,4247,118,0]An[3096,13,4957,4957,4855,118,0]An[3096,13,4957,4957,1171,118,0]An[3096,13,1694,1694,1836,118,0]Am[3096,13,1694,1694,498,118,0]An[3096,13,1694,1694,5065,118,0]An[3096,13,1694,1694,3935,118,0]An[3096,13,1694,1694,4815,118,0]An[3096,13,1774,1774,3253,118,0]An[3096,13,1774,1774,4218,118,0]Ak[3096,13,1774,0,1170,118,0]An[3096,13,1774,1774,4672,118,0]An[3096,13,1774,1774,4911,118,0]An[3096,13,1774,1774,4674,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,3937,118,0]An[3096,13,3636,2358,1841,118,0]An[3096,13,3636,2358,4234,118,0]An[3096,13,3636,3636,4738,118,0]An[3096,13,4706,4706,1172,118,0]An[3096,13,4706,4706,1175,118,0]An[1985,13,1986,1986,3256,118,0]Am[1985,13,1986,416,4358,118,0]An[1985,13,1986,1986,2279,118,0]An[1985,13,1986,1986,2293,118,0]An[1985,13,1986,1986,4087,118,0]An[1095,13,1096,1096,3015,118,0]An[1095,13,1096,1096,4848,118,0]Am[1095,13,1683,1683,135,118,0]An[1095,13,1381,1381,1190,118,0]An[1095,13,1381,1381,3961,118,0]An[1095,13,1381,1381,4453,118,0]An[1095,13,4174,4174,5050,118,0]An[1095,13,4174,4174,5051,118,0]Am[1095,13,1779,1779,136,118,0]Aj[463,13,464,3640,4918,0,0]Aj[463,13,464,1094,4359,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,0,0]Al[3096,14,3097,1756,5005,0,0]Ai[3096,14,4745,0,4810,0,0]Ah[3096,14,4456,0,499,0,0]Ai[3096,14,4456,0,1184,0,0]Af[463,5,464,3640,0,0,0]Al[1195,15,1196,1196,3928,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,4749,0,0]Al[3096,15,3097,3070,4750,0,0]Af[463,5,464,2304,0,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,2002,3959,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,4808,0,0]Ai[3096,19,3097,0,4809,0,0]=Ah[463,12,1693,0,4115,0,0]>Ak[463,13,1773,0,4673,4115,0]>Al[3096,12,1694,1694,4117,0,0]>Ao[3096,13,1774,1774,4674,4117,0]Ao[1095,13,4174,4174,5051,4117,0]An[2358,13,2359,2359,125,3943,0]Ao[2358,13,2359,2359,2250,3943,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Ag[463,13,464,0,4114,0,0]Al[3096,13,3097,1691,4116,0,0]Aj[463,13,464,1994,4316,0,0]0>=Al[1095,13,1381,1381,4453,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]Al[3096,13,3097,3641,3212,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]43Ak[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,4254,5094,0,0]Al[3096,13,3097,4254,5099,0,0]Aj[463,13,464,4039,3243,0,0]Al[3096,13,3097,2002,3244,0,0]=Al[1195,14,1380,1380,1189,0,0]Ao[1095,13,1096,1096,4848,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,4213,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,4748,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,4444,0,0]Al[3096,15,3097,3641,4445,0,0]Af[463,5,464,3640,0,0,0]Aj[463,15,464,4034,3044,0,0]Aj[463,15,464,4034,3239,0,0]Aj[463,15,464,4039,3257,0,0]Aj[463,15,464,4039,4120,0,0]An[1195,13,1196,1196,134,4212,0]Ao[1195,13,1196,1196,3952,4212,0]Ao[1195,13,1196,1196,3928,4212,0]Am[463,13,464,3640,3211,4212,0]Am[463,13,464,3640,4918,4212,0]Am[463,13,464,3640,4749,4212,0]Am[463,13,464,2304,2259,4212,0]Am[463,13,464,2304,4215,4212,0]Am[463,13,464,4142,1418,4212,0]Al[463,13,464,1094,503,4212,0]Am[463,13,464,1094,4359,4212,0]Am[463,13,464,4034,4352,4212,0]Am[463,13,464,4034,3044,4212,0]Am[463,13,464,4034,3239,4212,0]Am[463,13,464,4034,4351,4212,0]Am[463,13,464,4039,3257,4212,0]Am[463,13,464,4039,4120,4212,0]Aj[463,13,464,0,1443,4212,0]Aj[463,13,464,0,4915,4212,0]Aj[463,13,464,0,1426,4212,0]Aj[463,13,464,0,2294,4212,0]Aj[463,13,464,0,3217,4212,0]Aj[463,13,464,0,3041,4212,0]Aj[463,13,464,0,4448,4212,0]Aj[463,13,464,0,1867,4212,0]Aj[463,13,464,0,4071,4212,0]Aj[463,13,464,0,4444,4212,0]Aj[463,13,464,0,4467,4212,0]Aj[463,13,464,0,4773,4212,0]Aj[463,13,464,0,4788,4212,0]Aj[463,13,464,0,3941,4212,0]Aj[463,13,464,0,4328,4212,0]Aj[463,13,464,0,4114,4212,0]Aj[463,13,464,0,4972,4212,0]Aj[463,13,464,0,4065,4212,0]Aj[463,13,464,0,3931,4212,0]Aj[463,13,464,0,3025,4212,0]Aj[463,13,464,0,4441,4212,0]Aj[463,13,464,0,4642,4212,0]Aj[463,13,464,0,4077,4212,0]Aj[463,13,464,0,4080,4212,0]Aj[463,13,464,0,4085,4212,0]Aj[463,13,464,0,4808,4212,0]Aj[463,13,464,0,3220,4212,0]Ai[463,13,464,0,510,4212,0]Ai[463,13,464,0,126,4212,0]Aj[463,13,464,0,2281,4212,0]Aj[463,13,3635,0,120,4212,0]Ak[463,13,3635,0,3012,4212,0]Ak[463,13,3635,0,1156,4212,0]Ak[463,13,3635,0,3936,4212,0]Ak[463,13,3635,0,1840,4212,0]Ak[463,13,3635,0,4233,4212,0]Ak[463,13,1773,0,1169,4212,0]Ak[463,13,1773,0,4671,4212,0]Ak[463,13,1773,0,4910,4212,0]Ak[463,13,1773,0,4673,4212,0]Ao[3096,13,3097,1810,1444,4212,0]Ao[3096,13,3097,1810,4916,4212,0]Ao[3096,13,3097,3070,4750,4212,0]Ao[3096,13,3097,1366,1427,4212,0]Ao[3096,13,3097,1366,4110,4212,0]Ao[3096,13,3097,1366,3233,4212,0]Ao[3096,13,3097,1366,3040,4212,0]Ao[3096,13,3097,1366,4748,4212,0]Ao[3096,13,3097,1366,4804,4212,0]Ao[3096,13,3097,1366,3207,4212,0]Ao[3096,13,3097,1382,2295,4212,0]Ao[3096,13,3097,1382,3218,4212,0]Ao[3096,13,3097,1382,3042,4212,0]Ao[3096,13,3097,1382,4449,4212,0]Ao[3096,13,3097,1120,3045,4212,0]Ao[3096,13,3097,1120,4241,4212,0]Ao[3096,13,3097,1125,1868,4212,0]Ao[3096,13,3097,1125,3258,4212,0]Ao[3096,13,3097,1125,3940,4212,0]Ao[3096,13,3097,2002,4353,4212,0]Ao[3096,13,3097,2002,4075,4212,0]Ao[3096,13,3097,3641,4445,4212,0]Ao[3096,13,3097,3641,3038,4212,0]Ao[3096,13,3097,3641,4319,4212,0]Ao[3096,13,3097,3641,5001,4212,0]Ao[3096,13,3097,3194,4468,4212,0]Ao[3096,13,3097,3194,4774,4212,0]Ao[3096,13,3097,3194,4789,4212,0]Ao[3096,13,3097,3194,3942,4212,0]Ao[3096,13,3097,1691,4329,4212,0]Ao[3096,13,3097,1691,4116,4212,0]Ao[3096,13,3097,1691,4973,4212,0]Ao[3096,13,3097,1691,4067,4212,0]Ao[3096,13,3097,1691,3932,4212,0]Ao[3096,13,3097,1356,3026,4212,0]Ao[3096,13,3097,1356,3224,4212,0]Ao[3096,13,3097,1356,3247,4212,0]Ao[3096,13,3097,1356,4082,4212,0]Ao[3096,13,3097,1356,4443,4212,0]Ao[3096,13,3097,1356,4644,4212,0]Ao[3096,13,3097,1356,2253,4212,0]Ao[3096,13,3097,2305,4648,4212,0]Ao[3096,13,3097,2305,4078,4212,0]Ao[3096,13,3097,1756,4457,4212,0]Ao[3096,13,3097,1756,5005,4212,0]Ao[3096,13,3097,1756,2267,4212,0]Ao[3096,13,3097,1756,4746,4212,0]Ao[3096,13,3097,1784,4081,4212,0]Ao[3096,13,3097,1784,4086,4212,0]Al[3096,13,3097,0,4357,4212,0]Al[3096,13,3097,0,4809,4212,0]Ao[3096,13,3097,4254,3221,4212,0]Ao[3096,13,3097,4254,5099,4212,0]An[3096,13,3097,3097,511,4212,0]An[3096,13,3097,3097,127,4212,0]Ao[3096,13,3097,3097,2282,4212,0]Ao[3096,13,3097,3097,3024,4212,0]Ao[3096,13,1689,1689,4247,4212,0]Ao[3096,13,4957,4957,4855,4212,0]Ao[3096,13,4957,4957,1171,4212,0]Al[3096,13,1774,0,1170,4212,0]Ao[3096,13,1774,1774,4672,4212,0]Ao[3096,13,1774,1774,4911,4212,0]Ao[3096,13,1774,1774,4674,4212,0]Am[3096,13,3636,148,121,4212,0]An[3096,13,3636,148,3013,4212,0]Ao[3096,13,3636,1352,1157,4212,0]Ao[3096,13,3636,1352,3937,4212,0]Ao[3096,13,3636,2358,1841,4212,0]Ao[3096,13,3636,2358,4234,4212,0]Ao[3096,13,4706,4706,1175,4212,0]Ao[1985,13,1986,1986,2279,4212,0]Ao[1985,13,1986,1986,2293,4212,0]Ao[1985,13,1986,1986,4087,4212,0]Ao[1095,13,1096,1096,4848,4212,0]Ao[1095,13,1381,1381,4453,4212,0]Ao[1095,13,4174,4174,5050,4212,0]Ao[1095,13,4174,4174,5051,4212,0]Af[463,7,464,1994,0,0,0]Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,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[4257,7,4258,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,4353,0,0]Al[1195,13,1380,1380,1189,0,0]Al[1195,14,1380,1380,3960,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4121,1852,0]Am[463,13,464,1137,3955,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,4444,0,0]Al[3096,15,3097,3641,4445,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,3641,1174,0,0]1Ag[463,15,464,0,4077,0,0]Al[3096,15,3097,2305,4078,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,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,4844,0,0,0]Ah[3096,5,3097,4844,0,0,0]Al[3096,15,4706,4706,1172,0,0]Al[3096,15,3097,1366,4748,0,0]6Al[3096,15,3097,1756,4457,0,0]Ag[463,12,464,0,2287,0,0]Aj[463,13,464,0,4206,2287,0]Aj[463,13,464,0,4098,2287,0]Al[3096,12,3097,1392,2288,0,0]Ao[3096,13,3097,4477,4207,2288,0]Ao[3096,13,3097,1392,4099,2288,0]Ae[3966,7,3967,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,4330,0]An[2358,13,2359,2359,125,4330,0]Ao[2358,13,2359,2359,2250,4330,0]Ao[1095,13,1096,1096,3015,4330,0]An[1095,13,1683,1683,135,4330,0]An[1095,13,1779,1779,136,4330,0]Ak[1985,13,1986,416,4358,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,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[4257,7,4258,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,4114,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4116,0,0]Al[3096,13,3097,1691,4067,0,0]Ag[463,14,464,0,4114,0,0]Al[3096,14,3097,1691,4116,0,0]53Aj[463,13,464,4039,3243,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Ag[463,15,464,0,4444,0,0]Al[3096,15,3097,1366,4748,0,0]Al[3096,15,3097,3641,4445,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,4077,0,0]Al[3096,15,3097,2305,4078,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,4749,0,0]Al[3096,15,3097,3070,4750,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Ah[463,14,3635,0,4737,0,0]Al[3096,14,3636,3636,4738,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[4768,3,0,0,0,0,0]Ao[1095,13,1096,1096,4848,3050,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,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,4241,0,0]4365Al[3096,15,4706,4706,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,3952,0,0]Ac[463,5,464,0,0,0,0]Ae[3096,5,3097,0,0,0,0]Ag[463,15,464,0,4077,0,0]Ag[463,5,1693,1694,0,0,0]Al[3096,15,3097,2305,4078,0,0]Al[3096,15,3097,1756,4746,0,0]Ae[3096,5,1694,0,0,0,0]An[1195,13,1196,1196,134,4320,0]An[2358,13,2359,2359,125,4320,0]Ao[1095,13,1096,1096,3015,4320,0]An[1095,13,1683,1683,135,4320,0]An[1095,13,1779,1779,136,4320,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ag[463,13,464,0,1443,0,0]Al[3096,13,3097,1810,1444,0,0]Aj[463,14,464,2304,4215,0,0]Aj[463,13,464,3640,4918,0,0]Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,0,0]Ag[463,13,464,0,4206,0,0]Al[3096,13,3097,4477,4207,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,4671,0,0]Ah[463,13,1773,0,4673,0,0]Al[3096,13,1774,1774,4672,0,0]Al[3096,13,1774,1774,4674,0,0]45;:Ao[3966,13,3967,3967,5006,4802,0]Ag[463,13,464,0,4458,0,0]Al[3096,13,3097,1116,4459,0,0]Ae[1095,6,1096,0,0,0,0]Af[463,5,464,4142,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,4957,0,0,0,0]Af[463,5,464,4034,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Al[3096,15,4706,4706,1172,0,0]Aj[463,14,464,2304,4215,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,4788,0,0]Al[3096,13,3097,3194,4789,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,4743,0,0]Al[3096,12,3097,3641,4744,0,0]Ag[463,13,464,0,4467,0,0]Al[3096,13,3097,3194,4468,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,4215,0,0]Al[3096,13,3097,2002,1861,0,0]Ah[3096,2,4252,4038,0,0,0]Ae[1195,7,1196,0,0,0,0]==Ai[463,13,464,1094,503,0,0]Ak[1985,13,1986,416,4358,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,4254,0,0,0]Ai[3096,10,3097,4254,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ag[463,15,464,0,4077,0,0]Al[3096,15,3097,2305,4078,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,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,4233,0,0]Al[3096,13,3636,2358,4234,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,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Al[3096,15,4706,4706,1172,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Al[3096,15,3097,1366,4804,0,0]Al[3096,15,3097,3641,3038,0,0]Al[3096,15,3097,3641,4319,0,0]Ah[3096,5,3097,3641,0,0,0]Al[3096,15,3097,1366,4748,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[3966,5,3967,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,4890,4889,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[3966,13,3967,3967,5006,4802,0]0Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Ag[463,13,464,0,4773,0,0]Al[3096,13,3097,3194,4774,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,4330,0]An[2358,13,2359,2359,125,4330,0]Ao[2358,13,2359,2359,2250,4330,0]Ao[1095,13,1096,1096,3015,4330,0]An[1095,13,1683,1683,135,4330,0]An[1095,13,1779,1779,136,4330,0]Ag[463,13,464,0,4114,0,0]Al[3096,13,3097,1691,4116,0,0]Ag[463,19,464,0,4808,0,0]Ai[3096,19,3097,0,4809,0,0]Ae[1095,5,4174,0,0,0,0]0Ag[463,13,464,0,4328,0,0]Al[3096,13,3097,1691,4329,0,0]Ag[463,13,464,0,4065,0,0]Al[3096,13,3097,1691,4067,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[3966,13,3967,3967,5006,4802,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,4467,0,0]Al[3096,13,3097,3194,4468,0,0]Ae[3966,7,3967,0,0,0,0]Ae[4257,7,4258,0,0,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]?434343>=>=Al[3096,14,4957,4957,4855,0,0]54Ai[3096,18,3097,3194,0,0,0]") \ No newline at end of file diff --git a/pr/545/docs/search.index/entry/99ec98389808.js b/pr/545/docs/search.index/entry/99ec98389808.js deleted file mode 100644 index b343fda99..000000000 --- a/pr/545/docs/search.index/entry/99ec98389808.js +++ /dev/null @@ -1 +0,0 @@ -rd_("Af[456,15,457,0,125,0,0]Ak[3064,15,3065,3065,126,0,0]Ag[456,15,457,0,4040,0,0]Al[3064,15,3065,1763,4041,0,0]Al[1964,15,1965,1965,4042,0,0]Al[3064,15,1668,1668,1416,0,0]Ao[1180,13,1181,1181,3883,3005,0]Am[456,13,457,3598,4700,3005,0]Al[456,13,457,1079,496,3005,0]Am[456,13,457,1079,4311,3005,0]Am[456,13,457,3989,4304,3005,0]Am[456,13,457,3989,3013,3005,0]Am[456,13,457,3989,3202,3005,0]Am[456,13,457,3989,4303,3005,0]Am[456,13,457,3994,3220,3005,0]Am[456,13,457,3994,4075,3005,0]Aj[456,13,457,0,1426,3005,0]Aj[456,13,457,0,4864,3005,0]Aj[456,13,457,0,1137,3005,0]Aj[456,13,457,0,1409,3005,0]Aj[456,13,457,0,2271,3005,0]Aj[456,13,457,0,3181,3005,0]Aj[456,13,457,0,3010,3005,0]Aj[456,13,457,0,1846,3005,0]Aj[456,13,457,0,4026,3005,0]Aj[456,13,457,0,4396,3005,0]Aj[456,13,457,0,3896,3005,0]Aj[456,13,457,0,3886,3005,0]Aj[456,13,457,0,2993,3005,0]Aj[456,13,457,0,4393,3005,0]Aj[456,13,457,0,4593,3005,0]Aj[456,13,457,0,4032,3005,0]Aj[456,13,457,0,4035,3005,0]Aj[456,13,457,0,4040,3005,0]Aj[456,13,457,0,4759,3005,0]Ai[456,13,457,0,503,3005,0]Ai[456,13,457,0,125,3005,0]Aj[456,13,457,0,2258,3005,0]Ak[456,13,1672,0,5013,3005,0]Ak[456,13,1752,0,1154,3005,0]Ao[3064,13,3065,1789,1427,3005,0]Ao[3064,13,3065,1789,4865,3005,0]Ao[3064,13,3065,3029,1138,3005,0]Ao[3064,13,3065,3038,4701,3005,0]Ao[3064,13,3065,1350,1410,3005,0]Ao[3064,13,3065,1350,3196,3005,0]Ao[3064,13,3065,1350,3009,3005,0]Ao[3064,13,3065,1350,4699,3005,0]Ao[3064,13,3065,1350,4755,3005,0]Ao[3064,13,3065,1350,3171,3005,0]Ao[3064,13,3065,1366,2272,3005,0]Ao[3064,13,3065,1366,3182,3005,0]Ao[3064,13,3065,1366,3011,3005,0]Ao[3064,13,3065,1105,3014,3005,0]Ao[3064,13,3065,1105,4195,3005,0]Ao[3064,13,3065,1110,1847,3005,0]Ao[3064,13,3065,1110,3221,3005,0]Ao[3064,13,3065,1110,3895,3005,0]Ao[3064,13,3065,1981,3914,3005,0]Ao[3064,13,3065,1981,4305,3005,0]Ao[3064,13,3065,1981,4030,3005,0]Ao[3064,13,3065,3599,4397,3005,0]Ao[3064,13,3065,3599,3006,3005,0]Ao[3064,13,3065,3599,4271,3005,0]Ao[3064,13,3065,3158,3897,3005,0]Ao[3064,13,3065,1670,3887,3005,0]Ao[3064,13,3065,1340,2994,3005,0]Ao[3064,13,3065,1340,4286,3005,0]Ao[3064,13,3065,1340,3188,3005,0]Ao[3064,13,3065,1340,3210,3005,0]Ao[3064,13,3065,1340,4037,3005,0]Ao[3064,13,3065,1340,4395,3005,0]Ao[3064,13,3065,1340,4595,3005,0]Ao[3064,13,3065,2282,4599,3005,0]Ao[3064,13,3065,2282,4033,3005,0]Ao[3064,13,3065,1735,2242,3005,0]Ao[3064,13,3065,1735,4697,3005,0]Ao[3064,13,3065,1763,4036,3005,0]Ao[3064,13,3065,1763,4041,3005,0]Al[3064,13,3065,0,4309,3005,0]Al[3064,13,3065,0,4760,3005,0]An[3064,13,3065,3065,504,3005,0]An[3064,13,3065,3065,126,3005,0]Ao[3064,13,3065,3065,2259,3005,0]Ao[3064,13,3065,3065,2992,3005,0]Ao[3064,13,1668,1668,4201,3005,0]Ao[3064,13,4906,4906,4805,3005,0]Ao[3064,13,4906,4906,1156,3005,0]Ao[3064,13,1673,1673,5014,3005,0]Al[3064,13,1753,0,1155,3005,0]Ao[1964,13,1965,1965,4042,3005,0]Ai[456,13,457,1079,496,0,0]Aj[456,13,457,1079,4311,0,0]Aj[456,13,457,3989,3200,0,0]Aj[456,13,457,3989,4806,0,0]Aj[456,13,457,3994,3206,0,0]Ai[3064,14,3007,0,1403,0,0]Ai[3064,14,3007,0,2970,0,0]Ai[3064,14,3007,0,2988,0,0]Ai[3064,14,3007,0,4062,0,0]Ai[3064,14,3007,0,4055,0,0]Ai[3064,14,3913,0,2252,0,0]Ai[3064,14,3913,0,2274,0,0]Ai[3064,14,3913,0,2236,0,0]Ai[3064,14,3913,0,1834,0,0]Ae[1180,7,1181,0,0,0,0]Ah[3064,14,4408,0,492,0,0]Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]Af[456,5,3593,147,0,0,0]Ag[3064,5,3594,147,0,0,0]Al[1080,15,1081,1081,4799,0,0]Ae[2335,5,2336,0,0,0,0]Af[456,6,457,3065,0,0,0]Ae[3064,6,3065,0,0,0,0]Al[3064,15,1668,1668,1416,0,0]Ag[456,19,457,0,1426,0,0]Ag[456,19,457,0,1409,0,0]Al[3064,19,3065,1789,1427,0,0]Al[3064,19,3065,1350,1410,0,0]Ae[1180,5,1181,0,0,0,0]Ae[1080,5,1662,0,0,0,0]Ae[1080,5,1758,0,0,0,0]Af[456,15,457,0,125,0,0]Ak[3064,15,3065,3065,126,0,0]Ai[456,13,457,0,2271,116,0]Ai[456,13,457,0,3181,116,0]Ai[456,13,457,0,4400,116,0]An[3064,13,3065,1366,2272,116,0]An[3064,13,3065,1366,3182,116,0]An[3064,13,3065,1366,4401,116,0]Ai[456,13,457,0,1426,136,0]Ai[456,13,457,0,1409,136,0]Ai[456,13,457,0,3896,136,0]Ai[456,13,457,0,4035,136,0]Ah[456,13,457,0,503,136,0]Ah[456,13,457,0,125,136,0]Ai[456,13,457,0,2258,136,0]An[3064,13,3065,1789,1427,136,0]An[3064,13,3065,3038,4701,136,0]An[3064,13,3065,1350,1410,136,0]An[3064,13,3065,1105,3014,136,0]An[3064,13,3065,1105,4195,136,0]An[3064,13,3065,1110,3221,136,0]An[3064,13,3065,3158,3897,136,0]An[3064,13,3065,2282,4599,136,0]An[3064,13,3065,1735,4697,136,0]An[3064,13,3065,1763,4036,136,0]Am[3064,13,3065,3065,504,136,0]Am[3064,13,3065,3065,126,136,0]An[3064,13,3065,3065,2259,136,0]Ag[456,13,457,0,2258,0,0]Al[3064,13,3065,3065,2259,0,0]Ai[3064,14,3913,0,1404,0,0]Ai[3064,14,3913,0,2977,0,0]Ag[456,14,457,0,2268,0,0]Al[3064,14,3065,3065,2269,0,0]Al[1964,14,1965,1965,2256,0,0]Al[1964,14,1965,1965,2270,0,0]An[1180,13,1181,1181,133,1144,0]Ao[1180,13,1181,1181,3907,1144,0]Ao[1180,13,1181,1181,3883,1144,0]Ao[1180,13,1364,1364,4306,1144,0]Ao[3921,13,3922,3922,4955,1144,0]Am[456,13,457,3598,3173,1144,0]Am[456,13,457,3598,3175,1144,0]Am[456,13,457,3598,4867,1144,0]Db[456,13,457,3598,4700,1806,0,\"impl-Display-for-SendDatagramError\"]D`[456,13,457,3598,4700,1144,0,\"impl-Debug-for-SendDatagramError\"]Am[456,13,457,2281,2234,1144,0]Am[456,13,457,2281,4169,1144,0]Am[456,13,457,2313,2238,1144,0]Ci[456,13,457,2313,3203,1144,0,\"impl-Debug-for-RetryError\"]Ck[456,13,457,2313,3203,1806,0,\"impl-Display-for-RetryError\"]Am[456,13,457,2313,4285,1144,0]Al[456,13,457,1079,496,1144,0]Am[456,13,457,1079,4311,1144,0]Am[456,13,457,3989,3200,1144,0]Am[456,13,457,3989,4806,1144,0]Co[456,13,457,3989,4304,1806,0,\"impl-Display-for-ReadToEndError\"]Cm[456,13,457,3989,4304,1144,0,\"impl-Debug-for-ReadToEndError\"]Cj[456,13,457,3989,3013,1806,0,\"impl-Display-for-ReadError\"]Ch[456,13,457,3989,3013,1144,0,\"impl-Debug-for-ReadError\"]Ck[456,13,457,3989,3202,1806,0,\"impl-Display-for-ResetError\"]Ci[456,13,457,3989,3202,1144,0,\"impl-Debug-for-ResetError\"]Cm[456,13,457,3989,4303,1144,0,\"impl-Debug-for-ReadExactError\"]Co[456,13,457,3989,4303,1806,0,\"impl-Display-for-ReadExactError\"]Am[456,13,457,1377,4076,1144,0]Am[456,13,457,1122,3910,1144,0]Am[456,13,457,3994,3206,1144,0]Ci[456,13,457,3994,3220,1144,0,\"impl-Debug-for-WriteError\"]Ck[456,13,457,3994,3220,1806,0,\"impl-Display-for-WriteError\"]Ck[456,13,457,3994,4075,1144,0,\"impl-Debug-for-StoppedError\"]Cm[456,13,457,3994,4075,1806,0,\"impl-Display-for-StoppedError\"]Am[456,13,457,3994,1836,1144,0]Cd[456,13,457,0,1426,1806,0,\"impl-Display-for-VarInt\"]Cb[456,13,457,0,1426,1144,0,\"impl-Debug-for-VarInt\"]D`[456,13,457,0,4864,1144,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Db[456,13,457,0,4864,1806,0,\"impl-Display-for-VarIntBoundsExceeded\"]Aj[456,13,457,0,1137,1144,0]Cb[456,13,457,0,1409,1144,0,\"impl-Debug-for-PathId\"]Cd[456,13,457,0,1409,1806,0,\"impl-Display-for-PathId\"]Aj[456,13,457,0,2271,1144,0]Aj[456,13,457,0,3181,1144,0]Aj[456,13,457,0,3010,1144,0]Aj[456,13,457,0,4400,1144,0]Aj[456,13,457,0,1846,1144,0]Ch[456,13,457,0,4026,1144,0,\"impl-Debug-for-ClosedStream\"]Cj[456,13,457,0,4026,1806,0,\"impl-Display-for-ClosedStream\"]Cm[456,13,457,0,4396,1806,0,\"impl-Display-for-ConnectionError\"]Ck[456,13,457,0,4396,1144,0,\"impl-Debug-for-ConnectionError\"]Aj[456,13,457,0,4410,1144,0]Aj[456,13,457,0,4419,1144,0]Aj[456,13,457,0,4724,1144,0]Aj[456,13,457,0,4739,1144,0]Aj[456,13,457,0,3896,1144,0]Aj[456,13,457,0,4280,1144,0]Aj[456,13,457,0,4069,1144,0]Aj[456,13,457,0,4921,1144,0]Aj[456,13,457,0,4020,1144,0]Cg[456,13,457,0,3886,1144,0,\"impl-Debug-for-ConfigError\"]Ci[456,13,457,0,3886,1806,0,\"impl-Display-for-ConfigError\"]Ce[456,13,457,0,2993,1144,0,\"impl-Debug-for-FrameType\"]Cg[456,13,457,0,2993,1806,0,\"impl-Display-for-FrameType\"]Ck[456,13,457,0,4393,1144,0,\"impl-Debug-for-ConnectionClose\"]Cm[456,13,457,0,4393,1806,0,\"impl-Display-for-ConnectionClose\"]Cl[456,13,457,0,4593,1144,0,\"impl-Debug-for-ApplicationClose\"]Cn[456,13,457,0,4593,1806,0,\"impl-Display-for-ApplicationClose\"]Ch[456,13,457,0,4032,1144,0,\"impl-Debug-for-ConnectError\"]Cj[456,13,457,0,4032,1806,0,\"impl-Display-for-ConnectError\"]Cj[456,13,457,0,4035,1806,0,\"impl-Display-for-ConnectionId\"]Ch[456,13,457,0,4035,1144,0,\"impl-Debug-for-ConnectionId\"]Aj[456,13,457,0,4040,1144,0]Cn[456,13,457,0,4759,1144,0,\"impl-Debug-for-TransportErrorCode\"]D`[456,13,457,0,4759,1806,0,\"impl-Display-for-TransportErrorCode\"]Aj[456,13,457,0,3184,1144,0]Aj[456,13,457,0,4626,1144,0]Ai[456,13,457,0,503,1144,0]C`[456,13,457,0,125,1806,0,\"impl-Display-for-Dir\"]Bn[456,13,457,0,125,1144,0,\"impl-Debug-for-Dir\"]Cd[456,13,457,0,2258,1144,0,\"impl-Debug-for-StreamId\"]Cf[456,13,457,0,2258,1806,0,\"impl-Display-for-StreamId\"]Aj[456,13,457,0,2268,1144,0]Aj[456,13,3593,0,119,1144,0]Ak[456,13,3593,0,2980,1144,0]Ak[456,13,3593,0,1141,1144,0]Ak[456,13,3593,0,3891,1144,0]Ak[456,13,3593,0,1819,1144,0]Ak[456,13,3593,0,4187,1144,0]Ak[456,13,3593,0,4688,1144,0]Ak[456,13,1672,0,5013,1144,0]Ak[456,13,1672,0,3889,1144,0]Ak[456,13,1672,0,4763,1144,0]Cd[456,13,1752,0,1154,1806,0,\"impl-Display-for-Error\"]Cb[456,13,1752,0,1154,1144,0,\"impl-Debug-for-Error\"]Dc[456,13,1752,0,4860,1806,0,\"impl-Display-for-NoInitialCipherSuite\"]Da[456,13,1752,0,4860,1144,0,\"impl-Debug-for-NoInitialCipherSuite\"]Ao[3064,13,3065,3599,3176,1144,0]Ao[3064,13,3065,2282,2235,1144,0]Ci[3064,13,3065,1789,1427,1806,0,\"impl-Display-for-VarInt\"]Cg[3064,13,3065,1789,1427,1144,0,\"impl-Debug-for-VarInt\"]De[3064,13,3065,1789,4865,1144,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Dg[3064,13,3065,1789,4865,1806,0,\"impl-Display-for-VarIntBoundsExceeded\"]Ao[3064,13,3065,3029,1138,1144,0]Db[3064,13,3065,3038,4701,1144,0,\"impl-Debug-for-SendDatagramError\"]Dd[3064,13,3065,3038,4701,1806,0,\"impl-Display-for-SendDatagramError\"]Ci[3064,13,3065,1350,1410,1806,0,\"impl-Display-for-PathId\"]Cg[3064,13,3065,1350,1410,1144,0,\"impl-Debug-for-PathId\"]Ao[3064,13,3065,1350,4065,1144,0]Ao[3064,13,3065,1350,3196,1144,0]Ao[3064,13,3065,1350,3009,1144,0]Ao[3064,13,3065,1350,4699,1144,0]Dc[3064,13,3065,1350,4755,1144,0,\"impl-Debug-for-SetPathStatusError\"]De[3064,13,3065,1350,4755,1806,0,\"impl-Display-for-SetPathStatusError\"]Cm[3064,13,3065,1350,3171,1806,0,\"impl-Display-for-ClosedPath\"]Ck[3064,13,3065,1350,3171,1144,0,\"impl-Debug-for-ClosedPath\"]Ao[3064,13,3065,1366,2272,1144,0]Ao[3064,13,3065,1366,3182,1144,0]Ao[3064,13,3065,1366,3011,1144,0]Ao[3064,13,3065,1366,4401,1144,0]Cj[3064,13,3065,1105,3014,1144,0,\"impl-Debug-for-ReadError\"]Cl[3064,13,3065,1105,3014,1806,0,\"impl-Display-for-ReadError\"]D`[3064,13,3065,1105,4195,1806,0,\"impl-Display-for-ReadableError\"]Cn[3064,13,3065,1105,4195,1144,0,\"impl-Debug-for-ReadableError\"]Ao[3064,13,3065,1110,1847,1144,0]Cm[3064,13,3065,1110,3221,1806,0,\"impl-Display-for-WriteError\"]Ck[3064,13,3065,1110,3221,1144,0,\"impl-Debug-for-WriteError\"]Cn[3064,13,3065,1110,3895,1806,0,\"impl-Display-for-FinishError\"]Cl[3064,13,3065,1110,3895,1144,0,\"impl-Debug-for-FinishError\"]Ao[3064,13,3065,1981,3914,1144,0]Ao[3064,13,3065,1981,4305,1144,0]Co[3064,13,3065,1981,4030,1806,0,\"impl-Display-for-ClosedStream\"]Cm[3064,13,3065,1981,4030,1144,0,\"impl-Debug-for-ClosedStream\"]Db[3064,13,3065,3599,4397,1806,0,\"impl-Display-for-ConnectionError\"]D`[3064,13,3065,3599,4397,1144,0,\"impl-Debug-for-ConnectionError\"]Cl[3064,13,3065,3599,3006,1806,0,\"impl-Display-for-PathError\"]Cj[3064,13,3065,3599,3006,1144,0,\"impl-Debug-for-PathError\"]Da[3064,13,3065,3599,4271,1806,0,\"impl-Display-for-ClosePathError\"]Co[3064,13,3065,3599,4271,1144,0,\"impl-Debug-for-ClosePathError\"]Dg[3064,13,3065,3599,4950,1144,0,\"impl-Debug-for-MultipathNotNegotiated\"]Di[3064,13,3065,3599,4950,1806,0,\"impl-Display-for-MultipathNotNegotiated\"]Ao[3064,13,3065,3599,1159,1144,0]Ao[3064,13,3065,1101,4411,1144,0]Ao[3064,13,3065,3158,4420,1144,0]Ao[3064,13,3065,3158,4725,1144,0]Ao[3064,13,3065,3158,4740,1144,0]Ao[3064,13,3065,3158,3897,1144,0]Ao[3064,13,3065,1670,4281,1144,0]Ao[3064,13,3065,1670,4071,1144,0]Ao[3064,13,3065,1670,4922,1144,0]Ao[3064,13,3065,1670,4022,1144,0]Cl[3064,13,3065,1670,3887,1144,0,\"impl-Debug-for-ConfigError\"]Cn[3064,13,3065,1670,3887,1806,0,\"impl-Display-for-ConfigError\"]Cl[3064,13,3065,1340,2994,1806,0,\"impl-Display-for-FrameType\"]Cj[3064,13,3065,1340,2994,1144,0,\"impl-Debug-for-FrameType\"]Da[3064,13,3065,1340,4286,1806,0,\"impl-Display-for-InvalidFrameId\"]Co[3064,13,3065,1340,4286,1144,0,\"impl-Debug-for-InvalidFrameId\"]Cm[3064,13,3065,1340,3188,1806,0,\"impl-Display-for-MaybeFrame\"]Ck[3064,13,3065,1340,3188,1144,0,\"impl-Debug-for-MaybeFrame\"]Cm[3064,13,3065,1340,3210,1806,0,\"impl-Display-for-StreamInfo\"]Ck[3064,13,3065,1340,3210,1144,0,\"impl-Debug-for-StreamInfo\"]Cm[3064,13,3065,1340,4037,1144,0,\"impl-Debug-for-DatagramInfo\"]Co[3064,13,3065,1340,4037,1806,0,\"impl-Display-for-DatagramInfo\"]Db[3064,13,3065,1340,4395,1806,0,\"impl-Display-for-ConnectionClose\"]D`[3064,13,3065,1340,4395,1144,0,\"impl-Debug-for-ConnectionClose\"]Dc[3064,13,3065,1340,4595,1806,0,\"impl-Display-for-ApplicationClose\"]Da[3064,13,3065,1340,4595,1144,0,\"impl-Debug-for-ApplicationClose\"]Ci[3064,13,3065,1340,2228,1144,0,\"impl-Debug-for-Datagram\"]Ck[3064,13,3065,1340,2228,1806,0,\"impl-Display-for-Datagram\"]Ao[3064,13,3065,2282,4599,1144,0]Ao[3064,13,3065,2282,2239,1144,0]Co[3064,13,3065,2282,4033,1806,0,\"impl-Display-for-ConnectError\"]Cm[3064,13,3065,2282,4033,1144,0,\"impl-Debug-for-ConnectError\"]Ao[3064,13,3065,2282,3881,1144,0]Cm[3064,13,3065,2282,3204,1806,0,\"impl-Display-for-RetryError\"]Ck[3064,13,3065,2282,3204,1144,0,\"impl-Debug-for-RetryError\"]Ao[3064,13,3065,1735,4190,1144,0]Ao[3064,13,3065,1735,4409,1144,0]Ao[3064,13,3065,1735,4954,1144,0]Ao[3064,13,3065,1735,2242,1144,0]Dd[3064,13,3065,1735,4697,1806,0,\"impl-Display-for-PacketDecodeError\"]Db[3064,13,3065,1735,4697,1144,0,\"impl-Debug-for-PacketDecodeError\"]Ao[3064,13,3065,1763,4399,1144,0]Ao[3064,13,3065,1763,4168,1144,0]Co[3064,13,3065,1763,4036,1806,0,\"impl-Display-for-ConnectionId\"]Cm[3064,13,3065,1763,4036,1144,0,\"impl-Debug-for-ConnectionId\"]Ao[3064,13,3065,1763,4041,1144,0]Ce[3064,13,3065,0,4309,1806,0,\"impl-Display-for-Error\"]Cc[3064,13,3065,0,4309,1144,0,\"impl-Debug-for-Error\"]Cd[3064,13,3065,0,4760,1806,0,\"impl-Display-for-Code\"]Cb[3064,13,3065,0,4760,1144,0,\"impl-Debug-for-Code\"]Ao[3064,13,3065,4208,3185,1144,0]Ao[3064,13,3065,4208,5048,1144,0]Ao[3064,13,3065,4795,4627,1144,0]An[3064,13,3065,3065,504,1144,0]Cc[3064,13,3065,3065,126,1144,0,\"impl-Debug-for-Dir\"]Ce[3064,13,3065,3065,126,1806,0,\"impl-Display-for-Dir\"]Ci[3064,13,3065,3065,2259,1144,0,\"impl-Debug-for-StreamId\"]Ck[3064,13,3065,3065,2259,1806,0,\"impl-Display-for-StreamId\"]Ao[3064,13,3065,3065,2269,1144,0]Cl[3064,13,3065,3065,2992,1806,0,\"impl-Display-for-FourTuple\"]Cj[3064,13,3065,3065,2992,1144,0,\"impl-Debug-for-FourTuple\"]Cn[3064,13,1668,1668,4201,1144,0,\"impl-Debug-for-UnexpectedEnd\"]D`[3064,13,1668,1668,4201,1806,0,\"impl-Display-for-UnexpectedEnd\"]Ao[3064,13,4906,4906,4805,1144,0]Ch[3064,13,4906,4906,1156,1806,0,\"impl-Display-for-Error\"]Cf[3064,13,4906,4906,1156,1144,0,\"impl-Debug-for-Error\"]Ao[3064,13,1673,1673,5014,1144,0]Ao[3064,13,1673,1673,3890,1144,0]Ao[3064,13,1673,1673,4766,1144,0]Cc[3064,13,1753,0,1155,1144,0,\"impl-Debug-for-Error\"]Ce[3064,13,1753,0,1155,1806,0,\"impl-Display-for-Error\"]Dg[3064,13,1753,1753,4861,1806,0,\"impl-Display-for-NoInitialCipherSuite\"]De[3064,13,1753,1753,4861,1144,0,\"impl-Debug-for-NoInitialCipherSuite\"]Am[3064,13,3594,147,120,1144,0]An[3064,13,3594,147,2981,1144,0]Ao[3064,13,3594,1336,1142,1144,0]Ao[3064,13,3594,1336,3892,1144,0]Ao[3064,13,3594,2335,1820,1144,0]Ao[3064,13,3594,2335,4188,1144,0]Ao[3064,13,3594,3594,4689,1144,0]Ch[3064,13,4657,4657,1157,1806,0,\"impl-Display-for-Error\"]Cf[3064,13,4657,4657,1157,1144,0,\"impl-Debug-for-Error\"]Ao[3064,13,4657,4657,1160,1144,0]An[1964,13,1965,409,4310,1144,0]Ao[1964,13,1965,1965,2256,1144,0]Ao[1964,13,1965,1965,2270,1144,0]Ao[1964,13,1965,1965,4042,1144,0]Al[3064,13,3065,1350,4065,0,0]Ag[456,14,457,0,2271,0,0]Al[3064,14,3065,1366,2272,0,0]Al[3064,13,3065,1735,4190,0,0]Al[3064,14,3065,1735,4954,0,0]Ah[3064,14,4408,0,492,0,0]Al[1964,14,1965,1965,2256,0,0]Ag[456,13,457,0,4921,0,0]Al[3064,13,3065,1670,4922,0,0]8Al[1180,13,1364,1364,4306,0,0]Al[3921,13,3922,3922,4955,0,0]Ag[456,13,457,0,4160,0,0]Aj[456,13,457,2281,2234,0,0]Ag[456,13,457,0,3197,0,0]Ag[456,13,457,0,4410,0,0]Ag[456,13,457,0,4280,0,0]Ag[456,13,457,0,4069,0,0]Ag[456,13,457,0,4020,0,0]Ag[456,13,457,0,4035,0,0]Ag[456,13,457,0,4626,0,0]Ag[456,13,457,0,2258,0,0]Ag[456,13,3593,0,119,0,0]Ah[456,13,3593,0,1141,0,0]Ah[456,13,3593,0,1819,0,0]Al[3064,13,3065,4429,4161,0,0]Al[3064,13,3065,1101,3198,0,0]Al[3064,13,3065,2282,2235,0,0]Al[3064,13,3065,1735,5073,0,0]Al[3064,13,3065,4208,5043,0,0]Al[3064,13,3065,1101,4411,0,0]Al[3064,13,3065,1670,4281,0,0]Al[3064,13,3065,1670,4071,0,0]Al[3064,13,3065,1670,4022,0,0]Al[3064,13,3065,1735,4190,0,0]Al[3064,13,3065,1763,4036,0,0]Ai[3064,13,3065,0,4309,0,0]Al[3064,13,3065,4208,5048,0,0]Al[3064,13,3065,4795,4627,0,0]Al[3064,13,3065,3065,2259,0,0]Al[3064,13,3065,3065,2992,0,0]Aj[3064,13,3594,147,120,0,0]Al[3064,13,3594,1336,1142,0,0]Al[3064,13,3594,2335,1820,0,0]Ak[1964,13,1965,409,4310,0,0]Al[1080,13,4128,4128,4999,0,0]Al[1080,13,4128,4128,5000,0,0]Aa[456,3,0,0,0,0,0]Ah[456,13,457,0,503,132,0]Am[3064,13,3065,3065,504,132,0]Ag[456,12,457,0,3213,0,0]Aj[456,13,457,1973,1831,0,0]0Am[456,13,457,1377,4076,1831,0]Aj[456,13,457,0,4199,3213,0]Al[3064,12,3065,1670,3214,0,0]Ao[3064,13,3065,1670,4200,3214,0]Aj[456,13,457,3598,3175,0,0]Ag[456,14,457,0,3010,0,0]Al[3064,13,3065,3599,3176,0,0]Al[3064,14,3065,1366,3011,0,0]Ae[1080,7,1662,0,0,0,0]Ae[1080,7,1758,0,0,0,0]Ac[456,4,457,0,0,0,0]Ag[456,15,457,0,4040,0,0]Al[3064,15,3065,1763,4041,0,0]Al[1964,15,1965,1965,4042,0,0]210Ag[456,5,1672,1673,0,0,0]Ae[3064,5,1673,0,0,0,0]Al[3064,15,3065,1735,4409,0,0]Al[3064,15,3065,1340,3188,0,0]Af[456,5,457,1079,0,0,0]Al[3064,15,3065,3599,1159,0,0]Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]Aj[456,15,457,3989,4304,0,0]Af[456,6,457,3065,0,0,0]Ae[3064,6,3065,0,0,0,0]Ag[456,19,457,0,1409,0,0]Al[3064,19,3065,1350,1410,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]Ai[3064,14,3007,0,4055,0,0]Al[1964,14,1965,1965,2256,0,0]Aa[512,3,0,0,0,0,0]Ai[3064,14,3065,0,4309,0,0]Ag[456,14,457,0,3010,0,0]Al[3064,14,3065,1366,3011,0,0]Al[3064,14,3065,1340,2228,0,0]Al[456,13,457,3598,2249,480,0]Al[456,13,457,2313,2238,480,0]Ak[456,13,457,1079,496,480,0]Al[456,13,457,1079,4311,480,0]Al[456,13,457,3989,3200,480,0]Al[456,13,457,3994,3206,480,0]An[3064,13,3065,1105,1391,480,0]Am[1180,13,1181,1181,133,487,0]An[1180,13,1181,1181,3907,487,0]An[1180,13,1181,1181,3883,487,0]An[1180,13,1364,1364,3915,487,0]An[1180,13,1364,1364,1174,487,0]An[1180,13,1364,1364,4306,487,0]Ak[512,13,513,513,3884,487,0]An[3921,13,3922,3922,4955,487,0]Al[456,13,457,3598,4424,487,0]Al[456,13,457,3598,2249,487,0]Ai[456,13,457,0,4160,487,0]Al[456,13,457,1079,2250,487,0]Al[456,13,457,1079,4591,487,0]Al[456,13,457,3598,3173,487,0]Al[456,13,457,3598,3175,487,0]Al[456,13,457,3598,1822,487,0]Al[456,13,457,3598,1402,487,0]Al[456,13,457,3598,2972,487,0]Al[456,13,457,3598,2222,487,0]Al[456,13,457,3598,4061,487,0]Al[456,13,457,3598,4066,487,0]Al[456,13,457,3598,4867,487,0]Al[456,13,457,3598,4700,487,0]0Al[456,13,457,2281,2234,487,0]Al[456,13,457,2281,4169,487,0]Al[456,13,457,2281,1383,487,0]Al[456,13,457,2313,2238,487,0]Al[456,13,457,2313,3203,487,0]Al[456,13,457,2313,4285,487,0]Ak[456,13,457,1079,496,487,0]Al[456,13,457,1079,4311,487,0]Al[456,13,457,3989,3200,487,0]Al[456,13,457,3989,4806,487,0]Al[456,13,457,3989,4304,487,0]0Df[456,13,457,3989,3013,487,0,\"impl-From%3CResetError%3E-for-ReadError\"]Dk[456,13,457,3989,3013,487,0,\"impl-From%3CConnectionError%3E-for-ReadError\"]Al[456,13,457,3989,3013,487,0]Al[456,13,457,3989,3202,487,0]0Al[456,13,457,3989,4303,487,0]0Al[456,13,457,1377,4076,487,0]Al[456,13,457,1122,3910,487,0]Al[456,13,457,3994,3206,487,0]Dl[456,13,457,3994,3220,487,0,\"impl-From%3CConnectionError%3E-for-WriteError\"]Al[456,13,457,3994,3220,487,0]Di[456,13,457,3994,3220,487,0,\"impl-From%3CStoppedError%3E-for-WriteError\"]Di[456,13,457,3994,3220,487,0,\"impl-From%3CClosedStream%3E-for-WriteError\"]Al[456,13,457,3994,4075,487,0]0Al[456,13,457,3994,1836,487,0]Ai[456,13,457,0,3197,487,0]Ai[456,13,457,0,4199,487,0]Ai[456,13,457,0,4416,487,0]Ai[456,13,457,0,4053,487,0]Ai[456,13,457,0,4294,487,0]Ci[456,13,457,0,1426,487,0,\"impl-From%3Cu32%3E-for-VarInt\"]Cn[456,13,457,0,1426,487,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Dh[456,13,457,0,1426,487,0,\"impl-From%3CTransportErrorCode%3E-for-VarInt\"]Ch[456,13,457,0,1426,487,0,\"impl-From%3Cu8%3E-for-VarInt\"]Ci[456,13,457,0,1426,487,0,\"impl-From%3Cu16%3E-for-VarInt\"]Ai[456,13,457,0,1426,487,0]Ai[456,13,457,0,4864,487,0]Ai[456,13,457,0,1137,487,0]Ai[456,13,457,0,1409,487,0]0Ai[456,13,457,0,2271,487,0]Ai[456,13,457,0,3181,487,0]Ai[456,13,457,0,3010,487,0]Ai[456,13,457,0,4400,487,0]Ai[456,13,457,0,1846,487,0]Ai[456,13,457,0,4026,487,0]Dd[456,13,457,0,4396,487,0,\"impl-From%3CClose%3E-for-ConnectionError\"]Dj[456,13,457,0,4396,487,0,\"impl-From%3CCloseReason%3E-for-ConnectionError\"]Dm[456,13,457,0,4396,487,0,\"impl-From%3CTransportError%3E-for-ConnectionError\"]Ai[456,13,457,0,4396,487,0]Ai[456,13,457,0,4410,487,0]Ai[456,13,457,0,4419,487,0]Ai[456,13,457,0,4724,487,0]Ai[456,13,457,0,4739,487,0]Ai[456,13,457,0,3896,487,0]0Ai[456,13,457,0,4280,487,0]Ai[456,13,457,0,4069,487,0]Ai[456,13,457,0,4921,487,0]Ai[456,13,457,0,4020,487,0]Ai[456,13,457,0,3886,487,0]Dj[456,13,457,0,3886,487,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Do[456,13,457,0,3886,487,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]Ai[456,13,457,0,2993,487,0]Ai[456,13,457,0,4393,487,0]0Ai[456,13,457,0,4593,487,0]Ai[456,13,457,0,4032,487,0]0Ai[456,13,457,0,4035,487,0]Ai[456,13,457,0,4040,487,0]Ai[456,13,457,0,4759,487,0]0Ai[456,13,457,0,3184,487,0]Ai[456,13,457,0,4626,487,0]Ah[456,13,457,0,503,487,0]Ah[456,13,457,0,125,487,0]Ai[456,13,457,0,2258,487,0]0Ai[456,13,457,0,2268,487,0]Ai[456,13,3593,0,119,487,0]Aj[456,13,3593,0,2980,487,0]Aj[456,13,3593,0,1141,487,0]Aj[456,13,3593,0,3891,487,0]Aj[456,13,3593,0,1819,487,0]Aj[456,13,3593,0,4187,487,0]Aj[456,13,3593,0,4688,487,0]Aj[456,13,1672,0,1814,487,0]Ai[456,13,1672,0,490,487,0]Aj[456,13,1672,0,5013,487,0]Aj[456,13,1672,0,3889,487,0]0Aj[456,13,1672,0,4763,487,0]Aj[456,13,1752,0,3215,487,0]Aj[456,13,1752,0,4171,487,0]Aj[456,13,1752,0,1154,487,0]Dm[456,13,1752,0,1154,487,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]Do[456,13,1752,0,1154,487,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]De[456,13,1752,0,1154,487,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]D`[456,13,1752,0,1154,487,0,\"impl-From%3COtherError%3E-for-Error\"]Df[456,13,1752,0,1154,487,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Dd[456,13,1752,0,1154,487,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]De[456,13,1752,0,1154,487,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]Dd[456,13,1752,0,1154,487,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Df[456,13,1752,0,1154,487,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Df[456,13,1752,0,1154,487,0,\"impl-From%3CCertificateError%3E-for-Error\"]Do[456,13,1752,0,1154,487,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Aj[456,13,1752,0,4622,487,0]Aj[456,13,1752,0,4860,487,0]Aj[456,13,1752,0,4624,487,0]Am[2335,13,2336,2336,124,487,0]An[2335,13,2336,2336,2225,487,0]An[3064,13,3065,4429,4161,487,0]An[3064,13,3065,3038,2986,487,0]An[3064,13,3065,1105,1391,487,0]An[3064,13,3065,1981,1840,487,0]An[3064,13,3065,1981,3201,487,0]An[3064,13,3065,1981,3207,487,0]An[3064,13,3065,3599,3176,487,0]An[3064,13,3065,1101,3198,487,0]An[3064,13,3065,1670,4200,487,0]An[3064,13,3065,2282,2235,487,0]An[3064,13,3065,2282,4167,487,0]An[3064,13,3065,2282,4602,487,0]An[3064,13,3065,2282,4178,487,0]An[3064,13,3065,1735,5073,487,0]An[3064,13,3065,4208,5043,487,0]An[3064,13,3065,1376,4417,487,0]An[3064,13,3065,1376,4054,487,0]An[3064,13,3065,1376,4295,487,0]Cn[3064,13,3065,1789,1427,487,0,\"impl-From%3Cu32%3E-for-VarInt\"]Dc[3064,13,3065,1789,1427,487,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Cn[3064,13,3065,1789,1427,487,0,\"impl-From%3Cu16%3E-for-VarInt\"]Cm[3064,13,3065,1789,1427,487,0,\"impl-From%3Cu8%3E-for-VarInt\"]An[3064,13,3065,1789,1427,487,0]Co[3064,13,3065,1789,1427,487,0,\"impl-From%3CCode%3E-for-VarInt\"]An[3064,13,3065,1789,4865,487,0]An[3064,13,3065,3029,1138,487,0]An[3064,13,3065,3038,4701,487,0]An[3064,13,3065,1350,1410,487,0]0An[3064,13,3065,1350,4065,487,0]An[3064,13,3065,1350,3196,487,0]An[3064,13,3065,1350,3009,487,0]An[3064,13,3065,1350,4699,487,0]An[3064,13,3065,1350,4755,487,0]An[3064,13,3065,1350,3171,487,0]An[3064,13,3065,1366,2272,487,0]An[3064,13,3065,1366,3182,487,0]An[3064,13,3065,1366,3011,487,0]An[3064,13,3065,1366,4401,487,0]An[3064,13,3065,1105,3014,487,0]An[3064,13,3065,1105,4195,487,0]An[3064,13,3065,1110,1847,487,0]An[3064,13,3065,1110,3221,487,0]An[3064,13,3065,1110,3895,487,0]An[3064,13,3065,1981,3914,487,0]An[3064,13,3065,1981,4305,487,0]An[3064,13,3065,1981,4030,487,0]An[3064,13,3065,3599,4397,487,0]0An[3064,13,3065,3599,3006,487,0]An[3064,13,3065,3599,4271,487,0]An[3064,13,3065,3599,4950,487,0]An[3064,13,3065,3599,1159,487,0]0An[3064,13,3065,1101,4411,487,0]An[3064,13,3065,3158,4420,487,0]An[3064,13,3065,3158,4725,487,0]An[3064,13,3065,3158,4740,487,0]An[3064,13,3065,3158,3897,487,0]0An[3064,13,3065,1670,4281,487,0]An[3064,13,3065,1670,4071,487,0]An[3064,13,3065,1670,4922,487,0]An[3064,13,3065,1670,4022,487,0]An[3064,13,3065,1670,3887,487,0]Do[3064,13,3065,1670,3887,487,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ed[3064,13,3065,1670,3887,487,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]An[3064,13,3065,1340,2994,487,0]An[3064,13,3065,1340,4286,487,0]An[3064,13,3065,1340,3188,487,0]An[3064,13,3065,1340,3210,487,0]An[3064,13,3065,1340,4037,487,0]An[3064,13,3065,1340,4395,487,0]0An[3064,13,3065,1340,4595,487,0]An[3064,13,3065,1340,2228,487,0]An[3064,13,3065,2282,4599,487,0]An[3064,13,3065,2282,2239,487,0]An[3064,13,3065,2282,4033,487,0]0An[3064,13,3065,2282,3881,487,0]An[3064,13,3065,2282,3204,487,0]An[3064,13,3065,1735,4190,487,0]An[3064,13,3065,1735,4409,487,0]An[3064,13,3065,1735,4954,487,0]An[3064,13,3065,1735,2242,487,0]An[3064,13,3065,1735,4697,487,0]0An[3064,13,3065,1763,4399,487,0]An[3064,13,3065,1763,4168,487,0]An[3064,13,3065,1763,4036,487,0]An[3064,13,3065,1763,4041,487,0]Ak[3064,13,3065,0,4309,487,0]0Ak[3064,13,3065,0,4760,487,0]0An[3064,13,3065,4208,3185,487,0]An[3064,13,3065,4208,5048,487,0]An[3064,13,3065,4795,4627,487,0]Am[3064,13,3065,3065,504,487,0]Am[3064,13,3065,3065,126,487,0]An[3064,13,3065,3065,2259,487,0]0An[3064,13,3065,3065,2269,487,0]An[3064,13,3065,3065,2992,487,0]An[3064,13,1668,1668,4201,487,0]An[3064,13,4906,4906,4805,487,0]An[3064,13,4906,4906,1156,487,0]0An[3064,13,1673,1673,1815,487,0]Am[3064,13,1673,1673,491,487,0]An[3064,13,1673,1673,5014,487,0]An[3064,13,1673,1673,3890,487,0]0An[3064,13,1673,1673,4766,487,0]An[3064,13,1753,1753,3216,487,0]An[3064,13,1753,1753,4172,487,0]E`[3064,13,1753,0,1155,487,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Dg[3064,13,1753,0,1155,487,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Da[3064,13,1753,0,1155,487,0,\"impl-From%3COtherError%3E-for-Error\"]Dg[3064,13,1753,0,1155,487,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Ak[3064,13,1753,0,1155,487,0]Df[3064,13,1753,0,1155,487,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]De[3064,13,1753,0,1155,487,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Df[3064,13,1753,0,1155,487,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]E`[3064,13,1753,0,1155,487,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Dg[3064,13,1753,0,1155,487,0,\"impl-From%3CCertificateError%3E-for-Error\"]De[3064,13,1753,0,1155,487,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dn[3064,13,1753,0,1155,487,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]An[3064,13,1753,1753,4623,487,0]An[3064,13,1753,1753,4861,487,0]An[3064,13,1753,1753,4625,487,0]Al[3064,13,3594,147,120,487,0]Am[3064,13,3594,147,2981,487,0]An[3064,13,3594,1336,1142,487,0]An[3064,13,3594,1336,3892,487,0]An[3064,13,3594,2335,1820,487,0]An[3064,13,3594,2335,4188,487,0]An[3064,13,3594,3594,4689,487,0]An[3064,13,4657,4657,1157,487,0]An[3064,13,4657,4657,1160,487,0]An[1964,13,1965,1965,3219,487,0]0Am[1964,13,1965,409,4310,487,0]An[1964,13,1965,1965,2256,487,0]An[1964,13,1965,1965,2270,487,0]An[1964,13,1965,1965,4042,487,0]An[1080,13,1081,1081,2983,487,0]An[1080,13,1081,1081,4799,487,0]Am[1080,13,1662,1662,134,487,0]An[1080,13,1365,1365,1175,487,0]An[1080,13,1365,1365,3916,487,0]An[1080,13,1365,1365,4405,487,0]An[1080,13,4128,4128,4999,487,0]An[1080,13,4128,4128,5000,487,0]Am[1080,13,1758,1758,135,487,0]Ai[456,13,457,0,1426,488,0]Ai[456,13,457,0,1409,488,0]Ai[456,13,457,0,3896,488,0]Ai[456,13,457,0,4035,488,0]Ah[456,13,457,0,503,488,0]Ah[456,13,457,0,125,488,0]Ai[456,13,457,0,2258,488,0]An[3064,13,3065,1789,1427,488,0]An[3064,13,3065,3038,4701,488,0]An[3064,13,3065,1350,1410,488,0]An[3064,13,3065,1105,3014,488,0]An[3064,13,3065,1105,4195,488,0]An[3064,13,3065,1110,3221,488,0]An[3064,13,3065,3158,3897,488,0]An[3064,13,3065,2282,4599,488,0]An[3064,13,3065,1735,4697,488,0]An[3064,13,3065,1763,4036,488,0]Am[3064,13,3065,3065,504,488,0]Am[3064,13,3065,3065,126,488,0]An[3064,13,3065,3065,2259,488,0]An[3064,13,3065,3065,2992,488,0]Am[1180,13,1181,1181,133,489,0]An[1180,13,1181,1181,3907,489,0]An[1180,13,1181,1181,3883,489,0]An[1180,13,1364,1364,3915,489,0]An[1180,13,1364,1364,1174,489,0]An[1180,13,1364,1364,4306,489,0]Ak[512,13,513,513,3884,489,0]An[3921,13,3922,3922,4955,489,0]Al[456,13,457,3598,4424,489,0]Al[456,13,457,3598,2249,489,0]Ai[456,13,457,0,4160,489,0]Al[456,13,457,1079,2250,489,0]Al[456,13,457,1079,4591,489,0]Al[456,13,457,3598,3173,489,0]Al[456,13,457,3598,3175,489,0]Al[456,13,457,3598,1822,489,0]Al[456,13,457,3598,1402,489,0]Al[456,13,457,3598,2972,489,0]Al[456,13,457,3598,2222,489,0]Al[456,13,457,3598,4061,489,0]Al[456,13,457,3598,4066,489,0]Al[456,13,457,3598,4867,489,0]Al[456,13,457,3598,4700,489,0]Al[456,13,457,2281,2234,489,0]Al[456,13,457,2281,4169,489,0]Al[456,13,457,2281,1383,489,0]Al[456,13,457,2313,2238,489,0]Al[456,13,457,2313,3203,489,0]Al[456,13,457,2313,4285,489,0]Ak[456,13,457,1079,496,489,0]Al[456,13,457,1079,4311,489,0]Al[456,13,457,3989,3200,489,0]Al[456,13,457,3989,4806,489,0]Al[456,13,457,3989,4304,489,0]Al[456,13,457,3989,3013,489,0]Al[456,13,457,3989,3202,489,0]Al[456,13,457,3989,4303,489,0]Al[456,13,457,1377,4076,489,0]Al[456,13,457,1122,3910,489,0]Al[456,13,457,3994,3206,489,0]Al[456,13,457,3994,3220,489,0]Al[456,13,457,3994,4075,489,0]Al[456,13,457,3994,1836,489,0]Ai[456,13,457,0,3197,489,0]Ai[456,13,457,0,4199,489,0]Ai[456,13,457,0,4416,489,0]Ai[456,13,457,0,4053,489,0]Ai[456,13,457,0,4294,489,0]Ai[456,13,457,0,1426,489,0]Ai[456,13,457,0,4864,489,0]Ai[456,13,457,0,1137,489,0]Ai[456,13,457,0,1409,489,0]Ai[456,13,457,0,2271,489,0]Ai[456,13,457,0,3181,489,0]Ai[456,13,457,0,3010,489,0]Ai[456,13,457,0,4400,489,0]Ai[456,13,457,0,1846,489,0]Ai[456,13,457,0,4026,489,0]Ai[456,13,457,0,4396,489,0]Ai[456,13,457,0,4410,489,0]Ai[456,13,457,0,4419,489,0]Ai[456,13,457,0,4724,489,0]Ai[456,13,457,0,4739,489,0]Ai[456,13,457,0,3896,489,0]Ai[456,13,457,0,4280,489,0]Ai[456,13,457,0,4069,489,0]Ai[456,13,457,0,4921,489,0]Ai[456,13,457,0,4020,489,0]Ai[456,13,457,0,3886,489,0]Ai[456,13,457,0,2993,489,0]Ai[456,13,457,0,4393,489,0]Ai[456,13,457,0,4593,489,0]Ai[456,13,457,0,4032,489,0]Ai[456,13,457,0,4035,489,0]Ai[456,13,457,0,4040,489,0]Ai[456,13,457,0,4759,489,0]Ai[456,13,457,0,3184,489,0]Ai[456,13,457,0,4626,489,0]Ah[456,13,457,0,503,489,0]Ah[456,13,457,0,125,489,0]Ai[456,13,457,0,2258,489,0]Ai[456,13,457,0,2268,489,0]Ai[456,13,3593,0,119,489,0]Aj[456,13,3593,0,2980,489,0]Aj[456,13,3593,0,1141,489,0]Aj[456,13,3593,0,3891,489,0]Aj[456,13,3593,0,1819,489,0]Aj[456,13,3593,0,4187,489,0]Aj[456,13,3593,0,4688,489,0]Aj[456,13,1672,0,1814,489,0]Ai[456,13,1672,0,490,489,0]Aj[456,13,1672,0,5013,489,0]Aj[456,13,1672,0,3889,489,0]Aj[456,13,1672,0,4763,489,0]Aj[456,13,1752,0,3215,489,0]Aj[456,13,1752,0,4171,489,0]Aj[456,13,1752,0,1154,489,0]Aj[456,13,1752,0,4622,489,0]Aj[456,13,1752,0,4860,489,0]Aj[456,13,1752,0,4624,489,0]Am[2335,13,2336,2336,124,489,0]An[2335,13,2336,2336,2225,489,0]An[3064,13,3065,4429,4161,489,0]An[3064,13,3065,3038,2986,489,0]An[3064,13,3065,1105,1391,489,0]An[3064,13,3065,1981,1840,489,0]An[3064,13,3065,1981,3201,489,0]An[3064,13,3065,1981,3207,489,0]An[3064,13,3065,3599,3176,489,0]An[3064,13,3065,1101,3198,489,0]An[3064,13,3065,1670,4200,489,0]An[3064,13,3065,2282,2235,489,0]An[3064,13,3065,2282,4167,489,0]An[3064,13,3065,2282,4602,489,0]An[3064,13,3065,2282,4178,489,0]An[3064,13,3065,1735,5073,489,0]An[3064,13,3065,4208,5043,489,0]An[3064,13,3065,1376,4417,489,0]An[3064,13,3065,1376,4054,489,0]An[3064,13,3065,1376,4295,489,0]An[3064,13,3065,1789,1427,489,0]An[3064,13,3065,1789,4865,489,0]An[3064,13,3065,3029,1138,489,0]An[3064,13,3065,3038,4701,489,0]An[3064,13,3065,1350,1410,489,0]An[3064,13,3065,1350,4065,489,0]An[3064,13,3065,1350,3196,489,0]An[3064,13,3065,1350,3009,489,0]An[3064,13,3065,1350,4699,489,0]An[3064,13,3065,1350,4755,489,0]An[3064,13,3065,1350,3171,489,0]An[3064,13,3065,1366,2272,489,0]An[3064,13,3065,1366,3182,489,0]An[3064,13,3065,1366,3011,489,0]An[3064,13,3065,1366,4401,489,0]An[3064,13,3065,1105,3014,489,0]An[3064,13,3065,1105,4195,489,0]An[3064,13,3065,1110,1847,489,0]An[3064,13,3065,1110,3221,489,0]An[3064,13,3065,1110,3895,489,0]An[3064,13,3065,1981,3914,489,0]An[3064,13,3065,1981,4305,489,0]An[3064,13,3065,1981,4030,489,0]An[3064,13,3065,3599,4397,489,0]An[3064,13,3065,3599,3006,489,0]An[3064,13,3065,3599,4271,489,0]An[3064,13,3065,3599,4950,489,0]An[3064,13,3065,3599,1159,489,0]An[3064,13,3065,1101,4411,489,0]An[3064,13,3065,3158,4420,489,0]An[3064,13,3065,3158,4725,489,0]An[3064,13,3065,3158,4740,489,0]An[3064,13,3065,3158,3897,489,0]An[3064,13,3065,1670,4281,489,0]An[3064,13,3065,1670,4071,489,0]An[3064,13,3065,1670,4922,489,0]An[3064,13,3065,1670,4022,489,0]An[3064,13,3065,1670,3887,489,0]An[3064,13,3065,1340,2994,489,0]An[3064,13,3065,1340,4286,489,0]An[3064,13,3065,1340,3188,489,0]An[3064,13,3065,1340,3210,489,0]An[3064,13,3065,1340,4037,489,0]An[3064,13,3065,1340,4395,489,0]An[3064,13,3065,1340,4595,489,0]An[3064,13,3065,1340,2228,489,0]An[3064,13,3065,2282,4599,489,0]An[3064,13,3065,2282,2239,489,0]An[3064,13,3065,2282,4033,489,0]An[3064,13,3065,2282,3881,489,0]An[3064,13,3065,2282,3204,489,0]An[3064,13,3065,1735,4190,489,0]An[3064,13,3065,1735,4409,489,0]An[3064,13,3065,1735,4954,489,0]An[3064,13,3065,1735,2242,489,0]An[3064,13,3065,1735,4697,489,0]An[3064,13,3065,1763,4399,489,0]An[3064,13,3065,1763,4168,489,0]An[3064,13,3065,1763,4036,489,0]An[3064,13,3065,1763,4041,489,0]Ak[3064,13,3065,0,4309,489,0]Ak[3064,13,3065,0,4760,489,0]An[3064,13,3065,4208,3185,489,0]An[3064,13,3065,4208,5048,489,0]An[3064,13,3065,4795,4627,489,0]Am[3064,13,3065,3065,504,489,0]Am[3064,13,3065,3065,126,489,0]An[3064,13,3065,3065,2259,489,0]An[3064,13,3065,3065,2269,489,0]An[3064,13,3065,3065,2992,489,0]An[3064,13,1668,1668,4201,489,0]An[3064,13,4906,4906,4805,489,0]An[3064,13,4906,4906,1156,489,0]An[3064,13,1673,1673,1815,489,0]Am[3064,13,1673,1673,491,489,0]An[3064,13,1673,1673,5014,489,0]An[3064,13,1673,1673,3890,489,0]An[3064,13,1673,1673,4766,489,0]An[3064,13,1753,1753,3216,489,0]An[3064,13,1753,1753,4172,489,0]Ak[3064,13,1753,0,1155,489,0]An[3064,13,1753,1753,4623,489,0]An[3064,13,1753,1753,4861,489,0]An[3064,13,1753,1753,4625,489,0]Al[3064,13,3594,147,120,489,0]Am[3064,13,3594,147,2981,489,0]An[3064,13,3594,1336,1142,489,0]An[3064,13,3594,1336,3892,489,0]An[3064,13,3594,2335,1820,489,0]An[3064,13,3594,2335,4188,489,0]An[3064,13,3594,3594,4689,489,0]An[3064,13,4657,4657,1157,489,0]An[3064,13,4657,4657,1160,489,0]An[1964,13,1965,1965,3219,489,0]Am[1964,13,1965,409,4310,489,0]An[1964,13,1965,1965,2256,489,0]An[1964,13,1965,1965,2270,489,0]An[1964,13,1965,1965,4042,489,0]An[1080,13,1081,1081,2983,489,0]An[1080,13,1081,1081,4799,489,0]Am[1080,13,1662,1662,134,489,0]An[1080,13,1365,1365,1175,489,0]An[1080,13,1365,1365,3916,489,0]An[1080,13,1365,1365,4405,489,0]An[1080,13,4128,4128,4999,489,0]An[1080,13,4128,4128,5000,489,0]Am[1080,13,1758,1758,135,489,0]Ac[512,7,513,0,0,0,0]Ae[3921,7,3922,0,0,0,0]Ae[4211,7,4212,0,0,0,0]Ae[2335,7,2336,0,0,0,0]Ae[4719,7,4720,0,0,0,0]Al[3064,13,3065,1105,1391,0,0]Ao[3064,13,3065,2282,4178,2240,0]Ah[456,12,1672,0,4690,0,0]Al[3064,13,3065,1981,1840,0,0]Al[3064,12,1673,1673,4691,0,0]Aj[456,13,457,3598,3175,0,0]Ab[1080,3,0,0,0,0,0]Ai[456,13,457,1079,496,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,13,3065,3599,3176,0,0]Al[3064,14,3065,1366,3182,0,0]Aj[456,12,457,1973,3164,0,0]Am[456,13,457,3598,4424,1399,0]Am[456,13,457,3598,2249,1399,0]Am[456,13,457,1079,2250,1399,0]Am[456,13,457,3598,3173,1399,0]Am[456,13,457,3598,1822,1399,0]Am[456,13,457,3598,1402,1399,0]Am[456,13,457,3598,2972,1399,0]Am[456,13,457,3598,2222,1399,0]Am[456,13,457,3598,4061,1399,0]Am[456,13,457,3598,4066,1399,0]Am[456,13,457,2281,1383,1399,0]Am[456,13,457,2313,4285,1399,0]Am[456,13,457,3994,1836,1399,0]?Aj[456,13,457,3989,3200,0,0]Al[3064,13,3065,1981,3201,0,0]Al[3064,13,4906,4906,4805,0,0]Al[3064,13,3065,3038,2986,0,0]Ak[1964,13,1965,409,4310,0,0]Ah[456,12,1672,0,4690,0,0]Al[3064,12,1673,1673,4691,0,0]32Ag[456,13,457,0,4921,0,0]Al[3064,13,3065,1670,4922,0,0]Aj[456,13,457,3598,3175,0,0]Al[3064,13,3065,3599,3176,0,0]Ah[456,12,1672,0,1810,0,0]Al[3064,12,1673,1673,1811,0,0]Al[1180,14,1364,1364,4306,0,0]Ag[456,14,457,0,2268,0,0]Al[3064,14,3065,3065,2269,0,0]Ai[3064,14,4408,0,1171,0,0]Aj[456,13,457,3989,3200,0,0]Aj[456,13,457,3989,4806,0,0]Al[3064,13,3065,1981,3201,0,0]Ag[456,12,457,0,3217,0,0]Aj[456,13,457,0,4294,3217,0]Aj[456,13,457,0,4626,3217,0]Al[3064,12,3065,1376,3218,0,0]Ao[3064,13,3065,1376,4295,3218,0]Ao[3064,13,3065,4795,4627,3218,0]Af[456,5,457,3029,0,0,0]Ah[3064,5,3065,3029,0,0,0]Ag[456,5,3593,1336,0,0,0]Ah[3064,5,3594,1336,0,0,0]Al[1080,15,1081,1081,4799,0,0]Ag[456,6,1752,1339,0,0,0]Ah[3064,6,1753,1339,0,0,0]Ae[3064,6,4906,0,0,0,0]Ae[3064,6,4657,0,0,0,0]Ah[3064,6,3065,3599,0,0,0]1Al[3064,15,3065,1340,3188,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]Aj[456,15,457,3989,3013,0,0]Ag[456,15,457,0,4396,0,0]Al[3064,15,3065,1105,3014,0,0]Al[3064,15,3065,3599,4397,0,0]Al[3064,15,3065,1735,4409,0,0]0Ae[1180,5,1364,0,0,0,0]Ae[1080,5,1365,0,0,0,0]Al[1180,15,1181,1181,3907,0,0]Al[3064,13,3065,2282,4602,0,0]Ab[1180,3,0,0,0,0,0]Ah[456,12,3593,0,4686,0,0]Ak[456,13,3593,0,2980,4686,0]Ak[456,13,3593,0,3891,4686,0]Ak[456,13,3593,0,4187,4686,0]Al[3064,12,3594,3594,4687,0,0]An[3064,13,3594,147,2981,4687,0]Ao[3064,13,3594,1336,3892,4687,0]Ao[3064,13,3594,2335,4188,4687,0]Al[1080,13,1081,1081,4799,0,0]Ag[456,14,457,0,1137,0,0]Ag[456,14,457,0,2271,0,0]Ag[456,14,457,0,1846,0,0]Al[3064,14,3065,3029,1138,0,0]Al[3064,14,3065,1366,2272,0,0]Al[3064,14,3065,1110,1847,0,0]Al[3064,14,3065,2282,3881,0,0]An[1180,13,1181,1181,133,1139,0]Ao[1180,13,1181,1181,3907,1139,0]Ao[1180,13,1181,1181,3883,1139,0]Am[456,13,457,3598,3175,1139,0]Am[456,13,457,3598,4867,1139,0]Am[456,13,457,3598,4700,1139,0]Am[456,13,457,2281,2234,1139,0]Am[456,13,457,2281,4169,1139,0]Al[456,13,457,1079,496,1139,0]Am[456,13,457,1079,4311,1139,0]Am[456,13,457,3989,4304,1139,0]Am[456,13,457,3989,3013,1139,0]Am[456,13,457,3989,3202,1139,0]Am[456,13,457,3989,4303,1139,0]Am[456,13,457,3994,3220,1139,0]Am[456,13,457,3994,4075,1139,0]Aj[456,13,457,0,1426,1139,0]Aj[456,13,457,0,4864,1139,0]Aj[456,13,457,0,1409,1139,0]Aj[456,13,457,0,2271,1139,0]Aj[456,13,457,0,3181,1139,0]Aj[456,13,457,0,3010,1139,0]Aj[456,13,457,0,4400,1139,0]Aj[456,13,457,0,1846,1139,0]Aj[456,13,457,0,4026,1139,0]Aj[456,13,457,0,4396,1139,0]Aj[456,13,457,0,4419,1139,0]Aj[456,13,457,0,4724,1139,0]Aj[456,13,457,0,4739,1139,0]Aj[456,13,457,0,3896,1139,0]Aj[456,13,457,0,4280,1139,0]Aj[456,13,457,0,4069,1139,0]Aj[456,13,457,0,4921,1139,0]Aj[456,13,457,0,4020,1139,0]Aj[456,13,457,0,3886,1139,0]Aj[456,13,457,0,2993,1139,0]Aj[456,13,457,0,4393,1139,0]Aj[456,13,457,0,4593,1139,0]Aj[456,13,457,0,4032,1139,0]Aj[456,13,457,0,4035,1139,0]Aj[456,13,457,0,4040,1139,0]Aj[456,13,457,0,4759,1139,0]Aj[456,13,457,0,3184,1139,0]Ai[456,13,457,0,503,1139,0]Ai[456,13,457,0,125,1139,0]Aj[456,13,457,0,2258,1139,0]Aj[456,13,3593,0,119,1139,0]Ak[456,13,3593,0,2980,1139,0]Ak[456,13,3593,0,1141,1139,0]Ak[456,13,3593,0,3891,1139,0]Ak[456,13,3593,0,1819,1139,0]Ak[456,13,3593,0,4187,1139,0]Ak[456,13,1752,0,1154,1139,0]Ak[456,13,1752,0,4622,1139,0]Ak[456,13,1752,0,4860,1139,0]Ak[456,13,1752,0,4624,1139,0]Ao[3064,13,3065,1789,1427,1139,0]Ao[3064,13,3065,1789,4865,1139,0]Ao[3064,13,3065,3038,4701,1139,0]Ao[3064,13,3065,1350,1410,1139,0]Ao[3064,13,3065,1350,4065,1139,0]Ao[3064,13,3065,1350,3196,1139,0]Ao[3064,13,3065,1350,3009,1139,0]Ao[3064,13,3065,1350,4699,1139,0]Ao[3064,13,3065,1350,4755,1139,0]Ao[3064,13,3065,1350,3171,1139,0]Ao[3064,13,3065,1366,2272,1139,0]Ao[3064,13,3065,1366,3182,1139,0]Ao[3064,13,3065,1366,3011,1139,0]Ao[3064,13,3065,1366,4401,1139,0]Ao[3064,13,3065,1105,3014,1139,0]Ao[3064,13,3065,1105,4195,1139,0]Ao[3064,13,3065,1110,1847,1139,0]Ao[3064,13,3065,1110,3221,1139,0]Ao[3064,13,3065,1110,3895,1139,0]Ao[3064,13,3065,1981,4305,1139,0]Ao[3064,13,3065,1981,4030,1139,0]Ao[3064,13,3065,3599,4397,1139,0]Ao[3064,13,3065,3599,3006,1139,0]Ao[3064,13,3065,3599,4271,1139,0]Ao[3064,13,3065,3599,4950,1139,0]Ao[3064,13,3065,3158,4420,1139,0]Ao[3064,13,3065,3158,4725,1139,0]Ao[3064,13,3065,3158,4740,1139,0]Ao[3064,13,3065,3158,3897,1139,0]Ao[3064,13,3065,1670,4281,1139,0]Ao[3064,13,3065,1670,4071,1139,0]Ao[3064,13,3065,1670,4922,1139,0]Ao[3064,13,3065,1670,4022,1139,0]Ao[3064,13,3065,1670,3887,1139,0]Ao[3064,13,3065,1340,2994,1139,0]Ao[3064,13,3065,1340,3188,1139,0]Ao[3064,13,3065,1340,3210,1139,0]Ao[3064,13,3065,1340,4037,1139,0]Ao[3064,13,3065,1340,4395,1139,0]Ao[3064,13,3065,1340,4595,1139,0]Ao[3064,13,3065,1340,2228,1139,0]Ao[3064,13,3065,2282,4599,1139,0]Ao[3064,13,3065,2282,4033,1139,0]Ao[3064,13,3065,1735,4409,1139,0]Ao[3064,13,3065,1735,4954,1139,0]Ao[3064,13,3065,1735,2242,1139,0]Ao[3064,13,3065,1735,4697,1139,0]Ao[3064,13,3065,1763,4036,1139,0]Ao[3064,13,3065,1763,4041,1139,0]Al[3064,13,3065,0,4309,1139,0]Al[3064,13,3065,0,4760,1139,0]Ao[3064,13,3065,4208,3185,1139,0]Ao[3064,13,3065,4208,5048,1139,0]An[3064,13,3065,3065,504,1139,0]An[3064,13,3065,3065,126,1139,0]Ao[3064,13,3065,3065,2259,1139,0]Ao[3064,13,3065,3065,2992,1139,0]Ao[3064,13,1668,1668,4201,1139,0]Ao[3064,13,4906,4906,4805,1139,0]Ao[3064,13,4906,4906,1156,1139,0]Al[3064,13,1753,0,1155,1139,0]Ao[3064,13,1753,1753,4623,1139,0]Ao[3064,13,1753,1753,4861,1139,0]Ao[3064,13,1753,1753,4625,1139,0]Am[3064,13,3594,147,120,1139,0]An[3064,13,3594,147,2981,1139,0]Ao[3064,13,3594,1336,1142,1139,0]Ao[3064,13,3594,1336,3892,1139,0]Ao[3064,13,3594,2335,1820,1139,0]Ao[3064,13,3594,2335,4188,1139,0]Ao[3064,13,4657,4657,1160,1139,0]Ao[1964,13,1965,1965,2256,1139,0]Ao[1964,13,1965,1965,2270,1139,0]Ao[1964,13,1965,1965,4042,1139,0]Ao[1080,13,1081,1081,4799,1139,0]Ao[1080,13,1365,1365,4405,1139,0]Ao[1080,13,4128,4128,4999,1139,0]Ao[1080,13,4128,4128,5000,1139,0]Aj[456,13,457,3598,3175,0,0]Aj[456,13,457,2281,2234,0,0]Ai[456,13,457,1079,496,0,0]Al[3064,13,3065,3599,3176,0,0]Aj[456,13,457,0,4035,1145,0]Ao[3064,13,3065,1763,4036,1145,0]Ai[3064,14,3065,0,4309,0,0]Ag[456,13,457,0,2258,0,0]Al[3064,13,3065,3065,2259,0,0]Ag[456,13,457,0,4040,0,0]Al[3064,13,3065,1763,4041,0,0]Ah[456,14,1672,0,1814,0,0]Al[3064,14,1673,1673,1815,0,0]Al[3064,12,3065,1735,4730,0,0]Ao[3064,13,3065,1735,5073,4730,0];Al[1180,13,1364,1364,1174,0,0]Ai[512,13,513,513,3884,0,0]Al[1080,13,1365,1365,1175,0,0]Aj[456,12,457,1973,3164,0,0]Aj[456,13,457,3994,3206,0,0]Al[3064,13,3065,1981,3207,0,0]Aj[456,13,457,2313,2238,0,0]Al[3064,13,3065,2282,2235,0,0]Aj[456,12,457,1973,1831,0,0]Am[456,13,457,1377,4076,1831,0]Am[456,13,457,1122,3910,1831,0]Ae[1180,2,1181,0,0,0,0]Ak[1180,14,1181,1181,133,0,0]Aj[456,13,457,3598,3175,0,0]Aj[456,13,457,2281,2234,0,0]Ai[456,13,457,1079,496,0,0]Al[3064,13,3065,3599,3176,0,0]Ae[1080,2,1081,0,0,0,0]Ag[456,13,457,0,3197,0,0]Al[3064,13,3065,1101,3198,0,0]?>Al[3064,13,4906,4906,4805,0,0]Af[456,5,457,2281,0,0,0]Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]Al[1180,15,1181,1181,3883,0,0]0Al[3064,15,3065,1350,3196,0,0]Ah[3064,5,3065,1105,0,0,0]Af[456,15,457,0,503,0,0]Al[2335,15,2336,2336,2225,0,0]Ak[3064,15,3065,3065,504,0,0]Al[3064,15,4657,4657,1157,0,0]87Af[456,5,457,3598,0,0,0]Al[3064,15,3065,1350,3009,0,0]Al[3064,15,3065,1981,3914,0,0]Af[456,5,457,1350,0,0,0]Ah[3064,5,3065,1350,0,0,0]Ae[3064,8,1668,0,0,0,0]987>Al[3064,15,3065,3599,1159,0,0]>Af[456,5,457,1789,0,0,0]Ah[3064,5,3065,1789,0,0,0]Aj[456,13,457,2281,2234,0,0]Aj[456,13,457,2313,2238,0,0]Al[3064,13,3065,1981,1840,0,0]Al[3064,13,3065,2282,2235,0,0]An[1180,13,1181,1181,133,1389,0]Ao[1180,13,1181,1181,3907,1389,0]Ao[1180,13,1181,1181,3883,1389,0]Ao[1180,13,1364,1364,3915,1389,0]Ao[1180,13,1364,1364,1174,1389,0]Ao[1180,13,1364,1364,4306,1389,0]Al[512,13,513,513,3884,1389,0]Ao[3921,13,3922,3922,4955,1389,0]Am[456,13,457,3598,4424,1389,0]Am[456,13,457,3598,2249,1389,0]Aj[456,13,457,0,4160,1389,0]Am[456,13,457,1079,2250,1389,0]Am[456,13,457,1079,4591,1389,0]Am[456,13,457,3598,3173,1389,0]Am[456,13,457,3598,3175,1389,0]Am[456,13,457,3598,1822,1389,0]Am[456,13,457,3598,1402,1389,0]Am[456,13,457,3598,2972,1389,0]Am[456,13,457,3598,2222,1389,0]Am[456,13,457,3598,4061,1389,0]Am[456,13,457,3598,4066,1389,0]Am[456,13,457,3598,4867,1389,0]Am[456,13,457,3598,4700,1389,0]Am[456,13,457,2281,2234,1389,0]Am[456,13,457,2281,4169,1389,0]Am[456,13,457,2281,1383,1389,0]Am[456,13,457,2313,2238,1389,0]Am[456,13,457,2313,3203,1389,0]Am[456,13,457,2313,4285,1389,0]Al[456,13,457,1079,496,1389,0]Am[456,13,457,1079,4311,1389,0]Am[456,13,457,3989,3200,1389,0]Am[456,13,457,3989,4806,1389,0]Am[456,13,457,3989,4304,1389,0]Am[456,13,457,3989,3013,1389,0]Am[456,13,457,3989,3202,1389,0]Am[456,13,457,3989,4303,1389,0]Am[456,13,457,1377,4076,1389,0]Am[456,13,457,1122,3910,1389,0]Am[456,13,457,3994,3206,1389,0]Am[456,13,457,3994,3220,1389,0]Am[456,13,457,3994,4075,1389,0]Am[456,13,457,3994,1836,1389,0]Aj[456,13,457,0,3197,1389,0]Aj[456,13,457,0,4199,1389,0]Aj[456,13,457,0,4416,1389,0]Aj[456,13,457,0,4053,1389,0]Aj[456,13,457,0,4294,1389,0]Aj[456,13,457,0,1426,1389,0]Aj[456,13,457,0,4864,1389,0]Aj[456,13,457,0,1137,1389,0]Aj[456,13,457,0,1409,1389,0]Aj[456,13,457,0,2271,1389,0]Aj[456,13,457,0,3181,1389,0]Aj[456,13,457,0,3010,1389,0]Aj[456,13,457,0,4400,1389,0]Aj[456,13,457,0,1846,1389,0]Aj[456,13,457,0,4026,1389,0]Aj[456,13,457,0,4396,1389,0]Aj[456,13,457,0,4410,1389,0]Aj[456,13,457,0,4419,1389,0]Aj[456,13,457,0,4724,1389,0]Aj[456,13,457,0,4739,1389,0]Aj[456,13,457,0,3896,1389,0]Aj[456,13,457,0,4280,1389,0]Aj[456,13,457,0,4069,1389,0]Aj[456,13,457,0,4921,1389,0]Aj[456,13,457,0,4020,1389,0]Aj[456,13,457,0,3886,1389,0]Aj[456,13,457,0,2993,1389,0]Aj[456,13,457,0,4393,1389,0]Aj[456,13,457,0,4593,1389,0]Aj[456,13,457,0,4032,1389,0]Aj[456,13,457,0,4035,1389,0]Aj[456,13,457,0,4040,1389,0]Aj[456,13,457,0,4759,1389,0]Aj[456,13,457,0,3184,1389,0]Aj[456,13,457,0,4626,1389,0]Ai[456,13,457,0,503,1389,0]Ai[456,13,457,0,125,1389,0]Aj[456,13,457,0,2258,1389,0]Aj[456,13,457,0,2268,1389,0]Aj[456,13,3593,0,119,1389,0]Ak[456,13,3593,0,2980,1389,0]Ak[456,13,3593,0,1141,1389,0]Ak[456,13,3593,0,3891,1389,0]Ak[456,13,3593,0,1819,1389,0]Ak[456,13,3593,0,4187,1389,0]Ak[456,13,3593,0,4688,1389,0]Ak[456,13,1672,0,1814,1389,0]Aj[456,13,1672,0,490,1389,0]Ak[456,13,1672,0,5013,1389,0]Ak[456,13,1672,0,3889,1389,0]Ak[456,13,1672,0,4763,1389,0]Ak[456,13,1752,0,3215,1389,0]Ak[456,13,1752,0,4171,1389,0]Ak[456,13,1752,0,1154,1389,0]Ak[456,13,1752,0,4622,1389,0]Ak[456,13,1752,0,4860,1389,0]Ak[456,13,1752,0,4624,1389,0]An[2335,13,2336,2336,124,1389,0]Ao[2335,13,2336,2336,2225,1389,0]Ao[3064,13,3065,4429,4161,1389,0]Ao[3064,13,3065,3038,2986,1389,0]Ao[3064,13,3065,1105,1391,1389,0]Ao[3064,13,3065,1981,1840,1389,0]Ao[3064,13,3065,1981,3201,1389,0]Ao[3064,13,3065,1981,3207,1389,0]Ao[3064,13,3065,3599,3176,1389,0]Ao[3064,13,3065,1101,3198,1389,0]Ao[3064,13,3065,1670,4200,1389,0]Ao[3064,13,3065,2282,2235,1389,0]Ao[3064,13,3065,2282,4167,1389,0]Ao[3064,13,3065,2282,4602,1389,0]Ao[3064,13,3065,2282,4178,1389,0]Ao[3064,13,3065,1735,5073,1389,0]Ao[3064,13,3065,4208,5043,1389,0]Ao[3064,13,3065,1376,4417,1389,0]Ao[3064,13,3065,1376,4054,1389,0]Ao[3064,13,3065,1376,4295,1389,0]Ao[3064,13,3065,1789,1427,1389,0]Ao[3064,13,3065,1789,4865,1389,0]Ao[3064,13,3065,3029,1138,1389,0]Ao[3064,13,3065,3038,4701,1389,0]Ao[3064,13,3065,1350,1410,1389,0]Ao[3064,13,3065,1350,4065,1389,0]Ao[3064,13,3065,1350,3196,1389,0]Ao[3064,13,3065,1350,3009,1389,0]Ao[3064,13,3065,1350,4699,1389,0]Ao[3064,13,3065,1350,4755,1389,0]Ao[3064,13,3065,1350,3171,1389,0]Ao[3064,13,3065,1366,2272,1389,0]Ao[3064,13,3065,1366,3182,1389,0]Ao[3064,13,3065,1366,3011,1389,0]Ao[3064,13,3065,1366,4401,1389,0]Ao[3064,13,3065,1105,3014,1389,0]Ao[3064,13,3065,1105,4195,1389,0]Ao[3064,13,3065,1110,1847,1389,0]Ao[3064,13,3065,1110,3221,1389,0]Ao[3064,13,3065,1110,3895,1389,0]Ao[3064,13,3065,1981,3914,1389,0]Ao[3064,13,3065,1981,4305,1389,0]Ao[3064,13,3065,1981,4030,1389,0]Ao[3064,13,3065,3599,4397,1389,0]Ao[3064,13,3065,3599,3006,1389,0]Ao[3064,13,3065,3599,4271,1389,0]Ao[3064,13,3065,3599,4950,1389,0]Ao[3064,13,3065,3599,1159,1389,0]Ao[3064,13,3065,1101,4411,1389,0]Ao[3064,13,3065,3158,4420,1389,0]Ao[3064,13,3065,3158,4725,1389,0]Ao[3064,13,3065,3158,4740,1389,0]Ao[3064,13,3065,3158,3897,1389,0]Ao[3064,13,3065,1670,4281,1389,0]Ao[3064,13,3065,1670,4071,1389,0]Ao[3064,13,3065,1670,4922,1389,0]Ao[3064,13,3065,1670,4022,1389,0]Ao[3064,13,3065,1670,3887,1389,0]Ao[3064,13,3065,1340,2994,1389,0]Ao[3064,13,3065,1340,4286,1389,0]Ao[3064,13,3065,1340,3188,1389,0]Ao[3064,13,3065,1340,3210,1389,0]Ao[3064,13,3065,1340,4037,1389,0]Ao[3064,13,3065,1340,4395,1389,0]Ao[3064,13,3065,1340,4595,1389,0]Ao[3064,13,3065,1340,2228,1389,0]Ao[3064,13,3065,2282,4599,1389,0]Ao[3064,13,3065,2282,2239,1389,0]Ao[3064,13,3065,2282,4033,1389,0]Ao[3064,13,3065,2282,3881,1389,0]Ao[3064,13,3065,2282,3204,1389,0]Ao[3064,13,3065,1735,4190,1389,0]Ao[3064,13,3065,1735,4409,1389,0]Ao[3064,13,3065,1735,4954,1389,0]Ao[3064,13,3065,1735,2242,1389,0]Ao[3064,13,3065,1735,4697,1389,0]Ao[3064,13,3065,1763,4399,1389,0]Ao[3064,13,3065,1763,4168,1389,0]Ao[3064,13,3065,1763,4036,1389,0]Ao[3064,13,3065,1763,4041,1389,0]Al[3064,13,3065,0,4309,1389,0]Al[3064,13,3065,0,4760,1389,0]Ao[3064,13,3065,4208,3185,1389,0]Ao[3064,13,3065,4208,5048,1389,0]Ao[3064,13,3065,4795,4627,1389,0]An[3064,13,3065,3065,504,1389,0]An[3064,13,3065,3065,126,1389,0]Ao[3064,13,3065,3065,2259,1389,0]Ao[3064,13,3065,3065,2269,1389,0]Ao[3064,13,3065,3065,2992,1389,0]Ao[3064,13,1668,1668,4201,1389,0]Ao[3064,13,4906,4906,4805,1389,0]Ao[3064,13,4906,4906,1156,1389,0]Ao[3064,13,1673,1673,1815,1389,0]An[3064,13,1673,1673,491,1389,0]Ao[3064,13,1673,1673,5014,1389,0]Ao[3064,13,1673,1673,3890,1389,0]Ao[3064,13,1673,1673,4766,1389,0]Ao[3064,13,1753,1753,3216,1389,0]Ao[3064,13,1753,1753,4172,1389,0]Al[3064,13,1753,0,1155,1389,0]Ao[3064,13,1753,1753,4623,1389,0]Ao[3064,13,1753,1753,4861,1389,0]Ao[3064,13,1753,1753,4625,1389,0]Am[3064,13,3594,147,120,1389,0]An[3064,13,3594,147,2981,1389,0]Ao[3064,13,3594,1336,1142,1389,0]Ao[3064,13,3594,1336,3892,1389,0]Ao[3064,13,3594,2335,1820,1389,0]Ao[3064,13,3594,2335,4188,1389,0]Ao[3064,13,3594,3594,4689,1389,0]Ao[3064,13,4657,4657,1157,1389,0]Ao[3064,13,4657,4657,1160,1389,0]Ao[1964,13,1965,1965,3219,1389,0]An[1964,13,1965,409,4310,1389,0]Ao[1964,13,1965,1965,2256,1389,0]Ao[1964,13,1965,1965,2270,1389,0]Ao[1964,13,1965,1965,4042,1389,0]Ao[1080,13,1081,1081,2983,1389,0]Ao[1080,13,1081,1081,4799,1389,0]An[1080,13,1662,1662,134,1389,0]Ao[1080,13,1365,1365,1175,1389,0]Ao[1080,13,1365,1365,3916,1389,0]Ao[1080,13,1365,1365,4405,1389,0]Ao[1080,13,4128,4128,4999,1389,0]Ao[1080,13,4128,4128,5000,1389,0]An[1080,13,1758,1758,135,1389,0]Ag[456,14,457,0,1846,0,0]Al[3064,14,3065,1110,1847,0,0]Ak[1180,14,1181,1181,133,0,0]Ac[512,7,513,0,0,0,0]Aj[456,13,457,2281,2234,0,0]Ae[1080,2,1081,0,0,0,0]Ae[4719,7,4720,0,0,0,0]Aj[456,13,457,3598,3175,0,0]Ae[3064,2,3065,0,0,0,0]Al[3064,13,3065,2282,2235,0,0]Af[456,2,457,3065,0,0,0]Ag[456,13,457,0,4759,0,0]Ag[456,14,457,0,3181,0,0]Ag[456,14,457,0,4069,0,0]5Ai[3064,13,3065,0,4760,0,0]Al[3064,14,3065,1366,3182,0,0]Al[3064,14,3065,1670,4071,0,0]Ai[3064,14,3065,0,4309,0,0]Aj[456,13,457,0,1426,2987,0]Aj[456,13,457,0,1409,2987,0]Aj[456,13,457,0,2993,2987,0]Aj[456,13,457,0,4759,2987,0]Aj[456,13,457,0,2258,2987,0]Ao[3064,13,3065,1789,1427,2987,0]Ao[3064,13,3065,1350,1410,2987,0]Ao[3064,13,3065,1340,2994,2987,0]Ao[3064,13,3065,1340,3188,2987,0]Al[3064,13,3065,1735,4409,0,0]Al[3064,13,3065,0,4760,2987,0]Ao[3064,13,3065,3065,2259,2987,0]Al[3064,12,1668,1668,2987,0,0]Al[1964,14,1965,1965,2256,0,0]Aj[456,13,457,0,1426,2990,0]Aj[456,13,457,0,1409,2990,0]Aj[456,13,457,0,2993,2990,0]Aj[456,13,457,0,4759,2990,0]Aj[456,13,457,0,2258,2990,0]Ao[3064,13,3065,1789,1427,2990,0]Ao[3064,13,3065,1350,1410,2990,0]Ao[3064,13,3065,1340,2994,2990,0]Ao[3064,13,3065,1340,3188,2990,0]Ao[3064,13,3065,1340,2228,2990,0]Al[3064,13,3065,0,4760,2990,0]Ao[3064,13,3065,3065,2259,2990,0]Al[3064,12,1668,1668,2990,0,0]Aj[456,13,457,3994,3206,0,0]Al[3064,13,3065,1981,3207,0,0]Al[1080,13,1365,1365,3916,0,0]Al[3064,13,3065,2282,2235,0,0]Ag[456,14,1672,0,490,0,0]Ak[3064,14,1673,1673,491,0,0]Aj[456,13,457,2313,2238,0,0]3Ag[456,12,457,0,3217,0,0]Aj[456,13,457,0,4294,3217,0]Aj[456,13,457,0,4626,3217,0]Al[3064,12,3065,1376,3218,0,0]Ao[3064,13,3065,1376,4295,3218,0]Ao[3064,13,3065,4795,4627,3218,0]Al[1080,14,1081,1081,2983,0,0]Ag[456,14,457,0,1137,0,0]Al[3064,14,3065,3029,1138,0,0]Ah[456,13,3593,0,3177,0,0]Aj[456,13,3593,0,119,3177,0]Ak[456,13,3593,0,1141,3177,0]Ak[456,13,3593,0,1819,3177,0]Al[3064,13,3594,3594,3178,0,0]Am[3064,13,3594,147,120,3178,0]Ao[3064,13,3594,1336,1142,3178,0]Ao[3064,13,3594,2335,1820,3178,0]Ag[456,14,1672,0,490,0,0]Ak[3064,14,1673,1673,491,0,0]Ai[3064,14,4408,0,4631,0,0]Ag[456,14,457,0,4393,0,0]Ag[456,14,457,0,4593,0,0]Al[3064,14,3065,1340,4395,0,0]Al[3064,14,3065,1340,4595,0,0]Ai[3064,14,3065,0,4309,0,0]Ai[3064,14,1158,0,4273,0,0]Ai[3064,14,3007,0,2970,0,0]Aj[456,13,457,2281,2234,0,0]Aj[456,13,457,2313,2238,0,0]Al[3064,13,3065,2282,2235,0,0]Ah[456,14,1672,0,1814,0,0]Al[3064,13,3065,3065,2992,0,0]Al[3064,14,1673,1673,1815,0,0]Ac[456,4,457,0,0,0,0]Ag[456,2,1672,1673,0,0,0]Ae[3064,4,3065,0,0,0,0]Ae[3064,2,1673,0,0,0,0]Ac[512,7,513,0,0,0,0]:Ae[1080,2,1081,0,0,0,0]Ae[4719,7,4720,0,0,0,0]Am[456,13,457,3598,4700,1147,0]Am[456,13,457,3989,4304,1147,0]Am[456,13,457,3989,3013,1147,0]Am[456,13,457,3989,3202,1147,0]Am[456,13,457,3989,4303,1147,0]Am[456,13,457,3994,3220,1147,0]Am[456,13,457,3994,4075,1147,0]Aj[456,13,457,0,4396,1147,0]Ao[3064,13,3065,3599,4397,1147,0]Ag[456,14,457,0,2268,0,0]Al[3064,14,3065,3065,2269,0,0]Al[1964,14,1965,1965,2270,0,0]Ai[456,13,457,1079,496,0,0]Ai[3064,14,3007,0,4062,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]Al[1964,14,1965,1965,2256,0,0]Ag[456,14,457,0,3010,0,0]Ag[456,14,457,0,4400,0,0]Al[3064,14,3065,1366,3011,0,0]Al[3064,14,3065,1366,4401,0,0]3210Ah[456,12,1672,0,1810,0,0]Al[3064,12,1673,1673,1811,0,0]Ah[456,12,3593,0,3177,0,0]Aj[456,13,3593,0,119,3177,0]Ak[456,13,3593,0,1141,3177,0]Ak[456,13,3593,0,1819,3177,0]Al[3064,12,3594,3594,3178,0,0]Am[3064,13,3594,147,120,3178,0]Ao[3064,13,3594,1336,1142,3178,0]Ao[3064,13,3594,2335,1820,3178,0]Al[3064,15,3065,3038,4701,0,0]Al[3064,15,3065,1105,3014,0,0]Al[3064,15,3065,1110,3221,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]Ah[456,10,1672,1673,0,0,0]Af[3064,10,1673,0,0,0,0]Al[3064,15,3065,1735,4409,0,0]Ag[456,5,1672,1673,0,0,0]Ae[3064,5,1673,0,0,0,0]Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]Ag[456,5,3593,2335,0,0,0]Ah[3064,5,3594,2335,0,0,0]Al[1080,15,1081,1081,4799,0,0]Af[456,5,457,3598,0,0,0]5454Ag[456,10,457,1973,0,0,0];:Aj[456,15,457,3994,3220,0,0]Af[456,5,457,3994,0,0,0]Al[3064,15,3065,1110,3221,0,0]Al[3064,15,3065,1110,3895,0,0]Al[3064,15,3065,1981,3914,0,0]Ah[3064,5,3065,1981,0,0,0]Aj[456,15,457,3989,4304,0,0]Al[3064,15,3065,1340,3188,0,0]Af[456,5,457,1110,0,0,0]Ah[3064,5,3065,1110,0,0,0]Al[3064,15,3065,1735,2242,0,0]Ag[456,12,457,0,4912,0,0]Al[3064,12,3065,4208,4913,0,0]Ao[3064,13,3065,4208,5043,4913,0]Ao[3064,13,3065,4208,5048,4913,0]Ak[1180,14,1181,1181,133,0,0]An[1180,13,1181,1181,133,4272,0]An[2335,13,2336,2336,124,4272,0]Ak[2335,14,2336,2336,124,0,0]Ao[1080,13,1081,1081,2983,4272,0]An[1080,13,1662,1662,134,4272,0]An[1080,13,1758,1758,135,4272,0]Aj[456,13,457,0,1426,3172,0]Aj[456,13,457,0,1409,3172,0]Aj[456,13,457,0,3896,3172,0]Aj[456,13,457,0,4035,3172,0]Ai[456,13,457,0,503,3172,0]Ai[456,13,457,0,125,3172,0]Aj[456,13,457,0,2258,3172,0]Ao[3064,13,3065,1789,1427,3172,0]Ao[3064,13,3065,3038,4701,3172,0]Ao[3064,13,3065,1350,1410,3172,0]Ao[3064,13,3065,1105,3014,3172,0]Ao[3064,13,3065,1105,4195,3172,0]Ao[3064,13,3065,1110,3221,3172,0]Ao[3064,13,3065,3158,3897,3172,0]Ao[3064,13,3065,2282,4599,3172,0]Ao[3064,13,3065,1735,4697,3172,0]Ao[3064,13,3065,1763,4036,3172,0]An[3064,13,3065,3065,504,3172,0]An[3064,13,3065,3065,126,3172,0]Ao[3064,13,3065,3065,2259,3172,0]Aj[456,13,457,2281,2234,0,0]Al[3064,13,3065,2282,2235,0,0]Aj[456,13,457,2313,2238,0,0]Ah[456,12,1672,0,3003,0,0]Ah[456,12,1672,0,2996,0,0]Al[3064,13,3065,2282,2239,0,0]Al[3064,12,1673,1673,3004,0,0]Al[3064,12,1673,1673,2997,0,0]Ao[1180,13,1364,1364,3915,1805,0]Ao[1180,13,1364,1364,1174,1805,0]Al[512,13,513,513,3884,1805,0]Aj[456,13,457,0,4160,1805,0]Am[456,13,457,2281,4169,1805,0]Aj[456,13,457,0,1426,1805,0]Aj[456,13,457,0,1409,1805,0]Aj[456,13,457,0,2271,1805,0]Aj[456,13,457,0,3181,1805,0]Aj[456,13,457,0,3010,1805,0]Aj[456,13,457,0,4400,1805,0]Aj[456,13,457,0,1846,1805,0]Aj[456,13,457,0,4026,1805,0]Aj[456,13,457,0,4419,1805,0]Aj[456,13,457,0,4724,1805,0]Aj[456,13,457,0,4739,1805,0]Aj[456,13,457,0,3896,1805,0]Aj[456,13,457,0,4280,1805,0]Aj[456,13,457,0,4921,1805,0]Aj[456,13,457,0,4626,1805,0]Ak[456,13,3593,0,2980,1805,0]Ak[456,13,3593,0,3891,1805,0]Ak[456,13,3593,0,4187,1805,0]Ak[456,13,3593,0,4688,1805,0]Ao[3064,13,3065,4429,4161,1805,0]Ao[3064,13,3065,4208,5043,1805,0]Ao[3064,13,3065,1789,1427,1805,0]Ao[3064,13,3065,1350,1410,1805,0]Ao[3064,13,3065,1350,3196,1805,0]Ao[3064,13,3065,1350,3171,1805,0]Ao[3064,13,3065,1366,2272,1805,0]Ao[3064,13,3065,1366,3182,1805,0]Ao[3064,13,3065,1366,3011,1805,0]Ao[3064,13,3065,1366,4401,1805,0]Ao[3064,13,3065,1110,1847,1805,0]Ao[3064,13,3065,1981,4305,1805,0]Ao[3064,13,3065,1981,4030,1805,0]Ao[3064,13,3065,3158,4420,1805,0]Ao[3064,13,3065,3158,4725,1805,0]Ao[3064,13,3065,3158,4740,1805,0]Ao[3064,13,3065,3158,3897,1805,0]Ao[3064,13,3065,1670,4281,1805,0]Ao[3064,13,3065,1670,4922,1805,0]Ao[3064,13,3065,4208,5048,1805,0]Ao[3064,13,3065,4795,4627,1805,0]An[3064,13,3594,147,2981,1805,0]Ao[3064,13,3594,1336,3892,1805,0]Ao[3064,13,3594,2335,4188,1805,0]Ao[3064,13,3594,3594,4689,1805,0]Ao[1964,13,1965,1965,2256,1805,0]Ao[1080,13,1365,1365,1175,1805,0]Ao[1080,13,1365,1365,4405,1805,0]Al[3064,13,3065,1763,4168,0,0]Al[3064,13,3065,1735,4190,0,0]Al[3064,13,3065,1735,4409,0,0]Al[3064,14,3065,1735,4954,0,0]Ai[3064,14,4696,0,4761,0,0]Ah[3064,14,4408,0,492,0,0]Ai[3064,14,4408,0,1169,0,0]Ai[3064,14,4408,0,1171,0,0]Ai[3064,14,4408,0,4631,0,0]Ah[456,12,1672,0,3003,0,0]Ah[456,12,1672,0,2996,0,0]Al[3064,12,1673,1673,3004,0,0]Al[3064,12,1673,1673,2997,0,0]Aj[456,13,457,3989,3200,0,0]Aj[456,13,457,3989,4806,0,0]Ah[456,13,3593,0,3177,0,0]Aj[456,13,3593,0,119,3177,0]Ak[456,13,3593,0,1141,3177,0]Ak[456,13,3593,0,1819,3177,0]Al[3064,13,3594,3594,3178,0,0]Am[3064,13,3594,147,120,3178,0]Ao[3064,13,3594,1336,1142,3178,0]Ao[3064,13,3594,2335,1820,3178,0]Ag[456,13,457,0,4419,0,0]Al[3064,13,3065,3158,4420,0,0]Ab[1964,3,0,0,0,0,0]:965Aj[456,13,457,3598,3175,0,0]Aj[456,13,457,1079,2250,0,0]Al[3064,14,3065,1735,4954,0,0]Ai[3064,14,4696,0,4761,0,0]Ah[3064,14,4408,0,492,0,0]Ai[3064,14,4408,0,1169,0,0]Ai[3064,14,4408,0,4631,0,0]Aj[456,13,457,3994,3206,0,0]Al[3064,13,3065,1981,3207,0,0]Ak[1180,14,1181,1181,133,0,0]Al[1180,14,1364,1364,1174,0,0]Al[3064,13,3065,3599,3176,0,0]Ah[456,12,1672,0,3003,0,0]Al[3064,12,1673,1673,3004,0,0]Am[1180,13,1181,1181,133,117,0]An[1180,13,1181,1181,3907,117,0]An[1180,13,1181,1181,3883,117,0]An[1180,13,1364,1364,3915,117,0]An[1180,13,1364,1364,1174,117,0]An[1180,13,1364,1364,4306,117,0]Ak[512,13,513,513,3884,117,0]An[3921,13,3922,3922,4955,117,0]Al[456,13,457,3598,4424,117,0]Al[456,13,457,3598,2249,117,0]Ai[456,13,457,0,4160,117,0]Al[456,13,457,1079,2250,117,0]Al[456,13,457,1079,4591,117,0]Al[456,13,457,3598,3173,117,0]Al[456,13,457,3598,3175,117,0]Al[456,13,457,3598,1822,117,0]Al[456,13,457,3598,1402,117,0]Al[456,13,457,3598,2972,117,0]Al[456,13,457,3598,2222,117,0]Al[456,13,457,3598,4061,117,0]Al[456,13,457,3598,4066,117,0]Al[456,13,457,3598,4867,117,0]Al[456,13,457,3598,4700,117,0]Al[456,13,457,2281,2234,117,0]Al[456,13,457,2281,4169,117,0]Al[456,13,457,2281,1383,117,0]Al[456,13,457,2313,2238,117,0]Al[456,13,457,2313,3203,117,0]Al[456,13,457,2313,4285,117,0]Ak[456,13,457,1079,496,117,0]Al[456,13,457,1079,4311,117,0]Al[456,13,457,3989,3200,117,0]Al[456,13,457,3989,4806,117,0]Al[456,13,457,3989,4304,117,0]Al[456,13,457,3989,3013,117,0]Al[456,13,457,3989,3202,117,0]Al[456,13,457,3989,4303,117,0]Al[456,13,457,1377,4076,117,0]Al[456,13,457,1122,3910,117,0]Al[456,13,457,3994,3206,117,0]Al[456,13,457,3994,3220,117,0]Al[456,13,457,3994,4075,117,0]Al[456,13,457,3994,1836,117,0]Ai[456,13,457,0,3197,117,0]Ai[456,13,457,0,4199,117,0]Ai[456,13,457,0,4416,117,0]Ai[456,13,457,0,4053,117,0]Ai[456,13,457,0,4294,117,0]Ai[456,13,457,0,1426,117,0]Ai[456,13,457,0,4864,117,0]Ai[456,13,457,0,1137,117,0]Ai[456,13,457,0,1409,117,0]Ai[456,13,457,0,2271,117,0]Ai[456,13,457,0,3181,117,0]Ai[456,13,457,0,3010,117,0]Ai[456,13,457,0,4400,117,0]Ai[456,13,457,0,1846,117,0]Ai[456,13,457,0,4026,117,0]Ai[456,13,457,0,4396,117,0]Ai[456,13,457,0,4410,117,0]Ai[456,13,457,0,4419,117,0]Ai[456,13,457,0,4724,117,0]Ai[456,13,457,0,4739,117,0]Ai[456,13,457,0,3896,117,0]Ai[456,13,457,0,4280,117,0]Ai[456,13,457,0,4069,117,0]Ai[456,13,457,0,4921,117,0]Ai[456,13,457,0,4020,117,0]Ai[456,13,457,0,3886,117,0]Ai[456,13,457,0,2993,117,0]Ai[456,13,457,0,4393,117,0]Ai[456,13,457,0,4593,117,0]Ai[456,13,457,0,4032,117,0]Ai[456,13,457,0,4035,117,0]Ai[456,13,457,0,4040,117,0]Ai[456,13,457,0,4759,117,0]Ai[456,13,457,0,3184,117,0]Ai[456,13,457,0,4626,117,0]Ah[456,13,457,0,503,117,0]Ah[456,13,457,0,125,117,0]Ai[456,13,457,0,2258,117,0]Ai[456,13,457,0,2268,117,0]Ai[456,13,3593,0,119,117,0]Aj[456,13,3593,0,2980,117,0]Aj[456,13,3593,0,1141,117,0]Aj[456,13,3593,0,3891,117,0]Aj[456,13,3593,0,1819,117,0]Aj[456,13,3593,0,4187,117,0]Aj[456,13,3593,0,4688,117,0]Aj[456,13,1672,0,1814,117,0]Ai[456,13,1672,0,490,117,0]Aj[456,13,1672,0,5013,117,0]Aj[456,13,1672,0,3889,117,0]Aj[456,13,1672,0,4763,117,0]Aj[456,13,1752,0,3215,117,0]Aj[456,13,1752,0,4171,117,0]Aj[456,13,1752,0,1154,117,0]Aj[456,13,1752,0,4622,117,0]Aj[456,13,1752,0,4860,117,0]Aj[456,13,1752,0,4624,117,0]Am[2335,13,2336,2336,124,117,0]An[2335,13,2336,2336,2225,117,0]An[3064,13,3065,4429,4161,117,0]An[3064,13,3065,3038,2986,117,0]An[3064,13,3065,1105,1391,117,0]An[3064,13,3065,1981,1840,117,0]An[3064,13,3065,1981,3201,117,0]An[3064,13,3065,1981,3207,117,0]An[3064,13,3065,3599,3176,117,0]An[3064,13,3065,1101,3198,117,0]An[3064,13,3065,1670,4200,117,0]An[3064,13,3065,2282,2235,117,0]An[3064,13,3065,2282,4167,117,0]An[3064,13,3065,2282,4602,117,0]An[3064,13,3065,2282,4178,117,0]An[3064,13,3065,1735,5073,117,0]An[3064,13,3065,4208,5043,117,0]An[3064,13,3065,1376,4417,117,0]An[3064,13,3065,1376,4054,117,0]An[3064,13,3065,1376,4295,117,0]An[3064,13,3065,1789,1427,117,0]An[3064,13,3065,1789,4865,117,0]An[3064,13,3065,3029,1138,117,0]An[3064,13,3065,3038,4701,117,0]An[3064,13,3065,1350,1410,117,0]An[3064,13,3065,1350,4065,117,0]An[3064,13,3065,1350,3196,117,0]An[3064,13,3065,1350,3009,117,0]An[3064,13,3065,1350,4699,117,0]An[3064,13,3065,1350,4755,117,0]An[3064,13,3065,1350,3171,117,0]An[3064,13,3065,1366,2272,117,0]An[3064,13,3065,1366,3182,117,0]An[3064,13,3065,1366,3011,117,0]An[3064,13,3065,1366,4401,117,0]An[3064,13,3065,1105,3014,117,0]An[3064,13,3065,1105,4195,117,0]An[3064,13,3065,1110,1847,117,0]An[3064,13,3065,1110,3221,117,0]An[3064,13,3065,1110,3895,117,0]An[3064,13,3065,1981,3914,117,0]An[3064,13,3065,1981,4305,117,0]An[3064,13,3065,1981,4030,117,0]An[3064,13,3065,3599,4397,117,0]An[3064,13,3065,3599,3006,117,0]An[3064,13,3065,3599,4271,117,0]An[3064,13,3065,3599,4950,117,0]An[3064,13,3065,3599,1159,117,0]An[3064,13,3065,1101,4411,117,0]An[3064,13,3065,3158,4420,117,0]An[3064,13,3065,3158,4725,117,0]An[3064,13,3065,3158,4740,117,0]An[3064,13,3065,3158,3897,117,0]An[3064,13,3065,1670,4281,117,0]An[3064,13,3065,1670,4071,117,0]An[3064,13,3065,1670,4922,117,0]An[3064,13,3065,1670,4022,117,0]An[3064,13,3065,1670,3887,117,0]An[3064,13,3065,1340,2994,117,0]An[3064,13,3065,1340,4286,117,0]An[3064,13,3065,1340,3188,117,0]An[3064,13,3065,1340,3210,117,0]An[3064,13,3065,1340,4037,117,0]An[3064,13,3065,1340,4395,117,0]An[3064,13,3065,1340,4595,117,0]An[3064,13,3065,1340,2228,117,0]An[3064,13,3065,2282,4599,117,0]An[3064,13,3065,2282,2239,117,0]An[3064,13,3065,2282,4033,117,0]An[3064,13,3065,2282,3881,117,0]An[3064,13,3065,2282,3204,117,0]An[3064,13,3065,1735,4190,117,0]An[3064,13,3065,1735,4409,117,0]An[3064,13,3065,1735,4954,117,0]An[3064,13,3065,1735,2242,117,0]An[3064,13,3065,1735,4697,117,0]An[3064,13,3065,1763,4399,117,0]An[3064,13,3065,1763,4168,117,0]An[3064,13,3065,1763,4036,117,0]An[3064,13,3065,1763,4041,117,0]Ak[3064,13,3065,0,4309,117,0]Ak[3064,13,3065,0,4760,117,0]An[3064,13,3065,4208,3185,117,0]An[3064,13,3065,4208,5048,117,0]An[3064,13,3065,4795,4627,117,0]Am[3064,13,3065,3065,504,117,0]Am[3064,13,3065,3065,126,117,0]An[3064,13,3065,3065,2259,117,0]An[3064,13,3065,3065,2269,117,0]An[3064,13,3065,3065,2992,117,0]An[3064,13,1668,1668,4201,117,0]An[3064,13,4906,4906,4805,117,0]An[3064,13,4906,4906,1156,117,0]An[3064,13,1673,1673,1815,117,0]Am[3064,13,1673,1673,491,117,0]An[3064,13,1673,1673,5014,117,0]An[3064,13,1673,1673,3890,117,0]An[3064,13,1673,1673,4766,117,0]An[3064,13,1753,1753,3216,117,0]An[3064,13,1753,1753,4172,117,0]Ak[3064,13,1753,0,1155,117,0]An[3064,13,1753,1753,4623,117,0]An[3064,13,1753,1753,4861,117,0]An[3064,13,1753,1753,4625,117,0]Al[3064,13,3594,147,120,117,0]Am[3064,13,3594,147,2981,117,0]An[3064,13,3594,1336,1142,117,0]An[3064,13,3594,1336,3892,117,0]An[3064,13,3594,2335,1820,117,0]An[3064,13,3594,2335,4188,117,0]An[3064,13,3594,3594,4689,117,0]An[3064,13,4657,4657,1157,117,0]An[3064,13,4657,4657,1160,117,0]An[1964,13,1965,1965,3219,117,0]Am[1964,13,1965,409,4310,117,0]An[1964,13,1965,1965,2256,117,0]An[1964,13,1965,1965,2270,117,0]An[1964,13,1965,1965,4042,117,0]An[1080,13,1081,1081,2983,117,0]An[1080,13,1081,1081,4799,117,0]Am[1080,13,1662,1662,134,117,0]An[1080,13,1365,1365,1175,117,0]An[1080,13,1365,1365,3916,117,0]An[1080,13,1365,1365,4405,117,0]An[1080,13,4128,4128,4999,117,0]An[1080,13,4128,4128,5000,117,0]Am[1080,13,1758,1758,135,117,0]Aj[456,13,457,3598,4867,0,0]Aj[456,13,457,1079,4311,0,0]Ag[456,13,457,0,4020,0,0]Al[3064,13,3065,1670,4022,0,0]Al[3064,14,3065,1735,4954,0,0]Ai[3064,14,4696,0,4761,0,0]Ah[3064,14,4408,0,492,0,0]Ai[3064,14,4408,0,1169,0,0]Af[456,5,457,3598,0,0,0]Al[1180,15,1181,1181,3883,0,0]Ae[2335,6,2336,0,0,0,0]Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]Ah[3064,5,3065,1340,0,0,0]Aj[456,15,457,3598,4700,0,0]Al[3064,15,3065,3038,4701,0,0]Af[456,5,457,2281,0,0,0]Ah[3064,5,3065,2282,0,0,0]Al[3064,15,3065,1981,3914,0,0]Af[456,5,457,2313,0,0,0]2Ah[3064,6,3065,1735,0,0,0]Ag[456,19,457,0,1426,0,0]Al[3064,19,3065,1789,1427,0,0]Ag[456,19,457,0,4759,0,0]Ai[3064,19,3065,0,4760,0,0]=Ah[456,12,1672,0,4070,0,0]>Ak[456,13,1752,0,4624,4070,0]>Al[3064,12,1673,1673,4072,0,0]>Ao[3064,13,1753,1753,4625,4072,0]Ao[1080,13,4128,4128,5000,4072,0]An[2335,13,2336,2336,124,3898,0]Ao[2335,13,2336,2336,2225,3898,0]Ag[456,14,457,0,3010,0,0]Al[3064,14,3065,1366,3011,0,0]Ag[456,13,457,0,4069,0,0]Al[3064,13,3065,1670,4071,0,0]Aj[456,13,457,1973,4268,0,0]0>=Al[1080,13,1365,1365,4405,0,0]Ae[1080,2,1081,0,0,0,0]Aj[456,13,457,2313,2238,0,0]Al[3064,13,3065,2282,2239,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]Al[3064,13,3065,3599,3176,0,0]Ag[456,13,457,0,4419,0,0]Al[3064,13,3065,3158,4420,0,0]43Ak[1180,14,1181,1181,133,0,0]Ag[456,14,457,0,2268,0,0]Al[3064,14,3065,3065,2269,0,0]Al[1964,14,1965,1965,2270,0,0]Al[3064,13,3065,1981,1840,0,0]Al[3064,13,3065,4208,5043,0,0]Al[3064,13,3065,4208,5048,0,0]Aj[456,13,457,3994,3206,0,0]Al[3064,13,3065,1981,3207,0,0]=Al[1180,14,1364,1364,1174,0,0]Ao[1080,13,1081,1081,4799,3018,0]Ag[456,15,457,0,2993,0,0]Af[456,5,457,1340,0,0,0]Al[3064,15,3065,1340,2994,0,0]Ah[3064,5,3065,1340,0,0,0]Af[456,6,457,3599,0,0,0]Ah[3064,6,3065,3599,0,0,0]Al[3064,15,3065,2282,4167,0,0]Ah[3064,5,3065,1763,0,0,0]Af[456,5,457,1366,0,0,0]Ah[3064,5,3065,1366,0,0,0]97Ae[1080,5,1365,0,0,0,0]:8Ah[3064,6,3065,1735,0,0,0]Af[456,5,457,1101,0,0,0]Ah[3064,5,3065,1101,0,0,0]Al[3064,15,3065,1350,4699,0,0]Af[456,5,457,1376,0,0,0]Ah[3064,5,3065,1376,0,0,0]Af[456,5,457,3158,0,0,0]Ah[3064,5,3065,3158,0,0,0]Ag[456,15,457,0,4396,0,0]Al[3064,15,3065,3599,4397,0,0]Af[456,5,457,3598,0,0,0]Aj[456,15,457,3989,3013,0,0]Aj[456,15,457,3989,3202,0,0]Aj[456,15,457,3994,3220,0,0]Aj[456,15,457,3994,4075,0,0]An[1180,13,1181,1181,133,4166,0]Ao[1180,13,1181,1181,3907,4166,0]Ao[1180,13,1181,1181,3883,4166,0]Am[456,13,457,3598,3175,4166,0]Am[456,13,457,3598,4867,4166,0]Am[456,13,457,3598,4700,4166,0]Am[456,13,457,2281,2234,4166,0]Am[456,13,457,2281,4169,4166,0]Al[456,13,457,1079,496,4166,0]Am[456,13,457,1079,4311,4166,0]Am[456,13,457,3989,4304,4166,0]Am[456,13,457,3989,3013,4166,0]Am[456,13,457,3989,3202,4166,0]Am[456,13,457,3989,4303,4166,0]Am[456,13,457,3994,3220,4166,0]Am[456,13,457,3994,4075,4166,0]Aj[456,13,457,0,1426,4166,0]Aj[456,13,457,0,4864,4166,0]Aj[456,13,457,0,1409,4166,0]Aj[456,13,457,0,2271,4166,0]Aj[456,13,457,0,3181,4166,0]Aj[456,13,457,0,3010,4166,0]Aj[456,13,457,0,4400,4166,0]Aj[456,13,457,0,1846,4166,0]Aj[456,13,457,0,4026,4166,0]Aj[456,13,457,0,4396,4166,0]Aj[456,13,457,0,4419,4166,0]Aj[456,13,457,0,4724,4166,0]Aj[456,13,457,0,4739,4166,0]Aj[456,13,457,0,3896,4166,0]Aj[456,13,457,0,4280,4166,0]Aj[456,13,457,0,4069,4166,0]Aj[456,13,457,0,4921,4166,0]Aj[456,13,457,0,4020,4166,0]Aj[456,13,457,0,3886,4166,0]Aj[456,13,457,0,2993,4166,0]Aj[456,13,457,0,4393,4166,0]Aj[456,13,457,0,4593,4166,0]Aj[456,13,457,0,4032,4166,0]Aj[456,13,457,0,4035,4166,0]Aj[456,13,457,0,4040,4166,0]Aj[456,13,457,0,4759,4166,0]Aj[456,13,457,0,3184,4166,0]Ai[456,13,457,0,503,4166,0]Ai[456,13,457,0,125,4166,0]Aj[456,13,457,0,2258,4166,0]Aj[456,13,3593,0,119,4166,0]Ak[456,13,3593,0,2980,4166,0]Ak[456,13,3593,0,1141,4166,0]Ak[456,13,3593,0,3891,4166,0]Ak[456,13,3593,0,1819,4166,0]Ak[456,13,3593,0,4187,4166,0]Ak[456,13,1752,0,1154,4166,0]Ak[456,13,1752,0,4622,4166,0]Ak[456,13,1752,0,4860,4166,0]Ak[456,13,1752,0,4624,4166,0]Ao[3064,13,3065,1789,1427,4166,0]Ao[3064,13,3065,1789,4865,4166,0]Ao[3064,13,3065,3038,4701,4166,0]Ao[3064,13,3065,1350,1410,4166,0]Ao[3064,13,3065,1350,4065,4166,0]Ao[3064,13,3065,1350,3196,4166,0]Ao[3064,13,3065,1350,3009,4166,0]Ao[3064,13,3065,1350,4699,4166,0]Ao[3064,13,3065,1350,4755,4166,0]Ao[3064,13,3065,1350,3171,4166,0]Ao[3064,13,3065,1366,2272,4166,0]Ao[3064,13,3065,1366,3182,4166,0]Ao[3064,13,3065,1366,3011,4166,0]Ao[3064,13,3065,1366,4401,4166,0]Ao[3064,13,3065,1105,3014,4166,0]Ao[3064,13,3065,1105,4195,4166,0]Ao[3064,13,3065,1110,1847,4166,0]Ao[3064,13,3065,1110,3221,4166,0]Ao[3064,13,3065,1110,3895,4166,0]Ao[3064,13,3065,1981,4305,4166,0]Ao[3064,13,3065,1981,4030,4166,0]Ao[3064,13,3065,3599,4397,4166,0]Ao[3064,13,3065,3599,3006,4166,0]Ao[3064,13,3065,3599,4271,4166,0]Ao[3064,13,3065,3599,4950,4166,0]Ao[3064,13,3065,3158,4420,4166,0]Ao[3064,13,3065,3158,4725,4166,0]Ao[3064,13,3065,3158,4740,4166,0]Ao[3064,13,3065,3158,3897,4166,0]Ao[3064,13,3065,1670,4281,4166,0]Ao[3064,13,3065,1670,4071,4166,0]Ao[3064,13,3065,1670,4922,4166,0]Ao[3064,13,3065,1670,4022,4166,0]Ao[3064,13,3065,1670,3887,4166,0]Ao[3064,13,3065,1340,2994,4166,0]Ao[3064,13,3065,1340,3188,4166,0]Ao[3064,13,3065,1340,3210,4166,0]Ao[3064,13,3065,1340,4037,4166,0]Ao[3064,13,3065,1340,4395,4166,0]Ao[3064,13,3065,1340,4595,4166,0]Ao[3064,13,3065,1340,2228,4166,0]Ao[3064,13,3065,2282,4599,4166,0]Ao[3064,13,3065,2282,4033,4166,0]Ao[3064,13,3065,1735,4409,4166,0]Ao[3064,13,3065,1735,4954,4166,0]Ao[3064,13,3065,1735,2242,4166,0]Ao[3064,13,3065,1735,4697,4166,0]Ao[3064,13,3065,1763,4036,4166,0]Ao[3064,13,3065,1763,4041,4166,0]Al[3064,13,3065,0,4309,4166,0]Al[3064,13,3065,0,4760,4166,0]Ao[3064,13,3065,4208,3185,4166,0]Ao[3064,13,3065,4208,5048,4166,0]An[3064,13,3065,3065,504,4166,0]An[3064,13,3065,3065,126,4166,0]Ao[3064,13,3065,3065,2259,4166,0]Ao[3064,13,3065,3065,2992,4166,0]Ao[3064,13,1668,1668,4201,4166,0]Ao[3064,13,4906,4906,4805,4166,0]Ao[3064,13,4906,4906,1156,4166,0]Al[3064,13,1753,0,1155,4166,0]Ao[3064,13,1753,1753,4623,4166,0]Ao[3064,13,1753,1753,4861,4166,0]Ao[3064,13,1753,1753,4625,4166,0]Am[3064,13,3594,147,120,4166,0]An[3064,13,3594,147,2981,4166,0]Ao[3064,13,3594,1336,1142,4166,0]Ao[3064,13,3594,1336,3892,4166,0]Ao[3064,13,3594,2335,1820,4166,0]Ao[3064,13,3594,2335,4188,4166,0]Ao[3064,13,4657,4657,1160,4166,0]Ao[1964,13,1965,1965,2256,4166,0]Ao[1964,13,1965,1965,2270,4166,0]Ao[1964,13,1965,1965,4042,4166,0]Ao[1080,13,1081,1081,4799,4166,0]Ao[1080,13,1365,1365,4405,4166,0]Ao[1080,13,4128,4128,4999,4166,0]Ao[1080,13,4128,4128,5000,4166,0]Af[456,7,457,1973,0,0,0]Ag[456,13,457,0,4280,0,0]Al[3064,13,3065,1670,4281,0,0]Ah[456,12,1672,0,3003,0,0]Al[3064,12,1673,1673,3004,0,0]Al[1964,14,1965,1965,2256,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]10Ae[1080,7,1081,0,0,0,0]Aj[456,13,457,2281,2234,0,0]Ae[4211,7,4212,0,0,0,0]Ae[1180,7,1181,0,0,0,0]Al[3064,13,3065,3599,3176,0,0]Aj[456,13,457,3598,3175,0,0]1Al[3064,13,3065,1981,4305,0,0]Al[1180,13,1364,1364,1174,0,0]Al[1180,14,1364,1364,3915,0,0]Aj[456,12,457,1973,1831,0,0]Am[456,13,457,1377,4076,1831,0]Am[456,13,457,1122,3910,1831,0]Ah[456,12,1672,0,1832,0,0]Ak[456,13,1752,0,3215,1832,0]Al[3064,12,1673,1673,1833,0,0]Ao[3064,13,1753,1753,3216,1833,0]Af[456,5,457,1079,0,0,0]Ag[456,15,457,0,2993,0,0]Af[456,5,457,1340,0,0,0]Al[3064,15,3065,1340,2994,0,0]Ah[3064,5,3065,1340,0,0,0]Ag[456,15,457,0,4396,0,0]Al[3064,15,3065,3599,4397,0,0]Ah[3064,5,3065,2282,0,0,0]Al[3064,15,3065,3599,1159,0,0]1Ag[456,15,457,0,4032,0,0]Al[3064,15,3065,2282,4033,0,0]Ag[456,19,457,0,4759,0,0]Ai[3064,19,3065,0,4760,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]32Al[3064,15,3065,3599,3006,0,0]><><><21Ag[456,5,1752,1753,0,0,0]Ae[3064,5,1753,0,0,0,0]10Af[456,5,457,4795,0,0,0]Ah[3064,5,3065,4795,0,0,0]Al[3064,15,4657,4657,1157,0,0]Al[3064,15,3065,1350,4699,0,0]6Al[3064,15,3065,1735,4409,0,0]Ag[456,12,457,0,2264,0,0]Aj[456,13,457,0,4160,2264,0]Aj[456,13,457,0,4053,2264,0]Al[3064,12,3065,1376,2265,0,0]Ao[3064,13,3065,4429,4161,2265,0]Ao[3064,13,3065,1376,4054,2265,0]Ae[3921,7,3922,0,0,0,0]Aj[456,13,457,3598,3175,0,0]Al[3064,13,3065,3599,3176,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]32An[1180,13,1181,1181,133,4282,0]An[2335,13,2336,2336,124,4282,0]Ao[2335,13,2336,2336,2225,4282,0]Ao[1080,13,1081,1081,2983,4282,0]An[1080,13,1662,1662,134,4282,0]An[1080,13,1758,1758,135,4282,0]Ak[1964,13,1965,409,4310,0,0]Ag[456,13,457,0,4419,0,0]Al[3064,13,3065,3158,4420,0,0]:9Ae[3064,2,3065,0,0,0,0]Aj[456,13,457,2281,2234,0,0]Al[3064,13,3065,2282,2235,0,0]?>43Ae[4211,7,4212,0,0,0,0]6Al[1080,14,1081,1081,2983,0,0]70Ae[1180,7,1181,0,0,0,0]Ag[456,13,457,0,4069,0,0]Ag[456,13,457,0,4020,0,0]Al[3064,13,3065,1670,4071,0,0]Al[3064,13,3065,1670,4022,0,0]Ag[456,14,457,0,4069,0,0]Al[3064,14,3065,1670,4071,0,0]53Aj[456,13,457,3994,3206,0,0]Ag[456,19,457,0,4759,0,0]Ai[3064,19,3065,0,4760,0,0]Ag[456,15,457,0,4396,0,0]Al[3064,15,3065,1350,4699,0,0]Al[3064,15,3065,3599,4397,0,0]Ah[456,10,3593,3594,0,0,0]Af[3064,10,3594,0,0,0,0]Ag[456,5,3593,3594,0,0,0]Ae[3064,5,3594,0,0,0,0]Ah[456,10,1672,1673,0,0,0]Af[3064,10,1673,0,0,0,0]Ag[456,15,457,0,4032,0,0]Al[3064,15,3065,2282,4033,0,0]Ag[456,10,457,3599,0,0,0]Ai[3064,10,3065,3599,0,0,0]Ah[3064,6,3065,1735,0,0,0]Ah[3064,6,3065,1350,0,0,0]Af[456,6,457,3598,0,0,0]Ah[3064,6,3065,3038,0,0,0]Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]10Aj[456,15,457,3598,4700,0,0]Al[3064,15,3065,3038,4701,0,0]Ag[456,14,457,0,3010,0,0]Al[3064,14,3065,1366,3011,0,0]Ah[456,14,3593,0,4688,0,0]Al[3064,14,3594,3594,4689,0,0]Aj[456,13,457,3598,3175,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]10Al[3064,13,3065,3038,2986,0,0]Aj[456,13,457,2281,2234,0,0]Al[3064,13,3065,2282,2235,0,0]Ab[4719,3,0,0,0,0,0]Ao[1080,13,1081,1081,4799,3018,0]Ag[456,19,457,0,4759,0,0]Ai[3064,19,3065,0,4760,0,0]Af[456,5,457,3158,0,0,0]Ah[3064,5,3065,3158,0,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]54Ai[3064,10,3065,1735,0,0,0]Al[3064,15,3065,3599,1159,0,0]7600Al[3064,15,3065,1105,4195,0,0]4365Al[3064,15,4657,4657,1157,0,0]Ae[1080,9,1081,0,0,0,0]:9Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]<;<;Ah[3064,6,3065,1350,0,0,0]21Al[1180,15,1181,1181,3907,0,0]Ac[456,5,457,0,0,0,0]Ae[3064,5,3065,0,0,0,0]Ag[456,15,457,0,4032,0,0]Ag[456,5,1672,1673,0,0,0]Al[3064,15,3065,2282,4033,0,0]Al[3064,15,3065,1735,4697,0,0]Ae[3064,5,1673,0,0,0,0]An[1180,13,1181,1181,133,4272,0]An[2335,13,2336,2336,124,4272,0]Ao[1080,13,1081,1081,2983,4272,0]An[1080,13,1662,1662,134,4272,0]An[1080,13,1758,1758,135,4272,0]Ag[456,13,457,0,4419,0,0]Al[3064,13,3065,3158,4420,0,0]Ag[456,13,457,0,1426,0,0]Al[3064,13,3065,1789,1427,0,0]Aj[456,14,457,2281,4169,0,0]Aj[456,13,457,3598,4867,0,0]Ag[456,13,457,0,4280,0,0]Al[3064,13,3065,1670,4281,0,0]Ag[456,13,457,0,4160,0,0]Al[3064,13,3065,4429,4161,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]7Al[3064,13,3065,3599,3176,0,0]Aj[456,13,457,3598,3175,0,0]Ah[456,13,1752,0,4622,0,0]Ah[456,13,1752,0,4624,0,0]Al[3064,13,1753,1753,4623,0,0]Al[3064,13,1753,1753,4625,0,0]45;:Ao[3921,13,3922,3922,4955,4753,0]Ag[456,13,457,0,4410,0,0]Al[3064,13,3065,1101,4411,0,0]Ae[1080,6,1081,0,0,0,0]Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]10Al[3064,15,3065,3599,3006,0,0]Ae[3064,5,4906,0,0,0,0]Af[456,5,457,3989,0,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]Al[3064,15,4657,4657,1157,0,0]Aj[456,14,457,2281,4169,0,0]Ai[456,13,457,0,503,2974,0]Ai[456,13,457,0,125,2974,0]An[3064,13,3065,3065,504,2974,0]An[3064,13,3065,3065,126,2974,0]Ao[2335,13,2336,2336,2225,3211,0]Ag[456,13,457,0,4739,0,0]Al[3064,13,3065,3158,4740,0,0]Ah[456,12,1672,0,1832,0,0]Ak[456,13,1752,0,3215,1832,0]Al[3064,12,1673,1673,1833,0,0]Ao[3064,13,1753,1753,3216,1833,0]Aj[456,13,457,3598,3175,0,0]Ag[456,12,457,0,4694,0,0]Al[3064,12,3065,3599,4695,0,0]Ag[456,13,457,0,4419,0,0]Al[3064,13,3065,3158,4420,0,0]Ag[456,14,457,0,3010,0,0]Al[3064,14,3065,1366,3011,0,0]Ah[456,12,3593,0,3177,0,0]Aj[456,13,3593,0,119,3177,0]Ak[456,13,3593,0,1141,3177,0]Ak[456,13,3593,0,1819,3177,0]Al[3064,12,3594,3594,3178,0,0]Am[3064,13,3594,147,120,3178,0]Ao[3064,13,3594,1336,1142,3178,0]Ao[3064,13,3594,2335,1820,3178,0]Aj[456,14,457,2281,4169,0,0]Al[3064,13,3065,1981,1840,0,0]Ah[3064,2,4206,3993,0,0,0]Ae[1180,7,1181,0,0,0,0]==Ai[456,13,457,1079,496,0,0]Ak[1964,13,1965,409,4310,0,0]032Ah[456,12,1672,0,1832,0,0]Ak[456,13,1752,0,3215,1832,0]Ae[3064,2,3065,0,0,0,0]Al[3064,12,1673,1673,1833,0,0]Ao[3064,13,1753,1753,3216,1833,0]Ag[456,10,457,4208,0,0,0]Ai[3064,10,3065,4208,0,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]Ag[456,15,457,0,4032,0,0]Al[3064,15,3065,2282,4033,0,0]Ag[456,19,457,0,4759,0,0]Ai[3064,19,3065,0,4760,0,0]Af[456,5,457,1670,0,0,0]Ah[3064,5,3065,1670,0,0,0]Ah[456,12,1672,0,3003,0,0]Al[3064,12,1673,1673,3004,0,0]Aj[456,13,457,2281,2234,0,0]Al[3064,13,3065,3599,3176,0,0]Al[3064,13,3065,2282,2235,0,0]Al[3064,13,3065,3065,2992,0,0]Ah[456,13,3593,0,4187,0,0]Al[3064,13,3594,2335,4188,0,0]Aj[456,13,457,1973,3016,0,0]0Aj[456,13,457,3598,3175,0,0]6Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]Ag[456,13,457,0,4419,0,0]Al[3064,13,3065,3158,4420,0,0]Al[1080,14,1081,1081,2983,0,0]Ag[456,19,457,0,4759,0,0]Ai[3064,19,3065,0,4760,0,0]Al[3064,15,4657,4657,1157,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]10Al[3064,15,3065,1350,4755,0,0]Al[3064,15,3065,3599,3006,0,0]Al[3064,15,3065,3599,4271,0,0]Ah[3064,5,3065,3599,0,0,0]Al[3064,15,3065,1350,4699,0,0]Ag[456,15,457,0,2993,0,0]Al[3064,15,3065,1340,2994,0,0]Ah[3064,5,3065,1735,0,0,0]Ae[3921,5,3922,0,0,0,0]Al[1080,13,1081,1081,2983,0,0]Aj[456,13,457,3598,3175,0,0]Ah[456,12,1672,0,1832,0,0]Ak[456,13,1752,0,3215,1832,0]Al[3064,12,1673,1673,1833,0,0]Ao[3064,13,1753,1753,3216,1833,0]Ah[3064,7,4840,4839,0,0,0]0Al[3064,13,3065,3599,3176,0,0]6Ai[456,13,457,1079,496,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]Ao[3921,13,3922,3922,4955,4753,0]0Ag[456,13,457,0,4020,0,0]Al[3064,13,3065,1670,4022,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]10Ag[456,13,457,0,4724,0,0]Al[3064,13,3065,3158,4725,0,0]Am[1180,13,1181,1181,133,478,0]Am[2335,13,2336,2336,124,478,0]An[1080,13,1081,1081,2983,478,0]Am[1080,13,1662,1662,134,478,0]Am[1080,13,1758,1758,135,478,0]??>An[1180,13,1181,1181,133,4282,0]An[2335,13,2336,2336,124,4282,0]Ao[2335,13,2336,2336,2225,4282,0]Ao[1080,13,1081,1081,2983,4282,0]An[1080,13,1662,1662,134,4282,0]An[1080,13,1758,1758,135,4282,0]Ag[456,13,457,0,4069,0,0]Al[3064,13,3065,1670,4071,0,0]Ag[456,19,457,0,4759,0,0]Ai[3064,19,3065,0,4760,0,0]Ae[1080,5,4128,0,0,0,0]0Ag[456,13,457,0,4280,0,0]Al[3064,13,3065,1670,4281,0,0]Ag[456,13,457,0,4020,0,0]Al[3064,13,3065,1670,4022,0,0]Aj[456,13,457,2281,2234,0,0]Aj[456,13,457,2313,2238,0,0]Al[3064,13,3065,2282,2239,0,0]Al[3064,13,3065,3599,3176,0,0]Ao[3921,13,3922,3922,4955,4753,0];:Ag[456,5,1672,1673,0,0,0]Ae[3064,5,1673,0,0,0,0]Ah[456,15,1752,0,1154,0,0]Ai[3064,15,1753,0,1155,0,0]?>?>Aj[456,13,457,3598,3175,0,0]6Ag[456,13,457,0,4419,0,0]Al[3064,13,3065,3158,4420,0,0]Ae[3921,7,3922,0,0,0,0]Ae[4211,7,4212,0,0,0,0]Ag[456,14,457,0,3181,0,0]Al[3064,14,3065,1366,3182,0,0]?434343>=>=Al[3064,14,4906,4906,4805,0,0]54Ai[3064,18,3065,3158,0,0,0]") \ No newline at end of file diff --git a/pr/545/docs/search.index/function/37913739753b.js b/pr/545/docs/search.index/function/37913739753b.js new file mode 100644 index 000000000..f0575514d --- /dev/null +++ b/pr/545/docs/search.index/function/37913739753b.js @@ -0,0 +1 @@ +rd_("Bf[\"{{{AHEf{ANK`}}{AHEf{ANK`}}}D@n}\",[]]Bf[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}D@n}\",[]]Bd[\"{{{AHEf{KAd}}{AHEf{KAd}}}D@n}\",[]]Bd[\"{{{AHEf{CNn}}{AHEf{CNn}}}D@n}\",[]]Bf[\"{{{AHEf{BB@n}}{AHEf{BB@n}}}D@n}\",[]]Bf[\"{{{AHEf{BB@`}}{AHEf{BB@`}}}D@n}\",[]]Bf[\"{{{AHEf{AGLh}}{AHEf{AGLh}}}D@n}\",[]]Bf[\"{{{AHEf{AIDn}}{AHEf{AIDn}}}D@n}\",[]]Bf[\"{{{AHEf{BAOn}}{AHEf{BAOn}}}D@n}\",[]]Bf[\"{{{AHEf{AIGb}}{AHEf{AIGb}}}D@n}\",[]]Bf[\"{{{AHEf{B@C`}}{AHEf{B@C`}}}D@n}\",[]]Bd[\"{{{AHEf{KDf}}{AHEf{KDf}}}D@n}\",[]]Bf[\"{{{AHEf{BFFf}}{AHEf{BFFf}}}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{AOLn}}{AHEf{AOLn}}}D@n}\",[]]Bf[\"{{{AHEf{BBKh}}{AHEf{BBKh}}}D@n}\",[]]Bf[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}D@n}\",[]]Bf[\"{{{AHEf{ANKf}}{AHEf{ANKf}}}D@n}\",[]]Bf[\"{{{AHEf{AGJb}}{AHEf{AGJb}}}D@n}\",[]]Bf[\"{{{AHEf{BBKb}}{AHEf{BBKb}}}D@n}\",[]]Bf[\"{{{AHEf{BDDd}}{AHEf{BDDd}}}D@n}\",[]]Bf[\"{{{AHEf{AOMj}}{AHEf{AOMj}}}D@n}\",[]]Bf[\"{{{AHEf{AON`}}{AHEf{AON`}}}D@n}\",[]]Bf[\"{{{AHEf{AONj}}{AHEf{AONj}}}D@n}\",[]]Bf[\"{{{AHEf{BEI`}}{AHEf{BEI`}}}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{BGI`}}{AHEf{BGI`}}}D@n}\",[]]Bd[\"{{{AHEf{IBb}}{AHEf{IBb}}}D@n}\",[]]Bd[\"{{{AHEf{KDh}}{AHEf{KDh}}}D@n}\",[]]Bf[\"{{{AHEf{BFFh}}{AHEf{BFFh}}}D@n}\",[]]Bd[\"{{{AHEf{I@b}}{AHEf{I@b}}}D@n}\",[]]Bf[\"{{{AHEf{BEAl}}{AHEf{BEAl}}}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{BEAh}}{AHEf{BEAh}}}D@n}\",[]]Bf[\"{{{AHEf{BEHh}}{AHEf{BEHh}}}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{BABb}}{AHEf{BABb}}}D@n}\",[]]Bd[\"{{{AHEf{NIh}}{AHEf{NIh}}}D@n}\",[]]Bf[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}D@n}\",[]]Bf[\"{{{AHEf{ANLh}}{AHEf{ANLh}}}D@n}\",[]]Bf[\"{{{AHEf{ANNn}}{AHEf{ANNn}}}D@n}\",[]]Bf[\"{{{AHEf{BB@b}}{AHEf{BB@b}}}D@n}\",[]]Bf[\"{{{AHEf{AOMf}}{AHEf{AOMf}}}D@n}\",[]]Bf[\"{{{AHEf{BBKj}}{AHEf{BBKj}}}D@n}\",[]]Bf[\"{{{AHEf{AGKl}}{AHEf{AGKl}}}D@n}\",[]]Bf[\"{{{AHEf{BAKn}}{AHEf{BAKn}}}D@n}\",[]]Bf[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}D@n}\",[]]Bf[\"{{{AHEf{ANKh}}{AHEf{ANKh}}}D@n}\",[]]Bf[\"{{{AHEf{AGJd}}{AHEf{AGJd}}}D@n}\",[]]Bf[\"{{{AHEf{BAMl}}{AHEf{BAMl}}}D@n}\",[]]Bf[\"{{{AHEf{AIC`}}{AHEf{AIC`}}}D@n}\",[]]Bf[\"{{{AHEf{AIEn}}{AHEf{AIEn}}}D@n}\",[]]Bf[\"{{{AHEf{AONd}}{AHEf{AONd}}}D@n}\",[]]Bf[\"{{{AHEf{BBKf}}{AHEf{BBKf}}}D@n}\",[]]Bf[\"{{{AHEf{BDDh}}{AHEf{BDDh}}}D@n}\",[]]Bf[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}D@n}\",[]]Bf[\"{{{AHEf{AOMl}}{AHEf{AOMl}}}D@n}\",[]]Bf[\"{{{AHEf{AAKf}}{AHEf{AAKf}}}D@n}\",[]]Bf[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}D@n}\",[]]Bf[\"{{{AHEf{AONb}}{AHEf{AONb}}}D@n}\",[]]Bf[\"{{{AHEf{AONl}}{AHEf{AONl}}}D@n}\",[]]Bf[\"{{{AHEf{BB@j}}{AHEf{BB@j}}}D@n}\",[]]Bf[\"{{{AHEf{BEIb}}{AHEf{BEIb}}}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{BABn}}{AHEf{BABn}}}D@n}\",[]]Bf[\"{{{AHEf{BENn}}{AHEf{BENn}}}D@n}\",[]]Bd[\"{{{AHEf{IBf}}{AHEf{IBf}}}D@n}\",[]]Bf[\"{{{AHEf{BGIb}}{AHEf{BGIb}}}D@n}\",[]]Bd[\"{{{AHEf{IBd}}{AHEf{IBd}}}D@n}\",[]]Bf[\"{{{AHEf{AONn}}{AHEf{AONn}}}D@n}\",[]]Ai[\"{{{AHEf{CNn}}}KBd}\",[]]Aj[\"{{{AHEf{BB@n}}}KBd}\",[]]Ak[\"{{{AHEf{AIDj}}}AAMb}\",[]]Ak[\"{{{AHEf{BEO`}}}AAMb}\",[]]Ak[\"{{{AHEf{AIEf}}}AAMb}\",[]]o[\"{KAhKBf}\",[]]A`[\"{AGGdKBf}\",[]]A`[\"{AGIhKBf}\",[]]A`[\"{B@AfKBf}\",[]]A`[\"{B@@hKBf}\",[]]Aa[\"{AALjAAMd}\",[]]Aa[\"{AAObAAMd}\",[]]Aa[\"{AAJjAAMd}\",[]]A`[\"{NGnAAMd}\",[]]A`[\"{ANN`NGf}\",[]]A`[\"{CNfAAKf}\",[]]Ac[\"{{AANlAANl}}\",[]]Ac[\"{{AIBbAIBb}}\",[]]Ac[\"{{BBL`AGLb}}\",[]]Bc[\"{{AANnAANn}c{}}\",[\"Add::Output\"]]Bc[\"{{AIBdAIBd}c{}}\",[\"Add::Output\"]]Bc[\"{{BBLbAGLd}c{}}\",[\"Add::Output\"]]Be[\"{{{AHEf{KDf}}{AHEf{KDf}}}AALh}\",[]]Be[\"{{{AHEf{KBd}}{AHEf{KBd}}}AALh}\",[]]Bg[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}AALh}\",[]]Bg[\"{{{AHEf{AON`}}{AHEf{AON`}}}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{BEAl}}{AHEf{BEAl}}}AALh}\",[]]Be[\"{{{AHEf{KBf}}{AHEf{KBf}}}AALh}\",[]]Bg[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}AALh}\",[]]Bg[\"{{{AHEf{BABb}}{AHEf{BABb}}}AALh}\",[]]Bg[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}AALh}\",[]]Bg[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}AALh}\",[]]Bg[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}AALh}\",[]]Bg[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}AALh}\",[]]Bg[\"{{{AHEf{AONb}}{AHEf{AONb}}}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{ANN`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@d}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGAl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFF`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFFl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAJf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Nn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KAd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AICn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BENb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIE`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAMj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{CNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@n}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEO`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGLh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIDn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAOn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Cb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANNf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@C`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NHb}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{KDf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFFf}}{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{BBL`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOLn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBMd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBNf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEDj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEFh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANLj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAM`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{B@Bd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BFMh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOLb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANKf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AGJb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BDDd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AOMj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AON`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AONj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEI`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AIBh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BDHf}}{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{ANL`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NF`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAAb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BE@b}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BGI`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANKl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEIh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{IBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFEl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{AIAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KDh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BFFh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{I@b}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{KBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Al}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGL`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEHh}}{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{BBLb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BABb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NIh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANLh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@b}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOMf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAKn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGAb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBNh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEDl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEFj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAMb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Bh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFMj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOLf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGJd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAMl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIC`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIEn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AONd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDDh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAIj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDE`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOMl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANJl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGAj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAKf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Nl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AONb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AONl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@j}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BEIb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIBj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGMf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BDHh}}{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{BABn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BENn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGIb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEIn}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{IBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{BFEn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bg[\"{{{AHEf{Ob}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGHj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{I@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{NFb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAAd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BE@d}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@l}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AALn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AANj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AONn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bd[\"{{{AHEf{BFF`}}}{{KB`{AIEl}}}}\",[]]Ak[\"{{{AHEf{B@Al}}}AAJb}\",[]]A`[\"{AANlCLf}\",[]]A`[\"{AANnCLf}\",[]]Aj[\"{{{AHEf{BAAh}}}JNf}\",[]]A`[\"{BGAjCLf}\",[]]o[\"{CNfCLf}\",[]]A`[\"{AALnJNf}\",[]]Ce[\"{{{AHEf{CEdBFMh}}{Nn{AAMn}}}{{AHEf{CEdBFMh}}}}\",[]]Ce[\"{{{AHEf{CEdBFMj}}{Nn{AAN`}}}{{AHEf{CEdBFMj}}}}\",[]]8Af[\"{{AAJbCLf}BB@d}\",[]]Ag[\"{{}{{Nn{BGAl}}}}\",[]]Ae[\"{{JNfCLd}B@Ml}\",[]]Cd[\"{{BAM`{KB`{B@Bd}}AGMb{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Ah[\"{{{Of{IEb}}}AIDd}\",[]]A`[\"{NG`BBMd}\",[]]Ah[\"{{{Nn{NDn}}}BAM`}\",[]]Bc[\"{{{Nn{B@Bf}}{Nn{BE@f}}}B@Bd}\",[]]Ai[\"{{{Nn{AOLd}}}AOLb}\",[]]B`[\"{{{AHEf{{JL`{Nd}}}}}AON`}\",[]]Ae[\"{{CLdJNf}BDHf}\",[]]Ag[\"{{COlOlCLf}AAMb}\",[]]Aj[\"{{{Nn{AGHh}}CLb}O`}\",[]]An[\"{{{Nn{ANL`}}NEdCLb}I@h}\",[]]An[\"{{{Nn{BAAb}}NEdCLb}NF`}\",[]]Ae[\"{{JNfCLd}B@Mn}\",[]]Ah[\"{{{Of{IEb}}}AIDf}\",[]]Bm[\"{{{Nn{BAMb}}{KB`{{Nn{B@Bh}}}}D@n}AAJh}\",[]]A`[\"{JNfBH@h}\",[]]o[\"{{}BGLl}\",[]]A`[\"{NG`BBMf}\",[]]Ah[\"{{{Nn{NE`}}}BAMb}\",[]]Bc[\"{{{Nn{B@Bj}}{Nn{BE@h}}}B@Bh}\",[]]Ai[\"{{{Nn{AOLh}}}AOLf}\",[]]Ek[\"{{AAI`{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{{JNd{BAAh{KB`{AAI`}}}}BEAd}}}{BEEfIDh}}\",[\"\"]]B`[\"{{{AHEf{{JL`{Nd}}}}}AONb}\",[]]Af[\"{{BEIbKDb}BB@j}\",[]]A`[\"{JNfBGMf}\",[]]Ae[\"{{CLdJNf}BDHh}\",[]]Ag[\"{{COnOnCLf}AAMd}\",[]]Am[\"{{AIEl{KB`{KAb}}}AGJ`}\",[]]Aj[\"{{{Nn{AGHj}}CLb}Ob}\",[]]An[\"{{{Nn{ANLb}}NEdCLb}I@j}\",[]]An[\"{{{Nn{BAAd}}NEdCLb}NFb}\",[]]Aj[\"{AIG`{{KBl{BB@l}}}}\",[]]Aa[\"{BDH`BGGd}\",[]]Aa[\"{BDHdBGGf}\",[]]o[\"{COlCOl}\",[]]o[\"{COnCOn}\",[]]Ak[\"{{{AHEf{AIFd}}}AIFb}\",[]]Ai[\"{{{AHEf{NGh}}}NEd}\",[]]0Aj[\"{{{AHEf{B@Cb}}}NEd}\",[]]Ak[\"{{{AHEf{BABj}}}AIFb}\",[]]Ak[\"{{{AHEf{AIFf}}}AIFb}\",[]]Ak[\"{{{AHEf{BABl}}}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@@hAIEl}\",[]]Aa[\"{AALnAIEl}\",[]]Aa[\"{BB@jBEIb}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{AAIjHOn}\",[]]Am[\"{{{AHEf{CEdAALd}}}HOj}\",[]]Am[\"{{{AHEf{CEdAAJn}}}HOj}\",[]]Al[\"{{{AHEf{CEdCNn}}}HOj}\",[]]Am[\"{{{AHEf{CEdBB@n}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIDj}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIEf}}}HOj}\",[]]Al[\"{{{AHEf{CEdJOn}}}HOj}\",[]]A`[\"{cc{}}\",[\"T\"]]0000000000000000000000Aa[\"{BBKhBEAj}\",[]]111111111111111Aa[\"{AGLhBB@`}\",[]]2Aa[\"{AIDnAGLh}\",[]]Aa[\"{BBKhAGLh}\",[]]4Aa[\"{BBKhAIDn}\",[]]Aa[\"{AGLhBAOn}\",[]]6666Aa[\"{B@C`AIGb}\",[]]Aa[\"{AOLnAIGb}\",[]]Aa[\"{BBKhAIGb}\",[]]9Aa[\"{BBKhB@C`}\",[]]:::::::A`[\"{BEI`KDf}\",[]]n[\"{NdKDf}\",[]]o[\"{CLbKDf}\",[]]A`[\"{AAMbKDf}\",[]]o[\"{CLdKDf}\",[]]????Al[\"{cKBd{{CN`{CLd}}}}\",[\"T\"]]A`[\"{cc{}}\",[\"T\"]]00000A`[\"{IAjBBKh}\",[]]A`[\"{I@fBBKh}\",[]]2Aa[\"{ANKdBBKh}\",[]]3333A`[\"{KDfANLj}\",[]]444444Aa[\"{BFFfANKf}\",[]]Aa[\"{BBNjANKf}\",[]]6A`[\"{IAjBBKb}\",[]]777Aa[\"{BEIhAOMj}\",[]]88A`[\"{KDfBEI`}\",[]]99999A`[\"{KDfAAMb}\",[]]::::::::::::Aa[\"{ANOdANKl}\",[]];;;;A`[\"{BDF`IBb}\",[]]A`[\"{BDGhIBb}\",[]]A`[\"{BBLdIBb}\",[]]A`[\"{BAMnIBb}\",[]]A`[\"{BAO`IBb}\",[]]A`[\"{BBMnIBb}\",[]]A`[\"{BGD`IBb}\",[]]A`[\"{BDDjIBb}\",[]]A`[\"{AICfIBb}\",[]]A`[\"{BGJ`IBb}\",[]]A`[\"{BGHnIBb}\",[]]A`[\"{cc{}}\",[\"T\"]]00000000000000000000000o[\"{CLdKDh}\",[]]A`[\"{AAMdKDh}\",[]]o[\"{CLbKDh}\",[]]n[\"{NdKDh}\",[]]4A`[\"{BEIbKDh}\",[]]5555Al[\"{cKBf{{CN`{CLd}}}}\",[\"T\"]]666666666666666666Aa[\"{BB@jBBKj}\",[]]77777A`[\"{AGL`IBl}\",[]]88888A`[\"{KDhANLl}\",[]]99999Aa[\"{BBNjANKh}\",[]]Aa[\"{BFFhANKh}\",[]];;;;;Aa[\"{BB@jBBKf}\",[]]<<<<>>>>>A`[\"{IBfBB@j}\",[]]A`[\"{KDhBEIb}\",[]]A`[\"{cc{}}\",[\"T\"]]00000A`[\"{KDhAAMd}\",[]]111111A`[\"{BABnIBf}\",[]]222Aa[\"{ANOdANKn}\",[]]3333A`[\"{BGJ`IBd}\",[]]A`[\"{BDF`IBd}\",[]]A`[\"{AICfIBd}\",[]]A`[\"{BDGhIBd}\",[]]7A`[\"{BBLdIBd}\",[]]A`[\"{BAO`IBd}\",[]]A`[\"{BBMnIBd}\",[]]A`[\"{BGHnIBd}\",[]]A`[\"{BDDjIBd}\",[]]A`[\"{BAMnIBd}\",[]]A`[\"{BGD`IBd}\",[]]>>>>>>>>>>>>An[\"{{{AHEf{c}}}AIG`CLl}\",[\"S\"]]??????????????Bm[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{ANLj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AON`}}{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{BEAl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{AGLj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BABb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AIGd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{ANLl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BDE`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEAd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AONb}}{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@`}}}{{KB`{c}}}{}}\",[\"Iterator::Item\"]]Dl[\"{{{AHEf{BE@f}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANKl}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Dl[\"{{{AHEf{BE@h}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANKn}}}}\",[]]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{CEdBBO`}}}}{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@Ad}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@An}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdJNn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdBAMj}}}}{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{JOnBABb}}}}\",[]]Bo[\"{{COn{AHEf{CEdc}}}{{KBj{BENnIBf}}}Oh}\",[\"R\"]]Bf[\"{{{AHEf{CEdAGId}}}{{KB`{HOn}}}}\",[]]Ec[\"{{{AHEf{BB@l}}AIG`{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{KBl{JNf}}}}\",[]]Cn[\"{{{AHEf{BE@f}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANKl}}}}\",[]]Cn[\"{{{AHEf{BE@h}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANKn}}}}\",[]]C`[\"{{{AHEf{CEdAGId}}HOnD@n}{{KBj{HOjBEAl}}}}\",[]]Cc[\"{{{AHEf{BB@l}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bn[\"{{{AHEf{CEdBFMh}}CLd}{{AHEf{CEdBFMh}}}}\",[]]Bn[\"{{{AHEf{CEdBFMj}}CLd}{{AHEf{CEdBFMj}}}}\",[]]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@dCLf}\",[]]A`[\"{AANfJNf}\",[]]A`[\"{AANhJNf}\",[]]o[\"{IDdD@n}\",[]]Bm[\"{{{AHEf{CEdAIDj}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdBEO`}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}KDh}{{KBj{HOjAOMf}}}}\",[]]Bn[\"{{{AHEf{AIFl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BANl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHf}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{AIFn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BANn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHh}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bd[\"{{{AHEf{BDEf}}}{{KB`{BA@`}}}}\",[]]Bg[\"{{{Nn{BDOn}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{AGHh}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{ANL`}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BAAb}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BE@`}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{AGHj}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{ANLb}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{BAAd}}NEdCLb}{{Of{AIAl}}}}\",[]]Ai[\"{BEN`{{Nn{BE@`}}}}\",[]]o[\"{I@`HOn}\",[]]A`[\"{AANlCLf}\",[]]o[\"{NIfJNf}\",[]]o[\"{I@bHOn}\",[]]A`[\"{AANnCLf}\",[]]o[\"{NIhJNf}\",[]]Aa[\"{ANJlBBKj}\",[]]Ai[\"{{{AHEf{A@l}}}A@l}\",[]]Ak[\"{{{AHEf{ANN`}}}ANN`}\",[]]Ak[\"{{{AHEf{ANK`}}}ANK`}\",[]]Ak[\"{{{AHEf{AIAf}}}AIAf}\",[]]Ak[\"{{{AHEf{BFFl}}}BFFl}\",[]]Ak[\"{{{AHEf{BEAj}}}BEAj}\",[]]Ak[\"{{{AHEf{AAJf}}}AAJf}\",[]]Ak[\"{{{AHEf{B@Nn}}}B@Nn}\",[]]Ai[\"{{{AHEf{KAd}}}KAd}\",[]]Ai[\"{{{AHEf{CNn}}}CNn}\",[]]Ak[\"{{{AHEf{BB@n}}}BB@n}\",[]]Ak[\"{{{AHEf{BB@`}}}BB@`}\",[]]Ak[\"{{{AHEf{AGLh}}}AGLh}\",[]]Ak[\"{{{AHEf{AIDn}}}AIDn}\",[]]Ak[\"{{{AHEf{BAOn}}}BAOn}\",[]]Ak[\"{{{AHEf{AIGb}}}AIGb}\",[]]Ak[\"{{{AHEf{B@C`}}}B@C`}\",[]]Ai[\"{{{AHEf{KDf}}}KDf}\",[]]Ak[\"{{{AHEf{BFFf}}}BFFf}\",[]]Ai[\"{{{AHEf{KBd}}}KBd}\",[]]Ak[\"{{{AHEf{AANl}}}AANl}\",[]]Ak[\"{{{AHEf{AIBb}}}AIBb}\",[]]Ak[\"{{{AHEf{AGLb}}}AGLb}\",[]]Ak[\"{{{AHEf{BBL`}}}BBL`}\",[]]Ai[\"{{{AHEf{NIf}}}NIf}\",[]]Ak[\"{{{AHEf{AOLn}}}AOLn}\",[]]Ak[\"{{{AHEf{BBKh}}}BBKh}\",[]]Ak[\"{{{AHEf{BBNf}}}BBNf}\",[]]Ak[\"{{{AHEf{BEDj}}}BEDj}\",[]]Ak[\"{{{AHEf{BEFh}}}BEFh}\",[]]Ak[\"{{{AHEf{ANLj}}}ANLj}\",[]]Ak[\"{{{AHEf{BAM`}}}BAM`}\",[]]Ak[\"{{{AHEf{B@Bd}}}B@Bd}\",[]]Ak[\"{{{AHEf{BFMh}}}BFMh}\",[]]Ak[\"{{{AHEf{AOLb}}}AOLb}\",[]]Ak[\"{{{AHEf{ANKf}}}ANKf}\",[]]Ak[\"{{{AHEf{AGJb}}}AGJb}\",[]]Ak[\"{{{AHEf{BBKb}}}BBKb}\",[]]Ak[\"{{{AHEf{BDDd}}}BDDd}\",[]]Ak[\"{{{AHEf{AOMj}}}AOMj}\",[]]Ak[\"{{{AHEf{AON`}}}AON`}\",[]]Ak[\"{{{AHEf{AONj}}}AONj}\",[]]Ak[\"{{{AHEf{BEI`}}}BEI`}\",[]]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{ANL`}}}ANL`}\",[]]Ai[\"{{{AHEf{NF`}}}NF`}\",[]]Ak[\"{{{AHEf{BAAb}}}BAAb}\",[]]Ai[\"{{{AHEf{IBb}}}IBb}\",[]]Ak[\"{{{AHEf{BDGn}}}BDGn}\",[]]Ak[\"{{{AHEf{BFEl}}}BFEl}\",[]]Ak[\"{{{AHEf{BDHb}}}BDHb}\",[]]Ai[\"{{{AHEf{KDh}}}KDh}\",[]]Ak[\"{{{AHEf{BFFh}}}BFFh}\",[]]Ak[\"{{{AHEf{BEAl}}}BEAl}\",[]]Ai[\"{{{AHEf{KBf}}}KBf}\",[]]Ak[\"{{{AHEf{B@Al}}}B@Al}\",[]]Ak[\"{{{AHEf{AIDb}}}AIDb}\",[]]Ak[\"{{{AHEf{AGL`}}}AGL`}\",[]]Ak[\"{{{AHEf{BEAh}}}BEAh}\",[]]Ak[\"{{{AHEf{BEHh}}}BEHh}\",[]]Ak[\"{{{AHEf{AI@n}}}AI@n}\",[]]Ak[\"{{{AHEf{AANn}}}AANn}\",[]]Ak[\"{{{AHEf{AIBd}}}AIBd}\",[]]Ak[\"{{{AHEf{AGLd}}}AGLd}\",[]]Ak[\"{{{AHEf{BBLb}}}BBLb}\",[]]Ak[\"{{{AHEf{AGLj}}}AGLj}\",[]]Ak[\"{{{AHEf{BABb}}}BABb}\",[]]Ai[\"{{{AHEf{NIh}}}NIh}\",[]]Ak[\"{{{AHEf{AIGd}}}AIGd}\",[]]Ak[\"{{{AHEf{ANLh}}}ANLh}\",[]]Ak[\"{{{AHEf{BB@b}}}BB@b}\",[]]Ak[\"{{{AHEf{AOMf}}}AOMf}\",[]]Ak[\"{{{AHEf{BBKj}}}BBKj}\",[]]Ak[\"{{{AHEf{AGKl}}}AGKl}\",[]]Ak[\"{{{AHEf{BAKn}}}BAKn}\",[]]Ak[\"{{{AHEf{BGAb}}}BGAb}\",[]]Ak[\"{{{AHEf{BBNh}}}BBNh}\",[]]Ak[\"{{{AHEf{BEDl}}}BEDl}\",[]]Ak[\"{{{AHEf{BEFj}}}BEFj}\",[]]Ak[\"{{{AHEf{ANLl}}}ANLl}\",[]]Ak[\"{{{AHEf{BAMb}}}BAMb}\",[]]Ak[\"{{{AHEf{B@Bh}}}B@Bh}\",[]]Ak[\"{{{AHEf{BFMj}}}BFMj}\",[]]Ak[\"{{{AHEf{AOLf}}}AOLf}\",[]]Ak[\"{{{AHEf{ANKh}}}ANKh}\",[]]Ak[\"{{{AHEf{AGJd}}}AGJd}\",[]]Ak[\"{{{AHEf{AIC`}}}AIC`}\",[]]Ak[\"{{{AHEf{AIEn}}}AIEn}\",[]]Ak[\"{{{AHEf{AONd}}}AONd}\",[]]Ak[\"{{{AHEf{BBKf}}}BBKf}\",[]]Ak[\"{{{AHEf{BDDh}}}BDDh}\",[]]Ak[\"{{{AHEf{AAIj}}}AAIj}\",[]]Ak[\"{{{AHEf{BDE`}}}BDE`}\",[]]Ak[\"{{{AHEf{AOMl}}}AOMl}\",[]]Ak[\"{{{AHEf{BBMb}}}BBMb}\",[]]Ak[\"{{{AHEf{BGAj}}}BGAj}\",[]]Ak[\"{{{AHEf{AAKf}}}AAKf}\",[]]Ak[\"{{{AHEf{BEAd}}}BEAd}\",[]]Ak[\"{{{AHEf{AONb}}}AONb}\",[]]Ak[\"{{{AHEf{AONl}}}AONl}\",[]]Ak[\"{{{AHEf{BB@j}}}BB@j}\",[]]Ak[\"{{{AHEf{BEIb}}}BEIb}\",[]]Ak[\"{{{AHEf{AIBj}}}AIBj}\",[]]Ak[\"{{{AHEf{BGMf}}}BGMf}\",[]]Ai[\"{{{AHEf{COn}}}COn}\",[]]Ag[\"{{{AHEf{On}}}On}\",[]]Ak[\"{{{AHEf{AAMd}}}AAMd}\",[]]Ak[\"{{{AHEf{AGJ`}}}AGJ`}\",[]]Ak[\"{{{AHEf{BABn}}}BABn}\",[]]Ak[\"{{{AHEf{BENn}}}BENn}\",[]]Ai[\"{{{AHEf{IBf}}}IBf}\",[]]Ai[\"{{{AHEf{IBd}}}IBd}\",[]]Ak[\"{{{AHEf{BDH`}}}BDH`}\",[]]Ak[\"{{{AHEf{BFEn}}}BFEn}\",[]]Ak[\"{{{AHEf{BDHd}}}BDHd}\",[]]Ag[\"{{{AHEf{Ob}}}Ob}\",[]]Ak[\"{{{AHEf{AGHj}}}AGHj}\",[]]Ai[\"{{{AHEf{I@j}}}I@j}\",[]]Ak[\"{{{AHEf{ANLb}}}ANLb}\",[]]Ai[\"{{{AHEf{NFb}}}NFb}\",[]]Ak[\"{{{AHEf{BAAd}}}BAAd}\",[]]Ai[\"{{{AHEf{IBn}}}IBn}\",[]]Ak[\"{{{AHEf{AALn}}}AALn}\",[]]Ak[\"{{{AHEf{AANj}}}AANj}\",[]]Ak[\"{{{AHEf{AONn}}}AONn}\",[]]Ak[\"{{{AHEf{BEN`}}}BEN`}\",[]]Ak[\"{{{AHEf{BBLj}}}BBLj}\",[]]Ak[\"{{{AHEf{BGGd}}}BGGd}\",[]]Ak[\"{{{AHEf{BGGf}}}BGGf}\",[]]Bn[\"{{{AHEf{AIAf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bn[\"{{{AHEf{AAJf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjBAKl}}}}\",[]]Bf[\"{{{AHEf{CEdAIAh}}NEdKDhHOn}HOj}\",[]]Bj[\"{{{AHEf{AON`}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Bj[\"{{{AHEf{AONb}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Aa[\"{BB@jAIC`}\",[]]A`[\"{AAMbCLf}\",[]]A`[\"{AAMdCLf}\",[]]A`[\"{AONjD@n}\",[]]A`[\"{AONlD@n}\",[]]l[\"{NEf}\",[]]l[\"{NEh}\",[]]Ce[\"{{{AHEf{BEEf}}{AHEf{CEdOh}}}{{KBj{AONbBEAd}}}}\",[]]Ce[\"{{{AHEf{BH@h}}{AHEf{CEdOh}}}{{KBj{AONbBEAd}}}}\",[]]Bc[\"{{{AHEf{AIAh}}}{{AAj{KBf}}}}\",[]]Bd[\"{{{AHEf{IDj}}{AHEf{CL`}}}HOj}\",[]]Am[\"{{{AHEf{ANKb}}JNf}HOj}\",[]]Ai[\"{{{AHEf{IDl}}}HOj}\",[]]Bg[\"{{{AAd{{AHEf{CEdAI@`}}}}NEd}HOj}\",[]]Bm[\"{{{AHEf{CEdAIEf}}KDf}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}KDh}{{KBj{HOjAOMf}}}}\",[]]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@Cb}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{ANNf}}{AAd{{Of{K@n}}}}}HOj}\",[]]o[\"{A@lD@n}\",[]]Ak[\"{{{AHEf{AIAf}}}BBL`}\",[]]Ak[\"{{{AHEf{AAJf}}}B@Nn}\",[]]Aj[\"{{{AHEf{CNn}}}AGLb}\",[]]An[\"{{{AHEf{CEdAIAh}}}BBLb}\",[]]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{BENn}}{AHEf{CEdc}}}HOjJOl}\",[\"W\"]]Aj[\"{{{AHEf{AAJf}}}JNn}\",[]]An[\"{AAJn{{KBj{AIAbBBKh}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Fh[\"{{{AHEf{CEdAAJh}}AAK`NEd{AHEf{CEd{AAj{Nd}}}}{KB`{{Nn{B@Bh}}}}}{{KBj{{JNd{BDE`AIAh}}{Of{ANJl}}}}}}\",[]]Am[\"{AHEf{{AHEf{c}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000o[\"{NIfJNf}\",[]]o[\"{NIhJNf}\",[]]A`[\"{A@lANK`}\",[]]Bc[\"{{AIElBAKjA@l}{{KBn{ANKb}}}}\",[]]Aj[\"{AIEl{{KBl{AAJf}}}}\",[]]B`[\"{{}{{KBj{HOj{Of{IAd}}}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BBKh}\",[]]Be[\"{{{AHEf{AAJh}}}{{AHEf{BAMb}}}}\",[]]o[\"{NdBEI`}\",[]]A`[\"{AIBbCLf}\",[]]o[\"{B@BdNn}\",[]]o[\"{NdBEIb}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{B@BhNn}\",[]]A`[\"{BB@jKB`}\",[]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KDfBABn}}}Oh}\",[\"B\"]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KBdBABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AGJbBABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{BEI`BABn}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AAMbBABn}}}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{BBMbBEAd}}}{BEEfIDh}}\",[\"\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{BEIb}}}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{BEI`}}{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{BEIb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGIl}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bj[\"{{{AHEf{CEdAIEf}}}{{KBj{HOjAOLn}}}}\",[]]Bj[\"{{{AHEf{CEdAIEh}}}{{KBj{HOjANLh}}}}\",[]]An[\"{{{AHEf{ANOb}}AAJb}HOj}\",[]]Ea[\"{{{AHEf{CEdAAJh}}NEdAGJ`{KB`{AONl}}AAI`{AHEf{CEd{AAj{Nd}}}}}{{KB`{B@Nj}}}}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]A`[\"{AAJnHOj}\",[]]Ba[\"{{{AHEf{CEdAAJh}}AAK`}HOj}\",[]]Bh[\"{{{AHEf{AIFl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BANl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHf}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{AIFn}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BANn}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHh}}{AHEf{CL`}}HOn}HOj}\",[]]A`[\"{AGHnD@n}\",[]]o[\"{I@`CLf}\",[]]o[\"{I@bCLf}\",[]]Ce[\"{{{AHEf{CEdAIAj}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cc[\"{{{AHEf{CEdO`}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@h}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNF`}}NEdNEdCLfD@n{AHEf{B@Aj}}}HOj}\",[]]Ce[\"{{{AHEf{CEdAIAl}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cc[\"{{{AHEf{CEdOb}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@j}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNFb}}NEdNEdCLfD@n{AHEf{B@Al}}}HOj}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]o[\"{BDI`Nd}\",[]]A`[\"{BBKbHOn}\",[]]A`[\"{BDDdHOn}\",[]]A`[\"{BBKfHOn}\",[]]A`[\"{BDDhHOn}\",[]]A`[\"{BB@jKDb}\",[]]Aa[\"{BALbBBKj}\",[]]Aa[\"{AGGdBEAh}\",[]]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@BdAIEl}{{KBl{AAJf}}}}\",[]]Bb[\"{B@B`{{KBj{HOj{Of{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BEAj}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BB@`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AGLh}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIDn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BAOn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIGb}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{B@C`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBKh}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBKj}}}{{KB`{{AHEf{IAd}}}}}}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Bg[\"{{{AHEf{CNn}}}{{KBj{AID`AI@h}}}}\",[]]Aa[\"{B@AfAIDb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]A`[\"{AALnJNf}\",[]]Aa[\"{AGLbAANl}\",[]]Aa[\"{BBL`AANl}\",[]]Aa[\"{AGLdAANn}\",[]]Aa[\"{BBLbAANn}\",[]]3210Dh[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANKl}}}}\",[]]Dh[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANKn}}}}\",[]]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{BFLf}}}JNf}\",[]]Aj[\"{{{AHEf{BFLh}}}JNf}\",[]]Aj[\"{{{AHEf{BGLl}}}JNf}\",[]]Aj[\"{{{AHEf{BGMf}}}JNf}\",[]]o[\"{A@lJNf}\",[]]n[\"{{}ND`}\",[]]0o[\"{OjAAId}\",[]]111Ba[\"{{AHEf{AHEf{c}}}AALh{}}\",[\"K\"]]0000000000000000000Cg[\"{{{AHEf{AAJf}}AIEl{AHEf{CL`}}}{{KBj{AIAbAOMj}}}}\",[]]Dl[\"{{{AHEf{CEdAAJh}}NEdAOLfAIEl{AHEf{CL`}}}{{KBj{{JNd{BDE`AIAh}}AOMl}}}}\",[]]Bd[\"{{{AHEf{AAJn}}}{{KB`{BDEd}}}}\",[]]Dm[\"{{{AHEf{AGKf}}KBdCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANKl}}}}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Bd[\"{{{AHEf{AAK`}}}{{KB`{BDEf}}}}\",[]]Dm[\"{{{AHEf{AGKh}}KBfCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANKn}}}}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]o[\"{{}ANO`}\",[]]n[\"{{}IDj}\",[]]o[\"{{}ANKb}\",[]]o[\"{{}B@Ml}\",[]]o[\"{{}B@Nn}\",[]]n[\"{{}KDf}\",[]]n[\"{{}KBd}\",[]]o[\"{{}AANl}\",[]]o[\"{{}AIBb}\",[]]o[\"{{}AGLb}\",[]]o[\"{{}BBL`}\",[]]n[\"{{}NIf}\",[]]o[\"{{}AOLn}\",[]]o[\"{{}BBNf}\",[]]o[\"{{}BEDj}\",[]]o[\"{{}BEFh}\",[]]o[\"{{}ANLj}\",[]]o[\"{{}BAM`}\",[]]o[\"{{}BFMh}\",[]]o[\"{{}BDHf}\",[]]o[\"{{}AGHh}\",[]]o[\"{{}ANL`}\",[]]o[\"{{}BAAb}\",[]]o[\"{{}BE@b}\",[]]o[\"{{}B@Mn}\",[]]o[\"{{}BGLl}\",[]]n[\"{{}KDh}\",[]]n[\"{{}KBf}\",[]]o[\"{{}AIDb}\",[]]o[\"{{}AI@n}\",[]]o[\"{{}AANn}\",[]]o[\"{{}AIBd}\",[]]o[\"{{}AGLd}\",[]]o[\"{{}BBLb}\",[]]n[\"{{}NIh}\",[]]o[\"{{}BB@b}\",[]]o[\"{{}AOMf}\",[]]o[\"{{}BBNh}\",[]]o[\"{{}BEDl}\",[]]o[\"{{}BEFj}\",[]]o[\"{{}ANLl}\",[]]o[\"{{}BAMb}\",[]]o[\"{{}BFMj}\",[]]o[\"{{}BGMf}\",[]]o[\"{{}BDHh}\",[]]o[\"{{}AGHj}\",[]]o[\"{{}ANLb}\",[]]o[\"{{}BAAd}\",[]]o[\"{{}BE@d}\",[]]o[\"{{}AALn}\",[]]n[\"{{}IDl}\",[]]o[\"{{}BBLj}\",[]]o[\"{{}B@Nl}\",[]]Ak[\"{{{AHEf{BAAh}}}AONb}\",[]]Ak[\"{{{AHEf{BBMb}}}AONb}\",[]]Aa[\"{BGAjAONb}\",[]]Aa[\"{BEIdAONb}\",[]]A`[\"{CNfAONb}\",[]]A`[\"{ID`AONb}\",[]]A`[\"{IDdAONb}\",[]]Aa[\"{BDI`AONb}\",[]]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{BEO`}}}D@n}\",[]]Ak[\"{{{AHEf{AIAj}}}BE@b}\",[]]Ai[\"{{{AHEf{O`}}}BE@b}\",[]]Aj[\"{{{AHEf{I@h}}}BE@b}\",[]]Aj[\"{{{AHEf{NF`}}}BE@b}\",[]]Ak[\"{{{AHEf{AIAl}}}BE@d}\",[]]Ai[\"{{{AHEf{Ob}}}BE@d}\",[]]Aj[\"{{{AHEf{I@j}}}BE@d}\",[]]Aj[\"{{{AHEf{NFb}}}BE@d}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLb}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLb}{{AHEf{CEdBBNh}}}}\",[]]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[\"{BGAjAONb}\",[]]Aa[\"{BEIdAONb}\",[]]A`[\"{CNfAONb}\",[]]A`[\"{ID`AONb}\",[]]Aa[\"{BDI`AONb}\",[]]Aj[\"{{{AHEf{AIEf}}}NHb}\",[]]Bn[\"{{{AHEf{AIEh}}}{{KBj{{KB`{KDh}}AOMf}}}}\",[]]o[\"{A@lJNf}\",[]]o[\"{IDjJNf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}NHj}\",[]]Aj[\"{{{AHEf{AGKf}}}JNf}\",[]]Aj[\"{{{AHEf{AGKh}}}JNf}\",[]]A`[\"{AHEfKDd}\",[]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bd[\"{{{AHEf{BFFl}}}{{KB`{AIAf}}}}\",[]]Bc[\"{{{AHEf{BB@n}}}{{KB`{CNn}}}}\",[]]Bn[\"{{{AHEf{CEdAOLb}}CLd}{{AHEf{CEdAOLb}}}}\",[]]Bn[\"{{{AHEf{CEdAOLf}}CLd}{{AHEf{CEdAOLf}}}}\",[]]A`[\"{BGAjCLd}\",[]]A`[\"{BEIdCLd}\",[]]o[\"{CNfCLd}\",[]]o[\"{ID`CLd}\",[]]A`[\"{AGHnKB`}\",[]]Aa[\"{AANjAHEf}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{BB@dAAJb}\",[]]A`[\"{JOnBB@b}\",[]]Aa[\"{AGLbAIBb}\",[]]Aa[\"{BBL`AIBb}\",[]]Aa[\"{AGLdAIBd}\",[]]Aa[\"{BBLbAIBd}\",[]]3210Bg[\"{{{AHEf{CEdc}}JNf}AON`{OhIDh}}\",[\"\"]]Bg[\"{{{AHEf{CEdc}}JNf}AONb{OhIDh}}\",[\"\"]]o[\"{{}BBMd}\",[]]o[\"{{}BBMf}\",[]]A`[\"{CLfBGLl}\",[]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANN`c}}}{}}\",[\"FromStr::Err\"]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANK`c}}}{}}\",[\"FromStr::Err\"]]o[\"{CLdKDf}\",[]]o[\"{CLdKDh}\",[]]Al[\"{CLf{{KBj{KDfBFFf}}}}\",[]]Al[\"{CLf{{KBj{KDhBFFh}}}}\",[]]Aa[\"{BFDnANKj}\",[]]Aa[\"{BH@jB@Oj}\",[]]Aa[\"{BFE`ANKj}\",[]]Aa[\"{BH@lB@Oj}\",[]]Af[\"{{}{{KB`{Ab}}}}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBEFh}}AAJb}{{AHEf{CEdBEFh}}}}\",[]]Bo[\"{{{AHEf{CEdBEFj}}AAJb}{{AHEf{CEdBEFj}}}}\",[]]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{BFFl}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBFMh}}AAJb}{{AHEf{CEdBFMh}}}}\",[]]Bo[\"{{{AHEf{CEdBFMj}}AAJb}{{AHEf{CEdBFMj}}}}\",[]]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{ANOb}}JNf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}NFf}\",[]]Bg[\"{{{AHEf{AIEf}}}{{KBj{CCnAOLn}}}}\",[]]Bg[\"{{{AHEf{AIEh}}}{{KBj{CCnAOMf}}}}\",[]]A`[\"{B@ObKB`}\",[]]A`[\"{B@OdKB`}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{ANJlKB`}\",[]]Ck[\"{{{AHEf{CEdBAM`}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAM`}}}}\",[]]Ck[\"{{{AHEf{CEdBAMb}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAMb}}}}\",[]]A`[\"{BE@bKB`}\",[]]A`[\"{BE@dKB`}\",[]]Ac[\"{AHEfc{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]000000000000000000000000000000000000000000000000000Al[\"{HOh{{KBj{KDfBFFf}}}}\",[]]Al[\"{JNf{{KBj{KDfBFFf}}}}\",[]]2Al[\"{CLf{{KBj{KDfBFFf}}}}\",[]]333333333333333Aj[\"{AAJb{{KBj{ANLj}}}}\",[]]44444Ai[\"{CLf{{KBj{AGJb}}}}\",[]]5555555555555555555555555555Aj[\"{AOL`{{KBj{BDGn}}}}\",[]]Bb[\"{{{Nn{AOL`}}}{{KBj{BDGn}}}}\",[]]777Bb[\"{{{Nn{B@Bb}}}{{KBj{BDHb}}}}\",[]]Aj[\"{B@Bb{{KBj{BDHb}}}}\",[]]999999999999999999999Al[\"{JNf{{KBj{KDhBFFh}}}}\",[]]Al[\"{HOh{{KBj{KDhBFFh}}}}\",[]]Al[\"{CLf{{KBj{KDhBFFh}}}}\",[]]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Bm[\"{AOL`{{KBj{BDH`c}}}{}}\",[\"TryFrom::Error\"]]Ce[\"{{{Nn{AOL`}}}{{KBj{BDH`c}}}{}}\",[\"TryFrom::Error\"]]Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]0Ce[\"{{{Nn{B@Bb}}}{{KBj{BDHdc}}}{}}\",[\"TryFrom::Error\"]]Bm[\"{B@Bb{{KBj{BDHdc}}}{}}\",[\"TryFrom::Error\"]]22222222222222222222222Aj[\"{{}{{KBj{c}}}{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cd[\"{{{AAd{{AHEf{CEdc}}}}{AHEf{CEdNDb}}}COf{}}\",[\"F\"]]000000000Cc[\"{{{AHEf{BB@l}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bk[\"{{{AHEf{BFLf}}AON`}{{KBj{HOjAIBh}}}}\",[]]Bk[\"{{{AHEf{BFLh}}AONb}{{KBj{HOjAIBj}}}}\",[]]0Bk[\"{{{AHEf{BGLl}}AONb}{{KBj{HOjAIBj}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AAHn}\",[]]Bi[\"{{{AHEf{CEdB@Cd}}}{{KBj{KDfIB`}}}}\",[]]Bi[\"{{{AHEf{CEdB@Cd}}}{{KBj{COlIB`}}}}\",[]]Bh[\"{{{AHEf{CEdB@Cd}}}{{KBj{OlIB`}}}}\",[]]Bj[\"{{{AHEf{CEdB@Cd}}}{{KBj{AAMbIB`}}}}\",[]]Bf[\"{{{AHEf{CEdB@Cd}}}{{KC`{KDh}}}}\",[]]Bf[\"{{{AHEf{CEdB@Cd}}}{{KC`{COn}}}}\",[]]Be[\"{{{AHEf{CEdB@Cd}}}{{KC`{On}}}}\",[]]Bg[\"{{{AHEf{CEdB@Cd}}}{{KC`{AAMd}}}}\",[]]Aa[\"{ANK`BFFd}\",[]]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{CEdAON`}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]C`[\"{{{AHEf{CEdAONb}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]Ah[\"{Nd{{KB`{AONj}}}}\",[]]Ah[\"{Nd{{KB`{AONl}}}}\",[]]Ah[\"{Nd{{KB`{AONn}}}}\",[]]A`[\"{AAMbCOl}\",[]]A`[\"{AAMdCOn}\",[]]Bi[\"{AIAb{{KBj{{JNd{AIAfBBO`}}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@Bd}}D@n}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}D@n}{{AHEf{CEdB@Bh}}}}\",[]]Bl[\"{{{AHEf{NGh}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{B@Cb}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{ANNf}}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{CEdBFF`}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBDD`}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdAICn}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBENb}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]Ec[\"{{{AHEf{CEdAIDj}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBj{JNfAGLh}}}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEdNGb}}}{{COf{{KBl{HOj}}}}}}\",[]]Ef[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Fg[\"{{{AHEf{CEdBAKh}}{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{CEdBAM`}}{Nn{NDn}}}{{AHEf{CEdBAM`}}}}\",[]]Cd[\"{{{AHEf{CEdBAMb}}{Nn{NE`}}}{{AHEf{CEdBAMb}}}}\",[]]Cj[\"{{{AHEf{B@Bf}}CLdAON`{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHb}}CLdAON`{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{B@Bj}}CLdAONb{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHd}}CLdAONb{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BGGf}}CLdAOMn{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Bb[\"{JNf{{JNd{JNf{KB`{JNf}}}}}}\",[]]000Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]A`[\"{AHEfKDb}\",[]]00000000000000000000000000000000000000000000000000000000000000Ce[\"{{{AHEf{CEdB@Bd}}{Nn{BE@f}}}{{AHEf{CEdB@Bd}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bh}}{Nn{BE@h}}}{{AHEf{CEdB@Bh}}}}\",[]]A`[\"{BGAjICf}\",[]]o[\"{B@BdNn}\",[]]o[\"{B@BhNn}\",[]]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{CEdBBL`}}AGLb}HOj}\",[]]Ba[\"{{{AHEf{CEdAANn}}AANn}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBd}}AIBd}HOj}\",[]]Ba[\"{{{AHEf{CEdBBLb}}AGLd}HOj}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Bi[\"{{{AHEf{CEd}}}{{AHEf{CEdc}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bc[\"{{AHEf{AHEf{CEdc}}}HOj{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cc[\"{{{AHEf{CEdAIAh}}NEdKBfKDh}{{KBj{HOjBAKn}}}}\",[]]A`[\"{AGHnD@n}\",[]]B`[\"{{AHEf{AHEf{c}}}D@n{}}\",[\"K\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Aa[\"{BBKbBEI`}\",[]]A`[\"{BDDdKDf}\",[]]Aa[\"{BBKfBEIb}\",[]]A`[\"{BDDhKDh}\",[]]A`[\"{BDOfKDh}\",[]]A`[\"{BBMhKDh}\",[]]o[\"{NGnKDh}\",[]]Aa[\"{BBKbAIBn}\",[]]Aa[\"{BBKfAIC`}\",[]]o[\"{KDfCLf}\",[]]o[\"{KDhCLf}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Aj[\"{{{AHEf{B@Nl}}}D@n}\",[]]Bd[\"{{{AHEf{BAKh}}}{{KBl{AIEl}}}}\",[]]Bd[\"{{{AHEf{AAJf}}}{{KBl{AIEl}}}}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]Cb[\"{{{AHEf{BBLj}}{AHEf{AIEd}}CLf}{{Nn{ANOb}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AGLb}}}}\",[]]Bj[\"{{{AHEf{CEdAIAh}}KBf}{{KB`{AGLd}}}}\",[]]o[\"{AGIhOf}\",[]]Db[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]00Eg[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBj{JNfAIGb}}}}}}\",[]]Ec[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]0Bm[\"{{{AHEf{IDl}}{AHEf{CNl}}}{{KBl{HOj}}}}\",[]]Cd[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cd[\"{{{AHEf{CEdBEO`}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cn[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{HOjBAOn}}}}\",[]]Bj[\"{{{AHEf{CNn}}AID`}{{KBj{HOjBEHf}}}}\",[]]Bn[\"{{{AHEf{CEdAIDd}}NEd}{{AHEf{CEdAIDd}}}}\",[]]Bn[\"{{{AHEf{CEdAIDf}}NEd}{{AHEf{CEdAIDf}}}}\",[]]A`[\"{BB@dAFd}\",[]]o[\"{IDjCLf}\",[]]o[\"{{}AIEl}\",[]]0o[\"{{}AHEf}\",[]]Bj[\"{{AAJn{Nn{B@Bd}}}{{KBj{AIAbBBKh}}}}\",[]]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{CEdBBNf}}CLb}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLb}{{AHEf{CEdBBNh}}}}\",[]]A`[\"{AGHnCLb}\",[]]Bo[\"{{{AHEf{CEdBBNf}}AAJb}{{AHEf{CEdBBNf}}}}\",[]]Bo[\"{{{AHEf{CEdBBNh}}AAJb}{{AHEf{CEdBBNh}}}}\",[]]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{BBLj}}}HOj}\",[]]A`[\"{BE@bKB`}\",[]]A`[\"{BE@dKB`}\",[]]Bn[\"{{{AHEf{KDf}}{AHEf{KDf}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBd}}{AHEf{KBd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANLj}}{AHEf{ANLj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AON`}}{AHEf{AON`}}}{{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{BEAl}}{AHEf{BEAl}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBf}}{AHEf{KBf}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BABb}}{AHEf{BABb}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BDE`}}{AHEf{BDE`}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEAd}}{AHEf{BEAd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AONb}}{AHEf{AONb}}}{{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@`}}}}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIDl}\",[]]Aj[\"{{{AHEf{AGJh}}}JNf}\",[]]Aj[\"{{{AHEf{AGJj}}}JNf}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIEh}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLf}{{AHEf{CEdBBNh}}}}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{B@ObKB`}\",[]]A`[\"{B@OdKB`}\",[]]Ce[\"{{{AHEf{CEdB@Bd}}{Nn{AIFd}}}{{AHEf{CEdB@Bd}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bh}}{Nn{AIFf}}}{{AHEf{CEdB@Bh}}}}\",[]]Ce[\"{{{AHEf{CEdAOLb}}{Nn{AIFl}}}{{AHEf{CEdAOLb}}}}\",[]]Ce[\"{{{AHEf{CEdAOLf}}{Nn{AIFn}}}{{AHEf{CEdAOLf}}}}\",[]]o[\"{A@lCLf}\",[]]Bn[\"{{{AHEf{CEdBEFh}}CLb}{{AHEf{CEdBEFh}}}}\",[]]Bn[\"{{{AHEf{CEdBEFj}}CLb}{{AHEf{CEdBEFj}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BFFl}\",[]]Aj[\"{{{AHEf{CNn}}}BB@n}\",[]]Ai[\"{{{Nn{B@Bf}}}B@Bd}\",[]]Ai[\"{{{Nn{B@Bj}}}B@Bh}\",[]]Aj[\"{{BBMdc}BBMdAAMl}\",[\"\"]]Aj[\"{{BBMfc}BBMfAAMl}\",[\"\"]]Bm[\"{{{AHEf{CEdAIEf}}HOn}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}KAb}\",[]]o[\"{ND`ND`}\",[]]0000Bd[\"{{{AHEf{BFLf}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BFLh}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGLl}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGMf}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{AIAf}}}{{KB`{BBKh}}}}\",[]]Ck[\"{{{AHEf{AAJf}}AOLbAIEl{AHEf{CL`}}}{{KBj{AIAbAOMj}}}}\",[]]Ak[\"{{{AHEf{B@Al}}}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`[\"{BFDnAAj}\",[]]A`[\"{BH@jAAj}\",[]]A`[\"{BFE`AAj}\",[]]A`[\"{BH@lAAj}\",[]]An[\"{{{AHEf{CEdBFLf}}}AON`}\",[]]An[\"{{{AHEf{CEdBFLh}}}AONb}\",[]]An[\"{{{AHEf{CEdBGLl}}}AONb}\",[]]An[\"{{{AHEf{CEdBGMf}}}AONb}\",[]]Ak[\"{{{AHEf{BB@l}}}B@@b}\",[]]Ba[\"{{{AHEf{CEdAIAh}}BBKn}HOj}\",[]]Bo[\"{{{AHEf{CEdAAJh}}BDE`B@Nl}{{KB`{BBKn}}}}\",[]]B`[\"{{{AHEf{NGj}}AON`COl}CNb}\",[]]Bn[\"{{{AHEf{B@Bf}}CLdAON`}{{KBj{CNbBEIh}}}}\",[]]Ba[\"{{{AHEf{AIFh}}AON`COl}CNb}\",[]]Bn[\"{{{AHEf{BDHb}}CLdAON`}{{KBj{CNbBEIh}}}}\",[]]B`[\"{{{AHEf{NGl}}AONbCOn}CNd}\",[]]Bn[\"{{{AHEf{B@Bj}}CLdAONb}{{KBj{CNdBEIn}}}}\",[]]Ba[\"{{{AHEf{AIFj}}AONbCOn}CNd}\",[]]Bn[\"{{{AHEf{BDHd}}CLdAONb}{{KBj{CNdBEIn}}}}\",[]]Bn[\"{{{AHEf{BGGf}}CLdAOMn}{{KBj{CNdBEIn}}}}\",[]]Aj[\"{{}{{NGd{c}}}{}}\",[\"T\"]]0A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]Bn[\"{{{AHEf{CEdB@Bd}}JNf}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}JNf}{{AHEf{CEdB@Bh}}}}\",[]]Aj[\"{{{AHEf{BAKh}}}D@n}\",[]]0Aj[\"{{{AHEf{BB@l}}}D@n}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AGJ`AI@n}}}}\",[]]Cb[\"{{{AHEf{BBLj}}{AHEf{AIDh}}CLf}{{Nn{ANOb}}}}\",[]]Ak[\"{{{AHEf{AAJn}}}AON`}\",[]]Ak[\"{{{AHEf{AAK`}}}AONb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{NEd}}}}\",[]]Ce[\"{{{AHEf{CEdBBNf}}{Nn{ANMh}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{Nn{ANMj}}}{{AHEf{CEdBBNh}}}}\",[]]43A`[\"{A@lANN`}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Ai[\"{{{AHEf{NHj}}}JNf}\",[]]Bo[\"{{{AHEf{CEdBGLl}}AAJb}{{AHEf{CEdBGLl}}}}\",[]]Bo[\"{{{AHEf{CEdBGMf}}AAJb}{{AHEf{CEdBGMf}}}}\",[]]Bj[\"{{{AHEf{AIEf}}CCn}{{KBj{HOjAOLn}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}CCn}{{KBj{HOjAOMf}}}}\",[]]==E`[\"{{{AHEf{BGAl}}{AHEf{{JL`{Nd}}}}{AHEf{BAKj}}{AHEf{BFLj}}}{{KBj{BGDbIAl}}}}\",[]]0Bf[\"{{{Nn{BABh}}}{{KBj{AOLbBFFj}}}}\",[]]Bf[\"{{{Nn{BABh}}}{{KBj{AOLfBFFj}}}}\",[]]Bn[\"{{{AHEf{CEdBEDj}}KDf}{{AHEf{CEdBEDj}}}}\",[]]Bn[\"{{{AHEf{CEdBEDl}}KDh}{{AHEf{CEdBEDl}}}}\",[]]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@Bd}}BFMh}{{AHEf{CEdB@Bd}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bh}}BFMj}{{AHEf{CEdB@Bh}}}}\",[]]Aj[\"{{{AHEf{BAM`}}}CLf}\",[]]Aj[\"{{{AHEf{BAMb}}}CLf}\",[]]Cc[\"{{{AHEf{CEdAOLb}}{Nn{A`}}}{{AHEf{CEdAOLb}}}}\",[]]Cc[\"{{{AHEf{CEdAOLf}}{Nn{A`}}}{{AHEf{CEdAOLf}}}}\",[]]Cj[\"{{BAM`{KB`{B@Bd}}{Of{BAKh}}{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Ca[\"{{{AHEf{CEdAIAh}}NEdAICd}{{KBj{HOjBGAb}}}}\",[]]Bd[\"{{{AHEf{BGAl}}}{{AAj{BBMl}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}JNf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}JNf}{{AHEf{CEdBBNh}}}}\",[]]Bl[\"{{}{{KBj{{JNd{BAKjBEGd}}{Of{IAd}}}}}}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{{AHEf{AAJf}}AOLb}HOj}\",[]]Dc[\"{{{AHEf{CEdAIAh}}NEdKBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]o[\"{{}AHEf}\",[]]Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]Bn[\"{{{AHEf{CEdB@Bd}}CLf}{{AHEf{CEdB@Bd}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}CLf}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}KDf}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}KDh}{{AHEf{CEdBBNh}}}}\",[]]:Bb[\"{{{AHEf{CEdAIAh}}OnKDh}HOj}\",[]]Ak[\"{{}{{KBj{AOLbIBb}}}}\",[]]Ak[\"{{}{{KBj{AOLfIBd}}}}\",[]]Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]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{CEdBBNf}}{KB`{JNf}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{KB`{JNf}}}{{AHEf{CEdBBNh}}}}\",[]]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{CEdBBNf}}{Nn{BDOn}}}{{AHEf{CEdBBNf}}}}\",[]]Ce[\"{{{AHEf{CEdBBNh}}{Nn{BE@`}}}{{AHEf{CEdBBNh}}}}\",[]]Cf[\"{{{AHEf{CEdBBNf}}{KB`{AAJb}}}{{AHEf{CEdBBNf}}}}\",[]]Cf[\"{{{AHEf{CEdBBNh}}{KB`{AAJb}}}{{AHEf{CEdBBNh}}}}\",[]]Aa[\"{B@ObAICb}\",[]]Aa[\"{B@OdAICb}\",[]]9Bn[\"{{{AHEf{CEdBBNf}}D@n}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}D@n}{{AHEf{CEdBBNh}}}}\",[]]Am[\"{{{AHEf{AIAf}}KDf}HOj}\",[]]o[\"{ND`ND`}\",[]]Bn[\"{{{AHEf{CEdBBNf}}CLd}{{AHEf{CEdBBNf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNh}}CLd}{{AHEf{CEdBBNh}}}}\",[]]3109854Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Bn[\"{{{AHEf{AIAh}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]10A`[\"{BENnKB`}\",[]]Bm[\"{{{AHEf{CEdBBNf}}Nd}{{AHEf{CEdBBNf}}}}\",[]]Bm[\"{{{AHEf{CEdBBNh}}Nd}{{AHEf{CEdBBNh}}}}\",[]]o[\"{{}AICd}\",[]]") \ No newline at end of file diff --git a/pr/545/docs/search.index/function/46beaf101177.js b/pr/545/docs/search.index/function/46beaf101177.js deleted file mode 100644 index 64ab57b33..000000000 --- a/pr/545/docs/search.index/function/46beaf101177.js +++ /dev/null @@ -1 +0,0 @@ -rd_("Bf[\"{{{AHA`{ANEf}}{AHA`{ANEf}}}D@`}\",[]]Bf[\"{{{AHA`{BDKh}}{AHA`{BDKh}}}D@`}\",[]]Bd[\"{{{AHA`{CN`}}{AHA`{CN`}}}D@`}\",[]]Bf[\"{{{AHA`{BAJn}}{AHA`{BAJn}}}D@`}\",[]]Bf[\"{{{AHA`{BAJ`}}{AHA`{BAJ`}}}D@`}\",[]]Bf[\"{{{AHA`{AGHj}}{AHA`{AGHj}}}D@`}\",[]]Bf[\"{{{AHA`{AI@d}}{AHA`{AI@d}}}D@`}\",[]]Bf[\"{{{AHA`{BAIn}}{AHA`{BAIn}}}D@`}\",[]]Bf[\"{{{AHA`{AIBh}}{AHA`{AIBh}}}D@`}\",[]]Bf[\"{{{AHA`{AOMf}}{AHA`{AOMf}}}D@`}\",[]]Bd[\"{{{AHA`{KBd}}{AHA`{KBd}}}D@`}\",[]]Bf[\"{{{AHA`{BF@`}}{AHA`{BF@`}}}D@`}\",[]]Bd[\"{{{AHA`{HNb}}{AHA`{HNb}}}D@`}\",[]]Bd[\"{{{AHA`{K@b}}{AHA`{K@b}}}D@`}\",[]]Bf[\"{{{AHA`{AAKn}}{AHA`{AAKn}}}D@`}\",[]]Bf[\"{{{AHA`{AHMj}}{AHA`{AHMj}}}D@`}\",[]]Bf[\"{{{AHA`{AGHd}}{AHA`{AGHd}}}D@`}\",[]]Bd[\"{{{AHA`{NFl}}{AHA`{NFl}}}D@`}\",[]]Bf[\"{{{AHA`{AOGd}}{AHA`{AOGd}}}D@`}\",[]]Bf[\"{{{AHA`{BBEh}}{AHA`{BBEh}}}D@`}\",[]]Bf[\"{{{AHA`{ANG`}}{AHA`{ANG`}}}D@`}\",[]]Bf[\"{{{AHA`{ANEl}}{AHA`{ANEl}}}D@`}\",[]]Bf[\"{{{AHA`{AGFb}}{AHA`{AGFb}}}D@`}\",[]]Bf[\"{{{AHA`{BBEb}}{AHA`{BBEb}}}D@`}\",[]]Bf[\"{{{AHA`{BCNb}}{AHA`{BCNb}}}D@`}\",[]]Bf[\"{{{AHA`{AOH`}}{AHA`{AOH`}}}D@`}\",[]]Bf[\"{{{AHA`{AOHf}}{AHA`{AOHf}}}D@`}\",[]]Bf[\"{{{AHA`{AOI`}}{AHA`{AOI`}}}D@`}\",[]]Bf[\"{{{AHA`{BEBn}}{AHA`{BEBn}}}D@`}\",[]]Bd[\"{{{AHA`{CNn}}{AHA`{CNn}}}D@`}\",[]]Bb[\"{{{AHA`{Oj}}{AHA`{Oj}}}D@`}\",[]]Bf[\"{{{AHA`{AAJd}}{AHA`{AAJd}}}D@`}\",[]]Bf[\"{{{AHA`{BGBj}}{AHA`{BGBj}}}D@`}\",[]]Bd[\"{{{AHA`{I@d}}{AHA`{I@d}}}D@`}\",[]]Bd[\"{{{AHA`{KBf}}{AHA`{KBf}}}D@`}\",[]]Bf[\"{{{AHA`{BF@b}}{AHA`{BF@b}}}D@`}\",[]]Bd[\"{{{AHA`{HNd}}{AHA`{HNd}}}D@`}\",[]]Bf[\"{{{AHA`{BDKj}}{AHA`{BDKj}}}D@`}\",[]]Bd[\"{{{AHA`{K@d}}{AHA`{K@d}}}D@`}\",[]]Bf[\"{{{AHA`{AHOh}}{AHA`{AHOh}}}D@`}\",[]]Bf[\"{{{AHA`{AGHb}}{AHA`{AGHb}}}D@`}\",[]]Bf[\"{{{AHA`{BDKf}}{AHA`{BDKf}}}D@`}\",[]]Bf[\"{{{AHA`{BEBf}}{AHA`{BEBf}}}D@`}\",[]]Bf[\"{{{AHA`{AHLf}}{AHA`{AHLf}}}D@`}\",[]]Bf[\"{{{AHA`{AAL`}}{AHA`{AAL`}}}D@`}\",[]]Bf[\"{{{AHA`{AHMl}}{AHA`{AHMl}}}D@`}\",[]]Bf[\"{{{AHA`{AGHf}}{AHA`{AGHf}}}D@`}\",[]]Bf[\"{{{AHA`{AGHl}}{AHA`{AGHl}}}D@`}\",[]]Bf[\"{{{AHA`{B@Lf}}{AHA`{B@Lf}}}D@`}\",[]]Bd[\"{{{AHA`{NFn}}{AHA`{NFn}}}D@`}\",[]]Bf[\"{{{AHA`{AIBj}}{AHA`{AIBj}}}D@`}\",[]]Bf[\"{{{AHA`{ANFn}}{AHA`{ANFn}}}D@`}\",[]]Bf[\"{{{AHA`{ANId}}{AHA`{ANId}}}D@`}\",[]]Bf[\"{{{AHA`{BAJb}}{AHA`{BAJb}}}D@`}\",[]]Bf[\"{{{AHA`{AOGl}}{AHA`{AOGl}}}D@`}\",[]]Bf[\"{{{AHA`{BBEj}}{AHA`{BBEj}}}D@`}\",[]]Bf[\"{{{AHA`{AGGl}}{AHA`{AGGl}}}D@`}\",[]]Bf[\"{{{AHA`{BAEn}}{AHA`{BAEn}}}D@`}\",[]]Bf[\"{{{AHA`{ANGb}}{AHA`{ANGb}}}D@`}\",[]]Bf[\"{{{AHA`{ANEn}}{AHA`{ANEn}}}D@`}\",[]]Bf[\"{{{AHA`{AGFd}}{AHA`{AGFd}}}D@`}\",[]]Bf[\"{{{AHA`{BAGl}}{AHA`{BAGl}}}D@`}\",[]]Bf[\"{{{AHA`{AHNh}}{AHA`{AHNh}}}D@`}\",[]]Bf[\"{{{AHA`{AIAd}}{AHA`{AIAd}}}D@`}\",[]]Bf[\"{{{AHA`{AOHj}}{AHA`{AOHj}}}D@`}\",[]]Bf[\"{{{AHA`{BBEf}}{AHA`{BBEf}}}D@`}\",[]]Bf[\"{{{AHA`{BCNf}}{AHA`{BCNf}}}D@`}\",[]]Bf[\"{{{AHA`{BCNn}}{AHA`{BCNn}}}D@`}\",[]]Bf[\"{{{AHA`{AOHb}}{AHA`{AOHb}}}D@`}\",[]]Bf[\"{{{AHA`{AAHd}}{AHA`{AAHd}}}D@`}\",[]]Bf[\"{{{AHA`{BDKb}}{AHA`{BDKb}}}D@`}\",[]]Bf[\"{{{AHA`{AOHh}}{AHA`{AOHh}}}D@`}\",[]]Bf[\"{{{AHA`{AOIb}}{AHA`{AOIb}}}D@`}\",[]]Bf[\"{{{AHA`{BAJj}}{AHA`{BAJj}}}D@`}\",[]]Bf[\"{{{AHA`{BEC`}}{AHA`{BEC`}}}D@`}\",[]]Bd[\"{{{AHA`{CO`}}{AHA`{CO`}}}D@`}\",[]]Bb[\"{{{AHA`{Ol}}{AHA`{Ol}}}D@`}\",[]]Bf[\"{{{AHA`{AAJf}}{AHA`{AAJf}}}D@`}\",[]]Bf[\"{{{AHA`{AGF`}}{AHA`{AGF`}}}D@`}\",[]]Bf[\"{{{AHA`{B@Mb}}{AHA`{B@Mb}}}D@`}\",[]]Bf[\"{{{AHA`{BEHj}}{AHA`{BEHj}}}D@`}\",[]]Bd[\"{{{AHA`{I@h}}{AHA`{I@h}}}D@`}\",[]]Bf[\"{{{AHA`{BGBl}}{AHA`{BGBl}}}D@`}\",[]]Bd[\"{{{AHA`{I@f}}{AHA`{I@f}}}D@`}\",[]]Bf[\"{{{AHA`{AOId}}{AHA`{AOId}}}D@`}\",[]]Ai[\"{{{AHA`{CN`}}}K@b}\",[]]Aj[\"{{{AHA`{BAJn}}}K@b}\",[]]Ak[\"{{{AHA`{AI@`}}}AAJd}\",[]]Ak[\"{{{AHA`{BEHl}}}AAJd}\",[]]Ak[\"{{{AHA`{AI@l}}}AAJd}\",[]]o[\"{JOfK@d}\",[]]A`[\"{AGCdK@d}\",[]]A`[\"{AGEhK@d}\",[]]A`[\"{AOKlK@d}\",[]]A`[\"{AOJnK@d}\",[]]Aa[\"{AAIhAAJf}\",[]]Aa[\"{AALdAAJf}\",[]]Aa[\"{AAGhAAJf}\",[]]A`[\"{NEdAAJf}\",[]]A`[\"{ANHfNDl}\",[]]A`[\"{CMhAAHd}\",[]]Ac[\"{{AAKnAAKn}}\",[]]Ac[\"{{AHMjAHMj}}\",[]]Ac[\"{{BBF`AGHd}}\",[]]Bc[\"{{AAL`AAL`}c{}}\",[\"Add::Output\"]]Bc[\"{{AHMlAHMl}c{}}\",[\"Add::Output\"]]Bc[\"{{BBFbAGHf}c{}}\",[\"Add::Output\"]]Be[\"{{{AHA`{KBd}}{AHA`{KBd}}}AAIf}\",[]]Be[\"{{{AHA`{K@b}}{AHA`{K@b}}}AAIf}\",[]]Bg[\"{{{AHA`{ANG`}}{AHA`{ANG`}}}AAIf}\",[]]Bg[\"{{{AHA`{AOHf}}{AHA`{AOHf}}}AAIf}\",[]]Be[\"{{{AHA`{CNn}}{AHA`{CNn}}}AAIf}\",[]]Bc[\"{{{AHA`{Oj}}{AHA`{Oj}}}AAIf}\",[]]Bg[\"{{{AHA`{AAJd}}{AHA`{AAJd}}}AAIf}\",[]]Be[\"{{{AHA`{KBf}}{AHA`{KBf}}}AAIf}\",[]]Bg[\"{{{AHA`{BDKj}}{AHA`{BDKj}}}AAIf}\",[]]Be[\"{{{AHA`{K@d}}{AHA`{K@d}}}AAIf}\",[]]Bg[\"{{{AHA`{AGHl}}{AHA`{AGHl}}}AAIf}\",[]]Bg[\"{{{AHA`{B@Lf}}{AHA`{B@Lf}}}AAIf}\",[]]Bg[\"{{{AHA`{AIBj}}{AHA`{AIBj}}}AAIf}\",[]]Bg[\"{{{AHA`{ANGb}}{AHA`{ANGb}}}AAIf}\",[]]Bg[\"{{{AHA`{BCNn}}{AHA`{BCNn}}}AAIf}\",[]]Bg[\"{{{AHA`{BDKb}}{AHA`{BDKb}}}AAIf}\",[]]Bg[\"{{{AHA`{AOHh}}{AHA`{AOHh}}}AAIf}\",[]]Be[\"{{{AHA`{CO`}}{AHA`{CO`}}}AAIf}\",[]]Bc[\"{{{AHA`{Ol}}{AHA`{Ol}}}AAIf}\",[]]Bg[\"{{{AHA`{AAJf}}{AHA`{AAJf}}}AAIf}\",[]]o[\"{AAJdOj}\",[]]o[\"{AAJfOl}\",[]]n[\"{JOhOl}\",[]]o[\"{AGDbOl}\",[]]A`[\"{AAKhJOn}\",[]]A`[\"{AAKjJOn}\",[]]A`[\"{AAJ`JOn}\",[]]A`[\"{AAKlJOn}\",[]]Bh[\"{{{AHA`{A@j}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{ANHf}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{ANEf}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BAJd}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BFKf}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AHLj}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AHLn}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BF@f}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BDKh}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AAGd}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{B@Ib}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AAGl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AI@f}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BAGj}}{AHA`{CDfAGEn}}}K@f}\",[]]Bh[\"{{{AHA`{CN`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BAJn}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AI@`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BEHl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BAJ`}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AGHj}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AI@d}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BAIn}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AOMh}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{ANHl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AI@l}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AIBh}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AOMf}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bh[\"{{{AHA`{NEh}}{AHA`{CDfAGEn}}}K@f}\",[]]Cd[\"{{{AHA`{KBd}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{BF@`}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Cd[\"{{{AHA`{HNb}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Cd[\"{{{AHA`{K@b}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{AAKn}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{AHMj}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{AGHd}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BBF`}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Cd[\"{{{AHA`{NFl}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{AOGd}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{BBEh}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{BBGd}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BBHf}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BDNh}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BE@f}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{ANG`}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BAG`}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{AOLj}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BFGb}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{AOFh}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{ANEl}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{AGFb}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{BBEb}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{BCNb}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{AOH`}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{AOHf}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{AOI`}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BEBn}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{AHN`}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BDBd}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Cd[\"{{{AHA`{CNn}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Cc[\"{{{AHA`{Oj}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{AAJd}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{AAKh}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Cc[\"{{{AHA`{Nn}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{AGDh}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Cd[\"{{{AHA`{HNj}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{ANFf}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Cd[\"{{{AHA`{NCf}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{B@Kf}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BDJ`}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BGBj}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{ANFb}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Ce[\"{{{AHA`{BECf}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]Cd[\"{{{AHA`{I@d}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Ce[\"{{{AHA`{BEOh}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Bi[\"{{{AHA`{AHM`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AAGf}}{AHA`{CDfAGEn}}}K@f}\",[]]Bh[\"{{{AHA`{KBf}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BF@b}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bh[\"{{{AHA`{HNd}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BDKj}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bh[\"{{{AHA`{K@d}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AOLb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AHOh}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AGHb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BDKf}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BEBf}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AHLf}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AAL`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AHMl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AGHf}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BBFb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AGHl}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{B@Lf}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bh[\"{{{AHA`{NFn}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AIBj}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{ANFn}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{ANId}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BAJb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AOGl}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BBEj}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AGGl}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BAEn}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BFJl}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bh[\"{{{AHA`{I@n}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BBGf}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BBHh}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BDNj}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BE@h}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{ANGb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BAGb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AOLn}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BFGd}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AOFl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{ANEn}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AGFd}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BAGl}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AHNh}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AIAd}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AOHj}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BBEf}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BCNf}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AAFh}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BCNn}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AAGn}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AOHb}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{ANEb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AI@h}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{B@Kl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BBGb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BFKd}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AAHd}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BDKb}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BBEn}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{B@I`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AOHh}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AOIb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BAJj}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BEC`}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AHNb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BGG`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BDBf}}{AHA`{CDfAGEn}}}K@f}\",[]]Bh[\"{{{AHA`{CO`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bg[\"{{{AHA`{Ol}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AAJf}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{AAKj}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AGF`}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{B@Mb}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BEHj}}{AHA`{CDfAGEn}}}K@f}\",[]]Bh[\"{{{AHA`{I@h}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bi[\"{{{AHA`{BGBl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{ANFd}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BECl}}{AHA`{CDfAGEn}}}K@f}\",[]]Cd[\"{{{AHA`{I@f}}{AHA`{CDfAGEn}}}{{K@h{HMlHOd}}}}\",[]]0Bi[\"{{{AHA`{BEOj}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bg[\"{{{AHA`{O`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AGDj}}{AHA`{CDfAGEn}}}K@f}\",[]]Bh[\"{{{AHA`{HNl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{ANFh}}{AHA`{CDfAGEn}}}K@f}\",[]]Bh[\"{{{AHA`{NCh}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{B@Kh}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BDJb}}{AHA`{CDfAGEn}}}K@f}\",[]]Bh[\"{{{AHA`{I@j}}{AHA`{CDfAGEn}}}K@f}\",[]]0Bh[\"{{{AHA`{IA`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{BAJl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AAJ`}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AAKl}}{AHA`{CDfAGEn}}}K@f}\",[]]Bi[\"{{{AHA`{AOId}}{AHA`{CDfAGEn}}}K@f}\",[]]Ak[\"{{{AHA`{AOLb}}}AAG`}\",[]]A`[\"{AAKnCKh}\",[]]A`[\"{AAL`CKh}\",[]]Aj[\"{{{AHA`{B@Kl}}}JLf}\",[]]A`[\"{BFKdCKh}\",[]]o[\"{CMhCKh}\",[]]A`[\"{AAJ`JLf}\",[]]Ce[\"{{{AHA`{CDfBFGb}}{Nl{AAK`}}}{{AHA`{CDfBFGb}}}}\",[]]Ce[\"{{{AHA`{CDfBFGd}}{Nl{AAKb}}}{{AHA`{CDfBFGd}}}}\",[]]8Af[\"{{AAG`CKh}BAJd}\",[]]Ag[\"{{}{{Nl{BFKf}}}}\",[]]Ae[\"{{JLfCKf}B@H`}\",[]]Cd[\"{{BAG`{JOn{AOLj}}AGIb{Nl{NDn}}}{{K@j{AAGd}}}}\",[]]Ah[\"{{{Od{ICd}}}AHOj}\",[]]A`[\"{NDfBBGd}\",[]]Ah[\"{{{Nl{NBd}}}BAG`}\",[]]Bc[\"{{{Nl{AOLl}}{Nl{BDJd}}}AOLj}\",[]]Ai[\"{{{Nl{AOFj}}}AOFh}\",[]]B`[\"{{{AHA`{{JJ`{Nb}}}}}AOHf}\",[]]Ae[\"{{CKfJLf}BDBd}\",[]]Ag[\"{{CNnOjCKh}AAJd}\",[]]Aj[\"{{{Nl{AGDh}}CKd}Nn}\",[]]An[\"{{{Nl{ANFf}}NBjCKd}HNj}\",[]]An[\"{{{Nl{B@Kf}}NBjCKd}NCf}\",[]]Ae[\"{{JLfCKf}B@Hb}\",[]]Ah[\"{{{Od{ICd}}}AHOl}\",[]]Bm[\"{{{Nl{BAGb}}{JOn{{Nl{AOLn}}}}D@`}AAGf}\",[]]A`[\"{JLfBGJb}\",[]]o[\"{{}BGFf}\",[]]A`[\"{NDfBBGf}\",[]]Ah[\"{{{Nl{NBf}}}BAGb}\",[]]Bc[\"{{{Nl{AOM`}}{Nl{BDJf}}}AOLn}\",[]]Ai[\"{{{Nl{AOFn}}}AOFl}\",[]]Ek[\"{{AAEn{AHA`{c}}{AHA`{{JJ`{CKf}}}}D@`}{{K@h{{JLd{B@Kl{JOn{AAEn}}}}BDKb}}}{BDOdIBj}}\",[\"\"]]B`[\"{{{AHA`{{JJ`{Nb}}}}}AOHh}\",[]]Af[\"{{BEC`KB`}BAJj}\",[]]A`[\"{JLfBGG`}\",[]]Ae[\"{{CKfJLf}BDBf}\",[]]Ag[\"{{CO`OlCKh}AAJf}\",[]]Am[\"{{AIAb{JOn{JOb}}}AGF`}\",[]]Aj[\"{{{Nl{AGDj}}CKd}O`}\",[]]An[\"{{{Nl{ANFh}}NBjCKd}HNl}\",[]]An[\"{{{Nl{B@Kh}}NBjCKd}NCh}\",[]]Aj[\"{AIBf{{K@j{BAJl}}}}\",[]]Aa[\"{BDAnBG@n}\",[]]Aa[\"{BDBbBGA`}\",[]]o[\"{CNnCNn}\",[]]o[\"{CO`CO`}\",[]]Ak[\"{{{AHA`{AIAj}}}AIAh}\",[]]Ai[\"{{{AHA`{NDn}}}NBj}\",[]]0Aj[\"{{{AHA`{AOMh}}}NBj}\",[]]Ak[\"{{{AHA`{B@Ln}}}AIAh}\",[]]Ak[\"{{{AHA`{AIAl}}}AIAh}\",[]]Ak[\"{{{AHA`{B@M`}}}AIAh}\",[]]Bg[\"{{{AHA`{AHLn}}K@b}{{JOn{AAG`}}}}\",[]]Aa[\"{AGHdAAG`}\",[]]Bg[\"{{{AHA`{AHM`}}K@d}{{JOn{AAG`}}}}\",[]]Aa[\"{AGHfAAG`}\",[]]Ah[\"{A@l{{K@l{HMl}}}}\",[]]Ah[\"{A@n{{K@l{HMl}}}}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]Aa[\"{AOJnAIAb}\",[]]Aa[\"{AAJ`AIAb}\",[]]Aa[\"{BAJjBEC`}\",[]]A`[\"{AGHdCKh}\",[]]A`[\"{AGHfCKh}\",[]]A`[\"{AAFhHN`}\",[]]Am[\"{{{AHA`{CDfAAIb}}}HMl}\",[]]Am[\"{{{AHA`{CDfAAGl}}}HMl}\",[]]Al[\"{{{AHA`{CDfCN`}}}HMl}\",[]]Am[\"{{{AHA`{CDfBAJn}}}HMl}\",[]]Am[\"{{{AHA`{CDfAI@`}}}HMl}\",[]]Am[\"{{{AHA`{CDfAI@l}}}HMl}\",[]]Al[\"{{{AHA`{CDfJMn}}}HMl}\",[]]A`[\"{cc{}}\",[\"T\"]]000000000000000000000Aa[\"{BBEhBDKh}\",[]]111111111111Aa[\"{AGHjBAJ`}\",[]]Aa[\"{AI@dAGHj}\",[]]Aa[\"{BBEhAGHj}\",[]]44Aa[\"{BBEhAI@d}\",[]]5Aa[\"{AGHjBAIn}\",[]]666Aa[\"{BBEhAIBh}\",[]]7Aa[\"{AOMfAIBh}\",[]]Aa[\"{AOGdAIBh}\",[]]Aa[\"{BBEhAOMf}\",[]]:::::::o[\"{CKfKBd}\",[]]A`[\"{AAJdKBd}\",[]]A`[\"{BEBnKBd}\",[]]n[\"{NbKBd}\",[]]o[\"{CKdKBd}\",[]]???Al[\"{cK@b{{CMb{CKf}}}}\",[\"T\"]]A`[\"{cc{}}\",[\"T\"]]000000A`[\"{HNhBBEh}\",[]]Aa[\"{ANEjBBEh}\",[]]A`[\"{HOlBBEh}\",[]]33333A`[\"{KBdANG`}\",[]]444444Aa[\"{BBHjANEl}\",[]]Aa[\"{BF@`ANEl}\",[]]6A`[\"{HOlBBEb}\",[]]77Aa[\"{BECfAOH`}\",[]]888A`[\"{KBdBEBn}\",[]]99999A`[\"{KBdAAJd}\",[]]:::::::::::::Aa[\"{ANIjANFb}\",[]];;;;A`[\"{BFMjI@d}\",[]]A`[\"{BGCjI@d}\",[]]A`[\"{BBFdI@d}\",[]]A`[\"{AHNnI@d}\",[]]A`[\"{BCOnI@d}\",[]]A`[\"{BAGnI@d}\",[]]A`[\"{BBGnI@d}\",[]]A`[\"{BAI`I@d}\",[]]A`[\"{BDAfI@d}\",[]]A`[\"{BCNhI@d}\",[]]A`[\"{BGBhI@d}\",[]]A`[\"{cc{}}\",[\"T\"]]0000000000000000000000o[\"{CKfKBf}\",[]]A`[\"{AAJfKBf}\",[]]o[\"{CKdKBf}\",[]]n[\"{NbKBf}\",[]]4A`[\"{BEC`KBf}\",[]]5555Al[\"{cK@d{{CMb{CKf}}}}\",[\"T\"]]666666666666666666Aa[\"{BAJjBBEj}\",[]]77777A`[\"{AGHbI@n}\",[]]88888A`[\"{KBfANGb}\",[]]99999Aa[\"{BBHjANEn}\",[]]Aa[\"{BF@bANEn}\",[]];;;;;Aa[\"{BAJjBBEf}\",[]]<<<<>>>>>A`[\"{I@hBAJj}\",[]]A`[\"{KBfBEC`}\",[]]A`[\"{cc{}}\",[\"T\"]]00000A`[\"{KBfAAJf}\",[]]111111A`[\"{B@MbI@h}\",[]]222Aa[\"{ANIjANFd}\",[]]3333A`[\"{BGCjI@f}\",[]]A`[\"{BCOnI@f}\",[]]A`[\"{AHNnI@f}\",[]]A`[\"{BDAfI@f}\",[]]7A`[\"{BBFdI@f}\",[]]A`[\"{BAI`I@f}\",[]]A`[\"{BBGnI@f}\",[]]A`[\"{BGBhI@f}\",[]]A`[\"{BCNhI@f}\",[]]A`[\"{BAGnI@f}\",[]]A`[\"{BFMjI@f}\",[]]>>>>>>>>>>>>An[\"{{{AHA`{c}}}AIBfCKn}\",[\"S\"]]??????????????Bm[\"{{{AHA`{KBd}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bk[\"{{{AHA`{K@b}}{AHA`{CDfc}}}HMlJO`}\",[\"H\"]]Bn[\"{{{AHA`{ANG`}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{AOHf}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bm[\"{{{AHA`{CNn}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bl[\"{{{AHA`{Oj}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{AAJd}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bm[\"{{{AHA`{KBf}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{BDKj}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bk[\"{{{AHA`{K@d}}{AHA`{CDfc}}}HMlJO`}\",[\"H\"]]Bn[\"{{{AHA`{AGHl}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{B@Lf}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{AIBj}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{ANGb}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{BCNn}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{BDKb}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{AOHh}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bm[\"{{{AHA`{CO`}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bl[\"{{{AHA`{Ol}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{AAJf}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Bn[\"{{{AHA`{AGF`}}{AHA`{CDfc}}}HMlJO`}\",[\"__H\"]]Aa[\"{{}c{}}\",[\"U\"]]0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n[\"{{}HMl}\",[]]0000Cc[\"{{{AHA`{CDfJMn}}JLf}{{K@h{{JOn{HNd}}AGHl}}}}\",[]]Cf[\"{{{AHA`{CDfB@Jd}}}{{JOn{c}}}{}}\",[\"Iterator::Item\"]]Dl[\"{{{AHA`{BDJd}}HMj{AHA`{CDf{JJ`{Nb}}}}}{{K@h{{AHA`{{JJ`{Nb}}}}ANFb}}}}\",[]]Bh[\"{{{AHA`{CDfNF`}}Ol}{{JOn{AAJf}}}}\",[]]Dl[\"{{{AHA`{BDJf}}HMj{AHA`{CDf{JJ`{Nb}}}}}{{K@h{{AHA`{{JJ`{Nb}}}}ANFd}}}}\",[]]Bf[\"{{{AHA`{AHLn}}K@b}{{JOn{CN`}}}}\",[]]Bf[\"{{{AHA`{CN`}}}{{K@h{HMlAHL`}}}}\",[]]A`[\"{AHMjCKh}\",[]]Am[\"{{{AHA`{CDfAHM`}}}HMl}\",[]]A`[\"{AHMlCKh}\",[]]Ck[\"{{{AAb{{AHA`{CDfAHKh}}}}{AHA`{CDfNAh}}}{{CNh{HMl}}}}\",[]]Dk[\"{{{AAb{{AHA`{CDfBBI`}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAb{{AHA`{CDfAAIb}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAb{{AHA`{CDfAAId}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAb{{AHA`{CDfAHLj}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAb{{AHA`{CDfNCl}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAb{{AHA`{CDfJOd}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAb{{AHA`{CDfAGCh}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAb{{AHA`{CDfAAEl}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAb{{AHA`{CDfAOKj}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAb{{AHA`{CDfAOLd}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAb{{AHA`{CDfJLn}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAb{{AHA`{CDfBAGj}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAb{{AHA`{CDfNEh}}}}{AHA`{CDfNAh}}}{{CNh{c}}}{}}\",[\"Future::Output\"]]Bf[\"{{{AHA`{CDfAHM`}}}{{JOn{I@n}}}}\",[]]De[\"{{{AHA`{CDfAI@`}}{AHA`{CDf{JJ`{Nb}}}}}{{K@h{{JOn{JLf}}AGHj}}}}\",[]]Bm[\"{{{AHA`{CDfAI@b}}D@`}{{K@h{JMnB@Lf}}}}\",[]]Bo[\"{{CO`{AHA`{CDfc}}}{{K@h{BEHjI@h}}}Of}\",[\"R\"]]Bf[\"{{{AHA`{CDfAGEd}}}{{JOn{HN`}}}}\",[]]Ec[\"{{{AHA`{BAJl}}AIBf{AHA`{CDf{JJ`{AHNd}}}}{AHA`{CDf{JJ`{AAJ`}}}}}{{K@j{JLf}}}}\",[]]Cn[\"{{{AHA`{BDJd}}HMj{AHA`{CDf{AAh{Nb}}}}}{{K@h{HMlANFb}}}}\",[]]Cn[\"{{{AHA`{BDJf}}HMj{AHA`{CDf{AAh{Nb}}}}}{{K@h{HMlANFd}}}}\",[]]C`[\"{{{AHA`{CDfAGEd}}HN`D@`}{{K@h{HMlBDKj}}}}\",[]]Cc[\"{{{AHA`{BAJl}}AIBf{AHA`{AAKl}}}{{K@j{HMl}}}}\",[]]Bn[\"{{{AHA`{CDfBFGb}}CKf}{{AHA`{CDfBFGb}}}}\",[]]Bn[\"{{{AHA`{CDfBFGd}}CKf}{{AHA`{CDfBFGd}}}}\",[]]Aj[\"{{{AHA`{AHLn}}}CNn}\",[]]Aj[\"{{{AHA`{AHM`}}}CO`}\",[]]Cn[\"{{{AHA`{NBd}}{AHA`{{JJ`{Nb}}}}{AHA`{CDf{JJ`{Nb}}}}}HMl}\",[]]Cn[\"{{{AHA`{NBf}}{AHA`{{JJ`{Nb}}}}{AHA`{CDf{JJ`{Nb}}}}}HMl}\",[]]A`[\"{BAJdCKh}\",[]]A`[\"{AAKhJLf}\",[]]A`[\"{AAKjJLf}\",[]]o[\"{IBfD@`}\",[]]Bm[\"{{{AHA`{CDfAI@`}}KBd}{{K@h{HMlAOGd}}}}\",[]]Bm[\"{{{AHA`{CDfBEHl}}KBd}{{K@h{HMlAOGd}}}}\",[]]Bm[\"{{{AHA`{CDfAI@b}}KBf}{{K@h{HMlAOGl}}}}\",[]]Bn[\"{{{AHA`{AIBb}}{AHA`{CKb}}}{{JOn{HN`}}}}\",[]]Bn[\"{{{AHA`{BAHl}}{AHA`{CKb}}}{{JOn{HN`}}}}\",[]]Bn[\"{{{AHA`{BDBd}}{AHA`{CKb}}}{{JOn{HN`}}}}\",[]]Bn[\"{{{AHA`{AIBd}}{AHA`{CKb}}}{{JOn{HN`}}}}\",[]]Bn[\"{{{AHA`{BAHn}}{AHA`{CKb}}}{{JOn{HN`}}}}\",[]]Bn[\"{{{AHA`{BDBf}}{AHA`{CKb}}}{{JOn{HN`}}}}\",[]]Bd[\"{{{AHA`{BCOd}}}{{JOn{B@Jd}}}}\",[]]Bg[\"{{{Nl{BDIl}}NBjCKd}{{Od{AHMb}}}}\",[]]Bg[\"{{{Nl{AGDh}}NBjCKd}{{Od{AHMb}}}}\",[]]Bg[\"{{{Nl{ANFf}}NBjCKd}{{Od{AHMb}}}}\",[]]Bg[\"{{{Nl{B@Kf}}NBjCKd}{{Od{AHMb}}}}\",[]]Bg[\"{{{Nl{BDIn}}NBjCKd}{{Od{AHMd}}}}\",[]]Bg[\"{{{Nl{AGDj}}NBjCKd}{{Od{AHMd}}}}\",[]]Bg[\"{{{Nl{ANFh}}NBjCKd}{{Od{AHMd}}}}\",[]]Bg[\"{{{Nl{B@Kh}}NBjCKd}{{Od{AHMd}}}}\",[]]Ai[\"{BEGn{{Nl{BDIn}}}}\",[]]o[\"{HNbHN`}\",[]]A`[\"{AAKnCKh}\",[]]o[\"{NFlJLf}\",[]]o[\"{HNdHN`}\",[]]A`[\"{AAL`CKh}\",[]]o[\"{NFnJLf}\",[]]Aa[\"{ANEbBBEj}\",[]]Ai[\"{{{AHA`{A@j}}}A@j}\",[]]Ak[\"{{{AHA`{ANHf}}}ANHf}\",[]]Ak[\"{{{AHA`{ANEf}}}ANEf}\",[]]Ak[\"{{{AHA`{AHLn}}}AHLn}\",[]]Ak[\"{{{AHA`{BF@f}}}BF@f}\",[]]Ak[\"{{{AHA`{BDKh}}}BDKh}\",[]]Ak[\"{{{AHA`{AAGd}}}AAGd}\",[]]Ak[\"{{{AHA`{B@Ib}}}B@Ib}\",[]]Ai[\"{{{AHA`{CN`}}}CN`}\",[]]Ak[\"{{{AHA`{BAJn}}}BAJn}\",[]]Ak[\"{{{AHA`{BAJ`}}}BAJ`}\",[]]Ak[\"{{{AHA`{AGHj}}}AGHj}\",[]]Ak[\"{{{AHA`{AI@d}}}AI@d}\",[]]Ak[\"{{{AHA`{BAIn}}}BAIn}\",[]]Ak[\"{{{AHA`{AIBh}}}AIBh}\",[]]Ak[\"{{{AHA`{AOMf}}}AOMf}\",[]]Ai[\"{{{AHA`{KBd}}}KBd}\",[]]Ak[\"{{{AHA`{BF@`}}}BF@`}\",[]]Ai[\"{{{AHA`{K@b}}}K@b}\",[]]Ak[\"{{{AHA`{AAKn}}}AAKn}\",[]]Ak[\"{{{AHA`{AHMj}}}AHMj}\",[]]Ak[\"{{{AHA`{AGHd}}}AGHd}\",[]]Ak[\"{{{AHA`{BBF`}}}BBF`}\",[]]Ai[\"{{{AHA`{NFl}}}NFl}\",[]]Ak[\"{{{AHA`{AOGd}}}AOGd}\",[]]Ak[\"{{{AHA`{BBEh}}}BBEh}\",[]]Ak[\"{{{AHA`{BBHf}}}BBHf}\",[]]Ak[\"{{{AHA`{BDNh}}}BDNh}\",[]]Ak[\"{{{AHA`{BE@f}}}BE@f}\",[]]Ak[\"{{{AHA`{ANG`}}}ANG`}\",[]]Ak[\"{{{AHA`{BAG`}}}BAG`}\",[]]Ak[\"{{{AHA`{AOLj}}}AOLj}\",[]]Ak[\"{{{AHA`{BFGb}}}BFGb}\",[]]Ak[\"{{{AHA`{AOFh}}}AOFh}\",[]]Ak[\"{{{AHA`{ANEl}}}ANEl}\",[]]Ak[\"{{{AHA`{AGFb}}}AGFb}\",[]]Ak[\"{{{AHA`{BBEb}}}BBEb}\",[]]Ak[\"{{{AHA`{BCNb}}}BCNb}\",[]]Ak[\"{{{AHA`{AOH`}}}AOH`}\",[]]Ak[\"{{{AHA`{AOHf}}}AOHf}\",[]]Ak[\"{{{AHA`{AOI`}}}AOI`}\",[]]Ak[\"{{{AHA`{BEBn}}}BEBn}\",[]]Ak[\"{{{AHA`{AHN`}}}AHN`}\",[]]Ai[\"{{{AHA`{CNn}}}CNn}\",[]]Ag[\"{{{AHA`{Oj}}}Oj}\",[]]Ak[\"{{{AHA`{AAJd}}}AAJd}\",[]]Ag[\"{{{AHA`{Nn}}}Nn}\",[]]Ak[\"{{{AHA`{AGDh}}}AGDh}\",[]]Ai[\"{{{AHA`{HNj}}}HNj}\",[]]Ak[\"{{{AHA`{ANFf}}}ANFf}\",[]]Ai[\"{{{AHA`{NCf}}}NCf}\",[]]Ak[\"{{{AHA`{B@Kf}}}B@Kf}\",[]]Ai[\"{{{AHA`{I@d}}}I@d}\",[]]Ak[\"{{{AHA`{BDAl}}}BDAl}\",[]]Ak[\"{{{AHA`{BEOh}}}BEOh}\",[]]Ak[\"{{{AHA`{BDB`}}}BDB`}\",[]]Ai[\"{{{AHA`{KBf}}}KBf}\",[]]Ak[\"{{{AHA`{BF@b}}}BF@b}\",[]]Ak[\"{{{AHA`{BDKj}}}BDKj}\",[]]Ai[\"{{{AHA`{K@d}}}K@d}\",[]]Ak[\"{{{AHA`{AOLb}}}AOLb}\",[]]Ak[\"{{{AHA`{AHOh}}}AHOh}\",[]]Ak[\"{{{AHA`{AGHb}}}AGHb}\",[]]Ak[\"{{{AHA`{BDKf}}}BDKf}\",[]]Ak[\"{{{AHA`{BEBf}}}BEBf}\",[]]Ak[\"{{{AHA`{AHLf}}}AHLf}\",[]]Ak[\"{{{AHA`{AAL`}}}AAL`}\",[]]Ak[\"{{{AHA`{AHMl}}}AHMl}\",[]]Ak[\"{{{AHA`{AGHf}}}AGHf}\",[]]Ak[\"{{{AHA`{BBFb}}}BBFb}\",[]]Ak[\"{{{AHA`{AGHl}}}AGHl}\",[]]Ak[\"{{{AHA`{B@Lf}}}B@Lf}\",[]]Ai[\"{{{AHA`{NFn}}}NFn}\",[]]Ak[\"{{{AHA`{AIBj}}}AIBj}\",[]]Ak[\"{{{AHA`{ANFn}}}ANFn}\",[]]Ak[\"{{{AHA`{BAJb}}}BAJb}\",[]]Ak[\"{{{AHA`{AOGl}}}AOGl}\",[]]Ak[\"{{{AHA`{BBEj}}}BBEj}\",[]]Ak[\"{{{AHA`{AGGl}}}AGGl}\",[]]Ak[\"{{{AHA`{BAEn}}}BAEn}\",[]]Ak[\"{{{AHA`{BFJl}}}BFJl}\",[]]Ak[\"{{{AHA`{BBHh}}}BBHh}\",[]]Ak[\"{{{AHA`{BDNj}}}BDNj}\",[]]Ak[\"{{{AHA`{BE@h}}}BE@h}\",[]]Ak[\"{{{AHA`{ANGb}}}ANGb}\",[]]Ak[\"{{{AHA`{BAGb}}}BAGb}\",[]]Ak[\"{{{AHA`{AOLn}}}AOLn}\",[]]Ak[\"{{{AHA`{BFGd}}}BFGd}\",[]]Ak[\"{{{AHA`{AOFl}}}AOFl}\",[]]Ak[\"{{{AHA`{ANEn}}}ANEn}\",[]]Ak[\"{{{AHA`{AGFd}}}AGFd}\",[]]Ak[\"{{{AHA`{AHNh}}}AHNh}\",[]]Ak[\"{{{AHA`{AIAd}}}AIAd}\",[]]Ak[\"{{{AHA`{AOHj}}}AOHj}\",[]]Ak[\"{{{AHA`{BBEf}}}BBEf}\",[]]Ak[\"{{{AHA`{BCNf}}}BCNf}\",[]]Ak[\"{{{AHA`{AAFh}}}AAFh}\",[]]Ak[\"{{{AHA`{BCNn}}}BCNn}\",[]]Ak[\"{{{AHA`{AOHb}}}AOHb}\",[]]Ak[\"{{{AHA`{BBGb}}}BBGb}\",[]]Ak[\"{{{AHA`{BFKd}}}BFKd}\",[]]Ak[\"{{{AHA`{AAHd}}}AAHd}\",[]]Ak[\"{{{AHA`{BDKb}}}BDKb}\",[]]Ak[\"{{{AHA`{AOHh}}}AOHh}\",[]]Ak[\"{{{AHA`{AOIb}}}AOIb}\",[]]Ak[\"{{{AHA`{BAJj}}}BAJj}\",[]]Ak[\"{{{AHA`{BEC`}}}BEC`}\",[]]Ak[\"{{{AHA`{AHNb}}}AHNb}\",[]]Ak[\"{{{AHA`{BGG`}}}BGG`}\",[]]Ai[\"{{{AHA`{CO`}}}CO`}\",[]]Ag[\"{{{AHA`{Ol}}}Ol}\",[]]Ak[\"{{{AHA`{AAJf}}}AAJf}\",[]]Ak[\"{{{AHA`{AGF`}}}AGF`}\",[]]Ak[\"{{{AHA`{B@Mb}}}B@Mb}\",[]]Ak[\"{{{AHA`{BEHj}}}BEHj}\",[]]Ai[\"{{{AHA`{I@h}}}I@h}\",[]]Ai[\"{{{AHA`{I@f}}}I@f}\",[]]Ak[\"{{{AHA`{BDAn}}}BDAn}\",[]]Ak[\"{{{AHA`{BEOj}}}BEOj}\",[]]Ak[\"{{{AHA`{BDBb}}}BDBb}\",[]]Ag[\"{{{AHA`{O`}}}O`}\",[]]Ak[\"{{{AHA`{AGDj}}}AGDj}\",[]]Ai[\"{{{AHA`{HNl}}}HNl}\",[]]Ak[\"{{{AHA`{ANFh}}}ANFh}\",[]]Ai[\"{{{AHA`{NCh}}}NCh}\",[]]Ak[\"{{{AHA`{B@Kh}}}B@Kh}\",[]]Ai[\"{{{AHA`{IA`}}}IA`}\",[]]Ak[\"{{{AHA`{AAJ`}}}AAJ`}\",[]]Ak[\"{{{AHA`{AAKl}}}AAKl}\",[]]Ak[\"{{{AHA`{AOId}}}AOId}\",[]]Ak[\"{{{AHA`{BEGn}}}BEGn}\",[]]Ak[\"{{{AHA`{BBFj}}}BBFj}\",[]]Ak[\"{{{AHA`{BG@n}}}BG@n}\",[]]Ak[\"{{{AHA`{BGA`}}}BGA`}\",[]]Bn[\"{{{AHA`{AHLn}}KBd{AHA`{{JJ`{Nb}}}}}HMl}\",[]]Bn[\"{{{AHA`{AAGd}}KBd{AHA`{{JJ`{Nb}}}}}HMl}\",[]]Bf[\"{{{AHA`{CN`}}}{{K@h{HMlBAEl}}}}\",[]]Bf[\"{{{AHA`{CDfAHM`}}NBjKBfHN`}HMl}\",[]]Bj[\"{{{AHA`{AOHf}}}{{AHA`{{JJ`{Nb}}}}}}\",[]]Bj[\"{{{AHA`{AOHh}}}{{AHA`{{JJ`{Nb}}}}}}\",[]]Aa[\"{BAJjAHNh}\",[]]A`[\"{AAJdCKh}\",[]]A`[\"{AAJfCKh}\",[]]A`[\"{AOI`D@`}\",[]]A`[\"{AOIbD@`}\",[]]l[\"{NBl}\",[]]l[\"{NBn}\",[]]Ce[\"{{{AHA`{BDOd}}{AHA`{CDfOf}}}{{K@h{AOHhBDKb}}}}\",[]]Ce[\"{{{AHA`{BGJb}}{AHA`{CDfOf}}}{{K@h{AOHhBDKb}}}}\",[]]Bc[\"{{{AHA`{AHM`}}}{{AAh{K@d}}}}\",[]]Bd[\"{{{AHA`{IBl}}{AHA`{CKb}}}HMl}\",[]]Am[\"{{{AHA`{ANEh}}JLf}HMl}\",[]]Ai[\"{{{AHA`{IBn}}}HMl}\",[]]Bg[\"{{{AAb{{AHA`{CDfAHKh}}}}NBj}HMl}\",[]]Bm[\"{{{AHA`{CDfAI@l}}KBd}{{K@h{HMlAOGd}}}}\",[]]Bm[\"{{{AHA`{CDfAI@n}}KBf}{{K@h{HMlAOGl}}}}\",[]]Am[\"{AAGl{{K@h{HMlAI@f}}}}\",[]]Dc[\"{{{AHA`{CDfAAGf}}AAGn{AHA`{CDf{AAh{Nb}}}}}{{K@h{AAKjAI@h}}}}\",[]]Bi[\"{{{AHA`{NDn}}{AAb{{Od{JNn}}}}}HMl}\",[]]Bj[\"{{{AHA`{AOMh}}{AAb{{Od{JNn}}}}}HMl}\",[]]Bj[\"{{{AHA`{ANHl}}{AAb{{Od{JNn}}}}}HMl}\",[]]o[\"{A@jD@`}\",[]]Ak[\"{{{AHA`{AHLn}}}BBF`}\",[]]Ak[\"{{{AHA`{AAGd}}}B@Ib}\",[]]Aj[\"{{{AHA`{CN`}}}AGHd}\",[]]An[\"{{{AHA`{CDfAHM`}}}BBFb}\",[]]Ce[\"{{{AHA`{CDfAHOj}}{JOn{KB`}}}{{AHA`{CDfAHOj}}}}\",[]]Ce[\"{{{AHA`{CDfAHOl}}{JOn{KB`}}}{{AHA`{CDfAHOl}}}}\",[]]Ck[\"{{{AHA`{CDfAI@l}}{AHA`{{JJ`{Nb}}}}}{{K@h{JLfAIBh}}}}\",[]]Ck[\"{{{AHA`{CDfAI@n}}{AHA`{{JJ`{Nb}}}}}{{K@h{JLfAIBj}}}}\",[]]Bl[\"{{{AHA`{BEHj}}{AHA`{CDfc}}}HMlJMl}\",[\"W\"]]Aj[\"{{{AHA`{AAGd}}}JLn}\",[]]An[\"{AAGl{{K@h{AHLjBBEh}}}}\",[]]Bh[\"{{{AHA`{CDfNF`}}Ol}{{JOn{AAJf}}}}\",[]]Fh[\"{{{AHA`{CDfAAGf}}AAGnNBj{AHA`{CDf{AAh{Nb}}}}{JOn{{Nl{AOLn}}}}}{{K@h{{JLd{BCNnAHM`}}{Od{ANEb}}}}}}\",[]]Am[\"{AHA`{{AHA`{c}}}{}}\",[\"T\"]]0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000o[\"{NFlJLf}\",[]]o[\"{NFnJLf}\",[]]A`[\"{A@jANEf}\",[]]Bc[\"{{AIAbBAEjA@j}{{K@l{ANEh}}}}\",[]]Aj[\"{AIAb{{K@j{AAGd}}}}\",[]]B`[\"{{}{{K@h{HMl{Od{HOf}}}}}}\",[]]Ak[\"{{{AHA`{AHLn}}}BBEh}\",[]]Be[\"{{{AHA`{AAGf}}}{{AHA`{BAGb}}}}\",[]]o[\"{NbBEBn}\",[]]A`[\"{AHMjCKh}\",[]]o[\"{AOLjNl}\",[]]o[\"{NbBEC`}\",[]]A`[\"{AHMlCKh}\",[]]o[\"{AOLnNl}\",[]]A`[\"{BAJjJOn}\",[]]Bl[\"{{{AHA`{CDfc}}}{{K@h{KBdB@Mb}}}Of}\",[\"B\"]]Bl[\"{{{AHA`{CDfc}}}{{K@h{K@bB@Mb}}}Of}\",[\"B\"]]Bm[\"{{{AHA`{CDfc}}}{{K@h{AGFbB@Mb}}}Of}\",[\"B\"]]Bm[\"{{{AHA`{CDfc}}}{{K@h{BEBnB@Mb}}}Of}\",[\"B\"]]Bm[\"{{{AHA`{CDfc}}}{{K@h{AAJdB@Mb}}}Of}\",[\"B\"]]Bh[\"{{{AHA`{CDfc}}}{{KA`{KBf}}}Of}\",[\"B\"]]Bh[\"{{{AHA`{CDfc}}}{{KA`{K@d}}}Of}\",[\"B\"]]Bi[\"{{{AHA`{CDfc}}}{{KA`{AGFd}}}Of}\",[\"B\"]]Bi[\"{{{AHA`{CDfc}}}{{KA`{AHNh}}}Of}\",[\"B\"]]Ek[\"{{{AHA`{CDf{JNl{AAEn}}}}{AHA`{c}}{AHA`{{JJ`{CKf}}}}D@`}{{K@h{BBGbBDKb}}}{BDOdIBj}}\",[\"\"]]Bi[\"{{{AHA`{CDfc}}}{{KA`{BEC`}}}Of}\",[\"B\"]]Bi[\"{{{AHA`{CDfc}}}{{KA`{AAJf}}}Of}\",[\"B\"]]Bi[\"{{{AHA`{CDfc}}}{{KA`{AGEf}}}Of}\",[\"B\"]]A`[\"{AAJ`JOn}\",[]]Bk[\"{{{AHA`{KBd}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bk[\"{{{AHA`{K@b}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{AGFb}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{BEBn}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{AAJd}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bk[\"{{{AHA`{KBf}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bk[\"{{{AHA`{K@d}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{AGFd}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{AHNh}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{AAFh}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{BEC`}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{AAJf}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bl[\"{{{AHA`{AGEl}}{AHA`{CDfc}}}HMlJMl}\",[\"B\"]]Bj[\"{{{AHA`{CDfAI@l}}}{{K@h{HMlAOGd}}}}\",[]]Bj[\"{{{AHA`{CDfAI@n}}}{{K@h{HMlANFn}}}}\",[]]An[\"{{{AHA`{ANIh}}AAG`}HMl}\",[]]Ea[\"{{{AHA`{CDfAAGf}}NBjAGF`{JOn{AOIb}}AAEn{AHA`{CDf{AAh{Nb}}}}}{{JOn{B@Hn}}}}\",[]]o[\"{CMdNBl}\",[]]o[\"{CMfNBn}\",[]]A`[\"{AAGlHMl}\",[]]Ba[\"{{{AHA`{CDfAAGf}}AAGn}HMl}\",[]]Bh[\"{{{AHA`{AIBb}}{AHA`{CKb}}HN`}HMl}\",[]]Bh[\"{{{AHA`{BAHl}}{AHA`{CKb}}HN`}HMl}\",[]]Bh[\"{{{AHA`{BDBd}}{AHA`{CKb}}HN`}HMl}\",[]]Bh[\"{{{AHA`{AIBd}}{AHA`{CKb}}HN`}HMl}\",[]]Bh[\"{{{AHA`{BAHn}}{AHA`{CKb}}HN`}HMl}\",[]]Bh[\"{{{AHA`{BDBf}}{AHA`{CKb}}HN`}HMl}\",[]]A`[\"{AGDnD@`}\",[]]o[\"{HNbCKh}\",[]]o[\"{HNdCKh}\",[]]Ce[\"{{{AHA`{CDfAHMb}}NBjNBjCKhD@`{AHA`{AOL`}}}HMl}\",[]]Cc[\"{{{AHA`{CDfNn}}NBjNBjCKhD@`{AHA`{AOL`}}}HMl}\",[]]Cd[\"{{{AHA`{CDfHNj}}NBjNBjCKhD@`{AHA`{AOL`}}}HMl}\",[]]Cd[\"{{{AHA`{CDfNCf}}NBjNBjCKhD@`{AHA`{AOL`}}}HMl}\",[]]Ce[\"{{{AHA`{CDfAHMd}}NBjNBjCKhD@`{AHA`{AOLb}}}HMl}\",[]]Cc[\"{{{AHA`{CDfO`}}NBjNBjCKhD@`{AHA`{AOLb}}}HMl}\",[]]Cd[\"{{{AHA`{CDfHNl}}NBjNBjCKhD@`{AHA`{AOLb}}}HMl}\",[]]Cd[\"{{{AHA`{CDfNCh}}NBjNBjCKhD@`{AHA`{AOLb}}}HMl}\",[]]o[\"{CMdNBl}\",[]]o[\"{CMfNBn}\",[]]o[\"{BDBnNb}\",[]]A`[\"{BBEbHN`}\",[]]A`[\"{BCNbHN`}\",[]]A`[\"{BBEfHN`}\",[]]A`[\"{BCNfHN`}\",[]]A`[\"{BAJjKB`}\",[]]Aa[\"{BAFbBBEj}\",[]]Aa[\"{AGCdBDKf}\",[]]Bg[\"{{{AHA`{AAGd}}AGIb}{{K@j{HMl}}}}\",[]]A`[\"{AAGlHMl}\",[]]Cf[\"{{{AHA`{CDfAAGf}}AAGn{AHA`{CDf{AAh{Nb}}}}}AAKj}\",[]]l[\"{NBl}\",[]]Ak[\"{{{AHA`{AGF`}}}AIAb}\",[]]l[\"{NBn}\",[]]An[\"{{AAGbA@j}{{K@l{HMl}}}}\",[]]B`[\"{{AOLjAIAb}{{K@j{AAGd}}}}\",[]]Bb[\"{AOLf{{K@h{HMl{Od{HOf}}}}}}\",[]]Bk[\"{{{AHA`{BDKh}}}{{JOn{{AHA`{HOf}}}}}}\",[]]Bk[\"{{{AHA`{BAJ`}}}{{JOn{{AHA`{HOf}}}}}}\",[]]Bk[\"{{{AHA`{AGHj}}}{{JOn{{AHA`{HOf}}}}}}\",[]]Bk[\"{{{AHA`{AI@d}}}{{JOn{{AHA`{HOf}}}}}}\",[]]Bk[\"{{{AHA`{BAIn}}}{{JOn{{AHA`{HOf}}}}}}\",[]]Bk[\"{{{AHA`{AIBh}}}{{JOn{{AHA`{HOf}}}}}}\",[]]Bk[\"{{{AHA`{AOMf}}}{{JOn{{AHA`{HOf}}}}}}\",[]]Bk[\"{{{AHA`{BBEh}}}{{JOn{{AHA`{HOf}}}}}}\",[]]Bk[\"{{{AHA`{BBEj}}}{{JOn{{AHA`{HOf}}}}}}\",[]]A`[\"{AAKhJOn}\",[]]A`[\"{AAKjJOn}\",[]]A`[\"{AAKlJOn}\",[]]Bg[\"{{{AHA`{CN`}}}{{K@h{AHOfAHL`}}}}\",[]]Aa[\"{AOKlAHOh}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]A`[\"{AAJ`JLf}\",[]]Aa[\"{AGHdAAKn}\",[]]Aa[\"{BBF`AAKn}\",[]]Aa[\"{AGHfAAL`}\",[]]Aa[\"{BBFbAAL`}\",[]]3210Dh[\"{{{AHA`{NBd}}{AHA`{{JJ`{Nb}}}}{AHA`{{JJ`{Nb}}}}}{{K@h{HMlANFb}}}}\",[]]Dh[\"{{{AHA`{NBf}}{AHA`{{JJ`{Nb}}}}{AHA`{{JJ`{Nb}}}}}{{K@h{HMlANFd}}}}\",[]]Aj[\"{{{AHA`{AHMb}}}CKh}\",[]]Ah[\"{{{AHA`{Nn}}}CKh}\",[]]Ai[\"{{{AHA`{HNj}}}CKh}\",[]]Ai[\"{{{AHA`{NCf}}}CKh}\",[]]Aj[\"{{{AHA`{AHMd}}}CKh}\",[]]Ah[\"{{{AHA`{O`}}}CKh}\",[]]Ai[\"{{{AHA`{HNl}}}CKh}\",[]]Ai[\"{{{AHA`{NCh}}}CKh}\",[]]Aj[\"{{{AHA`{BFF`}}}JLf}\",[]]Aj[\"{{{AHA`{BFFb}}}JLf}\",[]]Aj[\"{{{AHA`{BGFf}}}JLf}\",[]]Aj[\"{{{AHA`{BGG`}}}JLf}\",[]]o[\"{A@jJLf}\",[]]n[\"{{}NAf}\",[]]0o[\"{OhAAFb}\",[]]111Ba[\"{{AHA`{AHA`{c}}}AAIf{}}\",[\"K\"]]0000000000000000000Cg[\"{{{AHA`{AAGd}}AIAb{AHA`{CKb}}}{{K@h{AHLjAOH`}}}}\",[]]Dl[\"{{{AHA`{CDfAAGf}}NBjAOFlAIAb{AHA`{CKb}}}{{K@h{{JLd{BCNnAHM`}}AOHb}}}}\",[]]Bd[\"{{{AHA`{AAGl}}}{{JOn{BCOb}}}}\",[]]Dm[\"{{{AHA`{AGGf}}K@bCKh{AHA`{{JJ`{Nb}}}}{AHA`{CDfAAEn}}}{{K@h{HMlANFb}}}}\",[]]Ca[\"{{{AHA`{AGFh}}JLf{AHA`{CDf{JJ`{Nb}}}}}HMl}\",[]]Bd[\"{{{AHA`{AAGn}}}{{JOn{BCOd}}}}\",[]]Dm[\"{{{AHA`{AGGh}}K@dCKh{AHA`{{JJ`{Nb}}}}{AHA`{CDfAAEn}}}{{K@h{HMlANFd}}}}\",[]]Ca[\"{{{AHA`{AGFj}}JLf{AHA`{CDf{JJ`{Nb}}}}}HMl}\",[]]o[\"{{}ANIf}\",[]]n[\"{{}IBl}\",[]]o[\"{{}ANEh}\",[]]o[\"{{}B@H`}\",[]]o[\"{{}B@Ib}\",[]]n[\"{{}KBd}\",[]]n[\"{{}K@b}\",[]]o[\"{{}AAKn}\",[]]o[\"{{}AHMj}\",[]]o[\"{{}AGHd}\",[]]o[\"{{}BBF`}\",[]]n[\"{{}NFl}\",[]]o[\"{{}AOGd}\",[]]o[\"{{}BBHf}\",[]]o[\"{{}BDNh}\",[]]o[\"{{}BE@f}\",[]]o[\"{{}ANG`}\",[]]o[\"{{}BAG`}\",[]]o[\"{{}BFGb}\",[]]o[\"{{}BDBd}\",[]]o[\"{{}AGDh}\",[]]o[\"{{}ANFf}\",[]]o[\"{{}B@Kf}\",[]]o[\"{{}BDJ`}\",[]]o[\"{{}B@Hb}\",[]]o[\"{{}BGFf}\",[]]n[\"{{}KBf}\",[]]n[\"{{}K@d}\",[]]o[\"{{}AHOh}\",[]]o[\"{{}AHLf}\",[]]o[\"{{}AAL`}\",[]]o[\"{{}AHMl}\",[]]o[\"{{}AGHf}\",[]]o[\"{{}BBFb}\",[]]n[\"{{}NFn}\",[]]o[\"{{}BAJb}\",[]]o[\"{{}AOGl}\",[]]o[\"{{}BBHh}\",[]]o[\"{{}BDNj}\",[]]o[\"{{}BE@h}\",[]]o[\"{{}ANGb}\",[]]o[\"{{}BAGb}\",[]]o[\"{{}BFGd}\",[]]o[\"{{}BGG`}\",[]]o[\"{{}BDBf}\",[]]o[\"{{}AGDj}\",[]]o[\"{{}ANFh}\",[]]o[\"{{}B@Kh}\",[]]o[\"{{}BDJb}\",[]]o[\"{{}AAJ`}\",[]]n[\"{{}IBn}\",[]]o[\"{{}BBFj}\",[]]o[\"{{}B@I`}\",[]]Ak[\"{{{AHA`{B@Kl}}}AOHh}\",[]]Ak[\"{{{AHA`{BBGb}}}AOHh}\",[]]Aa[\"{BFKdAOHh}\",[]]Aa[\"{BECbAOHh}\",[]]A`[\"{CMhAOHh}\",[]]A`[\"{IBbAOHh}\",[]]A`[\"{IBfAOHh}\",[]]Aa[\"{BDBnAOHh}\",[]]Cg[\"{{{AHA`{AGGf}}K@bCKh{AHA`{CDf{JJ`{Nb}}}}JLf}HMl}\",[]]Ca[\"{{{AHA`{AGFh}}JLf{AHA`{CDf{JJ`{Nb}}}}}HMl}\",[]]Cg[\"{{{AHA`{AGGh}}K@dCKh{AHA`{CDf{JJ`{Nb}}}}JLf}HMl}\",[]]Ca[\"{{{AHA`{AGFj}}JLf{AHA`{CDf{JJ`{Nb}}}}}HMl}\",[]]Aj[\"{{{AHA`{AI@`}}}D@`}\",[]]Aj[\"{{{AHA`{BEHl}}}D@`}\",[]]Ak[\"{{{AHA`{AHMb}}}BDJ`}\",[]]Ai[\"{{{AHA`{Nn}}}BDJ`}\",[]]Aj[\"{{{AHA`{HNj}}}BDJ`}\",[]]Aj[\"{{{AHA`{NCf}}}BDJ`}\",[]]Ak[\"{{{AHA`{AHMd}}}BDJb}\",[]]Ai[\"{{{AHA`{O`}}}BDJb}\",[]]Aj[\"{{{AHA`{HNl}}}BDJb}\",[]]Aj[\"{{{AHA`{NCh}}}BDJb}\",[]]Bn[\"{{{AHA`{CDfBBHf}}CKd}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}CKd}{{AHA`{CDfBBHh}}}}\",[]]Bf[\"{{{AHA`{CDfAHMb}}NBjCKhCKh}HMl}\",[]]Bd[\"{{{AHA`{CDfNn}}NBjCKhCKh}HMl}\",[]]Bf[\"{{{AHA`{CDfAHMd}}NBjCKhCKh}HMl}\",[]]Bd[\"{{{AHA`{CDfO`}}NBjCKhCKh}HMl}\",[]]Aj[\"{{{AHA`{AHLn}}}JOd}\",[]]Bc[\"{{{AHA`{AAId}}}{{JOn{K@b}}}}\",[]]Aa[\"{BFKdAOHh}\",[]]Aa[\"{BECbAOHh}\",[]]A`[\"{CMhAOHh}\",[]]A`[\"{IBbAOHh}\",[]]Aa[\"{BDBnAOHh}\",[]]Aj[\"{{{AHA`{AI@l}}}NEh}\",[]]Bn[\"{{{AHA`{AI@n}}}{{K@h{{JOn{KBf}}AOGl}}}}\",[]]o[\"{A@jJLf}\",[]]o[\"{IBlJLf}\",[]]Am[\"{{{AHA`{CDfAHM`}}}NF`}\",[]]Aj[\"{{{AHA`{AGGf}}}JLf}\",[]]Aj[\"{{{AHA`{AGGh}}}JLf}\",[]]A`[\"{AHA`KBb}\",[]]0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bd[\"{{{AHA`{BF@f}}}{{JOn{AHLn}}}}\",[]]Bc[\"{{{AHA`{BAJn}}}{{JOn{CN`}}}}\",[]]Bn[\"{{{AHA`{CDfAOFh}}CKf}{{AHA`{CDfAOFh}}}}\",[]]Bn[\"{{{AHA`{CDfAOFl}}CKf}{{AHA`{CDfAOFl}}}}\",[]]A`[\"{BFKdCKf}\",[]]A`[\"{BECbCKf}\",[]]o[\"{CMhCKf}\",[]]o[\"{IBbCKf}\",[]]A`[\"{AGDnJOn}\",[]]Aa[\"{AAKlAHA`}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]Aa[\"{BAJdAAG`}\",[]]A`[\"{JMnBAJb}\",[]]Aa[\"{AGHdAHMj}\",[]]Aa[\"{BBF`AHMj}\",[]]Aa[\"{AGHfAHMl}\",[]]Aa[\"{BBFbAHMl}\",[]]3210Bg[\"{{{AHA`{CDfc}}JLf}AOHf{OfIBj}}\",[\"\"]]Bg[\"{{{AHA`{CDfc}}JLf}AOHh{OfIBj}}\",[\"\"]]o[\"{{}BBGd}\",[]]o[\"{{}BBGf}\",[]]A`[\"{CKhBGFf}\",[]]Cd[\"{{{AHA`{CKb}}}{{K@l{ANHfc}}}{}}\",[\"FromStr::Err\"]]Cd[\"{{{AHA`{CKb}}}{{K@l{ANEfc}}}{}}\",[\"FromStr::Err\"]]o[\"{CKfKBd}\",[]]o[\"{CKfKBf}\",[]]Al[\"{CKh{{K@h{KBdBF@`}}}}\",[]]Al[\"{CKh{{K@h{KBfBF@b}}}}\",[]]Aa[\"{BENjANF`}\",[]]Aa[\"{BGJdB@In}\",[]]Aa[\"{BENlANF`}\",[]]Aa[\"{BGJfB@In}\",[]]Af[\"{{}{{JOn{Ab}}}}\",[]]0000Aj[\"{{{AHA`{AHM`}}}D@`}\",[]]Bo[\"{{{AHA`{CDfBE@f}}AAG`}{{AHA`{CDfBE@f}}}}\",[]]Bo[\"{{{AHA`{CDfBE@h}}AAG`}{{AHA`{CDfBE@h}}}}\",[]]Ao[\"{{{Od{AHMb}}}{{Od{Nj}}}}\",[]]Am[\"{{{Od{Nn}}}{{Od{Nj}}}}\",[]]An[\"{{{Od{HNj}}}{{Od{Nj}}}}\",[]]An[\"{{{Od{NCf}}}{{Od{Nj}}}}\",[]]Ao[\"{{{Od{AHMd}}}{{Od{Nj}}}}\",[]]Am[\"{{{Od{O`}}}{{Od{Nj}}}}\",[]]An[\"{{{Od{HNl}}}{{Od{Nj}}}}\",[]]An[\"{{{Od{NCh}}}{{Od{Nj}}}}\",[]]Aj[\"{{{AHA`{BF@f}}}D@`}\",[]]Bo[\"{{{AHA`{CDfBFGb}}AAG`}{{AHA`{CDfBFGb}}}}\",[]]Bo[\"{{{AHA`{CDfBFGd}}AAG`}{{AHA`{CDfBFGd}}}}\",[]]Bc[\"{{{AHA`{AHLj}}}{{JOn{JOb}}}}\",[]]Bc[\"{{{AHA`{AHLn}}}{{JOn{JOb}}}}\",[]]Bc[\"{{{AHA`{AAGl}}}{{JOn{JOb}}}}\",[]]Bc[\"{{{AHA`{AAGn}}}{{JOn{JOb}}}}\",[]]Bc[\"{{{AHA`{AGF`}}}{{JOn{JOb}}}}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]Bc[\"{{{AHA`{AGEd}}}{{JOn{JLf}}}}\",[]]Am[\"{{{AHA`{ANIh}}JLf}HMl}\",[]]Aj[\"{{{AHA`{AHLn}}}NCl}\",[]]Bg[\"{{{AHA`{AI@l}}}{{K@h{CC`AOGd}}}}\",[]]Bg[\"{{{AHA`{AI@n}}}{{K@h{CC`AOGl}}}}\",[]]A`[\"{B@IfJOn}\",[]]A`[\"{B@IhJOn}\",[]]A`[\"{AGDnJOn}\",[]]A`[\"{ANEbJOn}\",[]]Ck[\"{{{AHA`{CDfBAG`}}{JOn{{ICh{Nb}}}}}{{AHA`{CDfBAG`}}}}\",[]]Ck[\"{{{AHA`{CDfBAGb}}{JOn{{ICh{Nb}}}}}{{AHA`{CDfBAGb}}}}\",[]]A`[\"{BDJ`JOn}\",[]]A`[\"{BDJbJOn}\",[]]Ac[\"{AHA`c{}}\",[\"T\"]]0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Ao[\"{c{{K@h{e}}}{}{}}\",[\"U\",\"T\"]]00000000000000000000000000000000000000000000000Al[\"{CKh{{K@h{KBdBF@`}}}}\",[]]Al[\"{JLf{{K@h{KBdBF@`}}}}\",[]]2Al[\"{HMj{{K@h{KBdBF@`}}}}\",[]]33333333333333Aj[\"{AAG`{{K@h{ANG`}}}}\",[]]444444Ai[\"{CKh{{K@h{AGFb}}}}\",[]]55555555555555555555555555555Bb[\"{{{Nl{AOFf}}}{{K@h{BDAl}}}}\",[]]Aj[\"{AOFf{{K@h{BDAl}}}}\",[]]77Bb[\"{{{Nl{AOLh}}}{{K@h{BDB`}}}}\",[]]Aj[\"{AOLh{{K@h{BDB`}}}}\",[]]999999999999999999999Al[\"{JLf{{K@h{KBfBF@b}}}}\",[]]Al[\"{HMj{{K@h{KBfBF@b}}}}\",[]]Al[\"{CKh{{K@h{KBfBF@b}}}}\",[]]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Bm[\"{AOFf{{K@h{BDAnc}}}{}}\",[\"TryFrom::Error\"]]Ce[\"{{{Nl{AOFf}}}{{K@h{BDAnc}}}{}}\",[\"TryFrom::Error\"]]Ao[\"{c{{K@h{e}}}{}{}}\",[\"U\",\"T\"]]0Ce[\"{{{Nl{AOLh}}}{{K@h{BDBbc}}}{}}\",[\"TryFrom::Error\"]]Bm[\"{AOLh{{K@h{BDBbc}}}{}}\",[\"TryFrom::Error\"]]22222222222222222222222Aj[\"{{}{{K@h{c}}}{}}\",[\"U\"]]0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cd[\"{{{AAb{{AHA`{CDfc}}}}{AHA`{CDfNAh}}}CNh{}}\",[\"F\"]]000000000Cc[\"{{{AHA`{BAJl}}AIBf{AHA`{AAKl}}}{{K@j{HMl}}}}\",[]]Bk[\"{{{AHA`{BFF`}}AOHf}{{K@h{HMlAHN`}}}}\",[]]Bk[\"{{{AHA`{BFFb}}AOHh}{{K@h{HMlAHNb}}}}\",[]]0Bk[\"{{{AHA`{BGFf}}AOHh}{{K@h{HMlAHNb}}}}\",[]]Ak[\"{{{AHA`{AHLn}}}AAEl}\",[]]Bi[\"{{{AHA`{CDfAOMj}}}{{K@h{KBdI@b}}}}\",[]]Bi[\"{{{AHA`{CDfAOMj}}}{{K@h{CNnI@b}}}}\",[]]Bh[\"{{{AHA`{CDfAOMj}}}{{K@h{OjI@b}}}}\",[]]Bj[\"{{{AHA`{CDfAOMj}}}{{K@h{AAJdI@b}}}}\",[]]Bf[\"{{{AHA`{CDfAOMj}}}{{K@n{KBf}}}}\",[]]Bf[\"{{{AHA`{CDfAOMj}}}{{K@n{CO`}}}}\",[]]Be[\"{{{AHA`{CDfAOMj}}}{{K@n{Ol}}}}\",[]]Bg[\"{{{AHA`{CDfAOMj}}}{{K@n{AAJf}}}}\",[]]Aa[\"{ANEfBEOn}\",[]]Bc[\"{{{AHA`{AHMb}}}{{Od{AHMb}}}}\",[]]Ba[\"{{{AHA`{Nn}}}{{Od{AHMb}}}}\",[]]Bb[\"{{{AHA`{HNj}}}{{Od{AHMb}}}}\",[]]Bb[\"{{{AHA`{NCf}}}{{Od{AHMb}}}}\",[]]Bc[\"{{{AHA`{AHMd}}}{{Od{AHMd}}}}\",[]]Ba[\"{{{AHA`{O`}}}{{Od{AHMd}}}}\",[]]Bb[\"{{{AHA`{HNl}}}{{Od{AHMd}}}}\",[]]Bb[\"{{{AHA`{NCh}}}{{Od{AHMd}}}}\",[]]A`[\"{AAKnCKh}\",[]]An[\"{{{AHA`{CDfAHM`}}}AGEd}\",[]]A`[\"{AAL`CKh}\",[]]C`[\"{{{AHA`{CDfAOHf}}}{{AHA`{CDf{JJ`{Nb}}}}}}\",[]]C`[\"{{{AHA`{CDfAOHh}}}{{AHA`{CDf{JJ`{Nb}}}}}}\",[]]Ah[\"{Nb{{JOn{AOI`}}}}\",[]]Ah[\"{Nb{{JOn{AOIb}}}}\",[]]Ah[\"{Nb{{JOn{AOId}}}}\",[]]A`[\"{AAJdCNn}\",[]]A`[\"{AAJfCO`}\",[]]Bi[\"{AHLj{{K@h{{JLd{AHLnBBI`}}AHLj}}}}\",[]]Aa[\"{{}c{}}\",[\"I\"]]o[\"{CNnD@`}\",[]]o[\"{CO`D@`}\",[]]Aj[\"{{{AHA`{AHM`}}}D@`}\",[]]21Aj[\"{{{AHA`{AAGl}}}D@`}\",[]]Aj[\"{{{AHA`{AAGn}}}D@`}\",[]]Bn[\"{{{AHA`{CDfAOLj}}D@`}{{AHA`{CDfAOLj}}}}\",[]]Bn[\"{{{AHA`{CDfAOLn}}D@`}{{AHA`{CDfAOLn}}}}\",[]]Bl[\"{{{AHA`{NDn}}NBj}{{AAb{{Od{AHKh}}}}}}\",[]]Bm[\"{{{AHA`{AOMh}}NBj}{{AAb{{Od{AHKh}}}}}}\",[]]Bm[\"{{{AHA`{ANHl}}NBj}{{AAb{{Od{AHKh}}}}}}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]Ak[\"{{{AHA`{AHLn}}}AAIb}\",[]]Bc[\"{{{AHA`{AHLn}}AIAbAHOf}AAId}\",[]]Ce[\"{{{AHA`{CDfAHM`}}AGF`AHOhNBj}{{K@h{K@dAGGl}}}}\",[]]43Bm[\"{{{AHA`{CDfAHM`}}K@d}{{K@h{HMlAHLf}}}}\",[]]E`[\"{{{AAb{{AHA`{CDfBCMn}}}}{AHA`{CDfNAh}}}{{CNh{{JOn{c}}}}}{}}\",[\"Stream::Item\"]]Ec[\"{{{AHA`{CDfAI@`}}{AHA`{CDfNAh}}{AHA`{CDf{JJ`{Nb}}}}}{{CNh{{K@h{JLfAGHj}}}}}}\",[]]E`[\"{{{AAb{{AHA`{CDfAI@`}}}}{AHA`{CDfNAh}}{AHA`{CDfNDh}}}{{CNh{{K@j{HMl}}}}}}\",[]]Ef[\"{{{AAb{{AHA`{CDfAI@`}}}}{AHA`{CDfNAh}}{AHA`{CDf{JJ`{Nb}}}}}{{CNh{{K@j{JLf}}}}}}\",[]]Fg[\"{{{AHA`{CDfBAEh}}{AHA`{CDfNAh}}{AHA`{CDf{JJ`{AHNd}}}}{AHA`{CDf{JJ`{AAJ`}}}}}{{CNh{{K@j{JLf}}}}}}\",[]]Dn[\"{{{AAb{{AHA`{CDfAGI`}}}}{AHA`{AAKl}}{AHA`{CDfNAh}}}{{CNh{{K@j{HMl}}}}}}\",[]];:Cd[\"{{{AHA`{CDfBAG`}}{Nl{NBd}}}{{AHA`{CDfBAG`}}}}\",[]]Cd[\"{{{AHA`{CDfBAGb}}{Nl{NBf}}}{{AHA`{CDfBAGb}}}}\",[]]Cj[\"{{{AHA`{AOLl}}CKfAOHf{AHA`{{JJ`{Nb}}}}}{{ICh{Nb}}}}\",[]]Cj[\"{{{AHA`{BDB`}}CKfAOHf{AHA`{{JJ`{Nb}}}}}{{ICh{Nb}}}}\",[]]Cj[\"{{{AHA`{AOM`}}CKfAOHh{AHA`{{JJ`{Nb}}}}}{{ICh{Nb}}}}\",[]]Cj[\"{{{AHA`{BDBb}}CKfAOHh{AHA`{{JJ`{Nb}}}}}{{ICh{Nb}}}}\",[]]Cj[\"{{{AHA`{BGA`}}CKfAOHd{AHA`{{JJ`{Nb}}}}}{{ICh{Nb}}}}\",[]]Bb[\"{JLf{{JLd{JLf{JOn{JLf}}}}}}\",[]]000Aj[\"{{{AHA`{AHLn}}}JLf}\",[]]A`[\"{AHA`KB`}\",[]]0000000000000000000000000000000000000000000000000000000000000Ce[\"{{{AHA`{CDfAOLj}}{Nl{BDJd}}}{{AHA`{CDfAOLj}}}}\",[]]Ce[\"{{{AHA`{CDfAOLn}}{Nl{BDJf}}}{{AHA`{CDfAOLn}}}}\",[]]A`[\"{BFKdIAh}\",[]]o[\"{AOLjNl}\",[]]o[\"{AOLnNl}\",[]]Aj[\"{{{AHA`{AAGd}}}HMl}\",[]]Ck[\"{{{AHA`{CDfAI@l}}{AHA`{{JJ`{Nb}}}}}{{K@h{HMlAIBh}}}}\",[]]n[\"{{}JLf}\",[]]Ak[\"{{{AHA`{AHLn}}}AGCh}\",[]]Ba[\"{{{AHA`{CDfAAKn}}AAKn}HMl}\",[]]Ba[\"{{{AHA`{CDfAHMj}}AHMj}HMl}\",[]]Ba[\"{{{AHA`{CDfBBF`}}AGHd}HMl}\",[]]Ba[\"{{{AHA`{CDfAAL`}}AAL`}HMl}\",[]]Ba[\"{{{AHA`{CDfAHMl}}AHMl}HMl}\",[]]Ba[\"{{{AHA`{CDfBBFb}}AGHf}HMl}\",[]]Bn[\"{{{AHA`{CDfBBHf}}D@`}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}D@`}{{AHA`{CDfBBHh}}}}\",[]]Bi[\"{{{AHA`{CDf}}}{{AHA`{CDfc}}}{}}\",[\"T\"]]0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bc[\"{{AHA`{AHA`{CDfc}}}HMl{}}\",[\"T\"]]0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cc[\"{{{AHA`{CDfAHM`}}NBjK@dKBf}{{K@h{HMlBAEn}}}}\",[]]A`[\"{AGDnD@`}\",[]]B`[\"{{AHA`{AHA`{c}}}D@`{}}\",[\"K\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Aa[\"{BBEbBEBn}\",[]]A`[\"{BCNbKBd}\",[]]Aa[\"{BBEfBEC`}\",[]]A`[\"{BCNfKBf}\",[]]A`[\"{BDIdKBf}\",[]]A`[\"{BBGhKBf}\",[]]o[\"{NEdKBf}\",[]]Aa[\"{BBEbAHNf}\",[]]Aa[\"{BBEfAHNh}\",[]]o[\"{KBdCKh}\",[]]o[\"{KBfCKh}\",[]]Aj[\"{{{AHA`{AHM`}}}D@`}\",[]]Aj[\"{{{AHA`{B@I`}}}D@`}\",[]]Bd[\"{{{AHA`{BAEh}}}{{K@j{AIAb}}}}\",[]]Bd[\"{{{AHA`{AAGd}}}{{K@j{AIAb}}}}\",[]]A`[\"{AGHdCKh}\",[]]A`[\"{AGHfCKh}\",[]]Cb[\"{{{AHA`{BBFj}}{AHA`{AI@j}}CKh}{{Nl{ANIh}}}}\",[]]Bn[\"{{{AHA`{CDfBBHf}}D@`}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}D@`}{{AHA`{CDfBBHh}}}}\",[]]Bg[\"{{{AHA`{AHLn}}K@b}{{JOn{AGHd}}}}\",[]]Bj[\"{{{AHA`{CDfAHM`}}K@d}{{JOn{AGHf}}}}\",[]]o[\"{AGEhOd}\",[]]Db[\"{{{AAb{{AHA`{CDfAI@l}}}}{AHA`{CDfNAh}}}{{CNh{{K@j{HMl}}}}}}\",[]]00Ec[\"{{{AAb{{AHA`{CDfAI@l}}}}{AHA`{CDfNAh}}{AHA`{{JJ`{Nb}}}}}{{CNh{{K@j{JLf}}}}}}\",[]]0Eg[\"{{{AAb{{AHA`{CDfAI@l}}}}{AHA`{CDfNAh}}{AHA`{{JJ`{Nb}}}}}{{CNh{{K@h{JLfAIBh}}}}}}\",[]]Bm[\"{{{AHA`{IBn}}{AHA`{CMn}}}{{K@j{HMl}}}}\",[]]Cd[\"{{{AHA`{CDfAI@`}}JLf}{{K@h{{JOn{HNb}}AGHj}}}}\",[]]Cd[\"{{{AHA`{CDfBEHl}}JLf}{{K@h{{JOn{HNb}}AGHj}}}}\",[]]Cn[\"{{{AHA`{CDfAI@`}}{AHA`{CDf{JJ`{Nb}}}}}{{K@h{HMlBAIn}}}}\",[]]Bj[\"{{{AHA`{CN`}}AHOf}{{K@h{HMlBEBd}}}}\",[]]Bn[\"{{{AHA`{CDfAHOj}}NBj}{{AHA`{CDfAHOj}}}}\",[]]Bn[\"{{{AHA`{CDfAHOl}}NBj}{{AHA`{CDfAHOl}}}}\",[]]A`[\"{BAJdAFb}\",[]]o[\"{IBlCKh}\",[]]o[\"{{}AIAb}\",[]]0o[\"{{}AHA`}\",[]]Bj[\"{{AAGl{Nl{AOLj}}}{{K@h{AHLjBBEh}}}}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]Bh[\"{{{AHA`{AGDn}}AIAb}{{K@l{AGIb}}}}\",[]]A`[\"{AGHdCKd}\",[]]Aj[\"{{{AHA`{AHM`}}}CKd}\",[]]A`[\"{AGHfCKd}\",[]]Ce[\"{{{AHA`{CDfAHOj}}{JOn{KB`}}}{{AHA`{CDfAHOj}}}}\",[]]Ce[\"{{{AHA`{CDfAHOl}}{JOn{KB`}}}{{AHA`{CDfAHOl}}}}\",[]]Aa[\"{AAKhAIAb}\",[]]Aa[\"{AAKjAIAb}\",[]]Aa[\"{AAKlAIAb}\",[]]Aa[\"{AIAbAGF`}\",[]]o[\"{A@jCKd}\",[]]Bn[\"{{{AHA`{CDfBBHf}}CKd}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}CKd}{{AHA`{CDfBBHh}}}}\",[]]A`[\"{AGDnCKd}\",[]]Bo[\"{{{AHA`{CDfBBHf}}AAG`}{{AHA`{CDfBBHf}}}}\",[]]Bo[\"{{{AHA`{CDfBBHh}}AAG`}{{AHA`{CDfBBHh}}}}\",[]]A`[\"{AGDnJOn}\",[]]k[\"{{}}\",[]]0000000000Bh[\"{AAGlc{}}\",[\"IntoFuture::IntoFuture\"]]11A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]o[\"{A@jJLf}\",[]]Ao[\"{{AHA`c}{{NC`{c}}}{}}\",[\"S\"]]0C`[\"{{{AHA`{CDfAHMb}}NBjCKhD@`{JOn{CKh}}}HMl}\",[]]Bn[\"{{{AHA`{CDfNn}}NBjCKhD@`{JOn{CKh}}}HMl}\",[]]C`[\"{{{AHA`{CDfAHMd}}NBjCKhD@`{JOn{CKh}}}HMl}\",[]]Bn[\"{{{AHA`{CDfO`}}NBjCKhD@`{JOn{CKh}}}HMl}\",[]]Bk[\"{{{AHA`{CDfIBn}}NBj{AHA`{BBFj}}}HMl}\",[]]A`[\"{BDJ`JOn}\",[]]A`[\"{BDJbJOn}\",[]]Bn[\"{{{AHA`{KBd}}{AHA`{KBd}}}{{JOn{AAIf}}}}\",[]]Bn[\"{{{AHA`{K@b}}{AHA`{K@b}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{ANG`}}{AHA`{ANG`}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{AOHf}}{AHA`{AOHf}}}{{JOn{AAIf}}}}\",[]]Bn[\"{{{AHA`{CNn}}{AHA`{CNn}}}{{JOn{AAIf}}}}\",[]]Bl[\"{{{AHA`{Oj}}{AHA`{Oj}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{AAJd}}{AHA`{AAJd}}}{{JOn{AAIf}}}}\",[]]Bn[\"{{{AHA`{KBf}}{AHA`{KBf}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{BDKj}}{AHA`{BDKj}}}{{JOn{AAIf}}}}\",[]]Bn[\"{{{AHA`{K@d}}{AHA`{K@d}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{AGHl}}{AHA`{AGHl}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{B@Lf}}{AHA`{B@Lf}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{AIBj}}{AHA`{AIBj}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{ANGb}}{AHA`{ANGb}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{BCNn}}{AHA`{BCNn}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{BDKb}}{AHA`{BDKb}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{AOHh}}{AHA`{AOHh}}}{{JOn{AAIf}}}}\",[]]Bn[\"{{{AHA`{CO`}}{AHA`{CO`}}}{{JOn{AAIf}}}}\",[]]Bl[\"{{{AHA`{Ol}}{AHA`{Ol}}}{{JOn{AAIf}}}}\",[]]C`[\"{{{AHA`{AAJf}}{AHA`{AAJf}}}{{JOn{AAIf}}}}\",[]]Be[\"{{{AHA`{AHLn}}}{{AAIl{AGH`}}}}\",[]]Bk[\"{{{AHA`{AHM`}}K@d}{{K@h{AHOhAHLf}}}}\",[]]Df[\"{{{AHA`{CDfAI@`}}{AHA`{CDf{JJ`{HN`}}}}}{{K@h{{JOn{JLf}}AGHj}}}}\",[]]Cc[\"{{{AHA`{CDfAI@`}}JLf}{{K@h{{AAh{Nb}}BAJ`}}}}\",[]]Bb[\"{{{AHA`{CDfAHM`}}AAJf}AI@b}\",[]]Aj[\"{{{AHA`{AGFh}}}JLf}\",[]]Aj[\"{{{AHA`{AGFj}}}JLf}\",[]]Bb[\"{{{AHA`{CDfAHM`}}AAJf}AI@n}\",[]]Bn[\"{{{AHA`{CDfBBHf}}CKh}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}CKh}{{AHA`{CDfBBHh}}}}\",[]]A`[\"{AGDnJOn}\",[]]A`[\"{B@IfJOn}\",[]]A`[\"{B@IhJOn}\",[]]Ce[\"{{{AHA`{CDfAOLj}}{Nl{AIAj}}}{{AHA`{CDfAOLj}}}}\",[]]Ce[\"{{{AHA`{CDfAOLn}}{Nl{AIAl}}}{{AHA`{CDfAOLn}}}}\",[]]Ce[\"{{{AHA`{CDfAOFh}}{Nl{AIBb}}}{{AHA`{CDfAOFh}}}}\",[]]Ce[\"{{{AHA`{CDfAOFl}}{Nl{AIBd}}}{{AHA`{CDfAOFl}}}}\",[]]o[\"{A@jCKh}\",[]]Bn[\"{{{AHA`{CDfBE@f}}CKd}{{AHA`{CDfBE@f}}}}\",[]]Bn[\"{{{AHA`{CDfBE@h}}CKd}{{AHA`{CDfBE@h}}}}\",[]]Ak[\"{{{AHA`{AHLn}}}BF@f}\",[]]Aj[\"{{{AHA`{CN`}}}BAJn}\",[]]Ai[\"{{{Nl{AOLl}}}AOLj}\",[]]Ai[\"{{{Nl{AOM`}}}AOLn}\",[]]Aj[\"{{BBGdc}BBGdAAJn}\",[\"\"]]Aj[\"{{BBGfc}BBGfAAJn}\",[\"\"]]Bm[\"{{{AHA`{CDfAI@l}}HN`}{{K@h{HMlAIBh}}}}\",[]]n[\"{{}JOb}\",[]]o[\"{NAfNAf}\",[]]0000Bd[\"{{{AHA`{BFF`}}}{{JOn{AAG`}}}}\",[]]Bd[\"{{{AHA`{BFFb}}}{{JOn{AAG`}}}}\",[]]Bd[\"{{{AHA`{BGFf}}}{{JOn{AAG`}}}}\",[]]Bd[\"{{{AHA`{BGG`}}}{{JOn{AAG`}}}}\",[]]Bd[\"{{{AHA`{AHLn}}}{{JOn{BBEh}}}}\",[]]Ck[\"{{{AHA`{AAGd}}AOFhAIAb{AHA`{CKb}}}{{K@h{AHLjAOH`}}}}\",[]]Ak[\"{{{AHA`{AOLb}}}AAG`}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]An[\"{{AHOnD@`}{{K@l{JLf}}}}\",[]]Cj[\"{{{AHA`{NE`}}}{{JOn{{JLd{{Od{AGFh}}{Od{AGGf}}}}}}}}\",[]]Ck[\"{{{AHA`{AIAn}}}{{JOn{{JLd{{Od{AGFh}}{Od{AGGf}}}}}}}}\",[]]Cj[\"{{{AHA`{NEb}}}{{JOn{{JLd{{Od{AGFj}}{Od{AGGh}}}}}}}}\",[]]Ck[\"{{{AHA`{AIB`}}}{{JOn{{JLd{{Od{AGFj}}{Od{AGGh}}}}}}}}\",[]]A`[\"{BENjAAh}\",[]]A`[\"{BGJdAAh}\",[]]A`[\"{BENlAAh}\",[]]A`[\"{BGJfAAh}\",[]]An[\"{{{AHA`{CDfBFF`}}}AOHf}\",[]]An[\"{{{AHA`{CDfBFFb}}}AOHh}\",[]]An[\"{{{AHA`{CDfBGFf}}}AOHh}\",[]]An[\"{{{AHA`{CDfBGG`}}}AOHh}\",[]]Ak[\"{{{AHA`{BAJl}}}AOJh}\",[]]Ba[\"{{{AHA`{CDfAHM`}}BBEn}HMl}\",[]]Bo[\"{{{AHA`{CDfAAGf}}BCNnB@I`}{{JOn{BBEn}}}}\",[]]B`[\"{{{AHA`{NE`}}AOHfCNn}CMd}\",[]]Bn[\"{{{AHA`{AOLl}}CKfAOHf}{{K@h{CMdBECf}}}}\",[]]Ba[\"{{{AHA`{AIAn}}AOHfCNn}CMd}\",[]]Bn[\"{{{AHA`{BDB`}}CKfAOHf}{{K@h{CMdBECf}}}}\",[]]B`[\"{{{AHA`{NEb}}AOHhCO`}CMf}\",[]]Bn[\"{{{AHA`{AOM`}}CKfAOHh}{{K@h{CMfBECl}}}}\",[]]Ba[\"{{{AHA`{AIB`}}AOHhCO`}CMf}\",[]]Bn[\"{{{AHA`{BDBb}}CKfAOHh}{{K@h{CMfBECl}}}}\",[]]Bn[\"{{{AHA`{BGA`}}CKfAOHd}{{K@h{CMfBECl}}}}\",[]]Aj[\"{{}{{NDj{c}}}{}}\",[\"T\"]]0A`[\"{AGHdCKh}\",[]]A`[\"{AGHfCKh}\",[]]Bn[\"{{{AHA`{CDfAOLj}}JLf}{{AHA`{CDfAOLj}}}}\",[]]Bn[\"{{{AHA`{CDfAOLn}}JLf}{{AHA`{CDfAOLn}}}}\",[]]Aj[\"{{{AHA`{BAEh}}}D@`}\",[]]0Aj[\"{{{AHA`{BAJl}}}D@`}\",[]]Bk[\"{{{AHA`{AHM`}}K@d}{{K@h{AGF`AHLf}}}}\",[]]Cb[\"{{{AHA`{BBFj}}{AHA`{AHOn}}CKh}{{Nl{ANIh}}}}\",[]]Ak[\"{{{AHA`{AAGl}}}AOHf}\",[]]Ak[\"{{{AHA`{AAGn}}}AOHh}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]Bf[\"{{{AHA`{CDfAHM`}}}{{JOn{NBj}}}}\",[]]Ce[\"{{{AHA`{CDfBBHf}}{Nl{ANGn}}}{{AHA`{CDfBBHf}}}}\",[]]Ce[\"{{{AHA`{CDfBBHh}}{Nl{ANH`}}}{{AHA`{CDfBBHh}}}}\",[]]43A`[\"{A@jANHf}\",[]]A`[\"{AAKhJOn}\",[]]A`[\"{AAKjJOn}\",[]]A`[\"{AAKlJOn}\",[]]Ai[\"{{{AHA`{NF`}}}JLf}\",[]]Bo[\"{{{AHA`{CDfBGFf}}AAG`}{{AHA`{CDfBGFf}}}}\",[]]Bo[\"{{{AHA`{CDfBGG`}}AAG`}{{AHA`{CDfBGG`}}}}\",[]]Bj[\"{{{AHA`{AI@l}}CC`}{{K@h{HMlAOGd}}}}\",[]]Bm[\"{{{AHA`{CDfAI@n}}CC`}{{K@h{HMlAOGl}}}}\",[]]==E`[\"{{{AHA`{BFKf}}{AHA`{{JJ`{Nb}}}}{AHA`{BAEj}}{AHA`{BFFd}}}{{K@h{BFMlHOn}}}}\",[]]0Bf[\"{{{Nl{B@Ll}}}{{K@h{AOFhBF@d}}}}\",[]]Bf[\"{{{Nl{B@Ll}}}{{K@h{AOFlBF@d}}}}\",[]]Bn[\"{{{AHA`{CDfBDNh}}KBd}{{AHA`{CDfBDNh}}}}\",[]]Bn[\"{{{AHA`{CDfBDNj}}KBf}{{AHA`{CDfBDNj}}}}\",[]]o[\"{NAfNAf}\",[]]0000Aj[\"{{{AHA`{AHM`}}}D@`}\",[]]0Ci[\"{{{AHA`{CN`}}{JOn{AAG`}}}{{K@h{{JOn{AAG`}}AHL`}}}}\",[]]Cd[\"{{{AHA`{CDfA@j}}{AHA`{AHKf}}}{{K@h{HMlI@`}}}}\",[]]Cc[\"{{{AHA`{CDfOh}}{AHA`{AHKf}}}{{K@h{HMlI@`}}}}\",[]]Ce[\"{{{AHA`{CDfAAFb}}{AHA`{AHKf}}}{{K@h{HMlI@`}}}}\",[]]Ce[\"{{{AHA`{CDfAGDn}}{AHA`{AHKf}}}{{K@h{HMlI@`}}}}\",[]]Cd[\"{{{AHA`{CDfA@l}}{AHA`{AHKf}}}{{K@h{HMlI@`}}}}\",[]]Cd[\"{{{AHA`{CDfA@n}}{AHA`{AHKf}}}{{K@h{HMlI@`}}}}\",[]]Bo[\"{{{AHA`{CDfAOLj}}BFGb}{{AHA`{CDfAOLj}}}}\",[]]Bo[\"{{{AHA`{CDfAOLn}}BFGd}{{AHA`{CDfAOLn}}}}\",[]]Aj[\"{{{AHA`{BAG`}}}CKh}\",[]]Aj[\"{{{AHA`{BAGb}}}CKh}\",[]]Cc[\"{{{AHA`{CDfAOFh}}{Nl{A`}}}{{AHA`{CDfAOFh}}}}\",[]]Cc[\"{{{AHA`{CDfAOFl}}{Nl{A`}}}{{AHA`{CDfAOFl}}}}\",[]]Cj[\"{{BAG`{JOn{AOLj}}{Od{BAEh}}{Nl{NDn}}}{{K@j{AAGd}}}}\",[]]Aj[\"{{{AHA`{AAGl}}}D@`}\",[]]Aj[\"{{{AHA`{AAGn}}}D@`}\",[]]Ca[\"{{{AHA`{CDfAHM`}}NBjAHNl}{{K@h{HMlBFJl}}}}\",[]]Bd[\"{{{AHA`{BFKf}}}{{AAh{BBGl}}}}\",[]]Bj[\"{{{AHA`{AHLn}}AIAb}{{K@h{HMlI@j}}}}\",[]]Bm[\"{{{AHA`{CDfAHM`}}AIAb}{{K@h{HMlI@j}}}}\",[]]Bn[\"{{{AHA`{CDfBBHf}}JLf}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}JLf}{{AHA`{CDfBBHh}}}}\",[]]Bl[\"{{}{{K@h{{JLd{BAEjBEAb}}{Od{HOf}}}}}}\",[]]Ai[\"{AHLl{{K@l{HMl}}}}\",[]]A`[\"{AHMjCKh}\",[]]A`[\"{AHMlCKh}\",[]]An[\"{{{AHA`{AAGd}}AOFh}HMl}\",[]]D`[\"{{{AHA`{CDfAHM`}}K@d{JOn{AAG`}}}{{K@h{{JOn{AAG`}}AHLf}}}}\",[]]o[\"{{}AHA`}\",[]]Aj[\"{{{AHA`{AHLn}}}JLf}\",[]]Bn[\"{{{AHA`{CDfAOLj}}CKh}{{AHA`{CDfAOLj}}}}\",[]]Bn[\"{{{AHA`{CDfAOLn}}CKh}{{AHA`{CDfAOLn}}}}\",[]]Bn[\"{{{AHA`{CDfBBHf}}KBd}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}KBf}{{AHA`{CDfBBHh}}}}\",[]]:Bb[\"{{{AHA`{CDfAHM`}}OlKBf}HMl}\",[]]Ak[\"{{}{{K@h{AOFhI@d}}}}\",[]]Ak[\"{{}{{K@h{AOFlI@f}}}}\",[]]Bn[\"{{{AHA`{CDfBBHf}}D@`}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}D@`}{{AHA`{CDfBBHh}}}}\",[]]65Cg[\"{{{AHA`{CDfA@j}}{AHA`{CDfAHKf}}}{{K@h{HMlI@`}}}}\",[]]Cf[\"{{{AHA`{CDfOh}}{AHA`{CDfAHKf}}}{{K@h{HMlI@`}}}}\",[]]Ch[\"{{{AHA`{CDfAAFb}}{AHA`{CDfAHKf}}}{{K@h{HMlI@`}}}}\",[]]Ch[\"{{{AHA`{CDfAGDn}}{AHA`{CDfAHKf}}}{{K@h{HMlI@`}}}}\",[]]Cg[\"{{{AHA`{CDfA@l}}{AHA`{CDfAHKf}}}{{K@h{HMlI@`}}}}\",[]]Cg[\"{{{AHA`{CDfA@n}}{AHA`{CDfAHKf}}}{{K@h{HMlI@`}}}}\",[]]Bi[\"{{{AHA`{CDfAGF`}}{AHA`{AGF`}}}D@`}\",[]]n[\"{{}HMl}\",[]]Ce[\"{{{AHA`{CDfBBHf}}{JOn{JLf}}}{{AHA`{CDfBBHf}}}}\",[]]Ce[\"{{{AHA`{CDfBBHh}}{JOn{JLf}}}{{AHA`{CDfBBHh}}}}\",[]]Bn[\"{{{AHA`{AHLn}}}{{K@h{{AAh{AIAb}}I@j}}}}\",[]]Cd[\"{{{AHA`{CDfAHM`}}NBj}{{K@h{{AAh{AIAb}}I@j}}}}\",[]]Am[\"{{{AHA`{CDfAHMb}}}HMl}\",[]]Al[\"{{{AHA`{CDfHNj}}}HMl}\",[]]Am[\"{{{AHA`{CDfAHMd}}}HMl}\",[]]Al[\"{{{AHA`{CDfHNl}}}HMl}\",[]]Ai[\"{AHLl{{K@l{HMl}}}}\",[]]Bj[\"{{{AHA`{AHLn}}AIAb}{{K@h{HMlI@j}}}}\",[]]Bm[\"{{{AHA`{CDfAHM`}}AIAb}{{K@h{HMlI@j}}}}\",[]]D`[\"{{{AHA`{CDfAHM`}}K@d{JOn{AAG`}}}{{K@h{{JOn{AAG`}}AHLf}}}}\",[]]Ce[\"{{{AHA`{CDfBBHf}}{Nl{BDIl}}}{{AHA`{CDfBBHf}}}}\",[]]Ce[\"{{{AHA`{CDfBBHh}}{Nl{BDIn}}}{{AHA`{CDfBBHh}}}}\",[]]Cf[\"{{{AHA`{CDfBBHf}}{JOn{AAG`}}}{{AHA`{CDfBBHf}}}}\",[]]Cf[\"{{{AHA`{CDfBBHh}}{JOn{AAG`}}}{{AHA`{CDfBBHh}}}}\",[]]Aa[\"{B@IfAHNj}\",[]]Aa[\"{B@IhAHNj}\",[]]9Bn[\"{{{AHA`{CDfBBHf}}D@`}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}D@`}{{AHA`{CDfBBHh}}}}\",[]]Am[\"{{{AHA`{AHLn}}KBd}HMl}\",[]]o[\"{NAfNAf}\",[]]Bn[\"{{{AHA`{CDfBBHf}}CKf}{{AHA`{CDfBBHf}}}}\",[]]Bn[\"{{{AHA`{CDfBBHh}}CKf}{{AHA`{CDfBBHh}}}}\",[]]3109854Bn[\"{{{AHA`{AHLn}}}{{K@h{{AAh{AIAb}}I@j}}}}\",[]]Bn[\"{{{AHA`{AHM`}}}{{K@h{{AAh{AIAb}}I@j}}}}\",[]]10A`[\"{BEHjJOn}\",[]]Bm[\"{{{AHA`{CDfBBHf}}Nb}{{AHA`{CDfBBHf}}}}\",[]]Bm[\"{{{AHA`{CDfBBHh}}Nb}{{AHA`{CDfBBHh}}}}\",[]]o[\"{{}AHNl}\",[]]") \ No newline at end of file diff --git a/pr/545/docs/search.index/generic_inverted_index/5e5024c3d9da.js b/pr/545/docs/search.index/generic_inverted_index/5e5024c3d9da.js deleted file mode 100644 index 163e929dd..000000000 --- a/pr/545/docs/search.index/generic_inverted_index/5e5024c3d9da.js +++ /dev/null @@ -1 +0,0 @@ -rb_("QUxuADswAAABAADjAAIASQPiAOkLAAA7MAAAAQAATgInAAwCFQAjAgsAMgIBADUCAAA3AgIAOwIAAD8CBgBLAgIATwIGAFkCBABfAgUAZwIAAGkCAQBsAgIAcAIEAHYCDACEAgMAkwIWAK4CAACwAgMAtQIRAMgCBADOAgQA1AIEANsCBADhAgQA5wIGAO8CBQD3AgUA/gIFAAUDAgAJAwMAEQMAABkDCwAmAw0ALAmFAKcK4gBtDwAAFBABADswAAABAADIAQ4AjwACAJcF4gCyCS8A5AkAAOYJDQD1CQUA/AkcABsKAQAfChQANwoeAFcKBgBfCioAjAoBAJAKFgA7MAAAAQAAEQELAE4CAAC0AgAAJQMAAEMHEwBWCgAAXgoAAIoKAACPCgAADw7yAHMPAQCrDwEAOzAAAAEAAHMBBgAyBAAA+AgBAIsKAACOCgAAngxoARwRBQA7MAAAAQAABgACAJcGAwCcBgIAOzAAAAEAACkABQA0AxQAZQUAAJIGBACgBgwA8wgBADswAAABAAAKAAIATwQAAIoLCQA7MAAAAQAADAABAD4EDAAB/wsAAAIIEQAACREAAAACcBAAAHEQAAAAArsBAACbBgAAQ24AAAA7MAAAAQAA4gAMALIJLwDkCQAA5gkNAPUJBQD8CRwAGwoBAB8KFAA3Ch4AVwoGAF8KKgCMCgEAkAoWAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/generic_inverted_index/af48d3aa5b7a.js b/pr/545/docs/search.index/generic_inverted_index/af48d3aa5b7a.js new file mode 100644 index 000000000..814955c52 --- /dev/null +++ b/pr/545/docs/search.index/generic_inverted_index/af48d3aa5b7a.js @@ -0,0 +1 @@ +rb_("QU5gADswAAABAADnAAIAVAPmAAkMAAA7MAAAAQAAVwIoABMCFgArAg4AOwIAAD4CAABBAgMASAIAAEoCBgBWAgMAWwIFAGMCAABlAgMAagIFAHICAAB0AgIAeAIBAHsCBACBAgsAjgIDAJ0CFwC5AgAAuwIDAMACEQDTAgQA2QIEAN8CBADmAgQA7AIEAPICBgD6AgUAAgMFAAkDBQAQAwIAFAMDABwDAAAkAwsAMQMNAEMJhgDDCuYAmg8AAEIQAQA7MAAAAQAA0AEOAJAAAgCoBeYAygkzAAAKAAACCg4AEgoEABgKGwA2CgIAOwoUAFMKHgBzCgYAewoqAKgKAQCsChYAOzAAAAEAABQBCwBaAgAAvwIAADADAABYBxMAcgoAAHoKAACmCgAAqwoAADkO9QCgDwEA2A8BADswAAABAAB4AQYAQQQAAA8JAQCnCgAAqgoAAMMMbQFMEQUAOzAAAAEAAAYAAgCsBgMAsQYCADswAAABAAApAAUAPwMUAHUFAACnBgQAtQYMAAoJAQA7MAAAAQAACgACAF4EAACqCwkAOzAAAAEAAAwAAQBNBAwAOzAAAAEAAAUAAgAfDAMA1BABAAI4EQAAOREAAAACnhAAAJ8QAAAAAsIBAACwBgAAQ24AAAA7MAAAAQAA5gAMAMoJMwAACgAAAgoOABIKBAAYChsANgoCADsKFABTCh4AcwoGAHsKKgCoCgEArAoWAA==") \ No newline at end of file diff --git a/pr/545/docs/search.index/name/c4d5f34d78f6.js b/pr/545/docs/search.index/name/c4d5f34d78f6.js deleted file mode 100644 index 8fd3c6bf4..000000000 --- a/pr/545/docs/search.index/name/c4d5f34d78f6.js +++ /dev/null @@ -1 +0,0 @@ -rd_("b()b->bBi0bCe00bFnbIdbOkb[]beq000000000000000000000000000000000000000000000000000000000000000000000000000000000000bid0000000000000brtbtybu8cAck0cAddcAnycArccBbr00cBoxcBufcClicDir0cErrcMAX000cNotcOpt00cOrdcPincUni0cVeccadd00000cbbrccmp0000000000000000000cdir000cecn000cf32cf64cfmt000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cgetci32cimpcios0clen000clog0cmincmutcnew000000000000000000000000000000000000cnoqcnot0cnow000000crtt000crun0cstrcu16cu32cu64cudpdArgsdAsFddDropdEct000dEct100dFromdHashdIntodKeys0dLong0dNonedPath00dPing0dPolldReaddSenddSide0dSyncdZERO0dacks0daddr0dbooldbulkdcodedcwnd0ddataddrop000000dfrom0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dhash00000000000000000000dinto0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dmain0000dnext0dopen00dpath0dperfdping000dpoll00000000000000dqlogdread00drecv00dseal0dsend00dsent0dside0dsign0dsize00dsmoldspindstop00dtake00000du128duniteAsRefeByteseChunk0eCloneeCloseeCubic00eDebugeDerefeError00000000000eEvent00eKnowneOther0eRangeeReset000eRetry0eShort0eSizedeStats0eSuiteeTokioeWriteealpnsearrayebenchebuild00000000ebytes00000ecauseeclone0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eclose000ecubicederef0eerroreframe0eindex0eis_ce0elocal0eparse0epaths0eprint00ereset00eretry0esliceespawn00estats000000000etitle0etokenetokioetupleeusizeewrite00fAcceptfAckEcn0fAes128fAes256fBackupfBorrowfBufMutfChunksfClient00fClosedfCrypto0fCursorfFuturefHasherfIpAddrfOpenBifOpened000fOptionfOutputfPathId0fResult00000fServer00fStream000fStringfTypeIdfVarInt0faccept000fborrow0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fchunks0fcipherfclient0000fclosedfcoding0fconfig0fcrypto0000000000fdecode000000000000fdst_ipfencode000000000000ffinish00fhandlefheader0fignore0finsert00000fkeylogfoffset0fon_ack0000000fpacket00frandomfreason000000frebindfrefuse0fremote00frustls00000fserver0000fsharedfsource00000000fsrc_ip00fstatus0fstream0fstridefudp_rx000fudp_tx000fvarintfverify0fwindow0000000gBlocked00gCommandgContextgDefaultgDisplaygFromStrgGeneral0gHmacKey0gInitialgInstantgKeyPair0gLayeredgMaxData0gNewReno00gOpenUnigPadding0gPathAck0gPathBufgReadBufgRequestgRuntime0gSession0gStopped00000gStreamsgToOwnedgTooLonggTryFromgTryIntogUnknowngWritten0gZeroRttgcid_len000gclientsgcommand00000gcompare0000000000000000000gconnect0gdecrypt00000gdefault000000000000000000000000000000000000000000000000000gdrainedgdst_cid0000000gencrypt000gis_0rtt0gmetrics0000000gmin_mtu0gnoq_udpgon_sent000gopen_bigpath_idgpointergruntimegsrc_cid0000gstopped0gstreams000gtag_len0gtype_id0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000gupgrade0gversion00000hAcceptBihBytesMuthChacha20hCommandshDatagram00hDerefMuthDisabled0hDurationhEndpoint00hFinished0hIncoming0hIteratorhLayerExthLongTypehMAX_SIZE0hNO_ERROR0hNewToken0hOnClosedhOpenPathhOrderinghReadable0hReceiver0hRecvMetahResponsehStreamId0hTimedOut00hToStringhTokenLog0hTooLarge0hTransmit00hUdpStats0hUnixTimehWritable0hcong_alghcontentshdatagram0hdurationhendpoint0hfinalizehframe_rx000hframe_tx000hfrom_buf0hfrom_env0hfrom_keyhfrom_str0hfrom_u320hfrom_u640hgot_type000hgroup_id0000hhas_0rtthincominghinterval0hinto_any0000000his_alivehlifetime0hlocal_ip0000hmax_data0hmax_sizehnew_renohnoq_perfhon_byteshopen_unihpriority0hprotocol0hqlog_dirhresponsehrng_seed0hssthresh0hto_owned0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000htry_from0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000htry_into0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000htry_poll000000000htry_sendhvalidate000iAbandoned0iAcceptUniiAddAssigniArbitraryiAsyncRead0iAvailable00iBbrConfig0iBorrowMutiCommonOptiConnectediCriterioniDatagramsiDecodableiDiscarded0iEncodableiFormatteriFourTupleiFrameType0iHandshakeiHeaderKey0iHistogramiMalformediMaxPathId0iMultipathiPacketKey0iPartialEqiPathErroriPathEvent00iPathStats0iReadError00iTryFutureiUdpSenderiUdpSocketiValueEnumiaccept_biiarbitrary0000000ias_rustlsiassemblericlone_box0000000idatagrams000ideref_mut0ifrom_bits00iinitiator0iinto_0rttiinto_iteriis_client0iis_closediis_server0imay_retry0imigration0inew_timer00inew_token0inoq_protoion_closediopen_path0ipath_acks0iping_pathipoll_nextipoll_read00ipoll_recvipoll_sendireach_out0ireferenceireset_key0iretry_tag0000isize_hint000istable_idito_string0000000000000000000000000000000000000000000000000000000000000itoken_key0itoken_positransport00iwait_idleiwrite_alljArgMatchesjAsyncTimerjAsyncWrite0jBATCH_SIZEjClosedPath000jComparablejConnectingjConnection00jController0jEquivalent0jFrameStats0jIntoFuturejInvalidCid0jIoSliceMutjMaybeFrame0jNamedGroupjNonZeroU32jOtherErrorjPartialOrdjPathAckEcn0jPathStatus0jQlogConfig0jRecvStream00jResetErrorjRetryError0jSendStream00jServerNamejSocketAddrjStreamInfojSubcommandjSystemTimejTimeSource0jTlsSession0jTokenStore0jUdpSockRefjWriteError0jaccept_unijadd_assign00000jallow_spin0jborrow_mut0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000jclone_into0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000jclose_pathjcongestion000jconn_statsjconnection0jequivalent00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000jerror_code000000jframe_type0jinto_inner0jis_drained0jlocal_addr0jlost_bytes0jnew_senderjpad_to_mtu0jpath_stats00jpoll_closejpoll_flush0jpoll_write00jprint_jsonjread_chunk0jread_exactjset_statusjstart_time0jthroughputjtotal_sizekAcceptErrorkCLIENT_ADDRkCipherSuitekClientStatskCloseReasonkConfigError0kContentTypekCryptoError0kCubicConfig0kDataBlocked0kFinishErrorkIdleTimeout0kIntoRequestkOutOfBounds0kPathAbandon0kQlogFactory0kResetStream0kRuntimeTypekSERVER_ADDRkSERVER_NAMEkSmolRuntimekStopSending0kStreamEvent0kStreamStats0kUnspecifiedkaccept_withkadd_address0kbind_socketkcertificatekcurrent_mtu00kdescription0kdestination00kfrom_remotekinitial_mtu000kinitial_rtt00kinto_future0000000000000kmax_path_id0kmax_streamsknamed_layer0kon_end_acks000kon_intervalkpacing_rate0kpartial_cmp0000000000000000000kpath_eventskpath_statuskread_chunkskread_to_endkrecv_stream0ksample_size0ksend_bufferksend_stream0ksend_window00kserver_name0ktime_source0ktoken_store0kupload_sizekupper_bound0kweak_handle0kwith_crypto0kwith_prefix0kwrite_chunklAckFrequency0lAddressAddedlClientConfig00000lClosedStream000000lConnectError00lConnectionId00lDatagramInfolDecryptError0lEcnCodepoint00lEncryptError0lIllegalValuelImmediateAck0lIntoIteratorlLOCALHOST_V4lLastOpenPathlNatTraversallNonZeroUsizelNoneTokenLog0lObservedAddr0lPathResponse0lPathsBlocked0lReadDatagramlRemoteStatus0lRttEstimator0lSendDatagramlServerConfig00000lSocketAddrV4lSocketAddrV6lStoppedErrorlTokioRuntimelUnstructuredlaugment_args0000lcid_lifetime000lclose_reasonlconnect_withlconservativeldata_blocked0ldrain_streamlearly_crypto000lexpect_types000lgenerate_cid000lgro_segmentslhandle_event0linitial_keys00000000linto_request0llost_packets0lmax_incoming0lmay_fragment00lnetwork_pathlnew_receiverlnoprotection0lorig_dst_cid0lpath_abandon0lpoll_timeoutlqlog_factory0lreset_stream0lruntime_typelsegment_size00lsend_streamslset_lifetime0lset_priority0lstop_sending0lstream_statslupload_statslwith_initial000lwrite_chunks0mAlertReceived0mBloomTokenLog0mCidsExhausted000mCloneToUninitmDatagramEventmEndpointEventmEndpointStatsmFinishedEarlymHandshakeData0mHandshakeDone0mHandshakeTypemINVALID_TOKEN0mIncomingAlpnsmInvalidHeadermLocallyClosed0mMaxStreamData0mMaxStreamsUni0mNewConnectionmNewRenoConfig0mParseIntErrormPartialDecodemPathChallenge0mPossibleValuemPrivateKeyDermReadableErrormRemoveAddress0mRootCertStoremStdSystemTime0mUnexpectedEndmaccepted_0rttmack_frequency00mbench_exports0mcid_generator00mcreate_sendermdata_transfermdownload_sizemduration_histmimmediate_ack0minto_incoming0mmax_ack_delay0mno_protectionmobserved_addr0mon_first_bytemon_mtu_update0000000mpath_response0mpaths_blocked0mpeer_identity0000mpoll_read_bufmpoll_shutdownmpoll_transmitmqlog_from_env0mread_datagrammsend_datagrammsend_fairness0msignature_len0mstart_session000000000nAddIpv4Address0nAddIpv6Address0nAddressRemovednAsyncUdpSocketnCertificateDernClosePathError0nCommandFactorynConnectionLost000000nEndpointConfig0nFromArgMatchesnINTERNAL_ERROR0nIncomingFuturenInvalidFrameIdnInvalidMessage00nMaxStreamsBidi0nNO_VIABLE_PATH0nNoneTokenStore0nPeerMisbehaved00nReachOutAtIpv40nReachOutAtIpv60nReadExactErrornReadToEndErrornShouldTransmitnTransferResultnTransportError00nUdpSocketStatenWeakPathHandlenconnect_clientncrypto_sessionndownload_statsnfor_connection000nhandle_timeoutnhandshake_data00000nhandshake_done0nhas_subcommandninitial_window0000000000000ninto_unorderednis_handshaking0000nis_valid_retry000nminimum_change0nnext_1rtt_keys000npath_challenge0nqlog_from_path0nread_handshake000nread_unorderednreceive_window00nreceived_reset00nremote_address0000nremove_address0nsaturating_add000nsaturating_sub0nthroughput_bpsntime_threshold0ntotal_durationnvalue_variantsoConnectionClose000oConnectionError0oConnectionEvent0oConnectionStats0oGetRandomFailedoNewConnectionId0oOpenStreamStatsoPathCidsBlocked0oProtectedHeader0oQlogFileFactory0oRemoteAbandoned0oSignatureSchemeoSystemTimeErroroTokenReuseError0oTransportConfig00oTryFromIntErroroVersionMismatch0oZeroRttAcceptedoZeroRttRejected000obloom_token_logoclone_to_uninit0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000odefault_runtimeogrease_quic_bit0ointegrity_limit0ointerface_indexomax_stream_data0omax_streams_uni0oparse_byte_sizeorebind_abstractosend_unreliableoserver_endpointoset_path_statusoset_send_window0oshould_transmitostream_finishedothroughput_histowrap_udp_socket00owrite_handshake000A`AddressDiscoveryA`ApplicationClose000A`CertificateErrorA`ConnectionClosed0A`ConnectionHandleA`DatagramReceivedA`DecryptedInitial0A`EndpointStopping0A`FINAL_SIZE_ERROR0A`InconsistentKeys00A`KEY_UPDATE_ERROR0A`MaxPathIdReachedA`ObservedIpv4Addr0A`ObservedIpv6Addr0A`PathStatusBackup0A`PeerIncompatible00A`QuicClientConfig0A`QuicServerConfig0A`TokenMemoryCache0A`TooManyAddressesA`ValidationFailed0A`VersionNegotiate0A`check_and_insert00000A`configure_clientA`congestion_state0A`connection_close0A`force_key_update0A`from_arg_matches00000A`max_gso_segmentsA`max_idle_timeout0A`max_streams_bidi0A`n0_nat_traversal0A`open_connections0A`open_path_ensure0A`packet_threshold0A`receive_datagramA`recv_buffer_size0A`send_buffer_size0A`transport_config0000A`validation_token0A`with_single_cert0A`write_all_chunksAaAPPLICATION_ERROR0AaApplicationClosed000AaControllerFactory0AaControllerMetrics0AaHandshakeTokenKey0AaInvalidServerName0AaNetworkChangeHint0AaPacketDecodeError0AaPathAbandonReason0AaSendDatagramError0AaStreamDataBlocked0AaStreamsBlockedUni0AaUnsupportedByPeer0Aacongestion_events0Aacongestion_window0Aamax_datagram_sizeAanew_connection_id0Aapath_cids_blocked0Aasend_buffer_spaceAaset_server_config0Aaset_up_connectionAato_possible_valueAbAEAD_LIMIT_REACHED0AbAckFrequencyConfig0AbBadMaxFragmentSize0AbCONNECTION_REFUSED0AbConnectionIdParserAbDatagramsUnblockedAbFLOW_CONTROL_ERROR0AbHandshakeConfirmedAbHandshakeDataReadyAbIllegalOrderedReadAbInvalidCertificate0AbMtuDiscoveryConfig0AbNotEnoughAddressesAbPERF_CIPHER_SUITESAbPROTOCOL_VIOLATION0AbPrivatePkcs8KeyDerAbRetireConnectionId0AbSTREAM_LIMIT_ERROR0AbSTREAM_STATE_ERROR0AbServerCertVerifiedAbServerCertVerifierAbSetPathStatusError0AbStreamsBlockedBidi0AbTokioCurrentThreadAbTransportErrorCode0AbUnsupportedVersion00000Abcommand_for_update0000Abcrypto_buffer_size0Abfrom_u64_unchecked0Abignored_handshakesAbis_same_connectionAbmin_reset_interval0Abnew_expected_items0Abpath_status_backup0Abrefused_handshakesAbremote_path_statusAbsend_datagram_waitAbset_alpn_protocols000Abset_receive_window0Absupported_versions0Abtoken_memory_cacheAbverify_server_certAbwith_start_instant0AcCongestionAlgorithmAcPathNewConnectionId0AcPathStatusAvailable0AcRemoteCidsExhaustedAcTransportParametersAcUnorderedRecvStreamAcUnsupportedNameType0AcWrongConnectionSideAcaccepted_handshakesAcarbitrary_take_rest000Acaugment_subcommandsAcblack_hole_cooldown0Acearly_data_accepted000Achandshake_confirmedAcis_path_recoverable0Ackeep_alive_interval0Aclost_plpmtud_probes0Acon_congestion_event0000000Acoutgoing_handshakesAcremote_open_streamsAcsend_buffer_benches00Acsend_data_on_streamAcsent_plpmtud_probes0Acstream_data_blocked0Acstreams_blocked_uni0AdFRAME_ENCODING_ERROR0AdHandshakeNotComplete0AdInappropriateMessage000AdInvalidRemoteAddress00AdNoInitialCipherSuite0AdServerSideNotAllowedAdSupportedCipherSuiteAdVarIntBoundsExceeded0AdVerifierBuilderErrorAdWeakConnectionHandleAdack_frequency_config0Adblack_holes_detected0Adfrom_arg_matches_mut00000Adhandle_client_streamAdincoming_buffer_size0Adis_multipath_enabledAdmax_receive_segments0Admax_udp_payload_size00Admtu_discovery_config0Adpoll_endpoint_eventsAdpreferred_address_v40Adpreferred_address_v60Adread_certs_from_fileAdreordering_threshold0Adretire_connection_id0Adretry_token_lifetime0Adset_max_idle_timeoutAdset_recv_buffer_sizeAdset_send_buffer_sizeAdstreams_blocked_bidi0Adtransport_parameters00000AeConnectionIdGenerator0AeDigitallySignedStructAeNoApplicationProtocol0AeNoDefaultClientConfig0AePATH_UNSTABLE_OR_POOR0AeValidationTokenConfig0Aeconfidentiality_limit0Aehandle_network_change0Aeincoming_buffer_bytesAeis_probably_same_pathAeloss_reduction_factor0Aemax_transmit_segments0Aenat_traversal_updatesAepath_observed_addressAepath_status_available0Aestream_receive_window00AfCRYPTO_BUFFER_EXCEEDED0AfExtensionNotNegotiatedAfFailedToGetCurrentTime0AfFailedToGetRandomBytes0AfMultipathNotNegotiated000AfNatTraversalRoundEndedAfPathRetireConnectionId0AfProtectedInitialHeaderAfSkipServerVerificationAfbuild_transport_configAfexport_keying_material0000Afget_into_many_segmentsAfget_loop_many_segmentsAfmax_concurrent_streamsAfobserved_external_addr0Afpath_new_connection_id0Afverify_tls12_signatureAfverify_tls13_signatureAfwith_root_certificates0AgCertRevocationListErrorAgHandshakeSignatureValidAgNoCertificatesPresented0AgPeerSentOversizedRecord0Agack_eliciting_threshold0Agaugment_args_for_update0000Aghas_pending_retransmitsAgis_multipath_negotiatedAgset_keep_alive_intervalAgupdate_from_arg_matches00000Agvalidation_token_config0AhAPPLICATION_ABANDON_PATH0AhNoProtectionClientConfigAhNoProtectionServerConfigAhget_max_udp_payload_size0Ahinitial_dst_cid_provider0Ahnew_with_abstract_socketAhremote_address_validated0Ahset_max_concurrent_pathsAhsupported_verify_schemesAiCONNECTION_ID_LIMIT_ERROR0AiEncryptedClientHelloErrorAiExportKeyingMaterialError0AiInvalidCertRevocationList0AiNO_CID_AVAILABLE_FOR_PATH0AiTRANSPORT_PARAMETER_ERROR0AiUnsupportedOperationErrorAiadd_nat_traversal_address0Aidatagram_send_buffer_size0Aigenerate_self_signed_certAiopen_bidirectional_streamAipath_retire_connection_id0Aiset_default_client_configAiset_path_max_idle_timeoutAjDEFAULT_SUPPORTED_VERSIONSAjUnusableAfterNetworkChangeAjdatagram_send_buffer_spaceAjincoming_buffer_size_total0Ajmax_concurrent_uni_streams0Ajopen_unidirectional_streamAjset_max_concurrent_streamsAjtry_with_platform_verifier0AkHashedConnectionIdGeneratorAkInvalidEncryptedClientHello0AkPATH_RESOURCE_LIMIT_REACHED0AkRandomConnectionIdGeneratorAkenable_segmentation_offload0Akmax_concurrent_bidi_streams0Akupdate_from_arg_matches_mut00000Akupdate_local_if_same_remoteAlconfigure_tracing_subscriberAldatagram_receive_buffer_size0Alinitiate_nat_traversal_round0Alon_spurious_congestion_event000Alreceive_bidirectional_streamAlremove_nat_traversal_address0Alset_path_keep_alive_intervalAmFixedLengthConnectionIdParserAmInappropriateHandshakeMessage000Amcongestion_controller_factory0Amdefault_path_max_idle_timeout0Amnegotiated_key_exchange_group0Amreceive_unidirectional_streamAmsend_observed_address_reports0Amset_max_concurrent_bi_streamsAnaugment_subcommands_for_updateAnmax_concurrent_multipath_paths0Anset_max_concurrent_uni_streamsAopersistent_congestion_threshold0B`default_path_keep_alive_interval0B`receive_observed_address_reports0Baget_local_nat_traversal_addresses0Bbget_remote_nat_traversal_addresses0Bbmax_remote_nat_traversal_addressesBfset_max_remote_nat_traversal_addresses0BoDEFAULT_CONCURRENT_MULTIPATH_PATHS_WHEN_ENABLED") \ No newline at end of file diff --git a/pr/545/docs/search.index/name/edb16650d3a7.js b/pr/545/docs/search.index/name/edb16650d3a7.js new file mode 100644 index 000000000..5baaa2535 --- /dev/null +++ b/pr/545/docs/search.index/name/edb16650d3a7.js @@ -0,0 +1 @@ +rd_("b()b->bBi0bCe00bFnbIdbOkb[]beq0000000000000000000000000000000000000000000000000000000000000000000000000000000000000bid0000000000000brtbtybu8cAck0cAddcAnycArccBbr00cBoxcBufcClicDir0cErrcMAX000cNotcOpt00cOrdcPincUni0cVeccadd00000cbbrccmp0000000000000000000cdir000cecn000cf32cf64cfmt00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cget0ci32cimpcios0clen000clog0cmincmutcnew000000000000000000000000000000000000cnoqcnot0cnow000000crtt000crun0cstrcu16cu32cu64cudpdArgsdAsFddDropdEct000dEct100dFromdHashdIntodKeys0dLong0dNonedPath00dPing0dPolldReaddSenddSide0dSyncdZERO0dacks0daddr0dbooldbulkdcodedcwnd0ddataddrop000000dfrom00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dhash00000000000000000000dinto00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dmain0000dnext0dopen00dpath0dperfdping000dpoll00000000000000dqlogdread00drecv00dseal0dsend00dsent0dside0dsign0dsize00dsmoldspindstop00dtake00000du128duniteAsRefeByteseChunk0eCloneeCloseeCubic00eDebugeDerefeError00000000000eEvent00eKnowneOther0eRangeeReset000eRetry0eShort0eSizedeStats0eSuiteeTokioeWriteealpnsearrayebenchebuild00000000ebytes00000ecauseeclone00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eclose000ecubicederef0eerroreframe0eindex0eis_ce0elocal0eparse0epaths0eprint00ereset00eretry0esliceespawn00estats000000000etitle0etokenetokioetupleeusizeewrite00fAcceptfAckEcn0fAes128fAes256fBackupfBorrowfBufMutfChunksfClient00fClosedfCrypto0fCursorfFuturefHasherfIpAddrfLaggedfOpenBifOpened000fOptionfOutputfPathId0fResult00000fServer00fStream000fStringfTypeIdfVarInt0faccept000fborrow00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fchunks0fcipherfclient0000fclosedfcoding0fconfig0fcrypto0000000000fdecode000000000000fdst_ipfencode000000000000ffinish00fhandlefheader0fignore0finsert00000fkeylogfoffset0fon_ack0000000fpacket00frandomfreason000000frebindfrefuse0fremote00frustls00000fserver0000fsharedfsource00000000fsrc_ip00fstatus0fstream0fstridefudp_rx000fudp_tx000fvarintfverify0fwindow0000000gBlocked00gCommandgContextgDefaultgDisplaygFromStrgGeneral0gHmacKey0gInitialgInstantgKeyPair0gLayeredgMaxData0gNewReno00gOpenUnigPadding0gPathAck0gPathBufgReadBufgRequestgRuntime0gSession0gStopped00000gStreamsgToOwnedgTooLonggTryFromgTryIntogUnknowngWritten0gZeroRttgcid_len000gclientsgcommand00000gcompare0000000000000000000gconnect0gdecrypt00000gdefault000000000000000000000000000000000000000000000000000gdrainedgdst_cid0000000gencrypt000gis_0rtt0gmetrics0000000gmin_mtu0gnoq_udpgon_sent000gopen_bigpath_idgpointergruntimegsrc_cid0000gstopped0gstreams000gtag_len0gtype_id00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000gupgrade0gversion00000hAcceptBihBytesMuthChacha20hCommandshDatagram00hDerefMuthDisabled0hDurationhEndpoint00hFinished0hIncoming0hIteratorhLayerExthLongTypehMAX_SIZE0hNO_ERROR0hNewToken0hOnClosedhOpenPathhOrderinghReadable0hRecvMetahResponsehStreamId0hTimedOut00hToStringhTokenLog0hTooLarge0hTransmit00hUdpStats0hUnixTimehWritable0hcong_alghcontentshdatagram0hdurationhendpoint0hfinalizehframe_rx000hframe_tx000hfrom_buf0hfrom_env0hfrom_keyhfrom_str0hfrom_u320hfrom_u640hgot_type000hgroup_id0000hhas_0rtthincominghinterval0hinto_any0000000his_alivehlifetime0hlocal_ip0000hmax_data0hmax_sizehnew_renohnoq_perfhon_byteshopen_unihpriority0hprotocol0hqlog_dirhresponsehrng_seed0hssthresh0hto_owned00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000htry_from00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000htry_into00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000htry_poll000000000htry_sendhvalidate000iAbandoned0iAcceptUniiAddAssigniArbitraryiAsyncRead0iAvailable00iBbrConfig0iBorrowMutiCommonOptiConnectediCriterioniDatagramsiDecodableiDiscarded0iEncodableiFormatteriFourTupleiFrameType0iHandshakeiHeaderKey0iHistogramiMalformediMaxPathId0iMultipathiPacketKey0iPartialEqiPathErroriPathEvent0iPathStats0iReadError00iTryFutureiTryStreamiUdpSenderiUdpSocketiValueEnumiaccept_biiarbitrary0000000ias_rustlsiassemblericlone_box0000000idatagrams000ideref_mut0ifrom_bits00iinitiator0iinto_0rttiinto_iteriis_client0iis_closediis_server0imay_retry0imigration0inew_timer00inew_token0inoq_protoion_closediopen_path0ipath_acks0iping_pathipoll_next000ipoll_read00ipoll_recvipoll_sendireach_out0ireferenceireset_key0iretry_tag0000isize_hint000istable_idito_string00000000000000000000000000000000000000000000000000000000000000itoken_key0itoken_positransport00iwait_idleiwrite_alljArgMatchesjAsyncTimerjAsyncWrite0jBATCH_SIZEjClosedPath000jComparablejConnectingjConnection00jController0jEquivalent0jFrameStats0jIntoFuturejInvalidCid0jIoSliceMutjMaybeFrame0jNamedGroupjNonZeroU32jOtherErrorjPartialOrdjPathAckEcn0jPathEventsjPathStatus0jQlogConfig0jRecvStream00jResetErrorjRetryError0jSendStream00jServerNamejSocketAddrjStreamInfojSubcommandjSystemTimejTimeSource0jTlsSession0jTokenStore0jUdpSockRefjWriteError0jaccept_unijadd_assign00000jallow_spin0jborrow_mut00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000jclone_into00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000jclose_pathjcongestion000jconn_statsjconnection0jequivalent00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000jerror_code000000jframe_type0jinto_inner0jis_drained0jlocal_addr0jlost_bytes0jnew_senderjpad_to_mtu0jpath_stats00jpoll_closejpoll_flush0jpoll_write00jprint_jsonjread_chunk0jread_exactjset_statusjstart_time0jthroughputjtotal_sizekAcceptErrorkCLIENT_ADDRkCipherSuitekClientStatskCloseReasonkConfigError0kContentTypekCryptoError0kCubicConfig0kDataBlocked0kFinishErrorkIdleTimeout0kIntoRequestkOutOfBounds0kPathAbandon0kQlogFactory0kResetStream0kRuntimeTypekSERVER_ADDRkSERVER_NAMEkSmolRuntimekStopSending0kStreamEvent0kStreamStats0kUnspecifiedkaccept_withkadd_address0kbind_socketkcertificatekcurrent_mtu00kdescription0kdestination00kfrom_remotekinitial_mtu000kinitial_rtt00kinto_future0000000000000kmax_path_id0kmax_streamsknamed_layer0kon_end_acks000kon_intervalkpacing_rate0kpartial_cmp0000000000000000000kpath_eventskpath_statuskread_chunkskread_to_endkrecv_stream0ksample_size0ksend_bufferksend_stream0ksend_window00kserver_name0ktime_source0ktoken_store0kupload_sizekupper_bound0kweak_handle0kwith_crypto0kwith_prefix0kwrite_chunklAckFrequency0lAddressAddedlClientConfig00000lClosedStream000000lConnectError00lConnectionId00lDatagramInfolDecryptError0lEcnCodepoint00lEncryptError0lIllegalValuelImmediateAck0lIntoIteratorlLOCALHOST_V4lLastOpenPathlNatTraversallNonZeroUsizelNoneTokenLog0lObservedAddr0lPathResponse0lPathsBlocked0lReadDatagramlRemoteStatus0lRttEstimator0lSendDatagramlServerConfig00000lSocketAddrV4lSocketAddrV6lStoppedErrorlTokioRuntimelUnstructuredlaugment_args0000lcid_lifetime000lclose_reasonlconnect_withlconservativeldata_blocked0ldrain_streamlearly_crypto000levent_streamlexpect_types000lgenerate_cid000lgro_segmentslhandle_event0linitial_keys00000000linto_request0llost_packets0lmax_incoming0lmay_fragment00lnetwork_pathlnew_receiverlnoprotection0lorig_dst_cid0lpath_abandon0lpoll_timeoutlqlog_factory0lreset_stream0lruntime_typelsegment_size00lsend_streamslset_lifetime0lset_priority0lstop_sending0lstream_statslupload_statslwith_initial000lwrite_chunks0mAlertReceived0mBloomTokenLog0mCidsExhausted000mCloneToUninitmDatagramEventmEndpointEventmEndpointStatsmFinishedEarlymHandshakeData0mHandshakeDone0mHandshakeTypemINVALID_TOKEN0mIncomingAlpnsmInvalidHeadermLocallyClosed0mMaxStreamData0mMaxStreamsUni0mNewConnectionmNewRenoConfig0mParseIntErrormPartialDecodemPathChallenge0mPossibleValuemPrivateKeyDermReadableErrormRemoveAddress0mRootCertStoremStdSystemTime0mUnexpectedEndmaccepted_0rttmack_frequency00mbench_exports0mcid_generator00mcreate_sendermdata_transfermdownload_sizemduration_histmimmediate_ack0minto_incoming0mmax_ack_delay0mno_protectionmobserved_addr0mon_first_bytemon_mtu_update0000000mpath_response0mpaths_blocked0mpeer_identity0000mpoll_read_bufmpoll_shutdownmpoll_transmitmqlog_from_env0mread_datagrammsend_datagrammsend_fairness0msignature_len0mstart_session000000000mtry_poll_next0nAddIpv4Address0nAddIpv6Address0nAddressRemovednAsyncUdpSocketnCertificateDernClosePathError0nCommandFactorynConnectionLost000000nEndpointConfig0nFromArgMatchesnINTERNAL_ERROR0nIncomingFuturenInvalidFrameIdnInvalidMessage00nMaxStreamsBidi0nNO_VIABLE_PATH0nNoneTokenStore0nPeerMisbehaved00nReachOutAtIpv40nReachOutAtIpv60nReadExactErrornReadToEndErrornShouldTransmitnTransferResultnTransportError00nUdpSocketStatenWeakPathHandlenconnect_clientncrypto_sessionndownload_statsnfor_connection000nhandle_timeoutnhandshake_data00000nhandshake_done0nhas_subcommandninitial_window0000000000000ninto_unorderednis_handshaking0000nis_valid_retry000nminimum_change0nnext_1rtt_keys000npath_challenge0nqlog_from_path0nread_handshake000nread_unorderednreceive_window00nreceived_reset00nremote_address0000nremove_address0nsaturating_add000nsaturating_sub0nthroughput_bpsntime_threshold0ntotal_durationnvalue_variantsoConnectionClose000oConnectionError0oConnectionEvent0oConnectionStats0oGetRandomFailedoNewConnectionId0oOpenStreamStatsoPathCidsBlocked0oProtectedHeader0oQlogFileFactory0oRemoteAbandoned0oSignatureSchemeoSystemTimeErroroTokenReuseError0oTransportConfig00oTryFromIntErroroVersionMismatch0oZeroRttAcceptedoZeroRttRejected000obloom_token_logoclone_to_uninit00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000odefault_runtimeogrease_quic_bit0ointegrity_limit0ointerface_indexomax_stream_data0omax_streams_uni0oparse_byte_sizeorebind_abstractosend_unreliableoserver_endpointoset_path_statusoset_send_window0oshould_transmitostream_finishedothroughput_histowrap_udp_socket00owrite_handshake000A`AddressDiscoveryA`ApplicationClose000A`CertificateErrorA`ConnectionClosed0A`ConnectionHandleA`DatagramReceivedA`DecryptedInitial0A`EndpointStopping0A`FINAL_SIZE_ERROR0A`InconsistentKeys00A`KEY_UPDATE_ERROR0A`MaxPathIdReachedA`ObservedIpv4Addr0A`ObservedIpv6Addr0A`PathStatusBackup0A`PeerIncompatible00A`QuicClientConfig0A`QuicServerConfig0A`TokenMemoryCache0A`TooManyAddressesA`ValidationFailed0A`VersionNegotiate0A`check_and_insert00000A`configure_clientA`congestion_state0A`connection_close0A`force_key_update0A`from_arg_matches00000A`max_gso_segmentsA`max_idle_timeout0A`max_streams_bidi0A`n0_nat_traversal0A`open_connections0A`open_path_ensure0A`packet_threshold0A`receive_datagramA`recv_buffer_size0A`send_buffer_size0A`transport_config0000A`validation_token0A`with_single_cert0A`write_all_chunksAaAPPLICATION_ERROR0AaApplicationClosed000AaControllerFactory0AaControllerMetrics0AaHandshakeTokenKey0AaInvalidServerName0AaNetworkChangeHint0AaPacketDecodeError0AaPathAbandonReason0AaSendDatagramError0AaStreamDataBlocked0AaStreamsBlockedUni0AaUnsupportedByPeer0Aacongestion_events0Aacongestion_window0Aamax_datagram_sizeAanew_connection_id0Aapath_cids_blocked0Aasend_buffer_spaceAaset_server_config0Aaset_up_connectionAato_possible_valueAbAEAD_LIMIT_REACHED0AbAckFrequencyConfig0AbBadMaxFragmentSize0AbCONNECTION_REFUSED0AbConnectionIdParserAbDatagramsUnblockedAbFLOW_CONTROL_ERROR0AbHandshakeConfirmedAbHandshakeDataReadyAbIllegalOrderedReadAbInvalidCertificate0AbMtuDiscoveryConfig0AbNotEnoughAddressesAbPERF_CIPHER_SUITESAbPROTOCOL_VIOLATION0AbPrivatePkcs8KeyDerAbRetireConnectionId0AbSTREAM_LIMIT_ERROR0AbSTREAM_STATE_ERROR0AbServerCertVerifiedAbServerCertVerifierAbSetPathStatusError0AbStreamsBlockedBidi0AbTokioCurrentThreadAbTransportErrorCode0AbUnsupportedVersion00000Abcommand_for_update0000Abcrypto_buffer_size0Abfrom_u64_unchecked0Abignored_handshakesAbis_same_connectionAbmin_reset_interval0Abnew_expected_items0Abpath_status_backup0Abrefused_handshakesAbremote_path_statusAbsend_datagram_waitAbset_alpn_protocols000Abset_receive_window0Absupported_versions0Abtoken_memory_cacheAbverify_server_certAbwith_start_instant0AcCongestionAlgorithmAcNatTraversalUpdatesAcPathNewConnectionId0AcPathStatusAvailable0AcRemoteCidsExhaustedAcTransportParametersAcUnorderedRecvStreamAcUnsupportedNameType0AcWrongConnectionSideAcaccepted_handshakesAcarbitrary_take_rest000Acaugment_subcommandsAcblack_hole_cooldown0Acearly_data_accepted000Achandshake_confirmedAcis_path_recoverable0Ackeep_alive_interval0Aclost_plpmtud_probes0Acon_congestion_event0000000Acoutgoing_handshakesAcremote_open_streamsAcsend_buffer_benches00Acsend_data_on_streamAcsent_plpmtud_probes0Acstream_data_blocked0Acstreams_blocked_uni0AdFRAME_ENCODING_ERROR0AdHandshakeNotComplete0AdInappropriateMessage000AdInvalidRemoteAddress00AdNoInitialCipherSuite0AdObservedExternalAddrAdServerSideNotAllowedAdSupportedCipherSuiteAdVarIntBoundsExceeded0AdVerifierBuilderErrorAdWeakConnectionHandleAdack_frequency_config0Adblack_holes_detected0Adfrom_arg_matches_mut00000Adhandle_client_streamAdincoming_buffer_size0Adis_multipath_enabledAdmax_receive_segments0Admax_udp_payload_size00Admtu_discovery_config0Adpoll_endpoint_eventsAdpreferred_address_v40Adpreferred_address_v60Adread_certs_from_fileAdreordering_threshold0Adretire_connection_id0Adretry_token_lifetime0Adset_max_idle_timeoutAdset_recv_buffer_sizeAdset_send_buffer_sizeAdstreams_blocked_bidi0Adtransport_parameters00000AeConnectionIdGenerator0AeDigitallySignedStructAeNoApplicationProtocol0AeNoDefaultClientConfig0AePATH_UNSTABLE_OR_POOR0AeValidationTokenConfig0Aeconfidentiality_limit0Aehandle_network_change0Aeincoming_buffer_bytesAeis_probably_same_pathAeloss_reduction_factor0Aemax_transmit_segments0Aenat_traversal_updatesAepath_observed_addressAepath_status_available0Aestream_receive_window00AfCRYPTO_BUFFER_EXCEEDED0AfExtensionNotNegotiatedAfFailedToGetCurrentTime0AfFailedToGetRandomBytes0AfMultipathNotNegotiated000AfNatTraversalRoundEndedAfPathRetireConnectionId0AfProtectedInitialHeaderAfSkipServerVerificationAfbuild_transport_configAfexport_keying_material0000Afget_into_many_segmentsAfget_loop_many_segmentsAfmax_concurrent_streamsAfobserved_external_addr0Afpath_new_connection_id0Afverify_tls12_signatureAfverify_tls13_signatureAfwith_root_certificates0AgCertRevocationListErrorAgHandshakeSignatureValidAgNoCertificatesPresented0AgPeerSentOversizedRecord0Agack_eliciting_threshold0Agaugment_args_for_update0000Aghas_pending_retransmitsAgis_multipath_negotiatedAgset_keep_alive_intervalAgupdate_from_arg_matches00000Agvalidation_token_config0AhAPPLICATION_ABANDON_PATH0AhNoProtectionClientConfigAhNoProtectionServerConfigAhget_max_udp_payload_size0Ahinitial_dst_cid_provider0Ahnew_with_abstract_socketAhremote_address_validated0Ahset_max_concurrent_pathsAhsupported_verify_schemesAiCONNECTION_ID_LIMIT_ERROR0AiEncryptedClientHelloErrorAiExportKeyingMaterialError0AiInvalidCertRevocationList0AiNO_CID_AVAILABLE_FOR_PATH0AiTRANSPORT_PARAMETER_ERROR0AiUnsupportedOperationErrorAiadd_nat_traversal_address0Aidatagram_send_buffer_size0Aigenerate_self_signed_certAiopen_bidirectional_streamAipath_retire_connection_id0Aiset_default_client_configAiset_path_max_idle_timeoutAjDEFAULT_SUPPORTED_VERSIONSAjUnusableAfterNetworkChangeAjdatagram_send_buffer_spaceAjincoming_buffer_size_total0Ajmax_concurrent_uni_streams0Ajopen_unidirectional_streamAjset_max_concurrent_streamsAjtry_with_platform_verifier0AkHashedConnectionIdGeneratorAkInvalidEncryptedClientHello0AkPATH_RESOURCE_LIMIT_REACHED0AkRandomConnectionIdGeneratorAkenable_segmentation_offload0Akmax_concurrent_bidi_streams0Akupdate_from_arg_matches_mut00000Akupdate_local_if_same_remoteAlconfigure_tracing_subscriberAldatagram_receive_buffer_size0Alinitiate_nat_traversal_round0Alon_spurious_congestion_event000Alreceive_bidirectional_streamAlremove_nat_traversal_address0Alset_path_keep_alive_intervalAmFixedLengthConnectionIdParserAmInappropriateHandshakeMessage000Amcongestion_controller_factory0Amdefault_path_max_idle_timeout0Amnegotiated_key_exchange_group0Amreceive_unidirectional_streamAmsend_observed_address_reports0Amset_max_concurrent_bi_streamsAnaugment_subcommands_for_updateAnmax_concurrent_multipath_paths0Anset_max_concurrent_uni_streamsAopersistent_congestion_threshold0B`default_path_keep_alive_interval0B`receive_observed_address_reports0Baget_local_nat_traversal_addresses0Bbget_remote_nat_traversal_addresses0Bbmax_remote_nat_traversal_addressesBfset_max_remote_nat_traversal_addresses0BoDEFAULT_CONCURRENT_MULTIPATH_PATHS_WHEN_ENABLED") \ No newline at end of file diff --git a/pr/545/docs/search.index/normalizedName/54aa4310aa6d.js b/pr/545/docs/search.index/normalizedName/54aa4310aa6d.js deleted file mode 100644 index b1bfb50be..000000000 --- a/pr/545/docs/search.index/normalizedName/54aa4310aa6d.js +++ /dev/null @@ -1 +0,0 @@ -rd_("b()b->bbi0bce00bfnbidbokb[]beq00000000000000000000000000000000000000000000000000000000000000000000000000000000000033333333333333brtbtybu8cack0caddcanycarccbbr00cboxcbufcclicdir0cerrcmax000cnotcopt00cordcpincuni0cvec??????bbi0bce00bfnbidbokb[]beq000000000000000000000000000000000000000000000000000000000000000000000000000000000000033333333333333brtbtybu8cack0caddcanycarccbbr00cboxcbufcclicdir0cerrcmax000cnotcopt00cordcpincuni0cvec??????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/545/docs/search.index/path/9a9587e154c3.js b/pr/545/docs/search.index/path/9a9587e154c3.js deleted file mode 100644 index 605eab758..000000000 --- a/pr/545/docs/search.index/path/9a9587e154c3.js +++ /dev/null @@ -1 +0,0 @@ -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\"]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\"]j[2,\"perf\"]8Bl[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\"]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\"]Be[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/545/docs/search.index/root.js b/pr/545/docs/search.index/root.js index d35586cc8..8baf72036 100644 --- a/pr/545/docs/search.index/root.js +++ b/pr/545/docs/search.index/root.js @@ -1 +1 @@ -rr_('{"normalizedName":{"I":"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","N":"ACOa","E":"OjAAAAAAAAA=","H":"VKpDEKpt"},"crateNames":{"N":"j","E":"OjAAAAAAAAA=","H":"JFDJy0NX"},"name":{"N":"ACOa","E":"OjAAAAAAAAA=","H":"xNXzTXj2"},"path":{"N":"BAl","E":"OzAAAAEAANQRuQACAAQACQAAAAsAZABxAAEAeAAAAH4ABACJAAEAjAAFAJMAGwCxAOUAmQEIAKMBJADJAQ4A3AEAAOABBQDsAQEA8AECAPQBAAD5AQUAAQI0AjcEAAA5BBIATQQCAFEEAwBWBAoAYgQJAHYEAACIBAIAjAQDAJEEAACTBAAAmAQAAJoEAACdBJkAOAUBADwFCABGBQgAUAUCAFYFCABjBQIAZwUEAG8FBQB8BQEAiAUCAIwFAgCTBekAfgYEAIQGAACGBgAAiQY8AMcGDwDZBgMA3gYDAOMGGAD9BgwADwcBABMHAAAYBwEAHAcAAB4HAwAqBwAALAcCADEHAAA0BwAANwd0AK0HBQC1BwYAvQfvAK8IAACxCAEAtQgBALwIAADCCAUAzAgAANAIAADTCAIA2QgBAOIIBQDqCB0ACQkUACAJeAKaCwAAoQsBAKcLAACsCwAAsgsAALYLAwDDCwAAygsJANULBwDeCxkA+QsNAAgMTABWDAMAXgwAAGAMAQB4DAEAlQxyAQoOAgAPDhgBKQ8AADQPAQA6DwMAQA8BAEMPAQBGDwEATQ8DAFIPQQCVDwIAmg8WALcPAQC6DwIAxQ8BAMoPBADQDwIA1w8EAN4PAADtDzEAIBAeAEEQAwBJEAAATBABAE8QAQBSEAcAXhABAGMQAQBpEAMAbhAAAHAQAgB0EDYAsRAFALoQAQC/EAUAyBAFANIQAQDXEFAAKREAAC0RAAAyEQEANREBADwRAABFEQEASBEDAE0RoADvEQAA8REAAPQRAQD3EQAA+hEDAP8RCgALEgEAExICABcSGAAxEhcAShICAFMSAQBdEhEAcBICAHUSAwB6EgcAhBIDAIkSBQCTEgIAmRIAAJsSAQCeEhsAuxICAL8SBADGEh8A6BILAPYSBAD9EgAAAxMlACoTBAAyEwUAOhMaAFYTAgBbExAAbhMXAIgTCgCWEwUAnRMUALMTAwC4ExcA0xMdAA==","H":"mpWH4VTD"},"entry":{"N":"ABNh","E":"OjAAAAEAAAAAAAgBEAAAAAAAAQAHAAgACgBwAHMAdAB1AHkAegCDAIcAiACLAJIArwCwAJcBmAGiAdgB2QHaAdsB3QHeAd8B5gHnAegB6wHuAfMB9QH4Af8BNgRMBFAEVQRhBGwEbQRuBG8EcgRzBHcEeAR5BHoEewR8BH0EfgR/BIAEhQSLBJAEkgSUBJcEmQSbBDcFOgU7BUUFTwVTBVQFVQVfBWAFYQViBWwFbQV1BXYFdwV4BXoFewV+BX8FggWDBYQFhQWGBYsFjwWQBX0GgwaFBocGiAbGBtcG2AbdBuIG/AYKBwsHDAcNBw4HFAcXByIHIwckByUHKQcwBzIHMwezB7QHvAeuCLQItwi4CLsIvwjACMoIywjNCM4I1gjgCOEI6AjpCAgJHgmZC5wLnQueC58LoAulC6gLqwuuC7ULvAu+C78LxgvIC8kL1AvdCwcMVQxaDFwMXQxfDGMMZQxqDGsMbgxxDHIMdAx1DHYMdwx6DH4MhAyHDIgMigyLDAgOCQ4NDg4OLA8vDzkPSA9MD5QPmA+ZD7EPsg++D8EPzw/TD9YP3Q/fD+IP4w/oD+kP7A8fEEUQThBcEGAQYRBlEG0QbxCsEK0QrxCwELkQvhDHEDERNxE7ET0RPhFBEUQRTBHzEfgR/hEKEhYSMBJJElcSWRKIEo8SkBKREpgSuhLmEucS9BL1Ev4SARMpEzETbBNtE5MTnBPRE9IT","H":"meyYOJgI"},"desc":{"N":"FMl","E":"OzAAAAEAABQNggEAAAEABwABAAoAVQBuAAAAcAAFAHgAAwCDAAEAhgACAIsAGwCvAOYAlwEBAKIBAgDFAQIAyQEBAM4BAQDRAQAA1gEJAOYBAgDrAQAA7gEAAPEBAgD1AQAA+AEAAPsBAQD/AQEABQIGACICAAAvAgIANAIAADYCAAA6AgAAPAICAEYCBABOAgAAVgICAF4CAABlAgEAaAIAAGsCAABvAgAAdQIAAIMCAACIAgoAqgIDAK8CAAC0AgAAxwIAAM0CAADTAgAA2QIBAOACAADmAgAA7gIAAPUCAQD9AgAABAMAAAgDAAANAwMAEgMGACUDAAA0AxQALAQEADIEAAA2BAAAOAQAADoEAAA8BAAAPgQMAEwEAABQBAAAUgQAAFUEAABeBAAAYQQAAGcEAQBqBAUAcgQBAHYECgCFBAAAiwQAAJAEAACSBAAAlAQFAJsEAQCeBAIAogQDAK0EhQA3BQQARAUBAEcFAgBPBQAAUQUFAFwFAABfBQMAZwUDAGwFAQBzBQUAegUBAH4FAQCCBQQAiwUBAI4FAgCXBeIAfQYBAIAGAQCDBgAAhQYAAIcGAQCLBgAAjwYAAJIGCACcBgEAoAYLAK8GAAC2BgEAuQYBAL8GAgDDBgMA1wYCANsGAADdBgEA4AYLAPEGAQD8BgAAAAcCAAQHAgAKBwQAFAcAABcHAgAcBwAAHgcHACkHAAAwBwAAMgcBADoHAAA9BxkAXwcwAJEHAQCjBwIApwcCAK4HAACwBwAAswcBALwHAAC+BwAAwgfiAK4IBAC0CAAAtwgBALsIAAC/CAEAxggBAMoIAQDNCAEA1ggAAOAIAQDlCAQA+AgBAAIJBAAICQAADAkCABAJAgAbCQEAHgkCACwJtQDkCQAA5glNADcKXAGYCwEAnAsEAKULAQCoCwAAqwsAAK4LAACwCwEAtQsAALcLAQC8CwAAvgsBAMYLAADICwEAywsJANYLAgDaCwMA4QsBAOkLAAD0CwMA/AsBAP8LAAABDAEABQwCAAsMAAANDAUAFAw9AFUMAABaDAAAXAwBAF8MAABjDAAAZQwAAGoMAQBuDAAAcQwBAHQMBgB+DAAAhAwAAIcMBACWDAUAngxoAQgOAQANDvQAEw8AABkPBAAfDwAAJg8BACkPAwAvDwAANA8BADkPAAA8DwEAQA8EAEYPAgBKDwIATg8DAGIPDwBzDwEAdg8AAHgPAQB8DxMAlA8AAJgPAQCuDwEAsQ8BAL4PAADBDwAAxA8AAM0PAwDTDwAA1g8AANgPAwDdDwAA3w8AAOIPAQDoDwEA7A8FAPQPAQD5DwIA/Q8AAP8PAAAGEAEADRABABEQBAAeEAIAIxABACgQAQAzEAMARRAAAEwQAgBVEAMAXBAAAF4QAwBjEAIAahABAG0QAABvEAAAcxAAAHUQAgB9EAIAgRACAIUQBgCSEAAAnhABAKIQBwCsEAEArxABALkQAAC+EAAAwRABAMcQAADKEAMA0RAAANkQAADbEAAA3RAAAOIQAADkEAMA6RAAAOsQAADtEAAA8BAAAPIQAAD0EAAA+BAAAPsQAAD9EAAA/xAAAAMRAAAFEQIACxEAAA0RAAAaEQEAIhEAACURAgApEQAAMRECADURAgA7EQAAPREBAEERAABEEQAATBGGANkRBADfEQAA5REBAOgRAQDrEQAA7REAAO8RAADxEQAA8xEAAPgRAAD+EQAABBIGABYSAAAZEgEAHBICACESAQAlEgUALhICADgSAAA9EgAASRIAAFcSAABZEgAAXRIDAGgSAwBvEgEAhRIAAIgSAgCPEgIAkxICAJgSAACeEgQArRIBALoSAQC+EgQAyhIEANISAADUEgAA3RICAOESAgDmEgEA6RIAAOwSAwD0EgEA/hIAAAETAAAHEwYAHRMAACATAQAnEwIAKxMAAC4TAAAxEwAARhMBAFcTAQBaEwEAXhMAAGATAABmEwMAbBMBAHQTBAB8EwUAhhMBAJATAACTEwAAnBMAAKETAwCuEwAAvBMFAMMTAADJEwAAyxMBANETAQDbEwAA3xMAAA==","H":"4zyYSj5p"},"function":{"N":"A@G`","E":"OzAAAAEAAIADVwAAAAoAcAAbAJIAAACvAAEAlwEBAKIBAADIAQAA2AEiAP8BAQA2BAAAOAQAAEwEAABQBAAAVQQAAGEEAABsBC0AmwQBADcFAAA6BQEARQUAAE8FAABTBQMAXAUAAF8FAwBmBSwAfQYAAIAGAACDBgIAhwYCAI0GAADGBgAA1wYGAOAGAADiBgAA/AYAAAcHMACsBwAAswcBALwHAACtCDUA6AgBAAgJAAAeCQEAmQswANQLAADdCwAA+AsAAAcMAABVDAAAWgwDAF8MNQAIDgMADQ4BACgPAAAqDxgARQ8HAFEPAACUDwAAmA8BAK4PIQDRDxsAHxABAD0QKwBtEAIAcxAAAKYQMAAnESUA7hEpADASAQBHEhsAbxIAAHESEwCGEhcAuhIAAL4SCgDmEgIA8BISACkTAAAsEwAALxMKAEsTDwBsEwUAhBMDAJETCwCoEwAAshMFANATBAA=","H":"Rr6vEBF3"},"type":{"N":"AJk","E":"OzAAAAEAAEUSmwACAAQACQAAAAsAZABxAAIAeAAAAH4ABQCHAAAAiQABAIwAIgCxAOUAmAEJAKMBNADcAQEA3wEIAOwBAQDwAQIA9AEAAPkBBQAAAmsCcgQAAHYEAgB7BAEAhQQAAIgEAgCMBAMAkQQAAJMEAACYBAAAmgQAAJwEsgBQBRAAYwUCAGcFBQBvBQUAfAUBAIgFBgCTBXYBDAcEABMHAAAYBwEAHAcAAB4HAwAqBwAALAcCADAHBAA3B3sAtAf4AK8IAACxCAEAtAgCALwIAAC/CAEAwggFAMwIAADQCAAA0wgCANkIAQDiCLYCmgsAAJwLAwChCwEApQsAAKcLAACsCwAAsgsAALYLAwC8CwAAvgsAAMMLAADGCwAAyQs9AAgMUQBcDAIAYAwBAGMMAABqDAEAbgwAAHcMAgCKDAAAlQySAikPAAA0DwEAOQ8EAEAPAQBDDwEARg8CAE0PYwC3DwEAug8CAMUPAQDKDwgA1w8EAN4PAADtD1EAQRAEAEkQAABMEAEATxABAFIQBwBeEAEAYxABAGkQQQCvEAAAsRAFALkQAgC/EAUAyBAFANIQAQDXEFAAKREAAC0RAAAyEQEANRECADwRAABFEQEASBGlAO8RAADxEQAA9BEBAPcRAAD6EQMA/xEKAAsSAQATEgIAFxIxAEoSAgBTEgEAVxIAAFkSAABdEhUAdRIDAHoSBwCEEgMAiRIFAJASAACTEgIAmRIAAJsSAQCeEh8AvxIEAMYSLQD2EgQA/RIAAAMTKwAyEwUAOhMaAFYTAgBbExAAbhMXAIgTCgCWEwUAnRMUALMTAwC4ExcA0xMdAA==","H":"+XKiSptl"},"alias":{"N":"`","E":"OzAAAAEAAPATAQAAAPAT","H":"p2IVDFMs"},"generic_inverted_index":{"N":"b","E":"OjAAAAAAAAA=","H":"XlAkw9na"}}') \ No newline at end of file +rr_('{"normalizedName":{"I":"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","N":"ADBd","E":"OjAAAAAAAAA=","H":"3jpX1T07"},"crateNames":{"N":"j","E":"OjAAAAAAAAA=","H":"JFDJy0NX"},"name":{"N":"ADBd","E":"OjAAAAAAAAA=","H":"7bFmUNOn"},"path":{"N":"BAo","E":"OzAAAAEAAAQSugACAAQACQAAAAsAZQByAAEAeQAAAH8ABACKAAEAjQAFAJQAGwCyAOsAoAEIAKoBJADQAQ4A4wEAAOcBBQDzAQEA9wECAPsBAAAAAgUACAI8AkYEAABIBBIAXAQCAGAEAwBlBAoAcQQJAIUEAACXBAIAmwQDAKAEAACiBAAApwQAAKkEAACsBJoASAUBAEwFCABWBQgAYAUCAGYFCABzBQIAdwUEAH8FBQCNBQEAmQUCAJ0FAgCkBe0AkwYEAJkGAACbBgAAngY8ANwGDwDuBgMA8wYDAPgGGAASBwwAJAcBACgHAAAtBwEAMQcAADMHAwA/BwAAQQcCAEYHAABJBwAATAd0AMIHBQDKBwYA0gfzAMgIAADKCAEAzggBANUIAADbCAUA5QgAAOcIAADqCAIA8AgBAPkIBQABCR0AIAkUADcJgQK6CwAAwQsBAMcLAADMCwAA0gsAANYLAwDiCwAA6gsJAPULBwD+CxkAGQwQACsMTQB6DAMAggwAAIQMAQCcDAEAugx3ATQOAgA5DhsBVg8AAGEPAQBnDwMAbQ8BAHAPAQBzDwEAeg8DAH8PQQDCDwIAxw8WAOQPAQDnDwIA8g8BAPcPBAD9DwIABBAEAAsQAAAaEBIALhAeAE4QHgBvEAMAdxAAAHoQAQB9EAEAgBAHAIwQAQCREAEAlxADAJwQAACeEAIAohA4AOEQBQDqEAEA7xAFAPgQBQACEQEABxFQAFkRAABdEQAAYhEBAGURAQBsEQAAdREBAHgRAwB9EaEAIBIAACISAAAlEgEAKBIAACsSAwAwEgoAPBIBAEQSAgBIEhgAYhIXAHsSAgCEEgEAjhIRAKESAgCmEgMAqxIHALUSAwC6EgUAxBICAMoSAADMEgEAzxIbAOwSAgDxEgQA+BIfABoTCwAoEwQAMBMAADYTJQBdEwQAZRMFAG0TGgCJEwIAjhMQAKETFwC7EwoAyRMFANATFADmEwMA6xMXAAYUHQA=","H":"DECPfczH"},"entry":{"N":"ACAl","E":"OjAAAAEAAAAAAAcBEAAAAAAAAQAHAAgACgBxAHQAdQB2AHoAewCEAIgAiQCMAJMAsACxAJ4BnwGpAd8B4AHhAeIB5AHlAeYB7QHuAe8B8gH1AfoB/AH/AQYCRQRbBF8EZARwBHsEfAR9BH4EgQSCBIYEhwSIBIkEigSLBIwEjQSOBI8ElASaBJ8EoQSjBKYEqASqBEcFSgVLBVUFXwVjBWQFZQVvBXAFcQVyBXwFfQWFBYYFhwWIBYsFjAWPBZAFkwWUBZUFlgWXBZwFoAWhBZIGmAaaBpwGnQbbBuwG7QbyBvcGEQcfByAHIQciByMHKQcsBzcHOAc5BzoHPgdFB0cHSAfIB8kH0QfHCM0I0AjRCNQI2AjZCOMI5AjtCPcI+Aj/CAAJHwk1CbkLvAu9C74LvwvAC8ULyAvLC84L1QvcC94L5QvmC+gL6Qv0C/0LKgx5DH4MgAyBDIMMhwyJDI4MjwySDJUMlgyYDJkMmgybDJ8MowypDKwMrQyvDLAMMg4zDjcOOA5ZD1wPZg91D3kPwQ/FD8YP3g/fD+sP7g/8DwAQAxAKEAwQDxAQEBUQFhAZEC0QTRBzEHwQihCOEI8QkxCbEJ0Q3BDdEN8Q4BDpEO4Q9xBhEWcRaxFtEW4RcRF0EXwRJBIpEi8SOxJHEmESehKIEooSuRLAEsESwhLJEusSGBMZEyYTJxMxEzQTXBNkE58ToBPGE88TBBQFFA==","H":"NMCeoNwo"},"desc":{"N":"FNi","E":"OzAAAAEAADoNhAEAAAEABwABAAoAVgBvAAAAcQAFAHkAAwCEAAEAhwACAIwAGwCwAOsAngEBAKkBAgDMAQIA0AEBANUBAQDYAQAA3QEJAO0BAgDyAQAA9QEAAPgBAgD8AQAA/wEAAAICAQAGAgEADAIGACoCAAA6AgAAPAIBAD8CAQBFAgIASQIAAFECBABaAgAAYQIBAGQCAABpAgAAcAIBAHMCAAB3AgAAegIAAIACAACNAgAAkgIKALUCAwC6AgAAvwIAANICAADYAgAA3gIAAOQCAQDrAgAA8QIAAPkCAAAAAwEACAMAAA8DAAATAwAAGAMDAB0DBgAwAwAAPwMUADsEBABBBAAARQQAAEcEAABJBAAASwQAAE0EDABbBAAAXwQAAGEEAABkBAAAbQQAAHAEAAB2BAEAeQQFAIEEAQCFBAoAlAQAAJoEAACfBAAAoQQAAKMEBQCqBAEArQQCALEEAwC8BIYARwUEAFQFAQBXBQIAXwUAAGEFBQBsBQAAbwUDAHcFAwB8BQEAgwUFAIsFAQCPBQEAkwUEAJwFAQCfBQIAqAXmAJIGAQCVBgEAmAYAAJoGAACcBgEAoAYAAKQGAACnBggAsQYBALUGCwDEBgAAywYBAM4GAQDUBgIA2AYDAOwGAgDwBgAA8gYBAPUGCwAGBwEAEQcAABUHAgAZBwIAHwcEACkHAAAsBwIAMQcAADMHBwA+BwAARQcAAEcHAQBPBwAAUgcZAHQHMACmBwEAuAcCALwHAgDDBwAAxQcAAMgHAQDRBwAA0wcAANcH5gDHCAQAzQgAANAIAQDUCAAA2AgBAN8IAQDjCAEA7QgAAPcIAQD8CAQADwkBABkJBAAfCQAAIwkCACcJAgAyCQEANQkCAEMJugAACgAAAgpNAFMKYAG4CwEAvAsEAMULAQDICwAAywsAAM4LAADQCwEA1QsAANcLAQDcCwAA3gsAAOULAQDoCwEA6wsJAPYLAgD6CwMAAQwBAAkMAAAUDAMAHAwBAB8MAwAkDAEAKAwCAC4MAAAwDAUANww+AHkMAAB+DAAAgAwBAIMMAACHDAAAiQwAAI4MAQCSDAAAlQwBAJgMBQCfDAAAowwAAKkMAACsDAQAuwwFAMMMbQEyDgEANw73AEAPAABGDwIASg8CAFMPAQBWDwMAXA8AAGEPAQBmDwAAaQ8BAG0PBABzDwIAdw8CAHsPAwCPDw8AoA8BAKMPAAClDwEAqQ8TAMEPAADFDwEA2w8BAN4PAQDrDwAA7g8AAPEPAAD6DwMAABAAAAMQAAAFEAMAChAAAAwQAAAPEAEAFRABABkQBQAhEAEAJhACACoQAAAsEAEANBABADsQAQA/EAQATBACAFEQAQBWEAEAYRADAHMQAAB6EAIAgxADAIoQAACMEAMAkRACAJgQAQCbEAAAnRAAAKEQAACjEAIAqxACAK8QAgCzEAYAwBAAAMwQAQDQEAkA3BABAN8QAQDpEAAA7hAAAPEQAQD3EAAA+hADAAERAAAJEQAACxEAAA0RAAASEQAAFBEDABkRAAAbEQAAHREAACARAAAiEQAAJBEAACgRAAArEQAALREAAC8RAAAzEQAANRECADsRAAA9EQAAShEBAFIRAABVEQIAWREAAGERAgBlEQIAaxEAAG0RAQBxEQAAdBEAAHwRhwAKEgQAEBIAABYSAQAZEgEAHBIAAB4SAAAgEgAAIhIAACQSAAApEgAALxIAADUSBgBHEgAAShIBAE0SAgBSEgEAVhIFAF8SAgBpEgAAbhIAAHoSAACIEgAAihIAAI4SAwCZEgMAoBIBALYSAAC5EgIAwBICAMQSAgDJEgAAzxIEAN4SAQDrEgEA7xIAAPESAwD8EgQABBMAAAYTAAAPEwIAExMCABgTAQAbEwAAHhMDACYTAQAxEwAANBMAADoTBgBQEwAAUxMBAFoTAgBeEwAAYRMAAGQTAAB5EwEAihMBAI0TAQCREwAAkxMAAJkTAwCfEwEApxMEAK8TBQC5EwEAwxMAAMYTAADPEwAA1BMDAOETAADvEwUA9hMAAPwTAAD+EwEABBQBAA4UAAASFAAA","H":"Web3xfsH"},"function":{"N":"A@J`","E":"OzAAAAEAAIMDWAAAAAoAcQAbAJMAAACwAAEAngEBAKkBAADPAQAA3wEiAAYCAQBFBAAARwQAAFsEAABfBAAAZAQAAHAEAAB7BC0AqgQBAEcFAABKBQEAVQUAAF8FAABjBQMAbAUAAG8FAwB2BS0AkgYAAJUGAACYBgIAnAYCAKIGAADbBgAA7AYGAPUGAAD3BgAAEQcAABwHMADBBwAAyAcBANEHAADGCDMA/wgBAB8JAAA1CQEAuQswAPQLAAD9CwAAGAwAACoMAAB5DAAAfgwDAIMMNgAyDgMANw4BAFUPAABXDxgAcg8HAH4PAADBDwAAxQ8BANsPIQD+DxsALRAAAE0QAQBrECsAmxACAKEQAADWEDAAVxElAB8SKQBhEgEAeBIbAKASAACiEhMAtxIXAOsSAADvEgsAGBMCACITEwBcEwAAXxMAAGITCgB+Ew8AnxMFALcTAwDEEwsA2xMAAOUTBQADFAQA","H":"N5E3OXU7"},"type":{"N":"AJl","E":"OzAAAAEAAHcSmwACAAQACQAAAAsAZQByAAIAeQAAAH8ABQCIAAAAigABAI0AIgCyAOsAnwEJAKoBNADjAQEA5gEIAPMBAQD3AQIA+wEAAAACBQAHAnMCgQQAAIUEAgCKBAEAlAQAAJcEAgCbBAMAoAQAAKIEAACnBAAAqQQAAKsEswBgBRAAcwUCAHcFBQB/BQUAjQUBAJkFBgCkBXoBIQcEACgHAAAtBwEAMQcAADMHAwA/BwAAQQcCAEUHBABMB3sAyQf8AMgIAADKCAEAzQgCANUIAADYCAEA2wgFAOUIAADnCAAA6ggCAPAIAQD5CL8CugsAALwLAwDBCwEAxQsAAMcLAADMCwAA0gsAANYLAwDcCwAA3gsAAOILAADlCwEA6QtAACsMUgCADAIAhAwBAIcMAACODAEAkgwAAJsMAgCvDAAAugyaAlYPAABhDwEAZg8EAG0PAQBwDwEAcw8CAHoPYwDkDwEA5w8CAPIPAQD3DwgABBAEAAsQAAAaEFIAbxAEAHcQAAB6EAEAfRABAIAQBwCMEAEAkRABAJcQQwDfEAAA4RAFAOkQAgDvEAUA+BAFAAIRAQAHEVAAWREAAF0RAABiEQEAZRECAGwRAAB1EQEAeBGmACASAAAiEgAAJRIBACgSAAArEgMAMBIKADwSAQBEEgIASBIxAHsSAgCEEgEAiBIAAIoSAACOEhUAphIDAKsSBwC1EgMAuhIFAMESAADEEgIAyhIAAMwSAQDPEh8A8RIEAPgSLQAoEwQAMBMAADYTKwBlEwUAbRMaAIkTAgCOExAAoRMXALsTCgDJEwUA0BMUAOYTAwDrExcABhQdAA==","H":"XypmJw7D"},"alias":{"N":"`","E":"OzAAAAEAACMUAQAAACMU","H":"p2IVDFMs"},"generic_inverted_index":{"N":"b","E":"OjAAAAAAAAA=","H":"r0jTqlt6"}}') \ No newline at end of file diff --git a/pr/545/docs/search.index/type/5f2a66270ec3.js b/pr/545/docs/search.index/type/5f2a66270ec3.js new file mode 100644 index 000000000..b4dfca549 --- /dev/null +++ b/pr/545/docs/search.index/type/5f2a66270ec3.js @@ -0,0 +1 @@ +rd_("CBk[\"\",\"ADswAAABAAAFAAIAOwQEAPYTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwQElQSaRLVE+ET/xMOFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJrRATElUS5xKUE5UT2BP7E/wT/RP+ExEUFRQ7MAAAAQAALAESAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAADIMAwC7DAUAqg2GADcQAACuEAcADhEAAH0RhgAUEgAAFhIAAJ4SAADoEgAABxMAADowAAABAAAAAAAdABAAAABaBWAFYQViBcIGwwbKBssGzAbNBs4Gzwa1C7YLtwu4CwgMTA9QD18QxRAPEhsTWBNZE28T0BPUE+ITABQ7MAAAAQAAPQAUAD8DFABmBAAAcgQCAEMFAQBGBQAAWwUBAHUFAAC1BgwAwgcDALQLAAAeDAAApg8AANoPAABgEAAABxEAAJ8SAADjEgMAUBMAANETAAABFAAAOzAAAAEAAFcADQDbAD0AigEBAGUEAABwBwAAcwcAALIHAAC0BwAAKRADAEkSBQBAEwAAcBMAAK8TBQDCEwAAOzAAAAEAABUABwBMBAAAfQwAADEOAACiDwMAERIAAA4TBwDvEwUAOzAAAAEAABMACQBiBAEAawQBANMGBwCxBwAAswcAAEYPAgBPDwAAwBAAAHcSAAADEgcAABMHAABmEgAAAScMAAAFbQcAAG8HAAByBwAAJAwAAL8QAAAAOzAAAAEAAAUAAgDCAQAAjxMEAAAAAacFAAA=\"]Bo[\"AAAAAAAAAAACvRMAAL4TAAAAAAAAAp4QAACfEAAA\",\"\"]0Bg[\"\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAA=\"]AGg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAADQAFAHMFAQA/CQEALQwEAH0MAAA6EQMAOjAAAAEAAAAAAAsAEAAAAGsEbASxB7MHTw9pEGoQLBEtES4RLxF3EgRcBAAAEgcAABMHAAC/DwAABEIEAABEBAAAmxMAAJwTAAAFYQQAAG8HAAByBwAASg8AAEsPAAADIwwAACUMAABJDwAAOzAAAAEAAAYAAwDCAQAAsAYAAI8TBAAB7BIAAAEmDAAA\",\"AAAAAVYRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAA==\"]ANg[\"AAAEUgIAALgCAACfBgAAowYAAAMDDAAABAwAAAUMAAACswEAAMMBAAA7MAAAAQAAhgABAH0RhgAAOzAAAAEAAAcAAwBDBQEA4xIDACEUAQAEcAcAAHMHAACyBwAAtAcAADswAAABAAASAAcAcwUBAOgGAAA/CQEALQwEAH0MAAA6EQMAGxIDADowAAABAAAAAAAKABAAAABiBGMEawRsBLEHswdPDywRLREuES8RBVwEAABeBQAAEgcAABMHAADBEAAABEIEAABEBAAAmxMAAJwTAAAEbwcAAHIHAABKDwAASw8AAATFBgAAIwwAACUMAABJDwAABY8TAACQEwAAkRMAAJITAACTEwAAAewSAAAAAacFAAA=\",\"AAAAAAACSAUAAEkFAAAAAgEMAAACDAAAAcAPAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAAAAAAAAA94GAAAVEQAAFhEAAA==\"]Dc[\"\",\"AAAAADswAAABAAAHAAEAIgkHADswAAABAAAJAAIAuhAEABARBAAAAQ8RAAA=\"]ADm[\"AAAABrABAACyAQAAvwEAAMEBAADWDwAA1w8AAAS2AQAAyQEAADUKAAA5CgAAOjAAAAEAAAAAAAkAEAAAALEBtwG4AcABygHLAacKqgqdE54TOzAAAAEAAA0ABACsBAcAeg8AAGUQAwBvEwAAArsBAACfEgAAOzAAAAEAABUACgCmAQEArQEAACsMAQB2DAEAzQ8DAFQQAQBvEgMAQBMAAL0TAQAIFAEAAb8TAAAAAAAAAAAAAAGnBQAA\",\"AAABqwEAAAK0BAAABBIAAAAAAAJADwAATBAAAAAAAAAAAAAAAAAEoQYAAKUGAAB6DAAAewwAAA==\",1]Fk[\"AAAABOsEAAAVBwAAuAcAABkRAAACIwkAAPYLAAABrxAAAAABwwcAAAELAQAAAqMPAAAPEwAAAdQGAAA=\",\"AAAAAesEAAABtgEAAA==\"]Fk[\"AAAABDUFAAAZBwAAvAcAACARAAACJwkAAPoLAAABsxAAAAGOAQAAAcUHAAAAAqUPAAATEwAAAdgGAAA=\",\"AAAAATUFAAAByQEAAA==\"]AEa[\"AAAAAq4BAAC6AQAAOzAAAAEAAAcAAQAiCQcAAARgBQAAYQUAAGIFAAAPEgAAAAABvxMAAAAAAAKeEAAAnxAAAA==\",\"AAAAADswAAABAAAQAAMAlgYAACIJBwD1CwcAOzAAAAEAAAsABAD2BgAAoBAAALoQBAAQEQQAOzAAAAEAAA8ABQCsBAcAEwwCABgSAgBQEgAA1BMAADowAAABAAAAAAAKABAAAADLEM0QzxDRENMQDxEyETMRNBE1EVATBCkQAAAqEAAAKxAAACwQAAAAAAXKEAAAzBAAAM4QAADQEAAA0hAAAAAAAAAAAAKnBQAARQ8AAA==\",1]Ec[\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCADswAAABAAAGAAIApwYEAAoJAQADXgQAAFMFAABUBQAA\",\"\"]Dg[\"AAAAAAAAAAABsBMAAAHwEwAAAAAAAAAAAAABVAcAAA==\",\"AAAAAAABVxIAAAE7EwAA\"]Eo[\"AAAAAekEAAABtQEAAAIqAAAAmQAAAAGuDwAAAUQDAAACBgEAAAcBAAA=\",\"AAABqAAAAAHpBAAAAf0SAAAAAe0LAAA=\"]Ic[\"AAAAASsFAAADxwEAABcTAACWEwAAAlgAAACmAAAABnsBAAB8AQAAQwQAAKYFAAC7DwAA4hMAAAFRAwAA\",\"AAABqQAAAAIrBQAA/xIAAAAB8QsAAAAAAAAAAAAAAAAAAAKqAAAAqwAAAA==\"]Ik[\"AAAAArwEAABuEgAAAfMGAAABkwYAAAGyAAAAAQcRAAABrxMAAAIREgAA7xMAAAAAAAAAAAAAOjAAAAEAAAAAAAkAEAAAAGcFkQZRB9IHiA+fD9EPWBCiED4R\",\"AAAAAbwEAAAAAVYSAAABOhMAAA==\"]Ck[\"AAAAAd0BAAAAAAAAAbMTAAAB8xMAAA==\",\"AAAAAAABWhIAAAE+EwAA\"]Ck[\"AAAAAd4BAAAAAAAAAbQTAAAB9BMAAA==\",\"AAAAAAABWxIAAAE/EwAA\"]Kk[\"AAAAAAAABFoFAABgBQAAYQUAAGIFAAAAOzAAAAEAAAkAAQCqCwkAOzAAAAEAAA0AAQBMBA0AOzAAAAEAAAkABAAfDAMARg8CAMAQAADUEAEAAAEnDAAAAyQMAABKDwAASw8AAAIlDAAASQ8AAA==\",\"AAAAAAABoBAAAAMTDAAAFAwAABUMAAA=\"]Nk[\"AAAAAAAAAnUSAAB2EgAABOMSAADkEgAA5RIAAOYSAAAC6RIAAOoSAAAF6AYAABsSAAAcEgAAHRIAAB4SAAACYgQAAGMEAAACXgUAAMEQAAAAAAHFBgAAAAAAAacFAAA=\",\"AAAAAAJWBQAAwxMAAAAF+RMAABwUAAAdFAAAHhQAAB8UAAABUBMAAALADwAA+hMAAAAAAAAAAAAAAAQuEAAALxAAADAQAAAxEAAA\"]Bg[\"AAAAAAAAAARTEQAAVBEAAHMTAAB0EwAA\",\"\"]Bk[\"\",\"AAAAAVIRAAAAAAAAAAAAAAAAAAAAAAFTDwAA\"]Cc[\"AAAAAAAAAV8QAAABYBAAAA==\",\"AAAAAAACOQkAADoJAAA=\"]FGo[\"AAAAADswAAABAAAVAAkADAIGAEoEAABrBQAA1AcAAP8LAAAyEAMAVRIAAJQTAQD7EwMAOzAAAAEAABMCEgBBBAAAWgQAAGAEAADJBgAA7wsDALsMBQDDDG0Bwg8AAMcPAAA3EAAAUxAAAK4QBwAOEQAAfRGGABQSAAAWEgAA6BIAAEsTAAA7MAAAAQAAwwAPALIAKAAZAXAAjAEPAEMEAABaBQAApgUAAKwGAwCxBgIAwgYBAOsLAwBEDwAAGxMAADoTBQDiEwAA9RMAADswAAABAACiAEIAPwMUAF0EAABnBAEAcgQCAEYFAABbBQEAdQUAAKcGBAC1BgwAvwcBAMIHAwDACAEACgkBACAJAQArCQEAAQwBABEMAQAeDAAAwQwBAEEPAQBRDwEAiQ8BAIwPAQCmDwAAyA8BANIPAQDaDwAAOBAAAEYQAQBdEAEAYBAAAMYQAQAPEQAAGhEAABwRAAAeEQAAIREAACMRAAAlEQAAMBEFAD8RAQBCEQIAUxEBAAUSAQBnEgEAnxIAANQSAQDaEgEA4xIDAAETAQBBEwEAURMBAFUTAQBzEwEAexMBAKUTAQC1EwEA0RMCAN0TAwDrEwMAARQAAA8UAQATFAEAFhQBABoUAQAhFAEAOzAAAAEAAI8AJgDbAD0AigEBAKYBAQBABAAAXgQAAGUEAABTBQEAbQUBAHAHAABzBwAAsgcAALQHAACqCwkAKwwBAHYMAQBNDwEAgg8BAMAPAADNDwMAVBABAKgQAQDCEAEAEhIAAF0SAQBvEgMA6RIBAAoTAQA2EwEASRMBAEwTAwBwEwAArxMFAL0TAQDCEwAA9xMBAPoTAAAIFAMAGBQBADswAAABAAAxAA0ATAQNAHMFAQDoBgAAPwkBABsMAAB9DAAAMQ4AAKIPAwA6EQMAGxIDAA4TBwBGEwEA7xMFADswAAABAAAcAA0AYgQBAGsEAQDTBgcAsQcAALMHAAAfDAMARg8CAE8PAABpEAEAwBAAANQQAQB3EgAAAhQAADowAAABAAAAAAAHABAAAABcBF4Fvw/BEDgRORFmEtkTA0IEAABEBAAAJwwAADowAAABAAAAAAAJABAAAABhBG0HbwdyByQMSg9LD54QnxC/EATFBgAAIwwAACUMAABJDwAAOzAAAAEAAAUAAgCwBgAAjxMEAAABJgwAAAGnBQAA\",\"AAAAAAA7MAAAAQAA5gABAMMM5gAAOjAAAAEAAAAAAFkAEAAAAGcEaAS/B8AHwAjBCCAJIQkrCSwJAQwCDBEMEgzBDMIMQQ9CD1EPUg+JD4oPjA+ND8gPyQ/SD9MPRhBHEF0QXhDGEMcQGhEcER4RIREjESURMBExET8RQBFTEVQRBRIGEmcSaBLUEtUS2hLbEgETAhNBE0ITURNSE1UTVhNzE3QTexN8E6UTphO1E7YT0hPTE90T3hPfE+AT6xPsE+0T7hMPFBAUExQUFBYUFxQaFBsUIRQiFDswAAABAAAvABQApgEBAG0FAQArDAEAdgwBAIIPAQDNDwMAVBABAKgQAQDCEAEAXRIBAG8SAwDpEgEAChMBADYTAQBJEwEATBMDAL0TAQD3EwEACBQDABgUAQAEPwkAAEAJAABGEwAARxMAAAACOBEAADkRAAAAAp4QAACfEAAA\"]Ic[\"AAAAARcRAAAABFcFAAAPCQAAEAkAAA4SAAA7MAAAAQAADAADAHUEBQDKBgUAjhMAAAADbAcAAMIQAADDEAAAASQQAAAAB8oQAADMEAAAzhAAANAQAADSEAAAOBEAADkRAAAAAW0HAAA=\",\"\"]Lk[\"AAACUwIAALcCAAAAArYBAADJAQAAOzAAAAEAAAsAAwC3AQEAygEBAK4QBwA7MAAAAQAABwABAKwEBwA6MAAAAQAAAAAABwAQAAAAvwfAB4kPig/SD9MPMBExEQACRhMAAEcTAAA=\",\"AAAAAYAPAAAAAAAAAAAAAAAAAAAAAAV/DwAAgQ8AAIgPAACLDwAASBMAAA==\"]AAg[\"AAAEVQIAALUCAAARCQAAEgkAAASsAQAAtAEAALkBAADGAQAAAloCAAC/AgAAAAA6MAAAAQAAAAAAEwAQAAAAZwRoBMAIwQg6EDwQPhBAEEEQyxDNEM8Q0RDTEGcSaBITFBQUFhQXFALpEgAA6hIAAAUtDAAALgwAAC8MAAAwDAAAMQwAAAAFyhAAAMwQAADOEAAA0BAAANIQAAAAAAACwgEAALAGAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAABMIIAADDCAAAxAgAAMUIAAA=\"]BKo[\"AAADDgkAANYSAADXEgAABaoBAAAXCgAAUhEAANwSAADdEgAAOjAAAAEAAAAAAAcAEAAAALUBxwETCRQJAQpSCnoKExIBFBIAAAEbEwAAOjAAAAEAAAAAABEAEAAAAMIHwwfEB8UHQA/ID8kPTBAaERwRHhEhESMRJRFBE0IT3RPeEwFAEwAAOzAAAAEAAAsAAgCiDwMADhMHADswAAABAAAJAAMA0wYHALEHAACzBwAAAAACbwcAAHIHAAA=\",\"AAAETQUAAE4FAAA4DwAAOQ8AADswAAABAAAWAAsAFAcHABgRAQAbEQAAHREAAB8RAQAiEQAAJBEAAAcSAQBtEwEAcRMAALsTAQACFxMAAJYTAAABDhIAAAAAAAAAAAAAAAAAADowAAABAAAAAABrABAAAACgAaEBowGkAQICAwIJAgoCSQRLBG0EtgS5BKAGpAbRBtIGBgcHB/wI/QgyCTMJ/gsADBYMFwwcDB0MKAwpDD4PPw9UD3sPfA+dD54P0Q8mECcQRBBFEFEQUhBWEFcQYRBiEJgQmRCiEKQQpRCrEKwQthC3ELgQuRA2ETcRShFLEQoSCxIMEg0SUhJTEl8SYBJrEm0SlBKVEpYSlxKZEpoSmxKcEtgS3hLfEuAS+xIMEw0TFhMcEx0THhMfEyATIRM4EzkTUxNUE1oTWxN5E3oTmROaE9YT1xM=\"]Ac[\"AAAAAAEwAwAA\",\"\"]Ca[\"AAAAAAJaAgAAvwIAADswAAABAAAFAAEATBEFAA==\",\"\",1]Ek[\"AAAAAAAAAAAAAAAAAAAAAAAAAsYGAADcBgAA\",\"AAAAAAACORAAADsQAAAAAjoQAAA8EAAAAAIbEgAAHBIAAA==\"]Eo[\"AAAAAAAAAAAAAAAAAAAAAAAAAscGAADdBgAA\",\"AAAAAAACPRAAAD8QAAAAAz4QAABAEAAAQRAAAAACHRIAAB4SAAA=\"]Ck[\"AAAAAAAAAAAAAAAAAAAAAAAABXAAAACkAQAArQcAAMwHAADECAAA\",\"\"]Bg[\"AAAAAAAAAUwPAAAAAAAAAjgRAAA5EQAA\",\"\"]Gk[\"AAAABGEAAADFBAAAagUAANUPAAABDgIAAAYOAAAASAQAAEUFAAAEBwAASBEAAJgTAAACxwAAAFAPAAAAAlcTAACuEwAA\",\"AAAAAcUEAAABvwgAAAFGBAAA\"]Ig[\"\",\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBGDwIAwBAAANQQAQAAAScMAAAEJAwAAEoPAABLDwAAvxAAAAMjDAAAJQwAAEkPAAAAAAEmDAAA\"]Bg[\"AAAAAAAAAAAAAAAAAAKeEAAAnxAAAA==\",\"\"]Hk[\"AAAD0AEAAAoMAAANDAAAAegEAAABtQEAAAQpAAAAmAAAADkQAAA7EAAAAa0PAAABQwMAAAMFAQAAChEAAAsRAAA=\",\"AAAC0AEAAAYMAAACaQQAAOgEAAAB/BIAAAAB7AsAAA==\"]Hk[\"AAAD0QEAAAsMAAAODAAAASoFAAABxwEAAARXAAAApQAAAD0QAAA/EAAAAnoBAAC6DwAAAVADAAADXgQAAAwRAAANEQAA\",\"AAAC0QEAAAcMAAADagQAACoFAAD+EgAAAAHwCwAA\"]2ALo[\"AAAAAAEoEAAAAAA6MAAAAQAAAAAAEQAQAAAAuwFdBBEMEgzBDMIMQQ9CD8YQxxAFEgYS6xPsEw8UEBQaFBsUAmUEAABAEwAAOzAAAAEAAAsAAgCiDwMADhMHADswAAABAAAHAAEA0wYHAAAAAAACwgEAALAGAAA=\",\"AAAHTwUAAFAFAAAKDAAACwwAAA0MAAAODAAAFRIAADowAAABAAAAAAAXABAAAAC1B7YHHgkqCQwMDwwQDDoPOw9IEEkQShCXEBcRJxEoESkRKhErEUMTrBOtE8ATwRM7MAAAAQAA+QACADkO9QADEwMAOzAAAAEAAFkABAALAFUA2RIAAAgTAQByEwAAAfUTAAAAAAQ6EQAAOxEAADwRAAA9EQAABCwRAAAtEQAALhEAAC8RAAABZhIAAAAAAAAAAAdxBAAAZwUAANAGAAA2DgAAmhAAAKoQAAA+EQAA\"]Dk[\"AAAAAAL+CQAAUQoAAAAAADswAAABAAAFAAEASRIFAAACYgQAAGMEAAAAAkIEAABEBAAA\",\"\"]BOc[\"\",\"ADswAAABAAAFAAIAOwQEAPYTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwQElQSaRLVE+ET/xMOFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJrRATElUS5xKUE5UT2BP7E/wT/RP+ExEUFRQ7MAAAAQAAKAERAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAALsMBQCqDYYANxAAAK4QBwAOEQAAfRGGABQSAAAWEgAAnhIAAOgSAAAHEwAAOjAAAAEAAAAAABsAEAAAAFoFYAVhBWIFwgbDBsoGywbMBs0GzgbPBrULtgu3C7gLTA9QD18QxRAPEhsTWBNZE28T0BPiEwAUOzAAAAEAADsAEgA/AxQAZgQAAHIEAgBDBQEARgUAAFsFAQB1BQAAtQYMAMIHAwC0CwAAHgwAAKYPAADaDwAAYBAAAJ8SAADjEgMA0RMAAAEUAAA7MAAAAQAAUgALANsAPQCKAQEAZQQAAHAHAABzBwAAsgcAALQHAABJEgUAcBMAAK8TBQDCEwAAOzAAAAEAABQABgBMBAAAfQwAADEOAACiDwMADhMHAO8TBQA7MAAAAQAAEwAJAGIEAQBrBAEA0wYHALEHAACzBwAARg8CAE8PAADAEAAAdxIAAAISBwAAEwcAAAEnDAAABG8HAAByBwAAJAwAAL8QAAAABY8TAACQEwAAkRMAAJITAACTEwAA\"]Bc[\"AAAAAAAAAAAAAAACOBEAADkRAAA=\",\"\"]Kc[\"AAAAAAHiEgAAADswAAABAAAGAAIAygYFAMUQAAACRgUAANoPAAABZQQAAAADaRAAAGoQAAB3EgAAAb8PAAA=\",\"AAAAAAABYAQAADswAAABAAAFAAEAdQQFAAAAAAAAAAAAAAAABwsCAAC1BAAAuAQAAN8GAADgBgAA4QYAAOIGAAA=\"]Do[\"AAAAAAABGAAAAAAAAd8AAAAAAAAAAAAAAAACtQQAANEGAAA=\",\"AAAAAAAAAAACTQ8AAE4PAAA=\"]Dk[\"AAAAAAABMAAAAAEfAQAAAAAAAAAAAAAAAAACuAQAANIGAAA=\",\"AAAAAAAAAAABQAQAAA==\"]Ac[\"AAABYgIAAA==\",\"\"]Fg[\"AAAABO0EAAAWBwAAuQcAABsRAAADJAkAAPcLAAD8EwAAAbAQAAAAAAENAQAAARATAAAB1QYAAA==\",\"AAAAAe0EAAAAAbcBAAA=\"]Fg[\"AAAABDcFAAAaBwAAvQcAACIRAAADKAkAAPsLAAD+EwAAAbQQAAABkAEAAAAAARQTAAAB2QYAAA==\",\"AAAAATcFAAAAAcoBAAA=\"]Bk[\"\",\"AAAAAAAAAAA7MAAAAQAAPwACANsAPQCKAQEA\"]Ck[\"\",\"AAAAAAGWBgAAOzAAAAEAAAkAAgD2BgAA+AYIAAHUEwAAAVATAAA=\"]Ck[\"AAACYQIAAHMCAAA=\",\"AAAAAAAAAl0TAABeEwAAAAACOhEAADsRAAA=\"]Bo[\"\",\"AAAAAAAAAAAAAAAAApsTAACcEwAAAAAAAewSAAA=\"]Eo[\"\",\"AAAAAAA7MAAAAQAABQABAFYSBQA7MAAAAQAABQABADoTBQAAOzAAAAEAAAUAAQCvEwUAOzAAAAEAAAUAAQDvEwUA\"]Cc[\"\",\"AAAAAAL8EgAA/RIAAAAE6wsAAOwLAADtCwAA7gsAAA==\"]Eg[\"AAAAAfEEAAAAAS0AAAAAAAIVAQAAFgEAAA==\",\"AAA7MAAAAQAACgABAJICCgAC8QQAAOMTAAAAAAF1EgAA\"]Eo[\"AAAAATEFAAAAAV8AAAAAAAKKAQAAiwEAAA==\",\"AAA7MAAAAQAACgACABgDAwAdAwYAAjEFAADkEwAAAAABdhIAAA==\"]Dg[\"AAABAAMAAAEwBQAAAAFdAAAAAoUBAACGAQAA\",\"AAABDwMAAAEwBQAAAAAAAAFeBAAA\"]Eo[\"AAAAAAAAApUBAACWAQAA\",\"AAAAAAAAB9ATAAD5EwAAABQAABwUAAAdFAAAHhQAAB8UAAAC0RMAAAEUAAAB+hMAAA==\"]Bk[\"AAAAAAAAAUUBAAA=\",\"AAAB2AIAAAAAAVoEAAA=\"]Bg[\"AAAAATsFAAAAAAGXAQAA\",\"AAAAATsFAAA=\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAXgMAAA=\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA64HAADNBwAAxQgAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAnEEAACvBwAA\",\"\"]Cc[\"AAAAAAAAAAIKCQAACwkAAAAAAAAAAAACwgEAALAGAAA=\",\"\"]Fo[\"AAAAAAACVwUAABYSAAAAAAAAAAAAAAAAAAAE0wcAAFQPAABjEAAAVREAAA==\",\"AAF1BwAAAAAAAAAAAAAAAAAAAAAAAAJkEAAACREAAA==\"]Bk[\"AAAAAVkFAAAAAAFMDwAAAaYPAAA=\",\"AAGmBwAA\"]Bg[\"AAAAAAAABGUQAABmEAAAZxAAAGgQAAA=\",\"\"]Ag[\"AAAAAq4BAAC6AQAA\",\"\"]Dg[\"AAAAAAAAAAAAAj8JAABACQAA\",\"AAAAAAAAAAAABS0MAAAuDAAALwwAADAMAAAxDAAA\"]AEg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAACwAEAHMFAQAtDAQAfQwAADoRAwA6MAAAAQAAAAAACwAQAAAAawRsBLEHswdPD2kQahAsES0RLhEvEXcSBFwEAAASBwAAEwcAAL8PAAAEQgQAAEQEAACbEwAAnBMAAAVhBAAAbwcAAHIHAABKDwAASw8AAAMjDAAAJQwAAEkPAAA7MAAAAQAABgADAMIBAACwBgAAjxMEAAHsEgAAASYMAAA=\",\"AAAAAVYRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAAAAACQgQAAEQEAAA=\"]He[\"\",\"AAAAAAAEMgwAADMMAAA0DAAANQwAAAIIDAAA1BMAAAIHEQAAUBMAAAUpEAAAKhAAACsQAAAsEAAAQBMAAAEREgAAAAFmEgAAAAFtBwAAAAHCAQAAAAABpwUAAA==\",1]AMk[\"AAACvAEAAMUBAAAGrAEAALQBAAC5AQAAxgEAANwSAADdEgAABFgFAAA3CQAA/wkAAFAKAAAEMgwAADMMAAA0DAAANQwAAAJYEwAAWRMAADowAAABAAAAAAAHABAAAAAKCQsJRhBHENQS1RLSE9MTOjAAAAEAAAAAAAkAEAAAAEAEcAdzB7IHtAdND04PwA/3E/gTAAKxBwAAswcAAA==\",\"AAAAOjAAAAEAAAAAABAAEAAAAKIBTQdOB08HUAfVB9YHNgzDD8QPXBDIEMkQYxJkEp0S3BMDNAkAACgQAACYEgAABjIMAAAzDAAANAwAADUMAABqEgAAbBIAAAAAAAJzBQAAdAUAAAACXAQAAL8PAAAAA2EEAABKDwAASw8AAAMjDAAAJQwAAEkPAAAAAAImDAAAggwAADowAAABAAAAAAALABAAAAClAW4EbwS3BLoEjwaQBggHUQfSB9MHnw8=\"]Bg[\"AAAAAAAAAAAAAVcEAAA=\",\"AAAAAaQFAAA=\"]Bk[\"AAAAAAAAADswAAABAAANAAIAdQUAALUGDAA=\",\"\"]Cc[\"AAABAQkAAAABEgIAAAAAAAFABAAA\",\"AAAAAAAAAAFdBAAA\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAbAGAAA=\",\"\"]Be[\"AAAAAAAAA2AFAABhBQAAYgUAAA==\",\"\",1]Bg[\"AAAAAAAAADswAAABAAAUAAEAPwMUAA==\",\"\"]Dk[\"AAAAAAHIAQAA\",\"AAAAAAUtCQAALgkAAC8JAAAwCQAAMQkAAAAAAAAAAAAAAAAAAAH9DwAA\"]Cc[\"AAAAAcQEAAAAAQ0AAAACvwAAAMAAAAA=\",\"AAAAAcQEAAA=\"]Bg[\"AAAAAAAAAAAAAVIEAAA=\",\"AAAAAcYHAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWYAAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAaoAAAA=\",\"\"]C@i[\"AAAAAAHIAQAAAZ4SAAABbxMAAAK7AQAAnxIAADowAAABAAAAAAAbABAAAACtAW0FbgWCD4MPqBCpEF0SXhIKEwsTNhM3E0kTShNME00TThNPE1cTcBOuE/cT+BMKFAsUGBQZFDswAAABAAAGAAMAPwkBAKIPAwC/EwAAAQIUAAAB2RMAAAAAAcUGAAAAAAABpwUAAA==\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAAEAwwAAAQMAAAFDAAABBIAADowAAABAAAAAAAXABAAAACcAakEbgdxB8cHvgi/CC0JLgkvCTAJMQk0CR8QIBAhECIQIxCYEqESAxMEEwUTBhM7MAAAAQAAIAAOANkBAADbAQAAQQQAAEYEAABaBAAAYAQAAPgGCAAyDAMAQw8AAFMQAAC6EAQAEBEEAOESAABLEwAAOzAAAAEAACMACQBDBAAAdQQFAKYFAADQBwAARA8AAKkPEwBQEgEAXRMBAGATAQA7MAAAAQAACAAEADgQAAAyEQMAQhECAHgTAAA7MAAAAQAADAAGAEAEAABNDwEAKRADAAoRAwBXEwAArhMAAAQbEgAAHBIAAB0SAAAeEgAAOzAAAAEAAAYAAwAfDAMA1BABAAIUAAAEXAQAAL8PAADBEAAA2RMAAAAAAcUGAAABwgEAAAAAOjAAAAEAAAAAABwAEAAAAKwArQCuAK8Apga0BgEHAgcDB/oIOwk8CT0JPglBCUIJjg+nD6gPyg/LD8wPWRBaEFsQQREJEn0TIBQ=\",1]Bg[\"AAAAAAAAAAAAAAAAAAKeEAAAnxAAAA==\",\"\"]Jo[\"AAAAAc8EAAAAOjAAAAEAAAAAAAcAEAAAABkAlQDZAUYEQw9NEVARCBMCqg8AAFASAAACQAMAALYGAAAC4AAAAOEAAAAAAbEHAAAAAAFvBwAA\",\"AAF6BwAAAANhAAAAYgAAAM8EAAACWgIAAMcHAAACTREAAFARAAAAAagGAAA=\"]A@c[\"AAAAAfgEAAAABzIAAACdAAAA2wEAAE8RAABREQAA4RIAAAkTAAAHIgEAACMBAABEDwAAsg8AAL4PAABLEAAAURIAAARIAwAAuwYAAB4MAAB4EwAAARISAAABMQ4AAAKzBwAAAhQAAAHZEwAAAAFyBwAA\",\"AAGPBwAAAAH4BAAAAr8CAABWBQAAAk8RAABREQAAAa0GAAAAAAEbDAAAAAFmEgAAAAAAAAAABWYAAABnAAAAaAAAAGkAAABqAAAA\"]Bo[\"\",\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwA=\"]CDe[\"\",\"AAA7MAAAAQAA5gABAMMK5gA7MAAAAQAA7QAMAMoJMwAACgAAAgoyADYKAgA6ChUAUwoeAHMKBgB7CioAqAoBAKwKFgBPEgAA4xMBADowAAABAAAAAAASABAAAABdBaUFlgYTCRQJ/gn/CQEKNQo5ClAKUQpSCnIKegqmCqsK/BL9EjowAAABAAAAAAASABAAAABIBEUF9gYEBzkJOgmnCqoKSBFWElcSWBJZEloSWxIHE5gTnROeEzowAAABAAAAAAApABAAAADCBsMG0Ae1C7YLtwu4C+sL7AvtC+4LCAxQD3oPvg9LEF8QZRBmEGcQaBDFEHUSdhI6EzsTPBM9Ez4TPxNdE14TYBNhE9AT1BP5EwAUHBQdFB4UHxQ6MAAAAQAAAAAAGgAQAAAAXQRyBHMEdARbBVwFpwaoBqkGqgarBh4M2g86EDwQPhBAEEEQYBAPEUIRQxFEEVATeBPREwEUOzAAAAEAAFkADwDbAD0AigEBAEAEAABeBAAAZQQAAFMFAQBsBwAATQ8BAMAPAAASEgAASRIFAFcTAACuEwYAwhMAAPoTAAA7MAAAAQAAEQAIAHMFAQAbDAAAfQwAADEOAAAkEAAAOhEDAEYTAQDvEwUAOjAAAAEAAAAAAAgAEAAAAGIEYwRPD2kQahDUENUQdxICFDowAAABAAAAAAALABAAAABcBF4FEgcTB78PyhDMEM4Q0BDSEGYS2RMEQgQAAEQEAACbEwAAnBMAAARtBwAAbwcAAHIHAAC/EAAAAiMMAABJDwAAOzAAAAEAAAYAAwDCAQAAsAYAAI8TBAAB7BIAAAABpwUAAA==\",1]Le[\"\",\"AAAAAswBAACUBgAAA/QGAAA8DwAAPQ8AAAPmBgAAahIAAGwSAAA6MAAAAQAAAAAABwAQAAAATA8PEhgSGRIaElgTWROOEwJmBAAAtAsAAAGtAQAAAb8TAAAERg8AAEcPAABIDwAAwBAAAAABJwwAAARhBAAAJAwAAEoPAABLDwAAASUMAAAAAAEmDAAA\",1]Gc[\"\",\"AAAAOjAAAAEAAAAAAAcAEAAAAN0B3gEQEmkS1RPhE/8TDhQC8wYAACgQAAAFkwYAAA8JAAAQCQAAfQ8AAA4SAAABGxMAAAEHEQAAAUATAAA=\"]Bo[\"\",\"AAAAAv4SAAD/EgAAAATvCwAA8AsAAPELAADyCwAA\"]Bk[\"\",\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCAA==\"]Fc[\"AAAAAcQBAAAAAAAABG0FAABuBQAAgg8AAIMPAAA=\",\"AAA7MAAAAQAAPgABADcMPgAAAAAAAAAAAAAAAAAAAAAB4wYAAA==\"]Ao[\"\",\"AAA7MAAAAQAA5gABANcH5gA=\"]A@o[\"AAAEaQIAAHoCAACAAgAAOA8AAAHNBAAAA+cSAAARFAAAFRQAAAMWAAAAlAAAAEwRAAABqQ8AADowAAABAAAAAAAMABAAAAA/A3IEcwRDBUQFWwW1Bj8RURN7E6UT3xPtEwLbAAAA3AAAAA==\",\"AAF5BwAAOzAAAAEAAAYAAwBRAgQAEQkAANYSAAABzQQAAAQTCQAA/gkAAP8JAAABCgAAAUwRAAAB6wsAAAOnBgAAQhEAAEMRAAAAAAAAAAAAAAAAATAPAAA=\"]ABc[\"AAAE3gIAAAEDAAAIAwAAOQ8AAAH1BAAAAAQuAAAAmwAAAE4RAADoEgAABBsBAAAcAQAAsA8AAOITAAA6MAAAAQAAAAAACgAQAAAARgN0BEYFXAW6BkARUhN8E6YT4BPuEwABMQ4AAA==\",\"AAGOBwAAB7UCAAC2AgAAtwIAALgCAAC6AgAAEgkAANcSAAAB9QQAAAQUCQAAUAoAAFEKAABSCgAAAu8LAABOEQAAAqwGAADQBwAAAUQRAAAAAAAAAAAAAAAABDIPAAAzDwAANA8AADUPAAA=\"]Gc[\"AAA7MAAAAQAACwAEABoQBAAAEwAApxMEABIUAAA=\",\"ADswAAABAAAJAAMAUgcBAFUHAgDPEgQAOzAAAAEAAAsABAAaEAQAABMAAKcTBAASFAAA\"]Ig[\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBGDwIAwBAAANQQAQAAAScMAAAEJAwAAEoPAABLDwAAvxAAAAMjDAAAJQwAAEkPAAAAAAEmDAAA\",\"\"]Cc[\"AAAAArABAADIEAAAAAAAAAErDAAAAAFrBAAAARIHAAA=\",\"\"]Cc[\"AAAAAr8BAADJEAAAAAAAAAEsDAAAAAFsBAAAARMHAAA=\",\"\"]ABg[\"AAAAAu0SAADuEgAAAAW3AQAAuAEAAMoBAADLAQAADhEAADswAAABAAALAAMArAQHAFoFAAATDAIAOjAAAAEAAAAAAAcAEAAAAEYFwgfDB8QHxQdRD1IPpg8HChEAAAsRAAAMEQAADREAAHATAADCEwAA+hMAADswAAABAAANAAQAGwwAADEOAACiDwMADhMHADswAAABAAAHAAEA0wYHAAPBEAAAZhIAANkTAAAAAW0HAAABxQYAAAAAAAGnBQAA\",\"AAAAA9MBAADUAQAA1QEAAAABUxAAAA==\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUQUAAOkGAAA=\",\"AAAAAAAAAAIyEQAAMxEAAAAAAAAAAAAAAAACxgYAANwGAAA=\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUgUAAOsGAAA=\",\"AAAAAAAAAAI0EQAANREAAAAAAAAAAAAAAAACxwYAAN0GAAA=\"]Ak[\"\",\"AAAAAAKgDwAAoQ8AAA==\"]Eo[\"AAAABO8EAAAXBwAAugcAAB0RAAACJQkAAPgLAAABsRAAAAAAAQ8BAAABERMAAAHWBgAA\",\"AAAAAe8EAAAAAbgBAAA=\"]Eo[\"AAAABDkFAAAbBwAAvgcAACQRAAACKQkAAPwLAAABtRAAAAGSAQAAAAABFRMAAAHaBgAA\",\"AAAAATkFAAAAAcsBAAA=\"]Bg[\"AAAAAAAAAAAAAVEEAAA=\",\"AAAAATgJAAA=\"]Ag[\"AAACrwEAAL4BAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAIkDAAAvxAAAA==\",\"\"]Ag[\"\",\"AAACQhAAAEMQAAA=\"]Bg[\"AAAAAAAAAAAAARESAAA=\",\"AAABbwAAAA==\"]Dg[\"AAAAAtMBAADUAQAAAAADYAUAABMMAAAYEgAAAAGtAQAAAb8TAAA=\",\"AAAAAQQSAAA=\"]Hg[\"AAAAAScRAAABAxMAAAM5EAAAuxAAABERAAABXRMAAAEyEQAAASkQAAACOhEAABsSAAABLBEAAAAAAAABkBMAAA==\",\"AAAAAAAAAALLEAAAzRAAAAAAAALKEAAAzBAAAA==\"]Ig[\"AAAAASoRAAABBRMAAAM9EAAAvRAAABMRAAABYBMAAAE0EQAAASsQAAACPBEAAB0SAAABLhEAAAAAAAABkhMAAA==\",\"AAAAAAEIEQAAAAADzxAAANEQAADTEAAAAAAAA84QAADQEAAA0hAAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAm4AAAA1DwAA\",\"\"]Bk[\"AAAAAAAAAdoAAAAAAAFZBAAA\",\"AAAAAc8HAAA=\"]Cc[\"AAAAAVwQAAABFxMAAAACQwQAAKYFAAA=\",\"AAAAAAHUBwAA\"]Ek[\"AAAAAdQEAAAAAR0AAAAAAAHmAAAAAAAAAAAAAAAAArcEAACPBgAA\",\"AAF/BwAAAAHUBAAAAAAAAAAAAWkQAAA=\"]Ek[\"AAAAAQUFAAAAAT0AAAABNAEAAAAAAAAAAAAAAAAAAroEAACQBgAA\",\"AAGWBwAAAAEFBQAAAAAAAAAAAWoQAAA=\"]Be[\"AAAAAAA7MAAAAQAAhgABAH0RhgA=\",\"\",1]Bg[\"AAAAAAAAAAAAAVQEAAA=\",\"AAAAAeoLAAA=\"]Ec[\"AAAAAAAAAAAAAAAAAAJvBwAAcgcAAAHFBgAAAsIBAACwBgAA\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Dk[\"AAAAAAAAAAABsRMAAAHxEwAA\",\"AAAAAAABWBIAAAE8EwAAAAAAAAAAAAAAAAABVAcAAA==\"]Dg[\"AAAAAR0FAAAAAAJfAQAAYAEAAAG+BgAAAAAAAAAAAAAAAAELAgAA\",\"AAAAAR0FAAA=\"]ABc[\"AAAAA6oBAAARCgAAUhEAAAPEBgAAcgoAAK0QAAAAADowAAABAAAAAAANABAAAAAgCSEJKwksCYwPjQ9dEF4Q2hLbEgETAhNVE1YTOzAAAAEAAA8ABwCoEAEASRIFAAoTAQBXEwAArhMAAAoUAQAYFAEAAAECFAAAAdkTAAA=\",\"AAAAA50BAACoAQAAJRAAAAQfEAAAIBAAACEQAAAiEAAAAtkBAADbAQAAAAACVxMAAK4TAAAAAQIUAAAB2RMAAAAAAAAAAATaAQAA3AEAAP4IAABVEQAA\"]Bk[\"AAAAAAHzBgAA\",\"AAAAAAAAAAEHEQAAAAEREgAA\"]Ho[\"AAAABcIEAABpBQAApAUAAHwMAABjEgAAAj0PAADYEwAAAuYGAACeEgAAA70AAAAPEgAAbxMAAAFEBQAAAWwHAAABJBAAAA==\",\"AAAAAsIEAACUBgAAAfQGAAAAAAABrQEAAAG/EwAA\"]Gc[\"AAAAAmQSAABxEwAAAZsGAAAByQYAAAEaAQAAAjgQAACfEgAAAAHoBgAAAAFeBQAAAAFtBwAAAcUGAAAAAAABpwUAAA==\",\"AAAAAAAAAAG7AQAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAW0AAAA=\",\"\"]Fg[\"AAADyAYAAOcGAACaDwAABA8MAABPEAAARxEAAMATAAAFDQIAAF0FAAClBQAAbgcAAC8JAAAAAsMAAAB6DwAA\",\"AAABphAAAA==\"]Fg[\"AAAABBAMAABQEAAASREAAMETAAACcQcAADAJAAAByQYAAAFiAQAAAAAB6AYAAAABXgUAAAAAAAAAAAGnBQAA\",\"AAABpxAAAA==\"]Dg[\"AAAAASIFAAAAAVEAAAABawEAAA==\",\"AAAAASIFAAAAAAAAAAAAAAAAAAAAAAFwAAAA\"]Bk[\"AAAAAAEMAgAAAAAAAAFOBAAA\",\"AAAAARkMAAA=\"]Cc[\"AAAAAAHHBwAAAAAAAAFPBAAA\",\"AAAAAAACGgwAAGUSAAA=\"]Dk[\"\",\"AAAAADswAAABAAATAAEAWAcTADswAAABAAATAAEAlAATADswAAABAAATAAEAqQ8TAA==\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWsAAAA=\",\"\"]Fg[\"AAAAATwFAAAAAAGZAQAAAAAAAAAAAWEEAAAAAAABJgwAAAauAAAApQEAAAUCAAC0BgAACAcAAAkSAAA=\",\"AAGlBwAAAAE8BQAA\"]Hk[\"AAAEqAAAAFQCAABNBQAABgwAAAHqBAAAAAIrAAAAmgAAAAGvDwAAAkUDAAC5BgAAAggBAAAJAQAA\",\"AAABgAIAAARjAAAAZAAAAGUAAADqBAAAAbUBAAAAAe4LAAABqwYAAA==\"]Kc[\"AAAEqQAAALYCAABOBQAABwwAAAEsBQAAAARZAAAApwAAAMIPAADHDwAAA30BAAB+AQAAvA8AAAJSAwAAwAYAAA==\",\"AAABCAMAAAEsBQAAAccBAAAB8gsAAANDBAAApgUAALIGAAAAAAAAAAAAAAAAAARrAAAAbAAAAG0AAABuAAAA\"]Ak[\"AAAAAALYDwAA2Q8AAA==\",\"\"]Ao[\"AAAAAAAAAAACpgEAAEkSAAA=\",\"\"]Ao[\"AAAAAAAAAAACpwEAAEwSAAA=\",\"\"]Dc[\"AAAAAAAAAAABCgEAAAAAAAAAAAAAAAWsAAAAbgQAAAEHAACEDwAAWRAAAA==\",\"\"]Fc[\"AAAAAAAAAX8BAAAAAAAAAAAAAAAAAAWtAAAAbwQAAAIHAACFDwAAWhAAAA==\",\"AAAAAAAAAAAAAegGAAAAAl4FAADBEAAA\"]Fc[\"AAAAAT0FAAAAAAGaAQAAAmYEAAC0CwAAAAAAAAEnDAAAAAAAAAAFrwAAAAMHAAD7CAAAhg8AAFsQAAA=\",\"AAAAAT0FAAA=\"]Hg[\"AAABjQAAAAHQBAAAAAIaAAAAuwwAAAAAAeIAAAAAAAAAAAAAAAADoAEAALYEAAD+CwAA\",\"AAF7BwAAAAHQBAAAAAAAAAAAAAAAAAAAAAAECQcAAAoHAAANBwAADgcAAA==\"]Hg[\"AAAAApAAAAD/BAAAAAI4AAAAvgwAAAEsAQAAAAAAAAAAAAAAAAADoQEAALkEAAAADAAA\",\"AAGSBwAAAAH/BAAAAAAAAAAAAAAAAAAAAAAECwcAAAwHAAAPBwAAEAcAAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWwAAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmcAAADlBgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVMEAAA=\",\"AAAAAboMAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAasAAAA=\",\"\"]Dk[\"AAAAAewEAAABtgEAAAABrQQAAAEaEQAAAQwBAAA=\",\"AAGIBwAAAAHsBAAAAAAAARoRAAA=\"]Dk[\"AAAAATYFAAAByQEAAAACjwEAALEEAAABIREAAA==\",\"AAGhBwAAAAE2BQAAAAAAASERAAA=\"]Hc[\"AAAAAAABfQ8AAAGOEwAAAAGyEwAAAfITAAAAAAAAAAAAADowAAABAAAAAAANABAAAADQBvoIPQk2DosPjg/KD5oQqhBBEWsSbRJIE30T\",\"AAAAAAABWRIAAAE9EwAA\"]Ak[\"AAAAAAKUEwAAlRMAAA==\",\"\"]Cg[\"AAAAAZ0SAAABNAkAAAFgBAAAAAABZQQAAA==\",\"AAAAAAH/CwAA\"]Ag[\"\",\"AAAAAAAAAbMGAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmgAAABFDwAA\",\"\"]Ag[\"AAAAAAAAAAHBBgAA\",\"\"]Dk[\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwAAOzAAAAEAAD8AAgDbAD0AigEBAA==\",\"\"]Hg[\"AAAAAi0FAADqBgAAATEJAAAEWgAAAAgTAAAJEwAAchMAAAOAAQAAgQEAAPUTAAABUwMAAAABGwwAAAABZhIAAAAAAcUGAAA=\",\"AAABhw8AAAEtBQAAAcgBAAAAAUsQAAA=\"]Dk[\"AAAAAeAEAAAAASIAAAAAAbcGAAAC9gAAAPcAAAA=\",\"AAAAAuAEAAAXCgAAAAAAAakGAAA=\"]Dk[\"AAAAARcFAAAAAUgAAAACUQEAAFIBAAABvAYAAA==\",\"AAAAARcFAAABegoAAAABrgYAAA==\"]Ck[\"AAAAAcMPAAAAAAAAAnAHAACyBwAA\",\"AAAAAAAAAAACKRAAACoQAAA=\"]Ck[\"AAAAAcQPAAAAAAAAAnMHAAC0BwAA\",\"AAAAAAAAAAACKxAAACwQAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAqMQAAAXEgAA\"]Ek[\"AAAAA9UHAAAHEgAAbRMAAAAAAAAAAAGxBwAAAAABbwcAAA==\",\"AAAAAAAAAAIyEQAAMxEAAAIpEAAAKhAAAA==\"]Ek[\"AAAAA9YHAAAIEgAAbhMAAAAAAAAAAAGzBwAAAAABcgcAAA==\",\"AAAAAAAAAAI0EQAANREAAAIrEAAALBAAAA==\"]Dg[\"AAAAAQsFAAAAAUQAAAACPwEAAEABAAA=\",\"AAAAAQsFAAAAAAAAAAEbDAAAAAFmEgAA\"]Cc[\"AAAB2AIAAAH7BAAAAAE0AAAAASYBAAA=\",\"AAAAAfsEAAA=\"]Ic[\"AAABjwAAAAHSBAAAAAIcAAAAvQwAAAAAAeQAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA2gEJAgkHDQcCCQYJPg9/D0QQlBIMExwTOBM=\",\"AAF9BwAAAALSBAAAagUAAAABQw8AAA==\"]Ho[\"AAAAApIAAAABBQAAAAI6AAAAwAwAAAEuAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA3AEKAgsHDwcECQgJPw+BD0UQlRINEx0TORM=\",\"AAGUBwAAAAEBBQAAAAABRA8AAA==\"]Gk[\"AAACOgIAAEACAAAByAQAAAACEQAAAPoGAAACzQAAAM4AAAA=\",\"AAACPAIAAD0CAAAByAQAAAAAAAACTQ8AAE4PAAAAAAJcBAAAvw8AAAABvxAAAAEjDAAA\"]Do[\"AAAAAQMFAAAAAjsAAACeAAAAAzABAAAxAQAAsw8AAAFJAwAA\",\"AAAAAQMFAAAAAAAAAUAEAAA=\"]Ck[\"AAAAAnUTAAB2EwAAAAAAAAAAAAABJwwAAA==\",\"AAAAAAABoBAAAA==\"]Co[\"AAAAAAAB5gYAAAMYEgAAGRIAABoSAAAAAa0BAAA=\",\"AAAAAAABfQ8AAA==\"]K@m[\"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\",1]Eo[\"AAAAAAA7MAAAAQAABQABAFYSBQA7MAAAAQAABQABADoTBQAAOzAAAAEAAAUAAQCvEwUAOzAAAAEAAAUAAQDvEwUA\",\"\"]Ck[\"AAAAAAAAAVoFAAAAAAFMBAAA\",\"AAAAAAAAAxMMAAAUDAAAFQwAAA==\"]Cc[\"\",\"AAAAAAAESAQAAAQHAABIEQAAmBMAAAAAAlcTAACuEwAA\"]Fc[\"AAAAAf4EAAAAATcAAAACKgEAACsBAAA=\",\"AAGRBwAAAAH+BAAAAAACvg8AAEsQAAACHgwAAHgTAAAAAAECFAAAAdkTAAA=\"]Eo[\"AAAAAUURAAABLQkAAAACuAAAAAgMAAABDxEAAAABUAQAAA==\",\"AAAAAAGlBQAAAAIIDAAAeg8AAAABbAcAAAEkEAAA\"]Dk[\"AAAABhASAABpEgAA1RMAAOETAAD/EwAADhQAAAAAAAABQBMAAA==\",\"AAAAAAAAAAEHEQAA\"]A@g[\"AAAAOjAAAAEAAAAAABIAEAAAAGkEvwRoBZcGxgc4CeoLGQw2DLoMvQ/UD8QQRhFUEkMTdxOXE9wTOjAAAAEAAAAAAAcAEAAAAC4JIxATEpgS4hLnEhEUFRQ6MAAAAQAAAAAABwAQAAAA2QFGBBoMQw+6EBARZRIHEzowAAABAAAAAAAHABAAAAC5AMUQUBLQE/kTABQcFB4UAUMFAAAAAAAAAAAAAY8TAAA=\",\"AAAAAb8EAAABvggAAAABCAwAAA==\"]ACk[\"AAAAOjAAAAEAAAAAAAgAEAAAAGoEHgkMDDoPgA+XECkRrBOtEzowAAABAAAAAAAHABAAAABKBFYFawXUB/8LCBFVEpYTOjAAAAEAAAAAAAoAEAAAANsBWgTCD8cPNxBTEA4RFBLhEugSSxM6MAAAAQAAAAAABwAQAAAAGQFED74PSxBREuITHRQfFAVGBQAAHgwAAHgTAADREwAAARQAAAQSEgAAcBMAAMITAAD6EwAAAhsMAAAxDgAAAQIUAAADwRAAAGYSAADZEwAA\",\"AAAAAAAAAAAAAAAAAAFtBwAAAAAAAAGnBQAA\"]Ho[\"AAAAAxQHAAC3BwAAGBEAAAMiCQAA9QsAAPsTAAABrhAAAAABwgcAAAACog8AAA4TAAAB0wYAAA==\",\"AAAAAAT1CwAA9gsAAPcLAAD4CwAAAAWsBAAArQQAAK4EAACvBAAAUBIAAA==\"]Ho[\"AAAAAxgHAAC7BwAAHxEAAAMmCQAA+QsAAP0TAAABshAAAAABxAcAAAACpA8AABITAAAB1wYAAA==\",\"AAAAAAT5CwAA+gsAAPsLAAD8CwAAAAWwBAAAsQQAALIEAACzBAAAURIAAA==\"]No[\"AAABjgAAAAHRBAAAAAIbAAAAvAwAAAAAAeMAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAgJJBKAGBgf8CDIJFgwcDCgMew+dDyYQURBWEGEQmBCkEKsQthC4EBURNhFKEQoSDBJSEl8SmRKbEt4SHhMgE1MTWhN5E5kT1hM=\",\"AAF8BwAAAAHRBAAAAAAAAAAAAAAAAAAAAAAEAgkAAAMJAAAGCQAABwkAAA==\"]No[\"AAAAApEAAAAABQAAAAI5AAAAvwwAAAEtAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAwJLBKQGBwf9CDMJFwwdDCkMfA+eDycQUhBXEGIQmRClEKwQtxC5EBYRNxFLEQsSDRJTEmASmhKcEt8SHxMhE1QTWxN6E5oT1xM=\",\"AAGTBwAAAAEABQAAAAAAAAAAAAAAAAAAAAAEBAkAAAUJAAAICQAACQkAAA==\"]Cc[\"AAAAAecEAAAAAAAAAQMBAAA=\",\"AAAAAecEAAAAAAG1CwAA\"]Ck[\"AAAAASgFAAAAAAF3AQAA\",\"AAAAASgFAAAAAAO2CwAAtwsAALgLAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAFhBAAAAAAAASYMAAA=\",\"\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAATYPAAA=\"]Eo[\"AAAAARgFAAAAAUoAAAACVQEAAFYBAAABvQYAAA==\",\"AAAAARgFAAAAAAGvBgAAAAAAAAAAAAAAAAACTAUAADcPAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAgwUAAANFAAA\"]Ck[\"AAAAAAAAAAABwhMAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAABIxQAAA==\"]Ag[\"AAACmgIAABoDAAA=\",\"\"]Bo[\"AAAAAAAAAcEAAAAAAAABIQwAAA==\",\"AAAAAb0PAAA=\"]Cc[\"AAAAAAACGgwAAGUSAAABUA8AAA==\",\"AAAAAAABBAcAAA==\"]Gc[\"AAAAAfoEAAAAATMAAAABJQEAAAABEhIAAAEbDAAAAAFmEgAA\",\"AAGQBwAAAAH6BAAAAAHhEgAAAb4PAAAAARISAAAAAAAAAAAAAAABBQcAAA==\"]Do[\"AAAAAAAAAAFRDwAAAm0FAACCDwAA\",\"AAAAAa4BAAAAAAABUQ8AAARtBQAAgg8AAAoRAAALEQAA\"]Do[\"AAAAAAAAAAFSDwAAAm4FAACDDwAA\",\"AAAAAboBAAAAAAABUg8AAARuBQAAgw8AAAwRAAANEQAA\"]Ao[\"AAAAAAEoEAAAAAABTBAAAA==\",\"\"]Gc[\"AAABJhEAAAJjAAAAtQcAAAEQAgAAAAHJAAAAAnIEAABCEQAAAk0PAADADwAAAAFPDwAAAlwEAAC/DwAAAAIkDAAAvxAAAAIjDAAAJQwAAA==\",\"\"]Cc[\"AAAAAAAAAANdBAAAdAQAAEQRAAA=\",\"AAAAAAABwg8AAA==\"]Ec[\"AAABPAIAAAHJBAAAAAISAAAA+wYAAALPAAAA0AAAAA==\",\"AAABPwIAAAHJBAAAAAAAAkIRAABDEQAA\"]Bo[\"AAABphAAAAAAAALEAAAAxQAAAA==\",\"AAAAAAFdBQAA\"]Ck[\"AAABpxAAAAAAAAJmAQAAZwEAAA==\",\"AAAAAAAAAAAAAAABXgUAAA==\"]Ao[\"AAAAAAAAARsTAAABQA8AAA==\",\"\"]Hg[\"AAAAAmUAAADPBwAAARECAAABOQkAAAPVAAAAwgYAAF8QAAACWwUAANoPAAAAAnMFAAB9DAAABkYPAABHDwAASA8AAGkQAADAEAAAdxIAAAAAAkoPAABLDwAAAUkPAAA=\",\"\"]Dk[\"AAAAAAABOgkAAALDBgAA0AcAAAJcBQAAYBAAAAABdAUAAAFqEAAA\",\"AAAAAAABxw8AAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\",\"\"]ABc[\"AAABhw8AAAGUBgAAAsgBAAD0BgAABJMGAAAaDAAAfQ8AAGUSAAAC0BMAAAAUAAADBxEAANETAAABFAAABWwHAAAKEQAACxEAAAwRAAANEQAAASQQAAAAAAABbQcAAA==\",\"AAAABeoGAABFEQAARhEAAEcRAABJEQAAA5wBAAA8DwAAPQ8AAAFIEQAABfkTAAAcFAAAHRQAAB4UAAAfFAAAAXgTAAAB+hMAAAEREgAAAAAAAAAAAAJWDwAAcA8AAAUEAgAABQIAAIQPAACFDwAAhg8AAA==\"]Cc[\"AAAAARkFAAAAAUsAAAACVwEAAFgBAAA=\",\"AAAAARkFAAA=\"]Dc[\"AAAAAAAAAAA7MAAAAQAABQABAEkSBQA=\",\"AAAABNIBAADWAQAA1wEAANgBAAA=\"]Ao[\"AAAAAdIBAAAAAAAAAc0PAAA=\",\"\"]Ao[\"AAAAAdcBAAAAAAAAAc4PAAA=\",\"\"]Eo[\"AAAAASgRAAABBBMAAAM7EAAAvBAAABIRAAABXhMAAAEzEQAAASoQAAACOxEAABwSAAABLREAAAAAAAABkRMAAA==\",\"\"]Eo[\"AAAAASsRAAABBhMAAAM/EAAAvhAAABQRAAABYRMAAAE1EQAAASwQAAACPREAAB4SAAABLxEAAAAAAAABkxMAAA==\",\"\"]Bc[\"AAAAAAAAAnUEAADKBgAAAAHPDwAA\",\"\"]Bc[\"AAAAAAAAAngEAADNBgAAAAHQDwAA\",\"\"]Ec[\"AAAAAcwBAAAAAmoSAABsEgAAAlgTAABZEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAAEwAwAA\"]Gg[\"AAAAAcsEAAAAAhQAAAD9BgAAAtYAAADXAAAA\",\"AAADRQIAAEYCAABHAgAAAcsEAAAAAAAB2g8AAAACcwUAAH0MAAACaRAAAHcSAAAAAAABSQ8AAA==\"]Eg[\"AAAAAQYFAAAAAj4AAACgAAAAAzUBAAA2AQAAtQ8AAAFLAwAA\",\"AAAAAQYFAAAAAAAAAAF0BQAAAWoQAAA=\"]Ec[\"AAAAAAAAAWUBAAAAAAAAAAAAAAAAAAK7BAAAPgkAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAacFAAA=\"]Ec[\"AAAB8wsAAAG+BAAAAAELAAAAAbQAAAA=\",\"AAAAAb4EAAAAARAJAAAAAAAAAAAAAAAAAAABkQYAAA==\"]Dg[\"AAAAAAFYBQAAAAAAAAAAAAAAAAAAAAJkEAAACREAAA==\",\"AAF2BwAAAAAAAZMGAAA=\"]Ac[\"AAABZAIAAA==\",\"\"]Do[\"AAAAAd8EAAAAASEAAAAAAAL0AAAA9QAAAA==\",\"AAACcAIAAHECAAAB3wQAAAAAAAAAAUYTAAA=\"]Dk[\"AAAAARYFAAAAAUcAAAACTwEAAFABAAA=\",\"AAAC5AIAAOUCAAABFgUAAAAAAAAAAUcTAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAXCQAA\"]Dk[\"AAAAAAAAAAABEwEAAA==\",\"AAABjQIAAAAAAAAAAAABYgQAAAESBwAAAUIEAAABbwcAAA==\"]Dg[\"AAAAAAAAAYgBAAA=\",\"AAABEwMAAAAAAAAAAAABYwQAAAETBwAAAUQEAAABcgcAAA==\"]Dk[\"AAAAAe4EAAAAAbcBAAABrgQAAAEcEQAAAQ4BAAA=\",\"AAGJBwAAAAHuBAAAAAAAARwRAAA=\"]Dk[\"AAAAATgFAAAAAcoBAAACkQEAALIEAAABIxEAAA==\",\"AAGiBwAAAAE4BQAAAAAAASMRAAA=\"]Ck[\"AAAAAQcFAAAAAT8AAAACNwEAADgBAAA=\",\"AAAAAQcFAAAAAAHDBgAA\"]Eg[\"AAAAAdoEAAAAAiAAAACWAAAAAasPAAABQQMAAALvAAAAXRIAAA==\",\"AAGEBwAAAWkCAAAC2gQAABEKAAA=\"]Eg[\"AAAAAREFAAAAAkYAAAChAAAAAkoBAAC2DwAAAUwDAAABXhIAAA==\",\"AAGcBwAAAd4CAAABEQUAAAFyCgAA\"]Ao[\"AAAAAAAAAAACVBAAAAoRAAA=\",\"\"]Ao[\"AAAAAAAAAAACVRAAAAwRAAA=\",\"\"]Do[\"AAABbwAAAAG9BAAAAAABswAAAA==\",\"AAAAAb0EAAAAAQ8JAAAAAAAAAAAAAAAAAAABWBAAAA==\"]Bg[\"AAAAAAAABNQAAABiBQAAFQwAABoSAAA=\",\"\"]Ak[\"AAAAAAABQAAAAAE5AQAA\",\"\"]Do[\"AAAAAAAAAAAAAAAAAAAAAAAAAqMQAAAXEgAA\",\"AAF0BwAAAAAAAAAAAAAAAAAAAAAAAAFjEAAA\"]Cg[\"AAAAAAPEBgAANwkAAK0QAAA=\",\"AAAAAAAAAAJADwAATBAAAA==\"]Ag[\"AAACjQIAABMDAAA=\",\"\"]Ac[\"\",\"AAAAAU8SAAA=\"]Cc[\"AAAAATQKAAACNQoAAKYKAAABpwoAAAJlEAAAZxAAAA==\",\"\"]Gg[\"AAAAAd4EAAAB2BMAAAAAAcAIAAAE8wAAAM8PAABwEgAAvRMAAAEkEAAA\",\"AAAAA7IBAADeBAAA4xMAAAABnRMAAAABwAgAAAPPDwAAcBIAAL0TAAA=\"]Bc[\"AAAAAbIBAAAAAAAAAAAAAcoQAAA=\",\"\"]Gg[\"AAAAARUFAAAAAAFOAQAAAcEIAAAD0A8AAHISAAC+EwAAAAAAAAFtBwAA\",\"AAAAA8EBAAAVBQAA5BMAAAABnhMAAAABwQgAAAPQDwAAchIAAL4TAAA=\"]Bc[\"AAAAAcEBAAAAAAAAAAAAAc4QAAA=\",\"\"]Fg[\"AAABRgIAAAHVBAAAAAEeAAAAAAAC5wAAAOgAAAA=\",\"AAGABwAAAAHVBAAAAAE5CQAAAsIGAABfEAAAA3IEAABzBAAAWwUAAA==\"]Eo[\"AAAAAQkFAAAAAUIAAAACOwEAADwBAAA=\",\"AAGYBwAAAAEJBQAAAAE6CQAAAdAHAAAEdAQAAFwFAABgEAAARBEAAA==\"]Ao[\"\",\"AAAAAAAAAAAAAAAB0hAAAA==\"]Ek[\"AAAAAeMEAAAAASUAAAAAAAL8AAAA/QAAAA==\",\"AAABdwIAAAHjBAAAAAAAAAFsBwAAASQQAAAAAsoQAADMEAAA\"]Eg[\"AAAAAR8FAAAAAVAAAAACYwEAAGQBAAA=\",\"AAAB8QIAAAEfBQAAAAAAAAAAAALOEAAA0BAAAAABbQcAAA==\"]Ao[\"AAAAAAAAAAFBEAAAAAExDAAA\",\"\"]Jk[\"AAAAAeQEAAAABSYAAACXAAAASAUAADkQAAA7EAAAArULAACsDwAABEIDAAABDAAAOhAAADwQAAAE/gAAAP8AAAAKEQAACxEAAAItDAAALgwAAAIsEQAALREAAA==\",\"AAAAAuQEAABPEAAAArMBAAAyEAAAAAABCgkAAA==\"]Og[\"AAAAASQFAAAABVMAAACkAAAASQUAAD0QAAA/EAAABnABAABxAQAAtgsAALcLAAC4CwAAuQ8AAARPAwAAAgwAAD4QAABAEAAAAgwRAAANEQAAAi8MAAAwDAAAAi4RAAAvEQAA\",\"AAAABCQFAACpBwAAqgcAAFAQAAAEwwEAADMQAAA0EAAANRAAAAAAAQsJAAACUwUAAFQFAAAAAAAAAAAAAAA7MAAAAQAACgACAKsHBQDKBwQA\"]Cc[\"AAAAARoFAAAAAUwAAAACWQEAAFoBAAA=\",\"AAAAARoFAAA=\"]Ck[\"AAABTwUAAAHlBAAAAAEnAAAAAAABAAEAAA==\",\"AAAAAuUEAAADDAAA\"]Dg[\"AAABUAUAAAElBQAAAAFUAAAAAXIBAAAAAAAAAAAAAcUGAAA=\",\"AAAAAiUFAAAEDAAA\"]Cc[\"AAAAAT4FAAAAAWAAAAABmwEAAA==\",\"AAAAAj4FAAAFDAAA\"]Dg[\"AAAAAAAAAAAAAAABwRAAAA==\",\"AAAABjYQAABcEgAARBMAAEUTAAB1EwAAdhMAAA==\"]Ak[\"AAAAAAAAAAABSxIAAA==\",\"\"]Ak[\"AAAAAAAAAAABThIAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmoAAAAEAgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVUEAAA=\",\"AAAAAcQQAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmkAAAAFBwAA\",\"\"]Bk[\"AAAAAAAAAAAAAATTBgAA1AYAANUGAADWBgAA\",\"\"]Ec[\"AAAABJ0BAACoAQAA+QQAACUQAAAAAAEkAQAAAAAABNcGAADYBgAA2QYAANoGAAA=\",\"AAAAAfkEAAA=\"]Bg[\"AAAAAAAAAAAAAVYEAAA=\",\"AAAAAAHiEgAA\"]Ag[\"AAAAAAAB9gYAAA==\",\"\"]Cc[\"AAAAAToKAAACOQoAAKsKAAABqgoAAAJmEAAAaBAAAA==\",\"\"]No[\"AAAAAdwEAAAB9AYAAAGeEgAAAXoPAAAGEQwAAEYQAABBEwAAVRMAALUTAADdEwAAB/EAAACtAQAAdgwAAM0PAABvEgAATBMAAE4TAAABvxMAAAAAAAAAAAAAA6EGAAB6DAAAcxIAAA==\",\"AAAAAtwEAADWDwAAAAGxAQAAAXUSAAAGEQwAAEYQAABBEwAAVRMAALUTAADdEwAABXYMAADNDwAAbxIAAEwTAABOEwAA\"]Bo[\"AAAAAdYPAAAAAbEBAAAAAjoQAADLEAAAAAEtDAAA\",\"\"]Nc[\"AAAAARMFAAAAAAFMAQAAOjAAAAEAAAAAAAcAEAAAALsBEgxHEJ8SQhNWE7YT3hMFdwwAAM4PAABxEgAATRMAAE8TAAAAAAAAAAAAAAAEpwUAAKUGAAB7DAAAdBIAAA==\",\"AAAAAhMFAADXDwAAAAHAAQAAAXYSAAAGEgwAAEcQAABCEwAAVhMAALYTAADeEwAABXcMAADODwAAcRIAAE0TAABPEwAA\"]Bo[\"AAAAAdcPAAAAAcABAAAAAj4QAADPEAAAAAEvDAAA\",\"\"]Ao[\"AAAAAAAAAAACTBMAAE0TAAA=\",\"\"]Ao[\"AAAAAAAAAAACThMAAE8TAAA=\",\"\"]Dc[\"AAABRQIAAAHMBAAAAAIVAAAA/gYAAALYAAAA2QAAAA==\",\"AAABSQIAAAHMBAAA\"]Bk[\"AAAAAdUBAAAAAATTAAAAYQUAABQMAAAZEgAA\",\"\"]Ec[\"AAAAAv4SAAD/EgAAAvwSAAD9EgAABO8LAADwCwAA8QsAAPILAAAE6wsAAOwLAADtCwAA7gsAAA==\",\"\"]Cc[\"AAAAAAAAAAABShIAAA==\",\"AAF3BwAAAAKsAQAA3BIAAA==\"]Cc[\"AAAAAAAAAAABTRIAAA==\",\"AAGMBwAAAAK5AQAA3RIAAA==\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAABxQYAAA==\"]Cg[\"AAAAATsPAAAAAAFvAQAAATgQAAA=\",\"AAGoBwAAAAAAAUsTAAA=\"]Ek[\"AAAAAcMEAAAAAAG+AAAAAAAAAAAAAAAAAAAE2BIAAOASAAD7EgAAFhMAAA==\",\"AAF4BwAAAALDBAAAaQUAAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzsJAADLDwAADBQAAA==\",\"\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzwJAADMDwAADRQAAA==\",\"\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAYCQAA\"]Bc[\"AAAAAAABQQQAAA==\",\"AAAAAAGpBAAA\"]Ec[\"AAAAAfAEAAAAAbgBAAABrwQAAAIeEQAAcxMAAAEQAQAA\",\"AAGKBwAAAAHwBAAAAAAAAh4RAABzEwAA\"]Ec[\"AAAAAToFAAAAAcsBAAACkwEAALMEAAACJREAAHQTAAA=\",\"AAGjBwAAAAE6BQAAAAAAAiURAAB0EwAA\"]Ag[\"\",\"AAAAAAABDhIAAA==\"]Co[\"AAAAAqIBAACpBwAAAAABaAEAAA==\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Ac[\"\",\"AAAAAAGhEgAA\"]Cg[\"AAAAAAAAAnUSAAB2EgAAAAABERIAAA==\",\"AAAAAAAAAAFQEwAA\"]Do[\"AAAAAQQFAAAAAjwAAACfAAAAAzIBAAAzAQAAtA8AAAFKAwAA\",\"AAAAAQQFAAAAAAABXQQAAA==\"]Ak[\"AAAAAAACnRMAAJ4TAAA=\",\"\"]Ac[\"AAAAAdYBAAA=\",\"\"]Ac[\"AAAAAdgBAAA=\",\"\"]Eo[\"AAAC+QIAAA8DAAABLgUAAAABWwAAAAKCAQAAgwEAAA==\",\"AAAAAS4FAAAAAAAFpwYAAKgGAACpBgAAqgYAAKsGAAA=\"]Fk[\"AAAABEgQAABJEAAARBMAAEUTAAABPA8AAAGgEAAAAQ8SAAAAAAG/EwAAAAAAAAAAAAEmDAAA\",\"AAAAAAAAAxgSAAAZEgAAGhIAAA==\"]Fc[\"AAAAAAABkwYAAAJ1EgAAdhIAAAEHEQAAAAEREgAAAAACmxMAAJwTAAAAAAAB7BIAAA==\",\"AAAAAAAAAdQTAAABUBMAAA==\"]Ag[\"\",\"AAAAAAABRQUAAA==\"]Co[\"AAAAAQwFAAAAAUUAAAACQQEAAEIBAAA=\",\"AAAAAQwFAAAAAAAAAAExDgAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAeQGAAA=\",\"\"]Jc[\"AAAAAtsEAAC7EwAAAAAAAgUSAADaEgAABPAAAACtAQAAKwwAAOkSAAADPwkAAEYTAAC/EwAAAAAAAZ4QAAA=\",\"AAGFBwAAAAKwAQAA2wQAAAAAAAIFEgAA2hIAAAIrDAAA6RIAAAI/CQAARhMAAAAAAAGeEAAA\"]Jg[\"AAAAAhIFAAC8EwAAAAABSwEAAAO7AQAABhIAANsSAAACLAwAAOoSAAACQAkAAEcTAAAAAAABnxAAAA==\",\"AAGdBwAAAAK/AQAAEgUAAAGbBgAAAAACBhIAANsSAAACLAwAAOoSAAACQAkAAEcTAAAAAAABnxAAAA==\"]Ao[\"AAAAAAAAAcYAAAAAAAFYBAAA\",\"\"]Bc[\"AAAAAAABSQAAAAJTAQAAVAEAAA==\",\"\"]Ag[\"AAAClQIAACIDAAA=\",\"\"]Ak[\"AAAAAAAAAnYEAADLBgAA\",\"\"]Ak[\"AAAAAAAAAnkEAADOBgAA\",\"\"]Ag[\"AAAClgIAAB4DAAA=\",\"\"]Dk[\"AAAAAcoEAAAAAhMAAAD8BgAAAtEAAADSAAAA\",\"AAABQAIAAAHKBAAAAAAAAAAAAU8PAAA=\"]Dg[\"AAAAAccEAAAAAhAAAAD5BgAAAssAAADMAAAA\",\"AAABOgIAAAHHBAAAAAAAAAHADwAA\"]Co[\"AAABFRIAAAEIBQAAAAFBAAAAAToBAAA=\",\"AAGXBwAAAQEJAAABCAUAAA==\"]Ec[\"AAAAAAABFhIAAAG1AAAAAAAAAAAAAAAAAAADbQQAAP4IAABTDwAA\",\"AAAAAaoBAAAAAAAAAUATAAA=\"]Hk[\"AAAC0gIAAOsCAAABJgUAAAABVQAAAAJzAQAAdAEAAAAAAAAAAAAAAAAABAgCAABMBQAApgYAAOMGAAA=\",\"AAABAAMAAALEAQAAJgUAAAAAAmATAABhEwAAAAACPBEAAD0RAAA=\"]Fc[\"AAAAAzYQAABKEAAAXBIAAAACahIAAGwSAAADmAEAAFgTAABZEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAcwBAAA=\"]Dc[\"AAAAAmIAAADGBAAAAg8CAAC/CAAAAQ8AAAAByAAAAA==\",\"AAAAAsYEAADVDwAA\"]Eg[\"AAAAAeEEAAAAASMAAAAAAAL4AAAA+QAAAAAAAAAAAAAAAAPfBgAALw8AADYPAAA=\",\"AAABcwIAAAHhBAAA\"]Eg[\"AAAAARsFAAAAAU0AAAACWwEAAFwBAAAAAAAAAAAAAAAAAAPhBgAAMQ8AADcPAAA=\",\"AAAB6wIAAAEbBQAA\"]Hk[\"AAAFKgIAAD0CAAA/AgAARwIAAEkCAAAB1gQAAAACHwAAAP8GAAAAAALpAAAA6gAAAA==\",\"AAADYQIAAGICAABkAgAAAtYEAACXBgAAAqUFAAAjEAAAAQcTAAABeg8AAAEPEQAA\"]Ek[\"AAAAAQoFAAAAAkMAAAAABwAAAj0BAAA+AQAA\",\"AAAB0gIAAAEKBQAAAAAAAAAAAAAAAAAAAAACuwQAAOQGAAA=\"]Bk[\"AAAAAAABNxAAAAFuAQAA\",\"AAAAAAAAAAE4EAAA\"]Fc[\"AAABjwAAAAHTBAAAAAG9DAAAAAAB5QAAAAAAAAAAAAAAAAQKBwAADgcAAAMJAAAHCQAA\",\"AAF+BwAAAALTBAAAaAUAAA==\"]Fc[\"AAAAApIAAAACBQAAAAHADAAAAS8BAAAAAAAAAAAAAAAAAAQMBwAAEAcAAAUJAAAJCQAA\",\"AAGVBwAAAAECBQAAAWsFAAA=\"]Ag[\"AAAClAIAAB0DAAA=\",\"\"]Cg[\"AAAAAUAFAAAAAAADQA8AAKYPAABMEAAA\",\"AAGnBwAAAAFABQAA\"]Dc[\"AAAAAiAFAACqBwAAAAABaQEAAA==\",\"AAAAASAFAAAAAAAAAAAAAAAAAAGwBgAA\"]Dg[\"AAAAAe0SAAAB2A8AAAAAAALrAAAACxEAAA==\",\"AAEMCQAAAa8BAAAB7RIAAAHYDwAA\"]Dg[\"AAAAAe4SAAAB2Q8AAAABRgEAAAABDREAAA==\",\"AAENCQAAAb4BAAAB7hIAAAHZDwAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATQPAAA=\",\"\"]Ac[\"\",\"AAAAAAHDEwAA\"]Ag[\"AAAClwIAAB8DAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAADSRIAAEoSAABLEgAA\"]Bc[\"\",\"AAAAAAAAAAADTBIAAE0SAABOEgAA\"]Ak[\"\",\"AAAAAW4SAAAAAAGOEwAA\"]ADc[\"AAAAAdcEAAAAAAA6MAAAAQAAAAAAFAAQAAAAvwfBDEEPiQ+MD8gPxhA/EVMRZxLUEnsT0hPfE+sT7RMPFBMUFhQaFCEUOjAAAAEAAAAAAAwAEAAAAOwAVBDCEF0SbxJwEgoTNhNJE/cTCBQKFBgUAAABOBEAAA==\",\"AAGBBwAAAAHXBAAAAAAAOjAAAAEAAAAAABQAEAAAAL8HwQxBD4kPjA/ID8YQPxFTEWcS1BJ7E9IT3xPrE+0TDxQTFBYUGhQhFDowAAABAAAAAAAJABAAAABUEMIQXRIKEzYTSRP3EwgUChQYFAAAATgRAAA=\"]ADc[\"AAAAAQ4FAAAAAAFHAQAAOjAAAAEAAAAAABQAEAAAAMAHwgxCD4oPjQ/JD8cQQBFUEWgS1RJ8E9MT4BPsE+4TEBQUFBcUGxQiFDowAAABAAAAAAALABAAAABVEMMQXhJxEnISCxM3E0oT+BMJFAsUGRQAAAE5EQAA\",\"AAGZBwAAAAEOBQAAAAAAOjAAAAEAAAAAABQAEAAAAMAHwgxCD4oPjQ/JD8cQQBFUEWgS1RJ8E9MT4BPsE+4TEBQUFBcUGxQiFDowAAABAAAAAAAJABAAAABVEMMQXhILEzcTShP4EwkUCxQZFAAAATkRAAA=\"]Ag[\"AAACcQIAAOQCAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAU0EAAA=\",\"AAAAAAAAAQgMAAA=\"]Bk[\"AAAAAAAAAAAAAAEgDAAA\",\"AAAAAAABmBMAAA==\"]Do[\"AAAAAeIEAAAAASQAAAAAAAL6AAAA+wAAAAAAAAAAAAAAAALgBgAAMA8AAA==\",\"AAAAAeIEAAA=\"]Do[\"AAAAARwFAAAAAU4AAAACXQEAAF4BAAAAAAAAAAAAAAAAAALiBgAAMg8AAA==\",\"AAAAARwFAAA=\"]Ag[\"AAACmQIAACEDAAA=\",\"\"]Fc[\"AAAAAR4FAAAAAk8AAACiAAAAAmEBAAC3DwAAAk0DAAA4EAAA\",\"AAAAAR4FAAAAAAAAAAAAAAABbQcAAAAAAAABpwUAAA==\"]Ac[\"\",\"AAAAAAFuBwAA\"]Ao[\"AAAAAAGpBAAA\",\"AAAAAAFxBwAA\"]Ag[\"AAACkgIAABkDAAA=\",\"\"]Ag[\"AAACkwIAABsDAAA=\",\"\"]Dg[\"AAAAAfIEAAAAAAAB4xIAAAAAAAHMEAAA\",\"AAAAAvIEAAA0CgAAATUKAAAAAWUQAAA=\"]Do[\"AAABzQEAAAEyBQAAAAAAAeUSAAAAAAAB0BAAAA==\",\"AAAAATIFAAABpgoAAAGnCgAAAWcQAAA=\"]Do[\"AAAAAfQEAAAAAAADPBAAAM0QAADkEgAAAAEuDAAA\",\"AAAAAvQEAAA6CgAAATkKAAAAAWYQAAA=\"]Eg[\"AAABzgEAAAE0BQAAAAAAA0AQAADREAAA5hIAAAABMAwAAA==\",\"AAAAATQFAAABqwoAAAGqCgAAAWgQAAA=\"]Cc[\"AAAAAAAAAncEAADMBgAAAAEEAQAA\",\"AAGHBwAAAAG0AQAA\"]Cc[\"AAAAAAAAA3kBAAB6BAAAzwYAAA==\",\"AAGgBwAAAAHGAQAA\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA94GAACwBwAAzgcAAA==\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATMPAAA=\",\"\"]Ao[\"AAAAAAAAAawEAAAAAQgUAAA=\",\"\"]Bk[\"AAAAAAAAAbAEAAAAAQkUAAA=\",\"AAAAAbQEAAA=\"]Eg[\"AAAAAAAAAAABEQEAAAAAAAAAAAAAAANBCQAApw8AAJYSAAA=\",\"AAGLBwAAAAS3BwAAuAcAALkHAAC6BwAA\"]Eg[\"AAAAAAAAAZQBAAAAAAAAAAAAAAAAAANCCQAAqA8AAJcSAAA=\",\"AAGkBwAAAAS7BwAAvAcAAL0HAAC+BwAA\"]Bo[\"AAAAAAABsQEAAAAAAXYMAAAAAWIEAAAAAUIEAAA=\",\"\"]Bo[\"AAAAAAABwAEAAAAAAXcMAAAAAWMEAAAAAUQEAAA=\",\"\"]Ak[\"AAAAAAABCBMAAAFvEwAA\",\"\"]Ao[\"AAAAAAABCRMAAAAAAXATAAA=\",\"\"]Fo[\"AAAAASMFAAAAAlIAAACjAAAAA2wBAABtAQAAuA8AAAFOAwAA\",\"AAAB+QIAAAEjBQAAAAAAAAJTBQAAVAUAAAAAAAAAAALCAQAAsAYAAA==\"]Dg[\"AAAAAfwEAAAAATUAAAABJwEAAA==\",\"AAAAAfwEAAAAAAAAAAAAAAAAAAAAAAHlBgAA\"]Dg[\"AAAAAcEEAAAAAgwAAAD4BgAAArsAAAC8AAAA\",\"AAABKgIAAAHBBAAAAAABxRAAAA==\"]Do[\"AAAAAfcEAAAAAjEAAACcAAAAAyABAAAhAQAAsQ8AAAFHAwAA\",\"AAAAAfcEAAAAAAAAAWUEAAA=\"]Ek[\"AAAAAdgEAAAAAAACURMAAKUTAAAD7QAAAKgQAAA2EwAA\",\"AAGCBwAAAAHYBAAAAAAAAlETAAClEwAAAagQAAA=\"]Ek[\"AAAAAQ8FAAAAAAFIAQAAAlITAACmEwAAAqkQAAA3EwAA\",\"AAGaBwAAAAEPBQAAAAAAAlITAACmEwAAAakQAAA=\"]Bo[\"AAAAAAAAAAABUwUAAAAAAAAAAALCAQAAsAYAAA==\",\"\"]Fg[\"AAAAAdkEAAAAAAAEIAkAANIPAAAwEQAAARMAAALuAAAASRMAAA==\",\"AAGDBwAAAAHZBAAAAAAABCAJAADSDwAAMBEAAAETAAA=\"]Fg[\"AAAAARAFAAAAAAFJAQAABCEJAADTDwAAMREAAAITAAABShMAAA==\",\"AAGbBwAAAAEQBQAAAAAABCEJAADTDwAAMREAAAITAAA=\"]Ag[\"\",\"AAAAAAAAAdQTAAA=\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAAAAAHsEgAA\"]Ag[\"\",\"AAAAAAAAAVAPAAA=\"]Co[\"AAAAAf0EAAAAATYAAAACKAEAACkBAAA=\",\"AAAAAf0EAAAAAAAAARISAAA=\"]Fg[\"AAABUQIAAAHmBAAAAAEoAAAAAAG4BgAAAgEBAAACAQAA\",\"AAACegIAAJ8GAAAB5gQAAAAAAAGqBgAAAAAAAAAAAAAAAAEvDwAA\"]Gc[\"AAABugIAAALEAQAAJwUAAAABVgAAAAJ1AQAAdgEAAAG/BgAA\",\"AAACAQMAAKMGAAABJwUAAAAAAbEGAAAAAAAAAAAAAAAAAAIIAgAAMQ8AAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA6wHAADLBwAAwwgAAA==\",\"\"]Cg[\"AAABdwIAAAAAAAAAARQBAAA=\",\"AAAAAAAAAAI6EAAAPBAAAA==\"]Cg[\"AAAB8QIAAAAAAAGJAQAA\",\"AAAAAAAAAAM+EAAAQBAAAEEQAAA=\"]Bo[\"AAAAArQEAAA/BQAAAaESAAA=\",\"AAAAAj8FAABWEQAA\"]Bo[\"AAAAAAAAAcIAAAAAAAABIgwAAA==\",\"AAAAAXcTAAA=\"]Io[\"AAAAAS8FAAAAAVwAAAABhAEAAAZ1BQAAyxAAAM0QAADPEAAA0RAAANMQAAAAAAAFyhAAAMwQAADOEAAA0BAAANIQAAAAAAAAAAABIBQAAA==\",\"AAAAAS8FAAAAAARdEwAAXhMAAGATAABhEwAAAAFeBAAA\"]Co[\"AAAAAmQAAAC2BwAAAAABygAAAAJzBAAAQxEAAAFODwAA\",\"AAABJhEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAuEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhcJAAAwEAAA\",\"\"]Co[\"AAAAAfMEAAAAAAAAAhcBAAAYAQAA\",\"AAAAAfMEAAAAAAJlEAAAZhAAAA==\"]Dc[\"AAAAATMFAAAAAAKMAQAAjQEAAA==\",\"AAAAAjMFAABPEgAAAAACZxAAAGgQAAA=\"]Cc[\"AAAAAAGcAQAAAAG3AAAAAAAAAR8MAAA=\",\"AAAAAZcTAAA=\"]Ac[\"\",\"AAAB8wsAAA==\"]Ec[\"AAABcAIAAAHOBAAAAAEXAAAAAAAC3QAAAN4AAAA=\",\"AAAAAc4EAAAEEwkAAP4JAAD/CQAAAQoAAA==\"]Do[\"AAAB5QIAAAH2BAAAAAEvAAAAAh0BAAAeAQAA\",\"AAAAAfYEAAAEFAkAAFAKAABRCgAAUgoAAA==\"]Ak[\"\",\"AAAAAAACnRMAAJ4TAAA=\"]Ck[\"AAAAAsAEAAAqCQAAAb4IAAAB2RIAAAG6AAAA\",\"AAAAAsAEAADUDwAA\"]Cg[\"AAAAAU0HAAACHxAAADIQAAAAAbULAAAAAAAAAAABnhAAAA==\",\"\"]Ck[\"AAAAAU4HAAACIBAAADMQAAAAArYLAAC3CwAAAAAAAAAAAZ8QAAA=\",\"\"]Bc[\"AAAAAAAAAAAAAAAAApsTAACcEwAA\",\"\"]Fo[\"AAAAAd0EAAAAAAADZwQAACsJAAC1EwAAAvIAAACmAQAA\",\"AAGGBwAAAAHdBAAAAAAAAmcEAAArCQAAAaYBAAAAAAAAAAAAAAABcxIAAA==\"]Fo[\"AAAAARQFAAAAAAFNAQAAA2gEAAAsCQAAthMAAAGnAQAA\",\"AAGeBwAAAAEUBQAAAAAAAmgEAAAsCQAAAacBAAAAAAAAAAAAAAABdBIAAA==\"]Ck[\"AAAAAQ0FAAAAAAJDAQAARAEAAA==\",\"AAAAAQ0FAAAAAAAAAcITAAA=\"]Ec[\"AAAAASEFAAAAAAFqAQAAAAAAAAAAAAAAAAAFowEAAKsHAADKBwAAwggAAHgMAAA=\",\"AAAAASEFAAA=\"]Dg[\"AAAAAAHDEwAAAAG2AAAAAAAAAAACmxMAAJwTAAAAAAAB7BIAAA==\",\"AAABqwEAAA==\"]Ag[\"AAACmAIAACMDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAAAAAAAApsTAACcEwAA\"]Cc[\"AAAAAUEFAAAAAAAAAAAAAdIQAAA=\",\"AAABzQEAAAFBBQAA\"]Ck[\"AAAAAUIFAAAAAAACQRAAANMQAAAAATEMAAA=\",\"AAABzgEAAAFCBQAA\"]Ag[\"AAACnAIAACADAAA=\",\"\"]Dg[\"AAAAAAABLAAAAAAAARIBAAA=\",\"AAAAAAAAAAAAAAAAAAAAA48TAACQEwAAkRMAAA==\"]Ck[\"AAAAAAABXgAAAAGHAQAA\",\"AAAAAAAAAAAAAAAAAAAAApITAACTEwAA\"]Ag[\"AAACmwIAABgDAAA=\",\"\"]Do[\"AAAAAU8HAAACIRAAADQQAAAAAbgLAAABXRAAAA==\",\"AAK9AQAAjQcAAAEOCQAAAAAAAAFdEAAA\"]Ec[\"AAAAAikFAABQBwAAAiIQAAA1EAAAAAF4AQAAAV4QAAA=\",\"AAGfBwAAAcUBAAABKQUAAAAAAAFeEAAA\"]Bg[\"AAAAAAAAAAABVAUAAA==\",\"AAABvAEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAvEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhgJAAAxEAAA\",\"\"]") \ No newline at end of file diff --git a/pr/545/docs/search.index/type/f972a24a9b65.js b/pr/545/docs/search.index/type/f972a24a9b65.js deleted file mode 100644 index bc67de679..000000000 --- a/pr/545/docs/search.index/type/f972a24a9b65.js +++ /dev/null @@ -1 +0,0 @@ -rd_("CBk[\"\",\"ADswAAABAAAFAAIALAQEAMMTAAACswYAANIGAAA6MAAAAQAAAAAACgAQAAAA1gHXAUkFWAzfESMSOBKiE64TzBPbEzowAAABAAAAAAAaABAAAAAFAgYCBwIIAgkCCgILAjsESAVNBYEGrwbeBiAJfxDiESQSthJhE2ITpRPIE8kTyhPLE94T4hM7MAAAAQAAKgESADkEAAA1BQAARwUAALQGAADRBgAA4QYAAA8MAwCWDAUAgQ2FAAkQAACAEAcA3hAAAE0RhQDjEQAA5REAAG0SAAC3EgAA1RIAADowAAABAAAAAAAdABAAAABKBVAFUQVSBa0Grga1BrYGtwa4BrkGugaVC5YLlwuYC+gLHw8jDzEQlxDeEekSJRMmEzwTnROhE68TzRM7MAAAAQAAPQAUADQDFABXBAAAYwQCADMFAQA2BQAASwUBAGUFAACgBgwArQcDAJQLAAD+CwAAeQ8AAK0PAAAyEAAA1xAAAG4SAACyEgMAHRMAAJ4TAADOEwAAOzAAAAEAAFcADQDVAD0AhAEBAFYEAABbBwAAXgcAAJ0HAACfBwAA/A8DABgSBQANEwAAPRMAAHwTBQCPEwAAOzAAAAEAABUABwA9BAAAWQwAAAcOAAB1DwMA4BEAANwSBwC8EwUAOzAAAAEAABMACQBTBAEAXAQBAL4GBwCcBwAAngcAABkPAgAiDwAAkhAAAEYSAAAD/QYAAP4GAAA1EgAAAQQMAAAFWAcAAFoHAABdBwAAAQwAAJEQAAAAOzAAAAEAAAUAAgC7AQAAXBMEAAAAAZYFAAA=\"]Bo[\"AAAAAAAAAAACihMAAIsTAAAAAAAAAnAQAABxEAAA\",\"\"]0Bg[\"\",\"AAAFAgkAAAMJAAAECQAABQkAAAYJAAA=\"]AGg[\"AAAAAAKsAQAAvAEAAAAAAjMFAAA0BQAABFsHAABeBwAAnQcAAJ8HAAA7MAAAAQAADQAFAGMFAQAoCQEACgwEAFkMAAAKEQMAOjAAAAEAAAAAAAsAEAAAAFwEXQScB54HIg87EDwQ/BD9EP4Q/xBGEgRNBAAA/QYAAP4GAACSDwAABDMEAAA1BAAAaBMAAGkTAAAFUgQAAFoHAABdBwAAHA8AAB0PAAADAAwAAAIMAAAeDwAAOzAAAAEAAAYAAwC7AQAAmwYAAFwTBAABuxIAAAEDDAAA\",\"AAAAASYRAAAAAjgFAAA5BQAAAALhCwAA4gsAAAAFCgwAAAsMAAAMDAAADQwAAA4MAAAAAAIzBAAANQQAAA==\"]ANg[\"AAAESQIAAK0CAACKBgAAjgYAAAPjCwAA5AsAAOULAAACrAEAALwBAAA7MAAAAQAAhQABAE0RhQAAOzAAAAEAAAcAAwAzBQEAshIDAO4TAQAEWwcAAF4HAACdBwAAnwcAADswAAABAAASAAcAYwUBANMGAAAoCQEACgwEAFkMAAAKEQMA6hEDADowAAABAAAAAAAKABAAAABTBFQEXARdBJwHngciD/wQ/RD+EP8QBU0EAABOBQAA/QYAAP4GAACTEAAABDMEAAA1BAAAaBMAAGkTAAAEWgcAAF0HAAAcDwAAHQ8AAASwBgAAAAwAAAIMAAAeDwAABVwTAABdEwAAXhMAAF8TAABgEwAAAbsSAAAAAZYFAAA=\",\"AAAAAAACOAUAADkFAAAAAuELAADiCwAAAZMPAAAFCgwAAAsMAAAMDAAADQwAAA4MAAAAAAIzBAAANQQAAAAAAAAAA8kGAADlEAAA5hAAAA==\"]Dc[\"\",\"AAAAADswAAABAAAHAAEACwkHADswAAABAAAJAAIAjBAEAOAQBAAAAd8QAAA=\"]ADm[\"AAAABqkBAACrAQAAuAEAALoBAACpDwAAqg8AAASvAQAAwgEAABkKAAAdCgAAOjAAAAEAAAAAAAkAEAAAAKoBsAGxAbkBwwHEAYsKjgpqE2sTOzAAAAEAAA0ABACdBAcATQ8AADcQAwA8EwAAArQBAABuEgAAOzAAAAEAABUACgCfAQEApgEAAAgMAQBSDAEAoA8DACYQAQA+EgMADRMAAIoTAQDVEwEAAYwTAAAAAAAAAAAAAAGWBQAA\",\"AAABpAEAAAKlBAAA0xEAAAAAAAITDwAAHhAAAAAAAAAAAAAAAAAEjAYAAJAGAABWDAAAVwwAAA==\",1]Fk[\"AAAABNsEAAAABwAAowcAAOkQAAACDAkAANYLAAABgRAAAAABrgcAAAEFAQAAAnYPAADdEgAAAb8GAAA=\",\"AAAAAdsEAAABrwEAAA==\"]Fk[\"AAAABCUFAAAEBwAApwcAAPAQAAACEAkAANoLAAABhRAAAAGIAQAAAbAHAAAAAngPAADhEgAAAcMGAAA=\",\"AAAAASUFAAABwgEAAA==\"]AEa[\"AAAAAqcBAACzAQAAOzAAAAEAAAcAAQALCQcAAARQBQAAUQUAAFIFAADeEQAAAAABjBMAAAAAAAJwEAAAcRAAAA==\",\"AAAAADswAAABAAAQAAMAgQYAAAsJBwDVCwcAOzAAAAEAAAsABADhBgAAchAAAIwQBADgEAQAOzAAAAEAAA8ABQCdBAcA8wsCAOcRAgAfEgAAoRMAADowAAABAAAAAAAKABAAAACdEJ8QoRCjEKUQ3xACEQMRBBEFER0TBPwPAAD9DwAA/g8AAP8PAAAAAAWcEAAAnhAAAKAQAACiEAAApBAAAAAAAAAAAAKWBQAAGA8AAA==\",1]Ec[\"AAAAAAAAOzAAAAEAAAYAAgCXBgMAnAYCADswAAABAAAGAAIAkgYEAPMIAQADTwQAAEMFAABEBQAA\",\"\"]Dg[\"AAAAAAAAAAABfRMAAAG9EwAAAAAAAAAAAAABPwcAAA==\",\"AAAAAAABJhIAAAEIEwAA\"]Eo[\"AAAAAdkEAAABrgEAAAIpAAAAmAAAAAGBDwAAATkDAAACAAEAAAEBAAA=\",\"AAABpwAAAAHZBAAAAcsSAAAAAc0LAAA=\"]Ic[\"AAAAARsFAAADwAEAAOUSAABjEwAAAlcAAAClAAAABnUBAAB2AQAANAQAAJUFAACODwAArxMAAAFGAwAA\",\"AAABqAAAAAIbBQAAzRIAAAAB0QsAAAAAAAAAAAAAAAAAAAKpAAAAqgAAAA==\"]Ik[\"AAAAAq0EAAA9EgAAAd4GAAABfgYAAAGxAAAAAdcQAAABfBMAAALgEQAAvBMAAAAAAAAAAAAAOjAAAAEAAAAAAAkAEAAAAFcFfAY8B70HWw9yD6QPKhB0EA4R\",\"AAAAAa0EAAAAASUSAAABBxMAAA==\"]Ck[\"AAAAAdYBAAAAAAAAAYATAAABwBMAAA==\",\"AAAAAAABKRIAAAELEwAA\"]Ck[\"AAAAAdcBAAAAAAAAAYETAAABwRMAAA==\",\"AAAAAAABKhIAAAEMEwAA\"]Kc[\"AAAAAAAABEoFAABQBQAAUQUAAFIFAAAAOzAAAAEAAAkAAQCKCwkAOzAAAAEAAA0AAQA9BA0ABf8LAAAZDwAAGg8AABsPAACSEAAAAAEEDAAAAwEMAAAcDwAAHQ8AAAICDAAAHg8AAA==\",\"AAAAAAABchAAAAPzCwAA9AsAAPULAAA=\"]Nk[\"AAAAAAAAAkQSAABFEgAABLISAACzEgAAtBIAALUSAAACuBIAALkSAAAF0wYAAOoRAADrEQAA7BEAAO0RAAACUwQAAFQEAAACTgUAAJMQAAAAAAGwBgAAAAAAAZYFAAA=\",\"AAAAAAJGBQAAkBMAAAAFxhMAAOkTAADqEwAA6xMAAOwTAAABHRMAAAKTDwAAxxMAAAAAAAAAAAAAAAQAEAAAARAAAAIQAAADEAAA\"]Bg[\"AAAAAAAAAAQjEQAAJBEAAEATAABBEwAA\",\"\"]Bk[\"\",\"AAAAASIRAAAAAAAAAAAAAAAAAAAAAAEmDwAA\"]Cc[\"AAAAAAAAATEQAAABMhAAAA==\",\"AAAAAAACIgkAACMJAAA=\"]FGo[\"AAAAADswAAABAAAVAAkABQIGADsEAABbBQAAvwcAAN8LAAAEEAMAJBIAAGETAQDIEwMAOzAAAAEAAA0CEgAyBAAASwQAAFEEAAC0BgAAzwsDAJYMBQCeDGgBlQ8AAJoPAAAJEAAAJRAAAIAQBwDeEAAATRGFAOMRAADlEQAAtxIAABgTAAA7MAAAAQAAvgAPALEAIwATAXAAhgEPADQEAABKBQAAlQUAAJcGAwCcBgIArQYBAMsLAwAXDwAA6RIAAAcTBQCvEwAAwhMAADswAAABAACiAEIANAMUAE4EAABYBAEAYwQCADYFAABLBQEAZQUAAJIGBACgBgwAqgcBAK0HAwCnCAEA8wgBAAkJAQAUCQEA4QsBAPELAQD+CwAAnAwBABQPAQAkDwEAXA8BAF8PAQB5DwAAmw8BAKUPAQCtDwAAChAAABgQAQAvEAEAMhAAAJgQAQDfEAAA6hAAAOwQAADuEAAA8RAAAPMQAAD1EAAAABEFAA8RAQASEQIAIxEBANQRAQA2EgEAbhIAAKMSAQCpEgEAshIDAM8SAQAOEwEAHhMBACITAQBAEwEASBMBAHITAQCCEwEAnhMCAKoTAwC4EwMAzhMAANwTAQDgEwEA4xMBAOcTAQDuEwEAOzAAAAEAAI8AJgDVAD0AhAEBAJ8BAQAxBAAATwQAAFYEAABDBQEAXQUBAFsHAABeBwAAnQcAAJ8HAACKCwkACAwBAFIMAQAgDwEAVQ8BAJMPAACgDwMAJhABAHoQAQCUEAEA4REAACwSAQA+EgMAuBIBANgSAQADEwEAFhMBABkTAwA9EwAAfBMFAIoTAQCPEwAAxBMBAMcTAADVEwMA5RMBADswAAABAAAxAA0APQQNAGMFAQDTBgAAKAkBAPsLAABZDAAABw4AAHUPAwAKEQMA6hEDANwSBwATEwEAvBMFADowAAABAAAAAAAYABAAAABTBFQEXARdBL4GvwbABsEGwgbDBsQGxQacB54H/wsZDxoPGw8iDzsQPBCSEEYSphPPEwdNBAAATgUAAJIPAACTEAAACBEAAAkRAAA1EgAAAzMEAAA1BAAABAwAADowAAABAAAAAAAJABAAAABSBFgHWgddBwEMHA8dD3AQcRCREASwBgAAAAwAAAIMAAAeDwAAOzAAAAEAAAUAAgCbBgAAXBMEAAABAwwAAAGWBQAA\",\"AAAAAAA7MAAAAQAA4gABAJ4M4gAAOjAAAAEAAAAAAFkAEAAAAFgEWQSqB6sHpwioCAkJCgkUCRUJ4QviC/EL8gucDJ0MFA8VDyQPJQ9cD10PXw9gD5sPnA+lD6YPGBAZEC8QMBCYEJkQ6hDsEO4Q8RDzEPUQABEBEQ8REBEjESQR1BHVETYSNxKjEqQSqRKqEs8S0BIOEw8THhMfEyITIxNAE0ETSBNJE3ITcxOCE4MTnxOgE6oTqxOsE60TuBO5E7oTuxPcE90T4BPhE+MT5BPnE+gT7hPvEzswAAABAAAvABQAnwEBAF0FAQAIDAEAUgwBAFUPAQCgDwMAJhABAHoQAQCUEAEALBIBAD4SAwC4EgEA2BIBAAMTAQAWEwEAGRMDAIoTAQDEEwEA1RMDAOUTAQAEKAkAACkJAAATEwAAFBMAAAACCBEAAAkRAAAAAnAQAABxEAAA\"]Ic[\"AAAAAecQAAAABEcFAAD4CAAA+QgAAN0RAAA7MAAAAQAADAADAGYEBQC1BgUAWxMAAAADVwcAAJQQAACVEAAAAfcPAAAAB5wQAACeEAAAoBAAAKIQAACkEAAACBEAAAkRAAAAAVgHAAA=\",\"\"]Lk[\"AAACSgIAAKwCAAAAAq8BAADCAQAAOzAAAAEAAAsAAwCwAQEAwwEBAIAQBwA7MAAAAQAABwABAJ0EBwA6MAAAAQAAAAAABwAQAAAAqgerB1wPXQ+lD6YPABEBEQACExMAABQTAAA=\",\"AAAAAVMPAAAAAAAAAAAAAAAAAAAAAAVSDwAAVA8AAFsPAABeDwAAFRMAAA==\"]AAg[\"AAAERgIAAKoCAAD6CAAA+wgAAASlAQAArQEAALIBAAC/AQAAAk4CAAC0AgAAAAA6MAAAAQAAAAAAEwAQAAAAWARZBKcIqAgMEA4QEBASEBMQnRCfEKEQoxClEDYSNxLgE+ET4xPkEwK4EgAAuRIAAAUKDAAACwwAAAwMAAANDAAADgwAAAAFnBAAAJ4QAACgEAAAohAAAKQQAAAAAAACuwEAAJsGAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAABKkIAACqCAAAqwgAAKwIAAA=\"]BKo[\"AAAD9wgAAKUSAACmEgAABaMBAAD7CQAAIhEAAKsSAACsEgAAOjAAAAEAAAAAAAcAEAAAAK4BwAH8CP0I4gk2Cl4K4hEB4xEAAAHpEgAAOjAAAAEAAAAAABEAEAAAAK0HrgevB7AHEw+bD5wPHhDqEOwQ7hDxEPMQ9RAOEw8TqhOrEwENEwAAOzAAAAEAAAsAAgB1DwMA3BIHADswAAABAAAJAAMAvgYHAJwHAACeBwAAAAACWgcAAF0HAAA=\",\"AAAEPQUAAD4FAAALDwAADA8AADswAAABAAAWAAsA/wYHAOgQAQDrEAAA7RAAAO8QAQDyEAAA9BAAANYRAQA6EwEAPhMAAIgTAQAC5RIAAGMTAAAB3REAAAAAAAAAAAAAAAAAADowAAABAAAAAABrABAAAACZAZoBnAGdAfsB/AECAgMCOgQ8BF4EpwSqBIsGjwa8Br0G8QbyBuUI5ggbCRwJ3gvgC/YL9wv8C/0LBQwGDBEPEg8nD04PTw9wD3EPpA/5D/oPFhAXECMQJBAoECkQMxA0EGoQaxB0EHYQdxB9EH4QiBCJEIoQixAGEQcRGhEbEdkR2hHbEdwRIRIiEi4SLxI6EjwSYxJkEmUSZhJoEmkSahJrEqcSrRKuEq8SyRLaEtsS5BLqEusS7BLtEu4S7xIFEwYTIBMhEycTKBNGE0cTZhNnE6MTpBM=\"]Ac[\"AAAAAAElAwAA\",\"\"]Ca[\"AAAAAAJOAgAAtAIAADswAAABAAAFAAEAHBEFAA==\",\"\",1]Ek[\"AAAAAAAAAAAAAAAAAAAAAAAAArEGAADHBgAA\",\"AAAAAAACCxAAAA0QAAAAAgwQAAAOEAAAAALqEQAA6xEAAA==\"]Eo[\"AAAAAAAAAAAAAAAAAAAAAAAAArIGAADIBgAA\",\"AAAAAAACDxAAABEQAAAAAxAQAAASEAAAExAAAAAC7BEAAO0RAAA=\"]Ck[\"AAAAAAAAAAAAAAAAAAAAAAAABW8AAACdAQAAmAcAALcHAACrCAAA\",\"\"]Bg[\"AAAAAAAAAR8PAAAAAAAAAggRAAAJEQAA\",\"\"]Gk[\"AAAABGAAAAC1BAAAWgUAAKgPAAABBwIAAAYNAAAAOQQAADUFAADvBgAAGBEAAGUTAAACwQAAACMPAAAAAiQTAAB7EwAA\",\"AAAAAbUEAAABpggAAAE3BAAA\"]Ho[\"\",\"AAAAAAAAAAA7MAAAAQAACQABAIoLCQA7MAAAAQAADQABAD0EDQAF/wsAABkPAAAaDwAAGw8AAJIQAAAAAQQMAAAEAQwAABwPAAAdDwAAkRAAAAMADAAAAgwAAB4PAAAAAAEDDAAA\"]Bg[\"AAAAAAAAAAAAAAAAAAJwEAAAcRAAAA==\",\"\"]Hk[\"AAADyQEAAOoLAADtCwAAAdgEAAABrgEAAAQoAAAAlwAAAAsQAAANEAAAAYAPAAABOAMAAAP/AAAA2hAAANsQAAA=\",\"AAACyQEAAOYLAAACWgQAANgEAAAByhIAAAABzAsAAA==\"]Hk[\"AAADygEAAOsLAADuCwAAARoFAAABwAEAAARWAAAApAAAAA8QAAAREAAAAnQBAACNDwAAAUUDAAADTwQAANwQAADdEAAA\",\"AAACygEAAOcLAAADWwQAABoFAADMEgAAAAHQCwAA\"]2ALo[\"AAAAAAH7DwAAAAA6MAAAAQAAAAAAEQAQAAAAtAFOBPEL8gucDJ0MFA8VD5gQmRDUEdURuBO5E9wT3RPnE+gTAlYEAAANEwAAOzAAAAEAAAsAAgB1DwMA3BIHADswAAABAAAHAAEAvgYHAAAAAAACuwEAAJsGAAA=\",\"AAAHPwUAAEAFAADqCwAA6wsAAO0LAADuCwAA5BEAADowAAABAAAAAAAXABAAAACgB6EHBwkTCewL7wvwCw0PDg8aEBsQHBBpEOcQ9xD4EPkQ+hD7EBATeRN6E40TjhM7MAAAAQAA9gACAA8O8gDREgMAOzAAAAEAAFgABAALAFQAqBIAANYSAQA/EwAAAcITAAAAAAQKEQAACxEAAAwRAAANEQAABPwQAAD9EAAA/hAAAP8QAAABNRIAAAAAAAAAAAdiBAAAVwUAALsGAAAMDgAAbBAAAHwQAAAOEQAA\"]Dk[\"AAAAAALlCQAANQoAAAAAADswAAABAAAFAAEAGBIFAAACUwQAAFQEAAAAAjMEAAA1BAAA\",\"\"]BOc[\"\",\"ADswAAABAAAFAAIALAQEAMMTAAACswYAANIGAAA6MAAAAQAAAAAACgAQAAAA1gHXAUkFWAzfESMSOBKiE64TzBPbEzowAAABAAAAAAAaABAAAAAFAgYCBwIIAgkCCgILAjsESAVNBYEGrwbeBiAJfxDiESQSthJhE2ITpRPIE8kTyhPLE94T4hM7MAAAAQAAJgERADkEAAA1BQAARwUAALQGAADRBgAA4QYAAJYMBQCBDYUACRAAAIAQBwDeEAAATRGFAOMRAADlEQAAbRIAALcSAADVEgAAOjAAAAEAAAAAABsAEAAAAEoFUAVRBVIFrQauBrUGtga3BrgGuQa6BpULlguXC5gLHw8jDzEQlxDeEekSJRMmEzwTnROvE80TOzAAAAEAADsAEgA0AxQAVwQAAGMEAgAzBQEANgUAAEsFAQBlBQAAoAYMAK0HAwCUCwAA/gsAAHkPAACtDwAAMhAAAG4SAACyEgMAnhMAAM4TAAA7MAAAAQAAUgALANUAPQCEAQEAVgQAAFsHAABeBwAAnQcAAJ8HAAAYEgUAPRMAAHwTBQCPEwAAOzAAAAEAABQABgA9BAAAWQwAAAcOAAB1DwMA3BIHALwTBQA7MAAAAQAAEwAJAFMEAQBcBAEAvgYHAJwHAACeBwAAGQ8CACIPAACSEAAARhIAAAL9BgAA/gYAAAEEDAAABFoHAABdBwAAAQwAAJEQAAAABVwTAABdEwAAXhMAAF8TAABgEwAA\"]Bc[\"AAAAAAAAAAAAAAACCBEAAAkRAAA=\",\"\"]Kc[\"AAAAAAGxEgAAADswAAABAAAGAAIAtQYFAJcQAAACNgUAAK0PAAABVgQAAAADOxAAADwQAABGEgAAAZIPAAA=\",\"AAAAAAABUQQAADswAAABAAAFAAEAZgQFAAAAAAAAAAAAAAAABwQCAACmBAAAqQQAAMoGAADLBgAAzAYAAM0GAAA=\"]Do[\"AAAAAAABFwAAAAAAAdkAAAAAAAAAAAAAAAACpgQAALwGAAA=\",\"AAAAAAAAAAACIA8AACEPAAA=\"]Dk[\"AAAAAAABLwAAAAEZAQAAAAAAAAAAAAAAAAACqQQAAL0GAAA=\",\"AAAAAAAAAAABMQQAAA==\"]Ac[\"AAABVgIAAA==\",\"\"]Fg[\"AAAABN0EAAABBwAApAcAAOsQAAADDQkAANcLAADJEwAAAYIQAAAAAAEHAQAAAd4SAAABwAYAAA==\",\"AAAAAd0EAAAAAbABAAA=\"]Fg[\"AAAABCcFAAAFBwAAqAcAAPIQAAADEQkAANsLAADLEwAAAYYQAAABigEAAAAAAeISAAABxAYAAA==\",\"AAAAAScFAAAAAcMBAAA=\"]Bk[\"\",\"AAAAAAAAAAA7MAAAAQAAPwACANUAPQCEAQEA\"]Ck[\"\",\"AAAAAAGBBgAAOzAAAAEAAAkAAgDhBgAA4wYIAAGhEwAAAR0TAAA=\"]Ck[\"AAACWAIAAGgCAAA=\",\"AAAAAAAAAioTAAArEwAAAAACChEAAAsRAAA=\"]Bo[\"\",\"AAAAAAAAAAAAAAAAAmgTAABpEwAAAAAAAbsSAAA=\"]Eo[\"\",\"AAAAAAA7MAAAAQAABQABACUSBQA7MAAAAQAABQABAAcTBQAAOzAAAAEAAAUAAQB8EwUAOzAAAAEAAAUAAQC8EwUA\"]Cc[\"\",\"AAAAAALKEgAAyxIAAAAEywsAAMwLAADNCwAAzgsAAA==\"]Eg[\"AAAAAeEEAAAAASwAAAAAAAIPAQAAEAEAAA==\",\"AAA7MAAAAQAACgABAIgCCgAC4QQAALATAAAAAAFEEgAA\"]Eo[\"AAAAASEFAAAAAV4AAAAAAAKEAQAAhQEAAA==\",\"AAA7MAAAAQAACgACAA0DAwASAwYAAiEFAACxEwAAAAABRRIAAA==\"]Dg[\"AAAB9QIAAAEgBQAAAAFcAAAAAn8BAACAAQAA\",\"AAABBAMAAAEgBQAAAAAAAAFPBAAA\"]Eo[\"AAAAAAAAAo8BAACQAQAA\",\"AAAAAAAAB50TAADGEwAAzRMAAOkTAADqEwAA6xMAAOwTAAACnhMAAM4TAAABxxMAAA==\"]Bk[\"AAAAAAAAAT8BAAA=\",\"AAABzQIAAAAAAUsEAAA=\"]Bo[\"AAAAASsFAAAAAAGRAQAA\",\"AAAAASsFAAABRBMAAA==\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAVQMAAA=\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA5kHAAC4BwAArAgAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmIEAACaBwAA\",\"\"]Cc[\"AAAAAAAAAALzCAAA9AgAAAAAAAAAAAACuwEAAJsGAAA=\",\"\"]Fo[\"AAAAAAACRwUAAOURAAAAAAAAAAAAAAAAAAAEvgcAACcPAAA1EAAAJREAAA==\",\"AAFgBwAAAAAAAAAAAAAAAAAAAAAAAAI2EAAA2RAAAA==\"]Bk[\"AAAAAUkFAAAAAAEfDwAAAXkPAAA=\",\"AAGRBwAA\"]Bg[\"AAAAAAAABDcQAAA4EAAAORAAADoQAAA=\",\"\"]Ag[\"AAAAAqcBAACzAQAA\",\"\"]Dg[\"AAAAAAAAAAAAAigJAAApCQAA\",\"AAAAAAAAAAAABQoMAAALDAAADAwAAA0MAAAODAAA\"]AEg[\"AAAAAAKsAQAAvAEAAAAAAjMFAAA0BQAABFsHAABeBwAAnQcAAJ8HAAA7MAAAAQAACwAEAGMFAQAKDAQAWQwAAAoRAwA6MAAAAQAAAAAACwAQAAAAXARdBJwHngciDzsQPBD8EP0Q/hD/EEYSBE0EAAD9BgAA/gYAAJIPAAAEMwQAADUEAABoEwAAaRMAAAVSBAAAWgcAAF0HAAAcDwAAHQ8AAAMADAAAAgwAAB4PAAA7MAAAAQAABgADALsBAACbBgAAXBMEAAG7EgAAAQMMAAA=\",\"AAAAASYRAAAAAjgFAAA5BQAAAALhCwAA4gsAAAAAAAACMwQAADUEAAA=\"]He[\"\",\"AAAAAAAEDwwAABAMAAARDAAAEgwAAALoCwAAoRMAAALXEAAAHRMAAAX8DwAA/Q8AAP4PAAD/DwAADRMAAAHgEQAAAAE1EgAAAAFYBwAAAAG7AQAAAAABlgUAAA==\",1]AMk[\"AAACtQEAAL4BAAAGpQEAAK0BAACyAQAAvwEAAKsSAACsEgAABEgFAAAgCQAA4wkAADQKAAAEDwwAABAMAAARDAAAEgwAAAIlEwAAJhMAADowAAABAAAAAAAHABAAAADzCPQIGBAZEKMSpBKfE6ATOjAAAAEAAAAAAAkAEAAAADEEWwdeB50HnwcgDyEPkw/EE8UTAAKcBwAAngcAAA==\",\"AAAAOjAAAAEAAAAAABAAEAAAAJsBOAc5BzoHOwfAB8EHEwyWD5cPLhCaEJsQMhIzEmwSqRMDHQkAAPsPAABnEgAABg8MAAAQDAAAEQwAABIMAAA5EgAAOxIAAAAAAAJjBQAAZAUAAAACTQQAAJIPAAAAA1IEAAAcDwAAHQ8AAAMADAAAAgwAAB4PAAAAAAIDDAAAXgwAADowAAABAAAAAAALABAAAACeAV8EYASoBKsEegZ7BvMGPAe9B74Hcg8=\"]Bg[\"AAAAAAAAAAAAAUgEAAA=\",\"AAAAAZMFAAA=\"]Bk[\"AAAAAAAAADswAAABAAANAAIAZQUAAKAGDAA=\",\"\"]Cc[\"AAAB6ggAAAABCwIAAAAAAAExBAAA\",\"AAAAAAAAAAFOBAAA\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAZsGAAA=\",\"\"]Be[\"AAAAAAAAA1AFAABRBQAAUgUAAA==\",\"\",1]Bg[\"AAAAAAAAADswAAABAAAUAAEANAMUAA==\",\"\"]Dk[\"AAAAAAHBAQAA\",\"AAAAAAUWCQAAFwkAABgJAAAZCQAAGgkAAAAAAAAAAAAAAAAAAAHQDwAA\"]Bg[\"AAAAAAAAAAAAAUMEAAA=\",\"AAAAAbEHAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWUAAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAakAAAA=\",\"\"]BOa[\"AAAAAAHBAQAAAW0SAAABPBMAAAK0AQAAbhIAADowAAABAAAAAAAbABAAAACmAV0FXgVVD1YPehB7ECwSLRLYEtkSAxMEExYTFxMZExoTGxMcEyQTPRN7E8QTxRPXE9gT5RPmEzswAAABAAAGAAMAKAkBAHUPAwCMEwAAAqYTAADPEwAAAAAAAbAGAAAAAAABlgUAAA==\",\"AAAFAgkAAAMJAAAECQAABQkAAAYJAAAE4wsAAOQLAADlCwAA0xEAADswAAABAAAWAAsAmgQAAFkHAABcBwAAsgcAAKUIAQAWCQQAHQkAAPIPBABnEgAAcBIAANESAwA7MAAAAQAAIQAPANIBAADUAQAAMgQAADcEAABLBAAAUQQAAOMGCAAPDAMAFg8AACUQAACMEAQA4BAEALASAAAYEwAAZBMAADswAAABAAAjAAkANAQAAGYEBQCVBQAAuwcAABcPAAB8DxMAHxIBACoTAQAtEwEAOzAAAAEAAAgABAAKEAAAAhEDABIRAgBFEwAAOzAAAAEAAAwABgAxBAAAIA8BAPwPAwDaEAMAJBMAAHsTAAAE6hEAAOsRAADsEQAA7REAAAP/CwAAphMAAM8TAAADTQQAAJIPAACTEAAAAAABsAYAAAG7AQAAAAA6MAAAAQAAAAAAHAAQAAAAqwCsAK0ArgCRBp8G7AbtBu4G4wgkCSUJJgknCSoJKwlhD3oPew+dD54Pnw8rECwQLRAREdgRShPtEw==\",1]Bg[\"AAAAAAAAAAAAAAAAAAJwEAAAcRAAAA==\",\"\"]Jo[\"AAAAAb8EAAAAOjAAAAEAAAAAAAcAEAAAABgAlADSATcEFg8dESAR1hICfQ8AAB8SAAACNQMAAKEGAAAC2gAAANsAAAAAAZwHAAAAAAFaBwAA\",\"AAFlBwAAAANgAAAAYQAAAL8EAAACTgIAALIHAAACHREAACARAAAAAZMGAAA=\"]A@c[\"AAAAAegEAAAABzEAAACcAAAA1AEAAB8RAAAhEQAAsBIAANcSAAAHHAEAAB0BAAAXDwAAhQ8AAJEPAAAdEAAAIBIAAAQ9AwAApgYAAP4LAABFEwAAAeERAAABBw4AAAOeBwAAphMAAM8TAAAAAAFdBwAA\",\"AAF6BwAAAAHoBAAAArQCAABGBQAAAh8RAAAhEQAAAZgGAAAAAAH7CwAAAAE1EgAAAAAAAAAABWUAAABmAAAAZwAAAGgAAABpAAAA\"]Bo[\"\",\"AAAAAAAAOzAAAAEAAKQAAwCxACMAEwFwAIYBDwA=\"]CCm[\"\",\"AAA7MAAAAQAA4gABAKcK4gA7MAAAAQAA6QAMALIJLwDkCQAA5gkyABoKAgAeChUANwoeAFcKBgBfCioAjAoBAJAKFgAeEgAAsBMBADowAAABAAAAAAASABAAAABNBZQFgQb8CP0I4gnjCeUJGQodCjQKNQo2ClYKXgqKCo8KyhLLEjowAAABAAAAAAASABAAAAA5BDUF4QbvBiIJIwmLCo4KGBElEiYSJxIoEikSKhLVEmUTahNrEzowAAABAAAAAAApABAAAACtBq4GuweVC5YLlwuYC8sLzAvNC84L6AsjD00PkQ8dEDEQNxA4EDkQOhCXEEQSRRIHEwgTCRMKEwsTDBMqEysTLRMuE50ToRPGE80T6RPqE+sT7BM6MAAAAQAAAAAAGgAQAAAATgRjBGQEZQRLBUwFkgaTBpQGlQaWBv4LrQ8MEA4QEBASEBMQMhDfEBIRExEUER0TRROeE84TOzAAAAEAAFkADwDVAD0AhAEBADEEAABPBAAAVgQAAEMFAQBXBwAAIA8BAJMPAADhEQAAGBIFACQTAAB7EwYAjxMAAMcTAAA7MAAAAQAAEQAIAGMFAQD7CwAAWQwAAAcOAAD3DwAAChEDABMTAQC8EwUAOjAAAAEAAAAAAAcAEAAAAFMEVAQiDzsQPBBGEqYTzxM6MAAAAQAAAAAACgAQAAAATQROBf0G/gaSD5wQnhCgEKIQpBA1EgQzBAAANQQAAGgTAABpEwAABFgHAABaBwAAXQcAAJEQAAACAAwAAB4PAAA7MAAAAQAABgADALsBAACbBgAAXBMEAAG7EgAAAAGWBQAA\",1]Le[\"\",\"AAAAAsUBAAB/BgAAA98GAAAPDwAAEA8AAAPRBgAAORIAADsSAAA6MAAAAQAAAAAABwAQAAAAHw/eEecR6BHpESUTJhNbEwJXBAAAlAsAAAGmAQAAAYwTAAAEGQ8AABoPAAAbDwAAkhAAAAABBAwAAARSBAAAAQwAABwPAAAdDwAAAQIMAAAAAAEDDAAA\",1]Gc[\"\",\"AAAAOjAAAAEAAAAAAAcAEAAAANYB1wHfETgSohOuE8wT2xMC3gYAAPsPAAAFfgYAAPgIAAD5CAAAUA8AAN0RAAAB6RIAAAHXEAAAAQ0TAAA=\"]Bo[\"\",\"AAAAAswSAADNEgAAAATPCwAA0AsAANELAADSCwAA\"]Bk[\"\",\"AAAAAAAAOzAAAAEAAAYAAgCXBgMAnAYCAA==\"]Fc[\"AAAAAb0BAAAAAAAABF0FAABeBQAAVQ8AAFYPAAA=\",\"AAA7MAAAAQAAPQABABQMPQAAAAAAAAAAAAAAAAAAAAABzgYAAA==\"]Ao[\"\",\"AAA7MAAAAQAA4gABAMIH4gA=\"]A@o[\"AAAEXgIAAG8CAAB1AgAACw8AAAG9BAAAA7YSAADeEwAA4hMAAAMVAAAAkwAAABwRAAABfA8AADowAAABAAAAAAAMABAAAAA0A2MEZAQzBTQFSwWgBg8RHhNIE3ITrBO6EwLVAAAA1gAAAA==\",\"AAFkBwAAOzAAAAEAAAYAAwBGAgQA+ggAAKUSAAABvQQAAAT8CAAA4gkAAOMJAADlCQAAARwRAAABywsAAAOSBgAAEhEAABMRAAAAAAAAAAAAAAAAAQMPAAA=\"]ABc[\"AAAE0wIAAPYCAAD9AgAADA8AAAHlBAAAAAQtAAAAmgAAAB4RAAC3EgAABBUBAAAWAQAAgw8AAK8TAAA6MAAAAQAAAAAACgAQAAAAOwNlBDYFTAWlBhARHxNJE3MTrRO7EwABBw4AAA==\",\"AAF5BwAAB6oCAACrAgAArAIAAK0CAACvAgAA+wgAAKYSAAAB5QQAAAT9CAAANAoAADUKAAA2CgAAAs8LAAAeEQAAApcGAAC7BwAAARQRAAAAAAAAAAAAAAAABAUPAAAGDwAABw8AAAgPAAA=\"]Gc[\"AAA7MAAAAQAACwAEAO0PBADOEgAAdBMEAN8TAAA=\",\"ADswAAABAAAJAAMAPQcBAEAHAgCeEgQAOzAAAAEAAAsABADtDwQAzhIAAHQTBADfEwAA\"]Ho[\"AAAAAAAAAAA7MAAAAQAACQABAIoLCQA7MAAAAQAADQABAD0EDQAF/wsAABkPAAAaDwAAGw8AAJIQAAAAAQQMAAAEAQwAABwPAAAdDwAAkRAAAAMADAAAAgwAAB4PAAAAAAEDDAAA\",\"\"]Cc[\"AAAAAqkBAACaEAAAAAAAAAEIDAAAAAFcBAAAAf0GAAA=\",\"\"]Cc[\"AAAAArgBAACbEAAAAAAAAAEJDAAAAAFdBAAAAf4GAAA=\",\"\"]ABc[\"AAAAArwSAAC9EgAAAAWwAQAAsQEAAMMBAADEAQAA3hAAADswAAABAAALAAMAnQQHAEoFAADzCwIAOjAAAAEAAAAAAAcAEAAAADYFrQeuB68HsAckDyUPeQ8H2hAAANsQAADcEAAA3RAAAD0TAACPEwAAxxMAADswAAABAAANAAQA+wsAAAcOAAB1DwMA3BIHADswAAABAAAHAAEAvgYHAAKTEAAANRIAAAABWAcAAAGwBgAAAAAAAZYFAAA=\",\"AAAAA8wBAADNAQAAzgEAAAABJRAAAA==\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACQQUAANQGAAA=\",\"AAAAAAAAAAICEQAAAxEAAAAAAAAAAAAAAAACsQYAAMcGAAA=\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACQgUAANYGAAA=\",\"AAAAAAAAAAIEEQAABREAAAAAAAAAAAAAAAACsgYAAMgGAAA=\"]Ak[\"\",\"AAAAAAJzDwAAdA8AAA==\"]Eo[\"AAAABN8EAAACBwAApQcAAO0QAAACDgkAANgLAAABgxAAAAAAAQkBAAAB3xIAAAHBBgAA\",\"AAAAAd8EAAAAAbEBAAA=\"]Eo[\"AAAABCkFAAAGBwAAqQcAAPQQAAACEgkAANwLAAABhxAAAAGMAQAAAAAB4xIAAAHFBgAA\",\"AAAAASkFAAAAAcQBAAA=\"]Bg[\"AAAAAAAAAAAAAUIEAAA=\",\"AAAAASEJAAA=\"]Ag[\"AAACqAEAALcBAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAIBDAAAkRAAAA==\",\"\"]Ag[\"\",\"AAACFBAAABUQAAA=\"]Bg[\"AAAAAAAAAAAAAeARAAA=\",\"AAABbgAAAA==\"]Dg[\"AAAAAswBAADNAQAAAAADUAUAAPMLAADnEQAAAAGmAQAAAYwTAAA=\",\"AAAAAdMRAAA=\"]Hg[\"AAAAAfcQAAAB0RIAAAMLEAAAjRAAAOEQAAABKhMAAAECEQAAAfwPAAACChEAAOoRAAAB/BAAAAAAAAABXRMAAA==\",\"AAAAAAAAAAKdEAAAnxAAAAAAAAKcEAAAnhAAAA==\"]Ig[\"AAAAAfoQAAAB0xIAAAMPEAAAjxAAAOMQAAABLRMAAAEEEQAAAf4PAAACDBEAAOwRAAAB/hAAAAAAAAABXxMAAA==\",\"AAAAAAHYEAAAAAADoRAAAKMQAAClEAAAAAAAA6AQAACiEAAApBAAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAm0AAAAIDwAA\",\"\"]Bk[\"AAAAAAAAAdQAAAAAAAFKBAAA\",\"AAAAAboHAAA=\"]Cc[\"AAAAAS4QAAAB5RIAAAACNAQAAJUFAAA=\",\"AAAAAAG/BwAA\"]Ek[\"AAAAAcQEAAAAARwAAAAAAAHgAAAAAAAAAAAAAAAAAqgEAAB6BgAA\",\"AAFqBwAAAAHEBAAAAAAAAAAAATsQAAA=\"]Ek[\"AAAAAfUEAAAAATwAAAABLgEAAAAAAAAAAAAAAAAAAqsEAAB7BgAA\",\"AAGBBwAAAAH1BAAAAAAAAAAAATwQAAA=\"]Be[\"AAAAAAA7MAAAAQAAhQABAE0RhQA=\",\"\",1]Bg[\"AAAAAAAAAAAAAUUEAAA=\",\"AAAAAcoLAAA=\"]Ec[\"AAAAAAAAAAAAAAAAAAJaBwAAXQcAAAGwBgAAArsBAACbBgAA\",\"AAAAAAAAAAAAAAAAAAAAAbsBAAA=\"]Dk[\"AAAAAAAAAAABfhMAAAG+EwAA\",\"AAAAAAABJxIAAAEJEwAAAAAAAAAAAAAAAAABPwcAAA==\"]Dg[\"AAAAAQ0FAAAAAAJZAQAAWgEAAAGpBgAAAAAAAAAAAAAAAAEEAgAA\",\"AAAAAQ0FAAA=\"]ABc[\"AAAAA6MBAAD0CQAAIhEAAAOvBgAAVgoAAH8QAAAAADowAAABAAAAAAANABAAAAAJCQoJFAkVCV8PYA8vEDAQqRKqEs8S0BIiEyMTOzAAAAEAAA8ABwB6EAEAGBIFANgSAQAkEwAAexMAANcTAQDlEwEAAAKmEwAAzxMAAA==\",\"AAAAA5YBAAChAQAA+A8AAATyDwAA8w8AAPQPAAD1DwAAAtIBAADUAQAAAAACJBMAAHsTAAAAAqYTAADPEwAAAAAAAAAAAATTAQAA1QEAAOcIAAAlEQAA\"]Bk[\"AAAAAAHeBgAA\",\"AAAAAAAAAAHXEAAAAAHgEQAA\"]Ho[\"AAAABbMEAABZBQAAkwUAAFgMAAAyEgAAAhAPAAClEwAAAtEGAABtEgAAA7sAAADeEQAAPBMAAAE0BQAAAVcHAAAB9w8AAA==\",\"AAAAArMEAAB/BgAAAd8GAAAAAAABpgEAAAGMEwAA\"]Gc[\"AAAAAjMSAAA+EwAAAYYGAAABtAYAAAEUAQAAAgoQAABuEgAAAAHTBgAAAAFOBQAAAAFYBwAAAbAGAAAAAAABlgUAAA==\",\"AAAAAAAAAAG0AQAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWwAAAA=\",\"\"]Fg[\"AAADswYAANIGAABtDwAABO8LAAAhEAAAFxEAAI0TAAAFBgIAAE0FAACUBQAAWQcAABgJAAAAAr0AAABNDwAA\",\"AAABeBAAAA==\"]Fg[\"AAAABPALAAAiEAAAGREAAI4TAAACXAcAABkJAAABtAYAAAFcAQAAAAAB0wYAAAABTgUAAAAAAAAAAAGWBQAA\",\"AAABeRAAAA==\"]Dg[\"AAAAARIFAAAAAVAAAAABZQEAAA==\",\"AAAAARIFAAAAAAAAAAAAAAAAAAAAAAFvAAAA\"]Bk[\"AAAAAAEFAgAAAAAAAAE/BAAA\",\"AAAAAfkLAAA=\"]Cc[\"AAAAAAGyBwAAAAAAAAFABAAA\",\"AAAAAAAC+gsAADQSAAA=\"]Dk[\"\",\"AAAAADswAAABAAATAAEAQwcTADswAAABAAATAAEAkwATADswAAABAAATAAEAfA8TAA==\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWoAAAA=\",\"\"]Ak[\"\",\"AAAAAAKQDwAARBMAAA==\"]Ag[\"\",\"AAAAAAABZBMAAA==\"]Fg[\"AAAAASwFAAAAAAGTAQAAAAAAAAAAAVIEAAAAAAABAwwAAAatAAAAngEAAP4BAACfBgAA8wYAANgRAAA=\",\"AAGQBwAAAAEsBQAA\"]Hk[\"AAAEpwAAAEcCAAA9BQAA5gsAAAHaBAAAAAIqAAAAmQAAAAGCDwAAAjoDAACkBgAAAgIBAAADAQAA\",\"AAABdQIAAARiAAAAYwAAAGQAAADaBAAAAa4BAAAAAc4LAAABlgYAAA==\"]Kc[\"AAAEqAAAAKsCAAA+BQAA5wsAAAEcBQAAAARYAAAApgAAAJUPAACaDwAAA3cBAAB4AQAAjw8AAAJHAwAAqwYAAA==\",\"AAAB/QIAAAEcBQAAAcABAAAB0gsAAAM0BAAAlQUAAJ0GAAAAAAAAAAAAAAAAAARqAAAAawAAAGwAAABtAAAA\"]Ak[\"AAAAAAKrDwAArA8AAA==\",\"\"]Ao[\"AAAAAAAAAAACnwEAABgSAAA=\",\"\"]Ao[\"AAAAAAAAAAACoAEAABsSAAA=\",\"\"]Dc[\"AAAAAAAAAAABBAEAAAAAAAAAAAAAAAWrAAAAXwQAAOwGAABXDwAAKxAAAA==\",\"\"]Fc[\"AAAAAAAAAXkBAAAAAAAAAAAAAAAAAAWsAAAAYAQAAO0GAABYDwAALBAAAA==\",\"AAAAAAAAAAAAAdMGAAAAAk4FAACTEAAA\"]Fc[\"AAAAAS0FAAAAAAGUAQAAAlcEAACUCwAAAAAAAAEEDAAAAAAAAAAFrgAAAO4GAADkCAAAWQ8AAC0QAAA=\",\"AAAAAS0FAAA=\"]Hg[\"AAABjAAAAAHABAAAAAIZAAAAlgwAAAAAAdwAAAAAAAAAAAAAAAADmQEAAKcEAADeCwAA\",\"AAFmBwAAAAHABAAAAAAAAAAAAAAAAAAAAAAE9AYAAPUGAAD4BgAA+QYAAA==\"]Hg[\"AAAAAo8AAADvBAAAAAI3AAAAmQwAAAEmAQAAAAAAAAAAAAAAAAADmgEAAKoEAADgCwAA\",\"AAF9BwAAAAHvBAAAAAAAAAAAAAAAAAAAAAAE9gYAAPcGAAD6BgAA+wYAAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAG7EgAA\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWsAAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmYAAADQBgAA\",\"\"]Bg[\"AAAAAAAAAAAAAUQEAAA=\",\"AAAAAZUMAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAaoAAAA=\",\"\"]Dk[\"AAAAAdwEAAABrwEAAAABngQAAAHqEAAAAQYBAAA=\",\"AAFzBwAAAAHcBAAAAAAAAeoQAAA=\"]Dk[\"AAAAASYFAAABwgEAAAACiQEAAKIEAAAB8RAAAA==\",\"AAGMBwAAAAEmBQAAAAAAAfEQAAA=\"]Hc[\"AAAAAAABUA8AAAFbEwAAAAF/EwAAAb8TAAAAAAAAAAAAADowAAABAAAAAAANABAAAAC7BuMIJgkMDl4PYQ+dD2wQfBAREToSPBIVE0oT\",\"AAAAAAABKBIAAAEKEwAA\"]Ak[\"AAAAAAJhEwAAYhMAAA==\",\"\"]Cg[\"AAAAAWwSAAABHQkAAAFRBAAAAAABVgQAAA==\",\"AAAAAAHfCwAA\"]Ag[\"\",\"AAAAAAAAAZ4GAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmcAAAAYDwAA\",\"\"]Ag[\"AAAAAAAAAAGsBgAA\",\"\"]Dk[\"AAAAAAAAOzAAAAEAAKQAAwCxACMAEwFwAIYBDwAAOzAAAAEAAD8AAgDVAD0AhAEBAA==\",\"\"]Hg[\"AAAAAh0FAADVBgAAARoJAAAEWQAAANYSAADXEgAAPxMAAAN6AQAAewEAAMITAAABSAMAAAAB+wsAAAABNRIAAAAAAbAGAAA=\",\"AAABWg8AAAEdBQAAAcEBAAAAAR0QAAA=\"]Dk[\"AAAAAdAEAAAAASEAAAAAAaIGAAAC8AAAAPEAAAA=\",\"AAAAAtAEAAD7CQAAAAAAAZQGAAA=\"]Dk[\"AAAAAQcFAAAAAUcAAAACSwEAAEwBAAABpwYAAA==\",\"AAAAAQcFAAABXgoAAAABmQYAAA==\"]Ck[\"AAAAAZYPAAAAAAAAAlsHAACdBwAA\",\"AAAAAAAAAAAC/A8AAP0PAAA=\"]Ck[\"AAAAAZcPAAAAAAAAAl4HAACfBwAA\",\"AAAAAAAAAAAC/g8AAP8PAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAnUQAADmEQAA\"]Ek[\"AAAAA8AHAADWEQAAOhMAAAAAAAAAAAGcBwAAAAABWgcAAA==\",\"AAAAAAAAAAICEQAAAxEAAAL8DwAA/Q8AAA==\"]Ek[\"AAAAA8EHAADXEQAAOxMAAAAAAAAAAAGeBwAAAAABXQcAAA==\",\"AAAAAAAAAAIEEQAABREAAAL+DwAA/w8AAA==\"]Dg[\"AAAAAfsEAAAAAUMAAAACOQEAADoBAAA=\",\"AAAAAfsEAAAAAAAAAAH7CwAAAAE1EgAA\"]Ac[\"\",\"AAAAAAGQDwAA\"]Cc[\"AAABzQIAAAHrBAAAAAEzAAAAASABAAA=\",\"AAAAAesEAAA=\"]Ic[\"AAABjgAAAAHCBAAAAAIbAAAAmAwAAAAAAd4AAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA0wECAvQG+AbrCO8IEQ9SDxYQYxLaEuoSBRM=\",\"AAFoBwAAAALCBAAAWgUAAAABFg8AAA==\"]Ho[\"AAAAApEAAADxBAAAAAI5AAAAmwwAAAEoAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA1QEDAvYG+gbtCPEIEg9UDxcQZBLbEusSBhM=\",\"AAF/BwAAAAHxBAAAAAABFw8AAA==\"]Gk[\"AAACLwIAADYCAAABuAQAAAACEAAAAOUGAAACxwAAAMgAAAA=\",\"AAACMAIAADECAAABuAQAAAAAAAACIA8AACEPAAAAAAJNBAAAkg8AAAABkRAAAAEADAAA\"]Do[\"AAAAAfMEAAAAAjoAAACdAAAAAyoBAAArAQAAhg8AAAE+AwAA\",\"AAAAAfMEAAAAAAAAATEEAAA=\"]Ck[\"AAAAAkITAABDEwAAAAAAAAAAAAABBAwAAA==\",\"AAAAAAABchAAAA==\"]Co[\"AAAAAAAB0QYAAAPnEQAA6BEAAOkRAAAAAaYBAAA=\",\"AAAAAAABUA8AAA==\"]K@e[\"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\",1]Eo[\"AAAAAAA7MAAAAQAABQABACUSBQA7MAAAAQAABQABAAcTBQAAOzAAAAEAAAUAAQB8EwUAOzAAAAEAAAUAAQC8EwUA\",\"\"]Ck[\"AAAAAAAAAUoFAAAAAAE9BAAA\",\"AAAAAAAAA/MLAAD0CwAA9QsAAA==\"]Cc[\"\",\"AAAAAAAEOQQAAO8GAAAYEQAAZRMAAAAAAiQTAAB7EwAA\"]Fc[\"AAAAAe4EAAAAATYAAAACJAEAACUBAAA=\",\"AAF8BwAAAAHuBAAAAAACkQ8AAB0QAAAC/gsAAEUTAAAAAAKmEwAAzxMAAA==\"]Eo[\"AAAAARURAAABFgkAAAACtgAAAOgLAAAB3xAAAAABQQQAAA==\",\"AAAAAAGUBQAAAALoCwAATQ8AAAABVwcAAAH3DwAA\"]Dk[\"AAAABt8RAAA4EgAAohMAAK4TAADMEwAA2xMAAAAAAAABDRMAAA==\",\"AAAAAAAAAAHXEAAA\"]A@g[\"AAAAOjAAAAEAAAAAAA8AEAAAAFoEsARYBYIGsQchCcoL+QsTDJUMpw+WEBYRIxIQE6kTOjAAAAEAAAAAAAkAEAAAABcJkA/2D+IRZxKxErYSRBPeE+ITOjAAAAEAAAAAAAgAEAAAANIBNwT6CxYPjBDgEDQS1RJkEzowAAABAAAAAAAHABAAAAC3AJcQHxKdE8YTzRPpE+sTATMFAAAAAAAAAAAAAVwTAAA=\",\"AAAAAbAEAAABpQgAAAAB6AsAAA==\"]ACk[\"AAAAOjAAAAEAAAAAAAgAEAAAAFsEBwnsCw0PUw9pEPkQeRN6EzowAAABAAAAAAAHABAAAAA7BEYFWwW/B98L2BAkEmMTOjAAAAEAAAAAAAoAEAAAANQBSwSVD5oPCRAlEN4Q4xGwErcSGBM6MAAAAQAAAAAABwAQAAAAEwEXD5EPHRAgEq8T6hPsEwU2BQAA/gsAAEUTAACeEwAAzhMAAAThEQAAPRMAAI8TAADHEwAAAvsLAAAHDgAAAqYTAADPEwAAApMQAAA1EgAA\",\"AAAAAAAAAAAAAAAAAAFYBwAAAAAAAAGWBQAA\"]Ho[\"AAAAA/8GAACiBwAA6BAAAAMLCQAA1QsAAMgTAAABgBAAAAABrQcAAAACdQ8AANwSAAABvgYAAA==\",\"AAAAAATVCwAA1gsAANcLAADYCwAAAAWdBAAAngQAAJ8EAACgBAAAHxIAAA==\"]Ho[\"AAAAAwMHAACmBwAA7xAAAAMPCQAA2QsAAMoTAAABhBAAAAABrwcAAAACdw8AAOASAAABwgYAAA==\",\"AAAAAATZCwAA2gsAANsLAADcCwAAAAWhBAAAogQAAKMEAACkBAAAIBIAAA==\"]No[\"AAABjQAAAAHBBAAAAAIaAAAAlwwAAAAAAd0AAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAA+wE6BIsG8QblCBsJ9gv8CwUMTg9wD/kPIxAoEDMQahB2EH0QiBCKEOUQBhEaEdkR2xEhEi4SaBJqEq0S7BLuEiATJxNGE2YToxM=\",\"AAFnBwAAAAHBBAAAAAAAAAAAAAAAAAAAAAAE6wgAAOwIAADvCAAA8AgAAA==\"]No[\"AAAAApAAAADwBAAAAAI4AAAAmgwAAAEnAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAA/AE8BI8G8gbmCBwJ9wv9CwYMTw9xD/oPJBApEDQQaxB3EH4QiRCLEOYQBxEbEdoR3BEiEi8SaRJrEq4S7RLvEiETKBNHE2cTpBM=\",\"AAF+BwAAAAHwBAAAAAAAAAAAAAAAAAAAAAAE7QgAAO4IAADxCAAA8ggAAA==\"]Cc[\"AAAAAdcEAAAAAAAAAf0AAAA=\",\"AAAAAdcEAAAAAAGVCwAA\"]Ck[\"AAAAARgFAAAAAAFxAQAA\",\"AAAAARgFAAAAAAOWCwAAlwsAAJgLAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAFSBAAAAAAAAQMMAAA=\",\"\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAQkPAAA=\"]Eo[\"AAAAAQgFAAAAAUkAAAACTwEAAFABAAABqAYAAA==\",\"AAAAAQgFAAAAAAGaBgAAAAAAAAAAAAAAAAACPAUAAAoPAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAtkTAADaEwAA\"]Ck[\"AAAAAAAAAAABjxMAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAB8BMAAA==\"]Ag[\"AAACiwIAAA8DAAA=\",\"\"]Cc[\"AAAAAAAC+gsAADQSAAABIw8AAA==\",\"AAAAAAAB7wYAAA==\"]Gc[\"AAAAAeoEAAAAATIAAAABHwEAAAAB4REAAAH7CwAAAAE1EgAA\",\"AAF7BwAAAAHqBAAAAAGwEgAAAZEPAAAAAeERAAAAAAAAAAAAAAAB8AYAAA==\"]Do[\"AAAAAAAAAAEkDwAAAl0FAABVDwAA\",\"AAAAAacBAAAAAAABJA8AAARdBQAAVQ8AANoQAADbEAAA\"]Do[\"AAAAAAAAAAElDwAAAl4FAABWDwAA\",\"AAAAAbMBAAAAAAABJQ8AAAReBQAAVg8AANwQAADdEAAA\"]Ao[\"AAAAAAH7DwAAAAABHhAAAA==\",\"\"]Gc[\"AAAB9hAAAAJiAAAAoAcAAAEJAgAAAAHDAAAAAmMEAAASEQAAAiAPAACTDwAAAAEiDwAAAk0EAACSDwAAAAIBDAAAkRAAAAIADAAAAgwAAA==\",\"\"]Cc[\"AAAAAAAAAANOBAAAZQQAABQRAAA=\",\"AAAAAAABlQ8AAA==\"]Ec[\"AAABMAIAAAG5BAAAAAIRAAAA5gYAAALJAAAAygAAAA==\",\"AAABNAIAAAG5BAAAAAAAAhIRAAATEQAA\"]Bo[\"AAABeBAAAAAAAAK+AAAAvwAAAA==\",\"AAAAAAFNBQAA\"]Ck[\"AAABeRAAAAAAAAJgAQAAYQEAAA==\",\"AAAAAAAAAAAAAAABTgUAAA==\"]Ao[\"AAAAAAAAAekSAAABEw8AAA==\",\"\"]Hg[\"AAAAAmQAAAC6BwAAAQoCAAABIgkAAAPPAAAArQYAADEQAAACSwUAAK0PAAAAAmMFAABZDAAABhkPAAAaDwAAGw8AADsQAACSEAAARhIAAAAAAhwPAAAdDwAAAR4PAAA=\",\"\"]Dk[\"AAAAAAABIwkAAAKuBgAAuwcAAAJMBQAAMhAAAAABZAUAAAE8EAAA\",\"AAAAAAABmg8AAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAG7EgAA\",\"\"]ABc[\"AAABWg8AAAF/BgAAAsEBAADfBgAABH4GAAD6CwAAUA8AADQSAAACnRMAAM0TAAAD1xAAAJ4TAADOEwAABVcHAADaEAAA2xAAANwQAADdEAAAAfcPAAAAAAABWAcAAA==\",\"AAAABdUGAAAVEQAAFhEAABcRAAAZEQAAAg8PAAAQDwAAAhgRAABkEwAABcYTAADpEwAA6hMAAOsTAADsEwAAAUUTAAABxxMAAAHgEQAAAAAAAAAAAAIpDwAAQw8AAAX9AQAA/gEAAFcPAABYDwAAWQ8AAA==\"]Cc[\"AAAAAQkFAAAAAUoAAAACUQEAAFIBAAA=\",\"AAAAAQkFAAA=\"]Dc[\"AAAAAAAAAAA7MAAAAQAABQABABgSBQA=\",\"AAAABMsBAADPAQAA0AEAANEBAAA=\"]Ao[\"AAAAAcsBAAAAAAAAAaAPAAA=\",\"\"]Ao[\"AAAAAdABAAAAAAAAAaEPAAA=\",\"\"]Eo[\"AAAAAfgQAAAB0hIAAAMNEAAAjhAAAOIQAAABKxMAAAEDEQAAAf0PAAACCxEAAOsRAAAB/RAAAAAAAAABXhMAAA==\",\"\"]Eo[\"AAAAAfsQAAAB1BIAAAMREAAAkBAAAOQQAAABLhMAAAEFEQAAAf8PAAACDREAAO0RAAAB/xAAAAAAAAABYBMAAA==\",\"\"]Bc[\"AAAAAAAAAmYEAAC1BgAAAAGiDwAA\",\"\"]Bc[\"AAAAAAAAAmkEAAC4BgAAAAGjDwAA\",\"\"]Ec[\"AAAAAcUBAAAAAjkSAAA7EgAAAiUTAAAmEwAAAlcEAACUCwAAAAAAAAABUgQAAA==\",\"AAAAAAElAwAA\"]Gg[\"AAAAAbsEAAAAAhMAAADoBgAAAtAAAADRAAAA\",\"AAADOgIAADwCAAA9AgAAAbsEAAAAAAABrQ8AAAACYwUAAFkMAAACOxAAAEYSAAAAAAABHg8AAA==\"]Eg[\"AAAAAfYEAAAAAj0AAACfAAAAAy8BAAAwAQAAiA8AAAFAAwAA\",\"AAAAAfYEAAAAAAAAAAFkBQAAATwQAAA=\"]Ec[\"AAAAAAAAAV8BAAAAAAAAAAAAAAAAAAKsBAAAJwkAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAZYFAAA=\"]Ec[\"AAAB0wsAAAGvBAAAAAELAAAAAbMAAAA=\",\"AAAAAa8EAAAAAfkIAAAAAAAAAAAAAAAAAAABfAYAAA==\"]Dg[\"AAAAAAFIBQAAAAAAAAAAAAAAAAAAAAI2EAAA2RAAAA==\",\"AAFhBwAAAAAAAX4GAAA=\"]Ac[\"AAABVwIAAA==\",\"\"]Do[\"AAAAAc8EAAAAASAAAAAAAALuAAAA7wAAAA==\",\"AAACZQIAAGYCAAABzwQAAAAAAAAAARMTAAA=\"]Dk[\"AAAAAQYFAAAAAUYAAAACSQEAAEoBAAA=\",\"AAAC2QIAANoCAAABBgUAAAAAAAAAARQTAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAv4IAAAACQAA\"]Dk[\"AAAAAAAAAAABDQEAAA==\",\"AAABgwIAAAAAAAAAAAABUwQAAAH9BgAAATMEAAABWgcAAA==\"]Dg[\"AAAAAAAAAYIBAAA=\",\"AAABCAMAAAAAAAAAAAABVAQAAAH+BgAAATUEAAABXQcAAA==\"]Dk[\"AAAAAd4EAAAAAbABAAABnwQAAAHsEAAAAQgBAAA=\",\"AAF0BwAAAAHeBAAAAAAAAewQAAA=\"]Dk[\"AAAAASgFAAAAAcMBAAACiwEAAKMEAAAB8xAAAA==\",\"AAGNBwAAAAEoBQAAAAAAAfMQAAA=\"]Ck[\"AAAAAfcEAAAAAT4AAAACMQEAADIBAAA=\",\"AAAAAfcEAAAAAAGuBgAA\"]Eg[\"AAAAAcoEAAAAAh8AAACVAAAAAX4PAAABNgMAAALpAAAALBIAAA==\",\"AAFvBwAAAV4CAAACygQAAPQJAAA=\"]Eg[\"AAAAAQEFAAAAAkUAAACgAAAAAkQBAACJDwAAAUEDAAABLRIAAA==\",\"AAGHBwAAAdMCAAABAQUAAAFWCgAA\"]Ao[\"AAAAAAAAAAACJhAAANoQAAA=\",\"\"]Ao[\"AAAAAAAAAAACJxAAANwQAAA=\",\"\"]Do[\"AAABbgAAAAGuBAAAAAABsgAAAA==\",\"AAAAAa4EAAAAAfgIAAAAAAAAAAAAAAAAAAABKhAAAA==\"]Bg[\"AAAAAAAABM4AAABSBQAA9QsAAOkRAAA=\",\"\"]Ak[\"AAAAAAABPwAAAAEzAQAA\",\"\"]Do[\"AAAAAAAAAAAAAAAAAAAAAAAAAnUQAADmEQAA\",\"AAFfBwAAAAAAAAAAAAAAAAAAAAAAAAE1EAAA\"]Cg[\"AAAAAAOvBgAAIAkAAH8QAAA=\",\"AAAAAAAAAAITDwAAHhAAAA==\"]Ag[\"AAACgwIAAAgDAAA=\",\"\"]Ac[\"\",\"AAAAAR4SAAA=\"]Cc[\"AAAAARoKAAACGQoAAIoKAAABiwoAAAI3EAAAORAAAA==\",\"\"]Gg[\"AAAAAc4EAAABpRMAAAAAAacIAAAE7QAAAKIPAAA/EgAAihMAAAH3DwAA\",\"AAAAA6sBAADOBAAAsBMAAAABahMAAAABpwgAAAOiDwAAPxIAAIoTAAA=\"]Bc[\"AAAAAasBAAAAAAAAAAAAAZwQAAA=\",\"\"]Gg[\"AAAAAQUFAAAAAAFIAQAAAagIAAADow8AAEESAACLEwAAAAAAAAFYBwAA\",\"AAAAA7oBAAAFBQAAsRMAAAABaxMAAAABqAgAAAOjDwAAQRIAAIsTAAA=\"]Bc[\"AAAAAboBAAAAAAAAAAAAAaAQAAA=\",\"\"]Fg[\"AAABPQIAAAHFBAAAAAEdAAAAAAAC4QAAAOIAAAA=\",\"AAFrBwAAAAHFBAAAAAEiCQAAAq0GAAAxEAAAA2MEAABkBAAASwUAAA==\"]Eo[\"AAAAAfkEAAAAAUEAAAACNQEAADYBAAA=\",\"AAGDBwAAAAH5BAAAAAEjCQAAAbsHAAAEZQQAAEwFAAAyEAAAFBEAAA==\"]Ao[\"\",\"AAAAAAAAAAAAAAABpBAAAA==\"]Ek[\"AAAAAdMEAAAAASQAAAAAAAL2AAAA9wAAAA==\",\"AAABawIAAAHTBAAAAAAAAAFXBwAAAfcPAAAAApwQAACeEAAA\"]Eg[\"AAAAAQ8FAAAAAU8AAAACXQEAAF4BAAA=\",\"AAAB5gIAAAEPBQAAAAAAAAAAAAKgEAAAohAAAAABWAcAAA==\"]Ao[\"AAAAAAAAAAETEAAAAAEODAAA\",\"\"]Jk[\"AAAAAdQEAAAABSUAAACWAAAAOAUAAAsQAAANEAAAApULAAB/DwAABDcDAADhCwAADBAAAA4QAAAE+AAAAPkAAADaEAAA2xAAAAIKDAAACwwAAAL8EAAA/RAAAA==\",\"AAAAAtQEAAAhEAAAAqwBAAAEEAAAAAAB8wgAAA==\"]Og[\"AAAAARQFAAAABVIAAACjAAAAOQUAAA8QAAAREAAABmoBAABrAQAAlgsAAJcLAACYCwAAjA8AAAREAwAA4gsAABAQAAASEAAAAtwQAADdEAAAAgwMAAANDAAAAv4QAAD/EAAA\",\"AAAABBQFAACUBwAAlQcAACIQAAAEvAEAAAUQAAAGEAAABxAAAAAAAfQIAAACQwUAAEQFAAAAAAAAAAAAAAA7MAAAAQAACgACAJYHBQC1BwQA\"]Cc[\"AAAAAQoFAAAAAUsAAAACUwEAAFQBAAA=\",\"AAAAAQoFAAA=\"]Ck[\"AAABPwUAAAHVBAAAAAEmAAAAAAAB+gAAAA==\",\"AAAAAtUEAADjCwAA\"]Dg[\"AAABQAUAAAEVBQAAAAFTAAAAAWwBAAAAAAAAAAAAAbAGAAA=\",\"AAAAAhUFAADkCwAA\"]Cc[\"AAAAAS4FAAAAAV8AAAABlQEAAA==\",\"AAAAAi4FAADlCwAA\"]Dg[\"AAAAAAAAAAAAAAABkxAAAA==\",\"AAAABggQAAArEgAAERMAABITAABCEwAAQxMAAA==\"]Ak[\"AAAAAAAAAAABGhIAAA==\",\"\"]Ak[\"AAAAAAAAAAABHRIAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmkAAAD9AQAA\",\"\"]Bg[\"AAAAAAAAAAAAAUYEAAA=\",\"AAAAAZYQAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmgAAADwBgAA\",\"\"]Bk[\"AAAAAAAAAAAAAAS+BgAAvwYAAMAGAADBBgAA\",\"\"]Ec[\"AAAABJYBAAChAQAA6QQAAPgPAAAAAAEeAQAAAAAABMIGAADDBgAAxAYAAMUGAAA=\",\"AAAAAekEAAA=\"]Bg[\"AAAAAAAAAAAAAUcEAAA=\",\"AAAAAAGxEgAA\"]Ag[\"AAAAAAAB4QYAAA==\",\"\"]Cc[\"AAAAAR4KAAACHQoAAI8KAAABjgoAAAI4EAAAOhAAAA==\",\"\"]No[\"AAAAAcwEAAAB3wYAAAFtEgAAAU0PAAAG8QsAABgQAAAOEwAAIhMAAIITAACqEwAAB+sAAACmAQAAUgwAAKAPAAA+EgAAGRMAABsTAAABjBMAAAAAAAAAAAAAA4wGAABWDAAAQhIAAA==\",\"AAAAAswEAACpDwAAAAGqAQAAAUQSAAAG8QsAABgQAAAOEwAAIhMAAIITAACqEwAABVIMAACgDwAAPhIAABkTAAAbEwAA\"]Bo[\"AAAAAakPAAAAAaoBAAAAAgwQAACdEAAAAAEKDAAA\",\"\"]Nc[\"AAAAAQMFAAAAAAFGAQAAOjAAAAEAAAAAAAcAEAAAALQB8gsZEG4SDxMjE4MTqxMFUwwAAKEPAABAEgAAGhMAABwTAAAAAAAAAAAAAAAElgUAAJAGAABXDAAAQxIAAA==\",\"AAAAAgMFAACqDwAAAAG5AQAAAUUSAAAG8gsAABkQAAAPEwAAIxMAAIMTAACrEwAABVMMAAChDwAAQBIAABoTAAAcEwAA\"]Bo[\"AAAAAaoPAAAAAbkBAAAAAhAQAAChEAAAAAEMDAAA\",\"\"]Ao[\"AAAAAAAAAAACGRMAABoTAAA=\",\"\"]Ao[\"AAAAAAAAAAACGxMAABwTAAA=\",\"\"]Dc[\"AAABPAIAAAG8BAAAAAIUAAAA6QYAAALSAAAA0wAAAA==\",\"AAABPgIAAAG8BAAA\"]Bk[\"AAAAAc4BAAAAAATNAAAAUQUAAPQLAADoEQAA\",\"\"]Ec[\"AAAAAswSAADNEgAAAsoSAADLEgAABM8LAADQCwAA0QsAANILAAAEywsAAMwLAADNCwAAzgsAAA==\",\"\"]Cc[\"AAAAAAAAAAABGRIAAA==\",\"AAFiBwAAAAKlAQAAqxIAAA==\"]Cc[\"AAAAAAAAAAABHBIAAA==\",\"AAF3BwAAAAKyAQAArBIAAA==\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAABsAYAAA==\"]Cg[\"AAAAAQ4PAAAAAAFpAQAAAQoQAAA=\",\"AAGTBwAAAAAAARgTAAA=\"]Ek[\"AAAAAbQEAAAAAAG8AAAAAAAAAAAAAAAAAAAEpxIAAK8SAADJEgAA5BIAAA==\",\"AAFjBwAAAAK0BAAAWQUAAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAyQJAACeDwAA2RMAAA==\",\"\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAyUJAACfDwAA2hMAAA==\",\"\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAv8IAAABCQAA\"]Bc[\"AAAAAAABMgQAAA==\",\"AAAAAAGaBAAA\"]Ec[\"AAAAAeAEAAAAAbEBAAABoAQAAALuEAAAQBMAAAEKAQAA\",\"AAF1BwAAAAHgBAAAAAAAAu4QAABAEwAA\"]Ec[\"AAAAASoFAAAAAcQBAAACjQEAAKQEAAAC9RAAAEETAAA=\",\"AAGOBwAAAAEqBQAAAAAAAvUQAABBEwAA\"]Ag[\"\",\"AAAAAAAB3REAAA==\"]Co[\"AAAAApsBAACUBwAAAAABYgEAAA==\",\"AAAAAAAAAAAAAAAAAAAAAbsBAAA=\"]Ac[\"\",\"AAAAAAFwEgAA\"]Cg[\"AAAAAAAAAkQSAABFEgAAAAAB4BEAAA==\",\"AAAAAAAAAAEdEwAA\"]Do[\"AAAAAfQEAAAAAjsAAACeAAAAAywBAAAtAQAAhw8AAAE/AwAA\",\"AAAAAfQEAAAAAAABTgQAAA==\"]Ak[\"AAAAAAACahMAAGsTAAA=\",\"\"]Ac[\"AAAAAc8BAAA=\",\"\"]Ac[\"AAAAAdEBAAA=\",\"\"]Eo[\"AAAC7gIAAAQDAAABHgUAAAABWgAAAAJ8AQAAfQEAAA==\",\"AAAAAR4FAAAAAAAFkgYAAJMGAACUBgAAlQYAAJYGAAA=\"]Fk[\"AAAABBoQAAAbEAAAERMAABITAAABDw8AAAFyEAAAAd4RAAAAAAGMEwAAAAAAAAAAAAEDDAAA\",\"AAAAAAAAA+cRAADoEQAA6REAAA==\"]Fc[\"AAAAAAABfgYAAAJEEgAARRIAAAHXEAAAAAHgEQAAAAACaBMAAGkTAAAAAAABuxIAAA==\",\"AAAAAAAAAaETAAABHRMAAA==\"]Ag[\"\",\"AAAAAAABNQUAAA==\"]Co[\"AAAAAfwEAAAAAUQAAAACOwEAADwBAAA=\",\"AAAAAfwEAAAAAAAAAAEHDgAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAc8GAAA=\",\"\"]Jc[\"AAAAAssEAACIEwAAAAAAAtQRAACpEgAABOoAAACmAQAACAwAALgSAAADKAkAABMTAACMEwAAAAAAAXAQAAA=\",\"AAFwBwAAAAKpAQAAywQAAAAAAALUEQAAqRIAAAIIDAAAuBIAAAIoCQAAExMAAAAAAAFwEAAA\"]Jg[\"AAAAAgIFAACJEwAAAAABRQEAAAO0AQAA1REAAKoSAAACCQwAALkSAAACKQkAABQTAAAAAAABcRAAAA==\",\"AAGIBwAAAAK4AQAAAgUAAAGGBgAAAAAC1REAAKoSAAACCQwAALkSAAACKQkAABQTAAAAAAABcRAAAA==\"]Ao[\"AAAAAAAAAcAAAAAAAAFJBAAA\",\"\"]Bc[\"AAAAAAABSAAAAAJNAQAATgEAAA==\",\"\"]Ag[\"AAACjQIAABcDAAA=\",\"\"]Ak[\"AAAAAAAAAmcEAAC2BgAA\",\"\"]Ak[\"AAAAAAAAAmoEAAC5BgAA\",\"\"]Ag[\"AAACjwIAABMDAAA=\",\"\"]Dk[\"AAAAAboEAAAAAhIAAADnBgAAAssAAADMAAAA\",\"AAABNgIAAAG6BAAAAAAAAAAAASIPAAA=\"]Dg[\"AAAAAbcEAAAAAg8AAADkBgAAAsUAAADGAAAA\",\"AAABLwIAAAG3BAAAAAAAAAGTDwAA\"]Co[\"AAAB5BEAAAH4BAAAAAFAAAAAATQBAAA=\",\"AAGCBwAAAeoIAAAB+AQAAA==\"]Ec[\"AAAAAAAB5REAAAG0AAAAAAAAAAAAAAAAAAADXgQAAOcIAAAmDwAA\",\"AAAAAaMBAAAAAAAAAQ0TAAA=\"]Hk[\"AAACxwIAAOACAAABFgUAAAABVAAAAAJtAQAAbgEAAAAAAAAAAAAAAAAABAECAAA8BQAAkQYAAM4GAAA=\",\"AAAB9QIAAAK9AQAAFgUAAAAAAi0TAAAuEwAAAAACDBEAAA0RAAA=\"]Fc[\"AAAAAwgQAAAcEAAAKxIAAAACORIAADsSAAADkgEAACUTAAAmEwAAAlcEAACUCwAAAAAAAAABUgQAAA==\",\"AAAAAcUBAAA=\"]Dc[\"AAAAAmEAAAC2BAAAAggCAACmCAAAAQ4AAAABwgAAAA==\",\"AAAAArYEAACoDwAA\"]Eg[\"AAAAAdEEAAAAASIAAAAAAALyAAAA8wAAAAAAAAAAAAAAAAPKBgAAAg8AAAkPAAA=\",\"AAABaAIAAAHRBAAA\"]Eg[\"AAAAAQsFAAAAAUwAAAACVQEAAFYBAAAAAAAAAAAAAAAAAAPMBgAABA8AAAoPAAA=\",\"AAAB4AIAAAELBQAA\"]Hk[\"AAAFIgIAADECAAA0AgAAOgIAAD4CAAABxgQAAAACHgAAAOoGAAAAAALjAAAA5AAAAA==\",\"AAADVgIAAFcCAABYAgAAAsYEAACCBgAAApQFAAD2DwAAAdUSAAABTQ8AAAHfEAAA\"]Ek[\"AAAAAfoEAAAAAkIAAADrBgAAAjcBAAA4AQAA\",\"AAABxwIAAAH6BAAAAAAAAAAAAAAAAAAAAAACrAQAAM8GAAA=\"]Bk[\"AAAAAAABCRAAAAFoAQAA\",\"AAAAAAAAAAEKEAAA\"]Fc[\"AAABjgAAAAHDBAAAAAGYDAAAAAAB3wAAAAAAAAAAAAAAAAT1BgAA+QYAAOwIAADwCAAA\",\"AAFpBwAAAALDBAAAWAUAAA==\"]Fc[\"AAAAApEAAADyBAAAAAGbDAAAASkBAAAAAAAAAAAAAAAAAAT3BgAA+wYAAO4IAADyCAAA\",\"AAGABwAAAAHyBAAAAVsFAAA=\"]Ag[\"AAACigIAABIDAAA=\",\"\"]Cg[\"AAAAATAFAAAAAAADEw8AAHkPAAAeEAAA\",\"AAGSBwAAAAEwBQAA\"]Dc[\"AAAAAhAFAACVBwAAAAABYwEAAA==\",\"AAAAARAFAAAAAAAAAAAAAAAAAAGbBgAA\"]Dg[\"AAAAAbwSAAABqw8AAAAAAALlAAAA2xAAAA==\",\"AAH1CAAAAagBAAABvBIAAAGrDwAA\"]Dg[\"AAAAAb0SAAABrA8AAAABQAEAAAAB3RAAAA==\",\"AAH2CAAAAbcBAAABvRIAAAGsDwAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAQcPAAA=\",\"\"]Ac[\"\",\"AAAAAAGQEwAA\"]Ag[\"AAACjgIAABQDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAADGBIAABkSAAAaEgAA\"]Bc[\"\",\"AAAAAAAAAAADGxIAABwSAAAdEgAA\"]Ak[\"\",\"AAAAAT0SAAAAAAFbEwAA\"]ADc[\"AAAAAccEAAAAAAA6MAAAAQAAAAAAFAAQAAAAqgecDBQPXA9fD5sPmBAPESMRNhKjEkgTnxOsE7gTuhPcE+AT4xPnE+4TOjAAAAEAAAAAAAwAEAAAAOYAJhCUECwSPhI/EtgSAxMWE8QT1RPXE+UTAAABCBEAAA==\",\"AAFsBwAAAAHHBAAAAAAAOjAAAAEAAAAAABQAEAAAAKoHnAwUD1wPXw+bD5gQDxEjETYSoxJIE58TrBO4E7oT3BPgE+MT5xPuEzowAAABAAAAAAAJABAAAAAmEJQQLBLYEgMTFhPEE9UT1xPlEwAAAQgRAAA=\"]ADc[\"AAAAAf4EAAAAAAFBAQAAOjAAAAEAAAAAABQAEAAAAKsHnQwVD10PYA+cD5kQEBEkETcSpBJJE6ATrRO5E7sT3RPhE+QT6BPvEzowAAABAAAAAAALABAAAAAnEJUQLRJAEkES2RIEExcTxRPWE9gT5hMAAAEJEQAA\",\"AAGEBwAAAAH+BAAAAAAAOjAAAAEAAAAAABQAEAAAAKsHnQwVD10PYA+cD5kQEBEkETcSpBJJE6ATrRO5E7sT3RPhE+QT6BPvEzowAAABAAAAAAAJABAAAAAnEJUQLRLZEgQTFxPFE9YT2BPmEwAAAQkRAAA=\"]Ag[\"AAACZQIAANkCAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAT4EAAA=\",\"AAAAAAAAAegLAAA=\"]Bk[\"AAAAAAAAAAAAAAH/CwAA\",\"AAAAAAABZRMAAA==\"]Do[\"AAAAAdIEAAAAASMAAAAAAAL0AAAA9QAAAAAAAAAAAAAAAALLBgAAAw8AAA==\",\"AAAAAdIEAAA=\"]Do[\"AAAAAQwFAAAAAU0AAAACVwEAAFgBAAAAAAAAAAAAAAAAAALNBgAABQ8AAA==\",\"AAAAAQwFAAA=\"]Ag[\"AAACkQIAABYDAAA=\",\"\"]Fc[\"AAAAAQ4FAAAAAk4AAAChAAAAAlsBAACKDwAAAkIDAAAKEAAA\",\"AAAAAQ4FAAAAAAAAAAAAAAABWAcAAAAAAAABlgUAAA==\"]Ac[\"\",\"AAAAAAFZBwAA\"]Ao[\"AAAAAAGaBAAA\",\"AAAAAAFcBwAA\"]Ag[\"AAACjAIAAA4DAAA=\",\"\"]Ag[\"AAACkAIAABADAAA=\",\"\"]Dg[\"AAAAAeIEAAAAAAABshIAAAAAAAGeEAAA\",\"AAAAAuIEAAAaCgAAARkKAAAAATcQAAA=\"]Do[\"AAABxgEAAAEiBQAAAAAAAbQSAAAAAAABohAAAA==\",\"AAAAASIFAAABigoAAAGLCgAAATkQAAA=\"]Do[\"AAAAAeQEAAAAAAADDhAAAJ8QAACzEgAAAAELDAAA\",\"AAAAAuQEAAAeCgAAAR0KAAAAATgQAAA=\"]Eg[\"AAABxwEAAAEkBQAAAAAAAxIQAACjEAAAtRIAAAABDQwAAA==\",\"AAAAASQFAAABjwoAAAGOCgAAAToQAAA=\"]Cc[\"AAAAAAAAAmgEAAC3BgAAAAH+AAAA\",\"AAFyBwAAAAGtAQAA\"]Cc[\"AAAAAAAAA3MBAABrBAAAugYAAA==\",\"AAGLBwAAAAG/AQAA\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA8kGAACbBwAAuQcAAA==\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAQYPAAA=\",\"\"]Ao[\"AAAAAAAAAZ0EAAAAAdUTAAA=\",\"\"]Bk[\"AAAAAAAAAaEEAAAAAdYTAAA=\",\"AAAAAaUEAAA=\"]Eg[\"AAAAAAAAAAABCwEAAAAAAAAAAAAAAAMqCQAAeg8AAGUSAAA=\",\"AAF2BwAAAASiBwAAowcAAKQHAAClBwAA\"]Eg[\"AAAAAAAAAY4BAAAAAAAAAAAAAAAAAAMrCQAAew8AAGYSAAA=\",\"AAGPBwAAAASmBwAApwcAAKgHAACpBwAA\"]Bo[\"AAAAAAABqgEAAAAAAVIMAAAAAVMEAAAAATMEAAA=\",\"\"]Bo[\"AAAAAAABuQEAAAAAAVMMAAAAAVQEAAAAATUEAAA=\",\"\"]Ak[\"AAAAAAAB1hIAAAE8EwAA\",\"\"]Ao[\"AAAAAAAB1xIAAAAAAT0TAAA=\",\"\"]Fo[\"AAAAARMFAAAAAlEAAACiAAAAA2YBAABnAQAAiw8AAAFDAwAA\",\"AAAB7gIAAAETBQAAAAAAAAJDBQAARAUAAAAAAAAAAAK7AQAAmwYAAA==\"]Dg[\"AAAAAewEAAAAATQAAAABIQEAAA==\",\"AAAAAewEAAAAAAAAAAAAAAAAAAAAAAHQBgAA\"]Dg[\"AAAAAbIEAAAAAgwAAADjBgAAArkAAAC6AAAA\",\"AAABIgIAAAGyBAAAAAABlxAAAA==\"]Do[\"AAAAAecEAAAAAjAAAACbAAAAAxoBAAAbAQAAhA8AAAE8AwAA\",\"AAAAAecEAAAAAAAAAVYEAAA=\"]Ek[\"AAAAAcgEAAAAAAACHhMAAHITAAAD5wAAAHoQAAADEwAA\",\"AAFtBwAAAAHIBAAAAAAAAh4TAAByEwAAAXoQAAA=\"]Ek[\"AAAAAf8EAAAAAAFCAQAAAh8TAABzEwAAAnsQAAAEEwAA\",\"AAGFBwAAAAH/BAAAAAAAAh8TAABzEwAAAXsQAAA=\"]Bo[\"AAAAAAAAAAABQwUAAAAAAAAAAAK7AQAAmwYAAA==\",\"\"]Fg[\"AAAAAckEAAAAAAAECQkAAKUPAAAAEQAAzxIAAALoAAAAFhMAAA==\",\"AAFuBwAAAAHJBAAAAAAABAkJAAClDwAAABEAAM8SAAA=\"]Fg[\"AAAAAQAFAAAAAAFDAQAABAoJAACmDwAAAREAANASAAABFxMAAA==\",\"AAGGBwAAAAEABQAAAAAABAoJAACmDwAAAREAANASAAA=\"]Ag[\"\",\"AAAAAAAAAaETAAA=\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAAAAAG7EgAA\"]Ag[\"\",\"AAAAAAAAASMPAAA=\"]Co[\"AAAAAe0EAAAAATUAAAACIgEAACMBAAA=\",\"AAAAAe0EAAAAAAAAAeERAAA=\"]Fg[\"AAABSAIAAAHWBAAAAAEnAAAAAAGjBgAAAvsAAAD8AAAA\",\"AAACbwIAAIoGAAAB1gQAAAAAAAGVBgAAAAAAAAAAAAAAAAECDwAA\"]Gc[\"AAABrwIAAAK9AQAAFwUAAAABVQAAAAJvAQAAcAEAAAGqBgAA\",\"AAAC9gIAAI4GAAABFwUAAAAAAZwGAAAAAAAAAAAAAAAAAAIBAgAABA8AAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA5cHAAC2BwAAqggAAA==\",\"\"]Cg[\"AAABawIAAAAAAAAAAQ4BAAA=\",\"AAAAAAAAAAIMEAAADhAAAA==\"]Cg[\"AAAB5gIAAAAAAAGDAQAA\",\"AAAAAAAAAAMQEAAAEhAAABMQAAA=\"]Bo[\"AAAAAqUEAAAvBQAAAXASAAA=\",\"AAAAAi8FAAAmEQAA\"]Io[\"AAAAAR8FAAAAAVsAAAABfgEAAAZlBQAAnRAAAJ8QAAChEAAAoxAAAKUQAAAAAAAFnBAAAJ4QAACgEAAAohAAAKQQAAAAAAAAAAAB7RMAAA==\",\"AAAAAR8FAAAAAAQqEwAAKxMAAC0TAAAuEwAAAAFPBAAA\"]Co[\"AAAAAmMAAAChBwAAAAABxAAAAAJkBAAAExEAAAEhDwAA\",\"AAAB9hAAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAv4IAAAAEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAgAJAAACEAAA\",\"\"]Co[\"AAAAAeMEAAAAAAAAAhEBAAASAQAA\",\"AAAAAeMEAAAAAAI3EAAAOBAAAA==\"]Dc[\"AAAAASMFAAAAAAKGAQAAhwEAAA==\",\"AAAAAiMFAAAeEgAAAAACORAAADoQAAA=\"]Ac[\"\",\"AAAB0wsAAA==\"]Ec[\"AAABZgIAAAG+BAAAAAEWAAAAAAAC1wAAANgAAAA=\",\"AAAAAb4EAAAE/AgAAOIJAADjCQAA5QkAAA==\"]Do[\"AAAB2gIAAAHmBAAAAAEuAAAAAhcBAAAYAQAA\",\"AAAAAeYEAAAE/QgAADQKAAA1CgAANgoAAA==\"]Ak[\"\",\"AAAAAAACahMAAGsTAAA=\"]Ck[\"AAAAArEEAAATCQAAAaUIAAABqBIAAAG4AAAA\",\"AAAAArEEAACnDwAA\"]Cg[\"AAAAATgHAAAC8g8AAAQQAAAAAZULAAAAAAAAAAABcBAAAA==\",\"\"]Ck[\"AAAAATkHAAAC8w8AAAUQAAAAApYLAACXCwAAAAAAAAAAAXEQAAA=\",\"\"]Bc[\"AAAAAAAAAAAAAAAAAmgTAABpEwAA\",\"\"]Fo[\"AAAAAc0EAAAAAAADWAQAABQJAACCEwAAAuwAAACfAQAA\",\"AAFxBwAAAAHNBAAAAAAAAlgEAAAUCQAAAZ8BAAAAAAAAAAAAAAABQhIAAA==\"]Fo[\"AAAAAQQFAAAAAAFHAQAAA1kEAAAVCQAAgxMAAAGgAQAA\",\"AAGJBwAAAAEEBQAAAAAAAlkEAAAVCQAAAaABAAAAAAAAAAAAAAABQxIAAA==\"]Ck[\"AAAAAf0EAAAAAAI9AQAAPgEAAA==\",\"AAAAAf0EAAAAAAAAAY8TAAA=\"]Ec[\"AAAAAREFAAAAAAFkAQAAAAAAAAAAAAAAAAAFnAEAAJYHAAC1BwAAqQgAAFQMAAA=\",\"AAAAAREFAAA=\"]Dg[\"AAAAAAGQEwAAAAG1AAAAAAAAAAACaBMAAGkTAAAAAAABuxIAAA==\",\"AAABpAEAAA==\"]Ag[\"AAACiAIAABgDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAmgTAABpEwAA\"]Cc[\"AAAAATEFAAAAAAAAAAAAAaQQAAA=\",\"AAABxgEAAAExBQAA\"]Ck[\"AAAAATIFAAAAAAACExAAAKUQAAAAAQ4MAAA=\",\"AAABxwEAAAEyBQAA\"]Ag[\"AAACkgIAABUDAAA=\",\"\"]Dg[\"AAAAAAABKwAAAAAAAQwBAAA=\",\"AAAAAAAAAAAAAAAAAAAAA1wTAABdEwAAXhMAAA==\"]Ck[\"AAAAAAABXQAAAAGBAQAA\",\"AAAAAAAAAAAAAAAAAAAAAl8TAABgEwAA\"]Ag[\"AAACiQIAAA0DAAA=\",\"\"]Do[\"AAAAAToHAAAC9A8AAAYQAAAAAZgLAAABLxAAAA==\",\"AAK2AQAAeAcAAAH3CAAAAAAAAAEvEAAA\"]Ec[\"AAAAAhkFAAA7BwAAAvUPAAAHEAAAAAFyAQAAATAQAAA=\",\"AAGKBwAAAb4BAAABGQUAAAAAAAEwEAAA\"]Bg[\"AAAAAAAAAAABRAUAAA==\",\"AAABtQEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAv8IAAABEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAgEJAAADEAAA\",\"\"]") \ No newline at end of file diff --git a/pr/545/docs/src-files.js b/pr/545/docs/src-files.js index b8d7393c6..e1e7f41c4 100644 --- a/pr/545/docs/src-files.js +++ b/pr/545/docs/src-files.js @@ -1,2 +1,2 @@ -createSrcSidebar('[["bench",["",[],["lib.rs","stats.rs"]]],["bulk",["",[],["bulk.rs"]]],["certificate",["",[],["certificate.rs"]]],["data_transfer",["",[],["data-transfer.rs"]]],["noq",["",[["runtime",[],["mod.rs","smol.rs","tokio.rs"]]],["connection.rs","endpoint.rs","incoming.rs","lib.rs","mutex.rs","path.rs","recv_stream.rs","send_stream.rs","work_limiter.rs"]]],["noq_perf",["",[],["perf.rs"]]],["noq_proto",["",[["config",[],["mod.rs","qlog.rs","transport.rs"]],["congestion",[["bbr",[],["bw_estimation.rs","min_max.rs","mod.rs"]]],["cubic.rs","new_reno.rs"]],["connection",[["streams",[],["mod.rs","recv.rs","send.rs","state.rs"]]],["ack_frequency.rs","assembler.rs","cid_state.rs","datagrams.rs","mod.rs","mtud.rs","pacing.rs","packet_builder.rs","packet_crypto.rs","paths.rs","qlog.rs","send_buffer.rs","spaces.rs","state.rs","stats.rs","timer.rs","transmit_buf.rs"]],["crypto",[],["ring_like.rs","rustls.rs"]],["range_set",[],["array_range_set.rs","mod.rs"]]],["address_discovery.rs","bloom_token_log.rs","cid_generator.rs","cid_queue.rs","coding.rs","congestion.rs","constant_time.rs","crypto.rs","endpoint.rs","frame.rs","lib.rs","n0_nat_traversal.rs","packet.rs","shared.rs","token.rs","token_memory_cache.rs","transport_error.rs","transport_parameters.rs","varint.rs"]]],["noq_udp",["",[["cmsg",[],["mod.rs","unix.rs"]]],["lib.rs","unix.rs"]]],["perf",["",[],["client.rs","lib.rs","noprotection.rs","server.rs","stats.rs"]]],["set_up_connection",["",[],["set-up-connection.rs"]]]]'); -//{"start":19,"fragment_lengths":[39,29,43,47,190,33,885,73,81,55]} \ No newline at end of file +createSrcSidebar('[["bench",["",[],["lib.rs","stats.rs"]]],["bulk",["",[],["bulk.rs"]]],["certificate",["",[],["certificate.rs"]]],["data_transfer",["",[],["data-transfer.rs"]]],["noq",["",[["runtime",[],["mod.rs","smol.rs","tokio.rs"]]],["connection.rs","endpoint.rs","event_stream.rs","incoming.rs","lib.rs","mutex.rs","path.rs","recv_stream.rs","send_stream.rs","work_limiter.rs"]]],["noq_perf",["",[],["perf.rs"]]],["noq_proto",["",[["config",[],["mod.rs","qlog.rs","transport.rs"]],["congestion",[["bbr",[],["bw_estimation.rs","min_max.rs","mod.rs"]]],["cubic.rs","new_reno.rs"]],["connection",[["streams",[],["mod.rs","recv.rs","send.rs","state.rs"]]],["ack_frequency.rs","assembler.rs","cid_state.rs","datagrams.rs","mod.rs","mtud.rs","pacing.rs","packet_builder.rs","packet_crypto.rs","paths.rs","qlog.rs","send_buffer.rs","spaces.rs","state.rs","stats.rs","timer.rs","transmit_buf.rs"]],["crypto",[],["ring_like.rs","rustls.rs"]],["range_set",[],["array_range_set.rs","mod.rs"]]],["address_discovery.rs","bloom_token_log.rs","cid_generator.rs","cid_queue.rs","coding.rs","congestion.rs","constant_time.rs","crypto.rs","endpoint.rs","frame.rs","lib.rs","n0_nat_traversal.rs","packet.rs","shared.rs","token.rs","token_memory_cache.rs","transport_error.rs","transport_parameters.rs","varint.rs"]]],["noq_udp",["",[["cmsg",[],["mod.rs","unix.rs"]]],["lib.rs","unix.rs"]]],["perf",["",[],["client.rs","lib.rs","noprotection.rs","server.rs","stats.rs"]]],["set_up_connection",["",[],["set-up-connection.rs"]]]]'); +//{"start":19,"fragment_lengths":[39,29,43,47,208,33,885,73,81,55]} \ No newline at end of file diff --git a/pr/545/docs/src/noq/connection.rs.html b/pr/545/docs/src/noq/connection.rs.html index 2e1552dc9..2a9cd944a 100644 --- a/pr/545/docs/src/noq/connection.rs.html +++ b/pr/545/docs/src/noq/connection.rs.html @@ -20,7 +20,7 @@ 20use crate::{ 21 ConnectionEvent, Duration, Instant, Path, VarInt, 22 endpoint::ensure_ipv6, -23 mutex::Mutex, +23 mutex::{Mutex, MutexGuard}, 24 path::OpenPath, 25 recv_stream::RecvStream, 26 runtime::{AsyncTimer, Runtime, UdpSender}, @@ -131,7 +131,7 @@ 131 pub fn into_0rtt(mut self) -> Result<(Connection, ZeroRttAccepted), Self> { 132 // This lock borrows `self` and would normally be dropped at the end of this scope, so we'll 133 // have to release it explicitly before returning `self` by value. -134 let conn = (self.conn.as_mut().unwrap()).state.lock("into_0rtt"); +134 let conn = (self.conn.as_mut().unwrap()).lock_without_waking("into_0rtt"); 135 136 let is_ok = conn.inner.has_0rtt() || conn.inner.side().is_server(); 137 drop(conn); @@ -158,7 +158,7 @@ 158 let _ = x.await; 159 } 160 let conn = self.conn.as_ref().unwrap(); -161 let inner = conn.state.lock("handshake"); +161 let inner = conn.lock_without_waking("handshake"); 162 inner 163 .inner 164 .crypto_session() @@ -184,7 +184,7 @@ 184 /// Will panic if called after `poll` has returned `Ready`. 185 pub fn local_ip(&self) -> Option<IpAddr> { 186 let conn = self.conn.as_ref().unwrap(); -187 let inner = conn.state.lock("local_ip"); +187 let inner = conn.lock_without_waking("local_ip"); 188 189 inner 190 .inner @@ -200,719 +200,719 @@ 200 let conn_ref: &ConnectionRef = self.conn.as_ref().expect("used after yielding Ready"); 201 // TODO: another unwrap 202 conn_ref -203 .state -204 .lock("remote_address") -205 .inner -206 .network_path(PathId::ZERO) -207 .expect("path exists when connecting") -208 .remote() -209 } -210} -211 -212impl Future for Connecting { -213 type Output = Result<Connection, ConnectionError>; -214 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -215 Pin::new(&mut self.connected).poll(cx).map(|_| { -216 let conn = self.conn.take().unwrap(); -217 let inner = conn.state.lock("connecting"); -218 if inner.connected { -219 drop(inner); -220 Ok(Connection(conn)) -221 } else { -222 Err(inner -223 .error -224 .clone() -225 .expect("connected signaled without connection success or error")) -226 } -227 }) -228 } -229} -230 -231/// Future that completes when a connection is fully established -232/// -233/// For clients, the resulting value indicates if 0-RTT was accepted. For servers, the resulting -234/// value is meaningless. -235pub struct ZeroRttAccepted(oneshot::Receiver<bool>); -236 -237impl Future for ZeroRttAccepted { -238 type Output = bool; -239 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -240 Pin::new(&mut self.0).poll(cx).map(|x| x.unwrap_or(false)) -241 } -242} -243 -244/// A future that drives protocol logic for a connection -245/// -246/// This future handles the protocol logic for a single connection, routing events from the -247/// `Connection` API object to the `Endpoint` task and the related stream-related interfaces. -248/// It also keeps track of outstanding timeouts for the `Connection`. -249/// -250/// If the connection encounters an error condition, this future will yield an error. It will -251/// terminate (yielding `Ok(())`) if the connection was closed without error. Unlike other -252/// connection-related futures, this waits for the draining period to complete to ensure that -253/// packets still in flight from the peer are handled gracefully. -254#[must_use = "connection drivers must be spawned for their connections to function"] -255#[derive(Debug)] -256struct ConnectionDriver(ConnectionRef); -257 -258impl Future for ConnectionDriver { -259 type Output = Result<(), io::Error>; -260 -261 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -262 let conn = &mut *self.0.state.lock("poll"); -263 -264 let span = debug_span!("drive", id = conn.handle.0); -265 let _guard = span.enter(); -266 -267 if let Err(e) = conn.process_conn_events(&self.0.shared, cx) { -268 conn.terminate(e, &self.0.shared); -269 return Poll::Ready(Ok(())); -270 } -271 let mut keep_going = conn.drive_transmit(cx)?; -272 // If a timer expires, there might be more to transmit. When we transmit something, we -273 // might need to reset a timer. Hence, we must loop until neither happens. -274 keep_going |= conn.drive_timer(cx); -275 conn.forward_endpoint_events(); -276 conn.forward_app_events(&self.0.shared); -277 -278 if !conn.inner.is_drained() { -279 if keep_going { -280 // If the connection hasn't processed all tasks, schedule it again -281 cx.waker().wake_by_ref(); -282 } else { -283 conn.driver = Some(cx.waker().clone()); -284 } -285 return Poll::Pending; -286 } -287 if conn.error.is_none() { -288 unreachable!("drained connections always have an error"); -289 } -290 Poll::Ready(Ok(())) -291 } -292} -293 -294/// A QUIC connection. -295/// -296/// If all references to a connection (including every clone of the `Connection` handle, streams of -297/// incoming streams, and the various stream types) have been dropped, then the connection will be -298/// automatically closed with an `error_code` of 0 and an empty `reason`. You can also close the -299/// connection explicitly by calling [`Connection::close()`]. -300/// -301/// Closing the connection immediately abandons efforts to deliver data to the peer. Upon -302/// receiving CONNECTION_CLOSE the peer *may* drop any stream data not yet delivered to the -303/// application. [`Connection::close()`] describes in more detail how to gracefully close a -304/// connection without losing application data. -305/// -306/// May be cloned to obtain another handle to the same connection. -307/// -308/// [`Connection::close()`]: Connection::close -309#[derive(Debug, Clone)] -310pub struct Connection(ConnectionRef); -311 -312impl Connection { -313 /// Returns a weak reference to the inner connection struct. -314 pub fn weak_handle(&self) -> WeakConnectionHandle { -315 self.0.weak_handle() -316 } -317 -318 /// Initiate a new outgoing unidirectional stream. -319 /// -320 /// Streams are cheap and instantaneous to open unless blocked by flow control. As a -321 /// consequence, the peer won't be notified that a stream has been opened until the stream is -322 /// actually used. -323 pub fn open_uni(&self) -> OpenUni<'_> { -324 OpenUni { -325 conn: &self.0, -326 notify: self.0.shared.stream_budget_available[Dir::Uni as usize].notified(), -327 } -328 } -329 -330 /// Initiate a new outgoing bidirectional stream. -331 /// -332 /// Streams are cheap and instantaneous to open unless blocked by flow control. As a -333 /// consequence, the peer won't be notified that a stream has been opened until the stream is -334 /// actually used. Calling [`open_bi()`] then waiting on the [`RecvStream`] without writing -335 /// anything to [`SendStream`] will never succeed. -336 /// -337 /// [`open_bi()`]: crate::Connection::open_bi -338 /// [`SendStream`]: crate::SendStream -339 /// [`RecvStream`]: crate::RecvStream -340 pub fn open_bi(&self) -> OpenBi<'_> { -341 OpenBi { -342 conn: &self.0, -343 notify: self.0.shared.stream_budget_available[Dir::Bi as usize].notified(), -344 } -345 } -346 -347 /// Accept the next incoming uni-directional stream -348 pub fn accept_uni(&self) -> AcceptUni<'_> { -349 AcceptUni { -350 conn: &self.0, -351 notify: self.0.shared.stream_incoming[Dir::Uni as usize].notified(), -352 } -353 } -354 -355 /// Accept the next incoming bidirectional stream -356 /// -357 /// **Important Note**: The `Connection` that calls [`open_bi()`] must write to its [`SendStream`] -358 /// before the other `Connection` is able to `accept_bi()`. Calling [`open_bi()`] then -359 /// waiting on the [`RecvStream`] without writing anything to [`SendStream`] will never succeed. -360 /// -361 /// [`accept_bi()`]: crate::Connection::accept_bi -362 /// [`open_bi()`]: crate::Connection::open_bi -363 /// [`SendStream`]: crate::SendStream -364 /// [`RecvStream`]: crate::RecvStream -365 pub fn accept_bi(&self) -> AcceptBi<'_> { -366 AcceptBi { -367 conn: &self.0, -368 notify: self.0.shared.stream_incoming[Dir::Bi as usize].notified(), -369 } -370 } -371 -372 /// Receive an application datagram -373 pub fn read_datagram(&self) -> ReadDatagram<'_> { -374 ReadDatagram { -375 conn: &self.0, -376 notify: self.0.shared.datagram_received.notified(), -377 } -378 } -379 -380 /// Opens a new path if no path exists yet for the remote address. -381 /// -382 /// Otherwise behaves exactly as [`open_path`]. -383 /// -384 /// [`open_path`]: Self::open_path -385 pub fn open_path_ensure(&self, addr: SocketAddr, initial_status: PathStatus) -> OpenPath { -386 let mut state = self.0.state.lock("open_path"); -387 -388 // If endpoint::State::ipv6 is true we want to keep all our IP addresses as IPv6. -389 // If not, we do not support IPv6. We can not access endpoint::State from here -390 // however, but either all our paths use an IPv6 address, or all our paths use an -391 // IPv4 address. So we can use that information. -392 let ipv6 = state -393 .inner -394 .paths() -395 .iter() -396 .filter_map(|id| { -397 state -398 .inner -399 .network_path(*id) -400 .map(|addrs| addrs.remote().is_ipv6()) -401 .ok() -402 }) -403 .next() -404 .unwrap_or_default(); -405 if addr.is_ipv6() && !ipv6 { -406 return OpenPath::rejected(PathError::InvalidRemoteAddress(addr)); -407 } -408 let addr = if ipv6 { -409 SocketAddr::V6(ensure_ipv6(addr)) -410 } else { -411 addr -412 }; -413 -414 let now = state.runtime.now(); -415 // TODO(matheus23): For now this means it's impossible to make use of short-circuiting path validation currently. -416 // However, changing that would mean changing the API. -417 let addrs = FourTuple::from_remote(addr); -418 let open_res = state.inner.open_path_ensure(addrs, initial_status, now); -419 state.wake(); -420 match open_res { -421 Ok((path_id, existed)) if existed => { -422 let recv = state.open_path.get(&path_id).map(|tx| tx.subscribe()); -423 drop(state); -424 match recv { -425 Some(recv) => OpenPath::new(path_id, recv, self.0.clone()), -426 None => OpenPath::ready(path_id, self.0.clone()), -427 } -428 } -429 Ok((path_id, _)) => { -430 let (tx, rx) = watch::channel(Ok(())); -431 state.open_path.insert(path_id, tx); -432 drop(state); -433 OpenPath::new(path_id, rx, self.0.clone()) -434 } -435 Err(err) => OpenPath::rejected(err), -436 } -437 } -438 -439 /// Opens an additional path if the multipath extension is negotiated. -440 /// -441 /// The returned future completes once the path is either fully opened and ready to -442 /// carry application data, or if there was an error. -443 /// -444 /// Dropping the returned future does not cancel the opening of the path, the -445 /// [`PathEvent::Opened`] event will still be emitted from [`Self::path_events`] if the -446 /// path opens. The [`PathId`] for the events can be extracted from -447 /// [`OpenPath::path_id`]. -448 /// -449 /// Failure to open a path can either occur immediately, before polling the returned -450 /// future, or at a later time. If the failure is immediate [`OpenPath::path_id`] will -451 /// return `None` and the future will be ready immediately. If the failure happens -452 /// later, a [`PathEvent`] will be emitted. -453 pub fn open_path(&self, addr: SocketAddr, initial_status: PathStatus) -> OpenPath { -454 let mut state = self.0.state.lock("open_path"); -455 -456 // If endpoint::State::ipv6 is true we want to keep all our IP addresses as IPv6. -457 // If not, we do not support IPv6. We can not access endpoint::State from here -458 // however, but either all our paths use an IPv6 address, or all our paths use an -459 // IPv4 address. So we can use that information. -460 let ipv6 = state -461 .inner -462 .paths() -463 .iter() -464 .filter_map(|id| { -465 state -466 .inner -467 .network_path(*id) -468 .map(|addrs| addrs.remote().is_ipv6()) -469 .ok() -470 }) -471 .next() -472 .unwrap_or_default(); -473 if addr.is_ipv6() && !ipv6 { -474 return OpenPath::rejected(PathError::InvalidRemoteAddress(addr)); -475 } -476 let addr = if ipv6 { -477 SocketAddr::V6(ensure_ipv6(addr)) -478 } else { -479 addr -480 }; -481 -482 let (on_open_path_send, on_open_path_recv) = watch::channel(Ok(())); -483 let now = state.runtime.now(); -484 // TODO(matheus23): For now this means it's impossible to make use of short-circuiting path validation currently. -485 // However, changing that would mean changing the API. -486 let addrs = FourTuple::from_remote(addr); -487 let open_res = state.inner.open_path(addrs, initial_status, now); -488 state.wake(); -489 match open_res { -490 Ok(path_id) => { -491 state.open_path.insert(path_id, on_open_path_send); -492 drop(state); -493 OpenPath::new(path_id, on_open_path_recv, self.0.clone()) -494 } -495 Err(err) => OpenPath::rejected(err), -496 } -497 } -498 -499 /// Returns the [`Path`] structure of an open path -500 pub fn path(&self, id: PathId) -> Option<Path> { -501 Path::new(&self.0, id) -502 } -503 -504 /// A broadcast receiver of [`PathEvent`]s for all paths in this connection -505 pub fn path_events(&self) -> tokio::sync::broadcast::Receiver<PathEvent> { -506 self.0.state.lock("path_events").path_events.subscribe() -507 } -508 -509 /// A broadcast receiver of [`n0_nat_traversal::Event`]s for updates about server addresses -510 pub fn nat_traversal_updates( -511 &self, -512 ) -> tokio::sync::broadcast::Receiver<n0_nat_traversal::Event> { -513 self.0 -514 .state -515 .lock("nat_traversal_updates") -516 .nat_traversal_updates -517 .subscribe() -518 } -519 -520 /// Wait for the connection to be closed for any reason -521 /// -522 /// Despite the return type's name, closed connections are often not an error condition at the -523 /// application layer. Cases that might be routine include [`ConnectionError::LocallyClosed`] -524 /// and [`ConnectionError::ApplicationClosed`]. -525 pub async fn closed(&self) -> ConnectionError { -526 { -527 let conn = self.0.state.lock("closed"); -528 if let Some(error) = conn.error.as_ref() { -529 return error.clone(); -530 } -531 // Construct the future while the lock is held to ensure we can't miss a wakeup if -532 // the `Notify` is signaled immediately after we release the lock. `await` it after -533 // the lock guard is out of scope. -534 self.0.shared.closed.notified() -535 } -536 .await; -537 self.0 -538 .state -539 .lock("closed") -540 .error -541 .as_ref() -542 .expect("closed without an error") -543 .clone() -544 } -545 -546 /// Wait for the connection to be closed without keeping a strong reference to the connection -547 /// -548 /// Returns a future that resolves, once the connection is closed, to a tuple of -549 /// ([`ConnectionError`], [`ConnectionStats`]). -550 /// -551 /// Calling [`Self::closed`] keeps the connection alive until it is either closed locally via [`Connection::close`] -552 /// or closed by the remote peer. This function instead does not keep the connection itself alive, -553 /// so if all *other* clones of the connection are dropped, the connection will be closed implicitly even -554 /// if there are futures returned from this function still being awaited. -555 pub fn on_closed(&self) -> OnClosed { -556 let (tx, rx) = oneshot::channel(); -557 let mut state = self.0.state.lock("on_closed"); -558 if let Some(error) = &state.error { -559 // Connection already closed, send immediately -560 let _ = tx.send((error.clone(), state.inner.stats())); -561 } else { -562 state.on_closed.push(tx); -563 } -564 drop(state); -565 OnClosed { -566 conn: self.weak_handle(), -567 rx, -568 } -569 } -570 -571 /// If the connection is closed, the reason why. -572 /// -573 /// Returns `None` if the connection is still open. -574 pub fn close_reason(&self) -> Option<ConnectionError> { -575 self.0.state.lock("close_reason").error.clone() -576 } -577 -578 /// Close the connection immediately. -579 /// -580 /// Pending operations will fail immediately with [`ConnectionError::LocallyClosed`]. No -581 /// more data is sent to the peer and the peer may drop buffered data upon receiving -582 /// the CONNECTION_CLOSE frame. +203 .lock_without_waking("remote_address") +204 .inner +205 .network_path(PathId::ZERO) +206 .expect("path exists when connecting") +207 .remote() +208 } +209} +210 +211impl Future for Connecting { +212 type Output = Result<Connection, ConnectionError>; +213 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +214 Pin::new(&mut self.connected).poll(cx).map(|_| { +215 let conn = self.conn.take().unwrap(); +216 let inner = conn.lock_without_waking("connecting"); +217 if inner.connected { +218 drop(inner); +219 Ok(Connection(conn)) +220 } else { +221 Err(inner +222 .error +223 .clone() +224 .expect("connected signaled without connection success or error")) +225 } +226 }) +227 } +228} +229 +230/// Future that completes when a connection is fully established +231/// +232/// For clients, the resulting value indicates if 0-RTT was accepted. For servers, the resulting +233/// value is meaningless. +234pub struct ZeroRttAccepted(oneshot::Receiver<bool>); +235 +236impl Future for ZeroRttAccepted { +237 type Output = bool; +238 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +239 Pin::new(&mut self.0).poll(cx).map(|x| x.unwrap_or(false)) +240 } +241} +242 +243/// A future that drives protocol logic for a connection +244/// +245/// This future handles the protocol logic for a single connection, routing events from the +246/// `Connection` API object to the `Endpoint` task and the related stream-related interfaces. +247/// It also keeps track of outstanding timeouts for the `Connection`. +248/// +249/// If the connection encounters an error condition, this future will yield an error. It will +250/// terminate (yielding `Ok(())`) if the connection was closed without error. Unlike other +251/// connection-related futures, this waits for the draining period to complete to ensure that +252/// packets still in flight from the peer are handled gracefully. +253#[must_use = "connection drivers must be spawned for their connections to function"] +254#[derive(Debug)] +255struct ConnectionDriver(ConnectionRef); +256 +257impl Future for ConnectionDriver { +258 type Output = Result<(), io::Error>; +259 +260 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +261 let conn = &mut *self.0.lock_without_waking("poll"); +262 +263 let span = debug_span!("drive", id = conn.handle.0); +264 let _guard = span.enter(); +265 +266 if let Err(e) = conn.process_conn_events(&self.0.shared, cx) { +267 conn.terminate(e, &self.0.shared); +268 return Poll::Ready(Ok(())); +269 } +270 let mut keep_going = conn.drive_transmit(cx)?; +271 // If a timer expires, there might be more to transmit. When we transmit something, we +272 // might need to reset a timer. Hence, we must loop until neither happens. +273 keep_going |= conn.drive_timer(cx); +274 conn.forward_endpoint_events(); +275 conn.forward_app_events(&self.0.shared); +276 +277 if !conn.inner.is_drained() { +278 if keep_going { +279 // If the connection hasn't processed all tasks, schedule it again +280 cx.waker().wake_by_ref(); +281 } else { +282 conn.driver = Some(cx.waker().clone()); +283 } +284 return Poll::Pending; +285 } +286 if conn.error.is_none() { +287 unreachable!("drained connections always have an error"); +288 } +289 Poll::Ready(Ok(())) +290 } +291} +292 +293/// A QUIC connection. +294/// +295/// If all references to a connection (including every clone of the `Connection` handle, streams of +296/// incoming streams, and the various stream types) have been dropped, then the connection will be +297/// automatically closed with an `error_code` of 0 and an empty `reason`. You can also close the +298/// connection explicitly by calling [`Connection::close()`]. +299/// +300/// Closing the connection immediately abandons efforts to deliver data to the peer. Upon +301/// receiving CONNECTION_CLOSE the peer *may* drop any stream data not yet delivered to the +302/// application. [`Connection::close()`] describes in more detail how to gracefully close a +303/// connection without losing application data. +304/// +305/// May be cloned to obtain another handle to the same connection. +306/// +307/// [`Connection::close()`]: Connection::close +308#[derive(Debug, Clone)] +309pub struct Connection(ConnectionRef); +310 +311impl Connection { +312 /// Returns a weak reference to the inner connection struct. +313 pub fn weak_handle(&self) -> WeakConnectionHandle { +314 self.0.weak_handle() +315 } +316 +317 /// Initiate a new outgoing unidirectional stream. +318 /// +319 /// Streams are cheap and instantaneous to open unless blocked by flow control. As a +320 /// consequence, the peer won't be notified that a stream has been opened until the stream is +321 /// actually used. +322 pub fn open_uni(&self) -> OpenUni<'_> { +323 OpenUni { +324 conn: &self.0, +325 notify: self.0.shared.stream_budget_available[Dir::Uni as usize].notified(), +326 } +327 } +328 +329 /// Initiate a new outgoing bidirectional stream. +330 /// +331 /// Streams are cheap and instantaneous to open unless blocked by flow control. As a +332 /// consequence, the peer won't be notified that a stream has been opened until the stream is +333 /// actually used. Calling [`open_bi()`] then waiting on the [`RecvStream`] without writing +334 /// anything to [`SendStream`] will never succeed. +335 /// +336 /// [`open_bi()`]: crate::Connection::open_bi +337 /// [`SendStream`]: crate::SendStream +338 /// [`RecvStream`]: crate::RecvStream +339 pub fn open_bi(&self) -> OpenBi<'_> { +340 OpenBi { +341 conn: &self.0, +342 notify: self.0.shared.stream_budget_available[Dir::Bi as usize].notified(), +343 } +344 } +345 +346 /// Accept the next incoming uni-directional stream +347 pub fn accept_uni(&self) -> AcceptUni<'_> { +348 AcceptUni { +349 conn: &self.0, +350 notify: self.0.shared.stream_incoming[Dir::Uni as usize].notified(), +351 } +352 } +353 +354 /// Accept the next incoming bidirectional stream +355 /// +356 /// **Important Note**: The `Connection` that calls [`open_bi()`] must write to its [`SendStream`] +357 /// before the other `Connection` is able to `accept_bi()`. Calling [`open_bi()`] then +358 /// waiting on the [`RecvStream`] without writing anything to [`SendStream`] will never succeed. +359 /// +360 /// [`accept_bi()`]: crate::Connection::accept_bi +361 /// [`open_bi()`]: crate::Connection::open_bi +362 /// [`SendStream`]: crate::SendStream +363 /// [`RecvStream`]: crate::RecvStream +364 pub fn accept_bi(&self) -> AcceptBi<'_> { +365 AcceptBi { +366 conn: &self.0, +367 notify: self.0.shared.stream_incoming[Dir::Bi as usize].notified(), +368 } +369 } +370 +371 /// Receive an application datagram +372 pub fn read_datagram(&self) -> ReadDatagram<'_> { +373 ReadDatagram { +374 conn: &self.0, +375 notify: self.0.shared.datagram_received.notified(), +376 } +377 } +378 +379 /// Opens a new path if no path exists yet for the remote address. +380 /// +381 /// Otherwise behaves exactly as [`open_path`]. +382 /// +383 /// [`open_path`]: Self::open_path +384 pub fn open_path_ensure(&self, addr: SocketAddr, initial_status: PathStatus) -> OpenPath { +385 let mut state = self.0.lock_and_wake("open_path"); +386 +387 // If endpoint::State::ipv6 is true we want to keep all our IP addresses as IPv6. +388 // If not, we do not support IPv6. We can not access endpoint::State from here +389 // however, but either all our paths use an IPv6 address, or all our paths use an +390 // IPv4 address. So we can use that information. +391 let ipv6 = state +392 .inner +393 .paths() +394 .iter() +395 .filter_map(|id| { +396 state +397 .inner +398 .network_path(*id) +399 .map(|addrs| addrs.remote().is_ipv6()) +400 .ok() +401 }) +402 .next() +403 .unwrap_or_default(); +404 if addr.is_ipv6() && !ipv6 { +405 return OpenPath::rejected(PathError::InvalidRemoteAddress(addr)); +406 } +407 let addr = if ipv6 { +408 SocketAddr::V6(ensure_ipv6(addr)) +409 } else { +410 addr +411 }; +412 +413 let now = state.runtime.now(); +414 // TODO(matheus23): For now this means it's impossible to make use of short-circuiting path validation currently. +415 // However, changing that would mean changing the API. +416 let addrs = FourTuple::from_remote(addr); +417 let open_res = state.inner.open_path_ensure(addrs, initial_status, now); +418 match open_res { +419 Ok((path_id, existed)) if existed => { +420 let recv = state.open_path.get(&path_id).map(|tx| tx.subscribe()); +421 drop(state); +422 match recv { +423 Some(recv) => OpenPath::new(path_id, recv, self.0.clone()), +424 None => OpenPath::ready(path_id, self.0.clone()), +425 } +426 } +427 Ok((path_id, _)) => { +428 let (tx, rx) = watch::channel(Ok(())); +429 state.open_path.insert(path_id, tx); +430 drop(state); +431 OpenPath::new(path_id, rx, self.0.clone()) +432 } +433 Err(err) => OpenPath::rejected(err), +434 } +435 } +436 +437 /// Opens an additional path if the multipath extension is negotiated. +438 /// +439 /// The returned future completes once the path is either fully opened and ready to +440 /// carry application data, or if there was an error. +441 /// +442 /// Dropping the returned future does not cancel the opening of the path, the +443 /// [`PathEvent::Opened`] event will still be emitted from [`Self::path_events`] if the +444 /// path opens. The [`PathId`] for the events can be extracted from +445 /// [`OpenPath::path_id`]. +446 /// +447 /// Failure to open a path can either occur immediately, before polling the returned +448 /// future, or at a later time. If the failure is immediate [`OpenPath::path_id`] will +449 /// return `None` and the future will be ready immediately. If the failure happens +450 /// later, a [`PathEvent`] will be emitted. +451 pub fn open_path(&self, addr: SocketAddr, initial_status: PathStatus) -> OpenPath { +452 let mut state = self.0.lock_and_wake("open_path"); +453 +454 // If endpoint::State::ipv6 is true we want to keep all our IP addresses as IPv6. +455 // If not, we do not support IPv6. We can not access endpoint::State from here +456 // however, but either all our paths use an IPv6 address, or all our paths use an +457 // IPv4 address. So we can use that information. +458 let ipv6 = state +459 .inner +460 .paths() +461 .iter() +462 .filter_map(|id| { +463 state +464 .inner +465 .network_path(*id) +466 .map(|addrs| addrs.remote().is_ipv6()) +467 .ok() +468 }) +469 .next() +470 .unwrap_or_default(); +471 if addr.is_ipv6() && !ipv6 { +472 return OpenPath::rejected(PathError::InvalidRemoteAddress(addr)); +473 } +474 let addr = if ipv6 { +475 SocketAddr::V6(ensure_ipv6(addr)) +476 } else { +477 addr +478 }; +479 +480 let (on_open_path_send, on_open_path_recv) = watch::channel(Ok(())); +481 let now = state.runtime.now(); +482 // TODO(matheus23): For now this means it's impossible to make use of short-circuiting path validation currently. +483 // However, changing that would mean changing the API. +484 let addrs = FourTuple::from_remote(addr); +485 let open_res = state.inner.open_path(addrs, initial_status, now); +486 match open_res { +487 Ok(path_id) => { +488 state.open_path.insert(path_id, on_open_path_send); +489 drop(state); +490 OpenPath::new(path_id, on_open_path_recv, self.0.clone()) +491 } +492 Err(err) => OpenPath::rejected(err), +493 } +494 } +495 +496 /// Returns the [`Path`] structure of an open path +497 pub fn path(&self, id: PathId) -> Option<Path> { +498 Path::new(&self.0, id) +499 } +500 +501 /// A stream of [`PathEvent`]s for all paths in this connection. +502 /// +503 /// The stream will yield a [`PathEvent`] whenever there is a change in the state of any path in this connection. +504 /// The events need to be processed immediately, since there isn't an unbounded buffer for them. +505 /// +506 /// If processing of events lags behind too much, you will get an error of type [`crate::Lagged`] indicating +507 /// how many events were lost. The stream continues after a lag, delivering the oldest retained message next. +508 pub fn path_events(&self) -> crate::PathEvents { +509 crate::PathEvents::new( +510 self.0 +511 .lock_without_waking("path_events") +512 .path_events +513 .subscribe(), +514 ) +515 } +516 +517 /// A stream of NAT traversal updates for this connection. +518 /// +519 /// The events need to be processed immediately, since there isn't an unbounded buffer for them. +520 /// +521 /// If processing of events lags behind too much, you will get an error of type [`crate::Lagged`] indicating +522 /// how many events were lost. The stream continues after a lag, delivering the oldest retained message next. +523 pub fn nat_traversal_updates(&self) -> crate::NatTraversalUpdates { +524 crate::NatTraversalUpdates::new( +525 self.0 +526 .lock_without_waking("nat_traversal_updates") +527 .nat_traversal_updates +528 .subscribe(), +529 ) +530 } +531 +532 /// Wait for the connection to be closed for any reason +533 /// +534 /// Despite the return type's name, closed connections are often not an error condition at the +535 /// application layer. Cases that might be routine include [`ConnectionError::LocallyClosed`] +536 /// and [`ConnectionError::ApplicationClosed`]. +537 pub async fn closed(&self) -> ConnectionError { +538 { +539 let conn = self.0.lock_without_waking("closed"); +540 if let Some(error) = conn.error.as_ref() { +541 return error.clone(); +542 } +543 // Construct the future while the lock is held to ensure we can't miss a wakeup if +544 // the `Notify` is signaled immediately after we release the lock. `await` it after +545 // the lock guard is out of scope. +546 self.0.shared.closed.notified() +547 } +548 .await; +549 self.0 +550 .lock_without_waking("closed") +551 .error +552 .as_ref() +553 .expect("closed without an error") +554 .clone() +555 } +556 +557 /// Wait for the connection to be closed without keeping a strong reference to the connection +558 /// +559 /// Returns a future that resolves, once the connection is closed, to a tuple of +560 /// ([`ConnectionError`], [`ConnectionStats`]). +561 /// +562 /// Calling [`Self::closed`] keeps the connection alive until it is either closed locally via [`Connection::close`] +563 /// or closed by the remote peer. This function instead does not keep the connection itself alive, +564 /// so if all *other* clones of the connection are dropped, the connection will be closed implicitly even +565 /// if there are futures returned from this function still being awaited. +566 pub fn on_closed(&self) -> OnClosed { +567 let (tx, rx) = oneshot::channel(); +568 let mut state = self.0.lock_without_waking("on_closed"); +569 if let Some(error) = &state.error { +570 // Connection already closed, send immediately +571 let _ = tx.send((error.clone(), state.inner.stats())); +572 } else { +573 state.on_closed.push(tx); +574 } +575 drop(state); +576 OnClosed { +577 conn: self.weak_handle(), +578 rx, +579 } +580 } +581 +582 /// If the connection is closed, the reason why. 583 /// -584 /// `error_code` and `reason` are not interpreted, and are provided directly to the peer. -585 /// -586 /// `reason` will be truncated to fit in a single packet with overhead; to improve odds that it -587 /// is preserved in full, it should be kept under 1KiB. -588 /// -589 /// # Gracefully closing a connection +584 /// Returns `None` if the connection is still open. +585 pub fn close_reason(&self) -> Option<ConnectionError> { +586 self.0.lock_without_waking("close_reason").error.clone() +587 } +588 +589 /// Close the connection immediately. 590 /// -591 /// Only the peer last receiving application data can be certain that all data is -592 /// delivered. The only reliable action it can then take is to close the connection, -593 /// potentially with a custom error code. The delivery of the final CONNECTION_CLOSE -594 /// frame is very likely if both endpoints stay online long enough, and -595 /// [`Endpoint::wait_idle()`] can be used to provide sufficient time. Otherwise, the -596 /// remote peer will time out the connection, provided that the idle timeout is not -597 /// disabled. -598 /// -599 /// The sending side can not guarantee all stream data is delivered to the remote -600 /// application. It only knows the data is delivered to the QUIC stack of the remote -601 /// endpoint. Once the local side sends a CONNECTION_CLOSE frame in response to calling -602 /// [`close()`] the remote endpoint may drop any data it received but is as yet -603 /// undelivered to the application, including data that was acknowledged as received to -604 /// the local endpoint. -605 /// -606 /// [`ConnectionError::LocallyClosed`]: crate::ConnectionError::LocallyClosed -607 /// [`Endpoint::wait_idle()`]: crate::Endpoint::wait_idle -608 /// [`close()`]: Connection::close -609 pub fn close(&self, error_code: VarInt, reason: &[u8]) { -610 let conn = &mut *self.0.state.lock("close"); -611 conn.close(error_code, Bytes::copy_from_slice(reason), &self.0.shared); -612 } -613 -614 /// Wait for the handshake to be confirmed. -615 /// -616 /// As a server, who must be authenticated by clients, -617 /// this happens when the handshake completes -618 /// upon receiving a TLS Finished message from the client. -619 /// In return, the server send a HANDSHAKE_DONE frame. -620 /// -621 /// As a client, this happens when receiving a HANDSHAKE_DONE frame. -622 /// At this point, the server has either accepted our authentication, -623 /// or, if client authentication is not required, accepted our lack of authentication. -624 pub async fn handshake_confirmed(&self) -> Result<(), ConnectionError> { -625 { -626 let conn = self.0.state.lock("handshake_confirmed"); -627 if let Some(error) = conn.error.as_ref() { -628 return Err(error.clone()); -629 } -630 if conn.handshake_confirmed { -631 return Ok(()); -632 } -633 // Construct the future while the lock is held to ensure we can't miss a wakeup if -634 // the `Notify` is signaled immediately after we release the lock. `await` it after -635 // the lock guard is out of scope. -636 self.0.shared.handshake_confirmed.notified() -637 } -638 .await; -639 if let Some(error) = self.0.state.lock("handshake_confirmed").error.as_ref() { -640 Err(error.clone()) -641 } else { -642 Ok(()) -643 } -644 } -645 -646 /// Transmit `data` as an unreliable, unordered application datagram -647 /// -648 /// Application datagrams are a low-level primitive. They may be lost or delivered out of order, -649 /// and `data` must both fit inside a single QUIC packet and be smaller than the maximum -650 /// dictated by the peer. -651 /// -652 /// Previously queued datagrams which are still unsent may be discarded to make space for this -653 /// datagram, in order of oldest to newest. -654 pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError> { -655 let conn = &mut *self.0.state.lock("send_datagram"); -656 if let Some(ref x) = conn.error { -657 return Err(SendDatagramError::ConnectionLost(x.clone())); -658 } -659 use proto::SendDatagramError::*; -660 match conn.inner.datagrams().send(data, true) { -661 Ok(()) => { -662 conn.wake(); -663 Ok(()) -664 } -665 Err(e) => Err(match e { -666 Blocked(..) => unreachable!(), -667 UnsupportedByPeer => SendDatagramError::UnsupportedByPeer, -668 Disabled => SendDatagramError::Disabled, -669 TooLarge => SendDatagramError::TooLarge, -670 }), -671 } -672 } -673 -674 /// Transmit `data` as an unreliable, unordered application datagram -675 /// -676 /// Unlike [`send_datagram()`], this method will wait for buffer space during congestion -677 /// conditions, which effectively prioritizes old datagrams over new datagrams. -678 /// -679 /// See [`send_datagram()`] for details. -680 /// -681 /// [`send_datagram()`]: Connection::send_datagram -682 pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_> { -683 SendDatagram { -684 conn: &self.0, -685 data: Some(data), -686 notify: self.0.shared.datagrams_unblocked.notified(), -687 } -688 } -689 -690 /// Compute the maximum size of datagrams that may be passed to [`send_datagram()`]. +591 /// Pending operations will fail immediately with [`ConnectionError::LocallyClosed`]. No +592 /// more data is sent to the peer and the peer may drop buffered data upon receiving +593 /// the CONNECTION_CLOSE frame. +594 /// +595 /// `error_code` and `reason` are not interpreted, and are provided directly to the peer. +596 /// +597 /// `reason` will be truncated to fit in a single packet with overhead; to improve odds that it +598 /// is preserved in full, it should be kept under 1KiB. +599 /// +600 /// # Gracefully closing a connection +601 /// +602 /// Only the peer last receiving application data can be certain that all data is +603 /// delivered. The only reliable action it can then take is to close the connection, +604 /// potentially with a custom error code. The delivery of the final CONNECTION_CLOSE +605 /// frame is very likely if both endpoints stay online long enough, and +606 /// [`Endpoint::wait_idle()`] can be used to provide sufficient time. Otherwise, the +607 /// remote peer will time out the connection, provided that the idle timeout is not +608 /// disabled. +609 /// +610 /// The sending side can not guarantee all stream data is delivered to the remote +611 /// application. It only knows the data is delivered to the QUIC stack of the remote +612 /// endpoint. Once the local side sends a CONNECTION_CLOSE frame in response to calling +613 /// [`close()`] the remote endpoint may drop any data it received but is as yet +614 /// undelivered to the application, including data that was acknowledged as received to +615 /// the local endpoint. +616 /// +617 /// [`ConnectionError::LocallyClosed`]: crate::ConnectionError::LocallyClosed +618 /// [`Endpoint::wait_idle()`]: crate::Endpoint::wait_idle +619 /// [`close()`]: Connection::close +620 pub fn close(&self, error_code: VarInt, reason: &[u8]) { +621 let conn = &mut *self.0.lock_without_waking("close"); // conn.close self-wakes +622 conn.close(error_code, Bytes::copy_from_slice(reason), &self.0.shared); +623 } +624 +625 /// Wait for the handshake to be confirmed. +626 /// +627 /// As a server, who must be authenticated by clients, +628 /// this happens when the handshake completes +629 /// upon receiving a TLS Finished message from the client. +630 /// In return, the server send a HANDSHAKE_DONE frame. +631 /// +632 /// As a client, this happens when receiving a HANDSHAKE_DONE frame. +633 /// At this point, the server has either accepted our authentication, +634 /// or, if client authentication is not required, accepted our lack of authentication. +635 pub async fn handshake_confirmed(&self) -> Result<(), ConnectionError> { +636 { +637 let conn = self.0.lock_without_waking("handshake_confirmed"); +638 if let Some(error) = conn.error.as_ref() { +639 return Err(error.clone()); +640 } +641 if conn.handshake_confirmed { +642 return Ok(()); +643 } +644 // Construct the future while the lock is held to ensure we can't miss a wakeup if +645 // the `Notify` is signaled immediately after we release the lock. `await` it after +646 // the lock guard is out of scope. +647 self.0.shared.handshake_confirmed.notified() +648 } +649 .await; +650 if let Some(error) = self +651 .0 +652 .lock_without_waking("handshake_confirmed") +653 .error +654 .as_ref() +655 { +656 Err(error.clone()) +657 } else { +658 Ok(()) +659 } +660 } +661 +662 /// Transmit `data` as an unreliable, unordered application datagram +663 /// +664 /// Application datagrams are a low-level primitive. They may be lost or delivered out of order, +665 /// and `data` must both fit inside a single QUIC packet and be smaller than the maximum +666 /// dictated by the peer. +667 /// +668 /// Previously queued datagrams which are still unsent may be discarded to make space for this +669 /// datagram, in order of oldest to newest. +670 pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError> { +671 let conn = &mut *self.0.lock_and_wake("send_datagram"); +672 if let Some(ref x) = conn.error { +673 return Err(SendDatagramError::ConnectionLost(x.clone())); +674 } +675 use proto::SendDatagramError::*; +676 match conn.inner.datagrams().send(data, true) { +677 Ok(()) => Ok(()), +678 Err(e) => Err(match e { +679 Blocked(..) => unreachable!(), +680 UnsupportedByPeer => SendDatagramError::UnsupportedByPeer, +681 Disabled => SendDatagramError::Disabled, +682 TooLarge => SendDatagramError::TooLarge, +683 }), +684 } +685 } +686 +687 /// Transmit `data` as an unreliable, unordered application datagram +688 /// +689 /// Unlike [`send_datagram()`], this method will wait for buffer space during congestion +690 /// conditions, which effectively prioritizes old datagrams over new datagrams. 691 /// -692 /// Returns `None` if datagrams are unsupported by the peer or disabled locally. +692 /// See [`send_datagram()`] for details. 693 /// -694 /// This may change over the lifetime of a connection according to variation in the path MTU -695 /// estimate. The peer can also enforce an arbitrarily small fixed limit, but if the peer's -696 /// limit is large this is guaranteed to be a little over a kilobyte at minimum. -697 /// -698 /// Not necessarily the maximum size of received datagrams. -699 /// -700 /// [`send_datagram()`]: Connection::send_datagram -701 pub fn max_datagram_size(&self) -> Option<usize> { -702 self.0 -703 .state -704 .lock("max_datagram_size") -705 .inner -706 .datagrams() -707 .max_size() -708 } -709 -710 /// Bytes available in the outgoing datagram buffer -711 /// -712 /// When greater than zero, calling [`send_datagram()`](Self::send_datagram) with a datagram of -713 /// at most this size is guaranteed not to cause older datagrams to be dropped. -714 pub fn datagram_send_buffer_space(&self) -> usize { +694 /// [`send_datagram()`]: Connection::send_datagram +695 pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_> { +696 SendDatagram { +697 conn: &self.0, +698 data: Some(data), +699 notify: self.0.shared.datagrams_unblocked.notified(), +700 } +701 } +702 +703 /// Compute the maximum size of datagrams that may be passed to [`send_datagram()`]. +704 /// +705 /// Returns `None` if datagrams are unsupported by the peer or disabled locally. +706 /// +707 /// This may change over the lifetime of a connection according to variation in the path MTU +708 /// estimate. The peer can also enforce an arbitrarily small fixed limit, but if the peer's +709 /// limit is large this is guaranteed to be a little over a kilobyte at minimum. +710 /// +711 /// Not necessarily the maximum size of received datagrams. +712 /// +713 /// [`send_datagram()`]: Connection::send_datagram +714 pub fn max_datagram_size(&self) -> Option<usize> { 715 self.0 -716 .state -717 .lock("datagram_send_buffer_space") -718 .inner -719 .datagrams() -720 .send_buffer_space() -721 } -722 -723 /// The side of the connection (client or server) -724 pub fn side(&self) -> Side { -725 self.0.state.lock("side").inner.side() -726 } -727 -728 /// The peer's UDP address -729 /// -730 /// If [`ServerConfig::migration`] is `true`, clients may change addresses at will, -731 /// e.g. when switching to a cellular internet connection. -732 /// -733 /// If [`multipath`] is enabled this will return the address of *any* -734 /// path, and may not be consistent. Prefer [`Path::remote_address`] instead. -735 /// -736 /// [`ServerConfig::migration`]: crate::ServerConfig::migration -737 /// [`multipath`]: crate::TransportConfig::max_concurrent_multipath_paths -738 pub fn remote_address(&self) -> SocketAddr { -739 // TODO: an unwrap again -740 let state = self.0.state.lock("remote_address"); -741 state -742 .inner -743 .paths() -744 .iter() -745 .filter_map(|id| state.inner.network_path(*id).ok()) -746 .next() -747 .unwrap() -748 .remote() -749 } -750 -751 /// The local IP address which was used when the peer established -752 /// the connection -753 /// -754 /// This can be different from the address the endpoint is bound to, in case -755 /// the endpoint is bound to a wildcard address like `0.0.0.0` or `::`. -756 /// -757 /// This will return `None` for clients, or when the platform does not expose this -758 /// information. See [`noq_udp::RecvMeta::dst_ip`](udp::RecvMeta::dst_ip) for a list of -759 /// supported platforms when using [`noq_udp`](udp) for I/O, which is the default. -760 pub fn local_ip(&self) -> Option<IpAddr> { -761 // TODO: an unwrap again -762 let state = self.0.state.lock("remote_address"); -763 state -764 .inner -765 .paths() -766 .iter() -767 .filter_map(|id| state.inner.network_path(*id).ok()) -768 .next() -769 .unwrap() -770 .local_ip() -771 } -772 -773 /// Current best estimate of this connection's latency (round-trip-time) -774 pub fn rtt(&self, path_id: PathId) -> Option<Duration> { -775 self.0.state.lock("rtt").inner.rtt(path_id) -776 } -777 -778 /// Returns connection statistics -779 pub fn stats(&self) -> ConnectionStats { -780 self.0.state.lock("stats").inner.stats() -781 } -782 -783 /// Returns path statistics -784 pub fn path_stats(&self, path_id: PathId) -> Option<PathStats> { -785 self.0.state.lock("path_stats").path_stats(path_id) -786 } -787 -788 /// Current state of the congestion control algorithm, for debugging purposes -789 pub fn congestion_state(&self, path_id: PathId) -> Option<Box<dyn Controller>> { -790 self.0 -791 .state -792 .lock("congestion_state") -793 .inner -794 .congestion_state(path_id) -795 .map(|c| c.clone_box()) -796 } -797 -798 /// Parameters negotiated during the handshake -799 /// -800 /// Guaranteed to return `Some` on fully established connections or after -801 /// [`Connecting::handshake_data()`] succeeds. See that method's documentations for details on -802 /// the returned value. -803 /// -804 /// [`Connection::handshake_data()`]: crate::Connecting::handshake_data -805 pub fn handshake_data(&self) -> Option<Box<dyn Any>> { -806 self.0 -807 .state -808 .lock("handshake_data") -809 .inner -810 .crypto_session() -811 .handshake_data() -812 } -813 -814 /// Cryptographic identity of the peer -815 /// -816 /// The dynamic type returned is determined by the configured -817 /// [`Session`](proto::crypto::Session). For the default `rustls` session, the return value can -818 /// be [`downcast`](Box::downcast) to a <code>Vec<[rustls::pki_types::CertificateDer]></code> -819 pub fn peer_identity(&self) -> Option<Box<dyn Any>> { -820 self.0 -821 .state -822 .lock("peer_identity") -823 .inner -824 .crypto_session() -825 .peer_identity() -826 } -827 -828 /// A stable identifier for this connection -829 /// -830 /// Peer addresses and connection IDs can change, but this value will remain -831 /// fixed for the lifetime of the connection. -832 pub fn stable_id(&self) -> usize { -833 self.0.stable_id() +716 .lock_without_waking("max_datagram_size") +717 .inner +718 .datagrams() +719 .max_size() +720 } +721 +722 /// Bytes available in the outgoing datagram buffer +723 /// +724 /// When greater than zero, calling [`send_datagram()`](Self::send_datagram) with a datagram of +725 /// at most this size is guaranteed not to cause older datagrams to be dropped. +726 pub fn datagram_send_buffer_space(&self) -> usize { +727 self.0 +728 .lock_without_waking("datagram_send_buffer_space") +729 .inner +730 .datagrams() +731 .send_buffer_space() +732 } +733 +734 /// The side of the connection (client or server) +735 pub fn side(&self) -> Side { +736 self.0.lock_without_waking("side").inner.side() +737 } +738 +739 /// The peer's UDP address +740 /// +741 /// If [`ServerConfig::migration`] is `true`, clients may change addresses at will, +742 /// e.g. when switching to a cellular internet connection. +743 /// +744 /// If [`multipath`] is enabled this will return the address of *any* +745 /// path, and may not be consistent. Prefer [`Path::remote_address`] instead. +746 /// +747 /// [`ServerConfig::migration`]: crate::ServerConfig::migration +748 /// [`multipath`]: crate::TransportConfig::max_concurrent_multipath_paths +749 pub fn remote_address(&self) -> SocketAddr { +750 // TODO: an unwrap again +751 let state = self.0.lock_without_waking("remote_address"); +752 state +753 .inner +754 .paths() +755 .iter() +756 .filter_map(|id| state.inner.network_path(*id).ok()) +757 .next() +758 .unwrap() +759 .remote() +760 } +761 +762 /// The local IP address which was used when the peer established +763 /// the connection +764 /// +765 /// This can be different from the address the endpoint is bound to, in case +766 /// the endpoint is bound to a wildcard address like `0.0.0.0` or `::`. +767 /// +768 /// This will return `None` for clients, or when the platform does not expose this +769 /// information. See [`noq_udp::RecvMeta::dst_ip`](udp::RecvMeta::dst_ip) for a list of +770 /// supported platforms when using [`noq_udp`](udp) for I/O, which is the default. +771 pub fn local_ip(&self) -> Option<IpAddr> { +772 // TODO: an unwrap again +773 let state = self.0.lock_without_waking("remote_address"); +774 state +775 .inner +776 .paths() +777 .iter() +778 .filter_map(|id| state.inner.network_path(*id).ok()) +779 .next() +780 .unwrap() +781 .local_ip() +782 } +783 +784 /// Current best estimate of this connection's latency (round-trip-time) +785 pub fn rtt(&self, path_id: PathId) -> Option<Duration> { +786 self.0.lock_without_waking("rtt").inner.rtt(path_id) +787 } +788 +789 /// Returns connection statistics +790 pub fn stats(&self) -> ConnectionStats { +791 self.0.lock_without_waking("stats").inner.stats() +792 } +793 +794 /// Returns path statistics +795 pub fn path_stats(&self, path_id: PathId) -> Option<PathStats> { +796 self.0.lock_without_waking("path_stats").path_stats(path_id) +797 } +798 +799 /// Current state of the congestion control algorithm, for debugging purposes +800 pub fn congestion_state(&self, path_id: PathId) -> Option<Box<dyn Controller>> { +801 self.0 +802 .lock_without_waking("congestion_state") +803 .inner +804 .congestion_state(path_id) +805 .map(|c| c.clone_box()) +806 } +807 +808 /// Parameters negotiated during the handshake +809 /// +810 /// Guaranteed to return `Some` on fully established connections or after +811 /// [`Connecting::handshake_data()`] succeeds. See that method's documentations for details on +812 /// the returned value. +813 /// +814 /// [`Connection::handshake_data()`]: crate::Connecting::handshake_data +815 pub fn handshake_data(&self) -> Option<Box<dyn Any>> { +816 self.0 +817 .lock_without_waking("handshake_data") +818 .inner +819 .crypto_session() +820 .handshake_data() +821 } +822 +823 /// Cryptographic identity of the peer +824 /// +825 /// The dynamic type returned is determined by the configured +826 /// [`Session`](proto::crypto::Session). For the default `rustls` session, the return value can +827 /// be [`downcast`](Box::downcast) to a <code>Vec<[rustls::pki_types::CertificateDer]></code> +828 pub fn peer_identity(&self) -> Option<Box<dyn Any>> { +829 self.0 +830 .lock_without_waking("peer_identity") +831 .inner +832 .crypto_session() +833 .peer_identity() 834 } 835 -836 /// Update traffic keys spontaneously +836 /// A stable identifier for this connection 837 /// -838 /// This primarily exists for testing purposes. -839 pub fn force_key_update(&self) { -840 self.0 -841 .state -842 .lock("force_key_update") -843 .inner -844 .force_key_update() -845 } -846 -847 /// Derive keying material from this connection's TLS session secrets. -848 /// -849 /// When both peers call this method with the same `label` and `context` -850 /// arguments and `output` buffers of equal length, they will get the -851 /// same sequence of bytes in `output`. These bytes are cryptographically -852 /// strong and pseudorandom, and are suitable for use as keying material. -853 /// -854 /// See [RFC5705](https://tools.ietf.org/html/rfc5705) for more information. -855 pub fn export_keying_material( -856 &self, -857 output: &mut [u8], -858 label: &[u8], -859 context: &[u8], -860 ) -> Result<(), proto::crypto::ExportKeyingMaterialError> { -861 self.0 -862 .state -863 .lock("export_keying_material") -864 .inner -865 .crypto_session() -866 .export_keying_material(output, label, context) -867 } -868 -869 /// Modify the number of remotely initiated unidirectional streams that may be concurrently open -870 /// -871 /// No streams may be opened by the peer unless fewer than `count` are already open. Large -872 /// `count`s increase both minimum and worst-case memory consumption. -873 pub fn set_max_concurrent_uni_streams(&self, count: VarInt) { -874 let mut conn = self.0.state.lock("set_max_concurrent_uni_streams"); -875 conn.inner.set_max_concurrent_streams(Dir::Uni, count); -876 // May need to send MAX_STREAMS to make progress -877 conn.wake(); -878 } -879 -880 /// See [`proto::TransportConfig::send_window()`] -881 pub fn set_send_window(&self, send_window: u64) { -882 let mut conn = self.0.state.lock("set_send_window"); -883 conn.inner.set_send_window(send_window); -884 conn.wake(); -885 } -886 -887 /// See [`proto::TransportConfig::receive_window()`] -888 pub fn set_receive_window(&self, receive_window: VarInt) { -889 let mut conn = self.0.state.lock("set_receive_window"); -890 conn.inner.set_receive_window(receive_window); -891 conn.wake(); -892 } -893 -894 /// Modify the number of remotely initiated bidirectional streams that may be concurrently open -895 /// -896 /// No streams may be opened by the peer unless fewer than `count` are already open. Large -897 /// `count`s increase both minimum and worst-case memory consumption. -898 pub fn set_max_concurrent_bi_streams(&self, count: VarInt) { -899 let mut conn = self.0.state.lock("set_max_concurrent_bi_streams"); -900 conn.inner.set_max_concurrent_streams(Dir::Bi, count); -901 // May need to send MAX_STREAMS to make progress -902 conn.wake(); +838 /// Peer addresses and connection IDs can change, but this value will remain +839 /// fixed for the lifetime of the connection. +840 pub fn stable_id(&self) -> usize { +841 self.0.stable_id() +842 } +843 +844 /// Update traffic keys spontaneously +845 /// +846 /// This primarily exists for testing purposes. +847 pub fn force_key_update(&self) { +848 self.0 +849 .lock_and_wake("force_key_update") +850 .inner +851 .force_key_update() +852 } +853 +854 /// Derive keying material from this connection's TLS session secrets. +855 /// +856 /// When both peers call this method with the same `label` and `context` +857 /// arguments and `output` buffers of equal length, they will get the +858 /// same sequence of bytes in `output`. These bytes are cryptographically +859 /// strong and pseudorandom, and are suitable for use as keying material. +860 /// +861 /// See [RFC5705](https://tools.ietf.org/html/rfc5705) for more information. +862 pub fn export_keying_material( +863 &self, +864 output: &mut [u8], +865 label: &[u8], +866 context: &[u8], +867 ) -> Result<(), proto::crypto::ExportKeyingMaterialError> { +868 self.0 +869 .lock_without_waking("export_keying_material") +870 .inner +871 .crypto_session() +872 .export_keying_material(output, label, context) +873 } +874 +875 /// Modify the number of remotely initiated unidirectional streams that may be concurrently open +876 /// +877 /// No streams may be opened by the peer unless fewer than `count` are already open. Large +878 /// `count`s increase both minimum and worst-case memory consumption. +879 pub fn set_max_concurrent_uni_streams(&self, count: VarInt) { +880 let mut conn = self.0.lock_and_wake("set_max_concurrent_uni_streams"); +881 conn.inner.set_max_concurrent_streams(Dir::Uni, count); +882 } +883 +884 /// See [`proto::TransportConfig::send_window()`] +885 pub fn set_send_window(&self, send_window: u64) { +886 let mut conn = self.0.lock_and_wake("set_send_window"); +887 conn.inner.set_send_window(send_window); +888 } +889 +890 /// See [`proto::TransportConfig::receive_window()`] +891 pub fn set_receive_window(&self, receive_window: VarInt) { +892 let mut conn = self.0.lock_and_wake("set_receive_window"); +893 conn.inner.set_receive_window(receive_window); +894 } +895 +896 /// Modify the number of remotely initiated bidirectional streams that may be concurrently open +897 /// +898 /// No streams may be opened by the peer unless fewer than `count` are already open. Large +899 /// `count`s increase both minimum and worst-case memory consumption. +900 pub fn set_max_concurrent_bi_streams(&self, count: VarInt) { +901 let mut conn = self.0.lock_and_wake("set_max_concurrent_bi_streams"); +902 conn.inner.set_max_concurrent_streams(Dir::Bi, count); 903 } 904 -905 /// Track changed on our external address as reported by the peer. -906 pub fn observed_external_addr(&self) -> watch::Receiver<Option<SocketAddr>> { -907 let conn = self.0.state.lock("external_addr"); -908 conn.observed_external_addr.subscribe() +905 /// Track changes on our external address as reported by the peer. +906 pub fn observed_external_addr(&self) -> crate::ObservedExternalAddr { +907 let conn = self.0.lock_without_waking("external_addr"); +908 crate::ObservedExternalAddr::new(conn.observed_external_addr.subscribe()) 909 } 910 911 /// Is multipath enabled? 912 // TODO(flub): not a useful API, once we do real things with multipath we can remove 913 // this again. 914 pub fn is_multipath_enabled(&self) -> bool { -915 let conn = self.0.state.lock("is_multipath_enabled"); +915 let conn = self.0.lock_without_waking("is_multipath_enabled"); 916 conn.inner.is_multipath_negotiated() 917 } 918 @@ -926,44 +926,44 @@ 926 &self, 927 address: SocketAddr, 928 ) -> Result<(), n0_nat_traversal::Error> { -929 let mut conn = self.0.state.lock("add_nat_traversal_addresses"); -930 let result = conn.inner.add_nat_traversal_address(address); -931 conn.wake(); -932 result -933 } -934 -935 /// Removes one or more addresses from the set of addresses at which this endpoint is reachable -936 /// -937 /// When the NAT traversal extension is negotiated, servers send address removals to -938 /// clients in `REMOVE_ADDRESS` frames. This allows clients to stop using outdated -939 /// server address candidates that are no longer valid for NAT traversal. +929 let mut conn = self.0.lock_and_wake("add_nat_traversal_addresses"); +930 conn.inner.add_nat_traversal_address(address) +931 } +932 +933 /// Removes one or more addresses from the set of addresses at which this endpoint is reachable +934 /// +935 /// When the NAT traversal extension is negotiated, servers send address removals to +936 /// clients in `REMOVE_ADDRESS` frames. This allows clients to stop using outdated +937 /// server address candidates that are no longer valid for NAT traversal. +938 /// +939 /// For clients, removed addresses will no longer be advertised in `REACH_OUT` frames. 940 /// -941 /// For clients, removed addresses will no longer be advertised in `REACH_OUT` frames. -942 /// -943 /// Addresses not present in the set will be silently ignored. -944 pub fn remove_nat_traversal_address( -945 &self, -946 address: SocketAddr, -947 ) -> Result<(), n0_nat_traversal::Error> { -948 let mut conn = self.0.state.lock("remove_nat_traversal_addresses"); -949 let result = conn.inner.remove_nat_traversal_address(address); -950 conn.wake(); -951 result -952 } -953 -954 /// Get the current local nat traversal addresses -955 pub fn get_local_nat_traversal_addresses( -956 &self, -957 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -958 let conn = self.0.state.lock("get_local_nat_traversal_addresses"); -959 conn.inner.get_local_nat_traversal_addresses() -960 } -961 -962 /// Get the currently advertised nat traversal addresses by the server -963 pub fn get_remote_nat_traversal_addresses( -964 &self, -965 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -966 let conn = self.0.state.lock("get_remote_nat_traversal_addresses"); +941 /// Addresses not present in the set will be silently ignored. +942 pub fn remove_nat_traversal_address( +943 &self, +944 address: SocketAddr, +945 ) -> Result<(), n0_nat_traversal::Error> { +946 let mut conn = self.0.lock_and_wake("remove_nat_traversal_addresses"); +947 conn.inner.remove_nat_traversal_address(address) +948 } +949 +950 /// Get the current local nat traversal addresses +951 pub fn get_local_nat_traversal_addresses( +952 &self, +953 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +954 let conn = self +955 .0 +956 .lock_without_waking("get_local_nat_traversal_addresses"); +957 conn.inner.get_local_nat_traversal_addresses() +958 } +959 +960 /// Get the currently advertised nat traversal addresses by the server +961 pub fn get_remote_nat_traversal_addresses( +962 &self, +963 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +964 let conn = self +965 .0 +966 .lock_without_waking("get_remote_nat_traversal_addresses"); 967 conn.inner.get_remote_nat_traversal_addresses() 968 } 969 @@ -975,865 +975,906 @@ 975 /// 976 /// Returns the server addresses that are now being probed. 977 pub fn initiate_nat_traversal_round(&self) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -978 let mut conn = self.0.state.lock("initiate_nat_traversal_round"); +978 let mut conn = self.0.lock_and_wake("initiate_nat_traversal_round"); 979 let now = conn.runtime.now(); -980 let result = conn.inner.initiate_nat_traversal_round(now); -981 conn.wake(); -982 result -983 } -984} -985 -986pin_project! { -987 /// Future produced by [`Connection::open_uni`] -988 pub struct OpenUni<'a> { -989 conn: &'a ConnectionRef, -990 #[pin] -991 notify: Notified<'a>, -992 } -993} -994 -995impl Future for OpenUni<'_> { -996 type Output = Result<SendStream, ConnectionError>; -997 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -998 let this = self.project(); -999 let (conn, id, is_0rtt) = ready!(poll_open(ctx, this.conn, this.notify, Dir::Uni))?; -1000 Poll::Ready(Ok(SendStream::new(conn, id, is_0rtt))) -1001 } -1002} -1003 -1004pin_project! { -1005 /// Future produced by [`Connection::open_bi`] -1006 pub struct OpenBi<'a> { -1007 conn: &'a ConnectionRef, -1008 #[pin] -1009 notify: Notified<'a>, -1010 } -1011} -1012 -1013impl Future for OpenBi<'_> { -1014 type Output = Result<(SendStream, RecvStream), ConnectionError>; -1015 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1016 let this = self.project(); -1017 let (conn, id, is_0rtt) = ready!(poll_open(ctx, this.conn, this.notify, Dir::Bi))?; -1018 -1019 Poll::Ready(Ok(( -1020 SendStream::new(conn.clone(), id, is_0rtt), -1021 RecvStream::new(conn, id, is_0rtt), -1022 ))) -1023 } -1024} -1025 -1026fn poll_open<'a>( -1027 ctx: &mut Context<'_>, -1028 conn: &'a ConnectionRef, -1029 mut notify: Pin<&mut Notified<'a>>, -1030 dir: Dir, -1031) -> Poll<Result<(ConnectionRef, StreamId, bool), ConnectionError>> { -1032 let mut state = conn.state.lock("poll_open"); -1033 if let Some(ref e) = state.error { -1034 return Poll::Ready(Err(e.clone())); -1035 } else if let Some(id) = state.inner.streams().open(dir) { -1036 let is_0rtt = state.inner.side().is_client() && state.inner.is_handshaking(); -1037 drop(state); // Release the lock so clone can take it -1038 return Poll::Ready(Ok((conn.clone(), id, is_0rtt))); -1039 } -1040 loop { -1041 match notify.as_mut().poll(ctx) { -1042 // `state` lock ensures we didn't race with readiness -1043 Poll::Pending => return Poll::Pending, -1044 // Spurious wakeup, get a new future -1045 Poll::Ready(()) => { -1046 notify.set(conn.shared.stream_budget_available[dir as usize].notified()) -1047 } -1048 } -1049 } -1050} -1051 -1052pin_project! { -1053 /// Future produced by [`Connection::accept_uni`] -1054 pub struct AcceptUni<'a> { -1055 conn: &'a ConnectionRef, -1056 #[pin] -1057 notify: Notified<'a>, -1058 } -1059} -1060 -1061impl Future for AcceptUni<'_> { -1062 type Output = Result<RecvStream, ConnectionError>; -1063 -1064 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1065 let this = self.project(); -1066 let (conn, id, is_0rtt) = ready!(poll_accept(ctx, this.conn, this.notify, Dir::Uni))?; -1067 Poll::Ready(Ok(RecvStream::new(conn, id, is_0rtt))) -1068 } -1069} -1070 -1071pin_project! { -1072 /// Future produced by [`Connection::accept_bi`] -1073 pub struct AcceptBi<'a> { -1074 conn: &'a ConnectionRef, -1075 #[pin] -1076 notify: Notified<'a>, -1077 } -1078} -1079 -1080impl Future for AcceptBi<'_> { -1081 type Output = Result<(SendStream, RecvStream), ConnectionError>; -1082 -1083 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1084 let this = self.project(); -1085 let (conn, id, is_0rtt) = ready!(poll_accept(ctx, this.conn, this.notify, Dir::Bi))?; -1086 Poll::Ready(Ok(( -1087 SendStream::new(conn.clone(), id, is_0rtt), -1088 RecvStream::new(conn, id, is_0rtt), -1089 ))) -1090 } -1091} -1092 -1093fn poll_accept<'a>( -1094 ctx: &mut Context<'_>, -1095 conn: &'a ConnectionRef, -1096 mut notify: Pin<&mut Notified<'a>>, -1097 dir: Dir, -1098) -> Poll<Result<(ConnectionRef, StreamId, bool), ConnectionError>> { -1099 let mut state = conn.state.lock("poll_accept"); -1100 // Check for incoming streams before checking `state.error` so that already-received streams, -1101 // which are necessarily finite, can be drained from a closed connection. -1102 if let Some(id) = state.inner.streams().accept(dir) { -1103 let is_0rtt = state.inner.is_handshaking(); -1104 state.wake(); // To send additional stream ID credit -1105 drop(state); // Release the lock so clone can take it -1106 return Poll::Ready(Ok((conn.clone(), id, is_0rtt))); -1107 } else if let Some(ref e) = state.error { -1108 return Poll::Ready(Err(e.clone())); -1109 } -1110 loop { -1111 match notify.as_mut().poll(ctx) { -1112 // `state` lock ensures we didn't race with readiness -1113 Poll::Pending => return Poll::Pending, -1114 // Spurious wakeup, get a new future -1115 Poll::Ready(()) => notify.set(conn.shared.stream_incoming[dir as usize].notified()), -1116 } -1117 } -1118} -1119 -1120pin_project! { -1121 /// Future produced by [`Connection::read_datagram`] -1122 pub struct ReadDatagram<'a> { -1123 conn: &'a ConnectionRef, -1124 #[pin] -1125 notify: Notified<'a>, -1126 } -1127} -1128 -1129impl Future for ReadDatagram<'_> { -1130 type Output = Result<Bytes, ConnectionError>; -1131 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1132 let mut this = self.project(); -1133 let mut state = this.conn.state.lock("ReadDatagram::poll"); -1134 // Check for buffered datagrams before checking `state.error` so that already-received -1135 // datagrams, which are necessarily finite, can be drained from a closed connection. -1136 if let Some(x) = state.inner.datagrams().recv() { -1137 return Poll::Ready(Ok(x)); -1138 } else if let Some(ref e) = state.error { -1139 return Poll::Ready(Err(e.clone())); -1140 } -1141 loop { -1142 match this.notify.as_mut().poll(ctx) { -1143 // `state` lock ensures we didn't race with readiness -1144 Poll::Pending => return Poll::Pending, -1145 // Spurious wakeup, get a new future -1146 Poll::Ready(()) => this -1147 .notify -1148 .set(this.conn.shared.datagram_received.notified()), -1149 } -1150 } -1151 } -1152} -1153 -1154pin_project! { -1155 /// Future produced by [`Connection::send_datagram_wait`] -1156 pub struct SendDatagram<'a> { -1157 conn: &'a ConnectionRef, -1158 data: Option<Bytes>, -1159 #[pin] -1160 notify: Notified<'a>, -1161 } -1162} -1163 -1164impl Future for SendDatagram<'_> { -1165 type Output = Result<(), SendDatagramError>; -1166 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { -1167 let mut this = self.project(); -1168 let mut state = this.conn.state.lock("SendDatagram::poll"); -1169 if let Some(ref e) = state.error { -1170 return Poll::Ready(Err(SendDatagramError::ConnectionLost(e.clone()))); -1171 } -1172 use proto::SendDatagramError::*; -1173 match state -1174 .inner -1175 .datagrams() -1176 .send(this.data.take().unwrap(), false) -1177 { -1178 Ok(()) => { -1179 state.wake(); -1180 Poll::Ready(Ok(())) -1181 } -1182 Err(e) => Poll::Ready(Err(match e { -1183 Blocked(data) => { -1184 this.data.replace(data); -1185 loop { -1186 match this.notify.as_mut().poll(ctx) { -1187 Poll::Pending => return Poll::Pending, -1188 // Spurious wakeup, get a new future -1189 Poll::Ready(()) => this -1190 .notify -1191 .set(this.conn.shared.datagrams_unblocked.notified()), -1192 } -1193 } -1194 } -1195 UnsupportedByPeer => SendDatagramError::UnsupportedByPeer, -1196 Disabled => SendDatagramError::Disabled, -1197 TooLarge => SendDatagramError::TooLarge, -1198 })), -1199 } -1200 } -1201} -1202 -1203/// Future returned by [`Connection::on_closed`] -1204/// -1205/// Resolves to a tuple of ([`ConnectionError`], [`ConnectionStats`]). -1206pub struct OnClosed { -1207 rx: oneshot::Receiver<(ConnectionError, ConnectionStats)>, -1208 conn: WeakConnectionHandle, -1209} -1210 -1211impl Drop for OnClosed { -1212 fn drop(&mut self) { -1213 if self.rx.is_terminated() { -1214 return; -1215 }; -1216 if let Some(conn) = self.conn.upgrade() { -1217 self.rx.close(); -1218 conn.0 -1219 .state -1220 .lock("OnClosed::drop") -1221 .on_closed -1222 .retain(|tx| !tx.is_closed()); -1223 } -1224 } -1225} -1226 -1227impl Future for OnClosed { -1228 type Output = (ConnectionError, ConnectionStats); -1229 -1230 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -1231 let this = self.get_mut(); -1232 // The `expect` is safe because `State::drop` ensures that all senders are triggered -1233 // before being dropped. -1234 Pin::new(&mut this.rx) -1235 .poll(cx) -1236 .map(|x| x.expect("on_close sender is never dropped before sending")) -1237 } -1238} -1239 -1240#[derive(Debug)] -1241#[allow(clippy::redundant_allocation)] -1242pub(crate) struct ConnectionRef(Arc<Arc<ConnectionInner>>); +980 conn.inner.initiate_nat_traversal_round(now) +981 } +982} +983 +984pin_project! { +985 /// Future produced by [`Connection::open_uni`] +986 pub struct OpenUni<'a> { +987 conn: &'a ConnectionRef, +988 #[pin] +989 notify: Notified<'a>, +990 } +991} +992 +993impl Future for OpenUni<'_> { +994 type Output = Result<SendStream, ConnectionError>; +995 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +996 let this = self.project(); +997 let (conn, id, is_0rtt) = ready!(poll_open(ctx, this.conn, this.notify, Dir::Uni))?; +998 Poll::Ready(Ok(SendStream::new(conn, id, is_0rtt))) +999 } +1000} +1001 +1002pin_project! { +1003 /// Future produced by [`Connection::open_bi`] +1004 pub struct OpenBi<'a> { +1005 conn: &'a ConnectionRef, +1006 #[pin] +1007 notify: Notified<'a>, +1008 } +1009} +1010 +1011impl Future for OpenBi<'_> { +1012 type Output = Result<(SendStream, RecvStream), ConnectionError>; +1013 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1014 let this = self.project(); +1015 let (conn, id, is_0rtt) = ready!(poll_open(ctx, this.conn, this.notify, Dir::Bi))?; +1016 +1017 Poll::Ready(Ok(( +1018 SendStream::new(conn.clone(), id, is_0rtt), +1019 RecvStream::new(conn, id, is_0rtt), +1020 ))) +1021 } +1022} +1023 +1024fn poll_open<'a>( +1025 ctx: &mut Context<'_>, +1026 conn: &'a ConnectionRef, +1027 mut notify: Pin<&mut Notified<'a>>, +1028 dir: Dir, +1029) -> Poll<Result<(ConnectionRef, StreamId, bool), ConnectionError>> { +1030 let mut state = conn.lock_without_waking("poll_open"); +1031 if let Some(ref e) = state.error { +1032 return Poll::Ready(Err(e.clone())); +1033 } else if let Some(id) = state.inner.streams().open(dir) { +1034 let is_0rtt = state.inner.side().is_client() && state.inner.is_handshaking(); +1035 drop(state); // Release the lock so clone can take it +1036 return Poll::Ready(Ok((conn.clone(), id, is_0rtt))); +1037 } +1038 loop { +1039 match notify.as_mut().poll(ctx) { +1040 // `state` lock ensures we didn't race with readiness +1041 Poll::Pending => return Poll::Pending, +1042 // Spurious wakeup, get a new future +1043 Poll::Ready(()) => { +1044 notify.set(conn.shared.stream_budget_available[dir as usize].notified()) +1045 } +1046 } +1047 } +1048} +1049 +1050pin_project! { +1051 /// Future produced by [`Connection::accept_uni`] +1052 pub struct AcceptUni<'a> { +1053 conn: &'a ConnectionRef, +1054 #[pin] +1055 notify: Notified<'a>, +1056 } +1057} +1058 +1059impl Future for AcceptUni<'_> { +1060 type Output = Result<RecvStream, ConnectionError>; +1061 +1062 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1063 let this = self.project(); +1064 let (conn, id, is_0rtt) = ready!(poll_accept(ctx, this.conn, this.notify, Dir::Uni))?; +1065 Poll::Ready(Ok(RecvStream::new(conn, id, is_0rtt))) +1066 } +1067} +1068 +1069pin_project! { +1070 /// Future produced by [`Connection::accept_bi`] +1071 pub struct AcceptBi<'a> { +1072 conn: &'a ConnectionRef, +1073 #[pin] +1074 notify: Notified<'a>, +1075 } +1076} +1077 +1078impl Future for AcceptBi<'_> { +1079 type Output = Result<(SendStream, RecvStream), ConnectionError>; +1080 +1081 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1082 let this = self.project(); +1083 let (conn, id, is_0rtt) = ready!(poll_accept(ctx, this.conn, this.notify, Dir::Bi))?; +1084 Poll::Ready(Ok(( +1085 SendStream::new(conn.clone(), id, is_0rtt), +1086 RecvStream::new(conn, id, is_0rtt), +1087 ))) +1088 } +1089} +1090 +1091fn poll_accept<'a>( +1092 ctx: &mut Context<'_>, +1093 conn: &'a ConnectionRef, +1094 mut notify: Pin<&mut Notified<'a>>, +1095 dir: Dir, +1096) -> Poll<Result<(ConnectionRef, StreamId, bool), ConnectionError>> { +1097 let mut state = conn.lock_and_wake("poll_accept"); +1098 // Check for incoming streams before checking `state.error` so that already-received streams, +1099 // which are necessarily finite, can be drained from a closed connection. +1100 if let Some(id) = state.inner.streams().accept(dir) { +1101 let is_0rtt = state.inner.is_handshaking(); +1102 drop(state); // Release the lock (wake on drop) so clone can take it +1103 return Poll::Ready(Ok((conn.clone(), id, is_0rtt))); +1104 } else if let Some(ref e) = state.error { +1105 return Poll::Ready(Err(e.clone())); +1106 } +1107 loop { +1108 match notify.as_mut().poll(ctx) { +1109 // `state` lock ensures we didn't race with readiness +1110 Poll::Pending => return Poll::Pending, +1111 // Spurious wakeup, get a new future +1112 Poll::Ready(()) => notify.set(conn.shared.stream_incoming[dir as usize].notified()), +1113 } +1114 } +1115} +1116 +1117pin_project! { +1118 /// Future produced by [`Connection::read_datagram`] +1119 pub struct ReadDatagram<'a> { +1120 conn: &'a ConnectionRef, +1121 #[pin] +1122 notify: Notified<'a>, +1123 } +1124} +1125 +1126impl Future for ReadDatagram<'_> { +1127 type Output = Result<Bytes, ConnectionError>; +1128 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1129 let mut this = self.project(); +1130 let mut state = this.conn.lock_without_waking("ReadDatagram::poll"); +1131 // Check for buffered datagrams before checking `state.error` so that already-received +1132 // datagrams, which are necessarily finite, can be drained from a closed connection. +1133 if let Some(x) = state.inner.datagrams().recv() { +1134 return Poll::Ready(Ok(x)); +1135 } else if let Some(ref e) = state.error { +1136 return Poll::Ready(Err(e.clone())); +1137 } +1138 loop { +1139 match this.notify.as_mut().poll(ctx) { +1140 // `state` lock ensures we didn't race with readiness +1141 Poll::Pending => return Poll::Pending, +1142 // Spurious wakeup, get a new future +1143 Poll::Ready(()) => this +1144 .notify +1145 .set(this.conn.shared.datagram_received.notified()), +1146 } +1147 } +1148 } +1149} +1150 +1151pin_project! { +1152 /// Future produced by [`Connection::send_datagram_wait`] +1153 pub struct SendDatagram<'a> { +1154 conn: &'a ConnectionRef, +1155 data: Option<Bytes>, +1156 #[pin] +1157 notify: Notified<'a>, +1158 } +1159} +1160 +1161impl Future for SendDatagram<'_> { +1162 type Output = Result<(), SendDatagramError>; +1163 fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> { +1164 let mut this = self.project(); +1165 let mut state = this.conn.lock_and_wake("SendDatagram::poll"); +1166 if let Some(ref e) = state.error { +1167 return Poll::Ready(Err(SendDatagramError::ConnectionLost(e.clone()))); +1168 } +1169 use proto::SendDatagramError::*; +1170 match state +1171 .inner +1172 .datagrams() +1173 .send(this.data.take().unwrap(), false) +1174 { +1175 Ok(()) => Poll::Ready(Ok(())), +1176 Err(e) => Poll::Ready(Err(match e { +1177 Blocked(data) => { +1178 this.data.replace(data); +1179 loop { +1180 match this.notify.as_mut().poll(ctx) { +1181 Poll::Pending => return Poll::Pending, +1182 // Spurious wakeup, get a new future +1183 Poll::Ready(()) => this +1184 .notify +1185 .set(this.conn.shared.datagrams_unblocked.notified()), +1186 } +1187 } +1188 } +1189 UnsupportedByPeer => SendDatagramError::UnsupportedByPeer, +1190 Disabled => SendDatagramError::Disabled, +1191 TooLarge => SendDatagramError::TooLarge, +1192 })), +1193 } +1194 } +1195} +1196 +1197/// Future returned by [`Connection::on_closed`] +1198/// +1199/// Resolves to a tuple of ([`ConnectionError`], [`ConnectionStats`]). +1200pub struct OnClosed { +1201 rx: oneshot::Receiver<(ConnectionError, ConnectionStats)>, +1202 conn: WeakConnectionHandle, +1203} +1204 +1205impl Drop for OnClosed { +1206 fn drop(&mut self) { +1207 if self.rx.is_terminated() { +1208 return; +1209 }; +1210 if let Some(conn) = self.conn.upgrade() { +1211 self.rx.close(); +1212 conn.0 +1213 .lock_without_waking("OnClosed::drop") +1214 .on_closed +1215 .retain(|tx| !tx.is_closed()); +1216 } +1217 } +1218} +1219 +1220impl Future for OnClosed { +1221 type Output = (ConnectionError, ConnectionStats); +1222 +1223 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +1224 let this = self.get_mut(); +1225 // The `expect` is safe because `State::drop` ensures that all senders are triggered +1226 // before being dropped. +1227 Pin::new(&mut this.rx) +1228 .poll(cx) +1229 .map(|x| x.expect("on_close sender is never dropped before sending")) +1230 } +1231} +1232 +1233#[derive(Debug)] +1234#[allow(clippy::redundant_allocation)] +1235pub(crate) struct ConnectionRef(Arc<Arc<ConnectionInner>>); +1236 +1237impl ConnectionRef { +1238 #[allow(clippy::redundant_allocation)] +1239 fn from_arc(inner: Arc<Arc<ConnectionInner>>) -> Self { +1240 inner.lock_without_waking("from_arc").ref_count += 1; +1241 Self(inner) +1242 } 1243 -1244impl ConnectionRef { -1245 #[allow(clippy::redundant_allocation)] -1246 fn from_arc(inner: Arc<Arc<ConnectionInner>>) -> Self { -1247 inner.state.lock("from_arc").ref_count += 1; -1248 Self(inner) -1249 } -1250 -1251 pub(crate) fn stable_id(&self) -> usize { -1252 &*self.0 as *const _ as usize -1253 } -1254 -1255 pub(crate) fn weak_handle(&self) -> WeakConnectionHandle { -1256 WeakConnectionHandle(Arc::downgrade(&self.0)) -1257 } -1258} -1259 -1260impl Clone for ConnectionRef { -1261 fn clone(&self) -> Self { -1262 Self::from_arc(Arc::clone(&self.0)) -1263 } -1264} -1265 -1266impl Drop for ConnectionRef { -1267 fn drop(&mut self) { -1268 let conn = &mut *self.state.lock("drop"); -1269 if let Some(x) = conn.ref_count.checked_sub(1) { -1270 conn.ref_count = x; -1271 if x == 0 && !conn.inner.is_closed() { -1272 // If the driver is alive, it's just it and us, so we'd better shut it down. If it's -1273 // not, we can't do any harm. If there were any streams being opened, then either -1274 // the connection will be closed for an unrelated reason or a fresh reference will -1275 // be constructed for the newly opened stream. -1276 conn.implicit_close(&self.shared); -1277 } -1278 } -1279 } +1244 pub(crate) fn stable_id(&self) -> usize { +1245 &*self.0 as *const _ as usize +1246 } +1247 +1248 pub(crate) fn weak_handle(&self) -> WeakConnectionHandle { +1249 WeakConnectionHandle(Arc::downgrade(&self.0)) +1250 } +1251} +1252 +1253impl Clone for ConnectionRef { +1254 fn clone(&self) -> Self { +1255 Self::from_arc(Arc::clone(&self.0)) +1256 } +1257} +1258 +1259impl Drop for ConnectionRef { +1260 fn drop(&mut self) { +1261 let conn = &mut *self.lock_without_waking("drop"); +1262 if let Some(x) = conn.ref_count.checked_sub(1) { +1263 conn.ref_count = x; +1264 if x == 0 && !conn.inner.is_closed() { +1265 // If the driver is alive, it's just it and us, so we'd better shut it down. If it's +1266 // not, we can't do any harm. If there were any streams being opened, then either +1267 // the connection will be closed for an unrelated reason or a fresh reference will +1268 // be constructed for the newly opened stream. +1269 conn.implicit_close(&self.shared); +1270 } +1271 } +1272 } +1273} +1274 +1275impl std::ops::Deref for ConnectionRef { +1276 type Target = ConnectionInner; +1277 fn deref(&self) -> &Self::Target { +1278 &self.0 +1279 } 1280} 1281 -1282impl std::ops::Deref for ConnectionRef { -1283 type Target = ConnectionInner; -1284 fn deref(&self) -> &Self::Target { -1285 &self.0 -1286 } +1282#[derive(Debug)] +1283pub(crate) struct ConnectionInner { +1284 /// Kept private intentionally, use [`Self::lock_and_wake`]. +1285 state: Mutex<State>, +1286 pub(crate) shared: Shared, 1287} 1288 -1289#[derive(Debug)] -1290pub(crate) struct ConnectionInner { -1291 pub(crate) state: Mutex<State>, -1292 pub(crate) shared: Shared, -1293} -1294 -1295/// A handle to some connection internals, use with care. -1296/// -1297/// This contains a weak reference to the connection so will not itself keep the connection -1298/// alive. -1299#[derive(Debug, Clone)] -1300pub struct WeakConnectionHandle(Weak<Arc<ConnectionInner>>); -1301 -1302impl WeakConnectionHandle { -1303 /// Returns `true` if the [`Connection`] associated with this handle is still alive. -1304 pub fn is_alive(&self) -> bool { -1305 self.0.upgrade().is_some() -1306 } -1307 -1308 /// Upgrade the handle to a full `Connection` -1309 pub fn upgrade(&self) -> Option<Connection> { -1310 self.upgrade_to_ref().map(Connection) -1311 } +1289impl ConnectionInner { +1290 /// Lock the state and return a guard that wakes the connection driver on drop. +1291 /// +1292 /// Use this for operations that may queue frames. The wake ensures the driver sends queued frames. +1293 /// If that's not needed, use [`Self::lock_without_waking`]. +1294 pub(crate) fn lock_and_wake(&self, purpose: &'static str) -> WakeGuard<'_> { +1295 WakeGuard { +1296 guard: self.state.lock(purpose), +1297 wake: true, +1298 } +1299 } +1300 +1301 /// Lock the state and return a guard that unlocks once dropped. +1302 /// +1303 /// Use this for operations that don't require any action from the connection driver. +1304 /// Otherwise, use [`Self::lock_and_wake`] instead. +1305 pub(crate) fn lock_without_waking(&self, purpose: &'static str) -> WakeGuard<'_> { +1306 WakeGuard { +1307 guard: self.state.lock(purpose), +1308 wake: false, +1309 } +1310 } +1311} 1312 -1313 pub(crate) fn upgrade_to_ref(&self) -> Option<ConnectionRef> { -1314 self.0.upgrade().map(ConnectionRef::from_arc) -1315 } -1316 -1317 /// Returns `true` if the two [`WeakConnectionHandle`] point at the same connection. -1318 pub fn is_same_connection(&self, other: &Self) -> bool { -1319 self.0.ptr_eq(&other.0) -1320 } -1321} -1322 -1323#[derive(Debug, Default)] -1324pub(crate) struct Shared { -1325 handshake_confirmed: Notify, -1326 /// Notified when new streams may be locally initiated due to an increase in stream ID flow -1327 /// control budget -1328 stream_budget_available: [Notify; 2], -1329 /// Notified when the peer has initiated a new stream -1330 stream_incoming: [Notify; 2], -1331 datagram_received: Notify, -1332 datagrams_unblocked: Notify, -1333 closed: Notify, +1313/// [`MutexGuard`] wrapper that calls [`State::wake`] on drop. +1314#[derive(derive_more::Deref, derive_more::DerefMut)] +1315pub(crate) struct WakeGuard<'a> { +1316 #[deref] +1317 #[deref_mut] +1318 guard: MutexGuard<'a, State>, +1319 wake: bool, +1320} +1321 +1322impl WakeGuard<'_> { +1323 pub(crate) fn skip_waking(&mut self) { +1324 self.wake = false; +1325 } +1326} +1327 +1328impl Drop for WakeGuard<'_> { +1329 fn drop(&mut self) { +1330 if self.wake { +1331 self.guard.wake(); +1332 } +1333 } 1334} 1335 -1336pub(crate) struct State { -1337 pub(crate) inner: proto::Connection, -1338 driver: Option<Waker>, -1339 handle: ConnectionHandle, -1340 on_handshake_data: Option<oneshot::Sender<()>>, -1341 on_connected: Option<oneshot::Sender<bool>>, -1342 connected: bool, -1343 handshake_confirmed: bool, -1344 timer: Option<Pin<Box<dyn AsyncTimer>>>, -1345 timer_deadline: Option<Instant>, -1346 conn_events: mpsc::UnboundedReceiver<ConnectionEvent>, -1347 endpoint_events: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>, -1348 pub(crate) blocked_writers: FxHashMap<StreamId, Waker>, -1349 pub(crate) blocked_readers: FxHashMap<StreamId, Waker>, -1350 pub(crate) stopped: FxHashMap<StreamId, Arc<Notify>>, -1351 /// Always set to Some before the connection becomes drained -1352 pub(crate) error: Option<ConnectionError>, -1353 /// Tracks paths being opened -1354 open_path: FxHashMap<PathId, watch::Sender<Result<(), PathError>>>, -1355 /// Tracks reference counts for paths. -1356 /// -1357 /// I.e. how many [`Path`] and [`WeakPathHandle`] structs are alive for a path. -1358 /// -1359 /// [`WeakPathHandle`]: crate::path::WeakPathHandle -1360 pub(crate) path_refs: FxHashMap<PathId, usize>, -1361 /// Final path stats for discarded paths. -1362 /// -1363 /// We only insert entries if the discarded path has a non-zero reference count in [`Self::path_refs`]. -1364 /// When the last reference to a path is dropped via [`Self::decrement_path_refs`] its value is cleared. -1365 pub(crate) final_path_stats: FxHashMap<PathId, PathStats>, -1366 pub(crate) path_events: tokio::sync::broadcast::Sender<PathEvent>, -1367 /// Number of live handles that can be used to initiate or handle I/O; excludes the driver -1368 ref_count: usize, -1369 sender: Pin<Box<dyn UdpSender>>, -1370 pub(crate) runtime: Arc<dyn Runtime>, -1371 send_buffer: Vec<u8>, -1372 /// We buffer a transmit when the underlying I/O would block -1373 buffered_transmit: Option<proto::Transmit>, -1374 /// Our last external address reported by the peer. When multipath is enabled, this will be the -1375 /// last report across all paths. -1376 pub(crate) observed_external_addr: watch::Sender<Option<SocketAddr>>, -1377 pub(crate) nat_traversal_updates: tokio::sync::broadcast::Sender<n0_nat_traversal::Event>, -1378 on_closed: Vec<oneshot::Sender<(ConnectionError, ConnectionStats)>>, -1379} -1380 -1381impl State { -1382 #[allow(clippy::too_many_arguments)] -1383 fn new( -1384 inner: proto::Connection, -1385 handle: ConnectionHandle, -1386 endpoint_events: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>, -1387 conn_events: mpsc::UnboundedReceiver<ConnectionEvent>, -1388 on_handshake_data: oneshot::Sender<()>, -1389 on_connected: oneshot::Sender<bool>, -1390 sender: Pin<Box<dyn UdpSender>>, -1391 runtime: Arc<dyn Runtime>, -1392 ) -> Self { -1393 Self { -1394 inner, -1395 driver: None, -1396 handle, -1397 on_handshake_data: Some(on_handshake_data), -1398 on_connected: Some(on_connected), -1399 connected: false, -1400 handshake_confirmed: false, -1401 timer: None, -1402 timer_deadline: None, -1403 conn_events, -1404 endpoint_events, -1405 blocked_writers: FxHashMap::default(), -1406 blocked_readers: FxHashMap::default(), -1407 stopped: FxHashMap::default(), -1408 open_path: FxHashMap::default(), -1409 error: None, -1410 ref_count: 0, -1411 sender, -1412 runtime, -1413 send_buffer: Vec::new(), -1414 buffered_transmit: None, -1415 path_events: tokio::sync::broadcast::channel(32).0, -1416 observed_external_addr: watch::Sender::new(None), -1417 nat_traversal_updates: tokio::sync::broadcast::channel(32).0, -1418 on_closed: Vec::new(), -1419 final_path_stats: Default::default(), -1420 path_refs: Default::default(), -1421 } -1422 } -1423 -1424 fn drive_transmit(&mut self, cx: &mut Context<'_>) -> io::Result<bool> { -1425 let now = self.runtime.now(); -1426 let mut transmits = 0; -1427 -1428 let max_datagrams = self -1429 .sender -1430 .max_transmit_segments() -1431 .min(MAX_TRANSMIT_SEGMENTS); -1432 -1433 loop { -1434 // Retry the last transmit, or get a new one. -1435 let t = match self.buffered_transmit.take() { -1436 Some(t) => t, -1437 None => { -1438 self.send_buffer.clear(); -1439 match self -1440 .inner -1441 .poll_transmit(now, max_datagrams, &mut self.send_buffer) -1442 { -1443 Some(t) => { -1444 transmits += match t.segment_size { -1445 None => 1, -1446 Some(s) => t.size.div_ceil(s), // round up -1447 }; -1448 t -1449 } -1450 None => break, -1451 } -1452 } -1453 }; -1454 -1455 let len = t.size; -1456 match self -1457 .sender -1458 .as_mut() -1459 .poll_send(&udp_transmit(&t, &self.send_buffer[..len]), cx) -1460 { -1461 Poll::Pending => { -1462 self.buffered_transmit = Some(t); -1463 return Ok(false); -1464 } -1465 Poll::Ready(Err(e)) => return Err(e), -1466 Poll::Ready(Ok(())) => {} -1467 } +1336/// A handle to some connection internals, use with care. +1337/// +1338/// This contains a weak reference to the connection so will not itself keep the connection +1339/// alive. +1340#[derive(Debug, Clone)] +1341pub struct WeakConnectionHandle(Weak<Arc<ConnectionInner>>); +1342 +1343impl WeakConnectionHandle { +1344 /// Returns `true` if the [`Connection`] associated with this handle is still alive. +1345 pub fn is_alive(&self) -> bool { +1346 self.0.upgrade().is_some() +1347 } +1348 +1349 /// Upgrade the handle to a full `Connection` +1350 pub fn upgrade(&self) -> Option<Connection> { +1351 self.upgrade_to_ref().map(Connection) +1352 } +1353 +1354 pub(crate) fn upgrade_to_ref(&self) -> Option<ConnectionRef> { +1355 self.0.upgrade().map(ConnectionRef::from_arc) +1356 } +1357 +1358 /// Returns `true` if the two [`WeakConnectionHandle`] point at the same connection. +1359 pub fn is_same_connection(&self, other: &Self) -> bool { +1360 self.0.ptr_eq(&other.0) +1361 } +1362} +1363 +1364#[derive(Debug, Default)] +1365pub(crate) struct Shared { +1366 handshake_confirmed: Notify, +1367 /// Notified when new streams may be locally initiated due to an increase in stream ID flow +1368 /// control budget +1369 stream_budget_available: [Notify; 2], +1370 /// Notified when the peer has initiated a new stream +1371 stream_incoming: [Notify; 2], +1372 datagram_received: Notify, +1373 datagrams_unblocked: Notify, +1374 closed: Notify, +1375} +1376 +1377pub(crate) struct State { +1378 pub(crate) inner: proto::Connection, +1379 driver: Option<Waker>, +1380 handle: ConnectionHandle, +1381 on_handshake_data: Option<oneshot::Sender<()>>, +1382 on_connected: Option<oneshot::Sender<bool>>, +1383 connected: bool, +1384 handshake_confirmed: bool, +1385 timer: Option<Pin<Box<dyn AsyncTimer>>>, +1386 timer_deadline: Option<Instant>, +1387 conn_events: mpsc::UnboundedReceiver<ConnectionEvent>, +1388 endpoint_events: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>, +1389 pub(crate) blocked_writers: FxHashMap<StreamId, Waker>, +1390 pub(crate) blocked_readers: FxHashMap<StreamId, Waker>, +1391 pub(crate) stopped: FxHashMap<StreamId, Arc<Notify>>, +1392 /// Always set to Some before the connection becomes drained +1393 pub(crate) error: Option<ConnectionError>, +1394 /// Tracks paths being opened +1395 open_path: FxHashMap<PathId, watch::Sender<Result<(), PathError>>>, +1396 /// Tracks reference counts for paths. +1397 /// +1398 /// I.e. how many [`Path`] and [`WeakPathHandle`] structs are alive for a path. +1399 /// +1400 /// [`WeakPathHandle`]: crate::path::WeakPathHandle +1401 pub(crate) path_refs: FxHashMap<PathId, usize>, +1402 /// Final path stats for discarded paths. +1403 /// +1404 /// We only insert entries if the discarded path has a non-zero reference count in [`Self::path_refs`]. +1405 /// When the last reference to a path is dropped via [`Self::decrement_path_refs`] its value is cleared. +1406 pub(crate) final_path_stats: FxHashMap<PathId, PathStats>, +1407 pub(crate) path_events: tokio::sync::broadcast::Sender<PathEvent>, +1408 /// Number of live handles that can be used to initiate or handle I/O; excludes the driver +1409 ref_count: usize, +1410 sender: Pin<Box<dyn UdpSender>>, +1411 pub(crate) runtime: Arc<dyn Runtime>, +1412 send_buffer: Vec<u8>, +1413 /// We buffer a transmit when the underlying I/O would block +1414 buffered_transmit: Option<proto::Transmit>, +1415 /// Our last external address reported by the peer. When multipath is enabled, this will be the +1416 /// last report across all paths. +1417 pub(crate) observed_external_addr: watch::Sender<Option<SocketAddr>>, +1418 pub(crate) nat_traversal_updates: tokio::sync::broadcast::Sender<n0_nat_traversal::Event>, +1419 on_closed: Vec<oneshot::Sender<(ConnectionError, ConnectionStats)>>, +1420} +1421 +1422impl State { +1423 #[allow(clippy::too_many_arguments)] +1424 fn new( +1425 inner: proto::Connection, +1426 handle: ConnectionHandle, +1427 endpoint_events: mpsc::UnboundedSender<(ConnectionHandle, EndpointEvent)>, +1428 conn_events: mpsc::UnboundedReceiver<ConnectionEvent>, +1429 on_handshake_data: oneshot::Sender<()>, +1430 on_connected: oneshot::Sender<bool>, +1431 sender: Pin<Box<dyn UdpSender>>, +1432 runtime: Arc<dyn Runtime>, +1433 ) -> Self { +1434 Self { +1435 inner, +1436 driver: None, +1437 handle, +1438 on_handshake_data: Some(on_handshake_data), +1439 on_connected: Some(on_connected), +1440 connected: false, +1441 handshake_confirmed: false, +1442 timer: None, +1443 timer_deadline: None, +1444 conn_events, +1445 endpoint_events, +1446 blocked_writers: FxHashMap::default(), +1447 blocked_readers: FxHashMap::default(), +1448 stopped: FxHashMap::default(), +1449 open_path: FxHashMap::default(), +1450 error: None, +1451 ref_count: 0, +1452 sender, +1453 runtime, +1454 send_buffer: Vec::new(), +1455 buffered_transmit: None, +1456 path_events: tokio::sync::broadcast::channel(32).0, +1457 observed_external_addr: watch::Sender::new(None), +1458 nat_traversal_updates: tokio::sync::broadcast::channel(32).0, +1459 on_closed: Vec::new(), +1460 final_path_stats: Default::default(), +1461 path_refs: Default::default(), +1462 } +1463 } +1464 +1465 fn drive_transmit(&mut self, cx: &mut Context<'_>) -> io::Result<bool> { +1466 let now = self.runtime.now(); +1467 let mut transmits = 0; 1468 -1469 if transmits >= MAX_TRANSMIT_DATAGRAMS { -1470 // TODO: What isn't ideal here yet is that if we don't poll all -1471 // datagrams that could be sent we don't go into the `app_limited` -1472 // state and CWND continues to grow until we get here the next time. -1473 // See https://github.com/quinn-rs/quinn/issues/1126 -1474 return Ok(true); -1475 } -1476 } -1477 -1478 Ok(false) -1479 } -1480 -1481 fn forward_endpoint_events(&mut self) { -1482 while let Some(event) = self.inner.poll_endpoint_events() { -1483 // If the endpoint driver is gone, noop. -1484 let _ = self.endpoint_events.send((self.handle, event)); -1485 } -1486 } -1487 -1488 /// If this returns `Err`, the endpoint is dead, so the driver should exit immediately. -1489 fn process_conn_events( -1490 &mut self, -1491 shared: &Shared, -1492 cx: &mut Context<'_>, -1493 ) -> Result<(), ConnectionError> { -1494 loop { -1495 match self.conn_events.poll_recv(cx) { -1496 Poll::Ready(Some(ConnectionEvent::Rebind(sender))) => { -1497 self.sender = sender; -1498 self.inner.handle_network_change(None, self.runtime.now()); -1499 } -1500 Poll::Ready(Some(ConnectionEvent::LocalAddressChanged(hint))) => { -1501 self.inner -1502 .handle_network_change(hint.as_deref().map(|x| x as _), self.runtime.now()); -1503 } -1504 Poll::Ready(Some(ConnectionEvent::Proto(event))) => { -1505 self.inner.handle_event(event); -1506 } -1507 Poll::Ready(Some(ConnectionEvent::Close { reason, error_code })) => { -1508 self.close(error_code, reason, shared); -1509 } -1510 Poll::Ready(None) => { -1511 return Err(ConnectionError::TransportError(TransportError::new( -1512 TransportErrorCode::INTERNAL_ERROR, -1513 "endpoint driver future was dropped".to_string(), -1514 ))); -1515 } -1516 Poll::Pending => { -1517 return Ok(()); -1518 } -1519 } -1520 } -1521 } -1522 -1523 fn forward_app_events(&mut self, shared: &Shared) { -1524 while let Some(event) = self.inner.poll() { -1525 use proto::Event::*; -1526 match event { -1527 HandshakeDataReady => { -1528 if let Some(x) = self.on_handshake_data.take() { -1529 let _ = x.send(()); -1530 } -1531 } -1532 Connected => { -1533 self.connected = true; -1534 if let Some(x) = self.on_connected.take() { -1535 // We don't care if the on-connected future was dropped -1536 let _ = x.send(self.inner.accepted_0rtt()); -1537 } -1538 if self.inner.side().is_client() && !self.inner.accepted_0rtt() { -1539 // Wake up rejected 0-RTT streams so they can fail immediately with -1540 // `ZeroRttRejected` errors. -1541 wake_all(&mut self.blocked_writers); -1542 wake_all(&mut self.blocked_readers); -1543 wake_all_notify(&mut self.stopped); -1544 } -1545 } -1546 HandshakeConfirmed => { -1547 self.handshake_confirmed = true; -1548 shared.handshake_confirmed.notify_waiters(); -1549 } -1550 ConnectionLost { reason } => { -1551 self.terminate(reason, shared); -1552 } -1553 Stream(StreamEvent::Writable { id }) => wake_stream(id, &mut self.blocked_writers), -1554 Stream(StreamEvent::Opened { dir: Dir::Uni }) => { -1555 shared.stream_incoming[Dir::Uni as usize].notify_waiters(); +1469 let max_datagrams = self +1470 .sender +1471 .max_transmit_segments() +1472 .min(MAX_TRANSMIT_SEGMENTS); +1473 +1474 loop { +1475 // Retry the last transmit, or get a new one. +1476 let t = match self.buffered_transmit.take() { +1477 Some(t) => t, +1478 None => { +1479 self.send_buffer.clear(); +1480 match self +1481 .inner +1482 .poll_transmit(now, max_datagrams, &mut self.send_buffer) +1483 { +1484 Some(t) => { +1485 transmits += match t.segment_size { +1486 None => 1, +1487 Some(s) => t.size.div_ceil(s), // round up +1488 }; +1489 t +1490 } +1491 None => break, +1492 } +1493 } +1494 }; +1495 +1496 let len = t.size; +1497 match self +1498 .sender +1499 .as_mut() +1500 .poll_send(&udp_transmit(&t, &self.send_buffer[..len]), cx) +1501 { +1502 Poll::Pending => { +1503 self.buffered_transmit = Some(t); +1504 return Ok(false); +1505 } +1506 Poll::Ready(Err(e)) => return Err(e), +1507 Poll::Ready(Ok(())) => {} +1508 } +1509 +1510 if transmits >= MAX_TRANSMIT_DATAGRAMS { +1511 // TODO: What isn't ideal here yet is that if we don't poll all +1512 // datagrams that could be sent we don't go into the `app_limited` +1513 // state and CWND continues to grow until we get here the next time. +1514 // See https://github.com/quinn-rs/quinn/issues/1126 +1515 return Ok(true); +1516 } +1517 } +1518 +1519 Ok(false) +1520 } +1521 +1522 fn forward_endpoint_events(&mut self) { +1523 while let Some(event) = self.inner.poll_endpoint_events() { +1524 // If the endpoint driver is gone, noop. +1525 let _ = self.endpoint_events.send((self.handle, event)); +1526 } +1527 } +1528 +1529 /// If this returns `Err`, the endpoint is dead, so the driver should exit immediately. +1530 fn process_conn_events( +1531 &mut self, +1532 shared: &Shared, +1533 cx: &mut Context<'_>, +1534 ) -> Result<(), ConnectionError> { +1535 loop { +1536 match self.conn_events.poll_recv(cx) { +1537 Poll::Ready(Some(ConnectionEvent::Rebind(sender))) => { +1538 self.sender = sender; +1539 self.inner.handle_network_change(None, self.runtime.now()); +1540 } +1541 Poll::Ready(Some(ConnectionEvent::LocalAddressChanged(hint))) => { +1542 self.inner +1543 .handle_network_change(hint.as_deref().map(|x| x as _), self.runtime.now()); +1544 } +1545 Poll::Ready(Some(ConnectionEvent::Proto(event))) => { +1546 self.inner.handle_event(event); +1547 } +1548 Poll::Ready(Some(ConnectionEvent::Close { reason, error_code })) => { +1549 self.close(error_code, reason, shared); +1550 } +1551 Poll::Ready(None) => { +1552 return Err(ConnectionError::TransportError(TransportError::new( +1553 TransportErrorCode::INTERNAL_ERROR, +1554 "endpoint driver future was dropped".to_string(), +1555 ))); 1556 } -1557 Stream(StreamEvent::Opened { dir: Dir::Bi }) => { -1558 shared.stream_incoming[Dir::Bi as usize].notify_waiters(); +1557 Poll::Pending => { +1558 return Ok(()); 1559 } -1560 DatagramReceived => { -1561 shared.datagram_received.notify_waiters(); -1562 } -1563 DatagramsUnblocked => { -1564 shared.datagrams_unblocked.notify_waiters(); -1565 } -1566 Stream(StreamEvent::Readable { id }) => wake_stream(id, &mut self.blocked_readers), -1567 Stream(StreamEvent::Available { dir }) => { -1568 // Might mean any number of streams are ready, so we wake up everyone -1569 shared.stream_budget_available[dir as usize].notify_waiters(); -1570 } -1571 Stream(StreamEvent::Finished { id }) => wake_stream_notify(id, &mut self.stopped), -1572 Stream(StreamEvent::Stopped { id, .. }) => { -1573 wake_stream_notify(id, &mut self.stopped); -1574 wake_stream(id, &mut self.blocked_writers); -1575 } -1576 Path(ref evt @ PathEvent::ObservedAddr { addr: observed, .. }) => { -1577 self.path_events.send(evt.clone()).ok(); -1578 self.observed_external_addr.send_if_modified(|addr| { -1579 let old = addr.replace(observed); -1580 old != *addr -1581 }); -1582 } -1583 Path(ref evt @ PathEvent::Opened { id }) => { -1584 self.path_events.send(evt.clone()).ok(); -1585 if let Some(sender) = self.open_path.remove(&id) { -1586 sender.send_modify(|value| *value = Ok(())); -1587 } -1588 } -1589 Path(ref evt @ PathEvent::Discarded { id, ref path_stats }) => { -1590 if self.path_refs.contains_key(&id) { -1591 self.final_path_stats.insert(id, *path_stats.clone()); -1592 } -1593 self.path_events.send(evt.clone()).ok(); -1594 } -1595 Path(ref evt @ PathEvent::Abandoned { id, .. }) => { -1596 if let Some(sender) = self.open_path.remove(&id) { -1597 // We don't care for the reason why this path was closed here, because semantically -1598 // all close reasons for a path that has not yet been opened equals to `ValidationFailed`. -1599 // With the noq API, there is no way to application-close a not-yet-opened path, so -1600 // `ApplicationClosed` cannot occur. And all other variants will only occur for paths -1601 // that have already been opened. -1602 // The previous iteration of this code had another event `PathEvent::LocallyClosed` which -1603 // contained a `PathError`, but that was only ever set to `ValidationFailed`. -1604 let error = PathError::ValidationFailed; -1605 sender.send_modify(|value| *value = Err(error)); -1606 } -1607 // this will happen also for already opened paths -1608 self.path_events.send(evt.clone()).ok(); -1609 } -1610 Path(evt @ PathEvent::RemoteStatus { .. }) => { -1611 self.path_events.send(evt).ok(); -1612 } -1613 NatTraversal(update) => { -1614 self.nat_traversal_updates.send(update).ok(); -1615 } -1616 } -1617 } -1618 } -1619 -1620 fn drive_timer(&mut self, cx: &mut Context<'_>) -> bool { -1621 // Check whether we need to (re)set the timer. If so, we must poll again to ensure the -1622 // timer is registered with the runtime (and check whether it's already -1623 // expired). -1624 match self.inner.poll_timeout() { -1625 Some(deadline) => { -1626 if let Some(delay) = &mut self.timer { -1627 // There is no need to reset the tokio timer if the deadline -1628 // did not change -1629 if self -1630 .timer_deadline -1631 .map(|current_deadline| current_deadline != deadline) -1632 .unwrap_or(true) -1633 { -1634 delay.as_mut().reset(deadline); -1635 } -1636 } else { -1637 self.timer = Some(self.runtime.new_timer(deadline)); -1638 } -1639 // Store the actual expiration time of the timer -1640 self.timer_deadline = Some(deadline); -1641 } -1642 None => { -1643 self.timer_deadline = None; -1644 return false; -1645 } -1646 } -1647 -1648 if self.timer_deadline.is_none() { -1649 return false; -1650 } -1651 -1652 let delay = self -1653 .timer -1654 .as_mut() -1655 .expect("timer must exist in this state") -1656 .as_mut(); -1657 if delay.poll(cx).is_pending() { -1658 // Since there wasn't a timeout event, there is nothing new -1659 // for the connection to do -1660 return false; -1661 } -1662 -1663 // A timer expired, so the caller needs to check for -1664 // new transmits, which might cause new timers to be set. -1665 self.inner.handle_timeout(self.runtime.now()); -1666 self.timer_deadline = None; -1667 true -1668 } -1669 -1670 /// Wake up a blocked `Driver` task to process I/O -1671 pub(crate) fn wake(&mut self) { -1672 if let Some(x) = self.driver.take() { -1673 x.wake(); -1674 } -1675 } -1676 -1677 /// Used to wake up all blocked futures when the connection becomes closed for any reason -1678 fn terminate(&mut self, reason: ConnectionError, shared: &Shared) { -1679 self.error = Some(reason.clone()); -1680 if let Some(x) = self.on_handshake_data.take() { -1681 let _ = x.send(()); -1682 } -1683 wake_all(&mut self.blocked_writers); -1684 wake_all(&mut self.blocked_readers); -1685 shared.stream_budget_available[Dir::Uni as usize].notify_waiters(); -1686 shared.stream_budget_available[Dir::Bi as usize].notify_waiters(); -1687 shared.stream_incoming[Dir::Uni as usize].notify_waiters(); -1688 shared.stream_incoming[Dir::Bi as usize].notify_waiters(); -1689 shared.datagram_received.notify_waiters(); -1690 shared.datagrams_unblocked.notify_waiters(); -1691 if let Some(x) = self.on_connected.take() { -1692 let _ = x.send(false); -1693 } -1694 shared.handshake_confirmed.notify_waiters(); -1695 wake_all_notify(&mut self.stopped); -1696 shared.closed.notify_waiters(); -1697 -1698 // Send to the registered on_closed futures. -1699 let stats = self.inner.stats(); -1700 for tx in self.on_closed.drain(..) { -1701 tx.send((reason.clone(), stats.clone())).ok(); +1560 } +1561 } +1562 } +1563 +1564 fn forward_app_events(&mut self, shared: &Shared) { +1565 while let Some(event) = self.inner.poll() { +1566 use proto::Event::*; +1567 match event { +1568 HandshakeDataReady => { +1569 if let Some(x) = self.on_handshake_data.take() { +1570 let _ = x.send(()); +1571 } +1572 } +1573 Connected => { +1574 self.connected = true; +1575 if let Some(x) = self.on_connected.take() { +1576 // We don't care if the on-connected future was dropped +1577 let _ = x.send(self.inner.accepted_0rtt()); +1578 } +1579 if self.inner.side().is_client() && !self.inner.accepted_0rtt() { +1580 // Wake up rejected 0-RTT streams so they can fail immediately with +1581 // `ZeroRttRejected` errors. +1582 wake_all(&mut self.blocked_writers); +1583 wake_all(&mut self.blocked_readers); +1584 wake_all_notify(&mut self.stopped); +1585 } +1586 } +1587 HandshakeConfirmed => { +1588 self.handshake_confirmed = true; +1589 shared.handshake_confirmed.notify_waiters(); +1590 } +1591 ConnectionLost { reason } => { +1592 self.terminate(reason, shared); +1593 } +1594 Stream(StreamEvent::Writable { id }) => wake_stream(id, &mut self.blocked_writers), +1595 Stream(StreamEvent::Opened { dir: Dir::Uni }) => { +1596 shared.stream_incoming[Dir::Uni as usize].notify_waiters(); +1597 } +1598 Stream(StreamEvent::Opened { dir: Dir::Bi }) => { +1599 shared.stream_incoming[Dir::Bi as usize].notify_waiters(); +1600 } +1601 DatagramReceived => { +1602 shared.datagram_received.notify_waiters(); +1603 } +1604 DatagramsUnblocked => { +1605 shared.datagrams_unblocked.notify_waiters(); +1606 } +1607 Stream(StreamEvent::Readable { id }) => wake_stream(id, &mut self.blocked_readers), +1608 Stream(StreamEvent::Available { dir }) => { +1609 // Might mean any number of streams are ready, so we wake up everyone +1610 shared.stream_budget_available[dir as usize].notify_waiters(); +1611 } +1612 Stream(StreamEvent::Finished { id }) => wake_stream_notify(id, &mut self.stopped), +1613 Stream(StreamEvent::Stopped { id, .. }) => { +1614 wake_stream_notify(id, &mut self.stopped); +1615 wake_stream(id, &mut self.blocked_writers); +1616 } +1617 Path(ref evt @ PathEvent::ObservedAddr { addr: observed, .. }) => { +1618 self.path_events.send(evt.clone()).ok(); +1619 self.observed_external_addr.send_if_modified(|addr| { +1620 let old = addr.replace(observed); +1621 old != *addr +1622 }); +1623 } +1624 Path(ref evt @ PathEvent::Opened { id }) => { +1625 self.path_events.send(evt.clone()).ok(); +1626 if let Some(sender) = self.open_path.remove(&id) { +1627 sender.send_modify(|value| *value = Ok(())); +1628 } +1629 } +1630 Path(ref evt @ PathEvent::Discarded { id, ref path_stats }) => { +1631 if self.path_refs.contains_key(&id) { +1632 self.final_path_stats.insert(id, *path_stats.clone()); +1633 } +1634 self.path_events.send(evt.clone()).ok(); +1635 } +1636 Path(ref evt @ PathEvent::Abandoned { id, .. }) => { +1637 if let Some(sender) = self.open_path.remove(&id) { +1638 // We don't care for the reason why this path was closed here, because semantically +1639 // all close reasons for a path that has not yet been opened equals to `ValidationFailed`. +1640 // With the noq API, there is no way to application-close a not-yet-opened path, so +1641 // `ApplicationClosed` cannot occur. And all other variants will only occur for paths +1642 // that have already been opened. +1643 // The previous iteration of this code had another event `PathEvent::LocallyClosed` which +1644 // contained a `PathError`, but that was only ever set to `ValidationFailed`. +1645 let error = PathError::ValidationFailed; +1646 sender.send_modify(|value| *value = Err(error)); +1647 } +1648 // this will happen also for already opened paths +1649 self.path_events.send(evt.clone()).ok(); +1650 } +1651 Path(evt @ PathEvent::RemoteStatus { .. }) => { +1652 self.path_events.send(evt).ok(); +1653 } +1654 NatTraversal(update) => { +1655 self.nat_traversal_updates.send(update).ok(); +1656 } +1657 } +1658 } +1659 } +1660 +1661 fn drive_timer(&mut self, cx: &mut Context<'_>) -> bool { +1662 // Check whether we need to (re)set the timer. If so, we must poll again to ensure the +1663 // timer is registered with the runtime (and check whether it's already +1664 // expired). +1665 match self.inner.poll_timeout() { +1666 Some(deadline) => { +1667 if let Some(delay) = &mut self.timer { +1668 // There is no need to reset the tokio timer if the deadline +1669 // did not change +1670 if self +1671 .timer_deadline +1672 .map(|current_deadline| current_deadline != deadline) +1673 .unwrap_or(true) +1674 { +1675 delay.as_mut().reset(deadline); +1676 } +1677 } else { +1678 self.timer = Some(self.runtime.new_timer(deadline)); +1679 } +1680 // Store the actual expiration time of the timer +1681 self.timer_deadline = Some(deadline); +1682 } +1683 None => { +1684 self.timer_deadline = None; +1685 return false; +1686 } +1687 } +1688 +1689 if self.timer_deadline.is_none() { +1690 return false; +1691 } +1692 +1693 let delay = self +1694 .timer +1695 .as_mut() +1696 .expect("timer must exist in this state") +1697 .as_mut(); +1698 if delay.poll(cx).is_pending() { +1699 // Since there wasn't a timeout event, there is nothing new +1700 // for the connection to do +1701 return false; 1702 } -1703 } -1704 -1705 fn close(&mut self, error_code: VarInt, reason: Bytes, shared: &Shared) { -1706 self.inner.close(self.runtime.now(), error_code, reason); -1707 self.terminate(ConnectionError::LocallyClosed, shared); -1708 self.wake(); -1709 } +1703 +1704 // A timer expired, so the caller needs to check for +1705 // new transmits, which might cause new timers to be set. +1706 self.inner.handle_timeout(self.runtime.now()); +1707 self.timer_deadline = None; +1708 true +1709 } 1710 -1711 /// Close for a reason other than the application's explicit request -1712 pub(crate) fn implicit_close(&mut self, shared: &Shared) { -1713 self.close(0u32.into(), Bytes::new(), shared); -1714 } -1715 -1716 pub(crate) fn check_0rtt(&self) -> Result<(), ()> { -1717 if self.inner.is_handshaking() -1718 || self.inner.accepted_0rtt() -1719 || self.inner.side().is_server() -1720 { -1721 Ok(()) -1722 } else { -1723 Err(()) -1724 } -1725 } -1726 -1727 /// Returns [`PathStats`] for a path, if available. -1728 /// -1729 /// This gets the stats from [`proto::Connection`]. If that returns `None` -1730 /// it gets them from `Self::final_path_stats` instead. -1731 pub(crate) fn path_stats(&mut self, path_id: PathId) -> Option<PathStats> { -1732 self.inner -1733 .path_stats(path_id) -1734 .or_else(|| self.final_path_stats.get(&path_id).copied()) -1735 } -1736 -1737 /// Increment the reference counter for a path in this connection. -1738 /// -1739 /// This counts how many [`Path`] or [`WeakPathHandle`] structs exist for a path. -1740 /// Currently this is used to determine whether to store the final stats after a path is -1741 /// abandoned. -1742 /// -1743 /// [`WeakPathHandle`]: crate::path::WeakPathHandle -1744 pub(crate) fn increment_path_refs(&mut self, path_id: PathId) { -1745 *self.path_refs.entry(path_id).or_default() += 1; -1746 } -1747 -1748 /// Decrement the reference counter for a path in this connection. -1749 pub(crate) fn decrement_path_refs(&mut self, path_id: PathId) { -1750 if let Some(refs) = self.path_refs.get_mut(&path_id) { -1751 *refs = refs.saturating_sub(1); -1752 if *refs == 0 { -1753 self.path_refs.remove(&path_id); -1754 self.final_path_stats.remove(&path_id); -1755 } -1756 } -1757 } -1758} -1759 -1760impl Drop for State { -1761 fn drop(&mut self) { -1762 if !self.inner.is_drained() { -1763 // Ensure the endpoint can tidy up -1764 let _ = self -1765 .endpoint_events -1766 .send((self.handle, proto::EndpointEvent::drained())); -1767 } -1768 -1769 if !self.on_closed.is_empty() { -1770 // Ensure that all on_closed oneshot senders are triggered before dropping. -1771 let reason = self.error.as_ref().expect("closed without error reason"); -1772 let stats = self.inner.stats(); -1773 for tx in self.on_closed.drain(..) { -1774 tx.send((reason.clone(), stats.clone())).ok(); -1775 } -1776 } -1777 } -1778} -1779 -1780impl fmt::Debug for State { -1781 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -1782 f.debug_struct("State").field("inner", &self.inner).finish() -1783 } -1784} -1785 -1786fn wake_stream(stream_id: StreamId, wakers: &mut FxHashMap<StreamId, Waker>) { -1787 if let Some(waker) = wakers.remove(&stream_id) { -1788 waker.wake(); -1789 } -1790} -1791 -1792fn wake_all(wakers: &mut FxHashMap<StreamId, Waker>) { -1793 wakers.drain().for_each(|(_, waker)| waker.wake()) -1794} -1795 -1796fn wake_stream_notify(stream_id: StreamId, wakers: &mut FxHashMap<StreamId, Arc<Notify>>) { -1797 if let Some(notify) = wakers.remove(&stream_id) { -1798 notify.notify_waiters() -1799 } -1800} -1801 -1802fn wake_all_notify(wakers: &mut FxHashMap<StreamId, Arc<Notify>>) { -1803 wakers -1804 .drain() -1805 .for_each(|(_, notify)| notify.notify_waiters()) -1806} -1807 -1808/// Errors that can arise when sending a datagram -1809#[derive(Debug, Error, Clone, Eq, PartialEq)] -1810pub enum SendDatagramError { -1811 /// The peer does not support receiving datagram frames -1812 #[error("datagrams not supported by peer")] -1813 UnsupportedByPeer, -1814 /// Datagram support is disabled locally -1815 #[error("datagram support disabled")] -1816 Disabled, -1817 /// The datagram is larger than the connection can currently accommodate -1818 /// -1819 /// Indicates that the path MTU minus overhead or the limit advertised by the peer has been -1820 /// exceeded. -1821 #[error("datagram too large")] -1822 TooLarge, -1823 /// The connection was lost -1824 #[error("connection lost")] -1825 ConnectionLost(#[from] ConnectionError), -1826} -1827 -1828/// The maximum amount of datagrams which will be produced in a single `drive_transmit` call -1829/// -1830/// This limits the amount of CPU resources consumed by datagram generation, -1831/// and allows other tasks (like receiving ACKs) to run in between. -1832const MAX_TRANSMIT_DATAGRAMS: usize = 20; -1833 -1834/// The maximum amount of datagrams that are sent in a single transmit -1835/// -1836/// This can be lower than the maximum platform capabilities, to avoid excessive -1837/// memory allocations when calling `poll_transmit()`. Benchmarks have shown -1838/// that numbers around 10 are a good compromise. -1839const MAX_TRANSMIT_SEGMENTS: NonZeroUsize = NonZeroUsize::new(10).expect("known");

\ No newline at end of file +1711 /// Wake up a blocked `Driver` task to process I/O +1712 pub(crate) fn wake(&mut self) { +1713 if let Some(x) = self.driver.take() { +1714 x.wake(); +1715 } +1716 } +1717 +1718 /// Used to wake up all blocked futures when the connection becomes closed for any reason +1719 fn terminate(&mut self, reason: ConnectionError, shared: &Shared) { +1720 self.error = Some(reason.clone()); +1721 if let Some(x) = self.on_handshake_data.take() { +1722 let _ = x.send(()); +1723 } +1724 wake_all(&mut self.blocked_writers); +1725 wake_all(&mut self.blocked_readers); +1726 shared.stream_budget_available[Dir::Uni as usize].notify_waiters(); +1727 shared.stream_budget_available[Dir::Bi as usize].notify_waiters(); +1728 shared.stream_incoming[Dir::Uni as usize].notify_waiters(); +1729 shared.stream_incoming[Dir::Bi as usize].notify_waiters(); +1730 shared.datagram_received.notify_waiters(); +1731 shared.datagrams_unblocked.notify_waiters(); +1732 if let Some(x) = self.on_connected.take() { +1733 let _ = x.send(false); +1734 } +1735 shared.handshake_confirmed.notify_waiters(); +1736 wake_all_notify(&mut self.stopped); +1737 shared.closed.notify_waiters(); +1738 +1739 // Send to the registered on_closed futures. +1740 let stats = self.inner.stats(); +1741 for tx in self.on_closed.drain(..) { +1742 tx.send((reason.clone(), stats.clone())).ok(); +1743 } +1744 } +1745 +1746 fn close(&mut self, error_code: VarInt, reason: Bytes, shared: &Shared) { +1747 self.inner.close(self.runtime.now(), error_code, reason); +1748 self.terminate(ConnectionError::LocallyClosed, shared); +1749 self.wake(); +1750 } +1751 +1752 /// Close for a reason other than the application's explicit request +1753 pub(crate) fn implicit_close(&mut self, shared: &Shared) { +1754 self.close(0u32.into(), Bytes::new(), shared); +1755 } +1756 +1757 pub(crate) fn check_0rtt(&self) -> Result<(), ()> { +1758 if self.inner.is_handshaking() +1759 || self.inner.accepted_0rtt() +1760 || self.inner.side().is_server() +1761 { +1762 Ok(()) +1763 } else { +1764 Err(()) +1765 } +1766 } +1767 +1768 /// Returns [`PathStats`] for a path, if available. +1769 /// +1770 /// This gets the stats from [`proto::Connection`]. If that returns `None` +1771 /// it gets them from `Self::final_path_stats` instead. +1772 pub(crate) fn path_stats(&mut self, path_id: PathId) -> Option<PathStats> { +1773 self.inner +1774 .path_stats(path_id) +1775 .or_else(|| self.final_path_stats.get(&path_id).copied()) +1776 } +1777 +1778 /// Increment the reference counter for a path in this connection. +1779 /// +1780 /// This counts how many [`Path`] or [`WeakPathHandle`] structs exist for a path. +1781 /// Currently this is used to determine whether to store the final stats after a path is +1782 /// abandoned. +1783 /// +1784 /// [`WeakPathHandle`]: crate::path::WeakPathHandle +1785 pub(crate) fn increment_path_refs(&mut self, path_id: PathId) { +1786 *self.path_refs.entry(path_id).or_default() += 1; +1787 } +1788 +1789 /// Decrement the reference counter for a path in this connection. +1790 pub(crate) fn decrement_path_refs(&mut self, path_id: PathId) { +1791 if let Some(refs) = self.path_refs.get_mut(&path_id) { +1792 *refs = refs.saturating_sub(1); +1793 if *refs == 0 { +1794 self.path_refs.remove(&path_id); +1795 self.final_path_stats.remove(&path_id); +1796 } +1797 } +1798 } +1799} +1800 +1801impl Drop for State { +1802 fn drop(&mut self) { +1803 if !self.inner.is_drained() { +1804 // Ensure the endpoint can tidy up +1805 let _ = self +1806 .endpoint_events +1807 .send((self.handle, proto::EndpointEvent::drained())); +1808 } +1809 +1810 if !self.on_closed.is_empty() { +1811 // Ensure that all on_closed oneshot senders are triggered before dropping. +1812 let reason = self.error.as_ref().expect("closed without error reason"); +1813 let stats = self.inner.stats(); +1814 for tx in self.on_closed.drain(..) { +1815 tx.send((reason.clone(), stats.clone())).ok(); +1816 } +1817 } +1818 } +1819} +1820 +1821impl fmt::Debug for State { +1822 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +1823 f.debug_struct("State").field("inner", &self.inner).finish() +1824 } +1825} +1826 +1827fn wake_stream(stream_id: StreamId, wakers: &mut FxHashMap<StreamId, Waker>) { +1828 if let Some(waker) = wakers.remove(&stream_id) { +1829 waker.wake(); +1830 } +1831} +1832 +1833fn wake_all(wakers: &mut FxHashMap<StreamId, Waker>) { +1834 wakers.drain().for_each(|(_, waker)| waker.wake()) +1835} +1836 +1837fn wake_stream_notify(stream_id: StreamId, wakers: &mut FxHashMap<StreamId, Arc<Notify>>) { +1838 if let Some(notify) = wakers.remove(&stream_id) { +1839 notify.notify_waiters() +1840 } +1841} +1842 +1843fn wake_all_notify(wakers: &mut FxHashMap<StreamId, Arc<Notify>>) { +1844 wakers +1845 .drain() +1846 .for_each(|(_, notify)| notify.notify_waiters()) +1847} +1848 +1849/// Errors that can arise when sending a datagram +1850#[derive(Debug, Error, Clone, Eq, PartialEq)] +1851pub enum SendDatagramError { +1852 /// The peer does not support receiving datagram frames +1853 #[error("datagrams not supported by peer")] +1854 UnsupportedByPeer, +1855 /// Datagram support is disabled locally +1856 #[error("datagram support disabled")] +1857 Disabled, +1858 /// The datagram is larger than the connection can currently accommodate +1859 /// +1860 /// Indicates that the path MTU minus overhead or the limit advertised by the peer has been +1861 /// exceeded. +1862 #[error("datagram too large")] +1863 TooLarge, +1864 /// The connection was lost +1865 #[error("connection lost")] +1866 ConnectionLost(#[from] ConnectionError), +1867} +1868 +1869/// The maximum amount of datagrams which will be produced in a single `drive_transmit` call +1870/// +1871/// This limits the amount of CPU resources consumed by datagram generation, +1872/// and allows other tasks (like receiving ACKs) to run in between. +1873const MAX_TRANSMIT_DATAGRAMS: usize = 20; +1874 +1875/// The maximum amount of datagrams that are sent in a single transmit +1876/// +1877/// This can be lower than the maximum platform capabilities, to avoid excessive +1878/// memory allocations when calling `poll_transmit()`. Benchmarks have shown +1879/// that numbers around 10 are a good compromise. +1880const MAX_TRANSMIT_SEGMENTS: NonZeroUsize = NonZeroUsize::new(10).expect("known");

\ No newline at end of file diff --git a/pr/545/docs/src/noq/event_stream.rs.html b/pr/545/docs/src/noq/event_stream.rs.html new file mode 100644 index 000000000..3ad2b9203 --- /dev/null +++ b/pr/545/docs/src/noq/event_stream.rs.html @@ -0,0 +1,114 @@ +event_stream.rs - source

noq/
event_stream.rs

1//! Newtype wrappers around broadcast receivers for connection events.
+2
+3use std::fmt;
+4use std::net::SocketAddr;
+5use std::pin::Pin;
+6use std::task::{Context, Poll};
+7
+8use proto::PathEvent;
+9use proto::n0_nat_traversal;
+10use thiserror::Error;
+11use tokio::sync::{broadcast, watch};
+12use tokio_stream::wrappers::{BroadcastStream, WatchStream, errors::BroadcastStreamRecvError};
+13use tokio_stream::Stream;
+14
+15/// The receiver lagged too far behind.
+16///
+17/// Attempting to receive again will return the oldest message still retained
+18/// by the channel.
+19#[derive(Debug, Clone, PartialEq, Eq, Error)]
+20#[error("channel lagged by {0}")]
+21pub struct Lagged(pub u64);
+22
+23/// A stream of [`PathEvent`]s for all paths in a connection.
+24#[derive(Debug)]
+25pub struct PathEvents {
+26    inner: BroadcastStream<PathEvent>,
+27}
+28
+29impl PathEvents {
+30    pub(crate) fn new(rx: broadcast::Receiver<PathEvent>) -> Self {
+31        Self {
+32            inner: BroadcastStream::new(rx),
+33        }
+34    }
+35}
+36
+37impl Stream for PathEvents {
+38    type Item = Result<PathEvent, Lagged>;
+39
+40    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+41        Pin::new(&mut self.inner)
+42            .poll_next(cx)
+43            .map(|opt| opt.map(|res| res.map_err(|BroadcastStreamRecvError::Lagged(n)| Lagged(n))))
+44    }
+45}
+46
+47/// A stream of NAT traversal updates for a connection.
+48#[derive(Debug)]
+49pub struct NatTraversalUpdates {
+50    inner: BroadcastStream<n0_nat_traversal::Event>,
+51}
+52
+53impl NatTraversalUpdates {
+54    pub(crate) fn new(rx: broadcast::Receiver<n0_nat_traversal::Event>) -> Self {
+55        Self {
+56            inner: BroadcastStream::new(rx),
+57        }
+58    }
+59}
+60
+61impl Stream for NatTraversalUpdates {
+62    type Item = Result<n0_nat_traversal::Event, Lagged>;
+63
+64    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+65        Pin::new(&mut self.inner)
+66            .poll_next(cx)
+67            .map(|opt| opt.map(|res| res.map_err(|BroadcastStreamRecvError::Lagged(n)| Lagged(n))))
+68    }
+69}
+70
+71/// Watches the external address reported by the peer for this connection.
+72///
+73/// Implements [`Stream`] yielding `SocketAddr` on each change.
+74/// Use [`get`](Self::get) to read the current value without waiting.
+75pub struct ObservedExternalAddr {
+76    rx: watch::Receiver<Option<SocketAddr>>,
+77    stream: WatchStream<Option<SocketAddr>>,
+78}
+79
+80impl ObservedExternalAddr {
+81    pub(crate) fn new(rx: watch::Receiver<Option<SocketAddr>>) -> Self {
+82        let stream = WatchStream::new(rx.clone());
+83        Self { rx, stream }
+84    }
+85
+86    /// Returns the most recently observed external address.
+87    ///
+88    /// `None` is returned if the peer has not yet reported an address. Retains
+89    /// the last value even after the stream is closed.
+90    pub fn get(&self) -> Option<SocketAddr> {
+91        *self.rx.borrow()
+92    }
+93}
+94
+95impl Stream for ObservedExternalAddr {
+96    type Item = SocketAddr;
+97
+98    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+99        loop {
+100            match Pin::new(&mut self.stream).poll_next(cx) {
+101                Poll::Ready(Some(Some(addr))) => return Poll::Ready(Some(addr)),
+102                Poll::Ready(Some(None)) => continue,
+103                Poll::Ready(None) => return Poll::Ready(None),
+104                Poll::Pending => return Poll::Pending,
+105            }
+106        }
+107    }
+108}
+109
+110impl fmt::Debug for ObservedExternalAddr {
+111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+112        f.debug_struct("ObservedExternalAddr").finish()
+113    }
+114}
\ No newline at end of file diff --git a/pr/545/docs/src/noq/lib.rs.html b/pr/545/docs/src/noq/lib.rs.html index 226cbf91a..7e9aeb412 100644 --- a/pr/545/docs/src/noq/lib.rs.html +++ b/pr/545/docs/src/noq/lib.rs.html @@ -44,97 +44,99 @@ 44 45mod connection; 46mod endpoint; -47mod incoming; -48mod mutex; -49mod path; -50mod recv_stream; -51mod runtime; -52mod send_stream; -53mod work_limiter; -54 -55#[cfg(not(wasm_browser))] -56pub(crate) use std::time::{Duration, Instant}; -57#[cfg(wasm_browser)] -58pub(crate) use web_time::{Duration, Instant}; -59 -60#[cfg(feature = "bloom")] -61pub use proto::BloomTokenLog; -62pub use proto::{ -63 AckFrequencyConfig, ApplicationClose, Chunk, ClientConfig, ClosedStream, ConfigError, -64 ConnectError, ConnectionClose, ConnectionError, ConnectionId, ConnectionIdGenerator, -65 ConnectionStats, Dir, EcnCodepoint, EndpointConfig, FrameStats, FrameType, IdleTimeout, -66 InvalidCid, MtuDiscoveryConfig, NetworkChangeHint, NoneTokenLog, NoneTokenStore, PathId, -67 PathStats, ServerConfig, Side, StdSystemTime, StreamId, TimeSource, TokenLog, TokenMemoryCache, -68 TokenReuseError, TokenStore, Transmit, TransportConfig, TransportErrorCode, UdpStats, -69 ValidationTokenConfig, VarInt, VarIntBoundsExceeded, Written, congestion, crypto, -70}; -71#[cfg(feature = "qlog")] -72pub use proto::{QlogConfig, QlogFactory, QlogFileFactory}; -73#[cfg(feature = "rustls")] -74pub use rustls; -75pub use udp; -76 -77pub use crate::connection::{ -78 AcceptBi, AcceptUni, Connecting, Connection, OnClosed, OpenBi, OpenUni, ReadDatagram, -79 SendDatagram, SendDatagramError, WeakConnectionHandle, ZeroRttAccepted, -80}; -81pub use crate::endpoint::{Accept, Endpoint, EndpointStats}; -82pub use crate::incoming::{Incoming, IncomingFuture, RetryError}; -83pub use crate::path::{AddressDiscovery, OpenPath, Path, WeakPathHandle}; -84pub use crate::recv_stream::{ -85 ReadError, ReadExactError, ReadToEndError, RecvStream, ResetError, UnorderedRecvStream, -86}; -87#[cfg(feature = "runtime-smol")] -88pub use crate::runtime::SmolRuntime; -89#[cfg(feature = "runtime-tokio")] -90pub use crate::runtime::TokioRuntime; -91#[cfg(any(feature = "runtime-tokio", feature = "runtime-smol"))] -92pub use crate::runtime::default_runtime; -93pub use crate::runtime::{AsyncTimer, AsyncUdpSocket, Runtime, UdpSender}; -94pub use crate::send_stream::{SendStream, Stopped, StoppedError, WriteError}; -95 -96#[cfg(test)] -97mod tests; -98 -99#[derive(Debug)] -100enum ConnectionEvent { -101 Close { -102 error_code: VarInt, -103 reason: bytes::Bytes, -104 }, -105 Proto(proto::ConnectionEvent), -106 Rebind(Pin<Box<dyn UdpSender>>), -107 LocalAddressChanged(Option<Arc<dyn NetworkChangeHint + Sync + Send>>), -108} -109 -110fn udp_transmit<'a>(t: &proto::Transmit, buffer: &'a [u8]) -> udp::Transmit<'a> { -111 udp::Transmit { -112 destination: t.destination, -113 ecn: t.ecn.map(udp_ecn), -114 contents: buffer, -115 segment_size: t.segment_size, -116 src_ip: t.src_ip, -117 } -118} -119 -120fn udp_ecn(ecn: proto::EcnCodepoint) -> udp::EcnCodepoint { -121 match ecn { -122 proto::EcnCodepoint::Ect0 => udp::EcnCodepoint::Ect0, -123 proto::EcnCodepoint::Ect1 => udp::EcnCodepoint::Ect1, -124 proto::EcnCodepoint::Ce => udp::EcnCodepoint::Ce, -125 } -126} -127 -128/// Maximum number of datagrams processed in send/recv calls to make before moving on to other processing -129/// -130/// This helps ensure we don't starve anything when the CPU is slower than the link. -131/// Value is selected by picking a low number which didn't degrade throughput in benchmarks. -132const IO_LOOP_BOUND: usize = 160; -133 -134/// The maximum amount of time that should be spent in `recvmsg()` calls per endpoint iteration -135/// -136/// 50us are chosen so that an endpoint iteration with a 50us sendmsg limit blocks -137/// the runtime for a maximum of about 100us. -138/// Going much lower does not yield any noticeable difference, since a single `recvmmsg` -139/// batch of size 32 was observed to take 30us on some systems. -140const RECV_TIME_BOUND: Duration = Duration::from_micros(50);
\ No newline at end of file +47mod event_stream; +48mod incoming; +49mod mutex; +50mod path; +51mod recv_stream; +52mod runtime; +53mod send_stream; +54mod work_limiter; +55 +56#[cfg(not(wasm_browser))] +57pub(crate) use std::time::{Duration, Instant}; +58#[cfg(wasm_browser)] +59pub(crate) use web_time::{Duration, Instant}; +60 +61#[cfg(feature = "bloom")] +62pub use proto::BloomTokenLog; +63pub use proto::{ +64 AckFrequencyConfig, ApplicationClose, Chunk, ClientConfig, ClosedStream, ConfigError, +65 ConnectError, ConnectionClose, ConnectionError, ConnectionId, ConnectionIdGenerator, +66 ConnectionStats, Dir, EcnCodepoint, EndpointConfig, FrameStats, FrameType, IdleTimeout, +67 InvalidCid, MtuDiscoveryConfig, NetworkChangeHint, NoneTokenLog, NoneTokenStore, PathId, +68 PathStats, ServerConfig, Side, StdSystemTime, StreamId, TimeSource, TokenLog, TokenMemoryCache, +69 TokenReuseError, TokenStore, Transmit, TransportConfig, TransportErrorCode, UdpStats, +70 ValidationTokenConfig, VarInt, VarIntBoundsExceeded, Written, congestion, crypto, +71}; +72#[cfg(feature = "qlog")] +73pub use proto::{QlogConfig, QlogFactory, QlogFileFactory}; +74#[cfg(feature = "rustls")] +75pub use rustls; +76pub use udp; +77 +78pub use crate::connection::{ +79 AcceptBi, AcceptUni, Connecting, Connection, OnClosed, OpenBi, OpenUni, ReadDatagram, +80 SendDatagram, SendDatagramError, WeakConnectionHandle, ZeroRttAccepted, +81}; +82pub use crate::event_stream::{ObservedExternalAddr, Lagged, NatTraversalUpdates, PathEvents}; +83pub use crate::endpoint::{Accept, Endpoint, EndpointStats}; +84pub use crate::incoming::{Incoming, IncomingFuture, RetryError}; +85pub use crate::path::{AddressDiscovery, OpenPath, Path, WeakPathHandle}; +86pub use crate::recv_stream::{ +87 ReadError, ReadExactError, ReadToEndError, RecvStream, ResetError, UnorderedRecvStream, +88}; +89#[cfg(feature = "runtime-smol")] +90pub use crate::runtime::SmolRuntime; +91#[cfg(feature = "runtime-tokio")] +92pub use crate::runtime::TokioRuntime; +93#[cfg(any(feature = "runtime-tokio", feature = "runtime-smol"))] +94pub use crate::runtime::default_runtime; +95pub use crate::runtime::{AsyncTimer, AsyncUdpSocket, Runtime, UdpSender}; +96pub use crate::send_stream::{SendStream, Stopped, StoppedError, WriteError}; +97 +98#[cfg(test)] +99mod tests; +100 +101#[derive(Debug)] +102enum ConnectionEvent { +103 Close { +104 error_code: VarInt, +105 reason: bytes::Bytes, +106 }, +107 Proto(proto::ConnectionEvent), +108 Rebind(Pin<Box<dyn UdpSender>>), +109 LocalAddressChanged(Option<Arc<dyn NetworkChangeHint + Sync + Send>>), +110} +111 +112fn udp_transmit<'a>(t: &proto::Transmit, buffer: &'a [u8]) -> udp::Transmit<'a> { +113 udp::Transmit { +114 destination: t.destination, +115 ecn: t.ecn.map(udp_ecn), +116 contents: buffer, +117 segment_size: t.segment_size, +118 src_ip: t.src_ip, +119 } +120} +121 +122fn udp_ecn(ecn: proto::EcnCodepoint) -> udp::EcnCodepoint { +123 match ecn { +124 proto::EcnCodepoint::Ect0 => udp::EcnCodepoint::Ect0, +125 proto::EcnCodepoint::Ect1 => udp::EcnCodepoint::Ect1, +126 proto::EcnCodepoint::Ce => udp::EcnCodepoint::Ce, +127 } +128} +129 +130/// Maximum number of datagrams processed in send/recv calls to make before moving on to other processing +131/// +132/// This helps ensure we don't starve anything when the CPU is slower than the link. +133/// Value is selected by picking a low number which didn't degrade throughput in benchmarks. +134const IO_LOOP_BOUND: usize = 160; +135 +136/// The maximum amount of time that should be spent in `recvmsg()` calls per endpoint iteration +137/// +138/// 50us are chosen so that an endpoint iteration with a 50us sendmsg limit blocks +139/// the runtime for a maximum of about 100us. +140/// Going much lower does not yield any noticeable difference, since a single `recvmmsg` +141/// batch of size 32 was observed to take 30us on some systems. +142const RECV_TIME_BOUND: Duration = Duration::from_micros(50); \ No newline at end of file diff --git a/pr/545/docs/src/noq/mutex.rs.html b/pr/545/docs/src/noq/mutex.rs.html index f04b9bef5..f184b770b 100644 --- a/pr/545/docs/src/noq/mutex.rs.html +++ b/pr/545/docs/src/noq/mutex.rs.html @@ -110,7 +110,7 @@ 110} 111 112#[cfg(feature = "lock_tracking")] -113pub(crate) use tracking::Mutex; +113pub(crate) use tracking::{Mutex, MutexGuard}; 114 115#[cfg(not(feature = "lock_tracking"))] 116mod non_tracking { @@ -160,4 +160,4 @@ 160} 161 162#[cfg(not(feature = "lock_tracking"))] -163pub(crate) use non_tracking::Mutex; \ No newline at end of file +163pub(crate) use non_tracking::{Mutex, MutexGuard}; \ No newline at end of file diff --git a/pr/545/docs/src/noq/path.rs.html b/pr/545/docs/src/noq/path.rs.html index 9dc85943d..51350e088 100644 --- a/pr/545/docs/src/noq/path.rs.html +++ b/pr/545/docs/src/noq/path.rs.html @@ -118,304 +118,297 @@ 118impl Clone for Path { 119 fn clone(&self) -> Self { 120 self.conn -121 .state -122 .lock("Path::clone") -123 .increment_path_refs(self.id); -124 Self { -125 id: self.id, -126 conn: self.conn.clone(), -127 } -128 } -129} -130 -131impl Drop for Path { -132 fn drop(&mut self) { -133 let mut state = self.conn.state.lock("Path::drop"); -134 state.decrement_path_refs(self.id); -135 } -136} -137 -138impl Path { -139 /// Returns a [`Path`] for a path id, after checking that the path is not closed. -140 pub(crate) fn new(conn: &ConnectionRef, id: PathId) -> Option<Self> { -141 { -142 let mut state = conn.state.lock("Path::new"); -143 // TODO(flub): Using this to know if the path still exists is... hacky. -144 state.inner.path_status(id).ok()?; -145 state.increment_path_refs(id); -146 } -147 Some(Self { -148 id, -149 conn: conn.clone(), -150 }) -151 } -152 -153 /// Returns a [`Path`] for a path id without checking if the path exists or is closed. -154 fn new_unchecked(conn: ConnectionRef, id: PathId) -> Self { -155 conn.state -156 .lock("Path::new_unchecked") -157 .increment_path_refs(id); -158 Self { id, conn } -159 } -160 -161 /// Returns a [`WeakPathHandle`] for this path. -162 /// -163 /// Holding a [`WeakPathHandle`] does not keep a connection alive, but ensures that the -164 /// path's stats are not dropped until the underlying connection is dropped, even if the -165 /// path is abandoned. -166 pub fn weak_handle(&self) -> WeakPathHandle { -167 self.conn -168 .state -169 .lock("Path::weak_handle") -170 .increment_path_refs(self.id); -171 WeakPathHandle { -172 id: self.id, -173 conn: self.conn.weak_handle(), -174 } -175 } -176 -177 /// The [`PathId`] of this path. -178 pub fn id(&self) -> PathId { -179 self.id -180 } -181 -182 /// The current local [`PathStatus`] of this path. -183 pub fn status(&self) -> Result<PathStatus, ClosedPath> { -184 self.conn -185 .state -186 .lock("path status") -187 .inner -188 .path_status(self.id) -189 } -190 -191 /// Sets the [`PathStatus`] of this path. -192 pub fn set_status(&self, status: PathStatus) -> Result<(), SetPathStatusError> { -193 self.conn -194 .state -195 .lock("set path status") -196 .inner -197 .set_path_status(self.id, status)?; -198 Ok(()) -199 } -200 -201 /// Returns the [`PathStats`] for this path. -202 pub fn stats(&self) -> PathStats { -203 // The `expect` is safe: -204 // - `Path` can only be created for non-closed paths. -205 // - `Path` and its clones or `WeakPathHandle`s all increment the connection state's `path_ref` -206 // reference counter -207 // - As long as a path is not abandoned, its stats are available from `proto::Connection` -208 // - If a path is abandoned, the `crate::Connection` stores the final stats as long as -209 // the path's refcount is not 0 -210 // - Therefore, we always get stats here. -211 self.conn -212 .state -213 .lock("Path::stats") -214 .path_stats(self.id) -215 .expect("either path stats or discarded path stats are always set as long as Path is not dropped") -216 } -217 -218 /// Closes this path. -219 /// -220 /// The path is immediately considered closed by the local endpoint. Once the state is removed, -221 /// after a short period of time for any in-flight packets, a [`PathEvent::Abandoned`] is -222 /// returned. -223 pub fn close(&self) -> Result<(), ClosePathError> { -224 let mut state = self.conn.state.lock("close_path"); -225 state.inner.close_path( -226 crate::Instant::now(), -227 self.id, -228 TransportErrorCode::APPLICATION_ABANDON_PATH.into(), -229 ) -230 } -231 -232 /// Sets the max idle timeout for a specific path -233 /// -234 /// See [`TransportConfig::default_path_max_idle_timeout`] for details. -235 /// -236 /// Returns the previous value of the setting. -237 /// -238 /// [`TransportConfig::default_path_max_idle_timeout`]: crate::TransportConfig::default_path_max_idle_timeout -239 pub fn set_max_idle_timeout( -240 &self, -241 timeout: Option<Duration>, -242 ) -> Result<Option<Duration>, ClosedPath> { -243 let mut state = self.conn.state.lock("path_set_max_idle_timeout"); -244 state.inner.set_path_max_idle_timeout(self.id, timeout) -245 } -246 -247 /// Sets the keep_alive_interval for a specific path -248 /// -249 /// See [`TransportConfig::default_path_keep_alive_interval`] for details. -250 /// -251 /// Returns the previous value of the setting. -252 /// -253 /// [`TransportConfig::default_path_keep_alive_interval`]: crate::TransportConfig::default_path_keep_alive_interval -254 pub fn set_keep_alive_interval( -255 &self, -256 interval: Option<Duration>, -257 ) -> Result<Option<Duration>, ClosedPath> { -258 let mut state = self.conn.state.lock("path_set_keep_alive_interval"); -259 state.inner.set_path_keep_alive_interval(self.id, interval) -260 } -261 -262 /// Track changes on our external address as reported by the peer. -263 /// -264 /// If the address-discovery extension is not negotiated, the stream will never return. -265 pub fn observed_external_addr(&self) -> Result<AddressDiscovery, ClosedPath> { -266 let state = self.conn.state.lock("per_path_observed_address"); -267 let path_events = state.path_events.subscribe(); -268 let initial_value = state.inner.path_observed_address(self.id)?; -269 Ok(AddressDiscovery::new( -270 self.id, -271 path_events, -272 initial_value, -273 state.runtime.clone(), -274 )) -275 } -276 -277 /// The peer's UDP address for this path. -278 pub fn remote_address(&self) -> Result<SocketAddr, ClosedPath> { -279 let state = self.conn.state.lock("per_path_remote_address"); -280 Ok(state.inner.network_path(self.id)?.remote()) -281 } -282 -283 /// Ping the remote endpoint over this path. -284 pub fn ping(&self) -> Result<(), ClosedPath> { -285 let mut state = self.conn.state.lock("ping"); -286 state.inner.ping_path(self.id) -287 } -288} -289 -290impl PartialEq for Path { -291 fn eq(&self, other: &Self) -> bool { -292 self.id == other.id && self.conn.stable_id() == other.conn.stable_id() -293 } -294} -295 -296/// Weak handle for a [`Path`] that does not keep the connection alive. +121 .lock_without_waking("Path::clone") +122 .increment_path_refs(self.id); +123 Self { +124 id: self.id, +125 conn: self.conn.clone(), +126 } +127 } +128} +129 +130impl Drop for Path { +131 fn drop(&mut self) { +132 let mut state = self.conn.lock_without_waking("Path::drop"); +133 state.decrement_path_refs(self.id); +134 } +135} +136 +137impl Path { +138 /// Returns a [`Path`] for a path id, after checking that the path is not closed. +139 pub(crate) fn new(conn: &ConnectionRef, id: PathId) -> Option<Self> { +140 { +141 let mut state = conn.lock_without_waking("Path::new"); +142 // TODO(flub): Using this to know if the path still exists is... hacky. +143 state.inner.path_status(id).ok()?; +144 state.increment_path_refs(id); +145 } +146 Some(Self { +147 id, +148 conn: conn.clone(), +149 }) +150 } +151 +152 /// Returns a [`Path`] for a path id without checking if the path exists or is closed. +153 fn new_unchecked(conn: ConnectionRef, id: PathId) -> Self { +154 conn.lock_without_waking("Path::new_unchecked") +155 .increment_path_refs(id); +156 Self { id, conn } +157 } +158 +159 /// Returns a [`WeakPathHandle`] for this path. +160 /// +161 /// Holding a [`WeakPathHandle`] does not keep a connection alive, but ensures that the +162 /// path's stats are not dropped until the underlying connection is dropped, even if the +163 /// path is abandoned. +164 pub fn weak_handle(&self) -> WeakPathHandle { +165 self.conn +166 .lock_without_waking("Path::weak_handle") +167 .increment_path_refs(self.id); +168 WeakPathHandle { +169 id: self.id, +170 conn: self.conn.weak_handle(), +171 } +172 } +173 +174 /// The [`PathId`] of this path. +175 pub fn id(&self) -> PathId { +176 self.id +177 } +178 +179 /// The current local [`PathStatus`] of this path. +180 pub fn status(&self) -> Result<PathStatus, ClosedPath> { +181 self.conn +182 .lock_without_waking("path status") +183 .inner +184 .path_status(self.id) +185 } +186 +187 /// Sets the [`PathStatus`] of this path. +188 pub fn set_status(&self, status: PathStatus) -> Result<(), SetPathStatusError> { +189 self.conn +190 .lock_and_wake("set path status") +191 .inner +192 .set_path_status(self.id, status)?; +193 Ok(()) +194 } +195 +196 /// Returns the [`PathStats`] for this path. +197 pub fn stats(&self) -> PathStats { +198 // The `expect` is safe: +199 // - `Path` can only be created for non-closed paths. +200 // - `Path` and its clones or `WeakPathHandle`s all increment the connection state's `path_ref` +201 // reference counter +202 // - As long as a path is not abandoned, its stats are available from `proto::Connection` +203 // - If a path is abandoned, the `crate::Connection` stores the final stats as long as +204 // the path's refcount is not 0 +205 // - Therefore, we always get stats here. +206 self.conn +207 .lock_without_waking("Path::stats") +208 .path_stats(self.id) +209 .expect("either path stats or discarded path stats are always set as long as Path is not dropped") +210 } +211 +212 /// Closes this path. +213 /// +214 /// The path is immediately considered closed by the local endpoint. Once the state is removed, +215 /// after a short period of time for any in-flight packets, a [`PathEvent::Abandoned`] is +216 /// returned. +217 pub fn close(&self) -> Result<(), ClosePathError> { +218 let mut state = self.conn.lock_and_wake("close_path"); +219 state.inner.close_path( +220 crate::Instant::now(), +221 self.id, +222 TransportErrorCode::APPLICATION_ABANDON_PATH.into(), +223 ) +224 } +225 +226 /// Sets the max idle timeout for a specific path +227 /// +228 /// See [`TransportConfig::default_path_max_idle_timeout`] for details. +229 /// +230 /// Returns the previous value of the setting. +231 /// +232 /// [`TransportConfig::default_path_max_idle_timeout`]: crate::TransportConfig::default_path_max_idle_timeout +233 pub fn set_max_idle_timeout( +234 &self, +235 timeout: Option<Duration>, +236 ) -> Result<Option<Duration>, ClosedPath> { +237 let mut state = self.conn.lock_and_wake("path_set_max_idle_timeout"); +238 let now = state.runtime.now(); +239 state.inner.set_path_max_idle_timeout(now, self.id, timeout) +240 } +241 +242 /// Sets the keep_alive_interval for a specific path +243 /// +244 /// See [`TransportConfig::default_path_keep_alive_interval`] for details. +245 /// +246 /// Returns the previous value of the setting. +247 /// +248 /// [`TransportConfig::default_path_keep_alive_interval`]: crate::TransportConfig::default_path_keep_alive_interval +249 pub fn set_keep_alive_interval( +250 &self, +251 interval: Option<Duration>, +252 ) -> Result<Option<Duration>, ClosedPath> { +253 let mut state = self.conn.lock_and_wake("path_set_keep_alive_interval"); +254 state.inner.set_path_keep_alive_interval(self.id, interval) +255 } +256 +257 /// Track changes on our external address as reported by the peer. +258 /// +259 /// If the address-discovery extension is not negotiated, the stream will never return. +260 pub fn observed_external_addr(&self) -> Result<AddressDiscovery, ClosedPath> { +261 let state = self.conn.lock_without_waking("per_path_observed_address"); +262 let path_events = state.path_events.subscribe(); +263 let initial_value = state.inner.path_observed_address(self.id)?; +264 Ok(AddressDiscovery::new( +265 self.id, +266 path_events, +267 initial_value, +268 state.runtime.clone(), +269 )) +270 } +271 +272 /// The peer's UDP address for this path. +273 pub fn remote_address(&self) -> Result<SocketAddr, ClosedPath> { +274 let state = self.conn.lock_without_waking("per_path_remote_address"); +275 Ok(state.inner.network_path(self.id)?.remote()) +276 } +277 +278 /// Ping the remote endpoint over this path. +279 pub fn ping(&self) -> Result<(), ClosedPath> { +280 let mut state = self.conn.lock_and_wake("ping"); +281 state.inner.ping_path(self.id) +282 } +283} +284 +285impl PartialEq for Path { +286 fn eq(&self, other: &Self) -> bool { +287 self.id == other.id && self.conn.stable_id() == other.conn.stable_id() +288 } +289} +290 +291/// Weak handle for a [`Path`] that does not keep the connection alive. +292/// +293/// As long as a [`WeakPathHandle`] for a path exists, that path's final stats will not be dropped even if +294/// the path was abandoned. +295/// +296/// The [`WeakPathHandle`] can be upgraded to a [`Path`] as long as its [`Connection`] has not been dropped. 297/// -298/// As long as a [`WeakPathHandle`] for a path exists, that path's final stats will not be dropped even if -299/// the path was abandoned. -300/// -301/// The [`WeakPathHandle`] can be upgraded to a [`Path`] as long as its [`Connection`] has not been dropped. -302/// -303/// [`Connection`]: crate::Connection -304#[derive(Debug)] -305pub struct WeakPathHandle { -306 id: PathId, -307 conn: WeakConnectionHandle, -308} -309 -310impl Clone for WeakPathHandle { -311 fn clone(&self) -> Self { -312 if let Some(conn) = self.conn.upgrade_to_ref() { -313 conn.state -314 .lock("WeakPathHandle::clone") -315 .increment_path_refs(self.id); -316 } -317 Self { -318 id: self.id, -319 conn: self.conn.clone(), -320 } +298/// [`Connection`]: crate::Connection +299#[derive(Debug)] +300pub struct WeakPathHandle { +301 id: PathId, +302 conn: WeakConnectionHandle, +303} +304 +305impl Clone for WeakPathHandle { +306 fn clone(&self) -> Self { +307 if let Some(conn) = self.conn.upgrade_to_ref() { +308 conn.lock_without_waking("WeakPathHandle::clone") +309 .increment_path_refs(self.id); +310 } +311 Self { +312 id: self.id, +313 conn: self.conn.clone(), +314 } +315 } +316} +317 +318impl PartialEq for WeakPathHandle { +319 fn eq(&self, other: &Self) -> bool { +320 self.id == other.id && self.conn.is_same_connection(&other.conn) 321 } 322} 323 -324impl PartialEq for WeakPathHandle { -325 fn eq(&self, other: &Self) -> bool { -326 self.id == other.id && self.conn.is_same_connection(&other.conn) -327 } -328} -329 -330impl Eq for WeakPathHandle {} -331 -332impl Drop for WeakPathHandle { -333 fn drop(&mut self) { -334 if let Some(conn) = self.conn.upgrade_to_ref() { -335 conn.state -336 .lock("WeakPathHandle::drop") -337 .decrement_path_refs(self.id); -338 } +324impl Eq for WeakPathHandle {} +325 +326impl Drop for WeakPathHandle { +327 fn drop(&mut self) { +328 if let Some(conn) = self.conn.upgrade_to_ref() { +329 conn.lock_without_waking("WeakPathHandle::drop") +330 .decrement_path_refs(self.id); +331 } +332 } +333} +334 +335impl WeakPathHandle { +336 /// Returns the [`PathId`] of this path. +337 pub fn id(&self) -> PathId { +338 self.id 339 } -340} -341 -342impl WeakPathHandle { -343 /// Returns the [`PathId`] of this path. -344 pub fn id(&self) -> PathId { -345 self.id -346 } -347 -348 /// Upgrades to a [`Path`]. -349 /// -350 /// Returns `None` if the connection was dropped. -351 pub fn upgrade(&self) -> Option<Path> { -352 let conn = self.conn.upgrade_to_ref()?; -353 Some(Path::new_unchecked(conn, self.id)) -354 } -355} -356 -357/// Stream produced by [`Path::observed_external_addr`] -358/// -359/// This will always return the external address most recently reported by the remote over this -360/// path. If the extension is not negotiated, this stream will never return. -361// TODO(@divma): provide a way to check if the extension is negotiated. -362pub struct AddressDiscovery { -363 watcher: WatchStream<SocketAddr>, -364} -365 -366impl AddressDiscovery { -367 pub(super) fn new( -368 path_id: PathId, -369 mut path_events: tokio::sync::broadcast::Receiver<PathEvent>, -370 initial_value: Option<SocketAddr>, -371 runtime: Arc<dyn Runtime>, -372 ) -> Self { -373 let (tx, rx) = watch::channel(initial_value.unwrap_or_else(|| -374 // if the dummy value is used, it will be ignored -375 SocketAddr::new([0, 0, 0, 0].into(), 0))); -376 let filter = async move { -377 loop { -378 match path_events.recv().await { -379 Ok(PathEvent::ObservedAddr { id, addr: observed }) if id == path_id => { -380 tx.send_if_modified(|addr| { -381 let old = std::mem::replace(addr, observed); -382 old != *addr -383 }); -384 } -385 Ok(PathEvent::Discarded { id, .. }) if id == path_id => { -386 // If the path is closed, terminate the stream -387 break; -388 } -389 Ok(_) => { -390 // ignore any other event -391 } -392 Err(_) => { -393 // A lagged error should never happen since this (detached) task is -394 // constantly reading from the channel. Therefore, if an error does happen, -395 // the stream can terminate -396 break; -397 } -398 } -399 } -400 }; -401 -402 let watcher = if initial_value.is_some() { -403 WatchStream::new(rx) -404 } else { -405 WatchStream::from_changes(rx) -406 }; +340 +341 /// Upgrades to a [`Path`]. +342 /// +343 /// Returns `None` if the connection was dropped. +344 pub fn upgrade(&self) -> Option<Path> { +345 let conn = self.conn.upgrade_to_ref()?; +346 Some(Path::new_unchecked(conn, self.id)) +347 } +348} +349 +350/// Stream produced by [`Path::observed_external_addr`] +351/// +352/// This will always return the external address most recently reported by the remote over this +353/// path. If the extension is not negotiated, this stream will never return. +354// TODO(@divma): provide a way to check if the extension is negotiated. +355pub struct AddressDiscovery { +356 watcher: WatchStream<SocketAddr>, +357} +358 +359impl AddressDiscovery { +360 pub(super) fn new( +361 path_id: PathId, +362 mut path_events: tokio::sync::broadcast::Receiver<PathEvent>, +363 initial_value: Option<SocketAddr>, +364 runtime: Arc<dyn Runtime>, +365 ) -> Self { +366 let (tx, rx) = watch::channel(initial_value.unwrap_or_else(|| +367 // if the dummy value is used, it will be ignored +368 SocketAddr::new([0, 0, 0, 0].into(), 0))); +369 let filter = async move { +370 loop { +371 match path_events.recv().await { +372 Ok(PathEvent::ObservedAddr { id, addr: observed }) if id == path_id => { +373 tx.send_if_modified(|addr| { +374 let old = std::mem::replace(addr, observed); +375 old != *addr +376 }); +377 } +378 Ok(PathEvent::Discarded { id, .. }) if id == path_id => { +379 // If the path is closed, terminate the stream +380 break; +381 } +382 Ok(_) => { +383 // ignore any other event +384 } +385 Err(_) => { +386 // A lagged error should never happen since this (detached) task is +387 // constantly reading from the channel. Therefore, if an error does happen, +388 // the stream can terminate +389 break; +390 } +391 } +392 } +393 }; +394 +395 let watcher = if initial_value.is_some() { +396 WatchStream::new(rx) +397 } else { +398 WatchStream::from_changes(rx) +399 }; +400 +401 runtime.spawn(Box::pin(filter)); +402 // TODO(@divma): check if there's a way to ensure the future ends. AbortHandle is not an +403 // option +404 Self { watcher } +405 } +406} 407 -408 runtime.spawn(Box::pin(filter)); -409 // TODO(@divma): check if there's a way to ensure the future ends. AbortHandle is not an -410 // option -411 Self { watcher } -412 } -413} -414 -415impl Stream for AddressDiscovery { -416 type Item = SocketAddr; -417 -418 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { -419 Pin::new(&mut self.watcher).poll_next(cx) -420 } -421} \ No newline at end of file +408impl Stream for AddressDiscovery { +409 type Item = SocketAddr; +410 +411 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { +412 Pin::new(&mut self.watcher).poll_next(cx) +413 } +414} \ No newline at end of file diff --git a/pr/545/docs/src/noq/recv_stream.rs.html b/pr/545/docs/src/noq/recv_stream.rs.html index 2f99b5538..01129b36a 100644 --- a/pr/545/docs/src/noq/recv_stream.rs.html +++ b/pr/545/docs/src/noq/recv_stream.rs.html @@ -268,12 +268,12 @@ 268 /// Discards unread data and notifies the peer to stop transmitting. Once stopped, further 269 /// attempts to operate on a stream will yield `ClosedStream` errors. 270 pub fn stop(&mut self, error_code: VarInt) -> Result<(), ClosedStream> { -271 let mut conn = self.conn.state.lock("RecvStream::stop"); +271 let mut conn = self.conn.lock_and_wake("RecvStream::stop"); 272 if self.is_0rtt && conn.check_0rtt().is_err() { -273 return Ok(()); -274 } -275 conn.inner.recv_stream(self.stream).stop(error_code)?; -276 conn.wake(); +273 conn.skip_waking(); +274 return Ok(()); +275 } +276 conn.inner.recv_stream(self.stream).stop(error_code)?; 277 self.all_data_read = true; 278 Ok(()) 279 } @@ -301,7 +301,7 @@ 301 /// This operation is cancel-safe. 302 pub async fn received_reset(&mut self) -> Result<Option<VarInt>, ResetError> { 303 poll_fn(|cx| { -304 let mut conn = self.conn.state.lock("RecvStream::reset"); +304 let mut conn = self.conn.lock_without_waking("RecvStream::reset"); 305 if self.is_0rtt && conn.check_0rtt().is_err() { 306 return Poll::Ready(Err(ResetError::ZeroRttRejected)); 307 } @@ -354,7 +354,7 @@ 354 return Poll::Ready(Ok(None)); 355 } 356 -357 let mut conn = self.conn.state.lock("RecvStream::poll_read"); +357 let mut conn = self.conn.lock_without_waking("RecvStream::poll_read"); 358 if self.is_0rtt { 359 conn.check_0rtt().map_err(|()| ReadError::ZeroRttRejected)?; 360 } @@ -581,18 +581,18 @@ 581 582impl Drop for RecvStream { 583 fn drop(&mut self) { -584 let mut conn = self.conn.state.lock("RecvStream::drop"); +584 let mut conn = self.conn.lock_and_wake("RecvStream::drop"); 585 586 // clean up any previously registered wakers 587 conn.blocked_readers.remove(&self.stream); 588 589 if conn.error.is_some() || (self.is_0rtt && conn.check_0rtt().is_err()) { -590 return; -591 } -592 if !self.all_data_read { -593 // Ignore ClosedStream errors -594 let _ = conn.inner.recv_stream(self.stream).stop(0u32.into()); -595 conn.wake(); +590 conn.skip_waking(); +591 return; +592 } +593 if !self.all_data_read { +594 // Ignore ClosedStream errors +595 let _ = conn.inner.recv_stream(self.stream).stop(0u32.into()); 596 } 597 } 598} diff --git a/pr/545/docs/src/noq/send_stream.rs.html b/pr/545/docs/src/noq/send_stream.rs.html index e27304db2..3978c2371 100644 --- a/pr/545/docs/src/noq/send_stream.rs.html +++ b/pr/545/docs/src/noq/send_stream.rs.html @@ -145,338 +145,345 @@ 145 F: FnOnce(&mut proto::SendStream<'_>) -> Result<R, proto::WriteError>, 146 { 147 use proto::WriteError::*; -148 let mut conn = self.conn.state.lock("SendStream::poll_write"); -149 if self.is_0rtt { -150 conn.check_0rtt() -151 .map_err(|()| WriteError::ZeroRttRejected)?; +148 let mut conn = self.conn.lock_and_wake("SendStream::poll_write"); +149 if self.is_0rtt && conn.check_0rtt().is_err() { +150 conn.skip_waking(); +151 return Poll::Ready(Err(WriteError::ZeroRttRejected)); 152 } -153 if let Some(ref x) = conn.error { -154 return Poll::Ready(Err(WriteError::ConnectionLost(x.clone()))); -155 } -156 -157 let result = match write_fn(&mut conn.inner.send_stream(self.stream)) { -158 Ok(result) => result, -159 Err(Blocked) => { -160 conn.blocked_writers.insert(self.stream, cx.waker().clone()); -161 return Poll::Pending; -162 } -163 Err(Stopped(error_code)) => { -164 return Poll::Ready(Err(WriteError::Stopped(error_code))); -165 } -166 Err(ClosedStream) => { -167 return Poll::Ready(Err(WriteError::ClosedStream)); +153 if let Some(conn_err) = conn.error.clone() { +154 conn.skip_waking(); +155 return Poll::Ready(Err(WriteError::ConnectionLost(conn_err))); +156 } +157 +158 let result = match write_fn(&mut conn.inner.send_stream(self.stream)) { +159 Ok(result) => result, +160 Err(Blocked) => { +161 conn.blocked_writers.insert(self.stream, cx.waker().clone()); +162 conn.skip_waking(); +163 return Poll::Pending; +164 } +165 Err(Stopped(error_code)) => { +166 conn.skip_waking(); +167 return Poll::Ready(Err(WriteError::Stopped(error_code))); 168 } -169 }; -170 -171 conn.wake(); -172 Poll::Ready(Ok(result)) -173 } +169 Err(ClosedStream) => { +170 conn.skip_waking(); +171 return Poll::Ready(Err(WriteError::ClosedStream)); +172 } +173 }; 174 -175 /// Notify the peer that no more data will ever be written to this stream -176 /// -177 /// It is an error to write to a [`SendStream`] after `finish()`ing it. [`reset()`](Self::reset) -178 /// may still be called after `finish` to abandon transmission of any stream data that might -179 /// still be buffered. -180 /// -181 /// To wait for the peer to receive all buffered stream data, see [`stopped()`](Self::stopped). -182 /// -183 /// May fail if [`finish()`](Self::finish) or [`reset()`](Self::reset) was previously -184 /// called. This error is harmless and serves only to indicate that the caller may have -185 /// incorrect assumptions about the stream's state. -186 pub fn finish(&mut self) -> Result<(), ClosedStream> { -187 let mut conn = self.conn.state.lock("finish"); -188 match conn.inner.send_stream(self.stream).finish() { -189 Ok(()) => { -190 conn.wake(); -191 Ok(()) -192 } -193 Err(FinishError::ClosedStream) => Err(ClosedStream::default()), -194 // Harmless. If the application needs to know about stopped streams at this point, it -195 // should call `stopped`. -196 Err(FinishError::Stopped(_)) => Ok(()), -197 } -198 } -199 -200 /// Close the send stream immediately. -201 /// -202 /// No new data can be written after calling this method. Locally buffered data is dropped, and -203 /// previously transmitted data will no longer be retransmitted if lost. If an attempt has -204 /// already been made to finish the stream, the peer may still receive all written data. +175 Poll::Ready(Ok(result)) +176 } +177 +178 /// Notify the peer that no more data will ever be written to this stream +179 /// +180 /// It is an error to write to a [`SendStream`] after `finish()`ing it. [`reset()`](Self::reset) +181 /// may still be called after `finish` to abandon transmission of any stream data that might +182 /// still be buffered. +183 /// +184 /// To wait for the peer to receive all buffered stream data, see [`stopped()`](Self::stopped). +185 /// +186 /// May fail if [`finish()`](Self::finish) or [`reset()`](Self::reset) was previously +187 /// called. This error is harmless and serves only to indicate that the caller may have +188 /// incorrect assumptions about the stream's state. +189 pub fn finish(&mut self) -> Result<(), ClosedStream> { +190 let mut conn = self.conn.lock_and_wake("finish"); +191 if let Err(e) = conn.inner.send_stream(self.stream).finish() { +192 conn.skip_waking(); +193 match e { +194 FinishError::ClosedStream => Err(ClosedStream::default()), +195 // Harmless. If the application needs to know about stopped streams at this point, it +196 // should call `stopped`. +197 FinishError::Stopped(_) => Ok(()), +198 } +199 } else { +200 Ok(()) +201 } +202 } +203 +204 /// Close the send stream immediately. 205 /// -206 /// May fail if [`finish()`](Self::finish) or [`reset()`](Self::reset) was previously -207 /// called. This error is harmless and serves only to indicate that the caller may have -208 /// incorrect assumptions about the stream's state. -209 pub fn reset(&mut self, error_code: VarInt) -> Result<(), ClosedStream> { -210 let mut conn = self.conn.state.lock("SendStream::reset"); -211 if self.is_0rtt && conn.check_0rtt().is_err() { -212 return Ok(()); -213 } -214 conn.inner.send_stream(self.stream).reset(error_code)?; -215 conn.wake(); -216 Ok(()) -217 } -218 -219 /// Set the priority of the send stream -220 /// -221 /// Every send stream has an initial priority of 0. Locally buffered data from streams with -222 /// higher priority will be transmitted before data from streams with lower priority. Changing -223 /// the priority of a stream with pending data may only take effect after that data has been -224 /// transmitted. Using many different priority levels per connection may have a negative -225 /// impact on performance. -226 pub fn set_priority(&self, priority: i32) -> Result<(), ClosedStream> { -227 let mut conn = self.conn.state.lock("SendStream::set_priority"); -228 conn.inner.send_stream(self.stream).set_priority(priority)?; -229 Ok(()) -230 } -231 -232 /// Get the priority of the send stream -233 pub fn priority(&self) -> Result<i32, ClosedStream> { -234 let mut conn = self.conn.state.lock("SendStream::priority"); -235 conn.inner.send_stream(self.stream).priority() -236 } -237 -238 /// Completes when the peer stops the stream or reads the stream to completion -239 /// -240 /// Yields `Some` with the stop error code if the peer stops the stream. Yields `None` if the -241 /// local side [`finish()`](Self::finish)es the stream and then the peer acknowledges receipt -242 /// of all stream data (although not necessarily the processing of it), after which the peer -243 /// closing the stream is no longer meaningful. -244 /// -245 /// For a variety of reasons, the peer may not send acknowledgements immediately upon receiving -246 /// data. As such, relying on `stopped` to know when the peer has read a stream to completion -247 /// may introduce more latency than using an application-level response of some sort. -248 pub fn stopped(&self) -> Stopped { -249 let notified = { -250 // Create an `OwnedNotified` to move into the future. By creating it before the first poll, -251 // we make sure that we don't miss any notifications. -252 let mut conn = self.conn.state.lock("SendStream::stopped"); -253 conn.stopped -254 .entry(self.stream) -255 .or_default() -256 .clone() -257 .notified_owned() -258 }; -259 Stopped { -260 conn: self.conn.clone(), -261 stream: self.stream, -262 is_0rtt: self.is_0rtt, -263 notified, -264 } -265 } -266 -267 /// Get the identity of this stream -268 pub fn id(&self) -> StreamId { -269 self.stream -270 } -271 -272 /// Attempt to write bytes from buf into the stream. -273 /// -274 /// On success, returns Poll::Ready(Ok(num_bytes_written)). -275 /// -276 /// If the stream is not ready for writing, the method returns Poll::Pending and arranges -277 /// for the current task (via cx.waker().wake_by_ref()) to receive a notification when the -278 /// stream becomes writable or is closed. -279 pub fn poll_write( -280 self: Pin<&mut Self>, -281 cx: &mut Context<'_>, -282 buf: &[u8], -283 ) -> Poll<Result<usize, WriteError>> { -284 pin!(self.get_mut().write(buf)).as_mut().poll(cx) -285 } -286} -287 -288/// Check if a send stream is stopped. -289/// -290/// Returns `Some` if the stream is stopped or the connection is closed. -291/// Returns `None` if the stream is not stopped. -292fn send_stream_stopped( -293 conn: &mut State, -294 stream: StreamId, -295 is_0rtt: bool, -296) -> Option<Result<Option<VarInt>, StoppedError>> { -297 if is_0rtt && conn.check_0rtt().is_err() { -298 return Some(Err(StoppedError::ZeroRttRejected)); -299 } -300 match conn.inner.send_stream(stream).stopped() { -301 Err(ClosedStream { .. }) => Some(Ok(None)), -302 Ok(Some(error_code)) => Some(Ok(Some(error_code))), -303 Ok(None) => conn.error.clone().map(|error| Err(error.into())), -304 } -305} -306 -307#[cfg(feature = "futures-io")] -308impl futures_io::AsyncWrite for SendStream { -309 fn poll_write( -310 self: Pin<&mut Self>, -311 cx: &mut Context<'_>, -312 buf: &[u8], -313 ) -> Poll<io::Result<usize>> { -314 self.poll_write(cx, buf).map_err(Into::into) -315 } -316 -317 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { -318 Poll::Ready(Ok(())) +206 /// No new data can be written after calling this method. Locally buffered data is dropped, and +207 /// previously transmitted data will no longer be retransmitted if lost. If an attempt has +208 /// already been made to finish the stream, the peer may still receive all written data. +209 /// +210 /// May fail if [`finish()`](Self::finish) or [`reset()`](Self::reset) was previously +211 /// called. This error is harmless and serves only to indicate that the caller may have +212 /// incorrect assumptions about the stream's state. +213 pub fn reset(&mut self, error_code: VarInt) -> Result<(), ClosedStream> { +214 let mut conn = self.conn.lock_and_wake("SendStream::reset"); +215 if self.is_0rtt && conn.check_0rtt().is_err() { +216 conn.skip_waking(); +217 return Ok(()); +218 } +219 conn.inner.send_stream(self.stream).reset(error_code)?; +220 Ok(()) +221 } +222 +223 /// Set the priority of the send stream +224 /// +225 /// Every send stream has an initial priority of 0. Locally buffered data from streams with +226 /// higher priority will be transmitted before data from streams with lower priority. Changing +227 /// the priority of a stream with pending data may only take effect after that data has been +228 /// transmitted. Using many different priority levels per connection may have a negative +229 /// impact on performance. +230 pub fn set_priority(&self, priority: i32) -> Result<(), ClosedStream> { +231 let mut conn = self.conn.lock_without_waking("SendStream::set_priority"); +232 conn.inner.send_stream(self.stream).set_priority(priority)?; +233 Ok(()) +234 } +235 +236 /// Get the priority of the send stream +237 pub fn priority(&self) -> Result<i32, ClosedStream> { +238 let mut conn = self.conn.lock_without_waking("SendStream::priority"); +239 conn.inner.send_stream(self.stream).priority() +240 } +241 +242 /// Completes when the peer stops the stream or reads the stream to completion +243 /// +244 /// Yields `Some` with the stop error code if the peer stops the stream. Yields `None` if the +245 /// local side [`finish()`](Self::finish)es the stream and then the peer acknowledges receipt +246 /// of all stream data (although not necessarily the processing of it), after which the peer +247 /// closing the stream is no longer meaningful. +248 /// +249 /// For a variety of reasons, the peer may not send acknowledgements immediately upon receiving +250 /// data. As such, relying on `stopped` to know when the peer has read a stream to completion +251 /// may introduce more latency than using an application-level response of some sort. +252 pub fn stopped(&self) -> Stopped { +253 let notified = { +254 // Create an `OwnedNotified` to move into the future. By creating it before the first poll, +255 // we make sure that we don't miss any notifications. +256 let mut conn = self.conn.lock_without_waking("SendStream::stopped"); +257 conn.stopped +258 .entry(self.stream) +259 .or_default() +260 .clone() +261 .notified_owned() +262 }; +263 Stopped { +264 conn: self.conn.clone(), +265 stream: self.stream, +266 is_0rtt: self.is_0rtt, +267 notified, +268 } +269 } +270 +271 /// Get the identity of this stream +272 pub fn id(&self) -> StreamId { +273 self.stream +274 } +275 +276 /// Attempt to write bytes from buf into the stream. +277 /// +278 /// On success, returns Poll::Ready(Ok(num_bytes_written)). +279 /// +280 /// If the stream is not ready for writing, the method returns Poll::Pending and arranges +281 /// for the current task (via cx.waker().wake_by_ref()) to receive a notification when the +282 /// stream becomes writable or is closed. +283 pub fn poll_write( +284 self: Pin<&mut Self>, +285 cx: &mut Context<'_>, +286 buf: &[u8], +287 ) -> Poll<Result<usize, WriteError>> { +288 pin!(self.get_mut().write(buf)).as_mut().poll(cx) +289 } +290} +291 +292/// Check if a send stream is stopped. +293/// +294/// Returns `Some` if the stream is stopped or the connection is closed. +295/// Returns `None` if the stream is not stopped. +296fn send_stream_stopped( +297 conn: &mut State, +298 stream: StreamId, +299 is_0rtt: bool, +300) -> Option<Result<Option<VarInt>, StoppedError>> { +301 if is_0rtt && conn.check_0rtt().is_err() { +302 return Some(Err(StoppedError::ZeroRttRejected)); +303 } +304 match conn.inner.send_stream(stream).stopped() { +305 Err(ClosedStream { .. }) => Some(Ok(None)), +306 Ok(Some(error_code)) => Some(Ok(Some(error_code))), +307 Ok(None) => conn.error.clone().map(|error| Err(error.into())), +308 } +309} +310 +311#[cfg(feature = "futures-io")] +312impl futures_io::AsyncWrite for SendStream { +313 fn poll_write( +314 self: Pin<&mut Self>, +315 cx: &mut Context<'_>, +316 buf: &[u8], +317 ) -> Poll<io::Result<usize>> { +318 self.poll_write(cx, buf).map_err(Into::into) 319 } 320 -321 fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { -322 Poll::Ready(self.get_mut().finish().map_err(Into::into)) +321 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { +322 Poll::Ready(Ok(())) 323 } -324} -325 -326impl tokio::io::AsyncWrite for SendStream { -327 fn poll_write( -328 self: Pin<&mut Self>, -329 cx: &mut Context<'_>, -330 buf: &[u8], -331 ) -> Poll<io::Result<usize>> { -332 self.poll_write(cx, buf).map_err(Into::into) -333 } -334 -335 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { -336 Poll::Ready(Ok(())) +324 +325 fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { +326 Poll::Ready(self.get_mut().finish().map_err(Into::into)) +327 } +328} +329 +330impl tokio::io::AsyncWrite for SendStream { +331 fn poll_write( +332 self: Pin<&mut Self>, +333 cx: &mut Context<'_>, +334 buf: &[u8], +335 ) -> Poll<io::Result<usize>> { +336 self.poll_write(cx, buf).map_err(Into::into) 337 } 338 -339 fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { -340 Poll::Ready(self.get_mut().finish().map_err(Into::into)) +339 fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { +340 Poll::Ready(Ok(())) 341 } -342} -343 -344impl Drop for SendStream { -345 fn drop(&mut self) { -346 let mut conn = self.conn.state.lock("SendStream::drop"); +342 +343 fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { +344 Poll::Ready(self.get_mut().finish().map_err(Into::into)) +345 } +346} 347 -348 // clean up any previously registered wakers -349 conn.blocked_writers.remove(&self.stream); -350 -351 if conn.error.is_some() || (self.is_0rtt && conn.check_0rtt().is_err()) { -352 return; -353 } -354 match conn.inner.send_stream(self.stream).finish() { -355 Ok(()) => conn.wake(), -356 Err(FinishError::Stopped(reason)) => { -357 if conn.inner.send_stream(self.stream).reset(reason).is_ok() { -358 conn.wake(); -359 } -360 } -361 // Already finished or reset, which is fine. -362 Err(FinishError::ClosedStream) => {} -363 } -364 } -365} -366 -367/// Errors that arise from writing to a stream -368#[derive(Debug, Error, Clone, PartialEq, Eq)] -369pub enum WriteError { -370 /// The peer is no longer accepting data on this stream -371 /// -372 /// Carries an application-defined error code. -373 #[error("sending stopped by peer: error {0}")] -374 Stopped(VarInt), -375 /// The connection was lost -376 #[error("connection lost")] -377 ConnectionLost(#[from] ConnectionError), -378 /// The stream has already been finished or reset -379 #[error("closed stream")] -380 ClosedStream, -381 /// This was a 0-RTT stream and the server rejected it -382 /// -383 /// Can only occur on clients for 0-RTT streams, which can be opened using -384 /// [`Connecting::into_0rtt()`]. -385 /// -386 /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt() -387 #[error("0-RTT rejected")] -388 ZeroRttRejected, -389} -390 -391impl From<ClosedStream> for WriteError { -392 #[inline] -393 fn from(_: ClosedStream) -> Self { -394 Self::ClosedStream -395 } +348impl Drop for SendStream { +349 fn drop(&mut self) { +350 let mut conn = self.conn.lock_and_wake("SendStream::drop"); +351 +352 // clean up any previously registered wakers +353 conn.blocked_writers.remove(&self.stream); +354 +355 if conn.error.is_some() || (self.is_0rtt && conn.check_0rtt().is_err()) { +356 conn.skip_waking(); +357 return; +358 } +359 match conn.inner.send_stream(self.stream).finish() { +360 Ok(()) => {} +361 Err(FinishError::Stopped(reason)) => { +362 if conn.inner.send_stream(self.stream).reset(reason).is_err() { +363 conn.skip_waking() +364 } +365 } +366 // Already finished or reset, which is fine. +367 Err(FinishError::ClosedStream) => { +368 conn.skip_waking(); +369 } +370 } +371 } +372} +373 +374/// Errors that arise from writing to a stream +375#[derive(Debug, Error, Clone, PartialEq, Eq)] +376pub enum WriteError { +377 /// The peer is no longer accepting data on this stream +378 /// +379 /// Carries an application-defined error code. +380 #[error("sending stopped by peer: error {0}")] +381 Stopped(VarInt), +382 /// The connection was lost +383 #[error("connection lost")] +384 ConnectionLost(#[from] ConnectionError), +385 /// The stream has already been finished or reset +386 #[error("closed stream")] +387 ClosedStream, +388 /// This was a 0-RTT stream and the server rejected it +389 /// +390 /// Can only occur on clients for 0-RTT streams, which can be opened using +391 /// [`Connecting::into_0rtt()`]. +392 /// +393 /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt() +394 #[error("0-RTT rejected")] +395 ZeroRttRejected, 396} 397 -398impl From<StoppedError> for WriteError { -399 fn from(x: StoppedError) -> Self { -400 match x { -401 StoppedError::ConnectionLost(e) => Self::ConnectionLost(e), -402 StoppedError::ZeroRttRejected => Self::ZeroRttRejected, -403 } -404 } -405} -406 -407impl From<WriteError> for io::Error { -408 fn from(x: WriteError) -> Self { -409 use WriteError::*; -410 let kind = match x { -411 Stopped(_) | ZeroRttRejected => io::ErrorKind::ConnectionReset, -412 ConnectionLost(_) | ClosedStream => io::ErrorKind::NotConnected, -413 }; -414 Self::new(kind, x) -415 } -416} -417 -418/// Errors that arise while monitoring for a send stream stop from the peer -419#[derive(Debug, Error, Clone, PartialEq, Eq)] -420pub enum StoppedError { -421 /// The connection was lost -422 #[error("connection lost")] -423 ConnectionLost(#[from] ConnectionError), -424 /// This was a 0-RTT stream and the server rejected it -425 /// -426 /// Can only occur on clients for 0-RTT streams, which can be opened using -427 /// [`Connecting::into_0rtt()`]. -428 /// -429 /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt() -430 #[error("0-RTT rejected")] -431 ZeroRttRejected, -432} -433 -434impl From<StoppedError> for io::Error { -435 fn from(x: StoppedError) -> Self { -436 use StoppedError::*; -437 let kind = match x { -438 ZeroRttRejected => io::ErrorKind::ConnectionReset, -439 ConnectionLost(_) => io::ErrorKind::NotConnected, -440 }; -441 Self::new(kind, x) -442 } -443} -444 -445pin_project! { -446 /// Future returned from [`SendStream::stopped`]. -447 #[derive(Debug)] -448 pub struct Stopped { -449 conn: ConnectionRef, -450 stream: StreamId, -451 is_0rtt: bool, -452 #[pin] -453 notified: OwnedNotified, -454 } -455} -456 -457impl Future for Stopped { -458 type Output = Result<Option<VarInt>, StoppedError>; -459 -460 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { -461 let mut this = self.project(); -462 loop { -463 let mut conn = this.conn.state.lock("SendStream::stopped"); -464 // Check if the stream is stopped before polling the notify. This makes sure that -465 // no wakeups are missed. -466 if let Some(output) = send_stream_stopped(&mut conn, *this.stream, *this.is_0rtt) { -467 return Poll::Ready(output); -468 } -469 std::task::ready!(this.notified.as_mut().poll(cx)); -470 } -471 } -472} -473 -474#[cfg(test)] -475mod tests { -476 fn check_is_send_sync<A: Send + Sync>() {} -477 -478 #[allow(dead_code)] -479 fn test_bounds() { -480 check_is_send_sync::<super::Stopped>(); -481 } -482} \ No newline at end of file +398impl From<ClosedStream> for WriteError { +399 #[inline] +400 fn from(_: ClosedStream) -> Self { +401 Self::ClosedStream +402 } +403} +404 +405impl From<StoppedError> for WriteError { +406 fn from(x: StoppedError) -> Self { +407 match x { +408 StoppedError::ConnectionLost(e) => Self::ConnectionLost(e), +409 StoppedError::ZeroRttRejected => Self::ZeroRttRejected, +410 } +411 } +412} +413 +414impl From<WriteError> for io::Error { +415 fn from(x: WriteError) -> Self { +416 use WriteError::*; +417 let kind = match x { +418 Stopped(_) | ZeroRttRejected => io::ErrorKind::ConnectionReset, +419 ConnectionLost(_) | ClosedStream => io::ErrorKind::NotConnected, +420 }; +421 Self::new(kind, x) +422 } +423} +424 +425/// Errors that arise while monitoring for a send stream stop from the peer +426#[derive(Debug, Error, Clone, PartialEq, Eq)] +427pub enum StoppedError { +428 /// The connection was lost +429 #[error("connection lost")] +430 ConnectionLost(#[from] ConnectionError), +431 /// This was a 0-RTT stream and the server rejected it +432 /// +433 /// Can only occur on clients for 0-RTT streams, which can be opened using +434 /// [`Connecting::into_0rtt()`]. +435 /// +436 /// [`Connecting::into_0rtt()`]: crate::Connecting::into_0rtt() +437 #[error("0-RTT rejected")] +438 ZeroRttRejected, +439} +440 +441impl From<StoppedError> for io::Error { +442 fn from(x: StoppedError) -> Self { +443 use StoppedError::*; +444 let kind = match x { +445 ZeroRttRejected => io::ErrorKind::ConnectionReset, +446 ConnectionLost(_) => io::ErrorKind::NotConnected, +447 }; +448 Self::new(kind, x) +449 } +450} +451 +452pin_project! { +453 /// Future returned from [`SendStream::stopped`]. +454 #[derive(Debug)] +455 pub struct Stopped { +456 conn: ConnectionRef, +457 stream: StreamId, +458 is_0rtt: bool, +459 #[pin] +460 notified: OwnedNotified, +461 } +462} +463 +464impl Future for Stopped { +465 type Output = Result<Option<VarInt>, StoppedError>; +466 +467 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { +468 let mut this = self.project(); +469 loop { +470 let mut conn = this.conn.lock_without_waking("SendStream::stopped"); +471 // Check if the stream is stopped before polling the notify. This makes sure that +472 // no wakeups are missed. +473 if let Some(output) = send_stream_stopped(&mut conn, *this.stream, *this.is_0rtt) { +474 return Poll::Ready(output); +475 } +476 std::task::ready!(this.notified.as_mut().poll(cx)); +477 } +478 } +479} +480 +481#[cfg(test)] +482mod tests { +483 fn check_is_send_sync<A: Send + Sync>() {} +484 +485 #[allow(dead_code)] +486 fn test_bounds() { +487 check_is_send_sync::<super::Stopped>(); +488 } +489} \ No newline at end of file diff --git a/pr/545/docs/src/noq_proto/connection/mod.rs.html b/pr/545/docs/src/noq_proto/connection/mod.rs.html index 531f7f2a7..454db8d3d 100644 --- a/pr/545/docs/src/noq_proto/connection/mod.rs.html +++ b/pr/545/docs/src/noq_proto/connection/mod.rs.html @@ -843,4995 +843,4995 @@ 843 self.path(path_id).and_then(|path| path.remote_status()) 844 } 845 -846 /// Sets the max_idle_timeout for a specific path +846 /// Sets the max_idle_timeout for a specific path. 847 /// -848 /// See [`TransportConfig::default_path_max_idle_timeout`] for details. -849 /// -850 /// Returns the previous value of the setting. -851 pub fn set_path_max_idle_timeout( -852 &mut self, -853 path_id: PathId, -854 timeout: Option<Duration>, -855 ) -> Result<Option<Duration>, ClosedPath> { -856 let path = self -857 .paths -858 .get_mut(&path_id) -859 .ok_or(ClosedPath { _private: () })?; -860 Ok(std::mem::replace(&mut path.data.idle_timeout, timeout)) -861 } -862 -863 /// Sets the keep_alive_interval for a specific path -864 /// -865 /// See [`TransportConfig::default_path_keep_alive_interval`] for details. -866 /// -867 /// Returns the previous value of the setting. -868 pub fn set_path_keep_alive_interval( -869 &mut self, -870 path_id: PathId, -871 interval: Option<Duration>, -872 ) -> Result<Option<Duration>, ClosedPath> { -873 let path = self -874 .paths -875 .get_mut(&path_id) -876 .ok_or(ClosedPath { _private: () })?; -877 Ok(std::mem::replace(&mut path.data.keep_alive, interval)) -878 } -879 -880 /// Gets the [`PathData`] for a known [`PathId`]. -881 /// -882 /// Will panic if the path_id does not reference any known path. -883 #[track_caller] -884 fn path_data_mut(&mut self, path_id: PathId) -> &mut PathData { -885 &mut self.paths.get_mut(&path_id).expect("known path").data -886 } -887 -888 /// Find an open, validated path that's on the same network path as the given network path. -889 /// -890 /// Returns the first path matching, even if there's multiple. -891 fn find_validated_path_on_network_path( -892 &self, -893 network_path: FourTuple, -894 ) -> Option<(&PathId, &PathState)> { -895 self.paths.iter().find(|(path_id, path_state)| { -896 path_state.data.validated -897 // Would this use the same network path, if network_path were used to send right now? -898 && network_path.is_probably_same_path(&path_state.data.network_path) -899 && !self.abandoned_paths.contains(path_id) -900 }) -901 // TODO(@divma): we might want to ensure the path has been recently active to consider the -902 // address validated -903 // matheus23: Perhaps looking at !self.abandoned_paths.contains(path_id) is enough, given keep-alives? -904 } +848 /// The PathIdle timer is immediately re-armed accounting for already-elapsed +849 /// idle time. Setting `None` disables the timeout and stops the timer. +850 /// +851 /// See [`TransportConfig::default_path_max_idle_timeout`] for details. +852 /// +853 /// Returns the previous value of the setting. +854 pub fn set_path_max_idle_timeout( +855 &mut self, +856 now: Instant, +857 path_id: PathId, +858 timeout: Option<Duration>, +859 ) -> Result<Option<Duration>, ClosedPath> { +860 let path = self +861 .paths +862 .get_mut(&path_id) +863 .ok_or(ClosedPath { _private: () })?; +864 let prev = std::mem::replace(&mut path.data.idle_timeout, timeout); +865 +866 // Adjust the PathIdle timer, accounting for already-elapsed idle time. +867 if !self.state.is_closed() { +868 if let Some(new_timeout) = timeout { +869 let timer = Timer::PerPath(path_id, PathTimer::PathIdle); +870 let deadline = match (prev, self.timers.get(timer)) { +871 (Some(old_timeout), Some(old_deadline)) => { +872 let last_activity = old_deadline.checked_sub(old_timeout).unwrap_or(now); +873 last_activity + new_timeout +874 } +875 _ => now + new_timeout, +876 }; +877 self.timers.set(timer, deadline, self.qlog.with_time(now)); +878 } else { +879 self.timers.stop( +880 Timer::PerPath(path_id, PathTimer::PathIdle), +881 self.qlog.with_time(now), +882 ); +883 } +884 } +885 +886 Ok(prev) +887 } +888 +889 /// Sets the keep_alive_interval for a specific path +890 /// +891 /// See [`TransportConfig::default_path_keep_alive_interval`] for details. +892 /// +893 /// Returns the previous value of the setting. +894 pub fn set_path_keep_alive_interval( +895 &mut self, +896 path_id: PathId, +897 interval: Option<Duration>, +898 ) -> Result<Option<Duration>, ClosedPath> { +899 let path = self +900 .paths +901 .get_mut(&path_id) +902 .ok_or(ClosedPath { _private: () })?; +903 Ok(std::mem::replace(&mut path.data.keep_alive, interval)) +904 } 905 -906 /// Creates the [`PathData`] for a new [`PathId`]. +906 /// Gets the [`PathData`] for a known [`PathId`]. 907 /// -908 /// Called for incoming packets as well as when opening a new path locally. -909 fn ensure_path( -910 &mut self, -911 path_id: PathId, -912 network_path: FourTuple, -913 now: Instant, -914 pn: Option<u64>, -915 ) -> &mut PathData { -916 let valid_path = self.find_validated_path_on_network_path(network_path); -917 let validated = valid_path.is_some(); -918 let initial_rtt = valid_path.map(|(_, path)| path.data.rtt.conservative()); -919 let vacant_entry = match self.paths.entry(path_id) { -920 btree_map::Entry::Vacant(vacant_entry) => vacant_entry, -921 btree_map::Entry::Occupied(occupied_entry) => { -922 return &mut occupied_entry.into_mut().data; -923 } -924 }; -925 -926 debug!(%validated, %path_id, %network_path, "path added"); -927 -928 // A new path was added. Cancel any pending NoAvailablePath grace timer. -929 self.timers.stop( -930 Timer::Conn(ConnTimer::NoAvailablePath), -931 self.qlog.with_time(now), -932 ); -933 let peer_max_udp_payload_size = -934 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX); -935 self.path_generation_counter = self.path_generation_counter.wrapping_add(1); -936 let mut data = PathData::new( -937 network_path, -938 self.allow_mtud, -939 Some(peer_max_udp_payload_size), -940 self.path_generation_counter, -941 now, -942 &self.config, -943 ); -944 -945 data.validated = validated; -946 if let Some(initial_rtt) = initial_rtt { -947 data.rtt.reset_initial_rtt(initial_rtt); -948 } -949 -950 // To open a path locally we need to send a packet on the path. Sending a challenge -951 // guarantees this. -952 data.pending_on_path_challenge = true; +908 /// Will panic if the path_id does not reference any known path. +909 #[track_caller] +910 fn path_data_mut(&mut self, path_id: PathId) -> &mut PathData { +911 &mut self.paths.get_mut(&path_id).expect("known path").data +912 } +913 +914 /// Find an open, validated path that's on the same network path as the given network path. +915 /// +916 /// Returns the first path matching, even if there's multiple. +917 fn find_validated_path_on_network_path( +918 &self, +919 network_path: FourTuple, +920 ) -> Option<(&PathId, &PathState)> { +921 self.paths.iter().find(|(path_id, path_state)| { +922 path_state.data.validated +923 // Would this use the same network path, if network_path were used to send right now? +924 && network_path.is_probably_same_path(&path_state.data.network_path) +925 && !self.abandoned_paths.contains(path_id) +926 }) +927 // TODO(@divma): we might want to ensure the path has been recently active to consider the +928 // address validated +929 // matheus23: Perhaps looking at !self.abandoned_paths.contains(path_id) is enough, given keep-alives? +930 } +931 +932 /// Creates the [`PathData`] for a new [`PathId`]. +933 /// +934 /// Called for incoming packets as well as when opening a new path locally. +935 fn ensure_path( +936 &mut self, +937 path_id: PathId, +938 network_path: FourTuple, +939 now: Instant, +940 pn: Option<u64>, +941 ) -> &mut PathData { +942 let valid_path = self.find_validated_path_on_network_path(network_path); +943 let validated = valid_path.is_some(); +944 let initial_rtt = valid_path.map(|(_, path)| path.data.rtt.conservative()); +945 let vacant_entry = match self.paths.entry(path_id) { +946 btree_map::Entry::Vacant(vacant_entry) => vacant_entry, +947 btree_map::Entry::Occupied(occupied_entry) => { +948 return &mut occupied_entry.into_mut().data; +949 } +950 }; +951 +952 debug!(%validated, %path_id, %network_path, "path added"); 953 -954 let path = vacant_entry.insert(PathState { data, prev: None }); -955 -956 let mut pn_space = spaces::PacketNumberSpace::new(now, SpaceId::Data, &mut self.rng); -957 if let Some(pn) = pn { -958 pn_space.dedup.insert(pn); -959 } -960 self.spaces[SpaceId::Data] -961 .number_spaces -962 .insert(path_id, pn_space); -963 self.qlog.emit_tuple_assigned(path_id, network_path, now); -964 -965 // If the remote opened this path we may not have CIDs for it. For locally opened -966 // paths the caller should have already made sure we have CIDs and refused to open -967 // it if there were none. -968 if !self.remote_cids.contains_key(&path_id) { -969 debug!(%path_id, "Remote opened path without issuing CIDs"); -970 self.spaces[SpaceId::Data] -971 .pending -972 .path_cids_blocked -973 .insert(path_id); -974 // Do not abandon this path right away. CIDs might be in-flight still and arrive -975 // soon. It is up to the remote to handle this situation. -976 } -977 -978 &mut path.data -979 } -980 -981 /// Returns packets to transmit -982 /// -983 /// Connections should be polled for transmit after: -984 /// - the application performed some I/O on the connection -985 /// - a call was made to `handle_event` -986 /// - a call was made to `handle_timeout` -987 /// -988 /// `max_datagrams` specifies how many datagrams can be returned inside a -989 /// single Transmit using GSO. This must be at least 1. -990 #[must_use] -991 pub fn poll_transmit( -992 &mut self, -993 now: Instant, -994 max_datagrams: NonZeroUsize, -995 buf: &mut Vec<u8>, -996 ) -> Option<Transmit> { -997 let max_datagrams = match self.config.enable_segmentation_offload { -998 false => NonZeroUsize::MIN, -999 true => max_datagrams, -1000 }; -1001 -1002 // Each call to poll_transmit can only send datagrams to one destination, because -1003 // all datagrams in a GSO batch are for the same destination. Therefore only -1004 // datagrams for one destination address are produced for each poll_transmit call. -1005 -1006 // Check whether we need to send a close message -1007 let connection_close_pending = match self.state.as_type() { -1008 StateType::Drained => { -1009 self.app_limited = true; -1010 return None; -1011 } -1012 StateType::Draining | StateType::Closed => { -1013 // self.connection_close_pending is only reset once the associated packet -1014 // had been encoded successfully -1015 if !self.connection_close_pending { -1016 self.app_limited = true; -1017 return None; -1018 } -1019 true -1020 } -1021 _ => false, -1022 }; -1023 -1024 // Schedule an ACK_FREQUENCY frame if a new one needs to be sent. -1025 if let Some(config) = &self.config.ack_frequency_config { -1026 let rtt = self -1027 .paths -1028 .values() -1029 .map(|p| p.data.rtt.get()) -1030 .min() -1031 .expect("one path exists"); -1032 self.spaces[SpaceId::Data].pending.ack_frequency = self -1033 .ack_frequency -1034 .should_send_ack_frequency(rtt, config, &self.peer_params) -1035 && self.highest_space == SpaceKind::Data -1036 && self.peer_supports_ack_frequency(); -1037 } -1038 -1039 // If we end up not sending anything, we need to know if that was because there was -1040 // nothing to send or because we were congestion blocked. -1041 let mut congestion_blocked = false; -1042 -1043 let mut next_path_id = self.paths.first_entry().map(|e| *e.key()); -1044 while let Some(path_id) = next_path_id { -1045 if !connection_close_pending -1046 && let Some(transmit) = self.poll_transmit_off_path(now, buf, path_id) -1047 { -1048 return Some(transmit); -1049 } -1050 -1051 let info = self.scheduling_info(path_id); -1052 match self.poll_transmit_on_path( -1053 now, -1054 buf, -1055 path_id, -1056 max_datagrams, -1057 &info, -1058 connection_close_pending, -1059 ) { -1060 PollPathStatus::Send(transmit) => { -1061 return Some(transmit); -1062 } -1063 PollPathStatus::NothingToSend { -1064 congestion_blocked: cb, -1065 } => { -1066 congestion_blocked |= cb; -1067 // Continue checking other paths, tail-loss probes may need to be sent -1068 // in all spaces. -1069 debug_assert!( -1070 buf.is_empty(), -1071 "nothing to send on path but buffer not empty" -1072 ); -1073 } -1074 } -1075 -1076 next_path_id = self.paths.keys().find(|i| **i > path_id).copied(); -1077 } -1078 -1079 // We didn't produce any application data packet -1080 debug_assert!( -1081 buf.is_empty(), -1082 "there was data in the buffer, but it was not sent" -1083 ); -1084 -1085 self.app_limited = !congestion_blocked; -1086 -1087 if self.state.is_established() { -1088 // Try MTU probing now -1089 let mut next_path_id = self.paths.first_entry().map(|e| *e.key()); -1090 while let Some(path_id) = next_path_id { -1091 if let Some(transmit) = self.poll_transmit_mtu_probe(now, buf, path_id) { -1092 return Some(transmit); -1093 } -1094 next_path_id = self.paths.keys().find(|i| **i > path_id).copied(); -1095 } -1096 } -1097 -1098 None -1099 } -1100 -1101 /// Computes the packet scheduling information for this path. -1102 /// -1103 /// While this information is only returned for a single path, it is important to know -1104 /// that this information remains static for the entire span of a single -1105 /// [`Connection::poll_transmit`] call. In other words, the return value is purely -1106 /// functional and only depends on the [`PathId`] **during a single** `poll_transmit` -1107 /// call. It can be computed up-front for all paths but we don't do that because it -1108 /// involves an allocation. -1109 /// -1110 /// See the inline comments for how the packet scheduling works. -1111 /// -1112 /// # Panics -1113 /// -1114 /// This will panic if called for a path for which we do not have any [`PathData`], like -1115 /// so many other functions we have. But this is the only one to document this in its -1116 /// doc comment. Maybe that should change. Eventually we'll refactor things for this -1117 /// panic to go away. -1118 fn scheduling_info(&self, path_id: PathId) -> PathSchedulingInfo { -1119 // Such a space is preferred for SpaceKind::Data frames. -1120 let have_validated_status_available_space = self.paths.iter().any(|(path_id, path)| { -1121 self.remote_cids.contains_key(path_id) -1122 && !self.abandoned_paths.contains(path_id) -1123 && path.data.validated -1124 && path.data.local_status() == PathStatus::Available -1125 }); +954 // A new path was added. Cancel any pending NoAvailablePath grace timer. +955 self.timers.stop( +956 Timer::Conn(ConnTimer::NoAvailablePath), +957 self.qlog.with_time(now), +958 ); +959 let peer_max_udp_payload_size = +960 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX); +961 self.path_generation_counter = self.path_generation_counter.wrapping_add(1); +962 let mut data = PathData::new( +963 network_path, +964 self.allow_mtud, +965 Some(peer_max_udp_payload_size), +966 self.path_generation_counter, +967 now, +968 &self.config, +969 ); +970 +971 data.validated = validated; +972 if let Some(initial_rtt) = initial_rtt { +973 data.rtt.reset_initial_rtt(initial_rtt); +974 } +975 +976 // To open a path locally we need to send a packet on the path. Sending a challenge +977 // guarantees this. +978 data.pending_on_path_challenge = true; +979 +980 let path = vacant_entry.insert(PathState { data, prev: None }); +981 +982 let mut pn_space = spaces::PacketNumberSpace::new(now, SpaceId::Data, &mut self.rng); +983 if let Some(pn) = pn { +984 pn_space.dedup.insert(pn); +985 } +986 self.spaces[SpaceId::Data] +987 .number_spaces +988 .insert(path_id, pn_space); +989 self.qlog.emit_tuple_assigned(path_id, network_path, now); +990 +991 // If the remote opened this path we may not have CIDs for it. For locally opened +992 // paths the caller should have already made sure we have CIDs and refused to open +993 // it if there were none. +994 if !self.remote_cids.contains_key(&path_id) { +995 debug!(%path_id, "Remote opened path without issuing CIDs"); +996 self.spaces[SpaceId::Data] +997 .pending +998 .path_cids_blocked +999 .insert(path_id); +1000 // Do not abandon this path right away. CIDs might be in-flight still and arrive +1001 // soon. It is up to the remote to handle this situation. +1002 } +1003 +1004 &mut path.data +1005 } +1006 +1007 /// Returns packets to transmit +1008 /// +1009 /// Connections should be polled for transmit after: +1010 /// - the application performed some I/O on the connection +1011 /// - a call was made to `handle_event` +1012 /// - a call was made to `handle_timeout` +1013 /// +1014 /// `max_datagrams` specifies how many datagrams can be returned inside a +1015 /// single Transmit using GSO. This must be at least 1. +1016 #[must_use] +1017 pub fn poll_transmit( +1018 &mut self, +1019 now: Instant, +1020 max_datagrams: NonZeroUsize, +1021 buf: &mut Vec<u8>, +1022 ) -> Option<Transmit> { +1023 let max_datagrams = match self.config.enable_segmentation_offload { +1024 false => NonZeroUsize::MIN, +1025 true => max_datagrams, +1026 }; +1027 +1028 // Each call to poll_transmit can only send datagrams to one destination, because +1029 // all datagrams in a GSO batch are for the same destination. Therefore only +1030 // datagrams for one destination address are produced for each poll_transmit call. +1031 +1032 // Check whether we need to send a close message +1033 let connection_close_pending = match self.state.as_type() { +1034 StateType::Drained => { +1035 self.app_limited = true; +1036 return None; +1037 } +1038 StateType::Draining | StateType::Closed => { +1039 // self.connection_close_pending is only reset once the associated packet +1040 // had been encoded successfully +1041 if !self.connection_close_pending { +1042 self.app_limited = true; +1043 return None; +1044 } +1045 true +1046 } +1047 _ => false, +1048 }; +1049 +1050 // Schedule an ACK_FREQUENCY frame if a new one needs to be sent. +1051 if let Some(config) = &self.config.ack_frequency_config { +1052 let rtt = self +1053 .paths +1054 .values() +1055 .map(|p| p.data.rtt.get()) +1056 .min() +1057 .expect("one path exists"); +1058 self.spaces[SpaceId::Data].pending.ack_frequency = self +1059 .ack_frequency +1060 .should_send_ack_frequency(rtt, config, &self.peer_params) +1061 && self.highest_space == SpaceKind::Data +1062 && self.peer_supports_ack_frequency(); +1063 } +1064 +1065 // If we end up not sending anything, we need to know if that was because there was +1066 // nothing to send or because we were congestion blocked. +1067 let mut congestion_blocked = false; +1068 +1069 let mut next_path_id = self.paths.first_entry().map(|e| *e.key()); +1070 while let Some(path_id) = next_path_id { +1071 if !connection_close_pending +1072 && let Some(transmit) = self.poll_transmit_off_path(now, buf, path_id) +1073 { +1074 return Some(transmit); +1075 } +1076 +1077 let info = self.scheduling_info(path_id); +1078 match self.poll_transmit_on_path( +1079 now, +1080 buf, +1081 path_id, +1082 max_datagrams, +1083 &info, +1084 connection_close_pending, +1085 ) { +1086 PollPathStatus::Send(transmit) => { +1087 return Some(transmit); +1088 } +1089 PollPathStatus::NothingToSend { +1090 congestion_blocked: cb, +1091 } => { +1092 congestion_blocked |= cb; +1093 // Continue checking other paths, tail-loss probes may need to be sent +1094 // in all spaces. +1095 debug_assert!( +1096 buf.is_empty(), +1097 "nothing to send on path but buffer not empty" +1098 ); +1099 } +1100 } +1101 +1102 next_path_id = self.paths.keys().find(|i| **i > path_id).copied(); +1103 } +1104 +1105 // We didn't produce any application data packet +1106 debug_assert!( +1107 buf.is_empty(), +1108 "there was data in the buffer, but it was not sent" +1109 ); +1110 +1111 self.app_limited = !congestion_blocked; +1112 +1113 if self.state.is_established() { +1114 // Try MTU probing now +1115 let mut next_path_id = self.paths.first_entry().map(|e| *e.key()); +1116 while let Some(path_id) = next_path_id { +1117 if let Some(transmit) = self.poll_transmit_mtu_probe(now, buf, path_id) { +1118 return Some(transmit); +1119 } +1120 next_path_id = self.paths.keys().find(|i| **i > path_id).copied(); +1121 } +1122 } +1123 +1124 None +1125 } 1126 -1127 // Such a space is able to send SpaceKind::Data frames. -1128 let have_validated_space = self.paths.iter().any(|(path_id, path)| { -1129 self.remote_cids.contains_key(path_id) -1130 && !self.abandoned_paths.contains(path_id) -1131 && path.data.validated -1132 }); -1133 -1134 let is_handshaking = self.is_handshaking(); -1135 let has_cids = self.remote_cids.contains_key(&path_id); -1136 let is_abandoned = self.abandoned_paths.contains(&path_id); -1137 let path_data = self.path_data(path_id); -1138 let validated = path_data.validated; -1139 let status = path_data.local_status(); -1140 -1141 // This is the core packet scheduling, whether this space ID may send -1142 // SpaceKind::Data frames. -1143 let may_send_data = has_cids -1144 && !is_abandoned -1145 && if is_handshaking { -1146 // There is only one path during the handshake. We want to -1147 // already send 0-RTT and 0.5-RTT (permitting anti-amplification -1148 // limit) data. -1149 true -1150 } else if !validated { -1151 // TODO(flub): When we have a network change we might end up -1152 // having to abandon all paths and re-open new ones to the -1153 // same remotes. This leaves us without any validated -1154 // path. Perhaps we should have a way to figure out if the -1155 // path is to a previously-validated remote address and allow -1156 // sending data to such remotes immediately. -1157 false -1158 } else { -1159 match status { -1160 PathStatus::Available => { -1161 // Best possible space to send data on. -1162 true -1163 } -1164 PathStatus::Backup => { -1165 // If there is a status-available path we prefer that. -1166 !have_validated_status_available_space -1167 } -1168 } -1169 }; -1170 -1171 // CONNECTION_CLOSE is allowed to be sent on a non-validated -1172 // path. Particularly during the handshake we want to send it before the -1173 // path is validated. Later if there is no validated path available we -1174 // will also accept sending it on an un-validated path. -1175 let may_send_close = has_cids -1176 && !is_abandoned -1177 && if !validated && have_validated_status_available_space { -1178 // We have a better space to send on. -1179 false -1180 } else { -1181 // No other validated space, this is as good as it gets. -1182 true -1183 }; -1184 -1185 // PATH_ABANDON is normally sent together with other SpaceKind::Data frames. But if -1186 // there is no other validated space to send it on, it can be sent on the path to be -1187 // abandoned itself if that was validated. -1188 let may_self_abandon = has_cids && validated && !have_validated_space; -1189 -1190 PathSchedulingInfo { -1191 is_abandoned, -1192 may_send_data, -1193 may_send_close, -1194 may_self_abandon, -1195 } -1196 } -1197 -1198 fn build_transmit(&mut self, path_id: PathId, transmit: TransmitBuf<'_>) -> Transmit { -1199 debug_assert!( -1200 !transmit.is_empty(), -1201 "must not be called with an empty transmit buffer" -1202 ); -1203 -1204 let network_path = self.path_data(path_id).network_path; -1205 trace!( -1206 segment_size = transmit.segment_size(), -1207 last_datagram_len = transmit.len() % transmit.segment_size(), -1208 %network_path, -1209 "sending {} bytes in {} datagrams", -1210 transmit.len(), -1211 transmit.num_datagrams() -1212 ); -1213 self.path_data_mut(path_id) -1214 .inc_total_sent(transmit.len() as u64); +1127 /// Computes the packet scheduling information for this path. +1128 /// +1129 /// While this information is only returned for a single path, it is important to know +1130 /// that this information remains static for the entire span of a single +1131 /// [`Connection::poll_transmit`] call. In other words, the return value is purely +1132 /// functional and only depends on the [`PathId`] **during a single** `poll_transmit` +1133 /// call. It can be computed up-front for all paths but we don't do that because it +1134 /// involves an allocation. +1135 /// +1136 /// See the inline comments for how the packet scheduling works. +1137 /// +1138 /// # Panics +1139 /// +1140 /// This will panic if called for a path for which we do not have any [`PathData`], like +1141 /// so many other functions we have. But this is the only one to document this in its +1142 /// doc comment. Maybe that should change. Eventually we'll refactor things for this +1143 /// panic to go away. +1144 fn scheduling_info(&self, path_id: PathId) -> PathSchedulingInfo { +1145 // Such a space is preferred for SpaceKind::Data frames. +1146 let have_validated_status_available_space = self.paths.iter().any(|(path_id, path)| { +1147 self.remote_cids.contains_key(path_id) +1148 && !self.abandoned_paths.contains(path_id) +1149 && path.data.validated +1150 && path.data.local_status() == PathStatus::Available +1151 }); +1152 +1153 // Such a space is able to send SpaceKind::Data frames. +1154 let have_validated_space = self.paths.iter().any(|(path_id, path)| { +1155 self.remote_cids.contains_key(path_id) +1156 && !self.abandoned_paths.contains(path_id) +1157 && path.data.validated +1158 }); +1159 +1160 let is_handshaking = self.is_handshaking(); +1161 let has_cids = self.remote_cids.contains_key(&path_id); +1162 let is_abandoned = self.abandoned_paths.contains(&path_id); +1163 let path_data = self.path_data(path_id); +1164 let validated = path_data.validated; +1165 let status = path_data.local_status(); +1166 +1167 // This is the core packet scheduling, whether this space ID may send +1168 // SpaceKind::Data frames. +1169 let may_send_data = has_cids +1170 && !is_abandoned +1171 && if is_handshaking { +1172 // There is only one path during the handshake. We want to +1173 // already send 0-RTT and 0.5-RTT (permitting anti-amplification +1174 // limit) data. +1175 true +1176 } else if !validated { +1177 // TODO(flub): When we have a network change we might end up +1178 // having to abandon all paths and re-open new ones to the +1179 // same remotes. This leaves us without any validated +1180 // path. Perhaps we should have a way to figure out if the +1181 // path is to a previously-validated remote address and allow +1182 // sending data to such remotes immediately. +1183 false +1184 } else { +1185 match status { +1186 PathStatus::Available => { +1187 // Best possible space to send data on. +1188 true +1189 } +1190 PathStatus::Backup => { +1191 // If there is a status-available path we prefer that. +1192 !have_validated_status_available_space +1193 } +1194 } +1195 }; +1196 +1197 // CONNECTION_CLOSE is allowed to be sent on a non-validated +1198 // path. Particularly during the handshake we want to send it before the +1199 // path is validated. Later if there is no validated path available we +1200 // will also accept sending it on an un-validated path. +1201 let may_send_close = has_cids +1202 && !is_abandoned +1203 && if !validated && have_validated_status_available_space { +1204 // We have a better space to send on. +1205 false +1206 } else { +1207 // No other validated space, this is as good as it gets. +1208 true +1209 }; +1210 +1211 // PATH_ABANDON is normally sent together with other SpaceKind::Data frames. But if +1212 // there is no other validated space to send it on, it can be sent on the path to be +1213 // abandoned itself if that was validated. +1214 let may_self_abandon = has_cids && validated && !have_validated_space; 1215 -1216 self.path_stats -1217 .for_path(path_id) -1218 .udp_tx -1219 .on_sent(transmit.num_datagrams() as u64, transmit.len()); -1220 -1221 Transmit { -1222 destination: network_path.remote, -1223 size: transmit.len(), -1224 ecn: if self.path_data(path_id).sending_ecn { -1225 Some(EcnCodepoint::Ect0) -1226 } else { -1227 None -1228 }, -1229 segment_size: match transmit.num_datagrams() { -1230 1 => None, -1231 _ => Some(transmit.segment_size()), -1232 }, -1233 src_ip: network_path.local_ip, -1234 } -1235 } -1236 -1237 /// poll_transmit logic for off-path data. -1238 fn poll_transmit_off_path( -1239 &mut self, -1240 now: Instant, -1241 buf: &mut Vec<u8>, -1242 path_id: PathId, -1243 ) -> Option<Transmit> { -1244 if let Some(challenge) = self.send_prev_path_challenge(now, buf, path_id) { -1245 return Some(challenge); -1246 } -1247 if let Some(response) = self.send_off_path_path_response(now, buf, path_id) { -1248 return Some(response); -1249 } -1250 if let Some(challenge) = self.send_nat_traversal_path_challenge(now, buf, path_id) { -1251 return Some(challenge); -1252 } -1253 None -1254 } -1255 -1256 /// poll_transmit logic for on-path data. -1257 /// -1258 /// This is not quite the same as for a multipath packet space, since [`PathId::ZERO`] -1259 /// has 3 packet spaces, which this handles. -1260 /// -1261 /// See [`Self::poll_transmit_off_path`] for off-path data. -1262 #[must_use] -1263 fn poll_transmit_on_path( -1264 &mut self, -1265 now: Instant, -1266 buf: &mut Vec<u8>, -1267 path_id: PathId, -1268 max_datagrams: NonZeroUsize, -1269 scheduling_info: &PathSchedulingInfo, -1270 connection_close_pending: bool, -1271 ) -> PollPathStatus { -1272 // Check if there is at least one active CID to use for sending -1273 let Some(remote_cid) = self.remote_cids.get(&path_id).map(CidQueue::active) else { -1274 if !self.abandoned_paths.contains(&path_id) { -1275 debug!(%path_id, "no remote CIDs for path"); -1276 } -1277 return PollPathStatus::NothingToSend { -1278 congestion_blocked: false, -1279 }; -1280 }; +1216 PathSchedulingInfo { +1217 is_abandoned, +1218 may_send_data, +1219 may_send_close, +1220 may_self_abandon, +1221 } +1222 } +1223 +1224 fn build_transmit(&mut self, path_id: PathId, transmit: TransmitBuf<'_>) -> Transmit { +1225 debug_assert!( +1226 !transmit.is_empty(), +1227 "must not be called with an empty transmit buffer" +1228 ); +1229 +1230 let network_path = self.path_data(path_id).network_path; +1231 trace!( +1232 segment_size = transmit.segment_size(), +1233 last_datagram_len = transmit.len() % transmit.segment_size(), +1234 %network_path, +1235 "sending {} bytes in {} datagrams", +1236 transmit.len(), +1237 transmit.num_datagrams() +1238 ); +1239 self.path_data_mut(path_id) +1240 .inc_total_sent(transmit.len() as u64); +1241 +1242 self.path_stats +1243 .for_path(path_id) +1244 .udp_tx +1245 .on_sent(transmit.num_datagrams() as u64, transmit.len()); +1246 +1247 Transmit { +1248 destination: network_path.remote, +1249 size: transmit.len(), +1250 ecn: if self.path_data(path_id).sending_ecn { +1251 Some(EcnCodepoint::Ect0) +1252 } else { +1253 None +1254 }, +1255 segment_size: match transmit.num_datagrams() { +1256 1 => None, +1257 _ => Some(transmit.segment_size()), +1258 }, +1259 src_ip: network_path.local_ip, +1260 } +1261 } +1262 +1263 /// poll_transmit logic for off-path data. +1264 fn poll_transmit_off_path( +1265 &mut self, +1266 now: Instant, +1267 buf: &mut Vec<u8>, +1268 path_id: PathId, +1269 ) -> Option<Transmit> { +1270 if let Some(challenge) = self.send_prev_path_challenge(now, buf, path_id) { +1271 return Some(challenge); +1272 } +1273 if let Some(response) = self.send_off_path_path_response(now, buf, path_id) { +1274 return Some(response); +1275 } +1276 if let Some(challenge) = self.send_nat_traversal_path_challenge(now, buf, path_id) { +1277 return Some(challenge); +1278 } +1279 None +1280 } 1281 -1282 // Whether the last packet in the datagram must be padded so the datagram takes up -1283 // an exact size. An earlier space can decide to not fill an entire datagram and -1284 // require the next space to fill it further. But may need a specific size of the -1285 // datagram containing the packet. The final packet built in the datagram must pad -1286 // to this size. -1287 let mut pad_datagram = PadDatagram::No; -1288 -1289 // The packet number of the last built packet. This is kept kept across spaces. -1290 // QUIC is supposed to have a single congestion controller for the Initial, -1291 // Handshake and Data(PathId::ZERO) spaces. -1292 let mut last_packet_number = None; -1293 -1294 // If we end up not sending anything, we need to know if that was because there was -1295 // nothing to send or because we were congestion blocked. -1296 let mut congestion_blocked = false; -1297 -1298 // Set the segment size to this path's MTU for on-path data. -1299 let pmtu = self.path_data(path_id).current_mtu().into(); -1300 let mut transmit = TransmitBuf::new(buf, max_datagrams, pmtu); -1301 -1302 // Iterate over the available spaces. -1303 for space_id in SpaceId::iter() { -1304 // Only PathId::ZERO uses non Data space ids. -1305 if path_id != PathId::ZERO && space_id != SpaceId::Data { -1306 continue; -1307 } -1308 match self.poll_transmit_path_space( -1309 now, -1310 &mut transmit, -1311 path_id, -1312 space_id, -1313 remote_cid, -1314 scheduling_info, -1315 connection_close_pending, -1316 pad_datagram, -1317 ) { -1318 PollPathSpaceStatus::NothingToSend { -1319 congestion_blocked: cb, -1320 } => { -1321 congestion_blocked |= cb; -1322 // Continue checking other spaces, tail-loss probes may need to be sent -1323 // in all spaces. -1324 } -1325 PollPathSpaceStatus::WrotePacket { -1326 last_packet_number: pn, -1327 pad_datagram: pad, -1328 } => { -1329 debug_assert!(!transmit.is_empty(), "transmit must contain packets"); -1330 last_packet_number = Some(pn); -1331 pad_datagram = pad; -1332 // Always check higher spaces. If the transmit is full or they have -1333 // nothing to send they will not write packets. But if they can, they -1334 // must always be allowed to add to this transmit because coalescing may -1335 // be required. -1336 continue; -1337 } -1338 PollPathSpaceStatus::Send { -1339 last_packet_number: pn, -1340 } => { -1341 debug_assert!(!transmit.is_empty(), "transmit must contain packets"); -1342 last_packet_number = Some(pn); -1343 break; -1344 } -1345 } -1346 } -1347 -1348 if last_packet_number.is_some() || congestion_blocked { -1349 self.qlog.emit_recovery_metrics( -1350 path_id, -1351 &mut self.paths.get_mut(&path_id).unwrap().data, -1352 now, -1353 ); -1354 } -1355 -1356 match last_packet_number { -1357 Some(last_packet_number) => { -1358 // Note that when sending in multiple spaces the last packet number will be -1359 // the one from the highest space. -1360 self.path_data_mut(path_id).congestion.on_sent( -1361 now, -1362 transmit.len() as u64, -1363 last_packet_number, -1364 ); -1365 PollPathStatus::Send(self.build_transmit(path_id, transmit)) -1366 } -1367 None => PollPathStatus::NothingToSend { congestion_blocked }, -1368 } -1369 } -1370 -1371 /// poll_transmit logic for a QUIC-MULTIPATH packet number space (PathID + SpaceId). -1372 #[must_use] -1373 fn poll_transmit_path_space( -1374 &mut self, -1375 now: Instant, -1376 transmit: &mut TransmitBuf<'_>, -1377 path_id: PathId, -1378 space_id: SpaceId, -1379 remote_cid: ConnectionId, -1380 scheduling_info: &PathSchedulingInfo, -1381 // If we need to send a CONNECTION_CLOSE frame. -1382 connection_close_pending: bool, -1383 // Whether the current datagram needs to be padded to a certain size. -1384 mut pad_datagram: PadDatagram, -1385 ) -> PollPathSpaceStatus { -1386 // Keep track of the last packet number we wrote. If None we did not write any -1387 // packets. -1388 let mut last_packet_number = None; -1389 -1390 // Each loop of this may build one packet. It works logically as follows: -1391 // -1392 // - Check if something *needs* to be sent in this space and *can* be sent. -1393 // - If not, return to the caller who will call us again for the next space. -1394 // - Start a new datagram. -1395 // - Unless coalescing the packet into an existing datagram. -1396 // - Write the packet header and payload. -1397 // - Check if coalescing a next packet into the datagram is possible. -1398 // - If coalescing, finish packet without padding to leave space in the datagram. -1399 // - If not coalescing, complete the datagram: -1400 // - Finish packet with padding. -1401 // - Set the transmit segment size if this is the first datagram. -1402 // - Loop: next iteration will exit the loop if nothing more to send in this -1403 // space. The TransmitBuf will contain a started datagram with space if -1404 // coalescing, or completely filled datagram if not coalescing. -1405 loop { -1406 // Determine if anything can be sent in this packet number space. -1407 let max_packet_size = if transmit.datagram_remaining_mut() > 0 { -1408 // A datagram is started already, we are coalescing another packet into it. -1409 transmit.datagram_remaining_mut() -1410 } else { -1411 // A new datagram needs to be started. -1412 transmit.segment_size() -1413 }; -1414 let can_send = -1415 self.space_can_send(space_id, path_id, max_packet_size, connection_close_pending); -1416 let needs_loss_probe = self.spaces[space_id].for_path(path_id).loss_probes > 0; -1417 let space_will_send = { -1418 if scheduling_info.is_abandoned { -1419 // If this path is abandoned then we might still have to send -1420 // PATH_ABANDON itself on it if there was no better space -1421 // available. Otherwise we want to send the PATH_ABANDON as permitted by -1422 // may_send_data however. -1423 scheduling_info.may_self_abandon -1424 && self.spaces[space_id] -1425 .pending -1426 .path_abandon -1427 .contains_key(&path_id) -1428 } else if can_send.close && scheduling_info.may_send_close { -1429 // This is the best path to send a CONNECTION_CLOSE on. -1430 true -1431 } else if needs_loss_probe || can_send.space_specific { -1432 // We always send a loss probe or space-specific frames if the path is -1433 // not abandoned. -1434 true -1435 } else { -1436 // Anything else we only send if we're the best path for SpaceKind::Data -1437 // frames. -1438 !can_send.is_empty() && scheduling_info.may_send_data -1439 } -1440 }; -1441 -1442 if !space_will_send { -1443 // Nothing more to send. Previous iterations of this loop may have built -1444 // packets already. -1445 return match last_packet_number { -1446 Some(pn) => PollPathSpaceStatus::WrotePacket { -1447 last_packet_number: pn, -1448 pad_datagram, -1449 }, -1450 None => { -1451 // Only log for spaces which have crypto. -1452 if self.crypto_state.has_keys(space_id.encryption_level()) -1453 || (space_id == SpaceId::Data -1454 && self.crypto_state.has_keys(EncryptionLevel::ZeroRtt)) -1455 { -1456 trace!(?space_id, %path_id, "nothing to send in space"); -1457 } -1458 PollPathSpaceStatus::NothingToSend { -1459 congestion_blocked: false, -1460 } -1461 } -1462 }; -1463 } -1464 -1465 // We want to send on this space, check congestion control if we can. But only -1466 // if we will need to start a new datagram. If we are coalescing into an already -1467 // started datagram we do not need to check congestion control again. -1468 if transmit.datagram_remaining_mut() == 0 { -1469 let congestion_blocked = -1470 self.path_congestion_check(space_id, path_id, transmit, &can_send, now); -1471 if congestion_blocked != PathBlocked::No { -1472 // Previous iterations of this loop may have built packets already. -1473 return match last_packet_number { -1474 Some(pn) => PollPathSpaceStatus::WrotePacket { -1475 last_packet_number: pn, -1476 pad_datagram, -1477 }, -1478 None => { -1479 return PollPathSpaceStatus::NothingToSend { -1480 congestion_blocked: true, -1481 }; -1482 } -1483 }; -1484 } -1485 } -1486 -1487 // If the datagram is full (or there never was one started), we need to start a -1488 // new one. -1489 if transmit.datagram_remaining_mut() == 0 { -1490 if transmit.num_datagrams() >= transmit.max_datagrams().get() { -1491 // No more datagrams allowed. -1492 // Previous iterations of this loop may have built packets already. -1493 return match last_packet_number { -1494 Some(pn) => PollPathSpaceStatus::WrotePacket { -1495 last_packet_number: pn, -1496 pad_datagram, -1497 }, -1498 None => { -1499 return PollPathSpaceStatus::NothingToSend { -1500 congestion_blocked: false, -1501 }; -1502 } -1503 }; -1504 } -1505 -1506 match self.spaces[space_id].for_path(path_id).loss_probes { -1507 0 => transmit.start_new_datagram(), -1508 _ => { -1509 // We need something to send for a tail-loss probe. -1510 let request_immediate_ack = -1511 space_id == SpaceId::Data && self.peer_supports_ack_frequency(); -1512 self.spaces[space_id].maybe_queue_probe( -1513 path_id, -1514 request_immediate_ack, -1515 &self.streams, -1516 ); -1517 -1518 self.spaces[space_id].for_path(path_id).loss_probes -= 1; -1519 -1520 // Clamp the datagram to at most the minimum MTU to ensure that loss -1521 // probes can get through and enable recovery even if the path MTU -1522 // has shrank unexpectedly. -1523 transmit.start_new_datagram_with_size(std::cmp::min( -1524 usize::from(INITIAL_MTU), -1525 transmit.segment_size(), -1526 )); -1527 } -1528 } -1529 trace!(count = transmit.num_datagrams(), "new datagram started"); -1530 -1531 // We started a new datagram, we decide later if it needs padding. -1532 pad_datagram = PadDatagram::No; -1533 } -1534 -1535 // If coalescing another packet into the existing datagram, there should -1536 // still be enough space for a whole packet. -1537 if transmit.datagram_start_offset() < transmit.len() { -1538 debug_assert!(transmit.datagram_remaining_mut() >= MIN_PACKET_SPACE); -1539 } -1540 -1541 // -1542 // From here on, we've determined that a packet will definitely be sent. -1543 // -1544 -1545 if self.crypto_state.has_keys(EncryptionLevel::Initial) -1546 && space_id == SpaceId::Handshake -1547 && self.side.is_client() -1548 { -1549 // A client stops both sending and processing Initial packets when it -1550 // sends its first Handshake packet. -1551 self.discard_space(now, SpaceKind::Initial); -1552 } -1553 if let Some(ref mut prev) = self.crypto_state.prev_crypto { -1554 prev.update_unacked = false; -1555 } +1282 /// poll_transmit logic for on-path data. +1283 /// +1284 /// This is not quite the same as for a multipath packet space, since [`PathId::ZERO`] +1285 /// has 3 packet spaces, which this handles. +1286 /// +1287 /// See [`Self::poll_transmit_off_path`] for off-path data. +1288 #[must_use] +1289 fn poll_transmit_on_path( +1290 &mut self, +1291 now: Instant, +1292 buf: &mut Vec<u8>, +1293 path_id: PathId, +1294 max_datagrams: NonZeroUsize, +1295 scheduling_info: &PathSchedulingInfo, +1296 connection_close_pending: bool, +1297 ) -> PollPathStatus { +1298 // Check if there is at least one active CID to use for sending +1299 let Some(remote_cid) = self.remote_cids.get(&path_id).map(CidQueue::active) else { +1300 if !self.abandoned_paths.contains(&path_id) { +1301 debug!(%path_id, "no remote CIDs for path"); +1302 } +1303 return PollPathStatus::NothingToSend { +1304 congestion_blocked: false, +1305 }; +1306 }; +1307 +1308 // Whether the last packet in the datagram must be padded so the datagram takes up +1309 // an exact size. An earlier space can decide to not fill an entire datagram and +1310 // require the next space to fill it further. But may need a specific size of the +1311 // datagram containing the packet. The final packet built in the datagram must pad +1312 // to this size. +1313 let mut pad_datagram = PadDatagram::No; +1314 +1315 // The packet number of the last built packet. This is kept kept across spaces. +1316 // QUIC is supposed to have a single congestion controller for the Initial, +1317 // Handshake and Data(PathId::ZERO) spaces. +1318 let mut last_packet_number = None; +1319 +1320 // If we end up not sending anything, we need to know if that was because there was +1321 // nothing to send or because we were congestion blocked. +1322 let mut congestion_blocked = false; +1323 +1324 // Set the segment size to this path's MTU for on-path data. +1325 let pmtu = self.path_data(path_id).current_mtu().into(); +1326 let mut transmit = TransmitBuf::new(buf, max_datagrams, pmtu); +1327 +1328 // Iterate over the available spaces. +1329 for space_id in SpaceId::iter() { +1330 // Only PathId::ZERO uses non Data space ids. +1331 if path_id != PathId::ZERO && space_id != SpaceId::Data { +1332 continue; +1333 } +1334 match self.poll_transmit_path_space( +1335 now, +1336 &mut transmit, +1337 path_id, +1338 space_id, +1339 remote_cid, +1340 scheduling_info, +1341 connection_close_pending, +1342 pad_datagram, +1343 ) { +1344 PollPathSpaceStatus::NothingToSend { +1345 congestion_blocked: cb, +1346 } => { +1347 congestion_blocked |= cb; +1348 // Continue checking other spaces, tail-loss probes may need to be sent +1349 // in all spaces. +1350 } +1351 PollPathSpaceStatus::WrotePacket { +1352 last_packet_number: pn, +1353 pad_datagram: pad, +1354 } => { +1355 debug_assert!(!transmit.is_empty(), "transmit must contain packets"); +1356 last_packet_number = Some(pn); +1357 pad_datagram = pad; +1358 // Always check higher spaces. If the transmit is full or they have +1359 // nothing to send they will not write packets. But if they can, they +1360 // must always be allowed to add to this transmit because coalescing may +1361 // be required. +1362 continue; +1363 } +1364 PollPathSpaceStatus::Send { +1365 last_packet_number: pn, +1366 } => { +1367 debug_assert!(!transmit.is_empty(), "transmit must contain packets"); +1368 last_packet_number = Some(pn); +1369 break; +1370 } +1371 } +1372 } +1373 +1374 if last_packet_number.is_some() || congestion_blocked { +1375 self.qlog.emit_recovery_metrics( +1376 path_id, +1377 &mut self.paths.get_mut(&path_id).unwrap().data, +1378 now, +1379 ); +1380 } +1381 +1382 match last_packet_number { +1383 Some(last_packet_number) => { +1384 // Note that when sending in multiple spaces the last packet number will be +1385 // the one from the highest space. +1386 self.path_data_mut(path_id).congestion.on_sent( +1387 now, +1388 transmit.len() as u64, +1389 last_packet_number, +1390 ); +1391 PollPathStatus::Send(self.build_transmit(path_id, transmit)) +1392 } +1393 None => PollPathStatus::NothingToSend { congestion_blocked }, +1394 } +1395 } +1396 +1397 /// poll_transmit logic for a QUIC-MULTIPATH packet number space (PathID + SpaceId). +1398 #[must_use] +1399 fn poll_transmit_path_space( +1400 &mut self, +1401 now: Instant, +1402 transmit: &mut TransmitBuf<'_>, +1403 path_id: PathId, +1404 space_id: SpaceId, +1405 remote_cid: ConnectionId, +1406 scheduling_info: &PathSchedulingInfo, +1407 // If we need to send a CONNECTION_CLOSE frame. +1408 connection_close_pending: bool, +1409 // Whether the current datagram needs to be padded to a certain size. +1410 mut pad_datagram: PadDatagram, +1411 ) -> PollPathSpaceStatus { +1412 // Keep track of the last packet number we wrote. If None we did not write any +1413 // packets. +1414 let mut last_packet_number = None; +1415 +1416 // Each loop of this may build one packet. It works logically as follows: +1417 // +1418 // - Check if something *needs* to be sent in this space and *can* be sent. +1419 // - If not, return to the caller who will call us again for the next space. +1420 // - Start a new datagram. +1421 // - Unless coalescing the packet into an existing datagram. +1422 // - Write the packet header and payload. +1423 // - Check if coalescing a next packet into the datagram is possible. +1424 // - If coalescing, finish packet without padding to leave space in the datagram. +1425 // - If not coalescing, complete the datagram: +1426 // - Finish packet with padding. +1427 // - Set the transmit segment size if this is the first datagram. +1428 // - Loop: next iteration will exit the loop if nothing more to send in this +1429 // space. The TransmitBuf will contain a started datagram with space if +1430 // coalescing, or completely filled datagram if not coalescing. +1431 loop { +1432 // Determine if anything can be sent in this packet number space. +1433 let max_packet_size = if transmit.datagram_remaining_mut() > 0 { +1434 // A datagram is started already, we are coalescing another packet into it. +1435 transmit.datagram_remaining_mut() +1436 } else { +1437 // A new datagram needs to be started. +1438 transmit.segment_size() +1439 }; +1440 let can_send = +1441 self.space_can_send(space_id, path_id, max_packet_size, connection_close_pending); +1442 let needs_loss_probe = self.spaces[space_id].for_path(path_id).loss_probes > 0; +1443 let space_will_send = { +1444 if scheduling_info.is_abandoned { +1445 // If this path is abandoned then we might still have to send +1446 // PATH_ABANDON itself on it if there was no better space +1447 // available. Otherwise we want to send the PATH_ABANDON as permitted by +1448 // may_send_data however. +1449 scheduling_info.may_self_abandon +1450 && self.spaces[space_id] +1451 .pending +1452 .path_abandon +1453 .contains_key(&path_id) +1454 } else if can_send.close && scheduling_info.may_send_close { +1455 // This is the best path to send a CONNECTION_CLOSE on. +1456 true +1457 } else if needs_loss_probe || can_send.space_specific { +1458 // We always send a loss probe or space-specific frames if the path is +1459 // not abandoned. +1460 true +1461 } else { +1462 // Anything else we only send if we're the best path for SpaceKind::Data +1463 // frames. +1464 !can_send.is_empty() && scheduling_info.may_send_data +1465 } +1466 }; +1467 +1468 if !space_will_send { +1469 // Nothing more to send. Previous iterations of this loop may have built +1470 // packets already. +1471 return match last_packet_number { +1472 Some(pn) => PollPathSpaceStatus::WrotePacket { +1473 last_packet_number: pn, +1474 pad_datagram, +1475 }, +1476 None => { +1477 // Only log for spaces which have crypto. +1478 if self.crypto_state.has_keys(space_id.encryption_level()) +1479 || (space_id == SpaceId::Data +1480 && self.crypto_state.has_keys(EncryptionLevel::ZeroRtt)) +1481 { +1482 trace!(?space_id, %path_id, "nothing to send in space"); +1483 } +1484 PollPathSpaceStatus::NothingToSend { +1485 congestion_blocked: false, +1486 } +1487 } +1488 }; +1489 } +1490 +1491 // We want to send on this space, check congestion control if we can. But only +1492 // if we will need to start a new datagram. If we are coalescing into an already +1493 // started datagram we do not need to check congestion control again. +1494 if transmit.datagram_remaining_mut() == 0 { +1495 let congestion_blocked = +1496 self.path_congestion_check(space_id, path_id, transmit, &can_send, now); +1497 if congestion_blocked != PathBlocked::No { +1498 // Previous iterations of this loop may have built packets already. +1499 return match last_packet_number { +1500 Some(pn) => PollPathSpaceStatus::WrotePacket { +1501 last_packet_number: pn, +1502 pad_datagram, +1503 }, +1504 None => { +1505 return PollPathSpaceStatus::NothingToSend { +1506 congestion_blocked: true, +1507 }; +1508 } +1509 }; +1510 } +1511 } +1512 +1513 // If the datagram is full (or there never was one started), we need to start a +1514 // new one. +1515 if transmit.datagram_remaining_mut() == 0 { +1516 if transmit.num_datagrams() >= transmit.max_datagrams().get() { +1517 // No more datagrams allowed. +1518 // Previous iterations of this loop may have built packets already. +1519 return match last_packet_number { +1520 Some(pn) => PollPathSpaceStatus::WrotePacket { +1521 last_packet_number: pn, +1522 pad_datagram, +1523 }, +1524 None => { +1525 return PollPathSpaceStatus::NothingToSend { +1526 congestion_blocked: false, +1527 }; +1528 } +1529 }; +1530 } +1531 +1532 match self.spaces[space_id].for_path(path_id).loss_probes { +1533 0 => transmit.start_new_datagram(), +1534 _ => { +1535 // We need something to send for a tail-loss probe. +1536 let request_immediate_ack = +1537 space_id == SpaceId::Data && self.peer_supports_ack_frequency(); +1538 self.spaces[space_id].maybe_queue_probe( +1539 path_id, +1540 request_immediate_ack, +1541 &self.streams, +1542 ); +1543 +1544 self.spaces[space_id].for_path(path_id).loss_probes -= 1; +1545 +1546 // Clamp the datagram to at most the minimum MTU to ensure that loss +1547 // probes can get through and enable recovery even if the path MTU +1548 // has shrank unexpectedly. +1549 transmit.start_new_datagram_with_size(std::cmp::min( +1550 usize::from(INITIAL_MTU), +1551 transmit.segment_size(), +1552 )); +1553 } +1554 } +1555 trace!(count = transmit.num_datagrams(), "new datagram started"); 1556 -1557 let Some(mut builder) = PacketBuilder::new( -1558 now, -1559 space_id, -1560 path_id, -1561 remote_cid, -1562 transmit, -1563 can_send.is_ack_eliciting(), -1564 self, -1565 ) else { -1566 // Confidentiality limit is exceeded and the connection has been killed. We -1567 // should not send any other packets. This works in a roundabout way: We -1568 // have started a datagram but not written anything into it. So even if we -1569 // get called again for another space we will see an already started -1570 // datagram and try and start another packet here. Then be stopped by the -1571 // same confidentiality limit. -1572 return PollPathSpaceStatus::NothingToSend { -1573 congestion_blocked: false, -1574 }; -1575 }; -1576 last_packet_number = Some(builder.packet_number); -1577 -1578 if space_id == SpaceId::Initial -1579 && (self.side.is_client() || can_send.is_ack_eliciting()) -1580 { -1581 // https://www.rfc-editor.org/rfc/rfc9000.html#section-14.1 -1582 pad_datagram |= PadDatagram::ToMinMtu; -1583 } -1584 if space_id == SpaceId::Data && self.config.pad_to_mtu { -1585 pad_datagram |= PadDatagram::ToSegmentSize; -1586 } -1587 -1588 if scheduling_info.may_send_close && can_send.close { -1589 trace!("sending CONNECTION_CLOSE"); -1590 // Encode ACKs before the ConnectionClose message, to give the receiver -1591 // a better approximate on what data has been processed. This is -1592 // especially important with ack delay, since the peer might not -1593 // have gotten any other ACK for the data earlier on. -1594 let is_multipath_negotiated = self.is_multipath_negotiated(); -1595 for path_id in self.spaces[space_id] -1596 .number_spaces -1597 .iter() -1598 .filter(|(_, pns)| !pns.pending_acks.ranges().is_empty()) -1599 .map(|(&path_id, _)| path_id) -1600 .collect::<Vec<_>>() -1601 { -1602 Self::populate_acks( -1603 now, -1604 self.receiving_ecn, -1605 path_id, -1606 space_id, -1607 &mut self.spaces[space_id], -1608 is_multipath_negotiated, -1609 &mut builder, -1610 &mut self.path_stats.for_path(path_id).frame_tx, -1611 self.crypto_state.has_keys(space_id.encryption_level()), -1612 ); -1613 } -1614 -1615 // Since there only 64 ACK frames there will always be enough space -1616 // to encode the ConnectionClose frame too. However we still have the -1617 // check here to prevent crashes if something changes. -1618 -1619 // TODO(flub): This needs fixing for multipath, to ensure we can always -1620 // write the CONNECTION_CLOSE even if we have many PATH_ACKs to send: -1621 // https://github.com/n0-computer/noq/issues/367. -1622 debug_assert!( -1623 builder.frame_space_remaining() > frame::ConnectionClose::SIZE_BOUND, -1624 "ACKs should leave space for ConnectionClose" -1625 ); -1626 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -1627 if frame::ConnectionClose::SIZE_BOUND < builder.frame_space_remaining() { -1628 let max_frame_size = builder.frame_space_remaining(); -1629 let close: Close = match self.state.as_type() { -1630 StateType::Closed => { -1631 let reason: Close = -1632 self.state.as_closed().expect("checked").clone().into(); -1633 if space_id == SpaceId::Data || reason.is_transport_layer() { -1634 reason -1635 } else { -1636 TransportError::APPLICATION_ERROR("").into() -1637 } -1638 } -1639 StateType::Draining => TransportError::NO_ERROR("").into(), -1640 _ => unreachable!( -1641 "tried to make a close packet when the connection wasn't closed" -1642 ), -1643 }; -1644 builder.write_frame(close.encoder(max_frame_size), stats); -1645 } -1646 let last_pn = builder.packet_number; -1647 builder.finish_and_track(now, self, path_id, pad_datagram); -1648 if space_id.kind() == self.highest_space { -1649 // Don't send another close packet. Even with multipath we only send -1650 // CONNECTION_CLOSE on a single path since we expect our paths to work. -1651 self.connection_close_pending = false; -1652 } -1653 // Send a close frame in every possible space for robustness, per -1654 // RFC9000 "Immediate Close during the Handshake". Don't bother trying -1655 // to send anything else. -1656 // TODO(flub): This breaks during the handshake if we can not coalesce -1657 // packets due to space reasons: the next space would either fail a -1658 // debug_assert checking for enough packet space or produce an invalid -1659 // packet. We need to keep track of per-space pending CONNECTION_CLOSE to -1660 // be able to send these across multiple calls to poll_transmit. Then -1661 // check for coalescing space here because initial packets need to be in -1662 // padded datagrams. And also add space checks for CONNECTION_CLOSE in -1663 // space_can_send so it would stop a GSO batch if the datagram is too -1664 // small for another CONNECTION_CLOSE packet. -1665 return PollPathSpaceStatus::WrotePacket { -1666 last_packet_number: last_pn, -1667 pad_datagram, -1668 }; -1669 } -1670 -1671 self.populate_packet(now, space_id, path_id, scheduling_info, &mut builder); -1672 -1673 // ACK-only packets should only be sent when explicitly allowed. If we write them due to -1674 // any other reason, there is a bug which leads to one component announcing write -1675 // readiness while not writing any data. This degrades performance. The condition is -1676 // only checked if the full MTU is available and when potentially large fixed-size -1677 // frames aren't queued, so that lack of space in the datagram isn't the reason for just -1678 // writing ACKs. -1679 debug_assert!( -1680 !(builder.sent_frames().is_ack_only(&self.streams) -1681 && !can_send.acks -1682 && (can_send.other || can_send.space_specific) -1683 && builder.buf.segment_size() -1684 == self.path_data(path_id).current_mtu() as usize -1685 && self.datagrams.outgoing.is_empty()), -1686 "SendableFrames was {can_send:?}, but only ACKs have been written" -1687 ); -1688 if builder.sent_frames().requires_padding { -1689 pad_datagram |= PadDatagram::ToMinMtu; -1690 } -1691 -1692 for (path_id, _pn) in builder.sent_frames().largest_acked.iter() { -1693 self.spaces[space_id] -1694 .for_path(*path_id) -1695 .pending_acks -1696 .acks_sent(); -1697 self.timers.stop( -1698 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), -1699 self.qlog.with_time(now), -1700 ); -1701 } -1702 -1703 // Now we need to finish the packet. Before we do so we need to know if we will -1704 // be coalescing the next packet into this one, or will be ending the datagram -1705 // as well. Because if this is the last packet in the datagram more padding -1706 // might be needed because of the packet type, or to fill the GSO segment size. -1707 -1708 // Are we allowed to coalesce AND is there enough space for another *packet* in -1709 // this datagram AND will we definitely send another packet? -1710 if builder.can_coalesce && path_id == PathId::ZERO && { -1711 let max_packet_size = builder -1712 .buf -1713 .datagram_remaining_mut() -1714 .saturating_sub(builder.predict_packet_end()); -1715 max_packet_size > MIN_PACKET_SPACE -1716 && self.has_pending_packet(space_id, max_packet_size, connection_close_pending) -1717 } { -1718 // We can append/coalesce the next packet into the current -1719 // datagram. Finish the current packet without adding extra padding. -1720 trace!("will coalesce with next packet"); -1721 builder.finish_and_track(now, self, path_id, PadDatagram::No); -1722 } else { -1723 // We need a new datagram for the next packet. Finish the current -1724 // packet with padding. -1725 // TODO(flub): if there isn't any more data to be sent, this will still pad -1726 // to the segment size and only discover there is nothing to send before -1727 // starting the next packet. That is wasting up to 32 bytes. -1728 if builder.buf.num_datagrams() > 1 && matches!(pad_datagram, PadDatagram::No) { -1729 // If too many padding bytes would be required to continue the -1730 // GSO batch after this packet, end the GSO batch here. Ensures -1731 // that fixed-size frames with heterogeneous sizes -1732 // (e.g. application datagrams) won't inadvertently waste large -1733 // amounts of bandwidth. The exact threshold is a bit arbitrary -1734 // and might benefit from further tuning, though there's no -1735 // universally optimal value. -1736 const MAX_PADDING: usize = 32; -1737 if builder.buf.datagram_remaining_mut() -1738 > builder.predict_packet_end() + MAX_PADDING -1739 { -1740 trace!( -1741 "GSO truncated by demand for {} padding bytes", -1742 builder.buf.datagram_remaining_mut() - builder.predict_packet_end() -1743 ); -1744 let last_pn = builder.packet_number; -1745 builder.finish_and_track(now, self, path_id, PadDatagram::No); -1746 return PollPathSpaceStatus::Send { -1747 last_packet_number: last_pn, -1748 }; -1749 } -1750 -1751 // Pad the current datagram to GSO segment size so it can be -1752 // included in the GSO batch. -1753 builder.finish_and_track(now, self, path_id, PadDatagram::ToSegmentSize); -1754 } else { -1755 builder.finish_and_track(now, self, path_id, pad_datagram); -1756 } -1757 -1758 // If this is the first datagram we set the segment size to the size of the -1759 // first datagram. -1760 if transmit.num_datagrams() == 1 { -1761 transmit.clip_segment_size(); -1762 } -1763 } -1764 } -1765 } -1766 -1767 fn poll_transmit_mtu_probe( -1768 &mut self, -1769 now: Instant, -1770 buf: &mut Vec<u8>, -1771 path_id: PathId, -1772 ) -> Option<Transmit> { -1773 let (active_cid, probe_size) = self.get_mtu_probe_data(now, path_id)?; -1774 -1775 // We are definitely sending a DPLPMTUD probe. -1776 let mut transmit = TransmitBuf::new(buf, NonZeroUsize::MIN, probe_size as usize); -1777 transmit.start_new_datagram_with_size(probe_size as usize); -1778 -1779 let mut builder = PacketBuilder::new( -1780 now, -1781 SpaceId::Data, -1782 path_id, -1783 active_cid, -1784 &mut transmit, -1785 true, -1786 self, -1787 )?; -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); +1557 // We started a new datagram, we decide later if it needs padding. +1558 pad_datagram = PadDatagram::No; +1559 } +1560 +1561 // If coalescing another packet into the existing datagram, there should +1562 // still be enough space for a whole packet. +1563 if transmit.datagram_start_offset() < transmit.len() { +1564 debug_assert!(transmit.datagram_remaining_mut() >= MIN_PACKET_SPACE); +1565 } +1566 +1567 // +1568 // From here on, we've determined that a packet will definitely be sent. +1569 // +1570 +1571 if self.crypto_state.has_keys(EncryptionLevel::Initial) +1572 && space_id == SpaceId::Handshake +1573 && self.side.is_client() +1574 { +1575 // A client stops both sending and processing Initial packets when it +1576 // sends its first Handshake packet. +1577 self.discard_space(now, SpaceKind::Initial); +1578 } +1579 if let Some(ref mut prev) = self.crypto_state.prev_crypto { +1580 prev.update_unacked = false; +1581 } +1582 +1583 let Some(mut builder) = PacketBuilder::new( +1584 now, +1585 space_id, +1586 path_id, +1587 remote_cid, +1588 transmit, +1589 can_send.is_ack_eliciting(), +1590 self, +1591 ) else { +1592 // Confidentiality limit is exceeded and the connection has been killed. We +1593 // should not send any other packets. This works in a roundabout way: We +1594 // have started a datagram but not written anything into it. So even if we +1595 // get called again for another space we will see an already started +1596 // datagram and try and start another packet here. Then be stopped by the +1597 // same confidentiality limit. +1598 return PollPathSpaceStatus::NothingToSend { +1599 congestion_blocked: false, +1600 }; +1601 }; +1602 last_packet_number = Some(builder.packet_number); +1603 +1604 if space_id == SpaceId::Initial +1605 && (self.side.is_client() || can_send.is_ack_eliciting()) +1606 { +1607 // https://www.rfc-editor.org/rfc/rfc9000.html#section-14.1 +1608 pad_datagram |= PadDatagram::ToMinMtu; +1609 } +1610 if space_id == SpaceId::Data && self.config.pad_to_mtu { +1611 pad_datagram |= PadDatagram::ToSegmentSize; +1612 } +1613 +1614 if scheduling_info.may_send_close && can_send.close { +1615 trace!("sending CONNECTION_CLOSE"); +1616 // Encode ACKs before the ConnectionClose message, to give the receiver +1617 // a better approximate on what data has been processed. This is +1618 // especially important with ack delay, since the peer might not +1619 // have gotten any other ACK for the data earlier on. +1620 let is_multipath_negotiated = self.is_multipath_negotiated(); +1621 for path_id in self.spaces[space_id] +1622 .number_spaces +1623 .iter() +1624 .filter(|(_, pns)| !pns.pending_acks.ranges().is_empty()) +1625 .map(|(&path_id, _)| path_id) +1626 .collect::<Vec<_>>() +1627 { +1628 Self::populate_acks( +1629 now, +1630 self.receiving_ecn, +1631 path_id, +1632 space_id, +1633 &mut self.spaces[space_id], +1634 is_multipath_negotiated, +1635 &mut builder, +1636 &mut self.path_stats.for_path(path_id).frame_tx, +1637 self.crypto_state.has_keys(space_id.encryption_level()), +1638 ); +1639 } +1640 +1641 // Since there only 64 ACK frames there will always be enough space +1642 // to encode the ConnectionClose frame too. However we still have the +1643 // check here to prevent crashes if something changes. +1644 +1645 // TODO(flub): This needs fixing for multipath, to ensure we can always +1646 // write the CONNECTION_CLOSE even if we have many PATH_ACKs to send: +1647 // https://github.com/n0-computer/noq/issues/367. +1648 debug_assert!( +1649 builder.frame_space_remaining() > frame::ConnectionClose::SIZE_BOUND, +1650 "ACKs should leave space for ConnectionClose" +1651 ); +1652 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +1653 if frame::ConnectionClose::SIZE_BOUND < builder.frame_space_remaining() { +1654 let max_frame_size = builder.frame_space_remaining(); +1655 let close: Close = match self.state.as_type() { +1656 StateType::Closed => { +1657 let reason: Close = +1658 self.state.as_closed().expect("checked").clone().into(); +1659 if space_id == SpaceId::Data || reason.is_transport_layer() { +1660 reason +1661 } else { +1662 TransportError::APPLICATION_ERROR("").into() +1663 } +1664 } +1665 StateType::Draining => TransportError::NO_ERROR("").into(), +1666 _ => unreachable!( +1667 "tried to make a close packet when the connection wasn't closed" +1668 ), +1669 }; +1670 builder.write_frame(close.encoder(max_frame_size), stats); +1671 } +1672 let last_pn = builder.packet_number; +1673 builder.finish_and_track(now, self, path_id, pad_datagram); +1674 if space_id.kind() == self.highest_space { +1675 // Don't send another close packet. Even with multipath we only send +1676 // CONNECTION_CLOSE on a single path since we expect our paths to work. +1677 self.connection_close_pending = false; +1678 } +1679 // Send a close frame in every possible space for robustness, per +1680 // RFC9000 "Immediate Close during the Handshake". Don't bother trying +1681 // to send anything else. +1682 // TODO(flub): This breaks during the handshake if we can not coalesce +1683 // packets due to space reasons: the next space would either fail a +1684 // debug_assert checking for enough packet space or produce an invalid +1685 // packet. We need to keep track of per-space pending CONNECTION_CLOSE to +1686 // be able to send these across multiple calls to poll_transmit. Then +1687 // check for coalescing space here because initial packets need to be in +1688 // padded datagrams. And also add space checks for CONNECTION_CLOSE in +1689 // space_can_send so it would stop a GSO batch if the datagram is too +1690 // small for another CONNECTION_CLOSE packet. +1691 return PollPathSpaceStatus::WrotePacket { +1692 last_packet_number: last_pn, +1693 pad_datagram, +1694 }; +1695 } +1696 +1697 self.populate_packet(now, space_id, path_id, scheduling_info, &mut builder); +1698 +1699 // ACK-only packets should only be sent when explicitly allowed. If we write them due to +1700 // any other reason, there is a bug which leads to one component announcing write +1701 // readiness while not writing any data. This degrades performance. The condition is +1702 // only checked if the full MTU is available and when potentially large fixed-size +1703 // frames aren't queued, so that lack of space in the datagram isn't the reason for just +1704 // writing ACKs. +1705 debug_assert!( +1706 !(builder.sent_frames().is_ack_only(&self.streams) +1707 && !can_send.acks +1708 && (can_send.other || can_send.space_specific) +1709 && builder.buf.segment_size() +1710 == self.path_data(path_id).current_mtu() as usize +1711 && self.datagrams.outgoing.is_empty()), +1712 "SendableFrames was {can_send:?}, but only ACKs have been written" +1713 ); +1714 if builder.sent_frames().requires_padding { +1715 pad_datagram |= PadDatagram::ToMinMtu; +1716 } +1717 +1718 for (path_id, _pn) in builder.sent_frames().largest_acked.iter() { +1719 self.spaces[space_id] +1720 .for_path(*path_id) +1721 .pending_acks +1722 .acks_sent(); +1723 self.timers.stop( +1724 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), +1725 self.qlog.with_time(now), +1726 ); +1727 } +1728 +1729 // Now we need to finish the packet. Before we do so we need to know if we will +1730 // be coalescing the next packet into this one, or will be ending the datagram +1731 // as well. Because if this is the last packet in the datagram more padding +1732 // might be needed because of the packet type, or to fill the GSO segment size. +1733 +1734 // Are we allowed to coalesce AND is there enough space for another *packet* in +1735 // this datagram AND will we definitely send another packet? +1736 if builder.can_coalesce && path_id == PathId::ZERO && { +1737 let max_packet_size = builder +1738 .buf +1739 .datagram_remaining_mut() +1740 .saturating_sub(builder.predict_packet_end()); +1741 max_packet_size > MIN_PACKET_SPACE +1742 && self.has_pending_packet(space_id, max_packet_size, connection_close_pending) +1743 } { +1744 // We can append/coalesce the next packet into the current +1745 // datagram. Finish the current packet without adding extra padding. +1746 trace!("will coalesce with next packet"); +1747 builder.finish_and_track(now, self, path_id, PadDatagram::No); +1748 } else { +1749 // We need a new datagram for the next packet. Finish the current +1750 // packet with padding. +1751 // TODO(flub): if there isn't any more data to be sent, this will still pad +1752 // to the segment size and only discover there is nothing to send before +1753 // starting the next packet. That is wasting up to 32 bytes. +1754 if builder.buf.num_datagrams() > 1 && matches!(pad_datagram, PadDatagram::No) { +1755 // If too many padding bytes would be required to continue the +1756 // GSO batch after this packet, end the GSO batch here. Ensures +1757 // that fixed-size frames with heterogeneous sizes +1758 // (e.g. application datagrams) won't inadvertently waste large +1759 // amounts of bandwidth. The exact threshold is a bit arbitrary +1760 // and might benefit from further tuning, though there's no +1761 // universally optimal value. +1762 const MAX_PADDING: usize = 32; +1763 if builder.buf.datagram_remaining_mut() +1764 > builder.predict_packet_end() + MAX_PADDING +1765 { +1766 trace!( +1767 "GSO truncated by demand for {} padding bytes", +1768 builder.buf.datagram_remaining_mut() - builder.predict_packet_end() +1769 ); +1770 let last_pn = builder.packet_number; +1771 builder.finish_and_track(now, self, path_id, PadDatagram::No); +1772 return PollPathSpaceStatus::Send { +1773 last_packet_number: last_pn, +1774 }; +1775 } +1776 +1777 // Pad the current datagram to GSO segment size so it can be +1778 // included in the GSO batch. +1779 builder.finish_and_track(now, self, path_id, PadDatagram::ToSegmentSize); +1780 } else { +1781 builder.finish_and_track(now, self, path_id, pad_datagram); +1782 } +1783 +1784 // If this is the first datagram we set the segment size to the size of the +1785 // first datagram. +1786 if transmit.num_datagrams() == 1 { +1787 transmit.clip_segment_size(); +1788 } +1789 } +1790 } +1791 } 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 } +1793 fn poll_transmit_mtu_probe( +1794 &mut self, +1795 now: Instant, +1796 buf: &mut Vec<u8>, +1797 path_id: PathId, +1798 ) -> Option<Transmit> { +1799 let (active_cid, probe_size) = self.get_mtu_probe_data(now, path_id)?; 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; +1801 // We are definitely sending a DPLPMTUD probe. +1802 let mut transmit = TransmitBuf::new(buf, NonZeroUsize::MIN, probe_size as usize); +1803 transmit.start_new_datagram_with_size(probe_size as usize); 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. -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( +1805 let mut builder = PacketBuilder::new( +1806 now, +1807 SpaceId::Data, +1808 path_id, +1809 active_cid, +1810 &mut transmit, +1811 true, +1812 self, +1813 )?; +1814 +1815 // We implement MTU probes as ping packets padded up to the probe size +1816 trace!(?probe_size, "writing MTUD probe"); +1817 builder.write_frame(frame::Ping, &mut self.path_stats.for_path(path_id).frame_tx); +1818 +1819 // If supported by the peer, we want no delays to the probe's ACK +1820 if self.peer_supports_ack_frequency() { +1821 builder.write_frame( +1822 frame::ImmediateAck, +1823 &mut self.path_stats.for_path(path_id).frame_tx, +1824 ); +1825 } +1826 +1827 builder.finish_and_track(now, self, path_id, PadDatagram::ToSize(probe_size)); +1828 +1829 self.path_stats.for_path(path_id).sent_plpmtud_probes += 1; +1830 +1831 Some(self.build_transmit(path_id, transmit)) +1832 } +1833 +1834 /// Returns the CID and probe size if a DPLPMTUD probe is needed. +1835 /// +1836 /// We MTU probe all paths for which all of the following is true: +1837 /// - We have an active destination CID for the path. +1838 /// - The remote address *and* path are validated. +1839 /// - The path is not abandoned. +1840 /// - The MTU Discovery subsystem wants to probe the path. +1841 fn get_mtu_probe_data(&mut self, now: Instant, path_id: PathId) -> Option<(ConnectionId, u16)> { +1842 let active_cid = self.remote_cids.get(&path_id).map(CidQueue::active)?; +1843 let is_eligible = self.path_data(path_id).validated +1844 && !self.path_data(path_id).is_validating_path() +1845 && !self.abandoned_paths.contains(&path_id); +1846 +1847 if !is_eligible { +1848 return None; +1849 } +1850 let next_pn = self.spaces[SpaceId::Data] +1851 .for_path(path_id) +1852 .peek_tx_number(); +1853 let probe_size = self +1854 .path_data_mut(path_id) +1855 .mtud +1856 .poll_transmit(now, next_pn)?; +1857 +1858 Some((active_cid, probe_size)) +1859 } +1860 +1861 /// Returns true if there is a further packet to send on [`PathId::ZERO`]. +1862 /// +1863 /// In other words this is predicting whether the next call to +1864 /// [`Connection::space_can_send`] issued will return some frames to be sent. Including +1865 /// having to predict which packet number space it will be invoked with. This depends on +1866 /// how both [`Connection::poll_transmit_on_path`] and +1867 /// [`Connection::poll_transmit_path_space`] behave. +1868 /// +1869 /// This is needed to determine if packet coalescing can happen. Because the last packet +1870 /// in a datagram may need to be padded and thus we must know if another packet will +1871 /// follow or not. +1872 /// +1873 /// The next packet can be either in the same space, or in one of the following spaces +1874 /// on the same path. Because a 0-RTT packet can be coalesced with a 1-RTT packet and +1875 /// both are in the Data(PathId::ZERO) space. Previous spaces are not checked, because +1876 /// packets are built from Initial to Handshake to Data spaces. +1877 fn has_pending_packet( 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 self.timers.set( -1921 Timer::PerPath(path_id, PathTimer::Pacing), -1922 delay, -1923 self.qlog.with_time(now), -1924 ); -1925 // Loss probes and CONNECTION_CLOSE should be subject to pacing, even though -1926 // they are not congestion controlled. -1927 trace!(?space_id, %path_id, "blocked by pacing"); -1928 return PathBlocked::Pacing; -1929 } -1930 -1931 PathBlocked::No -1932 } -1933 -1934 /// Send PATH_CHALLENGE for a previous path if necessary -1935 /// -1936 /// QUIC-TRANSPORT section 9.3.3 -1937 /// <https://www.rfc-editor.org/rfc/rfc9000.html#name-off-path-packet-forwarding> -1938 fn send_prev_path_challenge( -1939 &mut self, -1940 now: Instant, -1941 buf: &mut Vec<u8>, -1942 path_id: PathId, -1943 ) -> Option<Transmit> { -1944 let (prev_cid, prev_path) = self.paths.get_mut(&path_id)?.prev.as_mut()?; -1945 // TODO (matheus23): We could use !prev_path.is_validating() here instead to -1946 // (possibly) also re-send challenges when they get lost. -1947 if !prev_path.pending_on_path_challenge { -1948 return None; -1949 }; -1950 prev_path.pending_on_path_challenge = false; -1951 let token = self.rng.random(); -1952 let network_path = prev_path.network_path; -1953 prev_path.record_path_challenge_sent(now, token, network_path); -1954 -1955 debug_assert_eq!( -1956 self.highest_space, -1957 SpaceKind::Data, -1958 "PATH_CHALLENGE queued without 1-RTT keys" -1959 ); -1960 let buf = &mut TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); -1961 buf.start_new_datagram(); -1962 -1963 // Use the previous CID to avoid linking the new path with the previous path. We -1964 // don't bother accounting for possible retirement of that prev_cid because this is -1965 // sent once, immediately after migration, when the CID is known to be valid. Even -1966 // if a post-migration packet caused the CID to be retired, it's fair to pretend -1967 // this is sent first. -1968 let mut builder = -1969 PacketBuilder::new(now, SpaceId::Data, path_id, *prev_cid, buf, false, 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); -1979 -1980 builder.finish(self, now); -1981 self.path_stats -1982 .for_path(path_id) -1983 .udp_tx -1984 .on_sent(1, buf.len()); -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 -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, false, 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 server_side = self.n0_nat_traversal.server_side_mut().ok()?; -2047 let probe = server_side.next_probe()?; -2048 if !self.paths.get(&path_id)?.data.validated { -2049 // Path is not usable for probing -2050 return None; -2051 } -2052 -2053 let remote_cids = self.remote_cids.get_mut(&path_id)?; -2054 -2055 // Check if this path has enough CIDs to send a probe. One to be reserved, one in case the -2056 // active CID needs to be retired. -2057 if remote_cids.remaining() < 2 { -2058 return None; -2059 } -2060 -2061 let cid = remote_cids.next_reserved()?; -2062 let remote = probe.remote(); -2063 let token = self.rng.random(); -2064 probe.mark_as_sent(); -2065 -2066 let frame = frame::PathChallenge(token); -2067 -2068 let mut buf = TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); -2069 buf.start_new_datagram(); -2070 -2071 let mut builder = -2072 PacketBuilder::new(now, SpaceId::Data, path_id, cid, &mut buf, false, self)?; -2073 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -2074 builder.write_frame_with_log_msg(frame, stats, Some("(nat-traversal)")); -2075 // Off-path: not tracked in congestion control. The packet is sent to a -2076 // different destination than path_id's network path. -2077 builder.pad_to(MIN_INITIAL_SIZE); -2078 builder.finish(self, now); -2079 -2080 let path = &mut self.paths.get_mut(&path_id).expect("checked").data; -2081 let network_path = FourTuple { -2082 remote, -2083 local_ip: None, -2084 }; -2085 -2086 path.record_path_challenge_sent(now, token, network_path); -2087 -2088 let size = buf.len(); -2089 -2090 self.path_stats.for_path(path_id).udp_tx.on_sent(1, size); +1879 current_space_id: SpaceId, +1880 max_packet_size: usize, +1881 connection_close_pending: bool, +1882 ) -> bool { +1883 let mut space_id = current_space_id; +1884 loop { +1885 let can_send = self.space_can_send( +1886 space_id, +1887 PathId::ZERO, +1888 max_packet_size, +1889 connection_close_pending, +1890 ); +1891 if !can_send.is_empty() { +1892 return true; +1893 } +1894 match space_id.next() { +1895 Some(next_space_id) => space_id = next_space_id, +1896 None => break, +1897 } +1898 } +1899 false +1900 } +1901 +1902 /// Checks if creating a new datagram would be blocked by congestion control +1903 fn path_congestion_check( +1904 &mut self, +1905 space_id: SpaceId, +1906 path_id: PathId, +1907 transmit: &TransmitBuf<'_>, +1908 can_send: &SendableFrames, +1909 now: Instant, +1910 ) -> PathBlocked { +1911 // Anti-amplification is only based on `total_sent`, which gets updated after +1912 // the transmit is sent. Therefore we pass the amount of bytes for datagrams +1913 // that are already created, as well as 1 byte for starting another datagram. If +1914 // there is any anti-amplification budget left, we always allow a full MTU to be +1915 // sent (see https://github.com/quinn-rs/quinn/issues/1082). +1916 if self.side().is_server() +1917 && self +1918 .path_data(path_id) +1919 .anti_amplification_blocked(transmit.len() as u64 + 1) +1920 { +1921 trace!(?space_id, %path_id, "blocked by anti-amplification"); +1922 return PathBlocked::AntiAmplification; +1923 } +1924 +1925 // Congestion control check. +1926 // Tail loss probes must not be blocked by congestion, or a deadlock could arise. +1927 let bytes_to_send = transmit.segment_size() as u64; +1928 let need_loss_probe = self.spaces[space_id].for_path(path_id).loss_probes > 0; +1929 +1930 if can_send.other && !need_loss_probe && !can_send.close { +1931 let path = self.path_data(path_id); +1932 if path.in_flight.bytes + bytes_to_send >= path.congestion.window() { +1933 trace!( +1934 ?space_id, +1935 %path_id, +1936 in_flight=%path.in_flight.bytes, +1937 congestion_window=%path.congestion.window(), +1938 "blocked by congestion control", +1939 ); +1940 return PathBlocked::Congestion; +1941 } +1942 } +1943 +1944 // Pacing check. +1945 if let Some(delay) = self.path_data_mut(path_id).pacing_delay(bytes_to_send, now) { +1946 self.timers.set( +1947 Timer::PerPath(path_id, PathTimer::Pacing), +1948 delay, +1949 self.qlog.with_time(now), +1950 ); +1951 // Loss probes and CONNECTION_CLOSE should be subject to pacing, even though +1952 // they are not congestion controlled. +1953 trace!(?space_id, %path_id, "blocked by pacing"); +1954 return PathBlocked::Pacing; +1955 } +1956 +1957 PathBlocked::No +1958 } +1959 +1960 /// Send PATH_CHALLENGE for a previous path if necessary +1961 /// +1962 /// QUIC-TRANSPORT section 9.3.3 +1963 /// <https://www.rfc-editor.org/rfc/rfc9000.html#name-off-path-packet-forwarding> +1964 fn send_prev_path_challenge( +1965 &mut self, +1966 now: Instant, +1967 buf: &mut Vec<u8>, +1968 path_id: PathId, +1969 ) -> Option<Transmit> { +1970 let (prev_cid, prev_path) = self.paths.get_mut(&path_id)?.prev.as_mut()?; +1971 // TODO (matheus23): We could use !prev_path.is_validating() here instead to +1972 // (possibly) also re-send challenges when they get lost. +1973 if !prev_path.pending_on_path_challenge { +1974 return None; +1975 }; +1976 prev_path.pending_on_path_challenge = false; +1977 let token = self.rng.random(); +1978 let network_path = prev_path.network_path; +1979 prev_path.record_path_challenge_sent(now, token, network_path); +1980 +1981 debug_assert_eq!( +1982 self.highest_space, +1983 SpaceKind::Data, +1984 "PATH_CHALLENGE queued without 1-RTT keys" +1985 ); +1986 let buf = &mut TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); +1987 buf.start_new_datagram(); +1988 +1989 // Use the previous CID to avoid linking the new path with the previous path. We +1990 // don't bother accounting for possible retirement of that prev_cid because this is +1991 // sent once, immediately after migration, when the CID is known to be valid. Even +1992 // if a post-migration packet caused the CID to be retired, it's fair to pretend +1993 // this is sent first. +1994 let mut builder = +1995 PacketBuilder::new(now, SpaceId::Data, path_id, *prev_cid, buf, false, self)?; +1996 let challenge = frame::PathChallenge(token); +1997 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +1998 builder.write_frame_with_log_msg(challenge, stats, Some("validating previous path")); +1999 +2000 // An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame +2001 // to at least the smallest allowed maximum datagram size of 1200 bytes, +2002 // unless the anti-amplification limit for the path does not permit +2003 // sending a datagram of this size +2004 builder.pad_to(MIN_INITIAL_SIZE); +2005 +2006 builder.finish(self, now); +2007 self.path_stats +2008 .for_path(path_id) +2009 .udp_tx +2010 .on_sent(1, buf.len()); +2011 +2012 Some(Transmit { +2013 destination: network_path.remote, +2014 size: buf.len(), +2015 ecn: None, +2016 segment_size: None, +2017 src_ip: network_path.local_ip, +2018 }) +2019 } +2020 +2021 fn send_off_path_path_response( +2022 &mut self, +2023 now: Instant, +2024 buf: &mut Vec<u8>, +2025 path_id: PathId, +2026 ) -> Option<Transmit> { +2027 let path = self.paths.get_mut(&path_id).map(|state| &mut state.data)?; +2028 let cid_queue = self.remote_cids.get_mut(&path_id)?; +2029 let (token, network_path) = path.path_responses.pop_off_path(path.network_path)?; +2030 +2031 let cid = cid_queue +2032 .next_reserved() +2033 .unwrap_or_else(|| cid_queue.active()); +2034 // TODO(@divma): we should take a different approach when there is no fresh CID to use. +2035 // https://github.com/quinn-rs/quinn/issues/2184 +2036 +2037 let frame = frame::PathResponse(token); +2038 +2039 let buf = &mut TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); +2040 buf.start_new_datagram(); +2041 +2042 let mut builder = PacketBuilder::new(now, SpaceId::Data, path_id, cid, buf, false, self)?; +2043 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +2044 builder.write_frame_with_log_msg(frame, stats, Some("(off-path)")); +2045 // Off-path: not tracked in congestion control. The packet is sent to a +2046 // different destination than path_id's network path. +2047 builder.pad_to(MIN_INITIAL_SIZE); +2048 builder.finish(self, now); +2049 +2050 let size = buf.len(); +2051 +2052 self.path_stats.for_path(path_id).udp_tx.on_sent(1, size); +2053 Some(Transmit { +2054 destination: network_path.remote, +2055 size, +2056 ecn: None, +2057 segment_size: None, +2058 src_ip: network_path.local_ip, +2059 }) +2060 } +2061 +2062 /// Send a nat traversal challenge (off-path) on this path if possible. +2063 /// +2064 /// This will ensure the path still has a remaining CID to use if the active one should be +2065 /// retired. +2066 fn send_nat_traversal_path_challenge( +2067 &mut self, +2068 now: Instant, +2069 buf: &mut Vec<u8>, +2070 path_id: PathId, +2071 ) -> Option<Transmit> { +2072 let server_side = self.n0_nat_traversal.server_side_mut().ok()?; +2073 let probe = server_side.next_probe()?; +2074 if !self.paths.get(&path_id)?.data.validated { +2075 // Path is not usable for probing +2076 return None; +2077 } +2078 +2079 let remote_cids = self.remote_cids.get_mut(&path_id)?; +2080 +2081 // Check if this path has enough CIDs to send a probe. One to be reserved, one in case the +2082 // active CID needs to be retired. +2083 if remote_cids.remaining() < 2 { +2084 return None; +2085 } +2086 +2087 let cid = remote_cids.next_reserved()?; +2088 let remote = probe.remote(); +2089 let token = self.rng.random(); +2090 probe.mark_as_sent(); 2091 -2092 Some(Transmit { -2093 destination: remote, -2094 size, -2095 ecn: None, -2096 segment_size: None, -2097 src_ip: None, -2098 }) -2099 } -2100 -2101 /// Indicate what types of frames are ready to send for the given space. -2102 /// -2103 /// Only for on-path data. -2104 /// -2105 /// *packet_size* is the number of bytes available to build the next packet. -2106 /// *connection_close_pending* indicates whether a CONNECTION_CLOSE frame needs to be -2107 /// sent. -2108 fn space_can_send( -2109 &mut self, -2110 space_id: SpaceId, -2111 path_id: PathId, -2112 packet_size: usize, -2113 connection_close_pending: bool, -2114 ) -> SendableFrames { -2115 let space = &mut self.spaces[space_id]; -2116 let space_has_crypto = self.crypto_state.has_keys(space_id.encryption_level()); +2092 let frame = frame::PathChallenge(token); +2093 +2094 let mut buf = TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); +2095 buf.start_new_datagram(); +2096 +2097 let mut builder = +2098 PacketBuilder::new(now, SpaceId::Data, path_id, cid, &mut buf, false, self)?; +2099 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +2100 builder.write_frame_with_log_msg(frame, stats, Some("(nat-traversal)")); +2101 // Off-path: not tracked in congestion control. The packet is sent to a +2102 // different destination than path_id's network path. +2103 builder.pad_to(MIN_INITIAL_SIZE); +2104 builder.finish(self, now); +2105 +2106 let path = &mut self.paths.get_mut(&path_id).expect("checked").data; +2107 let network_path = FourTuple { +2108 remote, +2109 local_ip: None, +2110 }; +2111 +2112 path.record_path_challenge_sent(now, token, network_path); +2113 +2114 let size = buf.len(); +2115 +2116 self.path_stats.for_path(path_id).udp_tx.on_sent(1, size); 2117 -2118 if !space_has_crypto -2119 && (space_id != SpaceId::Data -2120 || !self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) -2121 || self.side.is_server()) -2122 { -2123 // Nothing to send in this space -2124 return SendableFrames::empty(); -2125 } +2118 Some(Transmit { +2119 destination: remote, +2120 size, +2121 ecn: None, +2122 segment_size: None, +2123 src_ip: None, +2124 }) +2125 } 2126 -2127 let mut can_send = space.can_send(path_id, &self.streams); -2128 -2129 // Check for 1RTT space. -2130 if space_id == SpaceId::Data { -2131 let pn = space.for_path(path_id).peek_tx_number(); -2132 // Number of bytes available for frames if this is a 1-RTT packet. We're -2133 // guaranteed to be able to send an individual frame at least this large in the -2134 // next 1-RTT packet. This could be generalized to support every space, but it's -2135 // only needed to handle large fixed-size frames, which only exist in 1-RTT -2136 // (application datagrams). -2137 let frame_space_1rtt = -2138 packet_size.saturating_sub(self.predict_1rtt_overhead(pn, path_id)); -2139 can_send |= self.can_send_1rtt(path_id, frame_space_1rtt); -2140 } -2141 -2142 can_send.close = connection_close_pending && space_has_crypto; +2127 /// Indicate what types of frames are ready to send for the given space. +2128 /// +2129 /// Only for on-path data. +2130 /// +2131 /// *packet_size* is the number of bytes available to build the next packet. +2132 /// *connection_close_pending* indicates whether a CONNECTION_CLOSE frame needs to be +2133 /// sent. +2134 fn space_can_send( +2135 &mut self, +2136 space_id: SpaceId, +2137 path_id: PathId, +2138 packet_size: usize, +2139 connection_close_pending: bool, +2140 ) -> SendableFrames { +2141 let space = &mut self.spaces[space_id]; +2142 let space_has_crypto = self.crypto_state.has_keys(space_id.encryption_level()); 2143 -2144 can_send -2145 } -2146 -2147 /// Process `ConnectionEvent`s generated by the associated `Endpoint` -2148 /// -2149 /// Will execute protocol logic upon receipt of a connection event, in turn preparing signals -2150 /// (including application `Event`s, `EndpointEvent`s and outgoing datagrams) that should be -2151 /// extracted through the relevant methods. -2152 pub fn handle_event(&mut self, event: ConnectionEvent) { -2153 use ConnectionEventInner::*; -2154 match event.0 { -2155 Datagram(DatagramConnectionEvent { -2156 now, -2157 network_path, -2158 path_id, -2159 ecn, -2160 first_decode, -2161 remaining, -2162 }) => { -2163 let span = trace_span!("pkt", %path_id); -2164 let _guard = span.enter(); -2165 -2166 if self.update_network_path_or_discard(network_path, path_id) { -2167 // A return value of true indicates we should discard this packet. -2168 return; -2169 } -2170 -2171 let was_anti_amplification_blocked = self -2172 .path(path_id) -2173 .map(|path| path.anti_amplification_blocked(1)) -2174 // We never tried to send on an non-existing (new) path so have not been -2175 // anti-amplification blocked for it previously. -2176 .unwrap_or(false); -2177 -2178 let rx = &mut self.path_stats.for_path(path_id).udp_rx; -2179 rx.datagrams += 1; -2180 rx.bytes += first_decode.len() as u64; -2181 let data_len = first_decode.len(); -2182 -2183 self.handle_decode(now, network_path, path_id, ecn, first_decode); -2184 // The current `path` might have changed inside `handle_decode` since the packet -2185 // could have triggered a migration. The packet might also belong to an unknown -2186 // path and have been rejected. Make sure the data received is accounted for the -2187 // most recent path by accessing `path` after `handle_decode`. -2188 if let Some(path) = self.path_mut(path_id) { -2189 path.inc_total_recvd(data_len as u64); -2190 } +2144 if !space_has_crypto +2145 && (space_id != SpaceId::Data +2146 || !self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) +2147 || self.side.is_server()) +2148 { +2149 // Nothing to send in this space +2150 return SendableFrames::empty(); +2151 } +2152 +2153 let mut can_send = space.can_send(path_id, &self.streams); +2154 +2155 // Check for 1RTT space. +2156 if space_id == SpaceId::Data { +2157 let pn = space.for_path(path_id).peek_tx_number(); +2158 // Number of bytes available for frames if this is a 1-RTT packet. We're +2159 // guaranteed to be able to send an individual frame at least this large in the +2160 // next 1-RTT packet. This could be generalized to support every space, but it's +2161 // only needed to handle large fixed-size frames, which only exist in 1-RTT +2162 // (application datagrams). +2163 let frame_space_1rtt = +2164 packet_size.saturating_sub(self.predict_1rtt_overhead(pn, path_id)); +2165 can_send |= self.can_send_1rtt(path_id, frame_space_1rtt); +2166 } +2167 +2168 can_send.close = connection_close_pending && space_has_crypto; +2169 +2170 can_send +2171 } +2172 +2173 /// Process `ConnectionEvent`s generated by the associated `Endpoint` +2174 /// +2175 /// Will execute protocol logic upon receipt of a connection event, in turn preparing signals +2176 /// (including application `Event`s, `EndpointEvent`s and outgoing datagrams) that should be +2177 /// extracted through the relevant methods. +2178 pub fn handle_event(&mut self, event: ConnectionEvent) { +2179 use ConnectionEventInner::*; +2180 match event.0 { +2181 Datagram(DatagramConnectionEvent { +2182 now, +2183 network_path, +2184 path_id, +2185 ecn, +2186 first_decode, +2187 remaining, +2188 }) => { +2189 let span = trace_span!("pkt", %path_id); +2190 let _guard = span.enter(); 2191 -2192 if let Some(data) = remaining { -2193 self.path_stats.for_path(path_id).udp_rx.bytes += data.len() as u64; -2194 self.handle_coalesced(now, network_path, path_id, ecn, data); +2192 if self.update_network_path_or_discard(network_path, path_id) { +2193 // A return value of true indicates we should discard this packet. +2194 return; 2195 } 2196 -2197 if let Some(path) = self.paths.get_mut(&path_id) { -2198 self.qlog -2199 .emit_recovery_metrics(path_id, &mut path.data, now); -2200 } -2201 -2202 if was_anti_amplification_blocked { -2203 // A prior attempt to set the loss detection timer may have failed due to -2204 // anti-amplification, so ensure it's set now. Prevents a handshake deadlock if -2205 // the server's first flight is lost. -2206 self.set_loss_detection_timer(now, path_id); -2207 } -2208 } -2209 NewIdentifiers(ids, now, cid_len, cid_lifetime) => { -2210 let path_id = ids.first().map(|issued| issued.path_id).unwrap_or_default(); -2211 debug_assert!(ids.iter().all(|issued| issued.path_id == path_id)); -2212 let cid_state = self -2213 .local_cid_state -2214 .entry(path_id) -2215 .or_insert_with(|| CidState::new(cid_len, cid_lifetime, now, 0)); -2216 cid_state.new_cids(&ids, now); +2197 let was_anti_amplification_blocked = self +2198 .path(path_id) +2199 .map(|path| path.anti_amplification_blocked(1)) +2200 // We never tried to send on an non-existing (new) path so have not been +2201 // anti-amplification blocked for it previously. +2202 .unwrap_or(false); +2203 +2204 let rx = &mut self.path_stats.for_path(path_id).udp_rx; +2205 rx.datagrams += 1; +2206 rx.bytes += first_decode.len() as u64; +2207 let data_len = first_decode.len(); +2208 +2209 self.handle_decode(now, network_path, path_id, ecn, first_decode); +2210 // The current `path` might have changed inside `handle_decode` since the packet +2211 // could have triggered a migration. The packet might also belong to an unknown +2212 // path and have been rejected. Make sure the data received is accounted for the +2213 // most recent path by accessing `path` after `handle_decode`. +2214 if let Some(path) = self.path_mut(path_id) { +2215 path.inc_total_recvd(data_len as u64); +2216 } 2217 -2218 ids.into_iter().rev().for_each(|frame| { -2219 self.spaces[SpaceId::Data].pending.new_cids.push(frame); -2220 }); -2221 // Always update Timer::PushNewCid -2222 self.reset_cid_retirement(now); -2223 } -2224 } -2225 } -2226 -2227 /// Updates the network path for `path_id`. -2228 /// -2229 /// Returns true if a packet coming in for this `path_id` over given `network_path` should be discarded. -2230 /// Returns false if the path was updated and the packet doesn't need to be discarded. -2231 fn update_network_path_or_discard(&mut self, network_path: FourTuple, path_id: PathId) -> bool { -2232 let remote_may_migrate = self.side.remote_may_migrate(&self.state); -2233 let local_ip_may_migrate = self.side.is_client(); -2234 // If this packet could initiate a migration and we're a client or a server that -2235 // forbids migration, drop the datagram. This could be relaxed to heuristically -2236 // permit NAT-rebinding-like migration. -2237 if let Some(known_path) = self.path_mut(path_id) { -2238 if network_path.remote != known_path.network_path.remote && !remote_may_migrate { -2239 trace!( -2240 %path_id, -2241 %network_path, -2242 %known_path.network_path, -2243 "discarding packet from unrecognized peer" -2244 ); -2245 return true; -2246 } -2247 -2248 if known_path.network_path.local_ip.is_some() -2249 && network_path.local_ip.is_some() -2250 && known_path.network_path.local_ip != network_path.local_ip -2251 && !local_ip_may_migrate -2252 { -2253 trace!( -2254 %path_id, -2255 %network_path, -2256 %known_path.network_path, -2257 "discarding packet sent to incorrect interface" -2258 ); -2259 return true; -2260 } -2261 // If the datagram indicates that we've changed our local IP, we update it. -2262 // This is alluded to in Section 5.2 of the Multipath RFC draft 18: -2263 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-18.html#name-using-multiple-paths-on-the -2264 // > Client receives the packet, recognizes a path migration, updates the source address of path 2 to 192.0.2.1. -2265 if let Some(local_ip) = network_path.local_ip { -2266 if known_path -2267 .network_path -2268 .local_ip -2269 .is_some_and(|ip| ip != local_ip) -2270 { -2271 debug!( -2272 %path_id, -2273 %network_path, -2274 %known_path.network_path, -2275 "path's local address seemingly migrated" -2276 ); -2277 } -2278 // We update the address without path validation on the client side. -2279 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-18.html#section-5.1 -2280 // > Servers observing a 4-tuple change will perform path validation (see Section 9 of [QUIC-TRANSPORT]). -2281 // This sounds like it's *only* the server endpoints that do this. -2282 // TODO(matheus23): We should still consider doing a proper migration on the client side in the future. -2283 // For now, this preserves the behavior of this code pre 4-tuple tracking. -2284 known_path.network_path.local_ip = Some(local_ip); -2285 } -2286 } -2287 false -2288 } -2289 -2290 /// Process timer expirations -2291 /// -2292 /// Executes protocol logic, potentially preparing signals (including application `Event`s, -2293 /// `EndpointEvent`s and outgoing datagrams) that should be extracted through the relevant -2294 /// methods. -2295 /// -2296 /// It is most efficient to call this immediately after the system clock reaches the latest -2297 /// `Instant` that was output by `poll_timeout`; however spurious extra calls will simply -2298 /// no-op and therefore are safe. -2299 pub fn handle_timeout(&mut self, now: Instant) { -2300 while let Some((timer, _time)) = self.timers.expire_before(now, &self.qlog) { -2301 // TODO(@divma): remove `at` when the unicorn is born -2302 trace!(?timer, at=?now, "timeout"); -2303 match timer { -2304 Timer::Conn(timer) => match timer { -2305 ConnTimer::Close => { -2306 self.state.move_to_drained(None); -2307 // move_to_drained checks that we weren't in drained before. -2308 // Adding events to endpoint_events is only legal if `Drained` was never queued before. -2309 self.endpoint_events.push_back(EndpointEventInner::Drained); -2310 } -2311 ConnTimer::Idle => { -2312 self.kill(ConnectionError::TimedOut); -2313 } -2314 ConnTimer::KeepAlive => { -2315 trace!("sending keep-alive"); -2316 self.ping(); -2317 } -2318 ConnTimer::KeyDiscard => { -2319 self.crypto_state.discard_temporary_keys(); -2320 } -2321 ConnTimer::PushNewCid => { -2322 while let Some((path_id, when)) = self.next_cid_retirement() { -2323 if when > now { -2324 break; -2325 } -2326 match self.local_cid_state.get_mut(&path_id) { -2327 None => error!(%path_id, "No local CID state for path"), -2328 Some(cid_state) => { -2329 // Update `retire_prior_to` field in NEW_CONNECTION_ID frame -2330 let num_new_cid = cid_state.on_cid_timeout().into(); -2331 if !self.state.is_closed() { -2332 trace!( -2333 "push a new CID to peer RETIRE_PRIOR_TO field {}", -2334 cid_state.retire_prior_to() -2335 ); -2336 self.endpoint_events.push_back( -2337 EndpointEventInner::NeedIdentifiers( -2338 path_id, -2339 now, -2340 num_new_cid, -2341 ), -2342 ); -2343 } -2344 } -2345 } -2346 } -2347 } -2348 ConnTimer::NoAvailablePath => { -2349 // Grace period expired: all paths were abandoned and no new path -2350 // was opened. Close the connection. There are no paths left to -2351 // send CONNECTION_CLOSE on, so this is a silent close. -2352 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-21.html#section-3.4-8 -2353 if self.state.is_closed() || self.state.is_drained() { -2354 // Connection already closing/drained (e.g. application called -2355 // close() before the grace timer fired). Nothing to do. -2356 error!("no viable path timer fired, but connection already closing"); -2357 } else { -2358 trace!("no viable path grace period expired, closing connection"); -2359 let err = TransportError::NO_VIABLE_PATH( -2360 "last path abandoned, no new path opened", -2361 ); -2362 self.close_common(); -2363 self.set_close_timer(now); -2364 self.connection_close_pending = true; -2365 self.state.move_to_closed(err); -2366 } -2367 } -2368 }, -2369 Timer::PerPath(path_id, timer) => { -2370 let span = trace_span!("per-path timer fired", %path_id, ?timer); -2371 let _guard = span.enter(); -2372 match timer { -2373 PathTimer::PathIdle => { -2374 if let Err(err) = -2375 self.close_path_inner(now, path_id, PathAbandonReason::TimedOut) -2376 { -2377 warn!(?err, "failed closing path"); -2378 } -2379 } -2380 -2381 PathTimer::PathKeepAlive => { -2382 trace!("sending keep-alive on path"); -2383 self.ping_path(path_id).ok(); -2384 } -2385 PathTimer::LossDetection => { -2386 self.on_loss_detection_timeout(now, path_id); -2387 self.qlog.emit_recovery_metrics( -2388 path_id, -2389 &mut self.paths.get_mut(&path_id).unwrap().data, -2390 now, -2391 ); +2218 if let Some(data) = remaining { +2219 self.path_stats.for_path(path_id).udp_rx.bytes += data.len() as u64; +2220 self.handle_coalesced(now, network_path, path_id, ecn, data); +2221 } +2222 +2223 if let Some(path) = self.paths.get_mut(&path_id) { +2224 self.qlog +2225 .emit_recovery_metrics(path_id, &mut path.data, now); +2226 } +2227 +2228 if was_anti_amplification_blocked { +2229 // A prior attempt to set the loss detection timer may have failed due to +2230 // anti-amplification, so ensure it's set now. Prevents a handshake deadlock if +2231 // the server's first flight is lost. +2232 self.set_loss_detection_timer(now, path_id); +2233 } +2234 } +2235 NewIdentifiers(ids, now, cid_len, cid_lifetime) => { +2236 let path_id = ids.first().map(|issued| issued.path_id).unwrap_or_default(); +2237 debug_assert!(ids.iter().all(|issued| issued.path_id == path_id)); +2238 let cid_state = self +2239 .local_cid_state +2240 .entry(path_id) +2241 .or_insert_with(|| CidState::new(cid_len, cid_lifetime, now, 0)); +2242 cid_state.new_cids(&ids, now); +2243 +2244 ids.into_iter().rev().for_each(|frame| { +2245 self.spaces[SpaceId::Data].pending.new_cids.push(frame); +2246 }); +2247 // Always update Timer::PushNewCid +2248 self.reset_cid_retirement(now); +2249 } +2250 } +2251 } +2252 +2253 /// Updates the network path for `path_id`. +2254 /// +2255 /// Returns true if a packet coming in for this `path_id` over given `network_path` should be discarded. +2256 /// Returns false if the path was updated and the packet doesn't need to be discarded. +2257 fn update_network_path_or_discard(&mut self, network_path: FourTuple, path_id: PathId) -> bool { +2258 let remote_may_migrate = self.side.remote_may_migrate(&self.state); +2259 let local_ip_may_migrate = self.side.is_client(); +2260 // If this packet could initiate a migration and we're a client or a server that +2261 // forbids migration, drop the datagram. This could be relaxed to heuristically +2262 // permit NAT-rebinding-like migration. +2263 if let Some(known_path) = self.path_mut(path_id) { +2264 if network_path.remote != known_path.network_path.remote && !remote_may_migrate { +2265 trace!( +2266 %path_id, +2267 %network_path, +2268 %known_path.network_path, +2269 "discarding packet from unrecognized peer" +2270 ); +2271 return true; +2272 } +2273 +2274 if known_path.network_path.local_ip.is_some() +2275 && network_path.local_ip.is_some() +2276 && known_path.network_path.local_ip != network_path.local_ip +2277 && !local_ip_may_migrate +2278 { +2279 trace!( +2280 %path_id, +2281 %network_path, +2282 %known_path.network_path, +2283 "discarding packet sent to incorrect interface" +2284 ); +2285 return true; +2286 } +2287 // If the datagram indicates that we've changed our local IP, we update it. +2288 // This is alluded to in Section 5.2 of the Multipath RFC draft 18: +2289 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-18.html#name-using-multiple-paths-on-the +2290 // > Client receives the packet, recognizes a path migration, updates the source address of path 2 to 192.0.2.1. +2291 if let Some(local_ip) = network_path.local_ip { +2292 if known_path +2293 .network_path +2294 .local_ip +2295 .is_some_and(|ip| ip != local_ip) +2296 { +2297 debug!( +2298 %path_id, +2299 %network_path, +2300 %known_path.network_path, +2301 "path's local address seemingly migrated" +2302 ); +2303 } +2304 // We update the address without path validation on the client side. +2305 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-18.html#section-5.1 +2306 // > Servers observing a 4-tuple change will perform path validation (see Section 9 of [QUIC-TRANSPORT]). +2307 // This sounds like it's *only* the server endpoints that do this. +2308 // TODO(matheus23): We should still consider doing a proper migration on the client side in the future. +2309 // For now, this preserves the behavior of this code pre 4-tuple tracking. +2310 known_path.network_path.local_ip = Some(local_ip); +2311 } +2312 } +2313 false +2314 } +2315 +2316 /// Process timer expirations +2317 /// +2318 /// Executes protocol logic, potentially preparing signals (including application `Event`s, +2319 /// `EndpointEvent`s and outgoing datagrams) that should be extracted through the relevant +2320 /// methods. +2321 /// +2322 /// It is most efficient to call this immediately after the system clock reaches the latest +2323 /// `Instant` that was output by `poll_timeout`; however spurious extra calls will simply +2324 /// no-op and therefore are safe. +2325 pub fn handle_timeout(&mut self, now: Instant) { +2326 while let Some((timer, _time)) = self.timers.expire_before(now, &self.qlog) { +2327 // TODO(@divma): remove `at` when the unicorn is born +2328 trace!(?timer, at=?now, "timeout"); +2329 match timer { +2330 Timer::Conn(timer) => match timer { +2331 ConnTimer::Close => { +2332 self.state.move_to_drained(None); +2333 // move_to_drained checks that we weren't in drained before. +2334 // Adding events to endpoint_events is only legal if `Drained` was never queued before. +2335 self.endpoint_events.push_back(EndpointEventInner::Drained); +2336 } +2337 ConnTimer::Idle => { +2338 self.kill(ConnectionError::TimedOut); +2339 } +2340 ConnTimer::KeepAlive => { +2341 trace!("sending keep-alive"); +2342 self.ping(); +2343 } +2344 ConnTimer::KeyDiscard => { +2345 self.crypto_state.discard_temporary_keys(); +2346 } +2347 ConnTimer::PushNewCid => { +2348 while let Some((path_id, when)) = self.next_cid_retirement() { +2349 if when > now { +2350 break; +2351 } +2352 match self.local_cid_state.get_mut(&path_id) { +2353 None => error!(%path_id, "No local CID state for path"), +2354 Some(cid_state) => { +2355 // Update `retire_prior_to` field in NEW_CONNECTION_ID frame +2356 let num_new_cid = cid_state.on_cid_timeout().into(); +2357 if !self.state.is_closed() { +2358 trace!( +2359 "push a new CID to peer RETIRE_PRIOR_TO field {}", +2360 cid_state.retire_prior_to() +2361 ); +2362 self.endpoint_events.push_back( +2363 EndpointEventInner::NeedIdentifiers( +2364 path_id, +2365 now, +2366 num_new_cid, +2367 ), +2368 ); +2369 } +2370 } +2371 } +2372 } +2373 } +2374 ConnTimer::NoAvailablePath => { +2375 // Grace period expired: all paths were abandoned and no new path +2376 // was opened. Close the connection. There are no paths left to +2377 // send CONNECTION_CLOSE on, so this is a silent close. +2378 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-21.html#section-3.4-8 +2379 if self.state.is_closed() || self.state.is_drained() { +2380 // Connection already closing/drained (e.g. application called +2381 // close() before the grace timer fired). Nothing to do. +2382 error!("no viable path timer fired, but connection already closing"); +2383 } else { +2384 trace!("no viable path grace period expired, closing connection"); +2385 let err = TransportError::NO_VIABLE_PATH( +2386 "last path abandoned, no new path opened", +2387 ); +2388 self.close_common(); +2389 self.set_close_timer(now); +2390 self.connection_close_pending = true; +2391 self.state.move_to_closed(err); 2392 } -2393 PathTimer::PathValidationFailed => { -2394 let Some(path) = self.paths.get_mut(&path_id) else { -2395 continue; -2396 }; -2397 self.timers.stop( -2398 Timer::PerPath(path_id, PathTimer::PathChallengeLost), -2399 self.qlog.with_time(now), -2400 ); -2401 debug!("path migration validation failed"); -2402 if let Some((_, prev)) = path.prev.take() { -2403 path.data = prev; +2393 } +2394 }, +2395 Timer::PerPath(path_id, timer) => { +2396 let span = trace_span!("per-path timer fired", %path_id, ?timer); +2397 let _guard = span.enter(); +2398 match timer { +2399 PathTimer::PathIdle => { +2400 if let Err(err) = +2401 self.close_path_inner(now, path_id, PathAbandonReason::TimedOut) +2402 { +2403 warn!(?err, "failed closing path"); 2404 } -2405 path.data.reset_on_path_challenges(); -2406 } -2407 PathTimer::PathChallengeLost => { -2408 let Some(path) = self.paths.get_mut(&path_id) else { -2409 continue; -2410 }; -2411 trace!("path challenge deemed lost"); -2412 path.data.pending_on_path_challenge = true; -2413 } -2414 PathTimer::PathOpenFailed => { -2415 let Some(path) = self.paths.get_mut(&path_id) else { -2416 continue; -2417 }; -2418 path.data.reset_on_path_challenges(); -2419 self.timers.stop( -2420 Timer::PerPath(path_id, PathTimer::PathChallengeLost), -2421 self.qlog.with_time(now), -2422 ); -2423 debug!("new path validation failed"); -2424 if let Err(err) = self.close_path_inner( -2425 now, -2426 path_id, -2427 PathAbandonReason::ValidationFailed, -2428 ) { -2429 warn!(?err, "failed closing path"); +2405 } +2406 +2407 PathTimer::PathKeepAlive => { +2408 trace!("sending keep-alive on path"); +2409 self.ping_path(path_id).ok(); +2410 } +2411 PathTimer::LossDetection => { +2412 self.on_loss_detection_timeout(now, path_id); +2413 self.qlog.emit_recovery_metrics( +2414 path_id, +2415 &mut self.paths.get_mut(&path_id).unwrap().data, +2416 now, +2417 ); +2418 } +2419 PathTimer::PathValidationFailed => { +2420 let Some(path) = self.paths.get_mut(&path_id) else { +2421 continue; +2422 }; +2423 self.timers.stop( +2424 Timer::PerPath(path_id, PathTimer::PathChallengeLost), +2425 self.qlog.with_time(now), +2426 ); +2427 debug!("path migration validation failed"); +2428 if let Some((_, prev)) = path.prev.take() { +2429 path.data = prev; 2430 } -2431 } -2432 PathTimer::Pacing => trace!("pacing timer expired"), -2433 PathTimer::MaxAckDelay => { -2434 trace!("max ack delay reached"); -2435 // This timer is only armed in the Data space -2436 self.spaces[SpaceId::Data] -2437 .for_path(path_id) -2438 .pending_acks -2439 .on_max_ack_delay_timeout() -2440 } -2441 PathTimer::PathDrained => { -2442 // The path was abandoned and 3*PTO has expired since. Clean up all -2443 // remaining state and install stateless reset token. -2444 self.timers.stop_per_path(path_id, self.qlog.with_time(now)); -2445 if let Some(local_cid_state) = self.local_cid_state.remove(&path_id) { -2446 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events. All timers should be cleared in drained connections. -2447 let (min_seq, max_seq) = local_cid_state.active_seq(); -2448 for seq in min_seq..=max_seq { -2449 self.endpoint_events.push_back( -2450 EndpointEventInner::RetireConnectionId( -2451 now, path_id, seq, false, -2452 ), -2453 ); -2454 } -2455 } -2456 self.discard_path(path_id, now); +2431 path.data.reset_on_path_challenges(); +2432 } +2433 PathTimer::PathChallengeLost => { +2434 let Some(path) = self.paths.get_mut(&path_id) else { +2435 continue; +2436 }; +2437 trace!("path challenge deemed lost"); +2438 path.data.pending_on_path_challenge = true; +2439 } +2440 PathTimer::PathOpenFailed => { +2441 let Some(path) = self.paths.get_mut(&path_id) else { +2442 continue; +2443 }; +2444 path.data.reset_on_path_challenges(); +2445 self.timers.stop( +2446 Timer::PerPath(path_id, PathTimer::PathChallengeLost), +2447 self.qlog.with_time(now), +2448 ); +2449 debug!("new path validation failed"); +2450 if let Err(err) = self.close_path_inner( +2451 now, +2452 path_id, +2453 PathAbandonReason::ValidationFailed, +2454 ) { +2455 warn!(?err, "failed closing path"); +2456 } 2457 } -2458 } -2459 } -2460 } -2461 } -2462 } -2463 -2464 /// Close a connection immediately -2465 /// -2466 /// This does not ensure delivery of outstanding data. It is the application's responsibility to -2467 /// call this only when all important communications have been completed, e.g. by calling -2468 /// [`SendStream::finish`] on outstanding streams and waiting for the corresponding -2469 /// [`StreamEvent::Finished`] event. -2470 /// -2471 /// If [`Streams::send_streams`] returns 0, all outstanding stream data has been -2472 /// delivered. There may still be data from the peer that has not been received. -2473 /// -2474 /// [`StreamEvent::Finished`]: crate::StreamEvent::Finished -2475 pub fn close(&mut self, now: Instant, error_code: VarInt, reason: Bytes) { -2476 self.close_inner( -2477 now, -2478 Close::Application(frame::ApplicationClose { error_code, reason }), -2479 ) -2480 } -2481 -2482 /// Close the connection immediately, initiated by an API call. -2483 /// -2484 /// This will not produce a [`ConnectionLost`] event propagated by the -2485 /// [`Connection::poll`] call, because the API call already propagated the error to the -2486 /// user. -2487 /// -2488 /// Not to be used when entering immediate close due to an internal state change based -2489 /// on an event. See [`State::move_to_closed_local`] for details. -2490 /// -2491 /// This initiates immediate close from -2492 /// <https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2>, moving to the closed -2493 /// state. -2494 /// -2495 /// [`ConnectionLost`]: crate::Event::ConnectionLost -2496 /// [`Connection::poll`]: super::Connection::poll -2497 fn close_inner(&mut self, now: Instant, reason: Close) { -2498 let was_closed = self.state.is_closed(); -2499 if !was_closed { -2500 self.close_common(); -2501 self.set_close_timer(now); -2502 self.connection_close_pending = true; -2503 self.state.move_to_closed_local(reason); -2504 } -2505 } -2506 -2507 /// Control datagrams -2508 pub fn datagrams(&mut self) -> Datagrams<'_> { -2509 Datagrams { conn: self } -2510 } -2511 -2512 /// Returns connection statistics -2513 pub fn stats(&mut self) -> ConnectionStats { -2514 let mut stats = self.partial_stats.clone(); -2515 -2516 for path_stats in self.path_stats.iter_stats() { -2517 // Self::path_stats() computes the path rtt, cwnd and current_mtu on access -2518 // because they are not simple counters. When computing the connection stats we -2519 // can skip that effort since those fields are not used in the `impl -2520 // Add<PathStats> for ConnectionStats`. -2521 stats += *path_stats; -2522 } -2523 -2524 stats -2525 } -2526 -2527 /// Returns path statistics -2528 pub fn path_stats(&mut self, path_id: PathId) -> Option<PathStats> { -2529 let path = self.paths.get(&path_id)?; -2530 let stats = self.path_stats.for_path(path_id); -2531 stats.rtt = path.data.rtt.get(); -2532 stats.cwnd = path.data.congestion.window(); -2533 stats.current_mtu = path.data.mtud.current_mtu(); -2534 Some(*stats) -2535 } -2536 -2537 /// Ping the remote endpoint -2538 /// -2539 /// Causes an ACK-eliciting packet to be transmitted on the connection. -2540 pub fn ping(&mut self) { -2541 // TODO(flub): This is very brute-force: it pings *all* the paths. Instead it would -2542 // be nice if we could only send a single packet for this. -2543 for path_data in self.spaces[self.highest_space].number_spaces.values_mut() { -2544 path_data.ping_pending = true; -2545 } -2546 } -2547 -2548 /// Ping the remote endpoint over a specific path -2549 /// -2550 /// Causes an ACK-eliciting packet to be transmitted on the path. -2551 pub fn ping_path(&mut self, path: PathId) -> Result<(), ClosedPath> { -2552 let path_data = self.spaces[self.highest_space] -2553 .number_spaces -2554 .get_mut(&path) -2555 .ok_or(ClosedPath { _private: () })?; -2556 path_data.ping_pending = true; -2557 Ok(()) -2558 } -2559 -2560 /// Update traffic keys spontaneously -2561 /// -2562 /// This can be useful for testing key updates, as they otherwise only happen infrequently. -2563 pub fn force_key_update(&mut self) { -2564 if !self.state.is_established() { -2565 debug!("ignoring forced key update in illegal state"); -2566 return; -2567 } -2568 if self.crypto_state.prev_crypto.is_some() { -2569 // We already just updated, or are currently updating, the keys. Concurrent key updates -2570 // are illegal. -2571 debug!("ignoring redundant forced key update"); -2572 return; -2573 } -2574 self.crypto_state.update_keys(None, false); -2575 } -2576 -2577 /// Get a session reference -2578 pub fn crypto_session(&self) -> &dyn crypto::Session { -2579 self.crypto_state.session.as_ref() -2580 } -2581 -2582 /// Whether the connection is in the process of being established -2583 /// -2584 /// If this returns `false`, the connection may be either established or closed, signaled by the -2585 /// emission of a `Connected` or `ConnectionLost` message respectively. -2586 pub fn is_handshaking(&self) -> bool { -2587 self.state.is_handshake() -2588 } -2589 -2590 /// Whether the connection is closed -2591 /// -2592 /// Closed connections cannot transport any further data. A connection becomes closed when -2593 /// either peer application intentionally closes it, or when either transport layer detects an -2594 /// error such as a time-out or certificate validation failure. -2595 /// -2596 /// A `ConnectionLost` event is emitted with details when the connection becomes closed. -2597 pub fn is_closed(&self) -> bool { -2598 self.state.is_closed() -2599 } -2600 -2601 /// Whether there is no longer any need to keep the connection around -2602 /// -2603 /// Closed connections become drained after a brief timeout to absorb any remaining in-flight -2604 /// packets from the peer. All drained connections have been closed. -2605 pub fn is_drained(&self) -> bool { -2606 self.state.is_drained() -2607 } -2608 -2609 /// For clients, if the peer accepted the 0-RTT data packets -2610 /// -2611 /// The value is meaningless until after the handshake completes. -2612 pub fn accepted_0rtt(&self) -> bool { -2613 self.crypto_state.accepted_0rtt +2458 PathTimer::Pacing => trace!("pacing timer expired"), +2459 PathTimer::MaxAckDelay => { +2460 trace!("max ack delay reached"); +2461 // This timer is only armed in the Data space +2462 self.spaces[SpaceId::Data] +2463 .for_path(path_id) +2464 .pending_acks +2465 .on_max_ack_delay_timeout() +2466 } +2467 PathTimer::PathDrained => { +2468 // The path was abandoned and 3*PTO has expired since. Clean up all +2469 // remaining state and install stateless reset token. +2470 self.timers.stop_per_path(path_id, self.qlog.with_time(now)); +2471 if let Some(local_cid_state) = self.local_cid_state.remove(&path_id) { +2472 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events. All timers should be cleared in drained connections. +2473 let (min_seq, max_seq) = local_cid_state.active_seq(); +2474 for seq in min_seq..=max_seq { +2475 self.endpoint_events.push_back( +2476 EndpointEventInner::RetireConnectionId( +2477 now, path_id, seq, false, +2478 ), +2479 ); +2480 } +2481 } +2482 self.discard_path(path_id, now); +2483 } +2484 } +2485 } +2486 } +2487 } +2488 } +2489 +2490 /// Close a connection immediately +2491 /// +2492 /// This does not ensure delivery of outstanding data. It is the application's responsibility to +2493 /// call this only when all important communications have been completed, e.g. by calling +2494 /// [`SendStream::finish`] on outstanding streams and waiting for the corresponding +2495 /// [`StreamEvent::Finished`] event. +2496 /// +2497 /// If [`Streams::send_streams`] returns 0, all outstanding stream data has been +2498 /// delivered. There may still be data from the peer that has not been received. +2499 /// +2500 /// [`StreamEvent::Finished`]: crate::StreamEvent::Finished +2501 pub fn close(&mut self, now: Instant, error_code: VarInt, reason: Bytes) { +2502 self.close_inner( +2503 now, +2504 Close::Application(frame::ApplicationClose { error_code, reason }), +2505 ) +2506 } +2507 +2508 /// Close the connection immediately, initiated by an API call. +2509 /// +2510 /// This will not produce a [`ConnectionLost`] event propagated by the +2511 /// [`Connection::poll`] call, because the API call already propagated the error to the +2512 /// user. +2513 /// +2514 /// Not to be used when entering immediate close due to an internal state change based +2515 /// on an event. See [`State::move_to_closed_local`] for details. +2516 /// +2517 /// This initiates immediate close from +2518 /// <https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2>, moving to the closed +2519 /// state. +2520 /// +2521 /// [`ConnectionLost`]: crate::Event::ConnectionLost +2522 /// [`Connection::poll`]: super::Connection::poll +2523 fn close_inner(&mut self, now: Instant, reason: Close) { +2524 let was_closed = self.state.is_closed(); +2525 if !was_closed { +2526 self.close_common(); +2527 self.set_close_timer(now); +2528 self.connection_close_pending = true; +2529 self.state.move_to_closed_local(reason); +2530 } +2531 } +2532 +2533 /// Control datagrams +2534 pub fn datagrams(&mut self) -> Datagrams<'_> { +2535 Datagrams { conn: self } +2536 } +2537 +2538 /// Returns connection statistics +2539 pub fn stats(&mut self) -> ConnectionStats { +2540 let mut stats = self.partial_stats.clone(); +2541 +2542 for path_stats in self.path_stats.iter_stats() { +2543 // Self::path_stats() computes the path rtt, cwnd and current_mtu on access +2544 // because they are not simple counters. When computing the connection stats we +2545 // can skip that effort since those fields are not used in the `impl +2546 // Add<PathStats> for ConnectionStats`. +2547 stats += *path_stats; +2548 } +2549 +2550 stats +2551 } +2552 +2553 /// Returns path statistics +2554 pub fn path_stats(&mut self, path_id: PathId) -> Option<PathStats> { +2555 let path = self.paths.get(&path_id)?; +2556 let stats = self.path_stats.for_path(path_id); +2557 stats.rtt = path.data.rtt.get(); +2558 stats.cwnd = path.data.congestion.window(); +2559 stats.current_mtu = path.data.mtud.current_mtu(); +2560 Some(*stats) +2561 } +2562 +2563 /// Ping the remote endpoint +2564 /// +2565 /// Causes an ACK-eliciting packet to be transmitted on the connection. +2566 pub fn ping(&mut self) { +2567 // TODO(flub): This is very brute-force: it pings *all* the paths. Instead it would +2568 // be nice if we could only send a single packet for this. +2569 for path_data in self.spaces[self.highest_space].number_spaces.values_mut() { +2570 path_data.ping_pending = true; +2571 } +2572 } +2573 +2574 /// Ping the remote endpoint over a specific path +2575 /// +2576 /// Causes an ACK-eliciting packet to be transmitted on the path. +2577 pub fn ping_path(&mut self, path: PathId) -> Result<(), ClosedPath> { +2578 let path_data = self.spaces[self.highest_space] +2579 .number_spaces +2580 .get_mut(&path) +2581 .ok_or(ClosedPath { _private: () })?; +2582 path_data.ping_pending = true; +2583 Ok(()) +2584 } +2585 +2586 /// Update traffic keys spontaneously +2587 /// +2588 /// This can be useful for testing key updates, as they otherwise only happen infrequently. +2589 pub fn force_key_update(&mut self) { +2590 if !self.state.is_established() { +2591 debug!("ignoring forced key update in illegal state"); +2592 return; +2593 } +2594 if self.crypto_state.prev_crypto.is_some() { +2595 // We already just updated, or are currently updating, the keys. Concurrent key updates +2596 // are illegal. +2597 debug!("ignoring redundant forced key update"); +2598 return; +2599 } +2600 self.crypto_state.update_keys(None, false); +2601 } +2602 +2603 /// Get a session reference +2604 pub fn crypto_session(&self) -> &dyn crypto::Session { +2605 self.crypto_state.session.as_ref() +2606 } +2607 +2608 /// Whether the connection is in the process of being established +2609 /// +2610 /// If this returns `false`, the connection may be either established or closed, signaled by the +2611 /// emission of a `Connected` or `ConnectionLost` message respectively. +2612 pub fn is_handshaking(&self) -> bool { +2613 self.state.is_handshake() 2614 } 2615 -2616 /// Whether 0-RTT is/was possible during the handshake -2617 pub fn has_0rtt(&self) -> bool { -2618 self.crypto_state.zero_rtt_enabled -2619 } -2620 -2621 /// Whether there are any pending retransmits -2622 pub fn has_pending_retransmits(&self) -> bool { -2623 !self.spaces[SpaceId::Data].pending.is_empty(&self.streams) -2624 } -2625 -2626 /// Look up whether we're the client or server of this Connection -2627 pub fn side(&self) -> Side { -2628 self.side.side() -2629 } -2630 -2631 /// Get the address observed by the remote over the given path -2632 pub fn path_observed_address(&self, path_id: PathId) -> Result<Option<SocketAddr>, ClosedPath> { -2633 self.path(path_id) -2634 .map(|path_data| { -2635 path_data -2636 .last_observed_addr_report -2637 .as_ref() -2638 .map(|observed| observed.socket_addr()) -2639 }) -2640 .ok_or(ClosedPath { _private: () }) -2641 } -2642 -2643 /// Current best estimate of this connection's latency (round-trip-time) -2644 pub fn rtt(&self, path_id: PathId) -> Option<Duration> { -2645 self.path(path_id).map(|d| d.rtt.get()) -2646 } -2647 -2648 /// Current state of this connection's congestion controller, for debugging purposes -2649 pub fn congestion_state(&self, path_id: PathId) -> Option<&dyn Controller> { -2650 self.path(path_id).map(|d| d.congestion.as_ref()) -2651 } -2652 -2653 /// Modify the number of remotely initiated streams that may be concurrently open -2654 /// -2655 /// No streams may be opened by the peer unless fewer than `count` are already open. Large -2656 /// `count`s increase both minimum and worst-case memory consumption. -2657 pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt) { -2658 self.streams.set_max_concurrent(dir, count); -2659 // If the limit was reduced, then a flow control update previously deemed insignificant may -2660 // now be significant. -2661 let pending = &mut self.spaces[SpaceId::Data].pending; -2662 self.streams.queue_max_stream_id(pending); -2663 } -2664 -2665 /// Modify the number of open paths allowed when multipath is enabled -2666 /// -2667 /// When reducing the number of concurrent paths this will only affect delaying sending -2668 /// new MAX_PATH_ID frames until fewer than this number of paths are possible. To -2669 /// actively reduce paths they must be closed using [`Connection::close_path`], which -2670 /// can also be used to close not-yet-opened paths. -2671 /// -2672 /// If multipath is not negotiated (see the [`TransportConfig`]) this can not enable -2673 /// multipath and will fail. -2674 pub fn set_max_concurrent_paths( -2675 &mut self, -2676 now: Instant, -2677 count: NonZeroU32, -2678 ) -> Result<(), MultipathNotNegotiated> { -2679 if !self.is_multipath_negotiated() { -2680 return Err(MultipathNotNegotiated { _private: () }); -2681 } -2682 self.max_concurrent_paths = count; -2683 -2684 let in_use_count = self -2685 .local_max_path_id -2686 .next() -2687 .saturating_sub(self.abandoned_paths.len() as u32) -2688 .as_u32(); -2689 let extra_needed = count.get().saturating_sub(in_use_count); -2690 let new_max_path_id = self.local_max_path_id.saturating_add(extra_needed); -2691 -2692 self.set_max_path_id(now, new_max_path_id); -2693 -2694 Ok(()) -2695 } -2696 -2697 /// If needed, issues a new MAX_PATH_ID frame and new CIDs for any newly allowed paths -2698 fn set_max_path_id(&mut self, now: Instant, max_path_id: PathId) { -2699 if max_path_id <= self.local_max_path_id { -2700 return; -2701 } -2702 -2703 self.local_max_path_id = max_path_id; -2704 self.spaces[SpaceId::Data].pending.max_path_id = true; -2705 -2706 self.issue_first_path_cids(now); -2707 } -2708 -2709 /// Current number of remotely initiated streams that may be concurrently open -2710 /// -2711 /// If the target for this limit is reduced using [`set_max_concurrent_streams`](Self::set_max_concurrent_streams), -2712 /// it will not change immediately, even if fewer streams are open. Instead, it will -2713 /// decrement by one for each time a remotely initiated stream of matching directionality is closed. -2714 pub fn max_concurrent_streams(&self, dir: Dir) -> u64 { -2715 self.streams.max_concurrent(dir) -2716 } +2616 /// Whether the connection is closed +2617 /// +2618 /// Closed connections cannot transport any further data. A connection becomes closed when +2619 /// either peer application intentionally closes it, or when either transport layer detects an +2620 /// error such as a time-out or certificate validation failure. +2621 /// +2622 /// A `ConnectionLost` event is emitted with details when the connection becomes closed. +2623 pub fn is_closed(&self) -> bool { +2624 self.state.is_closed() +2625 } +2626 +2627 /// Whether there is no longer any need to keep the connection around +2628 /// +2629 /// Closed connections become drained after a brief timeout to absorb any remaining in-flight +2630 /// packets from the peer. All drained connections have been closed. +2631 pub fn is_drained(&self) -> bool { +2632 self.state.is_drained() +2633 } +2634 +2635 /// For clients, if the peer accepted the 0-RTT data packets +2636 /// +2637 /// The value is meaningless until after the handshake completes. +2638 pub fn accepted_0rtt(&self) -> bool { +2639 self.crypto_state.accepted_0rtt +2640 } +2641 +2642 /// Whether 0-RTT is/was possible during the handshake +2643 pub fn has_0rtt(&self) -> bool { +2644 self.crypto_state.zero_rtt_enabled +2645 } +2646 +2647 /// Whether there are any pending retransmits +2648 pub fn has_pending_retransmits(&self) -> bool { +2649 !self.spaces[SpaceId::Data].pending.is_empty(&self.streams) +2650 } +2651 +2652 /// Look up whether we're the client or server of this Connection +2653 pub fn side(&self) -> Side { +2654 self.side.side() +2655 } +2656 +2657 /// Get the address observed by the remote over the given path +2658 pub fn path_observed_address(&self, path_id: PathId) -> Result<Option<SocketAddr>, ClosedPath> { +2659 self.path(path_id) +2660 .map(|path_data| { +2661 path_data +2662 .last_observed_addr_report +2663 .as_ref() +2664 .map(|observed| observed.socket_addr()) +2665 }) +2666 .ok_or(ClosedPath { _private: () }) +2667 } +2668 +2669 /// Current best estimate of this connection's latency (round-trip-time) +2670 pub fn rtt(&self, path_id: PathId) -> Option<Duration> { +2671 self.path(path_id).map(|d| d.rtt.get()) +2672 } +2673 +2674 /// Current state of this connection's congestion controller, for debugging purposes +2675 pub fn congestion_state(&self, path_id: PathId) -> Option<&dyn Controller> { +2676 self.path(path_id).map(|d| d.congestion.as_ref()) +2677 } +2678 +2679 /// Modify the number of remotely initiated streams that may be concurrently open +2680 /// +2681 /// No streams may be opened by the peer unless fewer than `count` are already open. Large +2682 /// `count`s increase both minimum and worst-case memory consumption. +2683 pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt) { +2684 self.streams.set_max_concurrent(dir, count); +2685 // If the limit was reduced, then a flow control update previously deemed insignificant may +2686 // now be significant. +2687 let pending = &mut self.spaces[SpaceId::Data].pending; +2688 self.streams.queue_max_stream_id(pending); +2689 } +2690 +2691 /// Modify the number of open paths allowed when multipath is enabled +2692 /// +2693 /// When reducing the number of concurrent paths this will only affect delaying sending +2694 /// new MAX_PATH_ID frames until fewer than this number of paths are possible. To +2695 /// actively reduce paths they must be closed using [`Connection::close_path`], which +2696 /// can also be used to close not-yet-opened paths. +2697 /// +2698 /// If multipath is not negotiated (see the [`TransportConfig`]) this can not enable +2699 /// multipath and will fail. +2700 pub fn set_max_concurrent_paths( +2701 &mut self, +2702 now: Instant, +2703 count: NonZeroU32, +2704 ) -> Result<(), MultipathNotNegotiated> { +2705 if !self.is_multipath_negotiated() { +2706 return Err(MultipathNotNegotiated { _private: () }); +2707 } +2708 self.max_concurrent_paths = count; +2709 +2710 let in_use_count = self +2711 .local_max_path_id +2712 .next() +2713 .saturating_sub(self.abandoned_paths.len() as u32) +2714 .as_u32(); +2715 let extra_needed = count.get().saturating_sub(in_use_count); +2716 let new_max_path_id = self.local_max_path_id.saturating_add(extra_needed); 2717 -2718 /// See [`TransportConfig::send_window()`] -2719 pub fn set_send_window(&mut self, send_window: u64) { -2720 self.streams.set_send_window(send_window); +2718 self.set_max_path_id(now, new_max_path_id); +2719 +2720 Ok(()) 2721 } 2722 -2723 /// See [`TransportConfig::receive_window()`] -2724 pub fn set_receive_window(&mut self, receive_window: VarInt) { -2725 if self.streams.set_receive_window(receive_window) { -2726 self.spaces[SpaceId::Data].pending.max_data = true; +2723 /// If needed, issues a new MAX_PATH_ID frame and new CIDs for any newly allowed paths +2724 fn set_max_path_id(&mut self, now: Instant, max_path_id: PathId) { +2725 if max_path_id <= self.local_max_path_id { +2726 return; 2727 } -2728 } -2729 -2730 /// Whether the Multipath for QUIC extension is enabled. -2731 /// -2732 /// Multipath is only enabled after the handshake is completed and if it was enabled by both -2733 /// peers. -2734 pub fn is_multipath_negotiated(&self) -> bool { -2735 !self.is_handshaking() -2736 && self.config.max_concurrent_multipath_paths.is_some() -2737 && self.peer_params.initial_max_path_id.is_some() -2738 } -2739 -2740 fn on_ack_received( -2741 &mut self, -2742 now: Instant, -2743 space: SpaceId, -2744 ack: frame::Ack, -2745 ) -> Result<(), TransportError> { -2746 // All ACKs are referencing path 0 -2747 let path = PathId::ZERO; -2748 self.inner_on_ack_received(now, space, path, ack) -2749 } -2750 -2751 fn on_path_ack_received( -2752 &mut self, -2753 now: Instant, -2754 space: SpaceId, -2755 path_ack: frame::PathAck, -2756 ) -> Result<(), TransportError> { -2757 let (ack, path) = path_ack.into_ack(); -2758 self.inner_on_ack_received(now, space, path, ack) -2759 } -2760 -2761 /// Handles an ACK frame acknowledging packets sent on *path*. -2762 fn inner_on_ack_received( -2763 &mut self, -2764 now: Instant, -2765 space: SpaceId, -2766 path: PathId, -2767 ack: frame::Ack, -2768 ) -> Result<(), TransportError> { -2769 if !self.spaces[space].number_spaces.contains_key(&path) -2770 && self.abandoned_paths.contains(&path) -2771 { -2772 // See also -2773 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-21.html#section-3.4.3-3 -2774 // > When an endpoint finally deletes all state associated with the path [...] -2775 // > PATH_ACK frames received with an abandoned path ID are silently ignored, -2776 // > as specified in Section 4. -2777 trace!("silently ignoring PATH_ACK on discarded path"); -2778 return Ok(()); -2779 } -2780 if ack.largest >= self.spaces[space].for_path(path).next_packet_number { -2781 return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked")); -2782 } -2783 let new_largest = { -2784 let space = &mut self.spaces[space].for_path(path); -2785 if space.largest_acked_packet.is_none_or(|pn| ack.largest > pn) { -2786 space.largest_acked_packet = Some(ack.largest); -2787 if let Some(info) = space.sent_packets.get(ack.largest) { -2788 // This should always succeed, but a misbehaving peer might ACK a packet we -2789 // haven't sent. At worst, that will result in us spuriously reducing the -2790 // congestion window. -2791 space.largest_acked_packet_sent = info.time_sent; -2792 } -2793 true -2794 } else { -2795 false -2796 } -2797 }; -2798 -2799 if self.detect_spurious_loss(&ack, space, path) { -2800 self.path_data_mut(path) -2801 .congestion -2802 .on_spurious_congestion_event(); -2803 } -2804 -2805 // Avoid DoS from unreasonably huge ack ranges by filtering out just the new acks. -2806 let mut newly_acked = ArrayRangeSet::new(); -2807 for range in ack.iter() { -2808 self.spaces[space].for_path(path).check_ack(range.clone())?; -2809 for (pn, _) in self.spaces[space] -2810 .for_path(path) -2811 .sent_packets -2812 .iter_range(range) -2813 { -2814 newly_acked.insert_one(pn); -2815 } -2816 } -2817 -2818 if newly_acked.is_empty() { -2819 return Ok(()); -2820 } -2821 -2822 let mut ack_eliciting_acked = false; -2823 for packet in newly_acked.elts() { -2824 if let Some(info) = self.spaces[space].for_path(path).take(packet) { -2825 for (acked_path_id, acked_pn) in info.largest_acked.iter() { -2826 // Assume ACKs for all packets below the largest acknowledged in -2827 // `packet` have been received. This can cause the peer to spuriously -2828 // retransmit if some of our earlier ACKs were lost, but allows for -2829 // simpler state tracking. See discussion at -2830 // https://www.rfc-editor.org/rfc/rfc9000.html#name-limiting-ranges-by-tracking -2831 if let Some(pns) = self.spaces[space].path_space_mut(*acked_path_id) { -2832 pns.pending_acks.subtract_below(*acked_pn); -2833 } -2834 } -2835 ack_eliciting_acked |= info.ack_eliciting; -2836 -2837 // Notify MTU discovery that a packet was acked, because it might be an MTU probe -2838 let path_data = self.path_data_mut(path); -2839 let mtu_updated = path_data.mtud.on_acked(space.kind(), packet, info.size); -2840 if mtu_updated { -2841 path_data -2842 .congestion -2843 .on_mtu_update(path_data.mtud.current_mtu()); -2844 } -2845 -2846 // Notify ack frequency that a packet was acked, because it might contain an ACK_FREQUENCY frame -2847 self.ack_frequency.on_acked(path, packet); -2848 -2849 self.on_packet_acked(now, path, info); -2850 } -2851 } -2852 -2853 let largest_ackd = self.spaces[space].for_path(path).largest_acked_packet; -2854 let app_limited = self.app_limited; -2855 let path_data = self.path_data_mut(path); -2856 let in_flight = path_data.in_flight.bytes; -2857 -2858 path_data -2859 .congestion -2860 .on_end_acks(now, in_flight, app_limited, largest_ackd); -2861 -2862 if new_largest && ack_eliciting_acked { -2863 let ack_delay = if space != SpaceId::Data { -2864 Duration::from_micros(0) -2865 } else { -2866 cmp::min( -2867 self.ack_frequency.peer_max_ack_delay, -2868 Duration::from_micros(ack.delay << self.peer_params.ack_delay_exponent.0), -2869 ) -2870 }; -2871 let rtt = now.saturating_duration_since( -2872 self.spaces[space].for_path(path).largest_acked_packet_sent, -2873 ); +2728 +2729 self.local_max_path_id = max_path_id; +2730 self.spaces[SpaceId::Data].pending.max_path_id = true; +2731 +2732 self.issue_first_path_cids(now); +2733 } +2734 +2735 /// Current number of remotely initiated streams that may be concurrently open +2736 /// +2737 /// If the target for this limit is reduced using [`set_max_concurrent_streams`](Self::set_max_concurrent_streams), +2738 /// it will not change immediately, even if fewer streams are open. Instead, it will +2739 /// decrement by one for each time a remotely initiated stream of matching directionality is closed. +2740 pub fn max_concurrent_streams(&self, dir: Dir) -> u64 { +2741 self.streams.max_concurrent(dir) +2742 } +2743 +2744 /// See [`TransportConfig::send_window()`] +2745 pub fn set_send_window(&mut self, send_window: u64) { +2746 self.streams.set_send_window(send_window); +2747 } +2748 +2749 /// See [`TransportConfig::receive_window()`] +2750 pub fn set_receive_window(&mut self, receive_window: VarInt) { +2751 if self.streams.set_receive_window(receive_window) { +2752 self.spaces[SpaceId::Data].pending.max_data = true; +2753 } +2754 } +2755 +2756 /// Whether the Multipath for QUIC extension is enabled. +2757 /// +2758 /// Multipath is only enabled after the handshake is completed and if it was enabled by both +2759 /// peers. +2760 pub fn is_multipath_negotiated(&self) -> bool { +2761 !self.is_handshaking() +2762 && self.config.max_concurrent_multipath_paths.is_some() +2763 && self.peer_params.initial_max_path_id.is_some() +2764 } +2765 +2766 fn on_ack_received( +2767 &mut self, +2768 now: Instant, +2769 space: SpaceId, +2770 ack: frame::Ack, +2771 ) -> Result<(), TransportError> { +2772 // All ACKs are referencing path 0 +2773 let path = PathId::ZERO; +2774 self.inner_on_ack_received(now, space, path, ack) +2775 } +2776 +2777 fn on_path_ack_received( +2778 &mut self, +2779 now: Instant, +2780 space: SpaceId, +2781 path_ack: frame::PathAck, +2782 ) -> Result<(), TransportError> { +2783 let (ack, path) = path_ack.into_ack(); +2784 self.inner_on_ack_received(now, space, path, ack) +2785 } +2786 +2787 /// Handles an ACK frame acknowledging packets sent on *path*. +2788 fn inner_on_ack_received( +2789 &mut self, +2790 now: Instant, +2791 space: SpaceId, +2792 path: PathId, +2793 ack: frame::Ack, +2794 ) -> Result<(), TransportError> { +2795 if !self.spaces[space].number_spaces.contains_key(&path) +2796 && self.abandoned_paths.contains(&path) +2797 { +2798 // See also +2799 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-21.html#section-3.4.3-3 +2800 // > When an endpoint finally deletes all state associated with the path [...] +2801 // > PATH_ACK frames received with an abandoned path ID are silently ignored, +2802 // > as specified in Section 4. +2803 trace!("silently ignoring PATH_ACK on discarded path"); +2804 return Ok(()); +2805 } +2806 if ack.largest >= self.spaces[space].for_path(path).next_packet_number { +2807 return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked")); +2808 } +2809 let new_largest = { +2810 let space = &mut self.spaces[space].for_path(path); +2811 if space.largest_acked_packet.is_none_or(|pn| ack.largest > pn) { +2812 space.largest_acked_packet = Some(ack.largest); +2813 if let Some(info) = space.sent_packets.get(ack.largest) { +2814 // This should always succeed, but a misbehaving peer might ACK a packet we +2815 // haven't sent. At worst, that will result in us spuriously reducing the +2816 // congestion window. +2817 space.largest_acked_packet_sent = info.time_sent; +2818 } +2819 true +2820 } else { +2821 false +2822 } +2823 }; +2824 +2825 if self.detect_spurious_loss(&ack, space, path) { +2826 self.path_data_mut(path) +2827 .congestion +2828 .on_spurious_congestion_event(); +2829 } +2830 +2831 // Avoid DoS from unreasonably huge ack ranges by filtering out just the new acks. +2832 let mut newly_acked = ArrayRangeSet::new(); +2833 for range in ack.iter() { +2834 self.spaces[space].for_path(path).check_ack(range.clone())?; +2835 for (pn, _) in self.spaces[space] +2836 .for_path(path) +2837 .sent_packets +2838 .iter_range(range) +2839 { +2840 newly_acked.insert_one(pn); +2841 } +2842 } +2843 +2844 if newly_acked.is_empty() { +2845 return Ok(()); +2846 } +2847 +2848 let mut ack_eliciting_acked = false; +2849 for packet in newly_acked.elts() { +2850 if let Some(info) = self.spaces[space].for_path(path).take(packet) { +2851 for (acked_path_id, acked_pn) in info.largest_acked.iter() { +2852 // Assume ACKs for all packets below the largest acknowledged in +2853 // `packet` have been received. This can cause the peer to spuriously +2854 // retransmit if some of our earlier ACKs were lost, but allows for +2855 // simpler state tracking. See discussion at +2856 // https://www.rfc-editor.org/rfc/rfc9000.html#name-limiting-ranges-by-tracking +2857 if let Some(pns) = self.spaces[space].path_space_mut(*acked_path_id) { +2858 pns.pending_acks.subtract_below(*acked_pn); +2859 } +2860 } +2861 ack_eliciting_acked |= info.ack_eliciting; +2862 +2863 // Notify MTU discovery that a packet was acked, because it might be an MTU probe +2864 let path_data = self.path_data_mut(path); +2865 let mtu_updated = path_data.mtud.on_acked(space.kind(), packet, info.size); +2866 if mtu_updated { +2867 path_data +2868 .congestion +2869 .on_mtu_update(path_data.mtud.current_mtu()); +2870 } +2871 +2872 // Notify ack frequency that a packet was acked, because it might contain an ACK_FREQUENCY frame +2873 self.ack_frequency.on_acked(path, packet); 2874 -2875 let next_pn = self.spaces[space].for_path(path).next_packet_number; -2876 let path_data = self.path_data_mut(path); -2877 // TODO(@divma): should be a method of path, should be contained in a single place -2878 path_data.rtt.update(ack_delay, rtt); -2879 if path_data.first_packet_after_rtt_sample.is_none() { -2880 path_data.first_packet_after_rtt_sample = Some((space.kind(), next_pn)); -2881 } -2882 } +2875 self.on_packet_acked(now, path, info); +2876 } +2877 } +2878 +2879 let largest_ackd = self.spaces[space].for_path(path).largest_acked_packet; +2880 let app_limited = self.app_limited; +2881 let path_data = self.path_data_mut(path); +2882 let in_flight = path_data.in_flight.bytes; 2883 -2884 // Must be called before crypto/pto_count are clobbered -2885 self.detect_lost_packets(now, space, path, true); -2886 -2887 if self.peer_completed_address_validation(path) { -2888 self.path_data_mut(path).pto_count = 0; -2889 } -2890 -2891 // Explicit congestion notification -2892 // TODO(@divma): this code is a good example of logic that should be contained in a single -2893 // place but it's split between the path data and the packet number space data, we should -2894 // find a way to make this work without two lookups -2895 if self.path_data(path).sending_ecn { -2896 if let Some(ecn) = ack.ecn { -2897 // We only examine ECN counters from ACKs that we are certain we received in transmit -2898 // order, allowing us to compute an increase in ECN counts to compare against the number -2899 // of newly acked packets that remains well-defined in the presence of arbitrary packet -2900 // reordering. -2901 if new_largest { -2902 let sent = self.spaces[space].for_path(path).largest_acked_packet_sent; -2903 self.process_ecn(now, space, path, newly_acked.len() as u64, ecn, sent); -2904 } -2905 } else { -2906 // We always start out sending ECN, so any ack that doesn't acknowledge it disables it. -2907 debug!("ECN not acknowledged by peer"); -2908 self.path_data_mut(path).sending_ecn = false; -2909 } -2910 } -2911 -2912 self.set_loss_detection_timer(now, path); -2913 Ok(()) -2914 } -2915 -2916 fn detect_spurious_loss(&mut self, ack: &frame::Ack, space: SpaceId, path: PathId) -> bool { -2917 let lost_packets = &mut self.spaces[space].for_path(path).lost_packets; -2918 -2919 if lost_packets.is_empty() { -2920 return false; -2921 } -2922 -2923 for range in ack.iter() { -2924 let spurious_losses: Vec<u64> = lost_packets -2925 .iter_range(range.clone()) -2926 .map(|(pn, _info)| pn) -2927 .collect(); -2928 -2929 for pn in spurious_losses { -2930 lost_packets.remove(pn); -2931 } -2932 } -2933 -2934 // If this ACK frame acknowledged all deemed lost packets, -2935 // then we have raised a spurious congestion event in the past. -2936 // We cannot conclude when there are remaining packets, -2937 // but future ACK frames might indicate a spurious loss detection. -2938 lost_packets.is_empty() -2939 } -2940 -2941 /// Drain lost packets that we reasonably think will never arrive -2942 /// -2943 /// The current criterion is copied from `msquic`: -2944 /// discard packets that were sent earlier than 2 probe timeouts ago. -2945 fn drain_lost_packets(&mut self, now: Instant, space: SpaceId, path: PathId) { -2946 let two_pto = 2 * self.path_data(path).rtt.pto_base(); -2947 -2948 let lost_packets = &mut self.spaces[space].for_path(path).lost_packets; -2949 lost_packets.retain(|_pn, info| now.saturating_duration_since(info.time_sent) <= two_pto); -2950 } -2951 -2952 /// Process a new ECN block from an in-order ACK -2953 fn process_ecn( -2954 &mut self, -2955 now: Instant, -2956 space: SpaceId, -2957 path: PathId, -2958 newly_acked: u64, -2959 ecn: frame::EcnCounts, -2960 largest_sent_time: Instant, -2961 ) { -2962 match self.spaces[space] -2963 .for_path(path) -2964 .detect_ecn(newly_acked, ecn) -2965 { -2966 Err(e) => { -2967 debug!("halting ECN due to verification failure: {}", e); -2968 -2969 self.path_data_mut(path).sending_ecn = false; -2970 // Wipe out the existing value because it might be garbage and could interfere with -2971 // future attempts to use ECN on new paths. -2972 self.spaces[space].for_path(path).ecn_feedback = frame::EcnCounts::ZERO; -2973 } -2974 Ok(false) => {} -2975 Ok(true) => { -2976 self.path_stats.for_path(path).congestion_events += 1; -2977 self.path_data_mut(path).congestion.on_congestion_event( -2978 now, -2979 largest_sent_time, -2980 false, -2981 true, -2982 0, -2983 ); -2984 } -2985 } -2986 } -2987 -2988 // Not timing-aware, so it's safe to call this for inferred acks, such as arise from -2989 // high-latency handshakes -2990 fn on_packet_acked(&mut self, now: Instant, path_id: PathId, info: SentPacket) { -2991 let app_limited = self.app_limited; -2992 let path = self.path_data_mut(path_id); -2993 path.remove_in_flight(&info); -2994 if info.ack_eliciting && info.path_generation == path.generation() { -2995 // Only pass ACKs to the congestion controller if it belongs to this exact -2996 // generation of the path. Otherwise we might be feeding ACKs from the previous -2997 // 4-tuple into our congestion controller. -2998 let rtt = path.rtt; -2999 path.congestion -3000 .on_ack(now, info.time_sent, info.size.into(), app_limited, &rtt); -3001 } -3002 -3003 // Update state for confirmed delivery of frames -3004 if let Some(retransmits) = info.retransmits.get() { -3005 for (id, _) in retransmits.reset_stream.iter() { -3006 self.streams.reset_acked(*id); -3007 } -3008 } -3009 -3010 for frame in info.stream_frames { -3011 self.streams.received_ack_of(frame); -3012 } -3013 } -3014 -3015 fn set_key_discard_timer(&mut self, now: Instant, space: SpaceKind) { -3016 let start = if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) { -3017 now -3018 } else { -3019 self.crypto_state -3020 .prev_crypto -3021 .as_ref() -3022 .expect("no previous keys") -3023 .end_packet -3024 .as_ref() -3025 .expect("update not acknowledged yet") -3026 .1 -3027 }; -3028 -3029 // QUIC-MULTIPATH § 2.5 Key Phase Update Process: use largest PTO of all paths. -3030 self.timers.set( -3031 Timer::Conn(ConnTimer::KeyDiscard), -3032 start + self.max_pto_for_space(space) * 3, -3033 self.qlog.with_time(now), -3034 ); -3035 } -3036 -3037 /// Handle a [`PathTimer::LossDetection`] timeout. -3038 /// -3039 /// This timer expires for two reasons: -3040 /// - An ACK-eliciting packet we sent should be considered lost. -3041 /// - The PTO may have expired and a tail-loss probe needs to be scheduled. -3042 /// -3043 /// The former needs us to schedule re-transmission of the lost data. -3044 /// -3045 /// The latter means we have not received an ACK for an ack-eliciting packet we sent -3046 /// within the PTO time-window. We need to schedule a tail-loss probe, an ack-eliciting -3047 /// packet, to try and elicit new acknowledgements. These new acknowledgements will -3048 /// indicate whether the previously sent packets were lost or not. -3049 fn on_loss_detection_timeout(&mut self, now: Instant, path_id: PathId) { -3050 if let Some((_, pn_space)) = self.loss_time_and_space(path_id) { -3051 // Time threshold loss Detection -3052 self.detect_lost_packets(now, pn_space, path_id, false); -3053 self.set_loss_detection_timer(now, path_id); -3054 return; -3055 } -3056 -3057 let Some((_, space)) = self.pto_time_and_space(now, path_id) else { -3058 error!(%path_id, "PTO expired while unset"); -3059 return; -3060 }; -3061 trace!( -3062 in_flight = self.path_data(path_id).in_flight.bytes, -3063 count = self.path_data(path_id).pto_count, -3064 ?space, -3065 %path_id, -3066 "PTO fired" -3067 ); -3068 -3069 let count = match self.path_data(path_id).in_flight.ack_eliciting { -3070 // A PTO when we're not expecting any ACKs must be due to handshake anti-amplification -3071 // deadlock preventions -3072 0 => { -3073 debug_assert!(!self.peer_completed_address_validation(path_id)); -3074 1 -3075 } -3076 // Conventional loss probe -3077 _ => 2, -3078 }; -3079 let pns = self.spaces[space].for_path(path_id); -3080 pns.loss_probes = pns.loss_probes.saturating_add(count); -3081 let path_data = self.path_data_mut(path_id); -3082 path_data.pto_count = path_data.pto_count.saturating_add(1); -3083 self.set_loss_detection_timer(now, path_id); -3084 } -3085 -3086 /// Detect any lost packets -3087 /// -3088 /// There are two cases in which we detects lost packets: -3089 /// -3090 /// - We received an ACK packet. -3091 /// - The [`PathTimer::LossDetection`] timer expired. So there is an un-acknowledged packet -3092 /// that was followed by an acknowledged packet. The loss timer for this -3093 /// un-acknowledged packet expired and we need to detect that packet as lost. -3094 /// -3095 /// Packets are lost if they are both (See RFC9002 §6.1): -3096 /// -3097 /// - Unacknowledged, in flight and sent prior to an acknowledged packet. -3098 /// - Old enough by either: -3099 /// - Having a packet number [`TransportConfig::packet_threshold`] lower then the last -3100 /// acknowledged packet. -3101 /// - Being sent [`TransportConfig::time_threshold`] * RTT in the past. -3102 fn detect_lost_packets( -3103 &mut self, -3104 now: Instant, -3105 pn_space: SpaceId, -3106 path_id: PathId, -3107 due_to_ack: bool, -3108 ) { -3109 let mut lost_packets = Vec::<u64>::new(); -3110 let mut lost_mtu_probe = None; -3111 let mut in_persistent_congestion = false; -3112 let mut size_of_lost_packets = 0u64; -3113 self.spaces[pn_space].for_path(path_id).loss_time = None; -3114 -3115 // Find all the lost packets, populating all variables initialised above. -3116 -3117 let path = self.path_data(path_id); -3118 let in_flight_mtu_probe = path.mtud.in_flight_mtu_probe(); -3119 let loss_delay = path -3120 .rtt -3121 .conservative() -3122 .mul_f32(self.config.time_threshold) -3123 .max(TIMER_GRANULARITY); -3124 let first_packet_after_rtt_sample = path.first_packet_after_rtt_sample; -3125 -3126 let largest_acked_packet = self.spaces[pn_space] -3127 .for_path(path_id) -3128 .largest_acked_packet -3129 .expect("detect_lost_packets only to be called if path received at least one ACK"); -3130 let packet_threshold = self.config.packet_threshold as u64; -3131 -3132 // InPersistentCongestion: Determine if all packets in the time period before the newest -3133 // lost packet, including the edges, are marked lost. PTO computation must always -3134 // include max ACK delay, i.e. operate as if in Data space (see RFC9001 §7.6.1). -3135 let congestion_period = self -3136 .pto(SpaceKind::Data, path_id) -3137 .saturating_mul(self.config.persistent_congestion_threshold); -3138 let mut persistent_congestion_start: Option<Instant> = None; -3139 let mut prev_packet = None; -3140 let space = self.spaces[pn_space].for_path(path_id); -3141 -3142 for (packet, info) in space.sent_packets.iter_range(0..largest_acked_packet) { -3143 if prev_packet != Some(packet.wrapping_sub(1)) { -3144 // An intervening packet was acknowledged -3145 persistent_congestion_start = None; -3146 } -3147 -3148 // Packets sent before now - loss_delay are deemed lost. -3149 // However, we avoid subtraction as it can panic and there's no -3150 // saturating equivalent of this subtraction operation with a Duration. -3151 let packet_too_old = now.saturating_duration_since(info.time_sent) >= loss_delay; -3152 if packet_too_old || largest_acked_packet >= packet + packet_threshold { -3153 // The packet should be declared lost. -3154 if Some(packet) == in_flight_mtu_probe { -3155 // Lost MTU probes are not included in `lost_packets`, because they -3156 // should not trigger a congestion control response -3157 lost_mtu_probe = in_flight_mtu_probe; -3158 } else { -3159 lost_packets.push(packet); -3160 size_of_lost_packets += info.size as u64; -3161 if info.ack_eliciting && due_to_ack { -3162 match persistent_congestion_start { -3163 // Two ACK-eliciting packets lost more than -3164 // congestion_period apart, with no ACKed packets in between -3165 Some(start) if info.time_sent - start > congestion_period => { -3166 in_persistent_congestion = true; -3167 } -3168 // Persistent congestion must start after the first RTT sample -3169 None if first_packet_after_rtt_sample -3170 .is_some_and(|x| x < (pn_space.kind(), packet)) => -3171 { -3172 persistent_congestion_start = Some(info.time_sent); -3173 } -3174 _ => {} -3175 } -3176 } -3177 } -3178 } else { -3179 // The packet should not yet be declared lost. -3180 if space.loss_time.is_none() { -3181 // Since we iterate in order the lowest packet number's loss time will -3182 // always be the earliest. -3183 space.loss_time = Some(info.time_sent + loss_delay); -3184 } -3185 persistent_congestion_start = None; -3186 } -3187 -3188 prev_packet = Some(packet); -3189 } -3190 -3191 self.handle_lost_packets( -3192 pn_space, -3193 path_id, -3194 now, -3195 lost_packets, -3196 lost_mtu_probe, -3197 loss_delay, -3198 in_persistent_congestion, -3199 size_of_lost_packets, -3200 ); -3201 } -3202 -3203 /// Drops the path state, declaring any remaining in-flight packets as lost -3204 fn discard_path(&mut self, path_id: PathId, now: Instant) { -3205 trace!(%path_id, "dropping path state"); -3206 let path = self.path_data(path_id); -3207 let in_flight_mtu_probe = path.mtud.in_flight_mtu_probe(); -3208 -3209 let mut size_of_lost_packets = 0u64; // add to path_stats.lost_bytes; -3210 let lost_pns: Vec<_> = self.spaces[SpaceId::Data] -3211 .for_path(path_id) -3212 .sent_packets -3213 .iter() -3214 .filter(|(pn, _info)| Some(*pn) != in_flight_mtu_probe) -3215 .map(|(pn, info)| { -3216 size_of_lost_packets += info.size as u64; -3217 pn -3218 }) -3219 .collect(); +2884 path_data +2885 .congestion +2886 .on_end_acks(now, in_flight, app_limited, largest_ackd); +2887 +2888 if new_largest && ack_eliciting_acked { +2889 let ack_delay = if space != SpaceId::Data { +2890 Duration::from_micros(0) +2891 } else { +2892 cmp::min( +2893 self.ack_frequency.peer_max_ack_delay, +2894 Duration::from_micros(ack.delay << self.peer_params.ack_delay_exponent.0), +2895 ) +2896 }; +2897 let rtt = now.saturating_duration_since( +2898 self.spaces[space].for_path(path).largest_acked_packet_sent, +2899 ); +2900 +2901 let next_pn = self.spaces[space].for_path(path).next_packet_number; +2902 let path_data = self.path_data_mut(path); +2903 // TODO(@divma): should be a method of path, should be contained in a single place +2904 path_data.rtt.update(ack_delay, rtt); +2905 if path_data.first_packet_after_rtt_sample.is_none() { +2906 path_data.first_packet_after_rtt_sample = Some((space.kind(), next_pn)); +2907 } +2908 } +2909 +2910 // Must be called before crypto/pto_count are clobbered +2911 self.detect_lost_packets(now, space, path, true); +2912 +2913 // If the peer did not complete the handshake address validation the ACK could be +2914 // spoofed, e.g. in the Initial space. Setting the pto_count back to 0 removes the +2915 // exponential backoff from the PTO timer and would result in too many tail-loss +2916 // probes being sent. +2917 if self.peer_completed_handshake_address_validation() { +2918 self.path_data_mut(path).pto_count = 0; +2919 } +2920 +2921 // Explicit congestion notification +2922 // TODO(@divma): this code is a good example of logic that should be contained in a single +2923 // place but it's split between the path data and the packet number space data, we should +2924 // find a way to make this work without two lookups +2925 if self.path_data(path).sending_ecn { +2926 if let Some(ecn) = ack.ecn { +2927 // We only examine ECN counters from ACKs that we are certain we received in transmit +2928 // order, allowing us to compute an increase in ECN counts to compare against the number +2929 // of newly acked packets that remains well-defined in the presence of arbitrary packet +2930 // reordering. +2931 if new_largest { +2932 let sent = self.spaces[space].for_path(path).largest_acked_packet_sent; +2933 self.process_ecn(now, space, path, newly_acked.len() as u64, ecn, sent); +2934 } +2935 } else { +2936 // We always start out sending ECN, so any ack that doesn't acknowledge it disables it. +2937 debug!("ECN not acknowledged by peer"); +2938 self.path_data_mut(path).sending_ecn = false; +2939 } +2940 } +2941 +2942 self.set_loss_detection_timer(now, path); +2943 Ok(()) +2944 } +2945 +2946 fn detect_spurious_loss(&mut self, ack: &frame::Ack, space: SpaceId, path: PathId) -> bool { +2947 let lost_packets = &mut self.spaces[space].for_path(path).lost_packets; +2948 +2949 if lost_packets.is_empty() { +2950 return false; +2951 } +2952 +2953 for range in ack.iter() { +2954 let spurious_losses: Vec<u64> = lost_packets +2955 .iter_range(range.clone()) +2956 .map(|(pn, _info)| pn) +2957 .collect(); +2958 +2959 for pn in spurious_losses { +2960 lost_packets.remove(pn); +2961 } +2962 } +2963 +2964 // If this ACK frame acknowledged all deemed lost packets, +2965 // then we have raised a spurious congestion event in the past. +2966 // We cannot conclude when there are remaining packets, +2967 // but future ACK frames might indicate a spurious loss detection. +2968 lost_packets.is_empty() +2969 } +2970 +2971 /// Drain lost packets that we reasonably think will never arrive +2972 /// +2973 /// The current criterion is copied from `msquic`: +2974 /// discard packets that were sent earlier than 2 probe timeouts ago. +2975 fn drain_lost_packets(&mut self, now: Instant, space: SpaceId, path: PathId) { +2976 let two_pto = 2 * self.path_data(path).rtt.pto_base(); +2977 +2978 let lost_packets = &mut self.spaces[space].for_path(path).lost_packets; +2979 lost_packets.retain(|_pn, info| now.saturating_duration_since(info.time_sent) <= two_pto); +2980 } +2981 +2982 /// Process a new ECN block from an in-order ACK +2983 fn process_ecn( +2984 &mut self, +2985 now: Instant, +2986 space: SpaceId, +2987 path: PathId, +2988 newly_acked: u64, +2989 ecn: frame::EcnCounts, +2990 largest_sent_time: Instant, +2991 ) { +2992 match self.spaces[space] +2993 .for_path(path) +2994 .detect_ecn(newly_acked, ecn) +2995 { +2996 Err(e) => { +2997 debug!("halting ECN due to verification failure: {}", e); +2998 +2999 self.path_data_mut(path).sending_ecn = false; +3000 // Wipe out the existing value because it might be garbage and could interfere with +3001 // future attempts to use ECN on new paths. +3002 self.spaces[space].for_path(path).ecn_feedback = frame::EcnCounts::ZERO; +3003 } +3004 Ok(false) => {} +3005 Ok(true) => { +3006 self.path_stats.for_path(path).congestion_events += 1; +3007 self.path_data_mut(path).congestion.on_congestion_event( +3008 now, +3009 largest_sent_time, +3010 false, +3011 true, +3012 0, +3013 ); +3014 } +3015 } +3016 } +3017 +3018 // Not timing-aware, so it's safe to call this for inferred acks, such as arise from +3019 // high-latency handshakes +3020 fn on_packet_acked(&mut self, now: Instant, path_id: PathId, info: SentPacket) { +3021 let app_limited = self.app_limited; +3022 let path = self.path_data_mut(path_id); +3023 path.remove_in_flight(&info); +3024 if info.ack_eliciting && info.path_generation == path.generation() { +3025 // Only pass ACKs to the congestion controller if it belongs to this exact +3026 // generation of the path. Otherwise we might be feeding ACKs from the previous +3027 // 4-tuple into our congestion controller. +3028 let rtt = path.rtt; +3029 path.congestion +3030 .on_ack(now, info.time_sent, info.size.into(), app_limited, &rtt); +3031 } +3032 +3033 // Update state for confirmed delivery of frames +3034 if let Some(retransmits) = info.retransmits.get() { +3035 for (id, _) in retransmits.reset_stream.iter() { +3036 self.streams.reset_acked(*id); +3037 } +3038 } +3039 +3040 for frame in info.stream_frames { +3041 self.streams.received_ack_of(frame); +3042 } +3043 } +3044 +3045 fn set_key_discard_timer(&mut self, now: Instant, space: SpaceKind) { +3046 let start = if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) { +3047 now +3048 } else { +3049 self.crypto_state +3050 .prev_crypto +3051 .as_ref() +3052 .expect("no previous keys") +3053 .end_packet +3054 .as_ref() +3055 .expect("update not acknowledged yet") +3056 .1 +3057 }; +3058 +3059 // QUIC-MULTIPATH § 2.5 Key Phase Update Process: use largest PTO of all paths. +3060 self.timers.set( +3061 Timer::Conn(ConnTimer::KeyDiscard), +3062 start + self.max_pto_for_space(space) * 3, +3063 self.qlog.with_time(now), +3064 ); +3065 } +3066 +3067 /// Handle a [`PathTimer::LossDetection`] timeout. +3068 /// +3069 /// This timer expires for two reasons: +3070 /// - An ACK-eliciting packet we sent should be considered lost. +3071 /// - The PTO may have expired and a tail-loss probe needs to be scheduled. +3072 /// +3073 /// The former needs us to schedule re-transmission of the lost data. +3074 /// +3075 /// The latter means we have not received an ACK for an ack-eliciting packet we sent +3076 /// within the PTO time-window. We need to schedule a tail-loss probe, an ack-eliciting +3077 /// packet, to try and elicit new acknowledgements. These new acknowledgements will +3078 /// indicate whether the previously sent packets were lost or not. +3079 fn on_loss_detection_timeout(&mut self, now: Instant, path_id: PathId) { +3080 if let Some((_, pn_space)) = self.loss_time_and_space(path_id) { +3081 // Time threshold loss Detection +3082 self.detect_lost_packets(now, pn_space, path_id, false); +3083 self.set_loss_detection_timer(now, path_id); +3084 return; +3085 } +3086 +3087 let Some((_, space)) = self.pto_time_and_space(now, path_id) else { +3088 error!(%path_id, "PTO expired while unset"); +3089 return; +3090 }; +3091 trace!( +3092 in_flight = self.path_data(path_id).in_flight.bytes, +3093 count = self.path_data(path_id).pto_count, +3094 ?space, +3095 %path_id, +3096 "PTO fired" +3097 ); +3098 +3099 let count = match self.path_data(path_id).in_flight.ack_eliciting { +3100 // A PTO when we're not expecting any ACKs must be due to handshake +3101 // anti-amplification deadlock prevention. +3102 0 => { +3103 debug_assert!(!self.peer_completed_handshake_address_validation()); +3104 1 +3105 } +3106 // Conventional loss probe +3107 _ => 2, +3108 }; +3109 let pns = self.spaces[space].for_path(path_id); +3110 pns.loss_probes = pns.loss_probes.saturating_add(count); +3111 let path_data = self.path_data_mut(path_id); +3112 path_data.pto_count = path_data.pto_count.saturating_add(1); +3113 self.set_loss_detection_timer(now, path_id); +3114 } +3115 +3116 /// Detect any lost packets +3117 /// +3118 /// There are two cases in which we detects lost packets: +3119 /// +3120 /// - We received an ACK packet. +3121 /// - The [`PathTimer::LossDetection`] timer expired. So there is an un-acknowledged packet +3122 /// that was followed by an acknowledged packet. The loss timer for this +3123 /// un-acknowledged packet expired and we need to detect that packet as lost. +3124 /// +3125 /// Packets are lost if they are both (See RFC9002 §6.1): +3126 /// +3127 /// - Unacknowledged, in flight and sent prior to an acknowledged packet. +3128 /// - Old enough by either: +3129 /// - Having a packet number [`TransportConfig::packet_threshold`] lower then the last +3130 /// acknowledged packet. +3131 /// - Being sent [`TransportConfig::time_threshold`] * RTT in the past. +3132 fn detect_lost_packets( +3133 &mut self, +3134 now: Instant, +3135 pn_space: SpaceId, +3136 path_id: PathId, +3137 due_to_ack: bool, +3138 ) { +3139 let mut lost_packets = Vec::<u64>::new(); +3140 let mut lost_mtu_probe = None; +3141 let mut in_persistent_congestion = false; +3142 let mut size_of_lost_packets = 0u64; +3143 self.spaces[pn_space].for_path(path_id).loss_time = None; +3144 +3145 // Find all the lost packets, populating all variables initialised above. +3146 +3147 let path = self.path_data(path_id); +3148 let in_flight_mtu_probe = path.mtud.in_flight_mtu_probe(); +3149 let loss_delay = path +3150 .rtt +3151 .conservative() +3152 .mul_f32(self.config.time_threshold) +3153 .max(TIMER_GRANULARITY); +3154 let first_packet_after_rtt_sample = path.first_packet_after_rtt_sample; +3155 +3156 let largest_acked_packet = self.spaces[pn_space] +3157 .for_path(path_id) +3158 .largest_acked_packet +3159 .expect("detect_lost_packets only to be called if path received at least one ACK"); +3160 let packet_threshold = self.config.packet_threshold as u64; +3161 +3162 // InPersistentCongestion: Determine if all packets in the time period before the newest +3163 // lost packet, including the edges, are marked lost. PTO computation must always +3164 // include max ACK delay, i.e. operate as if in Data space (see RFC9001 §7.6.1). +3165 let congestion_period = self +3166 .pto(SpaceKind::Data, path_id) +3167 .saturating_mul(self.config.persistent_congestion_threshold); +3168 let mut persistent_congestion_start: Option<Instant> = None; +3169 let mut prev_packet = None; +3170 let space = self.spaces[pn_space].for_path(path_id); +3171 +3172 for (packet, info) in space.sent_packets.iter_range(0..largest_acked_packet) { +3173 if prev_packet != Some(packet.wrapping_sub(1)) { +3174 // An intervening packet was acknowledged +3175 persistent_congestion_start = None; +3176 } +3177 +3178 // Packets sent before now - loss_delay are deemed lost. +3179 // However, we avoid subtraction as it can panic and there's no +3180 // saturating equivalent of this subtraction operation with a Duration. +3181 let packet_too_old = now.saturating_duration_since(info.time_sent) >= loss_delay; +3182 if packet_too_old || largest_acked_packet >= packet + packet_threshold { +3183 // The packet should be declared lost. +3184 if Some(packet) == in_flight_mtu_probe { +3185 // Lost MTU probes are not included in `lost_packets`, because they +3186 // should not trigger a congestion control response +3187 lost_mtu_probe = in_flight_mtu_probe; +3188 } else { +3189 lost_packets.push(packet); +3190 size_of_lost_packets += info.size as u64; +3191 if info.ack_eliciting && due_to_ack { +3192 match persistent_congestion_start { +3193 // Two ACK-eliciting packets lost more than +3194 // congestion_period apart, with no ACKed packets in between +3195 Some(start) if info.time_sent - start > congestion_period => { +3196 in_persistent_congestion = true; +3197 } +3198 // Persistent congestion must start after the first RTT sample +3199 None if first_packet_after_rtt_sample +3200 .is_some_and(|x| x < (pn_space.kind(), packet)) => +3201 { +3202 persistent_congestion_start = Some(info.time_sent); +3203 } +3204 _ => {} +3205 } +3206 } +3207 } +3208 } else { +3209 // The packet should not yet be declared lost. +3210 if space.loss_time.is_none() { +3211 // Since we iterate in order the lowest packet number's loss time will +3212 // always be the earliest. +3213 space.loss_time = Some(info.time_sent + loss_delay); +3214 } +3215 persistent_congestion_start = None; +3216 } +3217 +3218 prev_packet = Some(packet); +3219 } 3220 -3221 if !lost_pns.is_empty() { -3222 trace!( -3223 %path_id, -3224 count = lost_pns.len(), -3225 lost_bytes = size_of_lost_packets, -3226 "packets lost on path abandon" -3227 ); -3228 self.handle_lost_packets( -3229 SpaceId::Data, -3230 path_id, -3231 now, -3232 lost_pns, -3233 in_flight_mtu_probe, -3234 Duration::ZERO, -3235 false, -3236 size_of_lost_packets, -3237 ); -3238 } -3239 // Before removing the path, we fetch the final path stats via `Self::path_stats`. -3240 // This updates some values for the last time. -3241 let path_stats = self.path_stats.discard(&path_id); -3242 self.partial_stats += path_stats; -3243 self.paths.remove(&path_id); -3244 self.spaces[SpaceId::Data].number_spaces.remove(&path_id); -3245 -3246 self.events.push_back( -3247 PathEvent::Discarded { -3248 id: path_id, -3249 path_stats: Box::new(path_stats), -3250 } -3251 .into(), -3252 ); -3253 } -3254 -3255 fn handle_lost_packets( -3256 &mut self, -3257 pn_space: SpaceId, -3258 path_id: PathId, -3259 now: Instant, -3260 lost_packets: Vec<u64>, -3261 lost_mtu_probe: Option<u64>, -3262 loss_delay: Duration, -3263 in_persistent_congestion: bool, -3264 size_of_lost_packets: u64, -3265 ) { -3266 debug_assert!( -3267 { -3268 let mut sorted = lost_packets.clone(); -3269 sorted.sort(); -3270 sorted == lost_packets -3271 }, -3272 "lost_packets must be sorted" -3273 ); -3274 -3275 self.drain_lost_packets(now, pn_space, path_id); -3276 -3277 // OnPacketsLost -3278 if let Some(largest_lost) = lost_packets.last().cloned() { -3279 let old_bytes_in_flight = self.path_data_mut(path_id).in_flight.bytes; -3280 let largest_lost_sent = self.spaces[pn_space] -3281 .for_path(path_id) -3282 .sent_packets -3283 .get(largest_lost) -3284 .unwrap() -3285 .time_sent; -3286 let path_stats = self.path_stats.for_path(path_id); -3287 path_stats.lost_packets += lost_packets.len() as u64; -3288 path_stats.lost_bytes += size_of_lost_packets; -3289 trace!( -3290 %path_id, -3291 count = lost_packets.len(), -3292 lost_bytes = size_of_lost_packets, -3293 "packets lost", -3294 ); -3295 -3296 for &packet in &lost_packets { -3297 let Some(info) = self.spaces[pn_space].for_path(path_id).take(packet) else { -3298 continue; -3299 }; -3300 self.qlog -3301 .emit_packet_lost(packet, &info, loss_delay, pn_space.kind(), now); -3302 self.paths -3303 .get_mut(&path_id) -3304 .unwrap() -3305 .remove_in_flight(&info); +3221 self.handle_lost_packets( +3222 pn_space, +3223 path_id, +3224 now, +3225 lost_packets, +3226 lost_mtu_probe, +3227 loss_delay, +3228 in_persistent_congestion, +3229 size_of_lost_packets, +3230 ); +3231 } +3232 +3233 /// Drops the path state, declaring any remaining in-flight packets as lost +3234 fn discard_path(&mut self, path_id: PathId, now: Instant) { +3235 trace!(%path_id, "dropping path state"); +3236 let path = self.path_data(path_id); +3237 let in_flight_mtu_probe = path.mtud.in_flight_mtu_probe(); +3238 +3239 let mut size_of_lost_packets = 0u64; // add to path_stats.lost_bytes; +3240 let lost_pns: Vec<_> = self.spaces[SpaceId::Data] +3241 .for_path(path_id) +3242 .sent_packets +3243 .iter() +3244 .filter(|(pn, _info)| Some(*pn) != in_flight_mtu_probe) +3245 .map(|(pn, info)| { +3246 size_of_lost_packets += info.size as u64; +3247 pn +3248 }) +3249 .collect(); +3250 +3251 if !lost_pns.is_empty() { +3252 trace!( +3253 %path_id, +3254 count = lost_pns.len(), +3255 lost_bytes = size_of_lost_packets, +3256 "packets lost on path abandon" +3257 ); +3258 self.handle_lost_packets( +3259 SpaceId::Data, +3260 path_id, +3261 now, +3262 lost_pns, +3263 in_flight_mtu_probe, +3264 Duration::ZERO, +3265 false, +3266 size_of_lost_packets, +3267 ); +3268 } +3269 // Before removing the path, we fetch the final path stats via `Self::path_stats`. +3270 // This updates some values for the last time. +3271 let path_stats = self.path_stats.discard(&path_id); +3272 self.partial_stats += path_stats; +3273 self.paths.remove(&path_id); +3274 self.spaces[SpaceId::Data].number_spaces.remove(&path_id); +3275 +3276 self.events.push_back( +3277 PathEvent::Discarded { +3278 id: path_id, +3279 path_stats: Box::new(path_stats), +3280 } +3281 .into(), +3282 ); +3283 } +3284 +3285 fn handle_lost_packets( +3286 &mut self, +3287 pn_space: SpaceId, +3288 path_id: PathId, +3289 now: Instant, +3290 lost_packets: Vec<u64>, +3291 lost_mtu_probe: Option<u64>, +3292 loss_delay: Duration, +3293 in_persistent_congestion: bool, +3294 size_of_lost_packets: u64, +3295 ) { +3296 debug_assert!( +3297 { +3298 let mut sorted = lost_packets.clone(); +3299 sorted.sort(); +3300 sorted == lost_packets +3301 }, +3302 "lost_packets must be sorted" +3303 ); +3304 +3305 self.drain_lost_packets(now, pn_space, path_id); 3306 -3307 for frame in info.stream_frames { -3308 self.streams.retransmit(frame); -3309 } -3310 self.spaces[pn_space].pending |= info.retransmits; -3311 self.path_data_mut(path_id) -3312 .mtud -3313 .on_non_probe_lost(packet, info.size); -3314 -3315 self.spaces[pn_space].for_path(path_id).lost_packets.insert( -3316 packet, -3317 LostPacket { -3318 time_sent: info.time_sent, -3319 }, -3320 ); -3321 } -3322 -3323 let path = self.path_data_mut(path_id); -3324 if path.mtud.black_hole_detected(now) { -3325 path.congestion.on_mtu_update(path.mtud.current_mtu()); -3326 if let Some(max_datagram_size) = self.datagrams().max_size() -3327 && self.datagrams.drop_oversized(max_datagram_size) -3328 && self.datagrams.send_blocked -3329 { -3330 self.datagrams.send_blocked = false; -3331 self.events.push_back(Event::DatagramsUnblocked); -3332 } -3333 self.path_stats.for_path(path_id).black_holes_detected += 1; -3334 } -3335 -3336 // Don't apply congestion penalty for lost ack-only packets -3337 let lost_ack_eliciting = -3338 old_bytes_in_flight != self.path_data_mut(path_id).in_flight.bytes; -3339 -3340 if lost_ack_eliciting { -3341 self.path_stats.for_path(path_id).congestion_events += 1; -3342 self.path_data_mut(path_id).congestion.on_congestion_event( -3343 now, -3344 largest_lost_sent, -3345 in_persistent_congestion, -3346 false, -3347 size_of_lost_packets, -3348 ); -3349 } -3350 } -3351 -3352 // Handle a lost MTU probe -3353 if let Some(packet) = lost_mtu_probe { -3354 let info = self.spaces[SpaceId::Data] -3355 .for_path(path_id) -3356 .take(packet) -3357 .unwrap(); // safe: lost_mtu_probe is omitted from lost_packets, and -3358 // therefore must not have been removed yet -3359 self.paths -3360 .get_mut(&path_id) -3361 .unwrap() -3362 .remove_in_flight(&info); -3363 self.path_data_mut(path_id).mtud.on_probe_lost(); -3364 self.path_stats.for_path(path_id).lost_plpmtud_probes += 1; -3365 } -3366 } -3367 -3368 /// Returns the earliest time packets should be declared lost for all spaces on a path. -3369 /// -3370 /// If a path has an acknowledged packet with any prior un-acknowledged packets, the -3371 /// earliest un-acknowledged packet can be declared lost after a timeout has elapsed. -3372 /// The time returned is when this packet should be declared lost. -3373 fn loss_time_and_space(&self, path_id: PathId) -> Option<(Instant, SpaceId)> { -3374 SpaceId::iter() -3375 .filter_map(|id| { -3376 self.spaces[id] -3377 .number_spaces -3378 .get(&path_id) -3379 .and_then(|pns| pns.loss_time) -3380 .map(|time| (time, id)) -3381 }) -3382 .min_by_key(|&(time, _)| time) -3383 } -3384 -3385 /// Returns the earliest next PTO should fire for all spaces on a path. -3386 fn pto_time_and_space(&mut self, now: Instant, path_id: PathId) -> Option<(Instant, SpaceId)> { -3387 let path = self.path(path_id)?; -3388 let pto_count = path.pto_count; -3389 let backoff = 2u32.pow(pto_count.min(MAX_BACKOFF_EXPONENT)); -3390 let mut duration = path.rtt.pto_base() * backoff; -3391 -3392 if path_id == PathId::ZERO -3393 && path.in_flight.ack_eliciting == 0 -3394 && !self.peer_completed_address_validation(PathId::ZERO) -3395 { -3396 // Address Validation during Connection Establishment: -3397 // https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1. To prevent a -3398 // deadlock if an Initial or Handshake packet from the server is lost and the -3399 // server can not send more due to its anti-amplification limit the client must -3400 // send another packet on PTO. -3401 let space = match self.highest_space { -3402 SpaceKind::Handshake => SpaceId::Handshake, -3403 _ => SpaceId::Initial, -3404 }; -3405 -3406 return Some((now + duration, space)); -3407 } -3408 -3409 let mut result = None; -3410 for space in SpaceId::iter() { -3411 let Some(pns) = self.spaces[space].number_spaces.get(&path_id) else { -3412 continue; -3413 }; +3307 // OnPacketsLost +3308 if let Some(largest_lost) = lost_packets.last().cloned() { +3309 let old_bytes_in_flight = self.path_data_mut(path_id).in_flight.bytes; +3310 let largest_lost_sent = self.spaces[pn_space] +3311 .for_path(path_id) +3312 .sent_packets +3313 .get(largest_lost) +3314 .unwrap() +3315 .time_sent; +3316 let path_stats = self.path_stats.for_path(path_id); +3317 path_stats.lost_packets += lost_packets.len() as u64; +3318 path_stats.lost_bytes += size_of_lost_packets; +3319 trace!( +3320 %path_id, +3321 count = lost_packets.len(), +3322 lost_bytes = size_of_lost_packets, +3323 "packets lost", +3324 ); +3325 +3326 for &packet in &lost_packets { +3327 let Some(info) = self.spaces[pn_space].for_path(path_id).take(packet) else { +3328 continue; +3329 }; +3330 self.qlog +3331 .emit_packet_lost(packet, &info, loss_delay, pn_space.kind(), now); +3332 self.paths +3333 .get_mut(&path_id) +3334 .unwrap() +3335 .remove_in_flight(&info); +3336 +3337 for frame in info.stream_frames { +3338 self.streams.retransmit(frame); +3339 } +3340 self.spaces[pn_space].pending |= info.retransmits; +3341 self.path_data_mut(path_id) +3342 .mtud +3343 .on_non_probe_lost(packet, info.size); +3344 +3345 self.spaces[pn_space].for_path(path_id).lost_packets.insert( +3346 packet, +3347 LostPacket { +3348 time_sent: info.time_sent, +3349 }, +3350 ); +3351 } +3352 +3353 let path = self.path_data_mut(path_id); +3354 if path.mtud.black_hole_detected(now) { +3355 path.congestion.on_mtu_update(path.mtud.current_mtu()); +3356 if let Some(max_datagram_size) = self.datagrams().max_size() +3357 && self.datagrams.drop_oversized(max_datagram_size) +3358 && self.datagrams.send_blocked +3359 { +3360 self.datagrams.send_blocked = false; +3361 self.events.push_back(Event::DatagramsUnblocked); +3362 } +3363 self.path_stats.for_path(path_id).black_holes_detected += 1; +3364 } +3365 +3366 // Don't apply congestion penalty for lost ack-only packets +3367 let lost_ack_eliciting = +3368 old_bytes_in_flight != self.path_data_mut(path_id).in_flight.bytes; +3369 +3370 if lost_ack_eliciting { +3371 self.path_stats.for_path(path_id).congestion_events += 1; +3372 self.path_data_mut(path_id).congestion.on_congestion_event( +3373 now, +3374 largest_lost_sent, +3375 in_persistent_congestion, +3376 false, +3377 size_of_lost_packets, +3378 ); +3379 } +3380 } +3381 +3382 // Handle a lost MTU probe +3383 if let Some(packet) = lost_mtu_probe { +3384 let info = self.spaces[SpaceId::Data] +3385 .for_path(path_id) +3386 .take(packet) +3387 .unwrap(); // safe: lost_mtu_probe is omitted from lost_packets, and +3388 // therefore must not have been removed yet +3389 self.paths +3390 .get_mut(&path_id) +3391 .unwrap() +3392 .remove_in_flight(&info); +3393 self.path_data_mut(path_id).mtud.on_probe_lost(); +3394 self.path_stats.for_path(path_id).lost_plpmtud_probes += 1; +3395 } +3396 } +3397 +3398 /// Returns the earliest time packets should be declared lost for all spaces on a path. +3399 /// +3400 /// If a path has an acknowledged packet with any prior un-acknowledged packets, the +3401 /// earliest un-acknowledged packet can be declared lost after a timeout has elapsed. +3402 /// The time returned is when this packet should be declared lost. +3403 fn loss_time_and_space(&self, path_id: PathId) -> Option<(Instant, SpaceId)> { +3404 SpaceId::iter() +3405 .filter_map(|id| { +3406 self.spaces[id] +3407 .number_spaces +3408 .get(&path_id) +3409 .and_then(|pns| pns.loss_time) +3410 .map(|time| (time, id)) +3411 }) +3412 .min_by_key(|&(time, _)| time) +3413 } 3414 -3415 if !pns.has_in_flight() { -3416 continue; -3417 } -3418 if space == SpaceId::Data { -3419 // Skip ApplicationData until handshake completes. -3420 if self.is_handshaking() { -3421 return result; -3422 } -3423 // Include max_ack_delay and backoff for ApplicationData. -3424 duration += self.ack_frequency.max_ack_delay_for_pto() * backoff; -3425 } -3426 let Some(last_ack_eliciting) = pns.time_of_last_ack_eliciting_packet else { -3427 continue; -3428 }; -3429 let pto = last_ack_eliciting + duration; -3430 if result.is_none_or(|(earliest_pto, _)| pto < earliest_pto) { -3431 if path.anti_amplification_blocked(1) { -3432 // Nothing would be able to be sent. -3433 continue; -3434 } -3435 if path.in_flight.ack_eliciting == 0 { -3436 // Nothing ack-eliciting, no PTO to arm/fire. -3437 continue; -3438 } -3439 result = Some((pto, space)); -3440 } -3441 } -3442 result -3443 } +3415 /// Returns the earliest next PTO should fire for all spaces on a path. +3416 fn pto_time_and_space(&mut self, now: Instant, path_id: PathId) -> Option<(Instant, SpaceId)> { +3417 let path = self.path(path_id)?; +3418 let pto_count = path.pto_count; +3419 let backoff = 2u32.pow(pto_count.min(MAX_BACKOFF_EXPONENT)); +3420 let mut duration = path.rtt.pto_base() * backoff; +3421 +3422 if path_id == PathId::ZERO +3423 && path.in_flight.ack_eliciting == 0 +3424 && !self.peer_completed_handshake_address_validation() +3425 { +3426 // Address Validation during Connection Establishment: +3427 // https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1. To prevent a +3428 // deadlock if an Initial or Handshake packet from the server is lost and the +3429 // server can not send more due to its anti-amplification limit the client must +3430 // send another packet on PTO. +3431 let space = match self.highest_space { +3432 SpaceKind::Handshake => SpaceId::Handshake, +3433 _ => SpaceId::Initial, +3434 }; +3435 +3436 return Some((now + duration, space)); +3437 } +3438 +3439 let mut result = None; +3440 for space in SpaceId::iter() { +3441 let Some(pns) = self.spaces[space].number_spaces.get(&path_id) else { +3442 continue; +3443 }; 3444 -3445 fn peer_completed_address_validation(&self, path: PathId) -> bool { -3446 // TODO(flub): This logic needs updating for multipath -3447 if self.side.is_server() || self.state.is_closed() { -3448 return true; -3449 } -3450 // The server is guaranteed to have validated our address if any of our handshake or 1-RTT -3451 // packets are acknowledged or we've seen HANDSHAKE_DONE and discarded handshake keys. -3452 self.spaces[SpaceId::Handshake] -3453 .path_space(PathId::ZERO) -3454 .and_then(|pns| pns.largest_acked_packet) -3455 .is_some() -3456 || self.spaces[SpaceId::Data] -3457 .path_space(path) -3458 .and_then(|pns| pns.largest_acked_packet) -3459 .is_some() -3460 || (self.crypto_state.has_keys(EncryptionLevel::OneRtt) -3461 && !self.crypto_state.has_keys(EncryptionLevel::Handshake)) -3462 } -3463 -3464 /// Resets the the [`PathTimer::LossDetection`] timer to the next instant it may be needed -3465 /// -3466 /// The timer must fire if either: -3467 /// - An ack-eliciting packet we sent needs to be declared lost. -3468 /// - A tail-loss probe needs to be sent. -3469 /// -3470 /// See [`Connection::on_loss_detection_timeout`] for details. -3471 fn set_loss_detection_timer(&mut self, now: Instant, path_id: PathId) { -3472 if self.state.is_closed() { -3473 // No loss detection takes place on closed connections, and `close_common` already -3474 // stopped time timer. Ensure we don't restart it inadvertently, e.g. in response to a -3475 // reordered packet being handled by state-insensitive code. -3476 return; -3477 } -3478 -3479 if let Some((loss_time, _)) = self.loss_time_and_space(path_id) { -3480 // Time threshold loss detection. -3481 self.timers.set( -3482 Timer::PerPath(path_id, PathTimer::LossDetection), -3483 loss_time, -3484 self.qlog.with_time(now), -3485 ); -3486 return; -3487 } -3488 -3489 // Determine which PN space to arm PTO for. -3490 // Calculate PTO duration -3491 if let Some((timeout, _)) = self.pto_time_and_space(now, path_id) { -3492 self.timers.set( -3493 Timer::PerPath(path_id, PathTimer::LossDetection), -3494 timeout, -3495 self.qlog.with_time(now), -3496 ); -3497 } else { -3498 self.timers.stop( -3499 Timer::PerPath(path_id, PathTimer::LossDetection), -3500 self.qlog.with_time(now), -3501 ); -3502 } -3503 } -3504 -3505 /// The maximum probe timeout across all paths -3506 /// -3507 /// See [`Connection::pto`] -3508 fn max_pto_for_space(&self, space: SpaceKind) -> Duration { -3509 self.paths -3510 .keys() -3511 .map(|path_id| self.pto(space, *path_id)) -3512 .max() -3513 .unwrap_or_else(|| { -3514 // No paths remain (e.g. last path was abandoned and the NoAvailablePath grace timer -3515 // fired before any new path was opened). Fall back to a PTO derived from the -3516 // configured initial RTT, matching RFC 9002 §6.2.2 initial values. -3517 let rtt = self.config.initial_rtt; -3518 let max_ack_delay = match space { -3519 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, -3520 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), -3521 }; -3522 rtt + cmp::max(4 * (rtt / 2), TIMER_GRANULARITY) + max_ack_delay -3523 }) -3524 } -3525 -3526 /// Probe Timeout -3527 /// -3528 /// The PTO is logically the time in which you'd expect to receive an acknowledgement -3529 /// for a packet. So approximately RTT + max_ack_delay. -3530 fn pto(&self, space: SpaceKind, path_id: PathId) -> Duration { -3531 let max_ack_delay = match space { -3532 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, -3533 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), -3534 }; -3535 self.path_data(path_id).rtt.pto_base() + max_ack_delay -3536 } -3537 -3538 fn on_packet_authenticated( -3539 &mut self, -3540 now: Instant, -3541 space_id: SpaceKind, -3542 path_id: PathId, -3543 ecn: Option<EcnCodepoint>, -3544 packet: Option<u64>, -3545 spin: bool, -3546 is_1rtt: bool, -3547 ) { -3548 self.total_authed_packets += 1; -3549 self.reset_keep_alive(path_id, now); -3550 self.reset_idle_timeout(now, space_id, path_id); -3551 self.permit_idle_reset = true; -3552 self.receiving_ecn |= ecn.is_some(); -3553 if let Some(x) = ecn { -3554 let space = &mut self.spaces[space_id]; -3555 space.for_path(path_id).ecn_counters += x; +3445 if !pns.has_in_flight() { +3446 continue; +3447 } +3448 if space == SpaceId::Data { +3449 // Skip ApplicationData until handshake completes. +3450 if self.is_handshaking() { +3451 return result; +3452 } +3453 // Include max_ack_delay and backoff for ApplicationData. +3454 duration += self.ack_frequency.max_ack_delay_for_pto() * backoff; +3455 } +3456 let Some(last_ack_eliciting) = pns.time_of_last_ack_eliciting_packet else { +3457 continue; +3458 }; +3459 let pto = last_ack_eliciting + duration; +3460 if result.is_none_or(|(earliest_pto, _)| pto < earliest_pto) { +3461 if path.anti_amplification_blocked(1) { +3462 // Nothing would be able to be sent. +3463 continue; +3464 } +3465 if path.in_flight.ack_eliciting == 0 { +3466 // Nothing ack-eliciting, no PTO to arm/fire. +3467 continue; +3468 } +3469 result = Some((pto, space)); +3470 } +3471 } +3472 result +3473 } +3474 +3475 /// Whether the peer validated our address in the connection handshake. +3476 fn peer_completed_handshake_address_validation(&self) -> bool { +3477 if self.side.is_server() || self.state.is_closed() { +3478 return true; +3479 } +3480 // The server is guaranteed to have validated our address if any of our handshake or +3481 // 1-RTT packets are acknowledged or we've seen HANDSHAKE_DONE and discarded +3482 // handshake keys. +3483 self.spaces[SpaceId::Handshake] +3484 .path_space(PathId::ZERO) +3485 .and_then(|pns| pns.largest_acked_packet) +3486 .is_some() +3487 || self.spaces[SpaceId::Data] +3488 .path_space(PathId::ZERO) +3489 .and_then(|pns| pns.largest_acked_packet) +3490 .is_some() +3491 || (self.crypto_state.has_keys(EncryptionLevel::OneRtt) +3492 && !self.crypto_state.has_keys(EncryptionLevel::Handshake)) +3493 } +3494 +3495 /// Resets the the [`PathTimer::LossDetection`] timer to the next instant it may be needed +3496 /// +3497 /// The timer must fire if either: +3498 /// - An ack-eliciting packet we sent needs to be declared lost. +3499 /// - A tail-loss probe needs to be sent. +3500 /// +3501 /// See [`Connection::on_loss_detection_timeout`] for details. +3502 fn set_loss_detection_timer(&mut self, now: Instant, path_id: PathId) { +3503 if self.state.is_closed() { +3504 // No loss detection takes place on closed connections, and `close_common` already +3505 // stopped time timer. Ensure we don't restart it inadvertently, e.g. in response to a +3506 // reordered packet being handled by state-insensitive code. +3507 return; +3508 } +3509 +3510 if let Some((loss_time, _)) = self.loss_time_and_space(path_id) { +3511 // Time threshold loss detection. +3512 self.timers.set( +3513 Timer::PerPath(path_id, PathTimer::LossDetection), +3514 loss_time, +3515 self.qlog.with_time(now), +3516 ); +3517 return; +3518 } +3519 +3520 // Determine which PN space to arm PTO for. +3521 // Calculate PTO duration +3522 if let Some((timeout, _)) = self.pto_time_and_space(now, path_id) { +3523 self.timers.set( +3524 Timer::PerPath(path_id, PathTimer::LossDetection), +3525 timeout, +3526 self.qlog.with_time(now), +3527 ); +3528 } else { +3529 self.timers.stop( +3530 Timer::PerPath(path_id, PathTimer::LossDetection), +3531 self.qlog.with_time(now), +3532 ); +3533 } +3534 } +3535 +3536 /// The maximum probe timeout across all paths +3537 /// +3538 /// See [`Connection::pto`] +3539 fn max_pto_for_space(&self, space: SpaceKind) -> Duration { +3540 self.paths +3541 .keys() +3542 .map(|path_id| self.pto(space, *path_id)) +3543 .max() +3544 .unwrap_or_else(|| { +3545 // No paths remain (e.g. last path was abandoned and the NoAvailablePath grace timer +3546 // fired before any new path was opened). Fall back to a PTO derived from the +3547 // configured initial RTT, matching RFC 9002 §6.2.2 initial values. +3548 let rtt = self.config.initial_rtt; +3549 let max_ack_delay = match space { +3550 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, +3551 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), +3552 }; +3553 rtt + cmp::max(4 * (rtt / 2), TIMER_GRANULARITY) + max_ack_delay +3554 }) +3555 } 3556 -3557 if x.is_ce() { -3558 space -3559 .for_path(path_id) -3560 .pending_acks -3561 .set_immediate_ack_required(); -3562 } -3563 } -3564 -3565 let Some(packet) = packet else { -3566 return; -3567 }; -3568 match &self.side { -3569 ConnectionSide::Client { .. } => { -3570 // If we received a handshake packet that authenticated, then we're talking to -3571 // the real server. From now on we should no longer allow the server to migrate -3572 // its address. -3573 if space_id == SpaceKind::Handshake -3574 && let Some(hs) = self.state.as_handshake_mut() -3575 { -3576 hs.allow_server_migration = false; -3577 } -3578 } -3579 ConnectionSide::Server { .. } => { -3580 if self.crypto_state.has_keys(EncryptionLevel::Initial) -3581 && space_id == SpaceKind::Handshake -3582 { -3583 // A server stops sending and processing Initial packets when it receives its first Handshake packet. -3584 self.discard_space(now, SpaceKind::Initial); -3585 } -3586 if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) && is_1rtt { -3587 // Discard 0-RTT keys soon after receiving a 1-RTT packet -3588 self.set_key_discard_timer(now, space_id) -3589 } -3590 } -3591 } -3592 let space = self.spaces[space_id].for_path(path_id); -3593 space.pending_acks.insert_one(packet, now); -3594 if packet >= space.rx_packet.unwrap_or_default() { -3595 space.rx_packet = Some(packet); -3596 // Update outgoing spin bit, inverting iff we're the client -3597 self.spin = self.side.is_client() ^ spin; -3598 } -3599 } -3600 -3601 /// Resets the idle timeout timers -3602 /// -3603 /// Without multipath there is only the connection-wide idle timeout. When multipath is -3604 /// enabled there is an additional per-path idle timeout. -3605 fn reset_idle_timeout(&mut self, now: Instant, space: SpaceKind, path_id: PathId) { -3606 // First reset the global idle timeout. -3607 if let Some(timeout) = self.idle_timeout { -3608 if self.state.is_closed() { -3609 self.timers -3610 .stop(Timer::Conn(ConnTimer::Idle), self.qlog.with_time(now)); -3611 } else { -3612 let dt = cmp::max(timeout, 3 * self.max_pto_for_space(space)); -3613 self.timers.set( -3614 Timer::Conn(ConnTimer::Idle), -3615 now + dt, -3616 self.qlog.with_time(now), -3617 ); -3618 } -3619 } -3620 -3621 // Now handle the per-path state -3622 if let Some(timeout) = self.path_data(path_id).idle_timeout { -3623 if self.state.is_closed() { -3624 self.timers.stop( -3625 Timer::PerPath(path_id, PathTimer::PathIdle), -3626 self.qlog.with_time(now), -3627 ); -3628 } else { -3629 let dt = cmp::max(timeout, 3 * self.pto(space, path_id)); -3630 self.timers.set( -3631 Timer::PerPath(path_id, PathTimer::PathIdle), -3632 now + dt, -3633 self.qlog.with_time(now), -3634 ); -3635 } -3636 } -3637 } -3638 -3639 /// Resets both the [`ConnTimer::KeepAlive`] and [`PathTimer::PathKeepAlive`] timers -3640 fn reset_keep_alive(&mut self, path_id: PathId, now: Instant) { -3641 if !self.state.is_established() { -3642 return; -3643 } -3644 -3645 if let Some(interval) = self.config.keep_alive_interval { -3646 self.timers.set( -3647 Timer::Conn(ConnTimer::KeepAlive), -3648 now + interval, -3649 self.qlog.with_time(now), -3650 ); -3651 } -3652 -3653 if let Some(interval) = self.path_data(path_id).keep_alive { -3654 self.timers.set( -3655 Timer::PerPath(path_id, PathTimer::PathKeepAlive), -3656 now + interval, -3657 self.qlog.with_time(now), -3658 ); -3659 } -3660 } -3661 -3662 /// Sets the timer for when a previously issued CID should be retired next -3663 fn reset_cid_retirement(&mut self, now: Instant) { -3664 if let Some((_path, t)) = self.next_cid_retirement() { -3665 self.timers.set( -3666 Timer::Conn(ConnTimer::PushNewCid), -3667 t, -3668 self.qlog.with_time(now), -3669 ); -3670 } -3671 } -3672 -3673 /// The next time when a previously issued CID should be retired -3674 fn next_cid_retirement(&self) -> Option<(PathId, Instant)> { -3675 self.local_cid_state -3676 .iter() -3677 .filter_map(|(path_id, cid_state)| cid_state.next_timeout().map(|t| (*path_id, t))) -3678 .min_by_key(|(_path_id, timeout)| *timeout) -3679 } -3680 -3681 /// Handle the already-decrypted first packet from the client -3682 /// -3683 /// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more -3684 /// efficient. -3685 pub(crate) fn handle_first_packet( -3686 &mut self, -3687 now: Instant, -3688 network_path: FourTuple, -3689 ecn: Option<EcnCodepoint>, -3690 packet_number: u64, -3691 packet: InitialPacket, -3692 remaining: Option<BytesMut>, -3693 ) -> Result<(), ConnectionError> { -3694 let span = trace_span!("first recv"); -3695 let _guard = span.enter(); -3696 debug_assert!(self.side.is_server()); -3697 let len = packet.header_data.len() + packet.payload.len(); -3698 let path_id = PathId::ZERO; -3699 self.path_data_mut(path_id).total_recvd = len as u64; -3700 -3701 if let Some(hs) = self.state.as_handshake_mut() { -3702 hs.expected_token = packet.header.token.clone(); -3703 } else { -3704 unreachable!("first packet must be delivered in Handshake state"); -3705 } -3706 -3707 // The first packet is always on PathId::ZERO -3708 self.on_packet_authenticated( -3709 now, -3710 SpaceKind::Initial, -3711 path_id, -3712 ecn, -3713 Some(packet_number), -3714 false, -3715 false, -3716 ); -3717 -3718 let packet: Packet = packet.into(); -3719 -3720 let mut qlog = QlogRecvPacket::new(len); -3721 qlog.header(&packet.header, Some(packet_number), path_id); -3722 -3723 self.process_decrypted_packet( -3724 now, -3725 network_path, -3726 path_id, -3727 Some(packet_number), -3728 packet, -3729 &mut qlog, -3730 )?; -3731 self.qlog.emit_packet_received(qlog, now); -3732 if let Some(data) = remaining { -3733 self.handle_coalesced(now, network_path, path_id, ecn, data); -3734 } -3735 -3736 self.qlog.emit_recovery_metrics( -3737 path_id, -3738 &mut self.paths.get_mut(&path_id).unwrap().data, -3739 now, -3740 ); -3741 -3742 Ok(()) -3743 } -3744 -3745 fn init_0rtt(&mut self, now: Instant) { -3746 let Some((header, packet)) = self.crypto_state.session.early_crypto() else { -3747 return; -3748 }; -3749 if self.side.is_client() { -3750 match self.crypto_state.session.transport_parameters() { -3751 Ok(params) => { -3752 let params = params -3753 .expect("crypto layer didn't supply transport parameters with ticket"); -3754 // Certain values must not be cached -3755 let params = TransportParameters { -3756 initial_src_cid: None, -3757 original_dst_cid: None, -3758 preferred_address: None, -3759 retry_src_cid: None, -3760 stateless_reset_token: None, -3761 min_ack_delay: None, -3762 ack_delay_exponent: TransportParameters::default().ack_delay_exponent, -3763 max_ack_delay: TransportParameters::default().max_ack_delay, -3764 initial_max_path_id: None, -3765 ..params -3766 }; -3767 self.set_peer_params(params); -3768 self.qlog.emit_peer_transport_params_restored(self, now); -3769 } -3770 Err(e) => { -3771 error!("session ticket has malformed transport parameters: {}", e); -3772 return; -3773 } -3774 } -3775 } -3776 trace!("0-RTT enabled"); -3777 self.crypto_state.enable_zero_rtt(header, packet); -3778 } -3779 -3780 fn read_crypto( -3781 &mut self, -3782 space: SpaceId, -3783 crypto: &frame::Crypto, -3784 payload_len: usize, -3785 ) -> Result<(), TransportError> { -3786 let expected = if !self.state.is_handshake() { -3787 SpaceId::Data -3788 } else if self.highest_space == SpaceKind::Initial { -3789 SpaceId::Initial -3790 } else { -3791 // On the server, self.highest_space can be Data after receiving the client's first -3792 // flight, but we expect Handshake CRYPTO until the handshake is complete. -3793 SpaceId::Handshake -3794 }; -3795 // We can't decrypt Handshake packets when highest_space is Initial, CRYPTO frames in 0-RTT -3796 // packets are illegal, and we don't process 1-RTT packets until the handshake is -3797 // complete. Therefore, we will never see CRYPTO data from a later-than-expected space. -3798 debug_assert!(space <= expected, "received out-of-order CRYPTO data"); -3799 -3800 let end = crypto.offset + crypto.data.len() as u64; -3801 if space < expected -3802 && end -3803 > self.crypto_state.spaces[space.kind()] -3804 .crypto_stream -3805 .bytes_read() -3806 { -3807 warn!( -3808 "received new {:?} CRYPTO data when expecting {:?}", -3809 space, expected -3810 ); -3811 return Err(TransportError::PROTOCOL_VIOLATION( -3812 "new data at unexpected encryption level", -3813 )); -3814 } -3815 -3816 let crypto_space = &mut self.crypto_state.spaces[space.kind()]; -3817 let max = end.saturating_sub(crypto_space.crypto_stream.bytes_read()); -3818 if max > self.config.crypto_buffer_size as u64 { -3819 return Err(TransportError::CRYPTO_BUFFER_EXCEEDED("")); -3820 } -3821 -3822 crypto_space -3823 .crypto_stream -3824 .insert(crypto.offset, crypto.data.clone(), payload_len); -3825 while let Some(chunk) = crypto_space.crypto_stream.read(usize::MAX, true) { -3826 trace!("consumed {} CRYPTO bytes", chunk.bytes.len()); -3827 if self.crypto_state.session.read_handshake(&chunk.bytes)? { -3828 self.events.push_back(Event::HandshakeDataReady); -3829 } -3830 } -3831 -3832 Ok(()) -3833 } -3834 -3835 fn write_crypto(&mut self) { -3836 loop { -3837 let space = self.highest_space; -3838 let mut outgoing = Vec::new(); -3839 if let Some(crypto) = self.crypto_state.session.write_handshake(&mut outgoing) { -3840 match space { -3841 SpaceKind::Initial => { -3842 self.upgrade_crypto(SpaceKind::Handshake, crypto); -3843 } -3844 SpaceKind::Handshake => { -3845 self.upgrade_crypto(SpaceKind::Data, crypto); -3846 } -3847 SpaceKind::Data => unreachable!("got updated secrets during 1-RTT"), -3848 } -3849 } -3850 if outgoing.is_empty() { -3851 if space == self.highest_space { -3852 break; -3853 } else { -3854 // Keys updated, check for more data to send -3855 continue; -3856 } -3857 } -3858 let offset = self.crypto_state.spaces[space].crypto_offset; -3859 let outgoing = Bytes::from(outgoing); -3860 if let Some(hs) = self.state.as_handshake_mut() -3861 && space == SpaceKind::Initial -3862 && offset == 0 -3863 && self.side.is_client() -3864 { -3865 hs.client_hello = Some(outgoing.clone()); -3866 } -3867 self.crypto_state.spaces[space].crypto_offset += outgoing.len() as u64; -3868 trace!("wrote {} {:?} CRYPTO bytes", outgoing.len(), space); -3869 self.spaces[space].pending.crypto.push_back(frame::Crypto { -3870 offset, -3871 data: outgoing, -3872 }); -3873 } -3874 } -3875 -3876 /// Switch to stronger cryptography during handshake -3877 fn upgrade_crypto(&mut self, space: SpaceKind, crypto: Keys) { -3878 debug_assert!( -3879 !self.crypto_state.has_keys(space.encryption_level()), -3880 "already reached packet space {space:?}" -3881 ); -3882 trace!("{:?} keys ready", space); -3883 if space == SpaceKind::Data { -3884 // Precompute the first key update -3885 self.crypto_state.next_crypto = Some( -3886 self.crypto_state -3887 .session -3888 .next_1rtt_keys() -3889 .expect("handshake should be complete"), -3890 ); -3891 } -3892 -3893 self.crypto_state.spaces[space].keys = Some(crypto); -3894 debug_assert!(space > self.highest_space); -3895 self.highest_space = space; -3896 if space == SpaceKind::Data && self.side.is_client() { -3897 // Discard 0-RTT keys because 1-RTT keys are available. -3898 self.crypto_state.discard_zero_rtt(); -3899 } -3900 } -3901 -3902 fn discard_space(&mut self, now: Instant, space: SpaceKind) { -3903 debug_assert!(space != SpaceKind::Data); -3904 trace!("discarding {:?} keys", space); -3905 if space == SpaceKind::Initial { -3906 // No longer needed -3907 if let ConnectionSide::Client { token, .. } = &mut self.side { -3908 *token = Bytes::new(); -3909 } -3910 } -3911 self.crypto_state.spaces[space].keys = None; -3912 let space = &mut self.spaces[space]; -3913 let pns = space.for_path(PathId::ZERO); -3914 pns.time_of_last_ack_eliciting_packet = None; -3915 pns.loss_time = None; -3916 pns.loss_probes = 0; -3917 let sent_packets = mem::take(&mut pns.sent_packets); -3918 let path = self.paths.get_mut(&PathId::ZERO).unwrap(); -3919 for (_, packet) in sent_packets.into_iter() { -3920 path.data.remove_in_flight(&packet); -3921 } -3922 -3923 self.set_loss_detection_timer(now, PathId::ZERO) -3924 } -3925 -3926 fn handle_coalesced( -3927 &mut self, -3928 now: Instant, -3929 network_path: FourTuple, -3930 path_id: PathId, -3931 ecn: Option<EcnCodepoint>, -3932 data: BytesMut, -3933 ) { -3934 self.path_data_mut(path_id) -3935 .inc_total_recvd(data.len() as u64); -3936 let mut remaining = Some(data); -3937 let cid_len = self -3938 .local_cid_state -3939 .values() -3940 .map(|cid_state| cid_state.cid_len()) -3941 .next() -3942 .expect("one cid_state must exist"); -3943 while let Some(data) = remaining { -3944 match PartialDecode::new( -3945 data, -3946 &FixedLengthConnectionIdParser::new(cid_len), -3947 &[self.version], -3948 self.endpoint_config.grease_quic_bit, -3949 ) { -3950 Ok((partial_decode, rest)) => { -3951 remaining = rest; -3952 self.handle_decode(now, network_path, path_id, ecn, partial_decode); -3953 } -3954 Err(e) => { -3955 trace!("malformed header: {}", e); -3956 return; -3957 } -3958 } -3959 } -3960 } -3961 -3962 fn handle_decode( -3963 &mut self, -3964 now: Instant, -3965 network_path: FourTuple, -3966 path_id: PathId, -3967 ecn: Option<EcnCodepoint>, -3968 partial_decode: PartialDecode, -3969 ) { -3970 let qlog = QlogRecvPacket::new(partial_decode.len()); -3971 if let Some(decoded) = self -3972 .crypto_state -3973 .unprotect_header(partial_decode, self.peer_params.stateless_reset_token) -3974 { -3975 self.handle_packet( -3976 now, -3977 network_path, -3978 path_id, -3979 ecn, -3980 decoded.packet, -3981 decoded.stateless_reset, -3982 qlog, -3983 ); -3984 } -3985 } -3986 -3987 fn handle_packet( -3988 &mut self, -3989 now: Instant, -3990 network_path: FourTuple, -3991 path_id: PathId, -3992 ecn: Option<EcnCodepoint>, -3993 packet: Option<Packet>, -3994 stateless_reset: bool, -3995 mut qlog: QlogRecvPacket, -3996 ) { -3997 self.path_stats.for_path(path_id).udp_rx.ios += 1; -3998 -3999 if let Some(ref packet) = packet { -4000 trace!( -4001 "got {:?} packet ({} bytes) from {} using id {}", -4002 packet.header.space(), -4003 packet.payload.len() + packet.header_data.len(), -4004 network_path, -4005 packet.header.dst_cid(), -4006 ); -4007 } -4008 -4009 if self.is_handshaking() { -4010 if path_id != PathId::ZERO { -4011 debug!(%network_path, %path_id, "discarding multipath packet during handshake"); -4012 return; -4013 } -4014 if network_path != self.path_data_mut(path_id).network_path { -4015 if let Some(hs) = self.state.as_handshake() { -4016 if hs.allow_server_migration { -4017 trace!(%network_path, prev = %self.path_data(path_id).network_path, "server migrated to new remote"); -4018 self.path_data_mut(path_id).network_path = network_path; -4019 self.qlog.emit_tuple_assigned(path_id, network_path, now); -4020 } else { -4021 debug!("discarding packet with unexpected remote during handshake"); -4022 return; -4023 } -4024 } else { -4025 debug!("discarding packet with unexpected remote during handshake"); -4026 return; -4027 } -4028 } -4029 } -4030 -4031 let was_closed = self.state.is_closed(); -4032 let was_drained = self.state.is_drained(); -4033 -4034 let decrypted = match packet { -4035 None => Err(None), -4036 Some(mut packet) => self -4037 .decrypt_packet(now, path_id, &mut packet) -4038 .map(move |number| (packet, number)), -4039 }; -4040 let result = match decrypted { -4041 _ if stateless_reset => { -4042 debug!("got stateless reset"); -4043 Err(ConnectionError::Reset) +3557 /// Probe Timeout +3558 /// +3559 /// The PTO is logically the time in which you'd expect to receive an acknowledgement +3560 /// for a packet. So approximately RTT + max_ack_delay. +3561 fn pto(&self, space: SpaceKind, path_id: PathId) -> Duration { +3562 let max_ack_delay = match space { +3563 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, +3564 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), +3565 }; +3566 self.path_data(path_id).rtt.pto_base() + max_ack_delay +3567 } +3568 +3569 fn on_packet_authenticated( +3570 &mut self, +3571 now: Instant, +3572 space_id: SpaceKind, +3573 path_id: PathId, +3574 ecn: Option<EcnCodepoint>, +3575 packet: Option<u64>, +3576 spin: bool, +3577 is_1rtt: bool, +3578 ) { +3579 self.total_authed_packets += 1; +3580 self.reset_keep_alive(path_id, now); +3581 self.reset_idle_timeout(now, space_id, path_id); +3582 self.permit_idle_reset = true; +3583 self.receiving_ecn |= ecn.is_some(); +3584 if let Some(x) = ecn { +3585 let space = &mut self.spaces[space_id]; +3586 space.for_path(path_id).ecn_counters += x; +3587 +3588 if x.is_ce() { +3589 space +3590 .for_path(path_id) +3591 .pending_acks +3592 .set_immediate_ack_required(); +3593 } +3594 } +3595 +3596 let Some(packet) = packet else { +3597 return; +3598 }; +3599 match &self.side { +3600 ConnectionSide::Client { .. } => { +3601 // If we received a handshake packet that authenticated, then we're talking to +3602 // the real server. From now on we should no longer allow the server to migrate +3603 // its address. +3604 if space_id == SpaceKind::Handshake +3605 && let Some(hs) = self.state.as_handshake_mut() +3606 { +3607 hs.allow_server_migration = false; +3608 } +3609 } +3610 ConnectionSide::Server { .. } => { +3611 if self.crypto_state.has_keys(EncryptionLevel::Initial) +3612 && space_id == SpaceKind::Handshake +3613 { +3614 // A server stops sending and processing Initial packets when it receives its first Handshake packet. +3615 self.discard_space(now, SpaceKind::Initial); +3616 } +3617 if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) && is_1rtt { +3618 // Discard 0-RTT keys soon after receiving a 1-RTT packet +3619 self.set_key_discard_timer(now, space_id) +3620 } +3621 } +3622 } +3623 let space = self.spaces[space_id].for_path(path_id); +3624 space.pending_acks.insert_one(packet, now); +3625 if packet >= space.rx_packet.unwrap_or_default() { +3626 space.rx_packet = Some(packet); +3627 // Update outgoing spin bit, inverting iff we're the client +3628 self.spin = self.side.is_client() ^ spin; +3629 } +3630 } +3631 +3632 /// Resets the idle timeout timers +3633 /// +3634 /// Without multipath there is only the connection-wide idle timeout. When multipath is +3635 /// enabled there is an additional per-path idle timeout. +3636 fn reset_idle_timeout(&mut self, now: Instant, space: SpaceKind, path_id: PathId) { +3637 // First reset the global idle timeout. +3638 if let Some(timeout) = self.idle_timeout { +3639 if self.state.is_closed() { +3640 self.timers +3641 .stop(Timer::Conn(ConnTimer::Idle), self.qlog.with_time(now)); +3642 } else { +3643 let dt = cmp::max(timeout, 3 * self.max_pto_for_space(space)); +3644 self.timers.set( +3645 Timer::Conn(ConnTimer::Idle), +3646 now + dt, +3647 self.qlog.with_time(now), +3648 ); +3649 } +3650 } +3651 +3652 // Now handle the per-path state +3653 if let Some(timeout) = self.path_data(path_id).idle_timeout { +3654 if self.state.is_closed() { +3655 self.timers.stop( +3656 Timer::PerPath(path_id, PathTimer::PathIdle), +3657 self.qlog.with_time(now), +3658 ); +3659 } else { +3660 let dt = cmp::max(timeout, 3 * self.pto(space, path_id)); +3661 self.timers.set( +3662 Timer::PerPath(path_id, PathTimer::PathIdle), +3663 now + dt, +3664 self.qlog.with_time(now), +3665 ); +3666 } +3667 } +3668 } +3669 +3670 /// Resets both the [`ConnTimer::KeepAlive`] and [`PathTimer::PathKeepAlive`] timers +3671 fn reset_keep_alive(&mut self, path_id: PathId, now: Instant) { +3672 if !self.state.is_established() { +3673 return; +3674 } +3675 +3676 if let Some(interval) = self.config.keep_alive_interval { +3677 self.timers.set( +3678 Timer::Conn(ConnTimer::KeepAlive), +3679 now + interval, +3680 self.qlog.with_time(now), +3681 ); +3682 } +3683 +3684 if let Some(interval) = self.path_data(path_id).keep_alive { +3685 self.timers.set( +3686 Timer::PerPath(path_id, PathTimer::PathKeepAlive), +3687 now + interval, +3688 self.qlog.with_time(now), +3689 ); +3690 } +3691 } +3692 +3693 /// Sets the timer for when a previously issued CID should be retired next +3694 fn reset_cid_retirement(&mut self, now: Instant) { +3695 if let Some((_path, t)) = self.next_cid_retirement() { +3696 self.timers.set( +3697 Timer::Conn(ConnTimer::PushNewCid), +3698 t, +3699 self.qlog.with_time(now), +3700 ); +3701 } +3702 } +3703 +3704 /// The next time when a previously issued CID should be retired +3705 fn next_cid_retirement(&self) -> Option<(PathId, Instant)> { +3706 self.local_cid_state +3707 .iter() +3708 .filter_map(|(path_id, cid_state)| cid_state.next_timeout().map(|t| (*path_id, t))) +3709 .min_by_key(|(_path_id, timeout)| *timeout) +3710 } +3711 +3712 /// Handle the already-decrypted first packet from the client +3713 /// +3714 /// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more +3715 /// efficient. +3716 pub(crate) fn handle_first_packet( +3717 &mut self, +3718 now: Instant, +3719 network_path: FourTuple, +3720 ecn: Option<EcnCodepoint>, +3721 packet_number: u64, +3722 packet: InitialPacket, +3723 remaining: Option<BytesMut>, +3724 ) -> Result<(), ConnectionError> { +3725 let span = trace_span!("first recv"); +3726 let _guard = span.enter(); +3727 debug_assert!(self.side.is_server()); +3728 let len = packet.header_data.len() + packet.payload.len(); +3729 let path_id = PathId::ZERO; +3730 self.path_data_mut(path_id).total_recvd = len as u64; +3731 +3732 if let Some(hs) = self.state.as_handshake_mut() { +3733 hs.expected_token = packet.header.token.clone(); +3734 } else { +3735 unreachable!("first packet must be delivered in Handshake state"); +3736 } +3737 +3738 // The first packet is always on PathId::ZERO +3739 self.on_packet_authenticated( +3740 now, +3741 SpaceKind::Initial, +3742 path_id, +3743 ecn, +3744 Some(packet_number), +3745 false, +3746 false, +3747 ); +3748 +3749 let packet: Packet = packet.into(); +3750 +3751 let mut qlog = QlogRecvPacket::new(len); +3752 qlog.header(&packet.header, Some(packet_number), path_id); +3753 +3754 self.process_decrypted_packet( +3755 now, +3756 network_path, +3757 path_id, +3758 Some(packet_number), +3759 packet, +3760 &mut qlog, +3761 )?; +3762 self.qlog.emit_packet_received(qlog, now); +3763 if let Some(data) = remaining { +3764 self.handle_coalesced(now, network_path, path_id, ecn, data); +3765 } +3766 +3767 self.qlog.emit_recovery_metrics( +3768 path_id, +3769 &mut self.paths.get_mut(&path_id).unwrap().data, +3770 now, +3771 ); +3772 +3773 Ok(()) +3774 } +3775 +3776 fn init_0rtt(&mut self, now: Instant) { +3777 let Some((header, packet)) = self.crypto_state.session.early_crypto() else { +3778 return; +3779 }; +3780 if self.side.is_client() { +3781 match self.crypto_state.session.transport_parameters() { +3782 Ok(params) => { +3783 let params = params +3784 .expect("crypto layer didn't supply transport parameters with ticket"); +3785 // Certain values must not be cached +3786 let params = TransportParameters { +3787 initial_src_cid: None, +3788 original_dst_cid: None, +3789 preferred_address: None, +3790 retry_src_cid: None, +3791 stateless_reset_token: None, +3792 min_ack_delay: None, +3793 ack_delay_exponent: TransportParameters::default().ack_delay_exponent, +3794 max_ack_delay: TransportParameters::default().max_ack_delay, +3795 initial_max_path_id: None, +3796 ..params +3797 }; +3798 self.set_peer_params(params); +3799 self.qlog.emit_peer_transport_params_restored(self, now); +3800 } +3801 Err(e) => { +3802 error!("session ticket has malformed transport parameters: {}", e); +3803 return; +3804 } +3805 } +3806 } +3807 trace!("0-RTT enabled"); +3808 self.crypto_state.enable_zero_rtt(header, packet); +3809 } +3810 +3811 fn read_crypto( +3812 &mut self, +3813 space: SpaceId, +3814 crypto: &frame::Crypto, +3815 payload_len: usize, +3816 ) -> Result<(), TransportError> { +3817 let expected = if !self.state.is_handshake() { +3818 SpaceId::Data +3819 } else if self.highest_space == SpaceKind::Initial { +3820 SpaceId::Initial +3821 } else { +3822 // On the server, self.highest_space can be Data after receiving the client's first +3823 // flight, but we expect Handshake CRYPTO until the handshake is complete. +3824 SpaceId::Handshake +3825 }; +3826 // We can't decrypt Handshake packets when highest_space is Initial, CRYPTO frames in 0-RTT +3827 // packets are illegal, and we don't process 1-RTT packets until the handshake is +3828 // complete. Therefore, we will never see CRYPTO data from a later-than-expected space. +3829 debug_assert!(space <= expected, "received out-of-order CRYPTO data"); +3830 +3831 let end = crypto.offset + crypto.data.len() as u64; +3832 if space < expected +3833 && end +3834 > self.crypto_state.spaces[space.kind()] +3835 .crypto_stream +3836 .bytes_read() +3837 { +3838 warn!( +3839 "received new {:?} CRYPTO data when expecting {:?}", +3840 space, expected +3841 ); +3842 return Err(TransportError::PROTOCOL_VIOLATION( +3843 "new data at unexpected encryption level", +3844 )); +3845 } +3846 +3847 let crypto_space = &mut self.crypto_state.spaces[space.kind()]; +3848 let max = end.saturating_sub(crypto_space.crypto_stream.bytes_read()); +3849 if max > self.config.crypto_buffer_size as u64 { +3850 return Err(TransportError::CRYPTO_BUFFER_EXCEEDED("")); +3851 } +3852 +3853 crypto_space +3854 .crypto_stream +3855 .insert(crypto.offset, crypto.data.clone(), payload_len); +3856 while let Some(chunk) = crypto_space.crypto_stream.read(usize::MAX, true) { +3857 trace!("consumed {} CRYPTO bytes", chunk.bytes.len()); +3858 if self.crypto_state.session.read_handshake(&chunk.bytes)? { +3859 self.events.push_back(Event::HandshakeDataReady); +3860 } +3861 } +3862 +3863 Ok(()) +3864 } +3865 +3866 fn write_crypto(&mut self) { +3867 loop { +3868 let space = self.highest_space; +3869 let mut outgoing = Vec::new(); +3870 if let Some(crypto) = self.crypto_state.session.write_handshake(&mut outgoing) { +3871 match space { +3872 SpaceKind::Initial => { +3873 self.upgrade_crypto(SpaceKind::Handshake, crypto); +3874 } +3875 SpaceKind::Handshake => { +3876 self.upgrade_crypto(SpaceKind::Data, crypto); +3877 } +3878 SpaceKind::Data => unreachable!("got updated secrets during 1-RTT"), +3879 } +3880 } +3881 if outgoing.is_empty() { +3882 if space == self.highest_space { +3883 break; +3884 } else { +3885 // Keys updated, check for more data to send +3886 continue; +3887 } +3888 } +3889 let offset = self.crypto_state.spaces[space].crypto_offset; +3890 let outgoing = Bytes::from(outgoing); +3891 if let Some(hs) = self.state.as_handshake_mut() +3892 && space == SpaceKind::Initial +3893 && offset == 0 +3894 && self.side.is_client() +3895 { +3896 hs.client_hello = Some(outgoing.clone()); +3897 } +3898 self.crypto_state.spaces[space].crypto_offset += outgoing.len() as u64; +3899 trace!("wrote {} {:?} CRYPTO bytes", outgoing.len(), space); +3900 self.spaces[space].pending.crypto.push_back(frame::Crypto { +3901 offset, +3902 data: outgoing, +3903 }); +3904 } +3905 } +3906 +3907 /// Switch to stronger cryptography during handshake +3908 fn upgrade_crypto(&mut self, space: SpaceKind, crypto: Keys) { +3909 debug_assert!( +3910 !self.crypto_state.has_keys(space.encryption_level()), +3911 "already reached packet space {space:?}" +3912 ); +3913 trace!("{:?} keys ready", space); +3914 if space == SpaceKind::Data { +3915 // Precompute the first key update +3916 self.crypto_state.next_crypto = Some( +3917 self.crypto_state +3918 .session +3919 .next_1rtt_keys() +3920 .expect("handshake should be complete"), +3921 ); +3922 } +3923 +3924 self.crypto_state.spaces[space].keys = Some(crypto); +3925 debug_assert!(space > self.highest_space); +3926 self.highest_space = space; +3927 if space == SpaceKind::Data && self.side.is_client() { +3928 // Discard 0-RTT keys because 1-RTT keys are available. +3929 self.crypto_state.discard_zero_rtt(); +3930 } +3931 } +3932 +3933 fn discard_space(&mut self, now: Instant, space: SpaceKind) { +3934 debug_assert!(space != SpaceKind::Data); +3935 trace!("discarding {:?} keys", space); +3936 if space == SpaceKind::Initial { +3937 // No longer needed +3938 if let ConnectionSide::Client { token, .. } = &mut self.side { +3939 *token = Bytes::new(); +3940 } +3941 } +3942 self.crypto_state.spaces[space].keys = None; +3943 let space = &mut self.spaces[space]; +3944 let pns = space.for_path(PathId::ZERO); +3945 pns.time_of_last_ack_eliciting_packet = None; +3946 pns.loss_time = None; +3947 pns.loss_probes = 0; +3948 let sent_packets = mem::take(&mut pns.sent_packets); +3949 let path = self.paths.get_mut(&PathId::ZERO).unwrap(); +3950 for (_, packet) in sent_packets.into_iter() { +3951 path.data.remove_in_flight(&packet); +3952 } +3953 +3954 self.set_loss_detection_timer(now, PathId::ZERO) +3955 } +3956 +3957 fn handle_coalesced( +3958 &mut self, +3959 now: Instant, +3960 network_path: FourTuple, +3961 path_id: PathId, +3962 ecn: Option<EcnCodepoint>, +3963 data: BytesMut, +3964 ) { +3965 self.path_data_mut(path_id) +3966 .inc_total_recvd(data.len() as u64); +3967 let mut remaining = Some(data); +3968 let cid_len = self +3969 .local_cid_state +3970 .values() +3971 .map(|cid_state| cid_state.cid_len()) +3972 .next() +3973 .expect("one cid_state must exist"); +3974 while let Some(data) = remaining { +3975 match PartialDecode::new( +3976 data, +3977 &FixedLengthConnectionIdParser::new(cid_len), +3978 &[self.version], +3979 self.endpoint_config.grease_quic_bit, +3980 ) { +3981 Ok((partial_decode, rest)) => { +3982 remaining = rest; +3983 self.handle_decode(now, network_path, path_id, ecn, partial_decode); +3984 } +3985 Err(e) => { +3986 trace!("malformed header: {}", e); +3987 return; +3988 } +3989 } +3990 } +3991 } +3992 +3993 fn handle_decode( +3994 &mut self, +3995 now: Instant, +3996 network_path: FourTuple, +3997 path_id: PathId, +3998 ecn: Option<EcnCodepoint>, +3999 partial_decode: PartialDecode, +4000 ) { +4001 let qlog = QlogRecvPacket::new(partial_decode.len()); +4002 if let Some(decoded) = self +4003 .crypto_state +4004 .unprotect_header(partial_decode, self.peer_params.stateless_reset_token) +4005 { +4006 self.handle_packet( +4007 now, +4008 network_path, +4009 path_id, +4010 ecn, +4011 decoded.packet, +4012 decoded.stateless_reset, +4013 qlog, +4014 ); +4015 } +4016 } +4017 +4018 fn handle_packet( +4019 &mut self, +4020 now: Instant, +4021 network_path: FourTuple, +4022 path_id: PathId, +4023 ecn: Option<EcnCodepoint>, +4024 packet: Option<Packet>, +4025 stateless_reset: bool, +4026 mut qlog: QlogRecvPacket, +4027 ) { +4028 self.path_stats.for_path(path_id).udp_rx.ios += 1; +4029 +4030 if let Some(ref packet) = packet { +4031 trace!( +4032 "got {:?} packet ({} bytes) from {} using id {}", +4033 packet.header.space(), +4034 packet.payload.len() + packet.header_data.len(), +4035 network_path, +4036 packet.header.dst_cid(), +4037 ); +4038 } +4039 +4040 if self.is_handshaking() { +4041 if path_id != PathId::ZERO { +4042 debug!(%network_path, %path_id, "discarding multipath packet during handshake"); +4043 return; 4044 } -4045 Err(Some(e)) => { -4046 warn!("illegal packet: {}", e); -4047 Err(e.into()) -4048 } -4049 Err(None) => { -4050 debug!("failed to authenticate packet"); -4051 self.authentication_failures += 1; -4052 let integrity_limit = self -4053 .crypto_state -4054 .integrity_limit(self.highest_space) -4055 .unwrap(); -4056 if self.authentication_failures > integrity_limit { -4057 Err(TransportError::AEAD_LIMIT_REACHED("integrity limit violated").into()) -4058 } else { -4059 return; -4060 } -4061 } -4062 Ok((packet, number)) => { -4063 qlog.header(&packet.header, number, path_id); -4064 let span = match number { -4065 Some(pn) => trace_span!("recv", space = ?packet.header.space(), pn), -4066 None => trace_span!("recv", space = ?packet.header.space()), -4067 }; -4068 let _guard = span.enter(); -4069 -4070 let dedup = self.spaces[packet.header.space()] -4071 .path_space_mut(path_id) -4072 .map(|pns| &mut pns.dedup); -4073 if number.zip(dedup).is_some_and(|(n, d)| d.insert(n)) { -4074 debug!("discarding possible duplicate packet"); -4075 self.qlog.emit_packet_received(qlog, now); -4076 return; -4077 } else if self.state.is_handshake() && packet.header.is_short() { -4078 // TODO: SHOULD buffer these to improve reordering tolerance. -4079 trace!("dropping short packet during handshake"); -4080 self.qlog.emit_packet_received(qlog, now); -4081 return; -4082 } else { -4083 if let Header::Initial(InitialHeader { ref token, .. }) = packet.header -4084 && let Some(hs) = self.state.as_handshake() -4085 && self.side.is_server() -4086 && token != &hs.expected_token -4087 { -4088 // Clients must send the same retry token in every Initial. Initial -4089 // packets can be spoofed, so we discard rather than killing the -4090 // connection. -4091 warn!("discarding Initial with invalid retry token"); -4092 self.qlog.emit_packet_received(qlog, now); -4093 return; -4094 } -4095 -4096 if !self.state.is_closed() { -4097 let spin = match packet.header { -4098 Header::Short { spin, .. } => spin, -4099 _ => false, -4100 }; -4101 -4102 if self.side().is_server() && !self.abandoned_paths.contains(&path_id) { -4103 // Only the client is allowed to open paths -4104 self.ensure_path(path_id, network_path, now, number); -4105 } -4106 if self.paths.contains_key(&path_id) { -4107 self.on_packet_authenticated( -4108 now, -4109 packet.header.space(), -4110 path_id, -4111 ecn, -4112 number, -4113 spin, -4114 packet.header.is_1rtt(), -4115 ); -4116 } -4117 } -4118 -4119 let res = self.process_decrypted_packet( -4120 now, -4121 network_path, -4122 path_id, -4123 number, -4124 packet, -4125 &mut qlog, -4126 ); -4127 -4128 self.qlog.emit_packet_received(qlog, now); -4129 res -4130 } -4131 } -4132 }; -4133 -4134 // State transitions for error cases -4135 if let Err(conn_err) = result { -4136 match conn_err { -4137 ConnectionError::ApplicationClosed(reason) => self.state.move_to_closed(reason), -4138 ConnectionError::ConnectionClosed(reason) => self.state.move_to_closed(reason), -4139 ConnectionError::Reset -4140 | ConnectionError::TransportError(TransportError { -4141 code: TransportErrorCode::AEAD_LIMIT_REACHED, -4142 .. -4143 }) => { -4144 self.state.move_to_drained(Some(conn_err)); -4145 } -4146 ConnectionError::TimedOut => { -4147 unreachable!("timeouts aren't generated by packet processing"); -4148 } -4149 ConnectionError::TransportError(err) => { -4150 debug!("closing connection due to transport error: {}", err); -4151 self.state.move_to_closed(err); -4152 } -4153 ConnectionError::VersionMismatch => { -4154 self.state.move_to_draining(Some(conn_err)); -4155 } -4156 ConnectionError::LocallyClosed => { -4157 unreachable!("LocallyClosed isn't generated by packet processing"); -4158 } -4159 ConnectionError::CidsExhausted => { -4160 unreachable!("CidsExhausted isn't generated by packet processing"); +4045 if network_path != self.path_data_mut(path_id).network_path { +4046 if let Some(hs) = self.state.as_handshake() { +4047 if hs.allow_server_migration { +4048 trace!(%network_path, prev = %self.path_data(path_id).network_path, "server migrated to new remote"); +4049 self.path_data_mut(path_id).network_path = network_path; +4050 self.qlog.emit_tuple_assigned(path_id, network_path, now); +4051 } else { +4052 debug!("discarding packet with unexpected remote during handshake"); +4053 return; +4054 } +4055 } else { +4056 debug!("discarding packet with unexpected remote during handshake"); +4057 return; +4058 } +4059 } +4060 } +4061 +4062 let was_closed = self.state.is_closed(); +4063 let was_drained = self.state.is_drained(); +4064 +4065 let decrypted = match packet { +4066 None => Err(None), +4067 Some(mut packet) => self +4068 .decrypt_packet(now, path_id, &mut packet) +4069 .map(move |number| (packet, number)), +4070 }; +4071 let result = match decrypted { +4072 _ if stateless_reset => { +4073 debug!("got stateless reset"); +4074 Err(ConnectionError::Reset) +4075 } +4076 Err(Some(e)) => { +4077 warn!("illegal packet: {}", e); +4078 Err(e.into()) +4079 } +4080 Err(None) => { +4081 debug!("failed to authenticate packet"); +4082 self.authentication_failures += 1; +4083 let integrity_limit = self +4084 .crypto_state +4085 .integrity_limit(self.highest_space) +4086 .unwrap(); +4087 if self.authentication_failures > integrity_limit { +4088 Err(TransportError::AEAD_LIMIT_REACHED("integrity limit violated").into()) +4089 } else { +4090 return; +4091 } +4092 } +4093 Ok((packet, number)) => { +4094 qlog.header(&packet.header, number, path_id); +4095 let span = match number { +4096 Some(pn) => trace_span!("recv", space = ?packet.header.space(), pn), +4097 None => trace_span!("recv", space = ?packet.header.space()), +4098 }; +4099 let _guard = span.enter(); +4100 +4101 let dedup = self.spaces[packet.header.space()] +4102 .path_space_mut(path_id) +4103 .map(|pns| &mut pns.dedup); +4104 if number.zip(dedup).is_some_and(|(n, d)| d.insert(n)) { +4105 debug!("discarding possible duplicate packet"); +4106 self.qlog.emit_packet_received(qlog, now); +4107 return; +4108 } else if self.state.is_handshake() && packet.header.is_short() { +4109 // TODO: SHOULD buffer these to improve reordering tolerance. +4110 trace!("dropping short packet during handshake"); +4111 self.qlog.emit_packet_received(qlog, now); +4112 return; +4113 } else { +4114 if let Header::Initial(InitialHeader { ref token, .. }) = packet.header +4115 && let Some(hs) = self.state.as_handshake() +4116 && self.side.is_server() +4117 && token != &hs.expected_token +4118 { +4119 // Clients must send the same retry token in every Initial. Initial +4120 // packets can be spoofed, so we discard rather than killing the +4121 // connection. +4122 warn!("discarding Initial with invalid retry token"); +4123 self.qlog.emit_packet_received(qlog, now); +4124 return; +4125 } +4126 +4127 if !self.state.is_closed() { +4128 let spin = match packet.header { +4129 Header::Short { spin, .. } => spin, +4130 _ => false, +4131 }; +4132 +4133 if self.side().is_server() && !self.abandoned_paths.contains(&path_id) { +4134 // Only the client is allowed to open paths +4135 self.ensure_path(path_id, network_path, now, number); +4136 } +4137 if self.paths.contains_key(&path_id) { +4138 self.on_packet_authenticated( +4139 now, +4140 packet.header.space(), +4141 path_id, +4142 ecn, +4143 number, +4144 spin, +4145 packet.header.is_1rtt(), +4146 ); +4147 } +4148 } +4149 +4150 let res = self.process_decrypted_packet( +4151 now, +4152 network_path, +4153 path_id, +4154 number, +4155 packet, +4156 &mut qlog, +4157 ); +4158 +4159 self.qlog.emit_packet_received(qlog, now); +4160 res 4161 } -4162 }; -4163 } +4162 } +4163 }; 4164 -4165 if !was_closed && self.state.is_closed() { -4166 self.close_common(); -4167 if !self.state.is_drained() { -4168 self.set_close_timer(now); -4169 } -4170 } -4171 if !was_drained && self.state.is_drained() { -4172 self.endpoint_events.push_back(EndpointEventInner::Drained); -4173 // Close timer may have been started previously, e.g. if we sent a close and got a -4174 // stateless reset in response -4175 self.timers -4176 .stop(Timer::Conn(ConnTimer::Close), self.qlog.with_time(now)); -4177 } -4178 -4179 // Transmit CONNECTION_CLOSE if necessary. -4180 // -4181 // If we received a valid packet and we are in the closed state we should respond -4182 // with a CONNECTION_CLOSE frame. -4183 // TODO: This SHOULD be rate-limited according to §10.2.1 of QUIC-TRANSPORT, but -4184 // that does not yet happen. This is triggered by each received packet. -4185 if matches!(self.state.as_type(), StateType::Closed) { -4186 // From https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.1-7 -4187 // -4188 // While in the closing state we must either: -4189 // - discard packets coming from an un-validated remote OR -4190 // - ensure we do not send more than 3 times the received data -4191 // -4192 // Doing the 2nd would mean we would be able to send CONNECTION_CLOSE to a peer -4193 // who was (involuntary) migrated just at the time we initiated immediate -4194 // close. It is a lot more work though. So while we would like to do this for -4195 // now we only do 1. -4196 // -4197 // Another shortcoming of the current implementation is that when we have a -4198 // previous PathData which is validated and the remote matches that path, we -4199 // should schedule CONNECTION_CLOSE on that path. However currently we can not -4200 // schedule such a packet. We should also fix this some day. This makes us -4201 // vulnerable to an attacker faking a migration at the right time and then we'd -4202 // be unable to send the CONNECTION_CLOSE to the real remote. -4203 if self -4204 .paths -4205 .get(&path_id) -4206 .map(|p| p.data.validated && p.data.network_path == network_path) -4207 .unwrap_or(false) -4208 { -4209 self.connection_close_pending = true; -4210 } -4211 } -4212 } -4213 -4214 fn process_decrypted_packet( -4215 &mut self, -4216 now: Instant, -4217 network_path: FourTuple, -4218 path_id: PathId, -4219 number: Option<u64>, -4220 packet: Packet, -4221 qlog: &mut QlogRecvPacket, -4222 ) -> Result<(), ConnectionError> { -4223 if !self.paths.contains_key(&path_id) { -4224 // There is a chance this is a server side, first (for this path) packet, which would -4225 // be a protocol violation. It's more likely, however, that this is a packet of a -4226 // pruned path -4227 trace!(%path_id, ?number, "discarding packet for unknown path"); -4228 return Ok(()); -4229 } -4230 let state = match self.state.as_type() { -4231 StateType::Established => { -4232 match packet.header.space() { -4233 SpaceKind::Data => self.process_payload( -4234 now, -4235 network_path, -4236 path_id, -4237 number.unwrap(), -4238 packet, -4239 qlog, -4240 )?, -4241 _ if packet.header.has_frames() => { -4242 self.process_early_payload(now, path_id, packet, qlog)? -4243 } -4244 _ => { -4245 trace!("discarding unexpected pre-handshake packet"); -4246 } -4247 } -4248 return Ok(()); -4249 } -4250 StateType::Closed => { -4251 for result in frame::Iter::new(packet.payload.freeze())? { -4252 let frame = match result { -4253 Ok(frame) => frame, -4254 Err(err) => { -4255 debug!("frame decoding error: {err:?}"); -4256 continue; -4257 } -4258 }; -4259 qlog.frame(&frame); -4260 -4261 if let Frame::Padding = frame { -4262 continue; -4263 }; -4264 -4265 self.path_stats -4266 .for_path(path_id) -4267 .frame_rx -4268 .record(frame.ty()); -4269 -4270 if let Frame::Close(_error) = frame { -4271 self.state.move_to_draining(None); -4272 break; -4273 } -4274 } -4275 return Ok(()); -4276 } -4277 StateType::Draining | StateType::Drained => return Ok(()), -4278 StateType::Handshake => self.state.as_handshake_mut().expect("checked"), -4279 }; -4280 -4281 match packet.header { -4282 Header::Retry { -4283 src_cid: remote_cid, -4284 .. -4285 } => { -4286 debug_assert_eq!(path_id, PathId::ZERO); -4287 if self.side.is_server() { -4288 return Err(TransportError::PROTOCOL_VIOLATION("client sent Retry").into()); -4289 } -4290 -4291 let is_valid_retry = self -4292 .remote_cids -4293 .get(&path_id) -4294 .map(|cids| cids.active()) -4295 .map(|orig_dst_cid| { -4296 self.crypto_state.session.is_valid_retry( -4297 orig_dst_cid, -4298 &packet.header_data, -4299 &packet.payload, -4300 ) -4301 }) -4302 .unwrap_or_default(); -4303 if self.total_authed_packets > 1 -4304 || packet.payload.len() <= 16 // token + 16 byte tag -4305 || !is_valid_retry -4306 { -4307 trace!("discarding invalid Retry"); -4308 // - After the client has received and processed an Initial or Retry -4309 // packet from the server, it MUST discard any subsequent Retry -4310 // packets that it receives. -4311 // - A client MUST discard a Retry packet with a zero-length Retry Token -4312 // field. -4313 // - Clients MUST discard Retry packets that have a Retry Integrity Tag -4314 // that cannot be validated -4315 return Ok(()); -4316 } -4317 -4318 trace!("retrying with CID {}", remote_cid); -4319 let client_hello = state.client_hello.take().unwrap(); -4320 self.retry_src_cid = Some(remote_cid); -4321 self.remote_cids -4322 .get_mut(&path_id) -4323 .expect("PathId::ZERO not yet abandoned, is_valid_retry would have been false") -4324 .update_initial_cid(remote_cid); -4325 self.remote_handshake_cid = remote_cid; -4326 -4327 let space = &mut self.spaces[SpaceId::Initial]; -4328 if let Some(info) = space.for_path(PathId::ZERO).take(0) { -4329 self.on_packet_acked(now, PathId::ZERO, info); -4330 }; -4331 -4332 self.discard_space(now, SpaceKind::Initial); // Make sure we clean up after -4333 // any retransmitted Initials -4334 let crypto_space = &mut self.crypto_state.spaces[SpaceKind::Initial]; -4335 crypto_space.keys = Some( -4336 self.crypto_state -4337 .session -4338 .initial_keys(remote_cid, self.side.side()), -4339 ); -4340 crypto_space.crypto_offset = client_hello.len() as u64; -4341 -4342 let next_pn = self.spaces[SpaceId::Initial] -4343 .for_path(path_id) -4344 .next_packet_number; -4345 self.spaces[SpaceId::Initial] = { -4346 let mut space = PacketSpace::new(now, SpaceId::Initial, &mut self.rng); -4347 space.for_path(path_id).next_packet_number = next_pn; -4348 space.pending.crypto.push_back(frame::Crypto { -4349 offset: 0, -4350 data: client_hello, -4351 }); -4352 space -4353 }; -4354 -4355 // Retransmit all 0-RTT data -4356 let zero_rtt = mem::take( -4357 &mut self.spaces[SpaceId::Data] -4358 .for_path(PathId::ZERO) -4359 .sent_packets, -4360 ); -4361 for (_, info) in zero_rtt.into_iter() { -4362 self.paths -4363 .get_mut(&PathId::ZERO) -4364 .unwrap() -4365 .remove_in_flight(&info); -4366 self.spaces[SpaceId::Data].pending |= info.retransmits; -4367 } -4368 self.streams.retransmit_all_for_0rtt(); -4369 -4370 let token_len = packet.payload.len() - 16; -4371 let ConnectionSide::Client { ref mut token, .. } = self.side else { -4372 unreachable!("we already short-circuited if we're server"); -4373 }; -4374 *token = packet.payload.freeze().split_to(token_len); -4375 -4376 self.state = State::handshake(state::Handshake { -4377 expected_token: Bytes::new(), -4378 remote_cid_set: false, -4379 client_hello: None, -4380 allow_server_migration: true, -4381 }); -4382 Ok(()) -4383 } -4384 Header::Long { -4385 ty: LongType::Handshake, -4386 src_cid: remote_cid, -4387 dst_cid: local_cid, -4388 .. -4389 } => { -4390 debug_assert_eq!(path_id, PathId::ZERO); -4391 if remote_cid != self.remote_handshake_cid { -4392 debug!( -4393 "discarding packet with mismatched remote CID: {} != {}", -4394 self.remote_handshake_cid, remote_cid -4395 ); -4396 return Ok(()); -4397 } -4398 self.on_path_validated(path_id); -4399 -4400 self.process_early_payload(now, path_id, packet, qlog)?; -4401 if self.state.is_closed() { -4402 return Ok(()); -4403 } -4404 -4405 if self.crypto_state.session.is_handshaking() { -4406 trace!("handshake ongoing"); -4407 return Ok(()); -4408 } -4409 -4410 if self.side.is_client() { -4411 // Client-only because server params were set from the client's Initial -4412 let params = self -4413 .crypto_state -4414 .session -4415 .transport_parameters()? -4416 .ok_or_else(|| { -4417 TransportError::new( -4418 TransportErrorCode::crypto(0x6d), -4419 "transport parameters missing".to_owned(), -4420 ) -4421 })?; -4422 -4423 if self.has_0rtt() { -4424 if !self.crypto_state.session.early_data_accepted().unwrap() { -4425 debug_assert!(self.side.is_client()); -4426 debug!("0-RTT rejected"); -4427 self.crypto_state.accepted_0rtt = false; -4428 self.streams.zero_rtt_rejected(); -4429 -4430 // Discard already-queued frames -4431 self.spaces[SpaceId::Data].pending = Retransmits::default(); -4432 -4433 // Discard 0-RTT packets -4434 let sent_packets = mem::take( -4435 &mut self.spaces[SpaceId::Data].for_path(path_id).sent_packets, -4436 ); -4437 for (_, packet) in sent_packets.into_iter() { -4438 self.paths -4439 .get_mut(&path_id) -4440 .unwrap() -4441 .remove_in_flight(&packet); -4442 } -4443 } else { -4444 self.crypto_state.accepted_0rtt = true; -4445 params.validate_resumption_from(&self.peer_params)?; -4446 } -4447 } -4448 if let Some(token) = params.stateless_reset_token { -4449 let remote = self.path_data(path_id).network_path.remote; -4450 debug_assert!(!self.state.is_drained()); // requirement for endpoint events, checked above -4451 self.endpoint_events -4452 .push_back(EndpointEventInner::ResetToken(path_id, remote, token)); -4453 } -4454 self.handle_peer_params(params, local_cid, remote_cid, now)?; -4455 self.issue_first_cids(now); -4456 } else { -4457 // Server-only -4458 self.spaces[SpaceId::Data].pending.handshake_done = true; -4459 self.discard_space(now, SpaceKind::Handshake); -4460 self.events.push_back(Event::HandshakeConfirmed); -4461 trace!("handshake confirmed"); -4462 } +4165 // State transitions for error cases +4166 if let Err(conn_err) = result { +4167 match conn_err { +4168 ConnectionError::ApplicationClosed(reason) => self.state.move_to_closed(reason), +4169 ConnectionError::ConnectionClosed(reason) => self.state.move_to_closed(reason), +4170 ConnectionError::Reset +4171 | ConnectionError::TransportError(TransportError { +4172 code: TransportErrorCode::AEAD_LIMIT_REACHED, +4173 .. +4174 }) => { +4175 self.state.move_to_drained(Some(conn_err)); +4176 } +4177 ConnectionError::TimedOut => { +4178 unreachable!("timeouts aren't generated by packet processing"); +4179 } +4180 ConnectionError::TransportError(err) => { +4181 debug!("closing connection due to transport error: {}", err); +4182 self.state.move_to_closed(err); +4183 } +4184 ConnectionError::VersionMismatch => { +4185 self.state.move_to_draining(Some(conn_err)); +4186 } +4187 ConnectionError::LocallyClosed => { +4188 unreachable!("LocallyClosed isn't generated by packet processing"); +4189 } +4190 ConnectionError::CidsExhausted => { +4191 unreachable!("CidsExhausted isn't generated by packet processing"); +4192 } +4193 }; +4194 } +4195 +4196 if !was_closed && self.state.is_closed() { +4197 self.close_common(); +4198 if !self.state.is_drained() { +4199 self.set_close_timer(now); +4200 } +4201 } +4202 if !was_drained && self.state.is_drained() { +4203 self.endpoint_events.push_back(EndpointEventInner::Drained); +4204 // Close timer may have been started previously, e.g. if we sent a close and got a +4205 // stateless reset in response +4206 self.timers +4207 .stop(Timer::Conn(ConnTimer::Close), self.qlog.with_time(now)); +4208 } +4209 +4210 // Transmit CONNECTION_CLOSE if necessary. +4211 // +4212 // If we received a valid packet and we are in the closed state we should respond +4213 // with a CONNECTION_CLOSE frame. +4214 // TODO: This SHOULD be rate-limited according to §10.2.1 of QUIC-TRANSPORT, but +4215 // that does not yet happen. This is triggered by each received packet. +4216 if matches!(self.state.as_type(), StateType::Closed) { +4217 // From https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.1-7 +4218 // +4219 // While in the closing state we must either: +4220 // - discard packets coming from an un-validated remote OR +4221 // - ensure we do not send more than 3 times the received data +4222 // +4223 // Doing the 2nd would mean we would be able to send CONNECTION_CLOSE to a peer +4224 // who was (involuntary) migrated just at the time we initiated immediate +4225 // close. It is a lot more work though. So while we would like to do this for +4226 // now we only do 1. +4227 // +4228 // Another shortcoming of the current implementation is that when we have a +4229 // previous PathData which is validated and the remote matches that path, we +4230 // should schedule CONNECTION_CLOSE on that path. However currently we can not +4231 // schedule such a packet. We should also fix this some day. This makes us +4232 // vulnerable to an attacker faking a migration at the right time and then we'd +4233 // be unable to send the CONNECTION_CLOSE to the real remote. +4234 if self +4235 .paths +4236 .get(&path_id) +4237 .map(|p| p.data.validated && p.data.network_path == network_path) +4238 .unwrap_or(false) +4239 { +4240 self.connection_close_pending = true; +4241 } +4242 } +4243 } +4244 +4245 fn process_decrypted_packet( +4246 &mut self, +4247 now: Instant, +4248 network_path: FourTuple, +4249 path_id: PathId, +4250 number: Option<u64>, +4251 packet: Packet, +4252 qlog: &mut QlogRecvPacket, +4253 ) -> Result<(), ConnectionError> { +4254 if !self.paths.contains_key(&path_id) { +4255 // There is a chance this is a server side, first (for this path) packet, which would +4256 // be a protocol violation. It's more likely, however, that this is a packet of a +4257 // pruned path +4258 trace!(%path_id, ?number, "discarding packet for unknown path"); +4259 return Ok(()); +4260 } +4261 let state = match self.state.as_type() { +4262 StateType::Established => { +4263 match packet.header.space() { +4264 SpaceKind::Data => self.process_payload( +4265 now, +4266 network_path, +4267 path_id, +4268 number.unwrap(), +4269 packet, +4270 qlog, +4271 )?, +4272 _ if packet.header.has_frames() => { +4273 self.process_early_payload(now, path_id, packet, qlog)? +4274 } +4275 _ => { +4276 trace!("discarding unexpected pre-handshake packet"); +4277 } +4278 } +4279 return Ok(()); +4280 } +4281 StateType::Closed => { +4282 for result in frame::Iter::new(packet.payload.freeze())? { +4283 let frame = match result { +4284 Ok(frame) => frame, +4285 Err(err) => { +4286 debug!("frame decoding error: {err:?}"); +4287 continue; +4288 } +4289 }; +4290 qlog.frame(&frame); +4291 +4292 if let Frame::Padding = frame { +4293 continue; +4294 }; +4295 +4296 self.path_stats +4297 .for_path(path_id) +4298 .frame_rx +4299 .record(frame.ty()); +4300 +4301 if let Frame::Close(_error) = frame { +4302 self.state.move_to_draining(None); +4303 break; +4304 } +4305 } +4306 return Ok(()); +4307 } +4308 StateType::Draining | StateType::Drained => return Ok(()), +4309 StateType::Handshake => self.state.as_handshake_mut().expect("checked"), +4310 }; +4311 +4312 match packet.header { +4313 Header::Retry { +4314 src_cid: remote_cid, +4315 .. +4316 } => { +4317 debug_assert_eq!(path_id, PathId::ZERO); +4318 if self.side.is_server() { +4319 return Err(TransportError::PROTOCOL_VIOLATION("client sent Retry").into()); +4320 } +4321 +4322 let is_valid_retry = self +4323 .remote_cids +4324 .get(&path_id) +4325 .map(|cids| cids.active()) +4326 .map(|orig_dst_cid| { +4327 self.crypto_state.session.is_valid_retry( +4328 orig_dst_cid, +4329 &packet.header_data, +4330 &packet.payload, +4331 ) +4332 }) +4333 .unwrap_or_default(); +4334 if self.total_authed_packets > 1 +4335 || packet.payload.len() <= 16 // token + 16 byte tag +4336 || !is_valid_retry +4337 { +4338 trace!("discarding invalid Retry"); +4339 // - After the client has received and processed an Initial or Retry +4340 // packet from the server, it MUST discard any subsequent Retry +4341 // packets that it receives. +4342 // - A client MUST discard a Retry packet with a zero-length Retry Token +4343 // field. +4344 // - Clients MUST discard Retry packets that have a Retry Integrity Tag +4345 // that cannot be validated +4346 return Ok(()); +4347 } +4348 +4349 trace!("retrying with CID {}", remote_cid); +4350 let client_hello = state.client_hello.take().unwrap(); +4351 self.retry_src_cid = Some(remote_cid); +4352 self.remote_cids +4353 .get_mut(&path_id) +4354 .expect("PathId::ZERO not yet abandoned, is_valid_retry would have been false") +4355 .update_initial_cid(remote_cid); +4356 self.remote_handshake_cid = remote_cid; +4357 +4358 let space = &mut self.spaces[SpaceId::Initial]; +4359 if let Some(info) = space.for_path(PathId::ZERO).take(0) { +4360 self.on_packet_acked(now, PathId::ZERO, info); +4361 }; +4362 +4363 self.discard_space(now, SpaceKind::Initial); // Make sure we clean up after +4364 // any retransmitted Initials +4365 let crypto_space = &mut self.crypto_state.spaces[SpaceKind::Initial]; +4366 crypto_space.keys = Some( +4367 self.crypto_state +4368 .session +4369 .initial_keys(remote_cid, self.side.side()), +4370 ); +4371 crypto_space.crypto_offset = client_hello.len() as u64; +4372 +4373 let next_pn = self.spaces[SpaceId::Initial] +4374 .for_path(path_id) +4375 .next_packet_number; +4376 self.spaces[SpaceId::Initial] = { +4377 let mut space = PacketSpace::new(now, SpaceId::Initial, &mut self.rng); +4378 space.for_path(path_id).next_packet_number = next_pn; +4379 space.pending.crypto.push_back(frame::Crypto { +4380 offset: 0, +4381 data: client_hello, +4382 }); +4383 space +4384 }; +4385 +4386 // Retransmit all 0-RTT data +4387 let zero_rtt = mem::take( +4388 &mut self.spaces[SpaceId::Data] +4389 .for_path(PathId::ZERO) +4390 .sent_packets, +4391 ); +4392 for (_, info) in zero_rtt.into_iter() { +4393 self.paths +4394 .get_mut(&PathId::ZERO) +4395 .unwrap() +4396 .remove_in_flight(&info); +4397 self.spaces[SpaceId::Data].pending |= info.retransmits; +4398 } +4399 self.streams.retransmit_all_for_0rtt(); +4400 +4401 let token_len = packet.payload.len() - 16; +4402 let ConnectionSide::Client { ref mut token, .. } = self.side else { +4403 unreachable!("we already short-circuited if we're server"); +4404 }; +4405 *token = packet.payload.freeze().split_to(token_len); +4406 +4407 self.state = State::handshake(state::Handshake { +4408 expected_token: Bytes::new(), +4409 remote_cid_set: false, +4410 client_hello: None, +4411 allow_server_migration: true, +4412 }); +4413 Ok(()) +4414 } +4415 Header::Long { +4416 ty: LongType::Handshake, +4417 src_cid: remote_cid, +4418 dst_cid: local_cid, +4419 .. +4420 } => { +4421 debug_assert_eq!(path_id, PathId::ZERO); +4422 if remote_cid != self.remote_handshake_cid { +4423 debug!( +4424 "discarding packet with mismatched remote CID: {} != {}", +4425 self.remote_handshake_cid, remote_cid +4426 ); +4427 return Ok(()); +4428 } +4429 self.on_path_validated(path_id); +4430 +4431 self.process_early_payload(now, path_id, packet, qlog)?; +4432 if self.state.is_closed() { +4433 return Ok(()); +4434 } +4435 +4436 if self.crypto_state.session.is_handshaking() { +4437 trace!("handshake ongoing"); +4438 return Ok(()); +4439 } +4440 +4441 if self.side.is_client() { +4442 // Client-only because server params were set from the client's Initial +4443 let params = self +4444 .crypto_state +4445 .session +4446 .transport_parameters()? +4447 .ok_or_else(|| { +4448 TransportError::new( +4449 TransportErrorCode::crypto(0x6d), +4450 "transport parameters missing".to_owned(), +4451 ) +4452 })?; +4453 +4454 if self.has_0rtt() { +4455 if !self.crypto_state.session.early_data_accepted().unwrap() { +4456 debug_assert!(self.side.is_client()); +4457 debug!("0-RTT rejected"); +4458 self.crypto_state.accepted_0rtt = false; +4459 self.streams.zero_rtt_rejected(); +4460 +4461 // Discard already-queued frames +4462 self.spaces[SpaceId::Data].pending = Retransmits::default(); 4463 -4464 self.events.push_back(Event::Connected); -4465 self.state.move_to_established(); -4466 trace!("established"); -4467 -4468 // Multipath can only be enabled after the state has reached Established. -4469 // So this can not happen any earlier. -4470 self.issue_first_path_cids(now); -4471 Ok(()) -4472 } -4473 Header::Initial(InitialHeader { -4474 src_cid: remote_cid, -4475 dst_cid: local_cid, -4476 .. -4477 }) => { -4478 debug_assert_eq!(path_id, PathId::ZERO); -4479 if !state.remote_cid_set { -4480 trace!("switching remote CID to {}", remote_cid); -4481 let mut state = state.clone(); -4482 self.remote_cids -4483 .get_mut(&path_id) -4484 .expect("PathId::ZERO not yet abandoned") -4485 .update_initial_cid(remote_cid); -4486 self.remote_handshake_cid = remote_cid; -4487 self.original_remote_cid = remote_cid; -4488 state.remote_cid_set = true; -4489 self.state.move_to_handshake(state); -4490 } else if remote_cid != self.remote_handshake_cid { -4491 debug!( -4492 "discarding packet with mismatched remote CID: {} != {}", -4493 self.remote_handshake_cid, remote_cid -4494 ); -4495 return Ok(()); -4496 } -4497 -4498 let starting_space = self.highest_space; -4499 self.process_early_payload(now, path_id, packet, qlog)?; -4500 -4501 if self.side.is_server() -4502 && starting_space == SpaceKind::Initial -4503 && self.highest_space != SpaceKind::Initial -4504 { -4505 let params = self -4506 .crypto_state -4507 .session -4508 .transport_parameters()? -4509 .ok_or_else(|| { -4510 TransportError::new( -4511 TransportErrorCode::crypto(0x6d), -4512 "transport parameters missing".to_owned(), -4513 ) -4514 })?; -4515 self.handle_peer_params(params, local_cid, remote_cid, now)?; -4516 self.issue_first_cids(now); -4517 self.init_0rtt(now); -4518 } -4519 Ok(()) -4520 } -4521 Header::Long { -4522 ty: LongType::ZeroRtt, -4523 .. -4524 } => { -4525 self.process_payload(now, network_path, path_id, number.unwrap(), packet, qlog)?; -4526 Ok(()) -4527 } -4528 Header::VersionNegotiate { .. } => { -4529 if self.total_authed_packets > 1 { -4530 return Ok(()); -4531 } -4532 let supported = packet -4533 .payload -4534 .chunks(4) -4535 .any(|x| match <[u8; 4]>::try_from(x) { -4536 Ok(version) => self.version == u32::from_be_bytes(version), -4537 Err(_) => false, -4538 }); -4539 if supported { -4540 return Ok(()); -4541 } -4542 debug!("remote doesn't support our version"); -4543 Err(ConnectionError::VersionMismatch) -4544 } -4545 Header::Short { .. } => unreachable!( -4546 "short packets received during handshake are discarded in handle_packet" -4547 ), -4548 } -4549 } -4550 -4551 /// Process an Initial or Handshake packet payload -4552 fn process_early_payload( -4553 &mut self, -4554 now: Instant, -4555 path_id: PathId, -4556 packet: Packet, -4557 #[allow(unused)] qlog: &mut QlogRecvPacket, -4558 ) -> Result<(), TransportError> { -4559 debug_assert_ne!(packet.header.space(), SpaceKind::Data); -4560 debug_assert_eq!(path_id, PathId::ZERO); -4561 let payload_len = packet.payload.len(); -4562 let mut ack_eliciting = false; -4563 for result in frame::Iter::new(packet.payload.freeze())? { -4564 let frame = result?; -4565 qlog.frame(&frame); -4566 let span = match frame { -4567 Frame::Padding => continue, -4568 _ => Some(trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty)), -4569 }; -4570 -4571 self.path_stats -4572 .for_path(path_id) -4573 .frame_rx -4574 .record(frame.ty()); -4575 -4576 let _guard = span.as_ref().map(|x| x.enter()); -4577 ack_eliciting |= frame.is_ack_eliciting(); -4578 -4579 // Process frames -4580 if frame.is_1rtt() && packet.header.space() != SpaceKind::Data { -4581 return Err(TransportError::PROTOCOL_VIOLATION( -4582 "illegal frame type in handshake", -4583 )); -4584 } -4585 -4586 match frame { -4587 Frame::Padding | Frame::Ping => {} -4588 Frame::Crypto(frame) => { -4589 self.read_crypto(packet.header.space().into(), &frame, payload_len)?; -4590 } -4591 Frame::Ack(ack) => { -4592 self.on_ack_received(now, packet.header.space().into(), ack)?; -4593 } -4594 Frame::PathAck(ack) => { -4595 span.as_ref() -4596 .map(|span| span.record("path", tracing::field::display(&ack.path_id))); -4597 self.on_path_ack_received(now, packet.header.space().into(), ack)?; -4598 } -4599 Frame::Close(reason) => { -4600 self.state.move_to_draining(Some(reason.into())); -4601 return Ok(()); -4602 } -4603 _ => { -4604 let mut err = -4605 TransportError::PROTOCOL_VIOLATION("illegal frame type in handshake"); -4606 err.frame = frame::MaybeFrame::Known(frame.ty()); -4607 return Err(err); -4608 } -4609 } -4610 } -4611 -4612 if ack_eliciting { -4613 // In the initial and handshake spaces, ACKs must be sent immediately -4614 self.spaces[packet.header.space()] -4615 .for_path(path_id) -4616 .pending_acks -4617 .set_immediate_ack_required(); -4618 } -4619 -4620 self.write_crypto(); -4621 Ok(()) -4622 } -4623 -4624 /// Processes the packet payload, always in the data space. -4625 fn process_payload( -4626 &mut self, -4627 now: Instant, -4628 network_path: FourTuple, -4629 path_id: PathId, -4630 number: u64, -4631 packet: Packet, -4632 #[allow(unused)] qlog: &mut QlogRecvPacket, -4633 ) -> Result<(), TransportError> { -4634 let is_multipath_negotiated = self.is_multipath_negotiated(); -4635 let payload = packet.payload.freeze(); -4636 let mut is_probing_packet = true; -4637 let mut close = None; -4638 let payload_len = payload.len(); -4639 let mut ack_eliciting = false; -4640 // if this packet triggers a path migration and includes a observed address frame, it's -4641 // stored here -4642 let mut migration_observed_addr = None; -4643 for result in frame::Iter::new(payload)? { -4644 let frame = result?; -4645 qlog.frame(&frame); -4646 let span = match frame { -4647 Frame::Padding => continue, -4648 _ => trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty), -4649 }; +4464 // Discard 0-RTT packets +4465 let sent_packets = mem::take( +4466 &mut self.spaces[SpaceId::Data].for_path(path_id).sent_packets, +4467 ); +4468 for (_, packet) in sent_packets.into_iter() { +4469 self.paths +4470 .get_mut(&path_id) +4471 .unwrap() +4472 .remove_in_flight(&packet); +4473 } +4474 } else { +4475 self.crypto_state.accepted_0rtt = true; +4476 params.validate_resumption_from(&self.peer_params)?; +4477 } +4478 } +4479 if let Some(token) = params.stateless_reset_token { +4480 let remote = self.path_data(path_id).network_path.remote; +4481 debug_assert!(!self.state.is_drained()); // requirement for endpoint events, checked above +4482 self.endpoint_events +4483 .push_back(EndpointEventInner::ResetToken(path_id, remote, token)); +4484 } +4485 self.handle_peer_params(params, local_cid, remote_cid, now)?; +4486 self.issue_first_cids(now); +4487 } else { +4488 // Server-only +4489 self.spaces[SpaceId::Data].pending.handshake_done = true; +4490 self.discard_space(now, SpaceKind::Handshake); +4491 self.events.push_back(Event::HandshakeConfirmed); +4492 trace!("handshake confirmed"); +4493 } +4494 +4495 self.events.push_back(Event::Connected); +4496 self.state.move_to_established(); +4497 trace!("established"); +4498 +4499 // Multipath can only be enabled after the state has reached Established. +4500 // So this can not happen any earlier. +4501 self.issue_first_path_cids(now); +4502 Ok(()) +4503 } +4504 Header::Initial(InitialHeader { +4505 src_cid: remote_cid, +4506 dst_cid: local_cid, +4507 .. +4508 }) => { +4509 debug_assert_eq!(path_id, PathId::ZERO); +4510 if !state.remote_cid_set { +4511 trace!("switching remote CID to {}", remote_cid); +4512 let mut state = state.clone(); +4513 self.remote_cids +4514 .get_mut(&path_id) +4515 .expect("PathId::ZERO not yet abandoned") +4516 .update_initial_cid(remote_cid); +4517 self.remote_handshake_cid = remote_cid; +4518 self.original_remote_cid = remote_cid; +4519 state.remote_cid_set = true; +4520 self.state.move_to_handshake(state); +4521 } else if remote_cid != self.remote_handshake_cid { +4522 debug!( +4523 "discarding packet with mismatched remote CID: {} != {}", +4524 self.remote_handshake_cid, remote_cid +4525 ); +4526 return Ok(()); +4527 } +4528 +4529 let starting_space = self.highest_space; +4530 self.process_early_payload(now, path_id, packet, qlog)?; +4531 +4532 if self.side.is_server() +4533 && starting_space == SpaceKind::Initial +4534 && self.highest_space != SpaceKind::Initial +4535 { +4536 let params = self +4537 .crypto_state +4538 .session +4539 .transport_parameters()? +4540 .ok_or_else(|| { +4541 TransportError::new( +4542 TransportErrorCode::crypto(0x6d), +4543 "transport parameters missing".to_owned(), +4544 ) +4545 })?; +4546 self.handle_peer_params(params, local_cid, remote_cid, now)?; +4547 self.issue_first_cids(now); +4548 self.init_0rtt(now); +4549 } +4550 Ok(()) +4551 } +4552 Header::Long { +4553 ty: LongType::ZeroRtt, +4554 .. +4555 } => { +4556 self.process_payload(now, network_path, path_id, number.unwrap(), packet, qlog)?; +4557 Ok(()) +4558 } +4559 Header::VersionNegotiate { .. } => { +4560 if self.total_authed_packets > 1 { +4561 return Ok(()); +4562 } +4563 let supported = packet +4564 .payload +4565 .chunks(4) +4566 .any(|x| match <[u8; 4]>::try_from(x) { +4567 Ok(version) => self.version == u32::from_be_bytes(version), +4568 Err(_) => false, +4569 }); +4570 if supported { +4571 return Ok(()); +4572 } +4573 debug!("remote doesn't support our version"); +4574 Err(ConnectionError::VersionMismatch) +4575 } +4576 Header::Short { .. } => unreachable!( +4577 "short packets received during handshake are discarded in handle_packet" +4578 ), +4579 } +4580 } +4581 +4582 /// Process an Initial or Handshake packet payload +4583 fn process_early_payload( +4584 &mut self, +4585 now: Instant, +4586 path_id: PathId, +4587 packet: Packet, +4588 #[allow(unused)] qlog: &mut QlogRecvPacket, +4589 ) -> Result<(), TransportError> { +4590 debug_assert_ne!(packet.header.space(), SpaceKind::Data); +4591 debug_assert_eq!(path_id, PathId::ZERO); +4592 let payload_len = packet.payload.len(); +4593 let mut ack_eliciting = false; +4594 for result in frame::Iter::new(packet.payload.freeze())? { +4595 let frame = result?; +4596 qlog.frame(&frame); +4597 let span = match frame { +4598 Frame::Padding => continue, +4599 _ => Some(trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty)), +4600 }; +4601 +4602 self.path_stats +4603 .for_path(path_id) +4604 .frame_rx +4605 .record(frame.ty()); +4606 +4607 let _guard = span.as_ref().map(|x| x.enter()); +4608 ack_eliciting |= frame.is_ack_eliciting(); +4609 +4610 // Process frames +4611 if frame.is_1rtt() && packet.header.space() != SpaceKind::Data { +4612 return Err(TransportError::PROTOCOL_VIOLATION( +4613 "illegal frame type in handshake", +4614 )); +4615 } +4616 +4617 match frame { +4618 Frame::Padding | Frame::Ping => {} +4619 Frame::Crypto(frame) => { +4620 self.read_crypto(packet.header.space().into(), &frame, payload_len)?; +4621 } +4622 Frame::Ack(ack) => { +4623 self.on_ack_received(now, packet.header.space().into(), ack)?; +4624 } +4625 Frame::PathAck(ack) => { +4626 span.as_ref() +4627 .map(|span| span.record("path", tracing::field::display(&ack.path_id))); +4628 self.on_path_ack_received(now, packet.header.space().into(), ack)?; +4629 } +4630 Frame::Close(reason) => { +4631 self.state.move_to_draining(Some(reason.into())); +4632 return Ok(()); +4633 } +4634 _ => { +4635 let mut err = +4636 TransportError::PROTOCOL_VIOLATION("illegal frame type in handshake"); +4637 err.frame = frame::MaybeFrame::Known(frame.ty()); +4638 return Err(err); +4639 } +4640 } +4641 } +4642 +4643 if ack_eliciting { +4644 // In the initial and handshake spaces, ACKs must be sent immediately +4645 self.spaces[packet.header.space()] +4646 .for_path(path_id) +4647 .pending_acks +4648 .set_immediate_ack_required(); +4649 } 4650 -4651 self.path_stats -4652 .for_path(path_id) -4653 .frame_rx -4654 .record(frame.ty()); -4655 // Crypto, Stream and Datagram frames are special cased in order no pollute -4656 // the log with payload data -4657 match &frame { -4658 Frame::Crypto(f) => { -4659 trace!(offset = f.offset, len = f.data.len(), "got frame CRYPTO"); -4660 } -4661 Frame::Stream(f) => { -4662 trace!(id = %f.id, offset = f.offset, len = f.data.len(), fin = f.fin, "got frame STREAM"); -4663 } -4664 Frame::Datagram(f) => { -4665 trace!(len = f.data.len(), "got frame DATAGRAM"); -4666 } -4667 f => { -4668 trace!("got frame {f}"); -4669 } -4670 } -4671 -4672 let _guard = span.enter(); -4673 if packet.header.is_0rtt() { -4674 match frame { -4675 Frame::Crypto(_) | Frame::Close(Close::Application(_)) => { -4676 return Err(TransportError::PROTOCOL_VIOLATION( -4677 "illegal frame type in 0-RTT", -4678 )); -4679 } -4680 _ => { -4681 if frame.is_1rtt() { -4682 return Err(TransportError::PROTOCOL_VIOLATION( -4683 "illegal frame type in 0-RTT", -4684 )); -4685 } -4686 } -4687 } -4688 } -4689 ack_eliciting |= frame.is_ack_eliciting(); -4690 -4691 // Check whether this could be a probing packet -4692 match frame { -4693 Frame::Padding -4694 | Frame::PathChallenge(_) -4695 | Frame::PathResponse(_) -4696 | Frame::NewConnectionId(_) -4697 | Frame::ObservedAddr(_) => {} -4698 _ => { -4699 is_probing_packet = false; +4651 self.write_crypto(); +4652 Ok(()) +4653 } +4654 +4655 /// Processes the packet payload, always in the data space. +4656 fn process_payload( +4657 &mut self, +4658 now: Instant, +4659 network_path: FourTuple, +4660 path_id: PathId, +4661 number: u64, +4662 packet: Packet, +4663 #[allow(unused)] qlog: &mut QlogRecvPacket, +4664 ) -> Result<(), TransportError> { +4665 let is_multipath_negotiated = self.is_multipath_negotiated(); +4666 let payload = packet.payload.freeze(); +4667 let mut is_probing_packet = true; +4668 let mut close = None; +4669 let payload_len = payload.len(); +4670 let mut ack_eliciting = false; +4671 // if this packet triggers a path migration and includes a observed address frame, it's +4672 // stored here +4673 let mut migration_observed_addr = None; +4674 for result in frame::Iter::new(payload)? { +4675 let frame = result?; +4676 qlog.frame(&frame); +4677 let span = match frame { +4678 Frame::Padding => continue, +4679 _ => trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty), +4680 }; +4681 +4682 self.path_stats +4683 .for_path(path_id) +4684 .frame_rx +4685 .record(frame.ty()); +4686 // Crypto, Stream and Datagram frames are special cased in order no pollute +4687 // the log with payload data +4688 match &frame { +4689 Frame::Crypto(f) => { +4690 trace!(offset = f.offset, len = f.data.len(), "got frame CRYPTO"); +4691 } +4692 Frame::Stream(f) => { +4693 trace!(id = %f.id, offset = f.offset, len = f.data.len(), fin = f.fin, "got frame STREAM"); +4694 } +4695 Frame::Datagram(f) => { +4696 trace!(len = f.data.len(), "got frame DATAGRAM"); +4697 } +4698 f => { +4699 trace!("got frame {f}"); 4700 } 4701 } 4702 -4703 match frame { -4704 Frame::Crypto(frame) => { -4705 self.read_crypto(SpaceId::Data, &frame, payload_len)?; -4706 } -4707 Frame::Stream(frame) => { -4708 if self.streams.received(frame, payload_len)?.should_transmit() { -4709 self.spaces[SpaceId::Data].pending.max_data = true; +4703 let _guard = span.enter(); +4704 if packet.header.is_0rtt() { +4705 match frame { +4706 Frame::Crypto(_) | Frame::Close(Close::Application(_)) => { +4707 return Err(TransportError::PROTOCOL_VIOLATION( +4708 "illegal frame type in 0-RTT", +4709 )); 4710 } -4711 } -4712 Frame::Ack(ack) => { -4713 self.on_ack_received(now, SpaceId::Data, ack)?; -4714 } -4715 Frame::PathAck(ack) => { -4716 span.record("path", tracing::field::display(&ack.path_id)); -4717 self.on_path_ack_received(now, SpaceId::Data, ack)?; +4711 _ => { +4712 if frame.is_1rtt() { +4713 return Err(TransportError::PROTOCOL_VIOLATION( +4714 "illegal frame type in 0-RTT", +4715 )); +4716 } +4717 } 4718 } -4719 Frame::Padding | Frame::Ping => {} -4720 Frame::Close(reason) => { -4721 close = Some(reason); -4722 } -4723 Frame::PathChallenge(challenge) => { -4724 let path = &mut self -4725 .path_mut(path_id) -4726 .expect("payload is processed only after the path becomes known"); -4727 path.path_responses.push(number, challenge.0, network_path); -4728 // At this point, update_network_path_or_discard was already called, so -4729 // we don't need to be lenient about `local_ip` possibly mis-matching. -4730 if network_path == path.network_path { -4731 // PATH_CHALLENGE on active path, possible off-path packet forwarding -4732 // attack. Send a non-probing packet to recover the active path. -4733 // TODO(flub): No longer true! We now path_challege also to validate -4734 // the path if the path is new, without an RFC9000-style -4735 // migration involved. This means we add in an extra -4736 // IMMEDIATE_ACK on some challenges. It isn't really wrong to do -4737 // so, but it still is something untidy. We should instead -4738 // suppress this when we know the remote is still validating the -4739 // path. -4740 match self.peer_supports_ack_frequency() { -4741 true => self.immediate_ack(path_id), -4742 false => { -4743 self.ping_path(path_id).ok(); -4744 } -4745 } -4746 } -4747 } -4748 Frame::PathResponse(response) => { -4749 let path = self -4750 .paths -4751 .get_mut(&path_id) -4752 .expect("payload is processed only after the path becomes known"); -4753 -4754 use PathTimer::*; -4755 use paths::OnPathResponseReceived::*; -4756 match path -4757 .data -4758 .on_path_response_received(now, response.0, network_path) -4759 { -4760 OnPath { was_open } => { -4761 let qlog = self.qlog.with_time(now); -4762 -4763 self.timers -4764 .stop(Timer::PerPath(path_id, PathValidationFailed), qlog.clone()); -4765 self.timers -4766 .stop(Timer::PerPath(path_id, PathOpenFailed), qlog.clone()); -4767 -4768 let next_challenge = path -4769 .data -4770 .earliest_on_path_expiring_challenge() -4771 .map(|time| time + self.ack_frequency.max_ack_delay_for_pto()); -4772 self.timers.set_or_stop( -4773 Timer::PerPath(path_id, PathChallengeLost), -4774 next_challenge, -4775 qlog, -4776 ); -4777 -4778 if !was_open { -4779 if is_multipath_negotiated { -4780 self.events -4781 .push_back(Event::Path(PathEvent::Opened { id: path_id })); -4782 } -4783 if let Some(observed) = path.data.last_observed_addr_report.as_ref() -4784 { -4785 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -4786 id: path_id, -4787 addr: observed.socket_addr(), -4788 })); -4789 } -4790 } -4791 if let Some((_, ref mut prev)) = path.prev { -4792 prev.reset_on_path_challenges(); -4793 } -4794 } -4795 OffPath => { -4796 debug!(%response, "Valid response to off-path PATH_CHALLENGE"); -4797 } -4798 Ignored { -4799 sent_on, -4800 current_path, -4801 } => { -4802 debug!(%sent_on, %current_path, %response, "ignoring valid PATH_RESPONSE") -4803 } -4804 Unknown => debug!(%response, "ignoring invalid PATH_RESPONSE"), -4805 } -4806 } -4807 Frame::MaxData(frame::MaxData(bytes)) => { -4808 self.streams.received_max_data(bytes); -4809 } -4810 Frame::MaxStreamData(frame::MaxStreamData { id, offset }) => { -4811 self.streams.received_max_stream_data(id, offset)?; -4812 } -4813 Frame::MaxStreams(frame::MaxStreams { dir, count }) => { -4814 self.streams.received_max_streams(dir, count)?; -4815 } -4816 Frame::ResetStream(frame) => { -4817 if self.streams.received_reset(frame)?.should_transmit() { -4818 self.spaces[SpaceId::Data].pending.max_data = true; -4819 } -4820 } -4821 Frame::DataBlocked(DataBlocked(offset)) => { -4822 debug!(offset, "peer claims to be blocked at connection level"); -4823 } -4824 Frame::StreamDataBlocked(StreamDataBlocked { id, offset }) => { -4825 if id.initiator() == self.side.side() && id.dir() == Dir::Uni { -4826 debug!("got STREAM_DATA_BLOCKED on send-only {}", id); -4827 return Err(TransportError::STREAM_STATE_ERROR( -4828 "STREAM_DATA_BLOCKED on send-only stream", -4829 )); -4830 } -4831 debug!( -4832 stream = %id, -4833 offset, "peer claims to be blocked at stream level" -4834 ); -4835 } -4836 Frame::StreamsBlocked(StreamsBlocked { dir, limit }) => { -4837 if limit > MAX_STREAM_COUNT { -4838 return Err(TransportError::FRAME_ENCODING_ERROR( -4839 "unrepresentable stream limit", -4840 )); -4841 } -4842 debug!( -4843 "peer claims to be blocked opening more than {} {} streams", -4844 limit, dir -4845 ); +4719 } +4720 ack_eliciting |= frame.is_ack_eliciting(); +4721 +4722 // Check whether this could be a probing packet +4723 match frame { +4724 Frame::Padding +4725 | Frame::PathChallenge(_) +4726 | Frame::PathResponse(_) +4727 | Frame::NewConnectionId(_) +4728 | Frame::ObservedAddr(_) => {} +4729 _ => { +4730 is_probing_packet = false; +4731 } +4732 } +4733 +4734 match frame { +4735 Frame::Crypto(frame) => { +4736 self.read_crypto(SpaceId::Data, &frame, payload_len)?; +4737 } +4738 Frame::Stream(frame) => { +4739 if self.streams.received(frame, payload_len)?.should_transmit() { +4740 self.spaces[SpaceId::Data].pending.max_data = true; +4741 } +4742 } +4743 Frame::Ack(ack) => { +4744 self.on_ack_received(now, SpaceId::Data, ack)?; +4745 } +4746 Frame::PathAck(ack) => { +4747 span.record("path", tracing::field::display(&ack.path_id)); +4748 self.on_path_ack_received(now, SpaceId::Data, ack)?; +4749 } +4750 Frame::Padding | Frame::Ping => {} +4751 Frame::Close(reason) => { +4752 close = Some(reason); +4753 } +4754 Frame::PathChallenge(challenge) => { +4755 let path = &mut self +4756 .path_mut(path_id) +4757 .expect("payload is processed only after the path becomes known"); +4758 path.path_responses.push(number, challenge.0, network_path); +4759 // At this point, update_network_path_or_discard was already called, so +4760 // we don't need to be lenient about `local_ip` possibly mis-matching. +4761 if network_path == path.network_path { +4762 // PATH_CHALLENGE on active path, possible off-path packet forwarding +4763 // attack. Send a non-probing packet to recover the active path. +4764 // TODO(flub): No longer true! We now path_challege also to validate +4765 // the path if the path is new, without an RFC9000-style +4766 // migration involved. This means we add in an extra +4767 // IMMEDIATE_ACK on some challenges. It isn't really wrong to do +4768 // so, but it still is something untidy. We should instead +4769 // suppress this when we know the remote is still validating the +4770 // path. +4771 match self.peer_supports_ack_frequency() { +4772 true => self.immediate_ack(path_id), +4773 false => { +4774 self.ping_path(path_id).ok(); +4775 } +4776 } +4777 } +4778 } +4779 Frame::PathResponse(response) => { +4780 let path = self +4781 .paths +4782 .get_mut(&path_id) +4783 .expect("payload is processed only after the path becomes known"); +4784 +4785 use PathTimer::*; +4786 use paths::OnPathResponseReceived::*; +4787 match path +4788 .data +4789 .on_path_response_received(now, response.0, network_path) +4790 { +4791 OnPath { was_open } => { +4792 let qlog = self.qlog.with_time(now); +4793 +4794 self.timers +4795 .stop(Timer::PerPath(path_id, PathValidationFailed), qlog.clone()); +4796 self.timers +4797 .stop(Timer::PerPath(path_id, PathOpenFailed), qlog.clone()); +4798 +4799 let next_challenge = path +4800 .data +4801 .earliest_on_path_expiring_challenge() +4802 .map(|time| time + self.ack_frequency.max_ack_delay_for_pto()); +4803 self.timers.set_or_stop( +4804 Timer::PerPath(path_id, PathChallengeLost), +4805 next_challenge, +4806 qlog, +4807 ); +4808 +4809 if !was_open { +4810 if is_multipath_negotiated { +4811 self.events +4812 .push_back(Event::Path(PathEvent::Opened { id: path_id })); +4813 } +4814 if let Some(observed) = path.data.last_observed_addr_report.as_ref() +4815 { +4816 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +4817 id: path_id, +4818 addr: observed.socket_addr(), +4819 })); +4820 } +4821 } +4822 if let Some((_, ref mut prev)) = path.prev { +4823 prev.reset_on_path_challenges(); +4824 } +4825 } +4826 OffPath => { +4827 debug!(%response, "Valid response to off-path PATH_CHALLENGE"); +4828 } +4829 Ignored { +4830 sent_on, +4831 current_path, +4832 } => { +4833 debug!(%sent_on, %current_path, %response, "ignoring valid PATH_RESPONSE") +4834 } +4835 Unknown => debug!(%response, "ignoring invalid PATH_RESPONSE"), +4836 } +4837 } +4838 Frame::MaxData(frame::MaxData(bytes)) => { +4839 self.streams.received_max_data(bytes); +4840 } +4841 Frame::MaxStreamData(frame::MaxStreamData { id, offset }) => { +4842 self.streams.received_max_stream_data(id, offset)?; +4843 } +4844 Frame::MaxStreams(frame::MaxStreams { dir, count }) => { +4845 self.streams.received_max_streams(dir, count)?; 4846 } -4847 Frame::StopSending(frame::StopSending { id, error_code }) => { -4848 if id.initiator() != self.side.side() { -4849 if id.dir() == Dir::Uni { -4850 debug!("got STOP_SENDING on recv-only {}", id); -4851 return Err(TransportError::STREAM_STATE_ERROR( -4852 "STOP_SENDING on recv-only stream", -4853 )); -4854 } -4855 } else if self.streams.is_local_unopened(id) { -4856 return Err(TransportError::STREAM_STATE_ERROR( -4857 "STOP_SENDING on unopened stream", -4858 )); -4859 } -4860 self.streams.received_stop_sending(id, error_code); -4861 } -4862 Frame::RetireConnectionId(frame::RetireConnectionId { path_id, sequence }) => { -4863 if let Some(ref path_id) = path_id { -4864 span.record("path", tracing::field::display(&path_id)); -4865 } -4866 let path_id = path_id.unwrap_or_default(); -4867 match self.local_cid_state.get_mut(&path_id) { -4868 None => error!(?path_id, "RETIRE_CONNECTION_ID for unknown path"), -4869 Some(cid_state) => { -4870 let allow_more_cids = cid_state -4871 .on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?; -4872 -4873 // If the path has closed, we do not issue more CIDs for this path -4874 // For details see https://www.ietf.org/archive/id/draft-ietf-quic-multipath-17.html#section-3.2.2 -4875 // > an endpoint SHOULD provide new connection IDs for that path, if still open, using PATH_NEW_CONNECTION_ID frames. -4876 let has_path = !self.abandoned_paths.contains(&path_id); -4877 let allow_more_cids = allow_more_cids && has_path; -4878 -4879 debug_assert!(!self.state.is_drained()); // required for adding endpoint events, process_payload is never called for drained connections -4880 self.endpoint_events -4881 .push_back(EndpointEventInner::RetireConnectionId( -4882 now, -4883 path_id, -4884 sequence, -4885 allow_more_cids, -4886 )); -4887 } -4888 } -4889 } -4890 Frame::NewConnectionId(frame) => { -4891 let path_id = if let Some(path_id) = frame.path_id { -4892 if !self.is_multipath_negotiated() { -4893 return Err(TransportError::PROTOCOL_VIOLATION( -4894 "received PATH_NEW_CONNECTION_ID frame when multipath was not negotiated", -4895 )); -4896 } -4897 if path_id > self.local_max_path_id { -4898 return Err(TransportError::PROTOCOL_VIOLATION( -4899 "PATH_NEW_CONNECTION_ID contains path_id exceeding current max", -4900 )); -4901 } -4902 path_id -4903 } else { -4904 PathId::ZERO -4905 }; -4906 -4907 if let Some(ref path_id) = frame.path_id { -4908 span.record("path", tracing::field::display(&path_id)); -4909 } -4910 -4911 if self.abandoned_paths.contains(&path_id) { -4912 trace!("ignoring issued CID for abandoned path"); -4913 continue; -4914 } -4915 let remote_cids = self -4916 .remote_cids -4917 .entry(path_id) -4918 .or_insert_with(|| CidQueue::new(frame.id)); -4919 if remote_cids.active().is_empty() { -4920 return Err(TransportError::PROTOCOL_VIOLATION( -4921 "NEW_CONNECTION_ID when CIDs aren't in use", -4922 )); -4923 } -4924 if frame.retire_prior_to > frame.sequence { -4925 return Err(TransportError::PROTOCOL_VIOLATION( -4926 "NEW_CONNECTION_ID retiring unissued CIDs", -4927 )); -4928 } -4929 -4930 use crate::cid_queue::InsertError; -4931 match remote_cids.insert(frame) { -4932 Ok(None) if self.path(path_id).is_none() => { -4933 // if this gives us CIDs to open a new path and a nat traversal attempt -4934 // is underway we could try to probe a pending remote -4935 self.continue_nat_traversal_round(now); -4936 } -4937 Ok(None) => {} -4938 Ok(Some((retired, reset_token))) => { -4939 let pending_retired = -4940 &mut self.spaces[SpaceId::Data].pending.retire_cids; -4941 /// Ensure `pending_retired` cannot grow without bound. Limit is -4942 /// somewhat arbitrary but very permissive. -4943 const MAX_PENDING_RETIRED_CIDS: u64 = CidQueue::LEN as u64 * 10; -4944 // We don't bother counting in-flight frames because those are bounded -4945 // by congestion control. -4946 if (pending_retired.len() as u64) -4947 .saturating_add(retired.end.saturating_sub(retired.start)) -4948 > MAX_PENDING_RETIRED_CIDS -4949 { -4950 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR( -4951 "queued too many retired CIDs", -4952 )); -4953 } -4954 pending_retired.extend(retired.map(|seq| (path_id, seq))); -4955 self.set_reset_token(path_id, network_path.remote, reset_token); -4956 } -4957 Err(InsertError::ExceedsLimit) => { -4958 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR("")); -4959 } -4960 Err(InsertError::Retired) => { -4961 trace!("discarding already-retired"); -4962 // RETIRE_CONNECTION_ID might not have been previously sent if e.g. a -4963 // range of connection IDs larger than the active connection ID limit -4964 // was retired all at once via retire_prior_to. -4965 self.spaces[SpaceId::Data] -4966 .pending -4967 .retire_cids -4968 .push((path_id, frame.sequence)); -4969 continue; -4970 } -4971 }; -4972 -4973 if self.side.is_server() -4974 && path_id == PathId::ZERO -4975 && self -4976 .remote_cids -4977 .get(&PathId::ZERO) -4978 .map(|cids| cids.active_seq() == 0) -4979 .unwrap_or_default() -4980 { -4981 // We're a server still using the initial remote CID for the client, so -4982 // let's switch immediately to enable clientside stateless resets. -4983 self.update_remote_cid(PathId::ZERO); -4984 } -4985 } -4986 Frame::NewToken(NewToken { token }) => { -4987 let ConnectionSide::Client { -4988 token_store, -4989 server_name, -4990 .. -4991 } = &self.side -4992 else { -4993 return Err(TransportError::PROTOCOL_VIOLATION("client sent NEW_TOKEN")); -4994 }; -4995 if token.is_empty() { -4996 return Err(TransportError::FRAME_ENCODING_ERROR("empty token")); -4997 } -4998 trace!("got new token"); -4999 token_store.insert(server_name, token); -5000 } -5001 Frame::Datagram(datagram) => { -5002 if self -5003 .datagrams -5004 .received(datagram, &self.config.datagram_receive_buffer_size)? -5005 { -5006 self.events.push_back(Event::DatagramReceived); -5007 } -5008 } -5009 Frame::AckFrequency(ack_frequency) => { -5010 // This frame can only be sent in the Data space -5011 -5012 if !self.ack_frequency.ack_frequency_received(&ack_frequency)? { -5013 // The AckFrequency frame is stale (we have already received a more -5014 // recent one) -5015 continue; -5016 } -5017 -5018 // Update the params for all of our paths -5019 for (path_id, space) in self.spaces[SpaceId::Data].number_spaces.iter_mut() { -5020 space.pending_acks.set_ack_frequency_params(&ack_frequency); -5021 -5022 // Our `max_ack_delay` has been updated, so we may need to adjust -5023 // its associated timeout -5024 if let Some(timeout) = space -5025 .pending_acks -5026 .max_ack_delay_timeout(self.ack_frequency.max_ack_delay) -5027 { -5028 self.timers.set( -5029 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), -5030 timeout, -5031 self.qlog.with_time(now), -5032 ); -5033 } -5034 } -5035 } -5036 Frame::ImmediateAck => { -5037 // This frame can only be sent in the Data space -5038 for pns in self.spaces[SpaceId::Data].iter_paths_mut() { -5039 pns.pending_acks.set_immediate_ack_required(); -5040 } -5041 } -5042 Frame::HandshakeDone => { -5043 if self.side.is_server() { -5044 return Err(TransportError::PROTOCOL_VIOLATION( -5045 "client sent HANDSHAKE_DONE", -5046 )); +4847 Frame::ResetStream(frame) => { +4848 if self.streams.received_reset(frame)?.should_transmit() { +4849 self.spaces[SpaceId::Data].pending.max_data = true; +4850 } +4851 } +4852 Frame::DataBlocked(DataBlocked(offset)) => { +4853 debug!(offset, "peer claims to be blocked at connection level"); +4854 } +4855 Frame::StreamDataBlocked(StreamDataBlocked { id, offset }) => { +4856 if id.initiator() == self.side.side() && id.dir() == Dir::Uni { +4857 debug!("got STREAM_DATA_BLOCKED on send-only {}", id); +4858 return Err(TransportError::STREAM_STATE_ERROR( +4859 "STREAM_DATA_BLOCKED on send-only stream", +4860 )); +4861 } +4862 debug!( +4863 stream = %id, +4864 offset, "peer claims to be blocked at stream level" +4865 ); +4866 } +4867 Frame::StreamsBlocked(StreamsBlocked { dir, limit }) => { +4868 if limit > MAX_STREAM_COUNT { +4869 return Err(TransportError::FRAME_ENCODING_ERROR( +4870 "unrepresentable stream limit", +4871 )); +4872 } +4873 debug!( +4874 "peer claims to be blocked opening more than {} {} streams", +4875 limit, dir +4876 ); +4877 } +4878 Frame::StopSending(frame::StopSending { id, error_code }) => { +4879 if id.initiator() != self.side.side() { +4880 if id.dir() == Dir::Uni { +4881 debug!("got STOP_SENDING on recv-only {}", id); +4882 return Err(TransportError::STREAM_STATE_ERROR( +4883 "STOP_SENDING on recv-only stream", +4884 )); +4885 } +4886 } else if self.streams.is_local_unopened(id) { +4887 return Err(TransportError::STREAM_STATE_ERROR( +4888 "STOP_SENDING on unopened stream", +4889 )); +4890 } +4891 self.streams.received_stop_sending(id, error_code); +4892 } +4893 Frame::RetireConnectionId(frame::RetireConnectionId { path_id, sequence }) => { +4894 if let Some(ref path_id) = path_id { +4895 span.record("path", tracing::field::display(&path_id)); +4896 } +4897 let path_id = path_id.unwrap_or_default(); +4898 match self.local_cid_state.get_mut(&path_id) { +4899 None => error!(?path_id, "RETIRE_CONNECTION_ID for unknown path"), +4900 Some(cid_state) => { +4901 let allow_more_cids = cid_state +4902 .on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?; +4903 +4904 // If the path has closed, we do not issue more CIDs for this path +4905 // For details see https://www.ietf.org/archive/id/draft-ietf-quic-multipath-17.html#section-3.2.2 +4906 // > an endpoint SHOULD provide new connection IDs for that path, if still open, using PATH_NEW_CONNECTION_ID frames. +4907 let has_path = !self.abandoned_paths.contains(&path_id); +4908 let allow_more_cids = allow_more_cids && has_path; +4909 +4910 debug_assert!(!self.state.is_drained()); // required for adding endpoint events, process_payload is never called for drained connections +4911 self.endpoint_events +4912 .push_back(EndpointEventInner::RetireConnectionId( +4913 now, +4914 path_id, +4915 sequence, +4916 allow_more_cids, +4917 )); +4918 } +4919 } +4920 } +4921 Frame::NewConnectionId(frame) => { +4922 let path_id = if let Some(path_id) = frame.path_id { +4923 if !self.is_multipath_negotiated() { +4924 return Err(TransportError::PROTOCOL_VIOLATION( +4925 "received PATH_NEW_CONNECTION_ID frame when multipath was not negotiated", +4926 )); +4927 } +4928 if path_id > self.local_max_path_id { +4929 return Err(TransportError::PROTOCOL_VIOLATION( +4930 "PATH_NEW_CONNECTION_ID contains path_id exceeding current max", +4931 )); +4932 } +4933 path_id +4934 } else { +4935 PathId::ZERO +4936 }; +4937 +4938 if let Some(ref path_id) = frame.path_id { +4939 span.record("path", tracing::field::display(&path_id)); +4940 } +4941 +4942 if self.abandoned_paths.contains(&path_id) { +4943 trace!("ignoring issued CID for abandoned path"); +4944 continue; +4945 } +4946 let remote_cids = self +4947 .remote_cids +4948 .entry(path_id) +4949 .or_insert_with(|| CidQueue::new(frame.id)); +4950 if remote_cids.active().is_empty() { +4951 return Err(TransportError::PROTOCOL_VIOLATION( +4952 "NEW_CONNECTION_ID when CIDs aren't in use", +4953 )); +4954 } +4955 if frame.retire_prior_to > frame.sequence { +4956 return Err(TransportError::PROTOCOL_VIOLATION( +4957 "NEW_CONNECTION_ID retiring unissued CIDs", +4958 )); +4959 } +4960 +4961 use crate::cid_queue::InsertError; +4962 match remote_cids.insert(frame) { +4963 Ok(None) if self.path(path_id).is_none() => { +4964 // if this gives us CIDs to open a new path and a nat traversal attempt +4965 // is underway we could try to probe a pending remote +4966 self.continue_nat_traversal_round(now); +4967 } +4968 Ok(None) => {} +4969 Ok(Some((retired, reset_token))) => { +4970 let pending_retired = +4971 &mut self.spaces[SpaceId::Data].pending.retire_cids; +4972 /// Ensure `pending_retired` cannot grow without bound. Limit is +4973 /// somewhat arbitrary but very permissive. +4974 const MAX_PENDING_RETIRED_CIDS: u64 = CidQueue::LEN as u64 * 10; +4975 // We don't bother counting in-flight frames because those are bounded +4976 // by congestion control. +4977 if (pending_retired.len() as u64) +4978 .saturating_add(retired.end.saturating_sub(retired.start)) +4979 > MAX_PENDING_RETIRED_CIDS +4980 { +4981 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR( +4982 "queued too many retired CIDs", +4983 )); +4984 } +4985 pending_retired.extend(retired.map(|seq| (path_id, seq))); +4986 self.set_reset_token(path_id, network_path.remote, reset_token); +4987 } +4988 Err(InsertError::ExceedsLimit) => { +4989 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR("")); +4990 } +4991 Err(InsertError::Retired) => { +4992 trace!("discarding already-retired"); +4993 // RETIRE_CONNECTION_ID might not have been previously sent if e.g. a +4994 // range of connection IDs larger than the active connection ID limit +4995 // was retired all at once via retire_prior_to. +4996 self.spaces[SpaceId::Data] +4997 .pending +4998 .retire_cids +4999 .push((path_id, frame.sequence)); +5000 continue; +5001 } +5002 }; +5003 +5004 if self.side.is_server() +5005 && path_id == PathId::ZERO +5006 && self +5007 .remote_cids +5008 .get(&PathId::ZERO) +5009 .map(|cids| cids.active_seq() == 0) +5010 .unwrap_or_default() +5011 { +5012 // We're a server still using the initial remote CID for the client, so +5013 // let's switch immediately to enable clientside stateless resets. +5014 self.update_remote_cid(PathId::ZERO); +5015 } +5016 } +5017 Frame::NewToken(NewToken { token }) => { +5018 let ConnectionSide::Client { +5019 token_store, +5020 server_name, +5021 .. +5022 } = &self.side +5023 else { +5024 return Err(TransportError::PROTOCOL_VIOLATION("client sent NEW_TOKEN")); +5025 }; +5026 if token.is_empty() { +5027 return Err(TransportError::FRAME_ENCODING_ERROR("empty token")); +5028 } +5029 trace!("got new token"); +5030 token_store.insert(server_name, token); +5031 } +5032 Frame::Datagram(datagram) => { +5033 if self +5034 .datagrams +5035 .received(datagram, &self.config.datagram_receive_buffer_size)? +5036 { +5037 self.events.push_back(Event::DatagramReceived); +5038 } +5039 } +5040 Frame::AckFrequency(ack_frequency) => { +5041 // This frame can only be sent in the Data space +5042 +5043 if !self.ack_frequency.ack_frequency_received(&ack_frequency)? { +5044 // The AckFrequency frame is stale (we have already received a more +5045 // recent one) +5046 continue; 5047 } -5048 if self.crypto_state.has_keys(EncryptionLevel::Handshake) { -5049 self.discard_space(now, SpaceKind::Handshake); -5050 } -5051 self.events.push_back(Event::HandshakeConfirmed); -5052 trace!("handshake confirmed"); -5053 } -5054 Frame::ObservedAddr(observed) => { -5055 // check if params allows the peer to send report and this node to receive it -5056 trace!(seq_no = %observed.seq_no, ip = %observed.ip, port = observed.port); -5057 if !self -5058 .peer_params -5059 .address_discovery_role -5060 .should_report(&self.config.address_discovery_role) -5061 { -5062 return Err(TransportError::PROTOCOL_VIOLATION( -5063 "received OBSERVED_ADDRESS frame when not negotiated", -5064 )); +5048 +5049 // Update the params for all of our paths +5050 for (path_id, space) in self.spaces[SpaceId::Data].number_spaces.iter_mut() { +5051 space.pending_acks.set_ack_frequency_params(&ack_frequency); +5052 +5053 // Our `max_ack_delay` has been updated, so we may need to adjust +5054 // its associated timeout +5055 if let Some(timeout) = space +5056 .pending_acks +5057 .max_ack_delay_timeout(self.ack_frequency.max_ack_delay) +5058 { +5059 self.timers.set( +5060 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), +5061 timeout, +5062 self.qlog.with_time(now), +5063 ); +5064 } 5065 } -5066 // must only be sent in data space -5067 if packet.header.space() != SpaceKind::Data { -5068 return Err(TransportError::PROTOCOL_VIOLATION( -5069 "OBSERVED_ADDRESS frame outside data space", -5070 )); +5066 } +5067 Frame::ImmediateAck => { +5068 // This frame can only be sent in the Data space +5069 for pns in self.spaces[SpaceId::Data].iter_paths_mut() { +5070 pns.pending_acks.set_immediate_ack_required(); 5071 } -5072 -5073 let path = self.path_data_mut(path_id); -5074 if network_path == path.network_path { -5075 if let Some(updated) = path.update_observed_addr_report(observed) -5076 && path.open_status == paths::OpenStatus::Informed -5077 { -5078 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -5079 id: path_id, -5080 addr: updated, -5081 })); -5082 // otherwise the event is reported when the path is deemed open -5083 } -5084 } else { -5085 // include in migration -5086 migration_observed_addr = Some(observed) -5087 } -5088 } -5089 Frame::PathAbandon(frame::PathAbandon { -5090 path_id, -5091 error_code, -5092 }) => { -5093 span.record("path", tracing::field::display(&path_id)); -5094 match self.close_path_inner( -5095 now, -5096 path_id, -5097 PathAbandonReason::RemoteAbandoned { -5098 error_code: error_code.into(), -5099 }, -5100 ) { -5101 Ok(()) => { -5102 trace!("peer abandoned path"); -5103 } -5104 Err(ClosePathError::ClosedPath) => { -5105 trace!("peer abandoned already closed path"); -5106 } -5107 Err(ClosePathError::MultipathNotNegotiated) => { -5108 return Err(TransportError::PROTOCOL_VIOLATION( -5109 "received PATH_ABANDON frame when multipath was not negotiated", -5110 )); -5111 } -5112 Err(ClosePathError::LastOpenPath) => { -5113 // Not reachable: close_path_inner allows remote abandons -5114 // for the last path. But handle gracefully just in case. -5115 error!( -5116 "peer abandoned last path but close_path_inner returned LastOpenPath" -5117 ); -5118 } -5119 }; -5120 -5121 // Start draining the path if it still exists and hasn't started draining yet. -5122 if let Some(path) = self.paths.get_mut(&path_id) -5123 && !mem::replace(&mut path.data.draining, true) -5124 { -5125 let ack_delay = self.ack_frequency.max_ack_delay_for_pto(); -5126 let pto = path.data.rtt.pto_base() + ack_delay; -5127 self.timers.set( -5128 Timer::PerPath(path_id, PathTimer::PathDrained), -5129 now + 3 * pto, -5130 self.qlog.with_time(now), -5131 ); -5132 -5133 self.set_max_path_id(now, self.local_max_path_id.saturating_add(1u8)); -5134 } -5135 } -5136 Frame::PathStatusAvailable(info) => { -5137 span.record("path", tracing::field::display(&info.path_id)); -5138 if self.is_multipath_negotiated() { -5139 self.on_path_status( -5140 info.path_id, -5141 PathStatus::Available, -5142 info.status_seq_no, -5143 ); -5144 } else { -5145 return Err(TransportError::PROTOCOL_VIOLATION( -5146 "received PATH_STATUS_AVAILABLE frame when multipath was not negotiated", -5147 )); -5148 } -5149 } -5150 Frame::PathStatusBackup(info) => { -5151 span.record("path", tracing::field::display(&info.path_id)); -5152 if self.is_multipath_negotiated() { -5153 self.on_path_status(info.path_id, PathStatus::Backup, info.status_seq_no); -5154 } else { -5155 return Err(TransportError::PROTOCOL_VIOLATION( -5156 "received PATH_STATUS_BACKUP frame when multipath was not negotiated", -5157 )); -5158 } -5159 } -5160 Frame::MaxPathId(frame::MaxPathId(path_id)) => { -5161 span.record("path", tracing::field::display(&path_id)); -5162 if !self.is_multipath_negotiated() { -5163 return Err(TransportError::PROTOCOL_VIOLATION( -5164 "received MAX_PATH_ID frame when multipath was not negotiated", -5165 )); -5166 } -5167 // frames that do not increase the path id are ignored -5168 if path_id > self.remote_max_path_id { -5169 self.remote_max_path_id = path_id; -5170 self.issue_first_path_cids(now); -5171 while let Some(true) = self.continue_nat_traversal_round(now) {} -5172 } -5173 } -5174 Frame::PathsBlocked(frame::PathsBlocked(max_path_id)) => { -5175 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST -5176 // be treated as a connection error of type PROTOCOL_VIOLATION. -5177 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> -5178 if self.is_multipath_negotiated() { -5179 if max_path_id > self.local_max_path_id { -5180 return Err(TransportError::PROTOCOL_VIOLATION( -5181 "PATHS_BLOCKED maximum path identifier was larger than local maximum", -5182 )); -5183 } -5184 debug!("received PATHS_BLOCKED({:?})", max_path_id); -5185 // TODO(@divma): ensure max concurrent paths -5186 } else { -5187 return Err(TransportError::PROTOCOL_VIOLATION( -5188 "received PATHS_BLOCKED frame when not multipath was not negotiated", -5189 )); -5190 } -5191 } -5192 Frame::PathCidsBlocked(frame::PathCidsBlocked { path_id, next_seq }) => { -5193 // Nothing to do. This is recorded in the frame stats, but otherwise we -5194 // always issue all CIDs we're allowed to issue, so either this is an -5195 // impatient peer or a bug on our side. -5196 -5197 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST -5198 // be treated as a connection error of type PROTOCOL_VIOLATION. -5199 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> -5200 if self.is_multipath_negotiated() { -5201 if path_id > self.local_max_path_id { -5202 return Err(TransportError::PROTOCOL_VIOLATION( -5203 "PATH_CIDS_BLOCKED path identifier was larger than local maximum", -5204 )); -5205 } -5206 if next_seq.0 -5207 > self -5208 .local_cid_state -5209 .get(&path_id) -5210 .map(|cid_state| cid_state.active_seq().1 + 1) -5211 .unwrap_or_default() -5212 { -5213 return Err(TransportError::PROTOCOL_VIOLATION( -5214 "PATH_CIDS_BLOCKED next sequence number larger than in local state", -5215 )); -5216 } -5217 debug!(%path_id, %next_seq, "received PATH_CIDS_BLOCKED"); -5218 } else { -5219 return Err(TransportError::PROTOCOL_VIOLATION( -5220 "received PATH_CIDS_BLOCKED frame when not multipath was not negotiated", -5221 )); -5222 } -5223 } -5224 Frame::AddAddress(addr) => { -5225 let client_state = match self.n0_nat_traversal.client_side_mut() { -5226 Ok(state) => state, -5227 Err(err) => { -5228 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5229 "Nat traversal(ADD_ADDRESS): {err}" -5230 ))); -5231 } -5232 }; -5233 -5234 if !client_state.check_remote_address(&addr) { -5235 // if the address is not valid we flag it, but update anyway -5236 warn!(?addr, "server sent illegal ADD_ADDRESS frame"); -5237 } -5238 -5239 match client_state.add_remote_address(addr) { -5240 Ok(maybe_added) => { -5241 if let Some(added) = maybe_added { -5242 self.events.push_back(Event::NatTraversal( -5243 n0_nat_traversal::Event::AddressAdded(added), -5244 )); -5245 } -5246 } -5247 Err(e) => { -5248 warn!(%e, "failed to add remote address") -5249 } -5250 } -5251 } -5252 Frame::RemoveAddress(addr) => { -5253 let client_state = match self.n0_nat_traversal.client_side_mut() { -5254 Ok(state) => state, -5255 Err(err) => { -5256 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5257 "Nat traversal(REMOVE_ADDRESS): {err}" -5258 ))); -5259 } -5260 }; -5261 if let Some(removed_addr) = client_state.remove_remote_address(addr) { -5262 self.events.push_back(Event::NatTraversal( -5263 n0_nat_traversal::Event::AddressRemoved(removed_addr), -5264 )); -5265 } -5266 } -5267 Frame::ReachOut(reach_out) => { -5268 let ipv6 = self.is_ipv6(); -5269 let server_state = match self.n0_nat_traversal.server_side_mut() { -5270 Ok(state) => state, -5271 Err(err) => { -5272 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5273 "Nat traversal(REACH_OUT): {err}" -5274 ))); -5275 } -5276 }; -5277 -5278 if let Err(err) = server_state.handle_reach_out(reach_out, ipv6) { -5279 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5280 "Nat traversal(REACH_OUT): {err}" -5281 ))); -5282 } -5283 } -5284 } -5285 } -5286 -5287 let space = self.spaces[SpaceId::Data].for_path(path_id); -5288 if space -5289 .pending_acks -5290 .packet_received(now, number, ack_eliciting, &space.dedup) -5291 { -5292 if self.abandoned_paths.contains(&path_id) { -5293 // § 3.4.3 QUIC-MULTIPATH: promptly send ACKs for packets received from -5294 // abandoned paths. -5295 space.pending_acks.set_immediate_ack_required(); -5296 } else { -5297 self.timers.set( -5298 Timer::PerPath(path_id, PathTimer::MaxAckDelay), -5299 now + self.ack_frequency.max_ack_delay, -5300 self.qlog.with_time(now), -5301 ); -5302 } -5303 } -5304 -5305 // Issue stream ID credit due to ACKs of outgoing finish/resets and incoming finish/resets -5306 // on stopped streams. Incoming finishes/resets on open streams are not handled here as they -5307 // are only freed, and hence only issue credit, once the application has been notified -5308 // during a read on the stream. -5309 let pending = &mut self.spaces[SpaceId::Data].pending; -5310 self.streams.queue_max_stream_id(pending); -5311 -5312 if let Some(reason) = close { -5313 self.state.move_to_draining(Some(reason.into())); -5314 self.connection_close_pending = true; -5315 } -5316 -5317 if Some(number) == self.spaces[SpaceId::Data].for_path(path_id).rx_packet -5318 && !is_probing_packet -5319 && network_path != self.path_data(path_id).network_path -5320 { -5321 let ConnectionSide::Server { ref server_config } = self.side else { -5322 panic!("packets from unknown remote should be dropped by clients"); -5323 }; -5324 debug_assert!( -5325 server_config.migration, -5326 "migration-initiating packets should have been dropped immediately" -5327 ); -5328 self.migrate(path_id, now, network_path, migration_observed_addr); -5329 // Break linkability, if possible -5330 self.update_remote_cid(path_id); -5331 self.spin = false; -5332 } -5333 -5334 Ok(()) -5335 } -5336 -5337 fn migrate( -5338 &mut self, -5339 path_id: PathId, -5340 now: Instant, -5341 network_path: FourTuple, -5342 observed_addr: Option<ObservedAddr>, -5343 ) { -5344 trace!(%network_path, %path_id, "migration initiated"); -5345 self.path_generation_counter = self.path_generation_counter.wrapping_add(1); -5346 // TODO(@divma): conditions for path migration in multipath are very specific, check them -5347 // again to prevent path migrations that should actually create a new path -5348 -5349 // Reset rtt/congestion state for new path unless it looks like a NAT rebinding. -5350 // Note that the congestion window will not grow until validation terminates. Helps mitigate -5351 // amplification attacks performed by spoofing source addresses. -5352 let prev_pto = self.pto(SpaceKind::Data, path_id); -5353 let path = self.paths.get_mut(&path_id).expect("known path"); -5354 let mut new_path_data = if network_path.remote.is_ipv4() -5355 && network_path.remote.ip() == path.data.network_path.remote.ip() -5356 { -5357 PathData::from_previous(network_path, &path.data, self.path_generation_counter, now) -5358 } else { -5359 let peer_max_udp_payload_size = -5360 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()) -5361 .unwrap_or(u16::MAX); -5362 PathData::new( -5363 network_path, -5364 self.allow_mtud, -5365 Some(peer_max_udp_payload_size), -5366 self.path_generation_counter, -5367 now, -5368 &self.config, -5369 ) -5370 }; -5371 new_path_data.last_observed_addr_report = path.data.last_observed_addr_report.clone(); -5372 if let Some(report) = observed_addr -5373 && let Some(updated) = new_path_data.update_observed_addr_report(report) -5374 { -5375 tracing::info!("adding observed addr event from migration"); -5376 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -5377 id: path_id, -5378 addr: updated, -5379 })); -5380 } -5381 new_path_data.pending_on_path_challenge = true; -5382 -5383 let mut prev_path_data = mem::replace(&mut path.data, new_path_data); -5384 -5385 // Only store this as previous path if it was validated. For all we know there could -5386 // already be a previous path stored which might have been validated in the past, -5387 // which is more valuable than one that's not yet validated. -5388 // -5389 // With multipath it is possible that there are no remote CIDs for the path ID -5390 // yet. In this case we would never have sent on this path yet and would not be able -5391 // to send a PATH_CHALLENGE either, which is currently a fire-and-forget affair -5392 // anyway. So don't store such a path either. -5393 if !prev_path_data.validated -5394 && let Some(cid) = self.remote_cids.get(&path_id).map(CidQueue::active) -5395 { -5396 prev_path_data.pending_on_path_challenge = true; -5397 // We haven't updated the remote CID yet, this captures the remote CID we were using on -5398 // the previous path. -5399 path.prev = Some((cid, prev_path_data)); -5400 } -5401 -5402 // We need to re-assign the correct remote to this path in qlog -5403 self.qlog.emit_tuple_assigned(path_id, network_path, now); -5404 -5405 self.timers.set( -5406 Timer::PerPath(path_id, PathTimer::PathValidationFailed), -5407 now + 3 * cmp::max(self.pto(SpaceKind::Data, path_id), prev_pto), -5408 self.qlog.with_time(now), -5409 ); -5410 } -5411 -5412 /// Handle a change in the local address, i.e. an active migration -5413 /// -5414 /// In the general (non-multipath) case, paths will perform a RFC9000 migration and be pinged -5415 /// for a liveness check. This is the behaviour of a path assumed to be recoverable, even if -5416 /// this is not the case. -5417 /// -5418 /// Clients in a connection in which multipath has been negotiated should migrate paths to new -5419 /// [`PathId`]s. For paths that are known to be non-recoverable can be migrated to a new -5420 /// [`PathId`] by closing the current path, and opening a new one to the same remote. Treating -5421 /// paths as non recoverable when necessary accelerates connectivity re-establishment, or might -5422 /// allow it altogether. -5423 /// -5424 /// The optional `hint` allows callers to indicate when paths are non-recoverable and should be -5425 /// migrated to new a [`PathId`]. -5426 // NOTE: only clients are allowed to migrate, but generally dealing with RFC9000 migrations is -5427 // lacking <https://github.com/n0-computer/noq/issues/364> -5428 pub fn handle_network_change(&mut self, hint: Option<&dyn NetworkChangeHint>, now: Instant) { -5429 debug!("network changed"); -5430 if self.state.is_drained() { -5431 return; -5432 } -5433 if self.highest_space < SpaceKind::Data { -5434 for path in self.paths.values_mut() { -5435 // Clear the local address for it to be obtained from the socket again. -5436 path.data.network_path.local_ip = None; -5437 } -5438 -5439 self.update_remote_cid(PathId::ZERO); -5440 self.ping(); -5441 -5442 return; -5443 } -5444 -5445 // Paths that can't recover so a new path should be open instead. If multipath is not -5446 // negotiated, this will be empty. -5447 let mut non_recoverable_paths = Vec::default(); -5448 let mut recoverable_paths = Vec::default(); -5449 let mut open_paths = 0; -5450 -5451 let is_multipath_negotiated = self.is_multipath_negotiated(); -5452 let is_client = self.side().is_client(); -5453 let immediate_ack_allowed = self.peer_supports_ack_frequency(); -5454 -5455 for (path_id, path) in self.paths.iter_mut() { -5456 if self.abandoned_paths.contains(path_id) { -5457 continue; -5458 } -5459 open_paths += 1; -5460 -5461 // Clear the local address for it to be obtained from the socket again. This applies to -5462 // all paths, regardless of being considered recoverable or not -5463 path.data.network_path.local_ip = None; -5464 -5465 let network_path = path.data.network_path; -5466 let remote = network_path.remote; -5467 -5468 // Without multipath, the connection tries to recover the single path, whereas with -5469 // multipath, even in a single-path scenario, we attempt to migrate the path to a new -5470 // PathId. -5471 let attempt_to_recover = if is_multipath_negotiated { -5472 if is_client { -5473 hint.map(|h| h.is_path_recoverable(*path_id, network_path)) -5474 .unwrap_or(false) -5475 } else { -5476 // Servers should have stable addresses so this scenario is generally discouraged. -5477 // There is no way to prevent this, so the best hope is to attempt to recover the -5478 // path -5479 true -5480 } -5481 } else { -5482 // In the non multipath case, we try to recover the single active path -5483 true -5484 }; +5072 } +5073 Frame::HandshakeDone => { +5074 if self.side.is_server() { +5075 return Err(TransportError::PROTOCOL_VIOLATION( +5076 "client sent HANDSHAKE_DONE", +5077 )); +5078 } +5079 if self.crypto_state.has_keys(EncryptionLevel::Handshake) { +5080 self.discard_space(now, SpaceKind::Handshake); +5081 } +5082 self.events.push_back(Event::HandshakeConfirmed); +5083 trace!("handshake confirmed"); +5084 } +5085 Frame::ObservedAddr(observed) => { +5086 // check if params allows the peer to send report and this node to receive it +5087 trace!(seq_no = %observed.seq_no, ip = %observed.ip, port = observed.port); +5088 if !self +5089 .peer_params +5090 .address_discovery_role +5091 .should_report(&self.config.address_discovery_role) +5092 { +5093 return Err(TransportError::PROTOCOL_VIOLATION( +5094 "received OBSERVED_ADDRESS frame when not negotiated", +5095 )); +5096 } +5097 // must only be sent in data space +5098 if packet.header.space() != SpaceKind::Data { +5099 return Err(TransportError::PROTOCOL_VIOLATION( +5100 "OBSERVED_ADDRESS frame outside data space", +5101 )); +5102 } +5103 +5104 let path = self.path_data_mut(path_id); +5105 if network_path == path.network_path { +5106 if let Some(updated) = path.update_observed_addr_report(observed) +5107 && path.open_status == paths::OpenStatus::Informed +5108 { +5109 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +5110 id: path_id, +5111 addr: updated, +5112 })); +5113 // otherwise the event is reported when the path is deemed open +5114 } +5115 } else { +5116 // include in migration +5117 migration_observed_addr = Some(observed) +5118 } +5119 } +5120 Frame::PathAbandon(frame::PathAbandon { +5121 path_id, +5122 error_code, +5123 }) => { +5124 span.record("path", tracing::field::display(&path_id)); +5125 match self.close_path_inner( +5126 now, +5127 path_id, +5128 PathAbandonReason::RemoteAbandoned { +5129 error_code: error_code.into(), +5130 }, +5131 ) { +5132 Ok(()) => { +5133 trace!("peer abandoned path"); +5134 } +5135 Err(ClosePathError::ClosedPath) => { +5136 trace!("peer abandoned already closed path"); +5137 } +5138 Err(ClosePathError::MultipathNotNegotiated) => { +5139 return Err(TransportError::PROTOCOL_VIOLATION( +5140 "received PATH_ABANDON frame when multipath was not negotiated", +5141 )); +5142 } +5143 Err(ClosePathError::LastOpenPath) => { +5144 // Not reachable: close_path_inner allows remote abandons +5145 // for the last path. But handle gracefully just in case. +5146 error!( +5147 "peer abandoned last path but close_path_inner returned LastOpenPath" +5148 ); +5149 } +5150 }; +5151 +5152 // Start draining the path if it still exists and hasn't started draining yet. +5153 if let Some(path) = self.paths.get_mut(&path_id) +5154 && !mem::replace(&mut path.data.draining, true) +5155 { +5156 let ack_delay = self.ack_frequency.max_ack_delay_for_pto(); +5157 let pto = path.data.rtt.pto_base() + ack_delay; +5158 self.timers.set( +5159 Timer::PerPath(path_id, PathTimer::PathDrained), +5160 now + 3 * pto, +5161 self.qlog.with_time(now), +5162 ); +5163 +5164 self.set_max_path_id(now, self.local_max_path_id.saturating_add(1u8)); +5165 } +5166 } +5167 Frame::PathStatusAvailable(info) => { +5168 span.record("path", tracing::field::display(&info.path_id)); +5169 if self.is_multipath_negotiated() { +5170 self.on_path_status( +5171 info.path_id, +5172 PathStatus::Available, +5173 info.status_seq_no, +5174 ); +5175 } else { +5176 return Err(TransportError::PROTOCOL_VIOLATION( +5177 "received PATH_STATUS_AVAILABLE frame when multipath was not negotiated", +5178 )); +5179 } +5180 } +5181 Frame::PathStatusBackup(info) => { +5182 span.record("path", tracing::field::display(&info.path_id)); +5183 if self.is_multipath_negotiated() { +5184 self.on_path_status(info.path_id, PathStatus::Backup, info.status_seq_no); +5185 } else { +5186 return Err(TransportError::PROTOCOL_VIOLATION( +5187 "received PATH_STATUS_BACKUP frame when multipath was not negotiated", +5188 )); +5189 } +5190 } +5191 Frame::MaxPathId(frame::MaxPathId(path_id)) => { +5192 span.record("path", tracing::field::display(&path_id)); +5193 if !self.is_multipath_negotiated() { +5194 return Err(TransportError::PROTOCOL_VIOLATION( +5195 "received MAX_PATH_ID frame when multipath was not negotiated", +5196 )); +5197 } +5198 // frames that do not increase the path id are ignored +5199 if path_id > self.remote_max_path_id { +5200 self.remote_max_path_id = path_id; +5201 self.issue_first_path_cids(now); +5202 while let Some(true) = self.continue_nat_traversal_round(now) {} +5203 } +5204 } +5205 Frame::PathsBlocked(frame::PathsBlocked(max_path_id)) => { +5206 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST +5207 // be treated as a connection error of type PROTOCOL_VIOLATION. +5208 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> +5209 if self.is_multipath_negotiated() { +5210 if max_path_id > self.local_max_path_id { +5211 return Err(TransportError::PROTOCOL_VIOLATION( +5212 "PATHS_BLOCKED maximum path identifier was larger than local maximum", +5213 )); +5214 } +5215 debug!("received PATHS_BLOCKED({:?})", max_path_id); +5216 // TODO(@divma): ensure max concurrent paths +5217 } else { +5218 return Err(TransportError::PROTOCOL_VIOLATION( +5219 "received PATHS_BLOCKED frame when not multipath was not negotiated", +5220 )); +5221 } +5222 } +5223 Frame::PathCidsBlocked(frame::PathCidsBlocked { path_id, next_seq }) => { +5224 // Nothing to do. This is recorded in the frame stats, but otherwise we +5225 // always issue all CIDs we're allowed to issue, so either this is an +5226 // impatient peer or a bug on our side. +5227 +5228 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST +5229 // be treated as a connection error of type PROTOCOL_VIOLATION. +5230 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> +5231 if self.is_multipath_negotiated() { +5232 if path_id > self.local_max_path_id { +5233 return Err(TransportError::PROTOCOL_VIOLATION( +5234 "PATH_CIDS_BLOCKED path identifier was larger than local maximum", +5235 )); +5236 } +5237 if next_seq.0 +5238 > self +5239 .local_cid_state +5240 .get(&path_id) +5241 .map(|cid_state| cid_state.active_seq().1 + 1) +5242 .unwrap_or_default() +5243 { +5244 return Err(TransportError::PROTOCOL_VIOLATION( +5245 "PATH_CIDS_BLOCKED next sequence number larger than in local state", +5246 )); +5247 } +5248 debug!(%path_id, %next_seq, "received PATH_CIDS_BLOCKED"); +5249 } else { +5250 return Err(TransportError::PROTOCOL_VIOLATION( +5251 "received PATH_CIDS_BLOCKED frame when not multipath was not negotiated", +5252 )); +5253 } +5254 } +5255 Frame::AddAddress(addr) => { +5256 let client_state = match self.n0_nat_traversal.client_side_mut() { +5257 Ok(state) => state, +5258 Err(err) => { +5259 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5260 "Nat traversal(ADD_ADDRESS): {err}" +5261 ))); +5262 } +5263 }; +5264 +5265 if !client_state.check_remote_address(&addr) { +5266 // if the address is not valid we flag it, but update anyway +5267 warn!(?addr, "server sent illegal ADD_ADDRESS frame"); +5268 } +5269 +5270 match client_state.add_remote_address(addr) { +5271 Ok(maybe_added) => { +5272 if let Some(added) = maybe_added { +5273 self.events.push_back(Event::NatTraversal( +5274 n0_nat_traversal::Event::AddressAdded(added), +5275 )); +5276 } +5277 } +5278 Err(e) => { +5279 warn!(%e, "failed to add remote address") +5280 } +5281 } +5282 } +5283 Frame::RemoveAddress(addr) => { +5284 let client_state = match self.n0_nat_traversal.client_side_mut() { +5285 Ok(state) => state, +5286 Err(err) => { +5287 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5288 "Nat traversal(REMOVE_ADDRESS): {err}" +5289 ))); +5290 } +5291 }; +5292 if let Some(removed_addr) = client_state.remove_remote_address(addr) { +5293 self.events.push_back(Event::NatTraversal( +5294 n0_nat_traversal::Event::AddressRemoved(removed_addr), +5295 )); +5296 } +5297 } +5298 Frame::ReachOut(reach_out) => { +5299 let ipv6 = self.is_ipv6(); +5300 let server_state = match self.n0_nat_traversal.server_side_mut() { +5301 Ok(state) => state, +5302 Err(err) => { +5303 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5304 "Nat traversal(REACH_OUT): {err}" +5305 ))); +5306 } +5307 }; +5308 +5309 if let Err(err) = server_state.handle_reach_out(reach_out, ipv6) { +5310 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5311 "Nat traversal(REACH_OUT): {err}" +5312 ))); +5313 } +5314 } +5315 } +5316 } +5317 +5318 let space = self.spaces[SpaceId::Data].for_path(path_id); +5319 if space +5320 .pending_acks +5321 .packet_received(now, number, ack_eliciting, &space.dedup) +5322 { +5323 if self.abandoned_paths.contains(&path_id) { +5324 // § 3.4.3 QUIC-MULTIPATH: promptly send ACKs for packets received from +5325 // abandoned paths. +5326 space.pending_acks.set_immediate_ack_required(); +5327 } else { +5328 self.timers.set( +5329 Timer::PerPath(path_id, PathTimer::MaxAckDelay), +5330 now + self.ack_frequency.max_ack_delay, +5331 self.qlog.with_time(now), +5332 ); +5333 } +5334 } +5335 +5336 // Issue stream ID credit due to ACKs of outgoing finish/resets and incoming finish/resets +5337 // on stopped streams. Incoming finishes/resets on open streams are not handled here as they +5338 // are only freed, and hence only issue credit, once the application has been notified +5339 // during a read on the stream. +5340 let pending = &mut self.spaces[SpaceId::Data].pending; +5341 self.streams.queue_max_stream_id(pending); +5342 +5343 if let Some(reason) = close { +5344 self.state.move_to_draining(Some(reason.into())); +5345 self.connection_close_pending = true; +5346 } +5347 +5348 if Some(number) == self.spaces[SpaceId::Data].for_path(path_id).rx_packet +5349 && !is_probing_packet +5350 && network_path != self.path_data(path_id).network_path +5351 { +5352 let ConnectionSide::Server { ref server_config } = self.side else { +5353 panic!("packets from unknown remote should be dropped by clients"); +5354 }; +5355 debug_assert!( +5356 server_config.migration, +5357 "migration-initiating packets should have been dropped immediately" +5358 ); +5359 self.migrate(path_id, now, network_path, migration_observed_addr); +5360 // Break linkability, if possible +5361 self.update_remote_cid(path_id); +5362 self.spin = false; +5363 } +5364 +5365 Ok(()) +5366 } +5367 +5368 fn migrate( +5369 &mut self, +5370 path_id: PathId, +5371 now: Instant, +5372 network_path: FourTuple, +5373 observed_addr: Option<ObservedAddr>, +5374 ) { +5375 trace!(%network_path, %path_id, "migration initiated"); +5376 self.path_generation_counter = self.path_generation_counter.wrapping_add(1); +5377 // TODO(@divma): conditions for path migration in multipath are very specific, check them +5378 // again to prevent path migrations that should actually create a new path +5379 +5380 // Reset rtt/congestion state for new path unless it looks like a NAT rebinding. +5381 // Note that the congestion window will not grow until validation terminates. Helps mitigate +5382 // amplification attacks performed by spoofing source addresses. +5383 let prev_pto = self.pto(SpaceKind::Data, path_id); +5384 let path = self.paths.get_mut(&path_id).expect("known path"); +5385 let mut new_path_data = if network_path.remote.is_ipv4() +5386 && network_path.remote.ip() == path.data.network_path.remote.ip() +5387 { +5388 PathData::from_previous(network_path, &path.data, self.path_generation_counter, now) +5389 } else { +5390 let peer_max_udp_payload_size = +5391 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()) +5392 .unwrap_or(u16::MAX); +5393 PathData::new( +5394 network_path, +5395 self.allow_mtud, +5396 Some(peer_max_udp_payload_size), +5397 self.path_generation_counter, +5398 now, +5399 &self.config, +5400 ) +5401 }; +5402 new_path_data.last_observed_addr_report = path.data.last_observed_addr_report.clone(); +5403 if let Some(report) = observed_addr +5404 && let Some(updated) = new_path_data.update_observed_addr_report(report) +5405 { +5406 tracing::info!("adding observed addr event from migration"); +5407 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +5408 id: path_id, +5409 addr: updated, +5410 })); +5411 } +5412 new_path_data.pending_on_path_challenge = true; +5413 +5414 let mut prev_path_data = mem::replace(&mut path.data, new_path_data); +5415 +5416 // Only store this as previous path if it was validated. For all we know there could +5417 // already be a previous path stored which might have been validated in the past, +5418 // which is more valuable than one that's not yet validated. +5419 // +5420 // With multipath it is possible that there are no remote CIDs for the path ID +5421 // yet. In this case we would never have sent on this path yet and would not be able +5422 // to send a PATH_CHALLENGE either, which is currently a fire-and-forget affair +5423 // anyway. So don't store such a path either. +5424 if !prev_path_data.validated +5425 && let Some(cid) = self.remote_cids.get(&path_id).map(CidQueue::active) +5426 { +5427 prev_path_data.pending_on_path_challenge = true; +5428 // We haven't updated the remote CID yet, this captures the remote CID we were using on +5429 // the previous path. +5430 path.prev = Some((cid, prev_path_data)); +5431 } +5432 +5433 // We need to re-assign the correct remote to this path in qlog +5434 self.qlog.emit_tuple_assigned(path_id, network_path, now); +5435 +5436 self.timers.set( +5437 Timer::PerPath(path_id, PathTimer::PathValidationFailed), +5438 now + 3 * cmp::max(self.pto(SpaceKind::Data, path_id), prev_pto), +5439 self.qlog.with_time(now), +5440 ); +5441 } +5442 +5443 /// Handle a change in the local address, i.e. an active migration +5444 /// +5445 /// In the general (non-multipath) case, paths will perform a RFC9000 migration and be pinged +5446 /// for a liveness check. This is the behaviour of a path assumed to be recoverable, even if +5447 /// this is not the case. +5448 /// +5449 /// Clients in a connection in which multipath has been negotiated should migrate paths to new +5450 /// [`PathId`]s. For paths that are known to be non-recoverable can be migrated to a new +5451 /// [`PathId`] by closing the current path, and opening a new one to the same remote. Treating +5452 /// paths as non recoverable when necessary accelerates connectivity re-establishment, or might +5453 /// allow it altogether. +5454 /// +5455 /// The optional `hint` allows callers to indicate when paths are non-recoverable and should be +5456 /// migrated to new a [`PathId`]. +5457 // NOTE: only clients are allowed to migrate, but generally dealing with RFC9000 migrations is +5458 // lacking <https://github.com/n0-computer/noq/issues/364> +5459 pub fn handle_network_change(&mut self, hint: Option<&dyn NetworkChangeHint>, now: Instant) { +5460 debug!("network changed"); +5461 if self.state.is_drained() { +5462 return; +5463 } +5464 if self.highest_space < SpaceKind::Data { +5465 for path in self.paths.values_mut() { +5466 // Clear the local address for it to be obtained from the socket again. +5467 path.data.network_path.local_ip = None; +5468 } +5469 +5470 self.update_remote_cid(PathId::ZERO); +5471 self.ping(); +5472 +5473 return; +5474 } +5475 +5476 // Paths that can't recover so a new path should be open instead. If multipath is not +5477 // negotiated, this will be empty. +5478 let mut non_recoverable_paths = Vec::default(); +5479 let mut recoverable_paths = Vec::default(); +5480 let mut open_paths = 0; +5481 +5482 let is_multipath_negotiated = self.is_multipath_negotiated(); +5483 let is_client = self.side().is_client(); +5484 let immediate_ack_allowed = self.peer_supports_ack_frequency(); 5485 -5486 if attempt_to_recover { -5487 recoverable_paths.push((*path_id, remote)); -5488 } else { -5489 non_recoverable_paths.push((*path_id, remote, path.data.local_status())) -5490 } -5491 } -5492 -5493 /* NON RECOVERABLE PATHS */ -5494 // This are handled first, so that in case the treatment intended for these fails, we can -5495 // go the recoverable route instead. -5496 -5497 // Decide if we need to close first or open first in the multipath case. -5498 // - Opening first has a higher risk of getting limited by the negotiated MAX_PATH_ID. -5499 // - Closing first risks this being the only open path. -5500 // We prefer closing paths first unless we identify this is the last open path. -5501 let open_first = open_paths == non_recoverable_paths.len(); -5502 -5503 for (path_id, remote, status) in non_recoverable_paths.into_iter() { -5504 let network_path = FourTuple { -5505 remote, -5506 local_ip: None, /* allow the local ip to be discovered */ -5507 }; -5508 -5509 if open_first && let Err(e) = self.open_path(network_path, status, now) { -5510 debug!(%e,"Failed to open new path for network change"); -5511 // if this fails, let the path try to recover itself -5512 recoverable_paths.push((path_id, remote)); -5513 continue; -5514 } -5515 -5516 if let Err(e) = -5517 self.close_path_inner(now, path_id, PathAbandonReason::UnusableAfterNetworkChange) -5518 { -5519 debug!(%e,"Failed to close unrecoverable path after network change"); -5520 recoverable_paths.push((path_id, remote)); -5521 continue; -5522 } -5523 -5524 if !open_first && let Err(e) = self.open_path(network_path, status, now) { -5525 // Path has already been closed if we got here. Since the path was not recoverable, -5526 // this might be desirable in any case, because other paths exist (!open_first) and -5527 // this was is considered non recoverable -5528 debug!(%e,"Failed to open new path for network change"); -5529 } -5530 } -5531 -5532 /* RECOVERABLE PATHS */ -5533 -5534 for (path_id, remote) in recoverable_paths.into_iter() { -5535 // Schedule a Ping for a liveness check. -5536 if let Some(path_space) = self.spaces[SpaceId::Data].number_spaces.get_mut(&path_id) { -5537 path_space.ping_pending = true; -5538 -5539 if immediate_ack_allowed { -5540 path_space.immediate_ack_pending = true; -5541 } -5542 } -5543 -5544 // Reset PTO backoff so retransmits resume promptly. Congestion controller -5545 // and RTT are intentionally preserved for recoverable paths. -5546 if let Some(path) = self.paths.get_mut(&path_id) { -5547 path.data.pto_count = 0; -5548 } -5549 self.set_loss_detection_timer(now, path_id); -5550 -5551 let Some((reset_token, retired)) = -5552 self.remote_cids.get_mut(&path_id).and_then(CidQueue::next) -5553 else { +5486 for (path_id, path) in self.paths.iter_mut() { +5487 if self.abandoned_paths.contains(path_id) { +5488 continue; +5489 } +5490 open_paths += 1; +5491 +5492 // Read the network path BEFORE clearing local_ip, so the hint can +5493 // check which interface the path was using. +5494 let network_path = path.data.network_path; +5495 +5496 // Clear the local address for it to be obtained from the socket again. This applies to +5497 // all paths, regardless of being considered recoverable or not +5498 path.data.network_path.local_ip = None; +5499 let remote = network_path.remote; +5500 +5501 // Without multipath, the connection tries to recover the single path, whereas with +5502 // multipath, even in a single-path scenario, we attempt to migrate the path to a new +5503 // PathId. +5504 let attempt_to_recover = if is_multipath_negotiated { +5505 if is_client { +5506 hint.map(|h| h.is_path_recoverable(*path_id, network_path)) +5507 .unwrap_or(false) +5508 } else { +5509 // Servers should have stable addresses so this scenario is generally discouraged. +5510 // There is no way to prevent this, so the best hope is to attempt to recover the +5511 // path +5512 true +5513 } +5514 } else { +5515 // In the non multipath case, we try to recover the single active path +5516 true +5517 }; +5518 +5519 if attempt_to_recover { +5520 recoverable_paths.push((*path_id, remote)); +5521 } else { +5522 non_recoverable_paths.push((*path_id, remote, path.data.local_status())) +5523 } +5524 } +5525 +5526 /* NON RECOVERABLE PATHS */ +5527 // This are handled first, so that in case the treatment intended for these fails, we can +5528 // go the recoverable route instead. +5529 +5530 // Decide if we need to close first or open first in the multipath case. +5531 // - Opening first has a higher risk of getting limited by the negotiated MAX_PATH_ID. +5532 // - Closing first risks this being the only open path. +5533 // We prefer closing paths first unless we identify this is the last open path. +5534 let open_first = open_paths == non_recoverable_paths.len(); +5535 +5536 for (path_id, remote, status) in non_recoverable_paths.into_iter() { +5537 let network_path = FourTuple { +5538 remote, +5539 local_ip: None, /* allow the local ip to be discovered */ +5540 }; +5541 +5542 if open_first && let Err(e) = self.open_path(network_path, status, now) { +5543 debug!(%e,"Failed to open new path for network change"); +5544 // if this fails, let the path try to recover itself +5545 recoverable_paths.push((path_id, remote)); +5546 continue; +5547 } +5548 +5549 if let Err(e) = +5550 self.close_path_inner(now, path_id, PathAbandonReason::UnusableAfterNetworkChange) +5551 { +5552 debug!(%e,"Failed to close unrecoverable path after network change"); +5553 recoverable_paths.push((path_id, remote)); 5554 continue; -5555 }; +5555 } 5556 -5557 // Retire the current remote CID and any CIDs we had to skip. -5558 self.spaces[SpaceId::Data] -5559 .pending -5560 .retire_cids -5561 .extend(retired.map(|seq| (path_id, seq))); -5562 -5563 debug_assert!(!self.state.is_drained()); // required for endpoint_events, checked above -5564 self.endpoint_events -5565 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); -5566 } -5567 } -5568 -5569 /// Switch to a previously unused remote connection ID, if possible -5570 fn update_remote_cid(&mut self, path_id: PathId) { -5571 let Some((reset_token, retired)) = self -5572 .remote_cids -5573 .get_mut(&path_id) -5574 .and_then(|cids| cids.next()) -5575 else { -5576 return; -5577 }; -5578 -5579 // Retire the current remote CID and any CIDs we had to skip. -5580 self.spaces[SpaceId::Data] -5581 .pending -5582 .retire_cids -5583 .extend(retired.map(|seq| (path_id, seq))); -5584 let remote = self.path_data(path_id).network_path.remote; -5585 self.set_reset_token(path_id, remote, reset_token); -5586 } -5587 -5588 /// Sends this reset token to the endpoint -5589 /// -5590 /// The endpoint needs to know the reset tokens issued by the peer, so that if the peer -5591 /// sends a reset token it knows to route it to this connection. See RFC 9000 section -5592 /// 10.3. Stateless Reset. -5593 /// -5594 /// Reset tokens are different for each path, the endpoint identifies paths by peer -5595 /// socket address however, not by path ID. -5596 fn set_reset_token(&mut self, path_id: PathId, remote: SocketAddr, reset_token: ResetToken) { -5597 debug_assert!(!self.state.is_drained()); // required for endpoint events, set_reset_token is never called for drained connections -5598 self.endpoint_events -5599 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); -5600 -5601 // During the handshake the server sends a reset token in the transport -5602 // parameters. When we are the client and we receive the reset token during the -5603 // handshake we want this to affect our peer transport parameters. -5604 // TODO(flub): Pretty sure this is pointless, the entire params is overwritten -5605 // shortly after this was called. And then the params don't have this anymore. -5606 if path_id == PathId::ZERO { -5607 self.peer_params.stateless_reset_token = Some(reset_token); -5608 } -5609 } -5610 -5611 /// Issue an initial set of connection IDs to the peer upon connection -5612 fn issue_first_cids(&mut self, now: Instant) { -5613 if self -5614 .local_cid_state -5615 .get(&PathId::ZERO) -5616 .expect("PathId::ZERO exists when the connection is created") -5617 .cid_len() -5618 == 0 -5619 { -5620 return; -5621 } +5557 if !open_first && let Err(e) = self.open_path(network_path, status, now) { +5558 // Path has already been closed if we got here. Since the path was not recoverable, +5559 // this might be desirable in any case, because other paths exist (!open_first) and +5560 // this was is considered non recoverable +5561 debug!(%e,"Failed to open new path for network change"); +5562 } +5563 } +5564 +5565 /* RECOVERABLE PATHS */ +5566 +5567 for (path_id, remote) in recoverable_paths.into_iter() { +5568 // Schedule a Ping for a liveness check. +5569 if let Some(path_space) = self.spaces[SpaceId::Data].number_spaces.get_mut(&path_id) { +5570 path_space.ping_pending = true; +5571 +5572 if immediate_ack_allowed { +5573 path_space.immediate_ack_pending = true; +5574 } +5575 } +5576 +5577 // Reset PTO backoff so retransmits resume promptly. Congestion controller and +5578 // RTT are intentionally preserved for recoverable paths. We explicitly allow +5579 // this reset also during the hanshake, so do not check +5580 // Self::peer_competed_handshake_address_validation. +5581 if let Some(path) = self.paths.get_mut(&path_id) { +5582 path.data.pto_count = 0; +5583 } +5584 self.set_loss_detection_timer(now, path_id); +5585 +5586 let Some((reset_token, retired)) = +5587 self.remote_cids.get_mut(&path_id).and_then(CidQueue::next) +5588 else { +5589 continue; +5590 }; +5591 +5592 // Retire the current remote CID and any CIDs we had to skip. +5593 self.spaces[SpaceId::Data] +5594 .pending +5595 .retire_cids +5596 .extend(retired.map(|seq| (path_id, seq))); +5597 +5598 debug_assert!(!self.state.is_drained()); // required for endpoint_events, checked above +5599 self.endpoint_events +5600 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); +5601 } +5602 } +5603 +5604 /// Switch to a previously unused remote connection ID, if possible +5605 fn update_remote_cid(&mut self, path_id: PathId) { +5606 let Some((reset_token, retired)) = self +5607 .remote_cids +5608 .get_mut(&path_id) +5609 .and_then(|cids| cids.next()) +5610 else { +5611 return; +5612 }; +5613 +5614 // Retire the current remote CID and any CIDs we had to skip. +5615 self.spaces[SpaceId::Data] +5616 .pending +5617 .retire_cids +5618 .extend(retired.map(|seq| (path_id, seq))); +5619 let remote = self.path_data(path_id).network_path.remote; +5620 self.set_reset_token(path_id, remote, reset_token); +5621 } 5622 -5623 // Subtract 1 to account for the CID we supplied while handshaking -5624 let mut n = self.peer_params.issue_cids_limit() - 1; -5625 if let ConnectionSide::Server { server_config } = &self.side -5626 && server_config.has_preferred_address() -5627 { -5628 // We also sent a CID in the transport parameters -5629 n -= 1; -5630 } -5631 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events -5632 self.endpoint_events -5633 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); -5634 } +5623 /// Sends this reset token to the endpoint +5624 /// +5625 /// The endpoint needs to know the reset tokens issued by the peer, so that if the peer +5626 /// sends a reset token it knows to route it to this connection. See RFC 9000 section +5627 /// 10.3. Stateless Reset. +5628 /// +5629 /// Reset tokens are different for each path, the endpoint identifies paths by peer +5630 /// socket address however, not by path ID. +5631 fn set_reset_token(&mut self, path_id: PathId, remote: SocketAddr, reset_token: ResetToken) { +5632 debug_assert!(!self.state.is_drained()); // required for endpoint events, set_reset_token is never called for drained connections +5633 self.endpoint_events +5634 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); 5635 -5636 /// Issues an initial set of CIDs for paths that have not yet had any CIDs issued -5637 /// -5638 /// Later CIDs are issued when CIDs expire or are retired by the peer. -5639 fn issue_first_path_cids(&mut self, now: Instant) { -5640 if let Some(max_path_id) = self.max_path_id() { -5641 let mut path_id = self.max_path_id_with_cids.next(); -5642 while path_id <= max_path_id { -5643 self.endpoint_events -5644 .push_back(EndpointEventInner::NeedIdentifiers( -5645 path_id, -5646 now, -5647 self.peer_params.issue_cids_limit(), -5648 )); -5649 path_id = path_id.next(); -5650 } -5651 self.max_path_id_with_cids = max_path_id; -5652 } -5653 } -5654 -5655 /// Populates a packet with frames -5656 /// -5657 /// This tries to fit as many frames as possible into the packet. -5658 /// -5659 /// *path_exclusive_only* means to only build frames which can only be sent on this -5660 /// *path. This is used in multipath for backup paths while there is still an active -5661 /// *path. -5662 fn populate_packet<'a, 'b>( -5663 &mut self, -5664 now: Instant, -5665 space_id: SpaceId, -5666 path_id: PathId, -5667 scheduling_info: &PathSchedulingInfo, -5668 builder: &mut PacketBuilder<'a, 'b>, -5669 ) { -5670 let is_multipath_negotiated = self.is_multipath_negotiated(); -5671 let space_has_keys = self.crypto_state.has_keys(space_id.encryption_level()); -5672 let is_0rtt = space_id == SpaceId::Data && !space_has_keys; -5673 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -5674 let space = &mut self.spaces[space_id]; -5675 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; -5676 space -5677 .for_path(path_id) -5678 .pending_acks -5679 .maybe_ack_non_eliciting(); -5680 -5681 // HANDSHAKE_DONE -5682 if !is_0rtt -5683 && !scheduling_info.is_abandoned -5684 && scheduling_info.may_send_data -5685 && mem::replace(&mut space.pending.handshake_done, false) -5686 { -5687 builder.write_frame(frame::HandshakeDone, stats); -5688 } +5636 // During the handshake the server sends a reset token in the transport +5637 // parameters. When we are the client and we receive the reset token during the +5638 // handshake we want this to affect our peer transport parameters. +5639 // TODO(flub): Pretty sure this is pointless, the entire params is overwritten +5640 // shortly after this was called. And then the params don't have this anymore. +5641 if path_id == PathId::ZERO { +5642 self.peer_params.stateless_reset_token = Some(reset_token); +5643 } +5644 } +5645 +5646 /// Issue an initial set of connection IDs to the peer upon connection +5647 fn issue_first_cids(&mut self, now: Instant) { +5648 if self +5649 .local_cid_state +5650 .get(&PathId::ZERO) +5651 .expect("PathId::ZERO exists when the connection is created") +5652 .cid_len() +5653 == 0 +5654 { +5655 return; +5656 } +5657 +5658 // Subtract 1 to account for the CID we supplied while handshaking +5659 let mut n = self.peer_params.issue_cids_limit() - 1; +5660 if let ConnectionSide::Server { server_config } = &self.side +5661 && server_config.has_preferred_address() +5662 { +5663 // We also sent a CID in the transport parameters +5664 n -= 1; +5665 } +5666 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events +5667 self.endpoint_events +5668 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); +5669 } +5670 +5671 /// Issues an initial set of CIDs for paths that have not yet had any CIDs issued +5672 /// +5673 /// Later CIDs are issued when CIDs expire or are retired by the peer. +5674 fn issue_first_path_cids(&mut self, now: Instant) { +5675 if let Some(max_path_id) = self.max_path_id() { +5676 let mut path_id = self.max_path_id_with_cids.next(); +5677 while path_id <= max_path_id { +5678 self.endpoint_events +5679 .push_back(EndpointEventInner::NeedIdentifiers( +5680 path_id, +5681 now, +5682 self.peer_params.issue_cids_limit(), +5683 )); +5684 path_id = path_id.next(); +5685 } +5686 self.max_path_id_with_cids = max_path_id; +5687 } +5688 } 5689 -5690 // PING -5691 if !scheduling_info.is_abandoned -5692 && mem::replace(&mut space.for_path(path_id).ping_pending, false) -5693 { -5694 builder.write_frame(frame::Ping, stats); -5695 } -5696 -5697 // IMMEDIATE_ACK -5698 if !scheduling_info.is_abandoned -5699 && mem::replace(&mut space.for_path(path_id).immediate_ack_pending, false) -5700 { -5701 debug_assert_eq!( -5702 space_id, -5703 SpaceId::Data, -5704 "immediate acks must be sent in the data space" -5705 ); -5706 builder.write_frame(frame::ImmediateAck, stats); -5707 } -5708 -5709 // ACK -5710 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { -5711 for path_id in space -5712 .number_spaces -5713 .iter_mut() -5714 .filter(|(_, pns)| pns.pending_acks.can_send()) -5715 .map(|(&path_id, _)| path_id) -5716 .collect::<Vec<_>>() -5717 { -5718 Self::populate_acks( -5719 now, -5720 self.receiving_ecn, -5721 path_id, -5722 space_id, -5723 space, -5724 is_multipath_negotiated, -5725 builder, -5726 stats, -5727 space_has_keys, -5728 ); -5729 } +5690 /// Populates a packet with frames +5691 /// +5692 /// This tries to fit as many frames as possible into the packet. +5693 /// +5694 /// *path_exclusive_only* means to only build frames which can only be sent on this +5695 /// *path. This is used in multipath for backup paths while there is still an active +5696 /// *path. +5697 fn populate_packet<'a, 'b>( +5698 &mut self, +5699 now: Instant, +5700 space_id: SpaceId, +5701 path_id: PathId, +5702 scheduling_info: &PathSchedulingInfo, +5703 builder: &mut PacketBuilder<'a, 'b>, +5704 ) { +5705 let is_multipath_negotiated = self.is_multipath_negotiated(); +5706 let space_has_keys = self.crypto_state.has_keys(space_id.encryption_level()); +5707 let is_0rtt = space_id == SpaceId::Data && !space_has_keys; +5708 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +5709 let space = &mut self.spaces[space_id]; +5710 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; +5711 space +5712 .for_path(path_id) +5713 .pending_acks +5714 .maybe_ack_non_eliciting(); +5715 +5716 // HANDSHAKE_DONE +5717 if !is_0rtt +5718 && !scheduling_info.is_abandoned +5719 && scheduling_info.may_send_data +5720 && mem::replace(&mut space.pending.handshake_done, false) +5721 { +5722 builder.write_frame(frame::HandshakeDone, stats); +5723 } +5724 +5725 // PING +5726 if !scheduling_info.is_abandoned +5727 && mem::replace(&mut space.for_path(path_id).ping_pending, false) +5728 { +5729 builder.write_frame(frame::Ping, stats); 5730 } 5731 -5732 // ACK_FREQUENCY +5732 // IMMEDIATE_ACK 5733 if !scheduling_info.is_abandoned -5734 && scheduling_info.may_send_data -5735 && mem::replace(&mut space.pending.ack_frequency, false) -5736 { -5737 let sequence_number = self.ack_frequency.next_sequence_number(); -5738 -5739 // Safe to unwrap because this is always provided when ACK frequency is enabled -5740 let config = self.config.ack_frequency_config.as_ref().unwrap(); -5741 -5742 // Ensure the delay is within bounds to avoid a PROTOCOL_VIOLATION error -5743 let max_ack_delay = self.ack_frequency.candidate_max_ack_delay( -5744 path.rtt.get(), -5745 config, -5746 &self.peer_params, -5747 ); -5748 -5749 let frame = frame::AckFrequency { -5750 sequence: sequence_number, -5751 ack_eliciting_threshold: config.ack_eliciting_threshold, -5752 request_max_ack_delay: max_ack_delay.as_micros().try_into().unwrap_or(VarInt::MAX), -5753 reordering_threshold: config.reordering_threshold, -5754 }; -5755 builder.write_frame(frame, stats); -5756 -5757 self.ack_frequency -5758 .ack_frequency_sent(path_id, builder.packet_number, max_ack_delay); -5759 } -5760 -5761 // PATH_CHALLENGE -5762 if !scheduling_info.is_abandoned -5763 && space_id == SpaceId::Data -5764 && path.pending_on_path_challenge -5765 && !self.state.is_closed() -5766 && builder.frame_space_remaining() > frame::PathChallenge::SIZE_BOUND -5767 // we don't want to send new challenges if we are already closing -5768 { -5769 path.pending_on_path_challenge = false; -5770 -5771 let token = self.rng.random(); -5772 path.record_path_challenge_sent(now, token, path.network_path); -5773 // Generate a new challenge every time we send a new PATH_CHALLENGE -5774 let challenge = frame::PathChallenge(token); -5775 builder.write_frame(challenge, stats); -5776 builder.require_padding(); -5777 let pto = self.ack_frequency.max_ack_delay_for_pto() + path.rtt.pto_base(); -5778 if path.open_status == paths::OpenStatus::Pending { -5779 path.open_status = paths::OpenStatus::Sent; -5780 self.timers.set( -5781 Timer::PerPath(path_id, PathTimer::PathOpenFailed), -5782 now + 3 * pto, -5783 self.qlog.with_time(now), -5784 ); -5785 } -5786 -5787 self.timers.set( -5788 Timer::PerPath(path_id, PathTimer::PathChallengeLost), -5789 now + pto, -5790 self.qlog.with_time(now), -5791 ); -5792 -5793 if is_multipath_negotiated && !path.validated && path.pending_on_path_challenge { -5794 // queue informing the path status along with the challenge -5795 space.pending.path_status.insert(path_id); -5796 } -5797 -5798 // Always include an OBSERVED_ADDR frame with a PATH_CHALLENGE, regardless -5799 // of whether one has already been sent on this path. -5800 if space_id == SpaceId::Data -5801 && self -5802 .config -5803 .address_discovery_role -5804 .should_report(&self.peer_params.address_discovery_role) -5805 { -5806 let frame = frame::ObservedAddr::new( -5807 path.network_path.remote, -5808 self.next_observed_addr_seq_no, -5809 ); -5810 if builder.frame_space_remaining() > frame.size() { -5811 builder.write_frame(frame, stats); -5812 -5813 self.next_observed_addr_seq_no = -5814 self.next_observed_addr_seq_no.saturating_add(1u8); -5815 path.observed_addr_sent = true; -5816 -5817 space.pending.observed_addr = false; -5818 } -5819 } -5820 } +5734 && mem::replace(&mut space.for_path(path_id).immediate_ack_pending, false) +5735 { +5736 debug_assert_eq!( +5737 space_id, +5738 SpaceId::Data, +5739 "immediate acks must be sent in the data space" +5740 ); +5741 builder.write_frame(frame::ImmediateAck, stats); +5742 } +5743 +5744 // ACK +5745 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { +5746 for path_id in space +5747 .number_spaces +5748 .iter_mut() +5749 .filter(|(_, pns)| pns.pending_acks.can_send()) +5750 .map(|(&path_id, _)| path_id) +5751 .collect::<Vec<_>>() +5752 { +5753 Self::populate_acks( +5754 now, +5755 self.receiving_ecn, +5756 path_id, +5757 space_id, +5758 space, +5759 is_multipath_negotiated, +5760 builder, +5761 stats, +5762 space_has_keys, +5763 ); +5764 } +5765 } +5766 +5767 // ACK_FREQUENCY +5768 if !scheduling_info.is_abandoned +5769 && scheduling_info.may_send_data +5770 && mem::replace(&mut space.pending.ack_frequency, false) +5771 { +5772 let sequence_number = self.ack_frequency.next_sequence_number(); +5773 +5774 // Safe to unwrap because this is always provided when ACK frequency is enabled +5775 let config = self.config.ack_frequency_config.as_ref().unwrap(); +5776 +5777 // Ensure the delay is within bounds to avoid a PROTOCOL_VIOLATION error +5778 let max_ack_delay = self.ack_frequency.candidate_max_ack_delay( +5779 path.rtt.get(), +5780 config, +5781 &self.peer_params, +5782 ); +5783 +5784 let frame = frame::AckFrequency { +5785 sequence: sequence_number, +5786 ack_eliciting_threshold: config.ack_eliciting_threshold, +5787 request_max_ack_delay: max_ack_delay.as_micros().try_into().unwrap_or(VarInt::MAX), +5788 reordering_threshold: config.reordering_threshold, +5789 }; +5790 builder.write_frame(frame, stats); +5791 +5792 self.ack_frequency +5793 .ack_frequency_sent(path_id, builder.packet_number, max_ack_delay); +5794 } +5795 +5796 // PATH_CHALLENGE +5797 if !scheduling_info.is_abandoned +5798 && space_id == SpaceId::Data +5799 && path.pending_on_path_challenge +5800 && !self.state.is_closed() +5801 && builder.frame_space_remaining() > frame::PathChallenge::SIZE_BOUND +5802 // we don't want to send new challenges if we are already closing +5803 { +5804 path.pending_on_path_challenge = false; +5805 +5806 let token = self.rng.random(); +5807 path.record_path_challenge_sent(now, token, path.network_path); +5808 // Generate a new challenge every time we send a new PATH_CHALLENGE +5809 let challenge = frame::PathChallenge(token); +5810 builder.write_frame(challenge, stats); +5811 builder.require_padding(); +5812 let pto = self.ack_frequency.max_ack_delay_for_pto() + path.rtt.pto_base(); +5813 if path.open_status == paths::OpenStatus::Pending { +5814 path.open_status = paths::OpenStatus::Sent; +5815 self.timers.set( +5816 Timer::PerPath(path_id, PathTimer::PathOpenFailed), +5817 now + 3 * pto, +5818 self.qlog.with_time(now), +5819 ); +5820 } 5821 -5822 // PATH_RESPONSE -5823 if !scheduling_info.is_abandoned -5824 && space_id == SpaceId::Data -5825 && builder.frame_space_remaining() > frame::PathResponse::SIZE_BOUND -5826 && let Some(token) = path.path_responses.pop_on_path(path.network_path) -5827 { -5828 let response = frame::PathResponse(token); -5829 builder.write_frame(response, stats); -5830 builder.require_padding(); -5831 -5832 // NOTE: this is technically not required but might be useful to ride the -5833 // request/response nature of path challenges to refresh an observation -5834 // Since PATH_RESPONSE is a probing frame, this is allowed by the spec. +5822 self.timers.set( +5823 Timer::PerPath(path_id, PathTimer::PathChallengeLost), +5824 now + pto, +5825 self.qlog.with_time(now), +5826 ); +5827 +5828 if is_multipath_negotiated && !path.validated && path.pending_on_path_challenge { +5829 // queue informing the path status along with the challenge +5830 space.pending.path_status.insert(path_id); +5831 } +5832 +5833 // Always include an OBSERVED_ADDR frame with a PATH_CHALLENGE, regardless +5834 // of whether one has already been sent on this path. 5835 if space_id == SpaceId::Data 5836 && self 5837 .config @@ -5854,1625 +5854,1660 @@ 5854 } 5855 } 5856 -5857 // REACH_OUT +5857 // PATH_RESPONSE 5858 if !scheduling_info.is_abandoned -5859 && scheduling_info.may_send_data -5860 && let Some((round, addresses)) = space.pending.reach_out.as_mut() -5861 { -5862 while let Some(local_addr) = addresses.iter().next().copied() { -5863 let local_addr = addresses.take(&local_addr).expect("found from iter"); -5864 let reach_out = frame::ReachOut::new(*round, local_addr); -5865 if builder.frame_space_remaining() > reach_out.size() { -5866 builder.write_frame(reach_out, stats); -5867 } else { -5868 addresses.insert(local_addr); -5869 break; -5870 } -5871 } -5872 if addresses.is_empty() { -5873 space.pending.reach_out = None; -5874 } -5875 } -5876 -5877 // PATH_ABANDON -5878 if space_id == SpaceId::Data -5879 && scheduling_info.is_abandoned -5880 && scheduling_info.may_self_abandon -5881 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() -5882 && let Some(error_code) = space.pending.path_abandon.remove(&path_id) -5883 { -5884 let frame = frame::PathAbandon { -5885 path_id, -5886 error_code, -5887 }; -5888 builder.write_frame(frame, stats); -5889 -5890 // Consider remotely issued CIDs as retired now that we have sent this frame at -5891 // least once. -5892 self.remote_cids.remove(&path_id); -5893 } -5894 while space_id == SpaceId::Data -5895 && scheduling_info.may_send_data -5896 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() -5897 && let Some((abandoned_path_id, error_code)) = space.pending.path_abandon.pop_first() -5898 { -5899 let frame = frame::PathAbandon { -5900 path_id: abandoned_path_id, -5901 error_code, -5902 }; -5903 builder.write_frame(frame, stats); -5904 -5905 // Consider remotely issued CIDs as retired now that we have sent this frame at -5906 // least once. -5907 self.remote_cids.remove(&abandoned_path_id); -5908 } -5909 -5910 // OBSERVED_ADDR -5911 if !scheduling_info.is_abandoned -5912 && scheduling_info.may_send_data -5913 && space_id == SpaceId::Data -5914 && self -5915 .config -5916 .address_discovery_role -5917 .should_report(&self.peer_params.address_discovery_role) -5918 && (!path.observed_addr_sent || space.pending.observed_addr) -5919 { -5920 let frame = -5921 frame::ObservedAddr::new(path.network_path.remote, self.next_observed_addr_seq_no); -5922 if builder.frame_space_remaining() > frame.size() { -5923 builder.write_frame(frame, stats); +5859 && space_id == SpaceId::Data +5860 && builder.frame_space_remaining() > frame::PathResponse::SIZE_BOUND +5861 && let Some(token) = path.path_responses.pop_on_path(path.network_path) +5862 { +5863 let response = frame::PathResponse(token); +5864 builder.write_frame(response, stats); +5865 builder.require_padding(); +5866 +5867 // NOTE: this is technically not required but might be useful to ride the +5868 // request/response nature of path challenges to refresh an observation +5869 // Since PATH_RESPONSE is a probing frame, this is allowed by the spec. +5870 if space_id == SpaceId::Data +5871 && self +5872 .config +5873 .address_discovery_role +5874 .should_report(&self.peer_params.address_discovery_role) +5875 { +5876 let frame = frame::ObservedAddr::new( +5877 path.network_path.remote, +5878 self.next_observed_addr_seq_no, +5879 ); +5880 if builder.frame_space_remaining() > frame.size() { +5881 builder.write_frame(frame, stats); +5882 +5883 self.next_observed_addr_seq_no = +5884 self.next_observed_addr_seq_no.saturating_add(1u8); +5885 path.observed_addr_sent = true; +5886 +5887 space.pending.observed_addr = false; +5888 } +5889 } +5890 } +5891 +5892 // REACH_OUT +5893 if !scheduling_info.is_abandoned +5894 && scheduling_info.may_send_data +5895 && let Some((round, addresses)) = space.pending.reach_out.as_mut() +5896 { +5897 while let Some(local_addr) = addresses.iter().next().copied() { +5898 let local_addr = addresses.take(&local_addr).expect("found from iter"); +5899 let reach_out = frame::ReachOut::new(*round, local_addr); +5900 if builder.frame_space_remaining() > reach_out.size() { +5901 builder.write_frame(reach_out, stats); +5902 } else { +5903 addresses.insert(local_addr); +5904 break; +5905 } +5906 } +5907 if addresses.is_empty() { +5908 space.pending.reach_out = None; +5909 } +5910 } +5911 +5912 // PATH_ABANDON +5913 if space_id == SpaceId::Data +5914 && scheduling_info.is_abandoned +5915 && scheduling_info.may_self_abandon +5916 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() +5917 && let Some(error_code) = space.pending.path_abandon.remove(&path_id) +5918 { +5919 let frame = frame::PathAbandon { +5920 path_id, +5921 error_code, +5922 }; +5923 builder.write_frame(frame, stats); 5924 -5925 self.next_observed_addr_seq_no = self.next_observed_addr_seq_no.saturating_add(1u8); -5926 path.observed_addr_sent = true; -5927 -5928 space.pending.observed_addr = false; -5929 } -5930 } -5931 -5932 // CRYPTO -5933 while !is_0rtt -5934 && !scheduling_info.is_abandoned -5935 && scheduling_info.may_send_data -5936 && builder.frame_space_remaining() > frame::Crypto::SIZE_BOUND -5937 { -5938 let Some(mut frame) = space.pending.crypto.pop_front() else { -5939 break; -5940 }; -5941 -5942 // Calculate the maximum amount of crypto data we can store in the buffer. -5943 // Since the offset is known, we can reserve the exact size required to encode it. -5944 // For length we reserve 2bytes which allows to encode up to 2^14, -5945 // which is more than what fits into normally sized QUIC frames. -5946 let max_crypto_data_size = builder.frame_space_remaining() -5947 - 1 // Frame Type -5948 - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) }) -5949 - 2; // Maximum encoded length for frame size, given we send less than 2^14 bytes -5950 -5951 let len = frame -5952 .data -5953 .len() -5954 .min(2usize.pow(14) - 1) -5955 .min(max_crypto_data_size); -5956 -5957 let data = frame.data.split_to(len); -5958 let offset = frame.offset; -5959 let truncated = frame::Crypto { offset, data }; -5960 builder.write_frame(truncated, stats); -5961 -5962 if !frame.data.is_empty() { -5963 frame.offset += len as u64; -5964 space.pending.crypto.push_front(frame); -5965 } -5966 } -5967 -5968 // PATH_STATUS_AVAILABLE & PATH_STATUS_BACKUP -5969 while space_id == SpaceId::Data -5970 && !scheduling_info.is_abandoned -5971 && scheduling_info.may_send_data -5972 && frame::PathStatusAvailable::SIZE_BOUND <= builder.frame_space_remaining() -5973 { -5974 let Some(path_id) = space.pending.path_status.pop_first() else { -5975 break; -5976 }; -5977 let Some(path) = self.paths.get(&path_id).map(|path_state| &path_state.data) else { -5978 trace!(%path_id, "discarding queued path status for unknown path"); -5979 continue; -5980 }; -5981 -5982 let seq = path.status.seq(); -5983 match path.local_status() { -5984 PathStatus::Available => { -5985 let frame = frame::PathStatusAvailable { -5986 path_id, -5987 status_seq_no: seq, -5988 }; -5989 builder.write_frame(frame, stats); -5990 } -5991 PathStatus::Backup => { -5992 let frame = frame::PathStatusBackup { -5993 path_id, -5994 status_seq_no: seq, -5995 }; -5996 builder.write_frame(frame, stats); -5997 } -5998 } -5999 } -6000 -6001 // MAX_PATH_ID -6002 if space_id == SpaceId::Data -6003 && !scheduling_info.is_abandoned -6004 && scheduling_info.may_send_data -6005 && space.pending.max_path_id -6006 && frame::MaxPathId::SIZE_BOUND <= builder.frame_space_remaining() -6007 { -6008 let frame = frame::MaxPathId(self.local_max_path_id); -6009 builder.write_frame(frame, stats); -6010 space.pending.max_path_id = false; -6011 } -6012 -6013 // PATHS_BLOCKED -6014 if space_id == SpaceId::Data -6015 && !scheduling_info.is_abandoned -6016 && scheduling_info.may_send_data -6017 && space.pending.paths_blocked -6018 && frame::PathsBlocked::SIZE_BOUND <= builder.frame_space_remaining() -6019 { -6020 let frame = frame::PathsBlocked(self.remote_max_path_id); -6021 builder.write_frame(frame, stats); -6022 space.pending.paths_blocked = false; -6023 } -6024 -6025 // PATH_CIDS_BLOCKED -6026 while space_id == SpaceId::Data -6027 && !scheduling_info.is_abandoned -6028 && scheduling_info.may_send_data -6029 && frame::PathCidsBlocked::SIZE_BOUND <= builder.frame_space_remaining() -6030 { -6031 let Some(path_id) = space.pending.path_cids_blocked.pop_first() else { -6032 break; -6033 }; -6034 let next_seq = match self.remote_cids.get(&path_id) { -6035 Some(cid_queue) => VarInt(cid_queue.active_seq() + 1), -6036 None => VarInt(0), -6037 }; -6038 let frame = frame::PathCidsBlocked { path_id, next_seq }; -6039 builder.write_frame(frame, stats); -6040 } -6041 -6042 // RESET_STREAM, STOP_SENDING, MAX_DATA, MAX_STREAM_DATA, MAX_STREAMS -6043 if space_id == SpaceId::Data -6044 && !scheduling_info.is_abandoned -6045 && scheduling_info.may_send_data -6046 { -6047 self.streams -6048 .write_control_frames(builder, &mut space.pending, stats); -6049 } -6050 -6051 // NEW_CONNECTION_ID -6052 let cid_len = self -6053 .local_cid_state -6054 .values() -6055 .map(|cid_state| cid_state.cid_len()) -6056 .max() -6057 .expect("some local CID state must exist"); -6058 let new_cid_size_bound = -6059 frame::NewConnectionId::size_bound(is_multipath_negotiated, cid_len); -6060 while !scheduling_info.is_abandoned -6061 && scheduling_info.may_send_data -6062 && builder.frame_space_remaining() > new_cid_size_bound -6063 { -6064 let Some(issued) = space.pending.new_cids.pop() else { -6065 break; -6066 }; -6067 let retire_prior_to = self -6068 .local_cid_state -6069 .get(&issued.path_id) -6070 .map(|cid_state| cid_state.retire_prior_to()) -6071 .unwrap_or_else(|| panic!("missing local CID state for path={}", issued.path_id)); -6072 -6073 let cid_path_id = match is_multipath_negotiated { -6074 true => Some(issued.path_id), -6075 false => { -6076 debug_assert_eq!(issued.path_id, PathId::ZERO); -6077 None -6078 } -6079 }; -6080 let frame = frame::NewConnectionId { -6081 path_id: cid_path_id, -6082 sequence: issued.sequence, -6083 retire_prior_to, -6084 id: issued.id, -6085 reset_token: issued.reset_token, -6086 }; -6087 builder.write_frame(frame, stats); -6088 } -6089 -6090 // RETIRE_CONNECTION_ID -6091 let retire_cid_bound = frame::RetireConnectionId::size_bound(is_multipath_negotiated); -6092 while !scheduling_info.is_abandoned -6093 && scheduling_info.may_send_data -6094 && builder.frame_space_remaining() > retire_cid_bound -6095 { -6096 let (path_id, sequence) = match space.pending.retire_cids.pop() { -6097 Some((PathId::ZERO, seq)) if !is_multipath_negotiated => (None, seq), -6098 Some((path_id, seq)) => (Some(path_id), seq), -6099 None => break, -6100 }; -6101 let frame = frame::RetireConnectionId { path_id, sequence }; -6102 builder.write_frame(frame, stats); -6103 } -6104 -6105 // DATAGRAM -6106 let mut sent_datagrams = false; -6107 while !scheduling_info.is_abandoned -6108 && scheduling_info.may_send_data -6109 && builder.frame_space_remaining() > Datagram::SIZE_BOUND -6110 && space_id == SpaceId::Data -6111 { -6112 match self.datagrams.write(builder, stats) { -6113 true => { -6114 sent_datagrams = true; -6115 } -6116 false => break, -6117 } -6118 } -6119 if self.datagrams.send_blocked && sent_datagrams { -6120 self.events.push_back(Event::DatagramsUnblocked); -6121 self.datagrams.send_blocked = false; -6122 } -6123 -6124 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; -6125 -6126 // NEW_TOKEN -6127 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { -6128 while let Some(network_path) = space.pending.new_tokens.pop() { -6129 debug_assert_eq!(space_id, SpaceId::Data); -6130 let ConnectionSide::Server { server_config } = &self.side else { -6131 panic!("NEW_TOKEN frames should not be enqueued by clients"); -6132 }; -6133 -6134 if !network_path.is_probably_same_path(&path.network_path) { -6135 // NEW_TOKEN frames contain tokens bound to a client's IP address, and are only -6136 // useful if used from the same IP address. Thus, we abandon enqueued NEW_TOKEN -6137 // frames upon an path change. Instead, when the new path becomes validated, -6138 // NEW_TOKEN frames may be enqueued for the new path instead. -6139 continue; -6140 } -6141 -6142 let token = Token::new( -6143 TokenPayload::Validation { -6144 ip: network_path.remote.ip(), -6145 issued: server_config.time_source.now(), -6146 }, -6147 &mut self.rng, -6148 ); -6149 let new_token = NewToken { -6150 token: token.encode(&*server_config.token_key).into(), -6151 }; -6152 -6153 if builder.frame_space_remaining() < new_token.size() { -6154 space.pending.new_tokens.push(network_path); -6155 break; -6156 } -6157 -6158 builder.write_frame(new_token, stats); -6159 builder.retransmits_mut().new_tokens.push(network_path); -6160 } -6161 } -6162 -6163 // STREAM -6164 if !scheduling_info.is_abandoned -6165 && scheduling_info.may_send_data -6166 && space_id == SpaceId::Data -6167 { -6168 self.streams -6169 .write_stream_frames(builder, self.config.send_fairness, stats); -6170 } -6171 -6172 // ADD_ADDRESS -6173 while space_id == SpaceId::Data -6174 && !scheduling_info.is_abandoned -6175 && scheduling_info.may_send_data -6176 && frame::AddAddress::SIZE_BOUND <= builder.frame_space_remaining() -6177 { -6178 if let Some(added_address) = space.pending.add_address.pop_last() { -6179 builder.write_frame(added_address, stats); -6180 } else { -6181 break; -6182 } -6183 } -6184 -6185 // REMOVE_ADDRESS -6186 while space_id == SpaceId::Data -6187 && !scheduling_info.is_abandoned -6188 && scheduling_info.may_send_data -6189 && frame::RemoveAddress::SIZE_BOUND <= builder.frame_space_remaining() -6190 { -6191 if let Some(removed_address) = space.pending.remove_address.pop_last() { -6192 builder.write_frame(removed_address, stats); -6193 } else { -6194 break; +5925 // Consider remotely issued CIDs as retired now that we have sent this frame at +5926 // least once. +5927 self.remote_cids.remove(&path_id); +5928 } +5929 while space_id == SpaceId::Data +5930 && scheduling_info.may_send_data +5931 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() +5932 && let Some((abandoned_path_id, error_code)) = space.pending.path_abandon.pop_first() +5933 { +5934 let frame = frame::PathAbandon { +5935 path_id: abandoned_path_id, +5936 error_code, +5937 }; +5938 builder.write_frame(frame, stats); +5939 +5940 // Consider remotely issued CIDs as retired now that we have sent this frame at +5941 // least once. +5942 self.remote_cids.remove(&abandoned_path_id); +5943 } +5944 +5945 // OBSERVED_ADDR +5946 if !scheduling_info.is_abandoned +5947 && scheduling_info.may_send_data +5948 && space_id == SpaceId::Data +5949 && self +5950 .config +5951 .address_discovery_role +5952 .should_report(&self.peer_params.address_discovery_role) +5953 && (!path.observed_addr_sent || space.pending.observed_addr) +5954 { +5955 let frame = +5956 frame::ObservedAddr::new(path.network_path.remote, self.next_observed_addr_seq_no); +5957 if builder.frame_space_remaining() > frame.size() { +5958 builder.write_frame(frame, stats); +5959 +5960 self.next_observed_addr_seq_no = self.next_observed_addr_seq_no.saturating_add(1u8); +5961 path.observed_addr_sent = true; +5962 +5963 space.pending.observed_addr = false; +5964 } +5965 } +5966 +5967 // CRYPTO +5968 while !is_0rtt +5969 && !scheduling_info.is_abandoned +5970 && scheduling_info.may_send_data +5971 && builder.frame_space_remaining() > frame::Crypto::SIZE_BOUND +5972 { +5973 let Some(mut frame) = space.pending.crypto.pop_front() else { +5974 break; +5975 }; +5976 +5977 // Calculate the maximum amount of crypto data we can store in the buffer. +5978 // Since the offset is known, we can reserve the exact size required to encode it. +5979 // For length we reserve 2bytes which allows to encode up to 2^14, +5980 // which is more than what fits into normally sized QUIC frames. +5981 let max_crypto_data_size = builder.frame_space_remaining() +5982 - 1 // Frame Type +5983 - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) }) +5984 - 2; // Maximum encoded length for frame size, given we send less than 2^14 bytes +5985 +5986 let len = frame +5987 .data +5988 .len() +5989 .min(2usize.pow(14) - 1) +5990 .min(max_crypto_data_size); +5991 +5992 let data = frame.data.split_to(len); +5993 let offset = frame.offset; +5994 let truncated = frame::Crypto { offset, data }; +5995 builder.write_frame(truncated, stats); +5996 +5997 if !frame.data.is_empty() { +5998 frame.offset += len as u64; +5999 space.pending.crypto.push_front(frame); +6000 } +6001 } +6002 +6003 // PATH_STATUS_AVAILABLE & PATH_STATUS_BACKUP +6004 while space_id == SpaceId::Data +6005 && !scheduling_info.is_abandoned +6006 && scheduling_info.may_send_data +6007 && frame::PathStatusAvailable::SIZE_BOUND <= builder.frame_space_remaining() +6008 { +6009 let Some(path_id) = space.pending.path_status.pop_first() else { +6010 break; +6011 }; +6012 let Some(path) = self.paths.get(&path_id).map(|path_state| &path_state.data) else { +6013 trace!(%path_id, "discarding queued path status for unknown path"); +6014 continue; +6015 }; +6016 +6017 let seq = path.status.seq(); +6018 match path.local_status() { +6019 PathStatus::Available => { +6020 let frame = frame::PathStatusAvailable { +6021 path_id, +6022 status_seq_no: seq, +6023 }; +6024 builder.write_frame(frame, stats); +6025 } +6026 PathStatus::Backup => { +6027 let frame = frame::PathStatusBackup { +6028 path_id, +6029 status_seq_no: seq, +6030 }; +6031 builder.write_frame(frame, stats); +6032 } +6033 } +6034 } +6035 +6036 // MAX_PATH_ID +6037 if space_id == SpaceId::Data +6038 && !scheduling_info.is_abandoned +6039 && scheduling_info.may_send_data +6040 && space.pending.max_path_id +6041 && frame::MaxPathId::SIZE_BOUND <= builder.frame_space_remaining() +6042 { +6043 let frame = frame::MaxPathId(self.local_max_path_id); +6044 builder.write_frame(frame, stats); +6045 space.pending.max_path_id = false; +6046 } +6047 +6048 // PATHS_BLOCKED +6049 if space_id == SpaceId::Data +6050 && !scheduling_info.is_abandoned +6051 && scheduling_info.may_send_data +6052 && space.pending.paths_blocked +6053 && frame::PathsBlocked::SIZE_BOUND <= builder.frame_space_remaining() +6054 { +6055 let frame = frame::PathsBlocked(self.remote_max_path_id); +6056 builder.write_frame(frame, stats); +6057 space.pending.paths_blocked = false; +6058 } +6059 +6060 // PATH_CIDS_BLOCKED +6061 while space_id == SpaceId::Data +6062 && !scheduling_info.is_abandoned +6063 && scheduling_info.may_send_data +6064 && frame::PathCidsBlocked::SIZE_BOUND <= builder.frame_space_remaining() +6065 { +6066 let Some(path_id) = space.pending.path_cids_blocked.pop_first() else { +6067 break; +6068 }; +6069 let next_seq = match self.remote_cids.get(&path_id) { +6070 Some(cid_queue) => VarInt(cid_queue.active_seq() + 1), +6071 None => VarInt(0), +6072 }; +6073 let frame = frame::PathCidsBlocked { path_id, next_seq }; +6074 builder.write_frame(frame, stats); +6075 } +6076 +6077 // RESET_STREAM, STOP_SENDING, MAX_DATA, MAX_STREAM_DATA, MAX_STREAMS +6078 if space_id == SpaceId::Data +6079 && !scheduling_info.is_abandoned +6080 && scheduling_info.may_send_data +6081 { +6082 self.streams +6083 .write_control_frames(builder, &mut space.pending, stats); +6084 } +6085 +6086 // NEW_CONNECTION_ID +6087 let cid_len = self +6088 .local_cid_state +6089 .values() +6090 .map(|cid_state| cid_state.cid_len()) +6091 .max() +6092 .expect("some local CID state must exist"); +6093 let new_cid_size_bound = +6094 frame::NewConnectionId::size_bound(is_multipath_negotiated, cid_len); +6095 while !scheduling_info.is_abandoned +6096 && scheduling_info.may_send_data +6097 && builder.frame_space_remaining() > new_cid_size_bound +6098 { +6099 let Some(issued) = space.pending.new_cids.pop() else { +6100 break; +6101 }; +6102 let retire_prior_to = self +6103 .local_cid_state +6104 .get(&issued.path_id) +6105 .map(|cid_state| cid_state.retire_prior_to()) +6106 .unwrap_or_else(|| panic!("missing local CID state for path={}", issued.path_id)); +6107 +6108 let cid_path_id = match is_multipath_negotiated { +6109 true => Some(issued.path_id), +6110 false => { +6111 debug_assert_eq!(issued.path_id, PathId::ZERO); +6112 None +6113 } +6114 }; +6115 let frame = frame::NewConnectionId { +6116 path_id: cid_path_id, +6117 sequence: issued.sequence, +6118 retire_prior_to, +6119 id: issued.id, +6120 reset_token: issued.reset_token, +6121 }; +6122 builder.write_frame(frame, stats); +6123 } +6124 +6125 // RETIRE_CONNECTION_ID +6126 let retire_cid_bound = frame::RetireConnectionId::size_bound(is_multipath_negotiated); +6127 while !scheduling_info.is_abandoned +6128 && scheduling_info.may_send_data +6129 && builder.frame_space_remaining() > retire_cid_bound +6130 { +6131 let (path_id, sequence) = match space.pending.retire_cids.pop() { +6132 Some((PathId::ZERO, seq)) if !is_multipath_negotiated => (None, seq), +6133 Some((path_id, seq)) => (Some(path_id), seq), +6134 None => break, +6135 }; +6136 let frame = frame::RetireConnectionId { path_id, sequence }; +6137 builder.write_frame(frame, stats); +6138 } +6139 +6140 // DATAGRAM +6141 let mut sent_datagrams = false; +6142 while !scheduling_info.is_abandoned +6143 && scheduling_info.may_send_data +6144 && builder.frame_space_remaining() > Datagram::SIZE_BOUND +6145 && space_id == SpaceId::Data +6146 { +6147 match self.datagrams.write(builder, stats) { +6148 true => { +6149 sent_datagrams = true; +6150 } +6151 false => break, +6152 } +6153 } +6154 if self.datagrams.send_blocked && sent_datagrams { +6155 self.events.push_back(Event::DatagramsUnblocked); +6156 self.datagrams.send_blocked = false; +6157 } +6158 +6159 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; +6160 +6161 // NEW_TOKEN +6162 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { +6163 while let Some(network_path) = space.pending.new_tokens.pop() { +6164 debug_assert_eq!(space_id, SpaceId::Data); +6165 let ConnectionSide::Server { server_config } = &self.side else { +6166 panic!("NEW_TOKEN frames should not be enqueued by clients"); +6167 }; +6168 +6169 if !network_path.is_probably_same_path(&path.network_path) { +6170 // NEW_TOKEN frames contain tokens bound to a client's IP address, and are only +6171 // useful if used from the same IP address. Thus, we abandon enqueued NEW_TOKEN +6172 // frames upon an path change. Instead, when the new path becomes validated, +6173 // NEW_TOKEN frames may be enqueued for the new path instead. +6174 continue; +6175 } +6176 +6177 let token = Token::new( +6178 TokenPayload::Validation { +6179 ip: network_path.remote.ip(), +6180 issued: server_config.time_source.now(), +6181 }, +6182 &mut self.rng, +6183 ); +6184 let new_token = NewToken { +6185 token: token.encode(&*server_config.token_key).into(), +6186 }; +6187 +6188 if builder.frame_space_remaining() < new_token.size() { +6189 space.pending.new_tokens.push(network_path); +6190 break; +6191 } +6192 +6193 builder.write_frame(new_token, stats); +6194 builder.retransmits_mut().new_tokens.push(network_path); 6195 } 6196 } -6197 } -6198 -6199 /// Write pending ACKs into a buffer -6200 fn populate_acks<'a, 'b>( -6201 now: Instant, -6202 receiving_ecn: bool, -6203 path_id: PathId, -6204 space_id: SpaceId, -6205 space: &mut PacketSpace, -6206 is_multipath_negotiated: bool, -6207 builder: &mut PacketBuilder<'a, 'b>, -6208 stats: &mut FrameStats, -6209 space_has_keys: bool, -6210 ) { -6211 // 0-RTT packets must never carry acks (which would have to be of handshake packets) -6212 debug_assert!(space_has_keys, "tried to send ACK in 0-RTT"); -6213 -6214 debug_assert!( -6215 is_multipath_negotiated || path_id == PathId::ZERO, -6216 "Only PathId::ZERO allowed without multipath (have {path_id:?})" -6217 ); -6218 if is_multipath_negotiated { -6219 debug_assert!( -6220 space_id == SpaceId::Data || path_id == PathId::ZERO, -6221 "path acks must be sent in 1RTT space (have {space_id:?})" -6222 ); -6223 } -6224 -6225 let pns = space.for_path(path_id); -6226 let ranges = pns.pending_acks.ranges(); -6227 debug_assert!(!ranges.is_empty(), "can not send empty ACK range"); -6228 let ecn = if receiving_ecn { -6229 Some(&pns.ecn_counters) -6230 } else { -6231 None -6232 }; +6197 +6198 // STREAM +6199 if !scheduling_info.is_abandoned +6200 && scheduling_info.may_send_data +6201 && space_id == SpaceId::Data +6202 { +6203 self.streams +6204 .write_stream_frames(builder, self.config.send_fairness, stats); +6205 } +6206 +6207 // ADD_ADDRESS +6208 while space_id == SpaceId::Data +6209 && !scheduling_info.is_abandoned +6210 && scheduling_info.may_send_data +6211 && frame::AddAddress::SIZE_BOUND <= builder.frame_space_remaining() +6212 { +6213 if let Some(added_address) = space.pending.add_address.pop_last() { +6214 builder.write_frame(added_address, stats); +6215 } else { +6216 break; +6217 } +6218 } +6219 +6220 // REMOVE_ADDRESS +6221 while space_id == SpaceId::Data +6222 && !scheduling_info.is_abandoned +6223 && scheduling_info.may_send_data +6224 && frame::RemoveAddress::SIZE_BOUND <= builder.frame_space_remaining() +6225 { +6226 if let Some(removed_address) = space.pending.remove_address.pop_last() { +6227 builder.write_frame(removed_address, stats); +6228 } else { +6229 break; +6230 } +6231 } +6232 } 6233 -6234 let delay_micros = pns.pending_acks.ack_delay(now).as_micros() as u64; -6235 // TODO: This should come from `TransportConfig` if that gets configurable. -6236 let ack_delay_exp = TransportParameters::default().ack_delay_exponent; -6237 let delay = delay_micros >> ack_delay_exp.into_inner(); -6238 -6239 if is_multipath_negotiated && space_id == SpaceId::Data { -6240 if !ranges.is_empty() { -6241 let frame = frame::PathAck::encoder(path_id, delay, ranges, ecn); -6242 builder.write_frame(frame, stats); -6243 } -6244 } else { -6245 builder.write_frame(frame::Ack::encoder(delay, ranges, ecn), stats); -6246 } -6247 } +6234 /// Write pending ACKs into a buffer +6235 fn populate_acks<'a, 'b>( +6236 now: Instant, +6237 receiving_ecn: bool, +6238 path_id: PathId, +6239 space_id: SpaceId, +6240 space: &mut PacketSpace, +6241 is_multipath_negotiated: bool, +6242 builder: &mut PacketBuilder<'a, 'b>, +6243 stats: &mut FrameStats, +6244 space_has_keys: bool, +6245 ) { +6246 // 0-RTT packets must never carry acks (which would have to be of handshake packets) +6247 debug_assert!(space_has_keys, "tried to send ACK in 0-RTT"); 6248 -6249 fn close_common(&mut self) { -6250 trace!("connection closed"); -6251 self.timers.reset(); -6252 } -6253 -6254 fn set_close_timer(&mut self, now: Instant) { -6255 // QUIC-MULTIPATH § 2.6 Connection Closure: draining for 3*PTO using the max PTO of -6256 // all paths. -6257 let pto_max = self.max_pto_for_space(self.highest_space); -6258 self.timers.set( -6259 Timer::Conn(ConnTimer::Close), -6260 now + 3 * pto_max, -6261 self.qlog.with_time(now), -6262 ); -6263 } -6264 -6265 /// Handle transport parameters received from the peer -6266 /// -6267 /// *remote_cid* and *local_cid* are the source and destination CIDs respectively of the -6268 /// *packet into which the transport parameters arrived. -6269 fn handle_peer_params( -6270 &mut self, -6271 params: TransportParameters, -6272 local_cid: ConnectionId, -6273 remote_cid: ConnectionId, -6274 now: Instant, -6275 ) -> Result<(), TransportError> { -6276 if Some(self.original_remote_cid) != params.initial_src_cid -6277 || (self.side.is_client() -6278 && (Some(self.initial_dst_cid) != params.original_dst_cid -6279 || self.retry_src_cid != params.retry_src_cid)) -6280 { -6281 return Err(TransportError::TRANSPORT_PARAMETER_ERROR( -6282 "CID authentication failure", -6283 )); -6284 } -6285 if params.initial_max_path_id.is_some() && (local_cid.is_empty() || remote_cid.is_empty()) { -6286 return Err(TransportError::PROTOCOL_VIOLATION( -6287 "multipath must not use zero-length CIDs", -6288 )); -6289 } -6290 -6291 self.set_peer_params(params); -6292 self.qlog.emit_peer_transport_params_received(self, now); -6293 -6294 Ok(()) -6295 } -6296 -6297 fn set_peer_params(&mut self, params: TransportParameters) { -6298 self.streams.set_params(&params); -6299 self.idle_timeout = -6300 negotiate_max_idle_timeout(self.config.max_idle_timeout, Some(params.max_idle_timeout)); -6301 trace!("negotiated max idle timeout {:?}", self.idle_timeout); -6302 -6303 if let Some(ref info) = params.preferred_address { -6304 // During the handshake PathId::ZERO exists. -6305 self.remote_cids.get_mut(&PathId::ZERO).expect("not yet abandoned").insert(frame::NewConnectionId { -6306 path_id: None, -6307 sequence: 1, -6308 id: info.connection_id, -6309 reset_token: info.stateless_reset_token, -6310 retire_prior_to: 0, -6311 }) -6312 .expect( -6313 "preferred address CID is the first received, and hence is guaranteed to be legal", -6314 ); -6315 let remote = self.path_data(PathId::ZERO).network_path.remote; -6316 self.set_reset_token(PathId::ZERO, remote, info.stateless_reset_token); -6317 } -6318 self.ack_frequency.peer_max_ack_delay = get_max_ack_delay(&params); -6319 -6320 let mut multipath_enabled = None; -6321 if let (Some(local_max_path_id), Some(remote_max_path_id)) = ( -6322 self.config.get_initial_max_path_id(), -6323 params.initial_max_path_id, -6324 ) { -6325 // multipath is enabled, register the local and remote maximums -6326 self.local_max_path_id = local_max_path_id; -6327 self.remote_max_path_id = remote_max_path_id; -6328 let initial_max_path_id = local_max_path_id.min(remote_max_path_id); -6329 debug!(%initial_max_path_id, "multipath negotiated"); -6330 multipath_enabled = Some(initial_max_path_id); -6331 } -6332 -6333 if let Some((max_locally_allowed_remote_addresses, max_remotely_allowed_remote_addresses)) = -6334 self.config -6335 .max_remote_nat_traversal_addresses -6336 .zip(params.max_remote_nat_traversal_addresses) -6337 { -6338 if let Some(max_initial_paths) = -6339 multipath_enabled.map(|path_id| path_id.saturating_add(1u8)) -6340 { -6341 let max_local_addresses = max_remotely_allowed_remote_addresses.get(); -6342 let max_remote_addresses = max_locally_allowed_remote_addresses.get(); -6343 self.n0_nat_traversal = n0_nat_traversal::State::new( -6344 max_remote_addresses, -6345 max_local_addresses, -6346 self.side(), -6347 ); -6348 debug!( -6349 %max_remote_addresses, %max_local_addresses, -6350 "n0's nat traversal negotiated" -6351 ); -6352 -6353 match self.side() { -6354 Side::Client => { -6355 if max_initial_paths.as_u32() < max_remote_addresses as u32 + 1 { -6356 // in this case the client might try to open `max_remote_addresses` new -6357 // paths, but the current multipath configuration will not allow it -6358 debug!(%max_initial_paths, %max_remote_addresses, "local client configuration might cause nat traversal issues") -6359 } else if max_local_addresses as u64 -6360 > params.active_connection_id_limit.into_inner() -6361 { -6362 // the server allows us to send at most `params.active_connection_id_limit` -6363 // but they might need at least `max_local_addresses` to effectively send -6364 // `PATH_CHALLENGE` frames to each advertised local address -6365 debug!(%max_local_addresses, remote_cid_limit=%params.active_connection_id_limit.into_inner(), "remote server configuration might cause nat traversal issues") -6366 } -6367 } -6368 Side::Server => { -6369 if (max_initial_paths.as_u32() as u64) < crate::LOCAL_CID_COUNT { -6370 debug!(%max_initial_paths, local_cid_limit=%crate::LOCAL_CID_COUNT, "local server configuration might cause nat traversal issues") -6371 } -6372 } -6373 } -6374 } else { -6375 debug!("n0 nat traversal enabled for both endpoints, but multipath is missing") -6376 } -6377 } -6378 -6379 self.peer_params = params; -6380 let peer_max_udp_payload_size = -6381 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX); -6382 self.path_data_mut(PathId::ZERO) -6383 .mtud -6384 .on_peer_max_udp_payload_size_received(peer_max_udp_payload_size); -6385 } -6386 -6387 /// Decrypts a packet, returning the packet number on success -6388 fn decrypt_packet( -6389 &mut self, -6390 now: Instant, -6391 path_id: PathId, -6392 packet: &mut Packet, -6393 ) -> Result<Option<u64>, Option<TransportError>> { -6394 let result = self -6395 .crypto_state -6396 .decrypt_packet_body(packet, path_id, &self.spaces)?; -6397 -6398 let Some(result) = result else { -6399 return Ok(None); -6400 }; -6401 -6402 if result.outgoing_key_update_acked -6403 && let Some(prev) = self.crypto_state.prev_crypto.as_mut() -6404 { -6405 prev.end_packet = Some((result.number, now)); -6406 self.set_key_discard_timer(now, packet.header.space()); -6407 } -6408 -6409 if result.incoming_key_update { -6410 trace!("key update authenticated"); -6411 self.crypto_state -6412 .update_keys(Some((result.number, now)), true); -6413 self.set_key_discard_timer(now, packet.header.space()); -6414 } -6415 -6416 Ok(Some(result.number)) -6417 } -6418 -6419 fn peer_supports_ack_frequency(&self) -> bool { -6420 self.peer_params.min_ack_delay.is_some() -6421 } -6422 -6423 /// Send an IMMEDIATE_ACK frame to the remote endpoint -6424 /// -6425 /// According to the spec, this will result in an error if the remote endpoint does not support -6426 /// the Acknowledgement Frequency extension -6427 pub(crate) fn immediate_ack(&mut self, path_id: PathId) { -6428 debug_assert_eq!( -6429 self.highest_space, -6430 SpaceKind::Data, -6431 "immediate ack must be written in the data space" -6432 ); -6433 self.spaces[SpaceId::Data] -6434 .for_path(path_id) -6435 .immediate_ack_pending = true; -6436 } -6437 -6438 /// Decodes a packet, returning its decrypted payload, so it can be inspected in tests -6439 #[cfg(test)] -6440 pub(crate) fn decode_packet(&self, event: &ConnectionEvent) -> Option<Vec<u8>> { -6441 let ConnectionEventInner::Datagram(DatagramConnectionEvent { -6442 path_id, -6443 first_decode, -6444 remaining, -6445 .. -6446 }) = &event.0 -6447 else { -6448 return None; -6449 }; +6249 debug_assert!( +6250 is_multipath_negotiated || path_id == PathId::ZERO, +6251 "Only PathId::ZERO allowed without multipath (have {path_id:?})" +6252 ); +6253 if is_multipath_negotiated { +6254 debug_assert!( +6255 space_id == SpaceId::Data || path_id == PathId::ZERO, +6256 "path acks must be sent in 1RTT space (have {space_id:?})" +6257 ); +6258 } +6259 +6260 let pns = space.for_path(path_id); +6261 let ranges = pns.pending_acks.ranges(); +6262 debug_assert!(!ranges.is_empty(), "can not send empty ACK range"); +6263 let ecn = if receiving_ecn { +6264 Some(&pns.ecn_counters) +6265 } else { +6266 None +6267 }; +6268 +6269 let delay_micros = pns.pending_acks.ack_delay(now).as_micros() as u64; +6270 // TODO: This should come from `TransportConfig` if that gets configurable. +6271 let ack_delay_exp = TransportParameters::default().ack_delay_exponent; +6272 let delay = delay_micros >> ack_delay_exp.into_inner(); +6273 +6274 if is_multipath_negotiated && space_id == SpaceId::Data { +6275 if !ranges.is_empty() { +6276 let frame = frame::PathAck::encoder(path_id, delay, ranges, ecn); +6277 builder.write_frame(frame, stats); +6278 } +6279 } else { +6280 builder.write_frame(frame::Ack::encoder(delay, ranges, ecn), stats); +6281 } +6282 } +6283 +6284 fn close_common(&mut self) { +6285 trace!("connection closed"); +6286 self.timers.reset(); +6287 } +6288 +6289 fn set_close_timer(&mut self, now: Instant) { +6290 // QUIC-MULTIPATH § 2.6 Connection Closure: draining for 3*PTO using the max PTO of +6291 // all paths. +6292 let pto_max = self.max_pto_for_space(self.highest_space); +6293 self.timers.set( +6294 Timer::Conn(ConnTimer::Close), +6295 now + 3 * pto_max, +6296 self.qlog.with_time(now), +6297 ); +6298 } +6299 +6300 /// Handle transport parameters received from the peer +6301 /// +6302 /// *remote_cid* and *local_cid* are the source and destination CIDs respectively of the +6303 /// *packet into which the transport parameters arrived. +6304 fn handle_peer_params( +6305 &mut self, +6306 params: TransportParameters, +6307 local_cid: ConnectionId, +6308 remote_cid: ConnectionId, +6309 now: Instant, +6310 ) -> Result<(), TransportError> { +6311 if Some(self.original_remote_cid) != params.initial_src_cid +6312 || (self.side.is_client() +6313 && (Some(self.initial_dst_cid) != params.original_dst_cid +6314 || self.retry_src_cid != params.retry_src_cid)) +6315 { +6316 return Err(TransportError::TRANSPORT_PARAMETER_ERROR( +6317 "CID authentication failure", +6318 )); +6319 } +6320 if params.initial_max_path_id.is_some() && (local_cid.is_empty() || remote_cid.is_empty()) { +6321 return Err(TransportError::PROTOCOL_VIOLATION( +6322 "multipath must not use zero-length CIDs", +6323 )); +6324 } +6325 +6326 self.set_peer_params(params); +6327 self.qlog.emit_peer_transport_params_received(self, now); +6328 +6329 Ok(()) +6330 } +6331 +6332 fn set_peer_params(&mut self, params: TransportParameters) { +6333 self.streams.set_params(&params); +6334 self.idle_timeout = +6335 negotiate_max_idle_timeout(self.config.max_idle_timeout, Some(params.max_idle_timeout)); +6336 trace!("negotiated max idle timeout {:?}", self.idle_timeout); +6337 +6338 if let Some(ref info) = params.preferred_address { +6339 // During the handshake PathId::ZERO exists. +6340 self.remote_cids.get_mut(&PathId::ZERO).expect("not yet abandoned").insert(frame::NewConnectionId { +6341 path_id: None, +6342 sequence: 1, +6343 id: info.connection_id, +6344 reset_token: info.stateless_reset_token, +6345 retire_prior_to: 0, +6346 }) +6347 .expect( +6348 "preferred address CID is the first received, and hence is guaranteed to be legal", +6349 ); +6350 let remote = self.path_data(PathId::ZERO).network_path.remote; +6351 self.set_reset_token(PathId::ZERO, remote, info.stateless_reset_token); +6352 } +6353 self.ack_frequency.peer_max_ack_delay = get_max_ack_delay(&params); +6354 +6355 let mut multipath_enabled = None; +6356 if let (Some(local_max_path_id), Some(remote_max_path_id)) = ( +6357 self.config.get_initial_max_path_id(), +6358 params.initial_max_path_id, +6359 ) { +6360 // multipath is enabled, register the local and remote maximums +6361 self.local_max_path_id = local_max_path_id; +6362 self.remote_max_path_id = remote_max_path_id; +6363 let initial_max_path_id = local_max_path_id.min(remote_max_path_id); +6364 debug!(%initial_max_path_id, "multipath negotiated"); +6365 multipath_enabled = Some(initial_max_path_id); +6366 } +6367 +6368 if let Some((max_locally_allowed_remote_addresses, max_remotely_allowed_remote_addresses)) = +6369 self.config +6370 .max_remote_nat_traversal_addresses +6371 .zip(params.max_remote_nat_traversal_addresses) +6372 { +6373 if let Some(max_initial_paths) = +6374 multipath_enabled.map(|path_id| path_id.saturating_add(1u8)) +6375 { +6376 let max_local_addresses = max_remotely_allowed_remote_addresses.get(); +6377 let max_remote_addresses = max_locally_allowed_remote_addresses.get(); +6378 self.n0_nat_traversal = n0_nat_traversal::State::new( +6379 max_remote_addresses, +6380 max_local_addresses, +6381 self.side(), +6382 ); +6383 debug!( +6384 %max_remote_addresses, %max_local_addresses, +6385 "n0's nat traversal negotiated" +6386 ); +6387 +6388 match self.side() { +6389 Side::Client => { +6390 if max_initial_paths.as_u32() < max_remote_addresses as u32 + 1 { +6391 // in this case the client might try to open `max_remote_addresses` new +6392 // paths, but the current multipath configuration will not allow it +6393 debug!(%max_initial_paths, %max_remote_addresses, "local client configuration might cause nat traversal issues") +6394 } else if max_local_addresses as u64 +6395 > params.active_connection_id_limit.into_inner() +6396 { +6397 // the server allows us to send at most `params.active_connection_id_limit` +6398 // but they might need at least `max_local_addresses` to effectively send +6399 // `PATH_CHALLENGE` frames to each advertised local address +6400 debug!(%max_local_addresses, remote_cid_limit=%params.active_connection_id_limit.into_inner(), "remote server configuration might cause nat traversal issues") +6401 } +6402 } +6403 Side::Server => { +6404 if (max_initial_paths.as_u32() as u64) < crate::LOCAL_CID_COUNT { +6405 debug!(%max_initial_paths, local_cid_limit=%crate::LOCAL_CID_COUNT, "local server configuration might cause nat traversal issues") +6406 } +6407 } +6408 } +6409 } else { +6410 debug!("n0 nat traversal enabled for both endpoints, but multipath is missing") +6411 } +6412 } +6413 +6414 self.peer_params = params; +6415 let peer_max_udp_payload_size = +6416 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX); +6417 self.path_data_mut(PathId::ZERO) +6418 .mtud +6419 .on_peer_max_udp_payload_size_received(peer_max_udp_payload_size); +6420 } +6421 +6422 /// Decrypts a packet, returning the packet number on success +6423 fn decrypt_packet( +6424 &mut self, +6425 now: Instant, +6426 path_id: PathId, +6427 packet: &mut Packet, +6428 ) -> Result<Option<u64>, Option<TransportError>> { +6429 let result = self +6430 .crypto_state +6431 .decrypt_packet_body(packet, path_id, &self.spaces)?; +6432 +6433 let Some(result) = result else { +6434 return Ok(None); +6435 }; +6436 +6437 if result.outgoing_key_update_acked +6438 && let Some(prev) = self.crypto_state.prev_crypto.as_mut() +6439 { +6440 prev.end_packet = Some((result.number, now)); +6441 self.set_key_discard_timer(now, packet.header.space()); +6442 } +6443 +6444 if result.incoming_key_update { +6445 trace!("key update authenticated"); +6446 self.crypto_state +6447 .update_keys(Some((result.number, now)), true); +6448 self.set_key_discard_timer(now, packet.header.space()); +6449 } 6450 -6451 if remaining.is_some() { -6452 panic!("Packets should never be coalesced in tests"); -6453 } -6454 -6455 let decrypted_header = self -6456 .crypto_state -6457 .unprotect_header(first_decode.clone(), self.peer_params.stateless_reset_token)?; -6458 -6459 let mut packet = decrypted_header.packet?; -6460 self.crypto_state -6461 .decrypt_packet_body(&mut packet, *path_id, &self.spaces) -6462 .ok()?; -6463 -6464 Some(packet.payload.to_vec()) -6465 } -6466 -6467 /// The number of bytes of packets containing retransmittable frames that have not been -6468 /// acknowledged or declared lost. -6469 #[cfg(test)] -6470 pub(crate) fn bytes_in_flight(&self) -> u64 { -6471 // TODO(@divma): consider including for multipath? -6472 self.path_data(PathId::ZERO).in_flight.bytes -6473 } -6474 -6475 /// Number of bytes worth of non-ack-only packets that may be sent -6476 #[cfg(test)] -6477 pub(crate) fn congestion_window(&self) -> u64 { -6478 let path = self.path_data(PathId::ZERO); -6479 path.congestion -6480 .window() -6481 .saturating_sub(path.in_flight.bytes) -6482 } -6483 -6484 /// Whether no timers but keepalive, idle, rtt, pushnewcid, and key discard are running -6485 #[cfg(test)] -6486 pub(crate) fn is_idle(&self) -> bool { -6487 let current_timers = self.timers.values(); -6488 current_timers -6489 .into_iter() -6490 .filter(|(timer, _)| { -6491 !matches!( -6492 timer, -6493 Timer::Conn(ConnTimer::KeepAlive) -6494 | Timer::PerPath(_, PathTimer::PathKeepAlive) -6495 | Timer::PerPath(_, PathTimer::PathIdle) -6496 | Timer::Conn(ConnTimer::PushNewCid) -6497 | Timer::Conn(ConnTimer::KeyDiscard) -6498 ) -6499 }) -6500 .min_by_key(|(_, time)| *time) -6501 .is_none_or(|(timer, _)| timer == Timer::Conn(ConnTimer::Idle)) -6502 } -6503 -6504 /// Whether explicit congestion notification is in use on outgoing packets. -6505 #[cfg(test)] -6506 pub(crate) fn using_ecn(&self) -> bool { -6507 self.path_data(PathId::ZERO).sending_ecn +6451 Ok(Some(result.number)) +6452 } +6453 +6454 fn peer_supports_ack_frequency(&self) -> bool { +6455 self.peer_params.min_ack_delay.is_some() +6456 } +6457 +6458 /// Send an IMMEDIATE_ACK frame to the remote endpoint +6459 /// +6460 /// According to the spec, this will result in an error if the remote endpoint does not support +6461 /// the Acknowledgement Frequency extension +6462 pub(crate) fn immediate_ack(&mut self, path_id: PathId) { +6463 debug_assert_eq!( +6464 self.highest_space, +6465 SpaceKind::Data, +6466 "immediate ack must be written in the data space" +6467 ); +6468 self.spaces[SpaceId::Data] +6469 .for_path(path_id) +6470 .immediate_ack_pending = true; +6471 } +6472 +6473 /// Decodes a packet, returning its decrypted payload, so it can be inspected in tests +6474 #[cfg(test)] +6475 pub(crate) fn decode_packet(&self, event: &ConnectionEvent) -> Option<Vec<u8>> { +6476 let ConnectionEventInner::Datagram(DatagramConnectionEvent { +6477 path_id, +6478 first_decode, +6479 remaining, +6480 .. +6481 }) = &event.0 +6482 else { +6483 return None; +6484 }; +6485 +6486 if remaining.is_some() { +6487 panic!("Packets should never be coalesced in tests"); +6488 } +6489 +6490 let decrypted_header = self +6491 .crypto_state +6492 .unprotect_header(first_decode.clone(), self.peer_params.stateless_reset_token)?; +6493 +6494 let mut packet = decrypted_header.packet?; +6495 self.crypto_state +6496 .decrypt_packet_body(&mut packet, *path_id, &self.spaces) +6497 .ok()?; +6498 +6499 Some(packet.payload.to_vec()) +6500 } +6501 +6502 /// The number of bytes of packets containing retransmittable frames that have not been +6503 /// acknowledged or declared lost. +6504 #[cfg(test)] +6505 pub(crate) fn bytes_in_flight(&self) -> u64 { +6506 // TODO(@divma): consider including for multipath? +6507 self.path_data(PathId::ZERO).in_flight.bytes 6508 } 6509 -6510 /// The number of received bytes in the current path +6510 /// Number of bytes worth of non-ack-only packets that may be sent 6511 #[cfg(test)] -6512 pub(crate) fn total_recvd(&self) -> u64 { -6513 self.path_data(PathId::ZERO).total_recvd -6514 } -6515 -6516 #[cfg(test)] -6517 pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) { -6518 self.local_cid_state -6519 .get(&PathId::ZERO) -6520 .unwrap() -6521 .active_seq() -6522 } -6523 -6524 #[cfg(test)] -6525 #[track_caller] -6526 pub(crate) fn active_local_path_cid_seq(&self, path_id: u32) -> (u64, u64) { -6527 self.local_cid_state -6528 .get(&PathId(path_id)) -6529 .unwrap() -6530 .active_seq() -6531 } -6532 -6533 /// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame -6534 /// with updated `retire_prior_to` field set to `v` -6535 #[cfg(test)] -6536 pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) { -6537 let n = self -6538 .local_cid_state -6539 .get_mut(&PathId::ZERO) -6540 .unwrap() -6541 .assign_retire_seq(v); -6542 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events -6543 self.endpoint_events -6544 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); -6545 } -6546 -6547 /// Check the current active remote CID sequence for `PathId::ZERO` -6548 #[cfg(test)] -6549 pub(crate) fn active_remote_cid_seq(&self) -> u64 { -6550 self.remote_cids.get(&PathId::ZERO).unwrap().active_seq() -6551 } -6552 -6553 /// Returns the detected maximum udp payload size for the current path -6554 #[cfg(test)] -6555 pub(crate) fn path_mtu(&self, path_id: PathId) -> u16 { -6556 self.path_data(path_id).current_mtu() +6512 pub(crate) fn congestion_window(&self) -> u64 { +6513 let path = self.path_data(PathId::ZERO); +6514 path.congestion +6515 .window() +6516 .saturating_sub(path.in_flight.bytes) +6517 } +6518 +6519 /// Whether no timers but keepalive, idle, rtt, pushnewcid, and key discard are running +6520 #[cfg(test)] +6521 pub(crate) fn is_idle(&self) -> bool { +6522 let current_timers = self.timers.values(); +6523 current_timers +6524 .into_iter() +6525 .filter(|(timer, _)| { +6526 !matches!( +6527 timer, +6528 Timer::Conn(ConnTimer::KeepAlive) +6529 | Timer::PerPath(_, PathTimer::PathKeepAlive) +6530 | Timer::PerPath(_, PathTimer::PathIdle) +6531 | Timer::Conn(ConnTimer::PushNewCid) +6532 | Timer::Conn(ConnTimer::KeyDiscard) +6533 ) +6534 }) +6535 .min_by_key(|(_, time)| *time) +6536 .is_none_or(|(timer, _)| timer == Timer::Conn(ConnTimer::Idle)) +6537 } +6538 +6539 /// Whether explicit congestion notification is in use on outgoing packets. +6540 #[cfg(test)] +6541 pub(crate) fn using_ecn(&self) -> bool { +6542 self.path_data(PathId::ZERO).sending_ecn +6543 } +6544 +6545 /// The number of received bytes in the current path +6546 #[cfg(test)] +6547 pub(crate) fn total_recvd(&self) -> u64 { +6548 self.path_data(PathId::ZERO).total_recvd +6549 } +6550 +6551 #[cfg(test)] +6552 pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) { +6553 self.local_cid_state +6554 .get(&PathId::ZERO) +6555 .unwrap() +6556 .active_seq() 6557 } 6558 -6559 /// Triggers path validation on all paths -6560 #[cfg(test)] -6561 pub(crate) fn trigger_path_validation(&mut self) { -6562 for path in self.paths.values_mut() { -6563 path.data.pending_on_path_challenge = true; -6564 } -6565 } -6566 -6567 /// Simulates a protocol violation error for test purposes. -6568 #[cfg(test)] -6569 pub fn simulate_protocol_violation(&mut self, now: Instant) { -6570 if !self.state.is_closed() { -6571 self.state -6572 .move_to_closed(TransportError::PROTOCOL_VIOLATION("simulated violation")); -6573 self.close_common(); -6574 if !self.state.is_drained() { -6575 self.set_close_timer(now); -6576 } -6577 self.connection_close_pending = true; -6578 } -6579 } -6580 -6581 /// Whether we have on-path 1-RTT data to send. -6582 /// -6583 /// This checks for frames that can only be sent in the data space (1-RTT): -6584 /// - Pending PATH_CHALLENGE frames on the active and previous path if just migrated. -6585 /// - Pending PATH_RESPONSE frames. -6586 /// - Pending data to send in STREAM frames. -6587 /// - Pending DATAGRAM frames to send. -6588 /// -6589 /// See also [`PacketSpace::can_send`] which keeps track of all other frame types that -6590 /// may need to be sent. -6591 fn can_send_1rtt(&self, path_id: PathId, max_size: usize) -> SendableFrames { -6592 let space_specific = self.paths.get(&path_id).is_some_and(|path| { -6593 path.data.pending_on_path_challenge || !path.data.path_responses.is_empty() -6594 }); -6595 -6596 // Stream control frames are checked in PacketSpace::can_send, only check data here. -6597 let other = self.streams.can_send_stream_data() -6598 || self -6599 .datagrams -6600 .outgoing -6601 .front() -6602 .is_some_and(|x| x.size(true) <= max_size); -6603 -6604 // All `false` fields are set in PacketSpace::can_send. -6605 SendableFrames { -6606 acks: false, -6607 close: false, -6608 space_specific, -6609 other, -6610 } -6611 } -6612 -6613 /// Terminate the connection instantly, without sending a close packet -6614 fn kill(&mut self, reason: ConnectionError) { -6615 self.close_common(); -6616 self.state.move_to_drained(Some(reason)); -6617 // move_to_drained checks that we were never in drained before, so we -6618 // never sent a `Drained` event before (it's illegal to send more events after drained). -6619 self.endpoint_events.push_back(EndpointEventInner::Drained); -6620 } -6621 -6622 /// Storage size required for the largest packet that can be transmitted on all currently -6623 /// available paths -6624 /// -6625 /// Buffers passed to [`Connection::poll_transmit`] should be at least this large. -6626 /// -6627 /// When multipath is enabled, this value is the minimum MTU across all available paths. -6628 pub fn current_mtu(&self) -> u16 { -6629 self.paths -6630 .iter() -6631 .filter(|&(path_id, _path_state)| !self.abandoned_paths.contains(path_id)) -6632 .map(|(_path_id, path_state)| path_state.data.current_mtu()) -6633 .min() -6634 .unwrap_or(INITIAL_MTU) -6635 } -6636 -6637 /// Size of non-frame data for a 1-RTT packet -6638 /// -6639 /// Quantifies space consumed by the QUIC header and AEAD tag. All other bytes in a packet are -6640 /// frames. Changes if the length of the remote connection ID changes, which is expected to be -6641 /// rare. If `pn` is specified, may additionally change unpredictably due to variations in -6642 /// latency and packet loss. -6643 fn predict_1rtt_overhead(&mut self, pn: u64, path: PathId) -> usize { -6644 let pn_len = PacketNumber::new( -6645 pn, -6646 self.spaces[SpaceId::Data] -6647 .for_path(path) -6648 .largest_acked_packet -6649 .unwrap_or(0), -6650 ) -6651 .len(); -6652 -6653 // 1 byte for flags -6654 1 + self -6655 .remote_cids -6656 .get(&path) -6657 .map(|cids| cids.active().len()) -6658 .unwrap_or(20) // Max CID len in QUIC v1 -6659 + pn_len -6660 + self.tag_len_1rtt() -6661 } -6662 -6663 fn predict_1rtt_overhead_no_pn(&self) -> usize { -6664 let pn_len = 4; -6665 -6666 let cid_len = self -6667 .remote_cids -6668 .values() -6669 .map(|cids| cids.active().len()) -6670 .max() -6671 .unwrap_or(20); // Max CID len in QUIC v1 -6672 -6673 // 1 byte for flags -6674 1 + cid_len + pn_len + self.tag_len_1rtt() -6675 } -6676 -6677 fn tag_len_1rtt(&self) -> usize { -6678 // encryption_keys for Data space returns 1-RTT keys if available, otherwise 0-RTT keys -6679 let packet_crypto = self -6680 .crypto_state -6681 .encryption_keys(SpaceKind::Data, self.side.side()) -6682 .map(|(_header, packet, _level)| packet); -6683 // If neither Data nor 0-RTT keys are available, make a reasonable tag length guess. As of -6684 // this writing, all QUIC cipher suites use 16-byte tags. We could return `None` instead, -6685 // but that would needlessly prevent sending datagrams during 0-RTT. -6686 packet_crypto.map_or(16, |x| x.tag_len()) -6687 } -6688 -6689 /// Mark the path as validated, and enqueue NEW_TOKEN frames to be sent as appropriate -6690 fn on_path_validated(&mut self, path_id: PathId) { -6691 self.path_data_mut(path_id).validated = true; -6692 let ConnectionSide::Server { server_config } = &self.side else { -6693 return; -6694 }; -6695 let network_path = self.path_data(path_id).network_path; -6696 let new_tokens = &mut self.spaces[SpaceId::Data as usize].pending.new_tokens; -6697 new_tokens.clear(); -6698 for _ in 0..server_config.validation_token.sent { -6699 new_tokens.push(network_path); -6700 } -6701 } -6702 -6703 /// Handle new path status information: PATH_STATUS_AVAILABLE, PATH_STATUS_BACKUP -6704 fn on_path_status(&mut self, path_id: PathId, status: PathStatus, status_seq_no: VarInt) { -6705 if let Some(path) = self.paths.get_mut(&path_id) { -6706 path.data.status.remote_update(status, status_seq_no); -6707 } else { -6708 debug!("PATH_STATUS_AVAILABLE received unknown path {:?}", path_id); -6709 } -6710 self.events.push_back( -6711 PathEvent::RemoteStatus { -6712 id: path_id, -6713 status, -6714 } -6715 .into(), -6716 ); -6717 } -6718 -6719 /// Returns the maximum [`PathId`] to be used for sending in this connection. -6720 /// -6721 /// This is calculated as minimum between the local and remote's maximums when multipath is -6722 /// enabled, or `None` when disabled. -6723 /// -6724 /// For data that's received, we should use [`Self::local_max_path_id`] instead. -6725 /// The reasoning is that the remote might already have updated to its own newer -6726 /// [`Self::max_path_id`] after sending out a `MAX_PATH_ID` frame, but it got re-ordered. -6727 fn max_path_id(&self) -> Option<PathId> { -6728 if self.is_multipath_negotiated() { -6729 Some(self.remote_max_path_id.min(self.local_max_path_id)) -6730 } else { -6731 None -6732 } -6733 } -6734 -6735 /// Returns whether this connection has a socket that supports IPv6. -6736 /// -6737 /// TODO(matheus23): This is related to noq endpoint state's `ipv6` bool. We should move that info -6738 /// here instead of trying to hack around not knowing it exactly. -6739 fn is_ipv6(&self) -> bool { -6740 self.paths -6741 .values() -6742 .any(|p| p.data.network_path.remote.is_ipv6()) -6743 } -6744 -6745 /// Add addresses the local endpoint considers are reachable for nat traversal. -6746 pub fn add_nat_traversal_address( -6747 &mut self, -6748 address: SocketAddr, -6749 ) -> Result<(), n0_nat_traversal::Error> { -6750 if let Some(added) = self.n0_nat_traversal.add_local_address(address)? { -6751 self.spaces[SpaceId::Data].pending.add_address.insert(added); -6752 }; -6753 Ok(()) -6754 } -6755 -6756 /// Removes an address the endpoing no longer considers reachable for nat traversal -6757 /// -6758 /// Addresses not present in the set will be silently ignored. -6759 pub fn remove_nat_traversal_address( -6760 &mut self, -6761 address: SocketAddr, -6762 ) -> Result<(), n0_nat_traversal::Error> { -6763 if let Some(removed) = self.n0_nat_traversal.remove_local_address(address)? { -6764 self.spaces[SpaceId::Data] -6765 .pending -6766 .remove_address -6767 .insert(removed); -6768 } -6769 Ok(()) -6770 } -6771 -6772 /// Get the current local nat traversal addresses -6773 pub fn get_local_nat_traversal_addresses( -6774 &self, -6775 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6776 self.n0_nat_traversal.get_local_nat_traversal_addresses() -6777 } -6778 -6779 /// Get the currently advertised nat traversal addresses by the server -6780 pub fn get_remote_nat_traversal_addresses( -6781 &self, -6782 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6783 Ok(self -6784 .n0_nat_traversal -6785 .client_side()? -6786 .get_remote_nat_traversal_addresses()) -6787 } -6788 -6789 /// Attempts to open a path for nat traversal. -6790 /// -6791 /// On success returns the [`PathId`] and remote address of the path. -6792 fn open_nat_traversal_path( -6793 &mut self, -6794 now: Instant, -6795 ip_port: (IpAddr, u16), -6796 ) -> Result<Option<(PathId, SocketAddr)>, PathError> { -6797 let remote = ip_port.into(); -6798 // TODO(matheus23): Probe the correct 4-tuple, instead of only a remote address? -6799 // By specifying None for `local_ip`, we do two things: 1. open_path_ensure won't -6800 // generate two paths to the same remote and 2. we let the OS choose which -6801 // interface to use for sending on that path. -6802 let network_path = FourTuple { -6803 remote, -6804 local_ip: None, -6805 }; -6806 match self.open_path_ensure(network_path, PathStatus::Backup, now) { -6807 Ok((path_id, path_was_known)) => { -6808 if path_was_known { -6809 trace!(%path_id, %remote, "nat traversal: path existed for remote, revalidating"); -6810 if let Some(path) = self.paths.get_mut(&path_id) { -6811 path.data.pending_on_path_challenge = true; -6812 } -6813 } -6814 Ok(Some((path_id, remote))) -6815 } -6816 Err(e) => { -6817 debug!(%remote, %e, "nat traversal: failed to probe remote"); -6818 Err(e) -6819 } -6820 } -6821 } -6822 -6823 /// Initiates a new nat traversal round -6824 /// -6825 /// A nat traversal round involves advertising the client's local addresses in `REACH_OUT` -6826 /// frames, and initiating probing of the known remote addresses. When a new round is -6827 /// initiated, the previous one is cancelled, and paths that have not been opened are closed. -6828 /// -6829 /// Returns the server addresses that are now being probed. -6830 /// If addresses fail due to spurious errors, these might succeed later and not be returned in -6831 /// this set. -6832 pub fn initiate_nat_traversal_round( -6833 &mut self, -6834 now: Instant, -6835 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6836 if self.state.is_closed() { -6837 return Err(n0_nat_traversal::Error::Closed); -6838 } -6839 -6840 let ipv6 = self.is_ipv6(); -6841 let client_state = self.n0_nat_traversal.client_side_mut()?; -6842 let n0_nat_traversal::NatTraversalRound { -6843 new_round, -6844 reach_out_at, -6845 addresses_to_probe, -6846 prev_round_path_ids, -6847 } = client_state.initiate_nat_traversal_round(ipv6)?; -6848 -6849 trace!(%new_round, reach_out=reach_out_at.len(), to_probe=addresses_to_probe.len(), -6850 "initiating nat traversal round"); -6851 -6852 self.spaces[SpaceId::Data].pending.reach_out = Some((new_round, reach_out_at)); -6853 -6854 for path_id in prev_round_path_ids { -6855 let Some(path) = self.path(path_id) else { -6856 continue; -6857 }; -6858 let ip = path.network_path.remote.ip(); -6859 let port = path.network_path.remote.port(); -6860 -6861 // We only close paths that aren't validated (thus are working) that we opened -6862 // in a previous round. -6863 // And we only close paths that we don't want to probe anyways. -6864 if !addresses_to_probe -6865 .iter() -6866 .any(|(_, probe)| *probe == (ip, port)) -6867 && !path.validated -6868 && !self.abandoned_paths.contains(&path_id) -6869 { -6870 trace!(%path_id, "closing path from previous round"); -6871 let _ = -6872 self.close_path_inner(now, path_id, PathAbandonReason::NatTraversalRoundEnded); -6873 } -6874 } -6875 -6876 let mut err = None; -6877 -6878 let mut path_ids = Vec::with_capacity(addresses_to_probe.len()); -6879 let mut probed_addresses = Vec::with_capacity(addresses_to_probe.len()); -6880 -6881 for (id, address) in addresses_to_probe { -6882 match self.open_nat_traversal_path(now, address) { -6883 Ok(None) => {} -6884 Ok(Some((path_id, remote))) => { -6885 path_ids.push(path_id); -6886 probed_addresses.push(remote); -6887 } -6888 Err(e) => { -6889 self.n0_nat_traversal -6890 .client_side_mut() -6891 .expect("validated") -6892 .report_in_continuation(id, e); -6893 err.get_or_insert(e); -6894 } -6895 } -6896 } -6897 -6898 if let Some(err) = err { -6899 // We failed to probe any addresses, bail out -6900 if probed_addresses.is_empty() { -6901 return Err(n0_nat_traversal::Error::Multipath(err)); -6902 } -6903 } -6904 -6905 self.n0_nat_traversal -6906 .client_side_mut() -6907 .expect("connection side validated") -6908 .set_round_path_ids(path_ids); -6909 -6910 Ok(probed_addresses) -6911 } +6559 #[cfg(test)] +6560 #[track_caller] +6561 pub(crate) fn active_local_path_cid_seq(&self, path_id: u32) -> (u64, u64) { +6562 self.local_cid_state +6563 .get(&PathId(path_id)) +6564 .unwrap() +6565 .active_seq() +6566 } +6567 +6568 /// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame +6569 /// with updated `retire_prior_to` field set to `v` +6570 #[cfg(test)] +6571 pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) { +6572 let n = self +6573 .local_cid_state +6574 .get_mut(&PathId::ZERO) +6575 .unwrap() +6576 .assign_retire_seq(v); +6577 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events +6578 self.endpoint_events +6579 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); +6580 } +6581 +6582 /// Check the current active remote CID sequence for `PathId::ZERO` +6583 #[cfg(test)] +6584 pub(crate) fn active_remote_cid_seq(&self) -> u64 { +6585 self.remote_cids.get(&PathId::ZERO).unwrap().active_seq() +6586 } +6587 +6588 /// Returns the detected maximum udp payload size for the current path +6589 #[cfg(test)] +6590 pub(crate) fn path_mtu(&self, path_id: PathId) -> u16 { +6591 self.path_data(path_id).current_mtu() +6592 } +6593 +6594 /// Triggers path validation on all paths +6595 #[cfg(test)] +6596 pub(crate) fn trigger_path_validation(&mut self) { +6597 for path in self.paths.values_mut() { +6598 path.data.pending_on_path_challenge = true; +6599 } +6600 } +6601 +6602 /// Simulates a protocol violation error for test purposes. +6603 #[cfg(test)] +6604 pub fn simulate_protocol_violation(&mut self, now: Instant) { +6605 if !self.state.is_closed() { +6606 self.state +6607 .move_to_closed(TransportError::PROTOCOL_VIOLATION("simulated violation")); +6608 self.close_common(); +6609 if !self.state.is_drained() { +6610 self.set_close_timer(now); +6611 } +6612 self.connection_close_pending = true; +6613 } +6614 } +6615 +6616 /// Whether we have on-path 1-RTT data to send. +6617 /// +6618 /// This checks for frames that can only be sent in the data space (1-RTT): +6619 /// - Pending PATH_CHALLENGE frames on the active and previous path if just migrated. +6620 /// - Pending PATH_RESPONSE frames. +6621 /// - Pending data to send in STREAM frames. +6622 /// - Pending DATAGRAM frames to send. +6623 /// +6624 /// See also [`PacketSpace::can_send`] which keeps track of all other frame types that +6625 /// may need to be sent. +6626 fn can_send_1rtt(&self, path_id: PathId, max_size: usize) -> SendableFrames { +6627 let space_specific = self.paths.get(&path_id).is_some_and(|path| { +6628 path.data.pending_on_path_challenge || !path.data.path_responses.is_empty() +6629 }); +6630 +6631 // Stream control frames are checked in PacketSpace::can_send, only check data here. +6632 let other = self.streams.can_send_stream_data() +6633 || self +6634 .datagrams +6635 .outgoing +6636 .front() +6637 .is_some_and(|x| x.size(true) <= max_size); +6638 +6639 // All `false` fields are set in PacketSpace::can_send. +6640 SendableFrames { +6641 acks: false, +6642 close: false, +6643 space_specific, +6644 other, +6645 } +6646 } +6647 +6648 /// Terminate the connection instantly, without sending a close packet +6649 fn kill(&mut self, reason: ConnectionError) { +6650 self.close_common(); +6651 self.state.move_to_drained(Some(reason)); +6652 // move_to_drained checks that we were never in drained before, so we +6653 // never sent a `Drained` event before (it's illegal to send more events after drained). +6654 self.endpoint_events.push_back(EndpointEventInner::Drained); +6655 } +6656 +6657 /// Storage size required for the largest packet that can be transmitted on all currently +6658 /// available paths +6659 /// +6660 /// Buffers passed to [`Connection::poll_transmit`] should be at least this large. +6661 /// +6662 /// When multipath is enabled, this value is the minimum MTU across all available paths. +6663 pub fn current_mtu(&self) -> u16 { +6664 self.paths +6665 .iter() +6666 .filter(|&(path_id, _path_state)| !self.abandoned_paths.contains(path_id)) +6667 .map(|(_path_id, path_state)| path_state.data.current_mtu()) +6668 .min() +6669 .unwrap_or(INITIAL_MTU) +6670 } +6671 +6672 /// Size of non-frame data for a 1-RTT packet +6673 /// +6674 /// Quantifies space consumed by the QUIC header and AEAD tag. All other bytes in a packet are +6675 /// frames. Changes if the length of the remote connection ID changes, which is expected to be +6676 /// rare. If `pn` is specified, may additionally change unpredictably due to variations in +6677 /// latency and packet loss. +6678 fn predict_1rtt_overhead(&mut self, pn: u64, path: PathId) -> usize { +6679 let pn_len = PacketNumber::new( +6680 pn, +6681 self.spaces[SpaceId::Data] +6682 .for_path(path) +6683 .largest_acked_packet +6684 .unwrap_or(0), +6685 ) +6686 .len(); +6687 +6688 // 1 byte for flags +6689 1 + self +6690 .remote_cids +6691 .get(&path) +6692 .map(|cids| cids.active().len()) +6693 .unwrap_or(20) // Max CID len in QUIC v1 +6694 + pn_len +6695 + self.tag_len_1rtt() +6696 } +6697 +6698 fn predict_1rtt_overhead_no_pn(&self) -> usize { +6699 let pn_len = 4; +6700 +6701 let cid_len = self +6702 .remote_cids +6703 .values() +6704 .map(|cids| cids.active().len()) +6705 .max() +6706 .unwrap_or(20); // Max CID len in QUIC v1 +6707 +6708 // 1 byte for flags +6709 1 + cid_len + pn_len + self.tag_len_1rtt() +6710 } +6711 +6712 fn tag_len_1rtt(&self) -> usize { +6713 // encryption_keys for Data space returns 1-RTT keys if available, otherwise 0-RTT keys +6714 let packet_crypto = self +6715 .crypto_state +6716 .encryption_keys(SpaceKind::Data, self.side.side()) +6717 .map(|(_header, packet, _level)| packet); +6718 // If neither Data nor 0-RTT keys are available, make a reasonable tag length guess. As of +6719 // this writing, all QUIC cipher suites use 16-byte tags. We could return `None` instead, +6720 // but that would needlessly prevent sending datagrams during 0-RTT. +6721 packet_crypto.map_or(16, |x| x.tag_len()) +6722 } +6723 +6724 /// Mark the path as validated, and enqueue NEW_TOKEN frames to be sent as appropriate +6725 fn on_path_validated(&mut self, path_id: PathId) { +6726 self.path_data_mut(path_id).validated = true; +6727 let ConnectionSide::Server { server_config } = &self.side else { +6728 return; +6729 }; +6730 let network_path = self.path_data(path_id).network_path; +6731 let new_tokens = &mut self.spaces[SpaceId::Data as usize].pending.new_tokens; +6732 new_tokens.clear(); +6733 for _ in 0..server_config.validation_token.sent { +6734 new_tokens.push(network_path); +6735 } +6736 } +6737 +6738 /// Handle new path status information: PATH_STATUS_AVAILABLE, PATH_STATUS_BACKUP +6739 fn on_path_status(&mut self, path_id: PathId, status: PathStatus, status_seq_no: VarInt) { +6740 if let Some(path) = self.paths.get_mut(&path_id) { +6741 path.data.status.remote_update(status, status_seq_no); +6742 } else { +6743 debug!("PATH_STATUS_AVAILABLE received unknown path {:?}", path_id); +6744 } +6745 self.events.push_back( +6746 PathEvent::RemoteStatus { +6747 id: path_id, +6748 status, +6749 } +6750 .into(), +6751 ); +6752 } +6753 +6754 /// Returns the maximum [`PathId`] to be used for sending in this connection. +6755 /// +6756 /// This is calculated as minimum between the local and remote's maximums when multipath is +6757 /// enabled, or `None` when disabled. +6758 /// +6759 /// For data that's received, we should use [`Self::local_max_path_id`] instead. +6760 /// The reasoning is that the remote might already have updated to its own newer +6761 /// [`Self::max_path_id`] after sending out a `MAX_PATH_ID` frame, but it got re-ordered. +6762 fn max_path_id(&self) -> Option<PathId> { +6763 if self.is_multipath_negotiated() { +6764 Some(self.remote_max_path_id.min(self.local_max_path_id)) +6765 } else { +6766 None +6767 } +6768 } +6769 +6770 /// Returns whether this connection has a socket that supports IPv6. +6771 /// +6772 /// TODO(matheus23): This is related to noq endpoint state's `ipv6` bool. We should move that info +6773 /// here instead of trying to hack around not knowing it exactly. +6774 fn is_ipv6(&self) -> bool { +6775 self.paths +6776 .values() +6777 .any(|p| p.data.network_path.remote.is_ipv6()) +6778 } +6779 +6780 /// Add addresses the local endpoint considers are reachable for nat traversal. +6781 pub fn add_nat_traversal_address( +6782 &mut self, +6783 address: SocketAddr, +6784 ) -> Result<(), n0_nat_traversal::Error> { +6785 if let Some(added) = self.n0_nat_traversal.add_local_address(address)? { +6786 self.spaces[SpaceId::Data].pending.add_address.insert(added); +6787 }; +6788 Ok(()) +6789 } +6790 +6791 /// Removes an address the endpoing no longer considers reachable for nat traversal +6792 /// +6793 /// Addresses not present in the set will be silently ignored. +6794 pub fn remove_nat_traversal_address( +6795 &mut self, +6796 address: SocketAddr, +6797 ) -> Result<(), n0_nat_traversal::Error> { +6798 if let Some(removed) = self.n0_nat_traversal.remove_local_address(address)? { +6799 self.spaces[SpaceId::Data] +6800 .pending +6801 .remove_address +6802 .insert(removed); +6803 } +6804 Ok(()) +6805 } +6806 +6807 /// Get the current local nat traversal addresses +6808 pub fn get_local_nat_traversal_addresses( +6809 &self, +6810 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6811 self.n0_nat_traversal.get_local_nat_traversal_addresses() +6812 } +6813 +6814 /// Get the currently advertised nat traversal addresses by the server +6815 pub fn get_remote_nat_traversal_addresses( +6816 &self, +6817 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6818 Ok(self +6819 .n0_nat_traversal +6820 .client_side()? +6821 .get_remote_nat_traversal_addresses()) +6822 } +6823 +6824 /// Attempts to open a path for nat traversal. +6825 /// +6826 /// On success returns the [`PathId`] and remote address of the path. +6827 fn open_nat_traversal_path( +6828 &mut self, +6829 now: Instant, +6830 ip_port: (IpAddr, u16), +6831 ) -> Result<Option<(PathId, SocketAddr)>, PathError> { +6832 let remote = ip_port.into(); +6833 // TODO(matheus23): Probe the correct 4-tuple, instead of only a remote address? +6834 // By specifying None for `local_ip`, we do two things: 1. open_path_ensure won't +6835 // generate two paths to the same remote and 2. we let the OS choose which +6836 // interface to use for sending on that path. +6837 let network_path = FourTuple { +6838 remote, +6839 local_ip: None, +6840 }; +6841 match self.open_path_ensure(network_path, PathStatus::Backup, now) { +6842 Ok((path_id, path_was_known)) => { +6843 if path_was_known { +6844 trace!(%path_id, %remote, "nat traversal: path existed for remote, revalidating"); +6845 if let Some(path) = self.paths.get_mut(&path_id) { +6846 path.data.pending_on_path_challenge = true; +6847 } +6848 } +6849 Ok(Some((path_id, remote))) +6850 } +6851 Err(e) => { +6852 debug!(%remote, %e, "nat traversal: failed to probe remote"); +6853 Err(e) +6854 } +6855 } +6856 } +6857 +6858 /// Initiates a new nat traversal round +6859 /// +6860 /// A nat traversal round involves advertising the client's local addresses in `REACH_OUT` +6861 /// frames, and initiating probing of the known remote addresses. When a new round is +6862 /// initiated, the previous one is cancelled, and paths that have not been opened are closed. +6863 /// +6864 /// Returns the server addresses that are now being probed. +6865 /// If addresses fail due to spurious errors, these might succeed later and not be returned in +6866 /// this set. +6867 pub fn initiate_nat_traversal_round( +6868 &mut self, +6869 now: Instant, +6870 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6871 if self.state.is_closed() { +6872 return Err(n0_nat_traversal::Error::Closed); +6873 } +6874 +6875 let ipv6 = self.is_ipv6(); +6876 let client_state = self.n0_nat_traversal.client_side_mut()?; +6877 let n0_nat_traversal::NatTraversalRound { +6878 new_round, +6879 reach_out_at, +6880 addresses_to_probe, +6881 prev_round_path_ids, +6882 } = client_state.initiate_nat_traversal_round(ipv6)?; +6883 +6884 trace!(%new_round, reach_out=reach_out_at.len(), to_probe=addresses_to_probe.len(), +6885 "initiating nat traversal round"); +6886 +6887 self.spaces[SpaceId::Data].pending.reach_out = Some((new_round, reach_out_at)); +6888 +6889 for path_id in prev_round_path_ids { +6890 let Some(path) = self.path(path_id) else { +6891 continue; +6892 }; +6893 let ip = path.network_path.remote.ip(); +6894 let port = path.network_path.remote.port(); +6895 +6896 // We only close paths that aren't validated (thus are working) that we opened +6897 // in a previous round. +6898 // And we only close paths that we don't want to probe anyways. +6899 if !addresses_to_probe +6900 .iter() +6901 .any(|(_, probe)| *probe == (ip, port)) +6902 && !path.validated +6903 && !self.abandoned_paths.contains(&path_id) +6904 { +6905 trace!(%path_id, "closing path from previous round"); +6906 let _ = +6907 self.close_path_inner(now, path_id, PathAbandonReason::NatTraversalRoundEnded); +6908 } +6909 } +6910 +6911 let mut err = None; 6912 -6913 /// Attempts to continue a nat traversal round by trying to open paths for pending client probes. -6914 /// -6915 /// If there was nothing to do, it returns `None`. Otherwise it returns whether the path was -6916 /// successfully open. -6917 fn continue_nat_traversal_round(&mut self, now: Instant) -> Option<bool> { -6918 let ipv6 = self.is_ipv6(); -6919 let client_state = self.n0_nat_traversal.client_side_mut().ok()?; -6920 let (id, address) = client_state.continue_nat_traversal_round(ipv6)?; -6921 let open_result = self.open_nat_traversal_path(now, address); -6922 let client_state = self.n0_nat_traversal.client_side_mut().expect("validated"); -6923 match open_result { -6924 Ok(None) => Some(true), -6925 Ok(Some((path_id, _remote))) => { -6926 client_state.add_round_path_id(path_id); -6927 Some(true) -6928 } -6929 Err(e) => { -6930 client_state.report_in_continuation(id, e); -6931 Some(false) -6932 } -6933 } -6934 } -6935} -6936 -6937impl fmt::Debug for Connection { -6938 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -6939 f.debug_struct("Connection") -6940 .field("handshake_cid", &self.handshake_cid) -6941 .finish() -6942 } -6943} +6913 let mut path_ids = Vec::with_capacity(addresses_to_probe.len()); +6914 let mut probed_addresses = Vec::with_capacity(addresses_to_probe.len()); +6915 +6916 for (id, address) in addresses_to_probe { +6917 match self.open_nat_traversal_path(now, address) { +6918 Ok(None) => {} +6919 Ok(Some((path_id, remote))) => { +6920 path_ids.push(path_id); +6921 probed_addresses.push(remote); +6922 } +6923 Err(e) => { +6924 self.n0_nat_traversal +6925 .client_side_mut() +6926 .expect("validated") +6927 .report_in_continuation(id, e); +6928 err.get_or_insert(e); +6929 } +6930 } +6931 } +6932 +6933 if let Some(err) = err { +6934 // We failed to probe any addresses, bail out +6935 if probed_addresses.is_empty() { +6936 return Err(n0_nat_traversal::Error::Multipath(err)); +6937 } +6938 } +6939 +6940 self.n0_nat_traversal +6941 .client_side_mut() +6942 .expect("connection side validated") +6943 .set_round_path_ids(path_ids); 6944 -6945/// Hints when the caller identifies a network change. -6946pub trait NetworkChangeHint: std::fmt::Debug + 'static { -6947 /// Inform the connection if a path may recover after a network change. -6948 /// -6949 /// After network changes, paths may not be recoverable. In this case, waiting for the path to -6950 /// become idle may take longer than what is desirable. If [`Self::is_path_recoverable`] -6951 /// returns `false`, a multipath-enabled, client-side connection will establish a new path to -6952 /// the same remote, closing the current one, instead of migrating the path. -6953 /// -6954 /// Paths that are deemed recoverable will simply be sent a PING for a liveness check. -6955 fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool; -6956} -6957 -6958/// Return value for [`Connection::poll_transmit_on_path`]. -6959#[derive(Debug)] -6960enum PollPathStatus { -6961 /// Nothing to send on the path, nothing was written into the [`TransmitBuf`]. -6962 NothingToSend { -6963 /// If true there was data to send but congestion control did not allow so. -6964 congestion_blocked: bool, -6965 }, -6966 /// The transmit is ready to be sent. -6967 Send(Transmit), -6968} -6969 -6970/// Return value for [`Connection::poll_transmit_path_space`]. -6971#[derive(Debug)] -6972enum PollPathSpaceStatus { -6973 /// Nothing to send in the space, nothing was written into the [`TransmitBuf`]. -6974 NothingToSend { -6975 /// If true there was data to send but congestion control did not allow so. -6976 congestion_blocked: bool, -6977 }, -6978 /// One or more packets have been written into the [`TransmitBuf`]. -6979 WrotePacket { -6980 /// The highest packet number. -6981 last_packet_number: u64, -6982 /// Whether to pad an already started datagram in the next packet. -6983 /// -6984 /// When packets in Initial, 0-RTT or Handshake packet do not fill the entire -6985 /// datagram they may decide to coalesce with the next packet from a higher -6986 /// encryption level on the same path. But the earlier packet may require specific -6987 /// size requirements for the datagram they are sent in. -6988 /// -6989 /// If a space did not complete the datagram, they use this to request the correct -6990 /// padding in the final packet of the datagram so that the final datagram will have -6991 /// the correct size. -6992 /// -6993 /// If a space did fill an entire datagram, it leaves this to the default of -6994 /// [`PadDatagram::No`]. -6995 pad_datagram: PadDatagram, -6996 }, -6997 /// Send the contents of the transmit immediately. -6998 /// -6999 /// Packets were written and the GSO batch must end now, regardless from whether higher -7000 /// spaces still have frames to write. This is used when the last datagram written would -7001 /// require too much padding to continue a GSO batch, which would waste space on the -7002 /// wire. -7003 Send { -7004 /// The highest packet number written into the transmit. -7005 last_packet_number: u64, -7006 }, -7007} -7008 -7009/// Information used to decide what frames to schedule into which packets. -7010/// -7011/// Primarily used by [`Connection::poll_transmit_on_path`] and the functions that help -7012/// building packets for it: [`Connection::poll_transmit_path_space`] and -7013/// [`Connection::populate_packet`]. -7014#[derive(Debug, Copy, Clone)] -7015struct PathSchedulingInfo { -7016 /// Whether the path is abandoned. -7017 /// -7018 /// Note that a path that is abandoned but still has CIDs can still send a packet. After -7019 /// sending that packet the CIDs issued by the remote have to be considered retired as -7020 /// well. -7021 is_abandoned: bool, -7022 /// Whether the path may send [`SpaceKind::Data`] frames. -7023 /// -7024 /// Some paths should only send frames from [`SendableFrames::space_specific`]. All other -7025 /// frames are essentially frames that can be sent on any [`SpaceKind::Data`] space. For -7026 /// those we want to respect packet scheduling rules however. -7027 /// -7028 /// Roughly speaking data frames are only sent on spaces that have CIDs, are not -7029 /// abandoned and have no *better* spaces. However see to comments where this is -7030 /// populated for the exact packet scheduling implementation. -7031 /// -7032 /// This essentially marks this paths as the best validated space ID. Except during -7033 /// the handshake in which case it does not need to be validated. Several paths could be -7034 /// equally good and all have this set to `true`, in that case packet scheduling can -7035 /// choose which path to use. Currently it chooses the lowest path that is not -7036 /// congestion blocked. -7037 /// -7038 /// Note that once in the closed or draining states this will never be true. -7039 may_send_data: bool, -7040 /// Whether the path may send a CONNECTION_CLOSE frame. -7041 /// -7042 /// This essentially marks this path as the best validated space ID with a fallback -7043 /// to unvalidated spaces if there are no validated spaces. Like for -7044 /// [`Self::may_send_data`] other paths could be equally good. -7045 may_send_close: bool, -7046 may_self_abandon: bool, -7047} -7048 -7049#[derive(Debug, Copy, Clone, PartialEq, Eq)] -7050enum PathBlocked { -7051 No, -7052 AntiAmplification, -7053 Congestion, -7054 Pacing, -7055} -7056 -7057/// Fields of `Connection` specific to it being client-side or server-side -7058enum ConnectionSide { -7059 Client { -7060 /// Sent in every outgoing Initial packet. Always empty after Initial keys are discarded -7061 token: Bytes, -7062 token_store: Arc<dyn TokenStore>, -7063 server_name: String, -7064 }, -7065 Server { -7066 server_config: Arc<ServerConfig>, -7067 }, -7068} -7069 -7070impl ConnectionSide { -7071 fn remote_may_migrate(&self, state: &State) -> bool { -7072 match self { -7073 Self::Server { server_config } => server_config.migration, -7074 Self::Client { .. } => { -7075 if let Some(hs) = state.as_handshake() { -7076 hs.allow_server_migration -7077 } else { -7078 false -7079 } -7080 } -7081 } -7082 } +6945 Ok(probed_addresses) +6946 } +6947 +6948 /// Attempts to continue a nat traversal round by trying to open paths for pending client probes. +6949 /// +6950 /// If there was nothing to do, it returns `None`. Otherwise it returns whether the path was +6951 /// successfully open. +6952 fn continue_nat_traversal_round(&mut self, now: Instant) -> Option<bool> { +6953 let ipv6 = self.is_ipv6(); +6954 let client_state = self.n0_nat_traversal.client_side_mut().ok()?; +6955 let (id, address) = client_state.continue_nat_traversal_round(ipv6)?; +6956 let open_result = self.open_nat_traversal_path(now, address); +6957 let client_state = self.n0_nat_traversal.client_side_mut().expect("validated"); +6958 match open_result { +6959 Ok(None) => Some(true), +6960 Ok(Some((path_id, _remote))) => { +6961 client_state.add_round_path_id(path_id); +6962 Some(true) +6963 } +6964 Err(e) => { +6965 client_state.report_in_continuation(id, e); +6966 Some(false) +6967 } +6968 } +6969 } +6970} +6971 +6972impl fmt::Debug for Connection { +6973 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +6974 f.debug_struct("Connection") +6975 .field("handshake_cid", &self.handshake_cid) +6976 .finish() +6977 } +6978} +6979 +6980/// Hints when the caller identifies a network change. +6981pub trait NetworkChangeHint: std::fmt::Debug + 'static { +6982 /// Inform the connection if a path may recover after a network change. +6983 /// +6984 /// After network changes, paths may not be recoverable. In this case, waiting for the path to +6985 /// become idle may take longer than what is desirable. If [`Self::is_path_recoverable`] +6986 /// returns `false`, a multipath-enabled, client-side connection will establish a new path to +6987 /// the same remote, closing the current one, instead of migrating the path. +6988 /// +6989 /// Paths that are deemed recoverable will simply be sent a PING for a liveness check. +6990 fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool; +6991} +6992 +6993/// Return value for [`Connection::poll_transmit_on_path`]. +6994#[derive(Debug)] +6995enum PollPathStatus { +6996 /// Nothing to send on the path, nothing was written into the [`TransmitBuf`]. +6997 NothingToSend { +6998 /// If true there was data to send but congestion control did not allow so. +6999 congestion_blocked: bool, +7000 }, +7001 /// The transmit is ready to be sent. +7002 Send(Transmit), +7003} +7004 +7005/// Return value for [`Connection::poll_transmit_path_space`]. +7006#[derive(Debug)] +7007enum PollPathSpaceStatus { +7008 /// Nothing to send in the space, nothing was written into the [`TransmitBuf`]. +7009 NothingToSend { +7010 /// If true there was data to send but congestion control did not allow so. +7011 congestion_blocked: bool, +7012 }, +7013 /// One or more packets have been written into the [`TransmitBuf`]. +7014 WrotePacket { +7015 /// The highest packet number. +7016 last_packet_number: u64, +7017 /// Whether to pad an already started datagram in the next packet. +7018 /// +7019 /// When packets in Initial, 0-RTT or Handshake packet do not fill the entire +7020 /// datagram they may decide to coalesce with the next packet from a higher +7021 /// encryption level on the same path. But the earlier packet may require specific +7022 /// size requirements for the datagram they are sent in. +7023 /// +7024 /// If a space did not complete the datagram, they use this to request the correct +7025 /// padding in the final packet of the datagram so that the final datagram will have +7026 /// the correct size. +7027 /// +7028 /// If a space did fill an entire datagram, it leaves this to the default of +7029 /// [`PadDatagram::No`]. +7030 pad_datagram: PadDatagram, +7031 }, +7032 /// Send the contents of the transmit immediately. +7033 /// +7034 /// Packets were written and the GSO batch must end now, regardless from whether higher +7035 /// spaces still have frames to write. This is used when the last datagram written would +7036 /// require too much padding to continue a GSO batch, which would waste space on the +7037 /// wire. +7038 Send { +7039 /// The highest packet number written into the transmit. +7040 last_packet_number: u64, +7041 }, +7042} +7043 +7044/// Information used to decide what frames to schedule into which packets. +7045/// +7046/// Primarily used by [`Connection::poll_transmit_on_path`] and the functions that help +7047/// building packets for it: [`Connection::poll_transmit_path_space`] and +7048/// [`Connection::populate_packet`]. +7049#[derive(Debug, Copy, Clone)] +7050struct PathSchedulingInfo { +7051 /// Whether the path is abandoned. +7052 /// +7053 /// Note that a path that is abandoned but still has CIDs can still send a packet. After +7054 /// sending that packet the CIDs issued by the remote have to be considered retired as +7055 /// well. +7056 is_abandoned: bool, +7057 /// Whether the path may send [`SpaceKind::Data`] frames. +7058 /// +7059 /// Some paths should only send frames from [`SendableFrames::space_specific`]. All other +7060 /// frames are essentially frames that can be sent on any [`SpaceKind::Data`] space. For +7061 /// those we want to respect packet scheduling rules however. +7062 /// +7063 /// Roughly speaking data frames are only sent on spaces that have CIDs, are not +7064 /// abandoned and have no *better* spaces. However see to comments where this is +7065 /// populated for the exact packet scheduling implementation. +7066 /// +7067 /// This essentially marks this paths as the best validated space ID. Except during +7068 /// the handshake in which case it does not need to be validated. Several paths could be +7069 /// equally good and all have this set to `true`, in that case packet scheduling can +7070 /// choose which path to use. Currently it chooses the lowest path that is not +7071 /// congestion blocked. +7072 /// +7073 /// Note that once in the closed or draining states this will never be true. +7074 may_send_data: bool, +7075 /// Whether the path may send a CONNECTION_CLOSE frame. +7076 /// +7077 /// This essentially marks this path as the best validated space ID with a fallback +7078 /// to unvalidated spaces if there are no validated spaces. Like for +7079 /// [`Self::may_send_data`] other paths could be equally good. +7080 may_send_close: bool, +7081 may_self_abandon: bool, +7082} 7083 -7084 fn is_client(&self) -> bool { -7085 self.side().is_client() -7086 } -7087 -7088 fn is_server(&self) -> bool { -7089 self.side().is_server() -7090 } +7084#[derive(Debug, Copy, Clone, PartialEq, Eq)] +7085enum PathBlocked { +7086 No, +7087 AntiAmplification, +7088 Congestion, +7089 Pacing, +7090} 7091 -7092 fn side(&self) -> Side { -7093 match *self { -7094 Self::Client { .. } => Side::Client, -7095 Self::Server { .. } => Side::Server, -7096 } -7097 } -7098} -7099 -7100impl From<SideArgs> for ConnectionSide { -7101 fn from(side: SideArgs) -> Self { -7102 match side { -7103 SideArgs::Client { -7104 token_store, -7105 server_name, -7106 } => Self::Client { -7107 token: token_store.take(&server_name).unwrap_or_default(), -7108 token_store, -7109 server_name, -7110 }, -7111 SideArgs::Server { -7112 server_config, -7113 pref_addr_cid: _, -7114 path_validated: _, -7115 } => Self::Server { server_config }, +7092/// Fields of `Connection` specific to it being client-side or server-side +7093enum ConnectionSide { +7094 Client { +7095 /// Sent in every outgoing Initial packet. Always empty after Initial keys are discarded +7096 token: Bytes, +7097 token_store: Arc<dyn TokenStore>, +7098 server_name: String, +7099 }, +7100 Server { +7101 server_config: Arc<ServerConfig>, +7102 }, +7103} +7104 +7105impl ConnectionSide { +7106 fn remote_may_migrate(&self, state: &State) -> bool { +7107 match self { +7108 Self::Server { server_config } => server_config.migration, +7109 Self::Client { .. } => { +7110 if let Some(hs) = state.as_handshake() { +7111 hs.allow_server_migration +7112 } else { +7113 false +7114 } +7115 } 7116 } 7117 } -7118} -7119 -7120/// Parameters to `Connection::new` specific to it being client-side or server-side -7121pub(crate) enum SideArgs { -7122 Client { -7123 token_store: Arc<dyn TokenStore>, -7124 server_name: String, -7125 }, -7126 Server { -7127 server_config: Arc<ServerConfig>, -7128 pref_addr_cid: Option<ConnectionId>, -7129 path_validated: bool, -7130 }, -7131} -7132 -7133impl SideArgs { -7134 pub(crate) fn pref_addr_cid(&self) -> Option<ConnectionId> { -7135 match *self { -7136 Self::Client { .. } => None, -7137 Self::Server { pref_addr_cid, .. } => pref_addr_cid, -7138 } -7139 } -7140 -7141 pub(crate) fn path_validated(&self) -> bool { -7142 match *self { -7143 Self::Client { .. } => true, -7144 Self::Server { path_validated, .. } => path_validated, -7145 } -7146 } -7147 -7148 pub(crate) fn side(&self) -> Side { -7149 match *self { -7150 Self::Client { .. } => Side::Client, -7151 Self::Server { .. } => Side::Server, -7152 } -7153 } -7154} -7155 -7156/// Reasons why a connection might be lost -7157#[derive(Debug, Error, Clone, PartialEq, Eq)] -7158pub enum ConnectionError { -7159 /// The peer doesn't implement any supported version -7160 #[error("peer doesn't implement any supported version")] -7161 VersionMismatch, -7162 /// The peer violated the QUIC specification as understood by this implementation -7163 #[error(transparent)] -7164 TransportError(#[from] TransportError), -7165 /// The peer's QUIC stack aborted the connection automatically -7166 #[error("aborted by peer: {0}")] -7167 ConnectionClosed(frame::ConnectionClose), -7168 /// The peer closed the connection -7169 #[error("closed by peer: {0}")] -7170 ApplicationClosed(frame::ApplicationClose), -7171 /// The peer is unable to continue processing this connection, usually due to having restarted -7172 #[error("reset by peer")] -7173 Reset, -7174 /// Communication with the peer has lapsed for longer than the negotiated idle timeout -7175 /// -7176 /// If neither side is sending keep-alives, a connection will time out after a long enough idle -7177 /// period even if the peer is still reachable. See also [`TransportConfig::max_idle_timeout()`] -7178 /// and [`TransportConfig::keep_alive_interval()`]. -7179 #[error("timed out")] -7180 TimedOut, -7181 /// The local application closed the connection -7182 #[error("closed")] -7183 LocallyClosed, -7184 /// The connection could not be created because not enough of the CID space is available -7185 /// -7186 /// Try using longer connection IDs. -7187 #[error("CIDs exhausted")] -7188 CidsExhausted, +7118 +7119 fn is_client(&self) -> bool { +7120 self.side().is_client() +7121 } +7122 +7123 fn is_server(&self) -> bool { +7124 self.side().is_server() +7125 } +7126 +7127 fn side(&self) -> Side { +7128 match *self { +7129 Self::Client { .. } => Side::Client, +7130 Self::Server { .. } => Side::Server, +7131 } +7132 } +7133} +7134 +7135impl From<SideArgs> for ConnectionSide { +7136 fn from(side: SideArgs) -> Self { +7137 match side { +7138 SideArgs::Client { +7139 token_store, +7140 server_name, +7141 } => Self::Client { +7142 token: token_store.take(&server_name).unwrap_or_default(), +7143 token_store, +7144 server_name, +7145 }, +7146 SideArgs::Server { +7147 server_config, +7148 pref_addr_cid: _, +7149 path_validated: _, +7150 } => Self::Server { server_config }, +7151 } +7152 } +7153} +7154 +7155/// Parameters to `Connection::new` specific to it being client-side or server-side +7156pub(crate) enum SideArgs { +7157 Client { +7158 token_store: Arc<dyn TokenStore>, +7159 server_name: String, +7160 }, +7161 Server { +7162 server_config: Arc<ServerConfig>, +7163 pref_addr_cid: Option<ConnectionId>, +7164 path_validated: bool, +7165 }, +7166} +7167 +7168impl SideArgs { +7169 pub(crate) fn pref_addr_cid(&self) -> Option<ConnectionId> { +7170 match *self { +7171 Self::Client { .. } => None, +7172 Self::Server { pref_addr_cid, .. } => pref_addr_cid, +7173 } +7174 } +7175 +7176 pub(crate) fn path_validated(&self) -> bool { +7177 match *self { +7178 Self::Client { .. } => true, +7179 Self::Server { path_validated, .. } => path_validated, +7180 } +7181 } +7182 +7183 pub(crate) fn side(&self) -> Side { +7184 match *self { +7185 Self::Client { .. } => Side::Client, +7186 Self::Server { .. } => Side::Server, +7187 } +7188 } 7189} 7190 -7191impl From<Close> for ConnectionError { -7192 fn from(x: Close) -> Self { -7193 match x { -7194 Close::Connection(reason) => Self::ConnectionClosed(reason), -7195 Close::Application(reason) => Self::ApplicationClosed(reason), -7196 } -7197 } -7198} -7199 -7200// For compatibility with API consumers -7201impl From<ConnectionError> for io::Error { -7202 fn from(x: ConnectionError) -> Self { -7203 use ConnectionError::*; -7204 let kind = match x { -7205 TimedOut => io::ErrorKind::TimedOut, -7206 Reset => io::ErrorKind::ConnectionReset, -7207 ApplicationClosed(_) | ConnectionClosed(_) => io::ErrorKind::ConnectionAborted, -7208 TransportError(_) | VersionMismatch | LocallyClosed | CidsExhausted => { -7209 io::ErrorKind::Other -7210 } -7211 }; -7212 Self::new(kind, x) -7213 } -7214} -7215 -7216/// Errors that might trigger a path being closed -7217// TODO(@divma): maybe needs to be reworked based on what we want to do with the public API -7218#[derive(Debug, Error, PartialEq, Eq, Clone, Copy)] -7219pub enum PathError { -7220 /// The extension was not negotiated with the peer -7221 #[error("multipath extension not negotiated")] -7222 MultipathNotNegotiated, -7223 /// Paths can only be opened client-side -7224 #[error("the server side may not open a path")] -7225 ServerSideNotAllowed, -7226 /// Current limits do not allow us to open more paths -7227 #[error("maximum number of concurrent paths reached")] -7228 MaxPathIdReached, -7229 /// No remote CIDs available to open a new path -7230 #[error("remoted CIDs exhausted")] -7231 RemoteCidsExhausted, -7232 /// Path could not be validated and will be abandoned -7233 #[error("path validation failed")] -7234 ValidationFailed, -7235 /// The remote address for the path is not supported by the endpoint -7236 #[error("invalid remote address")] -7237 InvalidRemoteAddress(SocketAddr), -7238} -7239 -7240/// Errors triggered when abandoning a path -7241#[derive(Debug, Error, Clone, Eq, PartialEq)] -7242pub enum ClosePathError { -7243 /// Multipath is not negotiated -7244 #[error("Multipath extension not negotiated")] -7245 MultipathNotNegotiated, -7246 /// The path is already closed or was never opened -7247 #[error("closed path")] -7248 ClosedPath, -7249 /// Cannot close the last remaining open path via the local API. -7250 /// -7251 /// Use [`Connection::close`] to end the connection instead. -7252 #[error("last open path")] -7253 LastOpenPath, -7254} -7255 -7256/// Error when the multipath extension was not negotiated, but attempted to be used. -7257#[derive(Debug, Error, Clone, Copy)] -7258#[error("Multipath extension not negotiated")] -7259pub struct MultipathNotNegotiated { -7260 _private: (), -7261} -7262 -7263/// Events of interest to the application -7264#[derive(Debug)] -7265pub enum Event { -7266 /// The connection's handshake data is ready -7267 HandshakeDataReady, -7268 /// The connection was successfully established -7269 Connected, -7270 /// The TLS handshake was confirmed -7271 HandshakeConfirmed, -7272 /// The connection was lost -7273 /// -7274 /// Emitted if the peer closes the connection or an error is encountered. -7275 ConnectionLost { -7276 /// Reason that the connection was closed -7277 reason: ConnectionError, -7278 }, -7279 /// Stream events -7280 Stream(StreamEvent), -7281 /// One or more application datagrams have been received -7282 DatagramReceived, -7283 /// One or more application datagrams have been sent after blocking -7284 DatagramsUnblocked, -7285 /// (Multi)Path events -7286 Path(PathEvent), -7287 /// n0's nat traversal events -7288 NatTraversal(n0_nat_traversal::Event), +7191/// Reasons why a connection might be lost +7192#[derive(Debug, Error, Clone, PartialEq, Eq)] +7193pub enum ConnectionError { +7194 /// The peer doesn't implement any supported version +7195 #[error("peer doesn't implement any supported version")] +7196 VersionMismatch, +7197 /// The peer violated the QUIC specification as understood by this implementation +7198 #[error(transparent)] +7199 TransportError(#[from] TransportError), +7200 /// The peer's QUIC stack aborted the connection automatically +7201 #[error("aborted by peer: {0}")] +7202 ConnectionClosed(frame::ConnectionClose), +7203 /// The peer closed the connection +7204 #[error("closed by peer: {0}")] +7205 ApplicationClosed(frame::ApplicationClose), +7206 /// The peer is unable to continue processing this connection, usually due to having restarted +7207 #[error("reset by peer")] +7208 Reset, +7209 /// Communication with the peer has lapsed for longer than the negotiated idle timeout +7210 /// +7211 /// If neither side is sending keep-alives, a connection will time out after a long enough idle +7212 /// period even if the peer is still reachable. See also [`TransportConfig::max_idle_timeout()`] +7213 /// and [`TransportConfig::keep_alive_interval()`]. +7214 #[error("timed out")] +7215 TimedOut, +7216 /// The local application closed the connection +7217 #[error("closed")] +7218 LocallyClosed, +7219 /// The connection could not be created because not enough of the CID space is available +7220 /// +7221 /// Try using longer connection IDs. +7222 #[error("CIDs exhausted")] +7223 CidsExhausted, +7224} +7225 +7226impl From<Close> for ConnectionError { +7227 fn from(x: Close) -> Self { +7228 match x { +7229 Close::Connection(reason) => Self::ConnectionClosed(reason), +7230 Close::Application(reason) => Self::ApplicationClosed(reason), +7231 } +7232 } +7233} +7234 +7235// For compatibility with API consumers +7236impl From<ConnectionError> for io::Error { +7237 fn from(x: ConnectionError) -> Self { +7238 use ConnectionError::*; +7239 let kind = match x { +7240 TimedOut => io::ErrorKind::TimedOut, +7241 Reset => io::ErrorKind::ConnectionReset, +7242 ApplicationClosed(_) | ConnectionClosed(_) => io::ErrorKind::ConnectionAborted, +7243 TransportError(_) | VersionMismatch | LocallyClosed | CidsExhausted => { +7244 io::ErrorKind::Other +7245 } +7246 }; +7247 Self::new(kind, x) +7248 } +7249} +7250 +7251/// Errors that might trigger a path being closed +7252// TODO(@divma): maybe needs to be reworked based on what we want to do with the public API +7253#[derive(Debug, Error, PartialEq, Eq, Clone, Copy)] +7254pub enum PathError { +7255 /// The extension was not negotiated with the peer +7256 #[error("multipath extension not negotiated")] +7257 MultipathNotNegotiated, +7258 /// Paths can only be opened client-side +7259 #[error("the server side may not open a path")] +7260 ServerSideNotAllowed, +7261 /// Current limits do not allow us to open more paths +7262 #[error("maximum number of concurrent paths reached")] +7263 MaxPathIdReached, +7264 /// No remote CIDs available to open a new path +7265 #[error("remoted CIDs exhausted")] +7266 RemoteCidsExhausted, +7267 /// Path could not be validated and will be abandoned +7268 #[error("path validation failed")] +7269 ValidationFailed, +7270 /// The remote address for the path is not supported by the endpoint +7271 #[error("invalid remote address")] +7272 InvalidRemoteAddress(SocketAddr), +7273} +7274 +7275/// Errors triggered when abandoning a path +7276#[derive(Debug, Error, Clone, Eq, PartialEq)] +7277pub enum ClosePathError { +7278 /// Multipath is not negotiated +7279 #[error("Multipath extension not negotiated")] +7280 MultipathNotNegotiated, +7281 /// The path is already closed or was never opened +7282 #[error("closed path")] +7283 ClosedPath, +7284 /// Cannot close the last remaining open path via the local API. +7285 /// +7286 /// Use [`Connection::close`] to end the connection instead. +7287 #[error("last open path")] +7288 LastOpenPath, 7289} 7290 -7291impl From<PathEvent> for Event { -7292 fn from(source: PathEvent) -> Self { -7293 Self::Path(source) -7294 } -7295} -7296 -7297fn get_max_ack_delay(params: &TransportParameters) -> Duration { -7298 Duration::from_micros(params.max_ack_delay.0 * 1000) -7299} -7300 -7301// Prevents overflow and improves behavior in extreme circumstances -7302const MAX_BACKOFF_EXPONENT: u32 = 16; -7303 -7304/// Minimal remaining size to allow packet coalescing, excluding cryptographic tag -7305/// -7306/// This must be at least as large as the header for a well-formed empty packet to be coalesced, -7307/// plus some space for frames. We only care about handshake headers because short header packets -7308/// necessarily have smaller headers, and initial packets are only ever the first packet in a -7309/// datagram (because we coalesce in ascending packet space order and the only reason to split a -7310/// packet is when packet space changes). -7311const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32; -7312 -7313/// Largest amount of space that could be occupied by a Handshake or 0-RTT packet's header -7314/// -7315/// Excludes packet-type-specific fields such as packet number or Initial token -7316// https://www.rfc-editor.org/rfc/rfc9000.html#name-0-rtt: flags + version + dcid len + dcid + -7317// scid len + scid + length + pn -7318const MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE: usize = -7319 1 + 4 + 1 + MAX_CID_SIZE + 1 + MAX_CID_SIZE + VarInt::from_u32(u16::MAX as u32).size() + 4; -7320 -7321#[derive(Default)] -7322struct SentFrames { -7323 retransmits: ThinRetransmits, -7324 /// The packet number of the largest acknowledged packet for each path -7325 largest_acked: FxHashMap<PathId, u64>, -7326 stream_frames: StreamMetaVec, -7327 /// Whether the packet contains non-retransmittable frames (like datagrams) -7328 non_retransmits: bool, -7329 /// If the datagram containing these frames should be padded to the min MTU -7330 requires_padding: bool, -7331} -7332 -7333impl SentFrames { -7334 /// Returns whether the packet contains only ACKs -7335 fn is_ack_only(&self, streams: &StreamsState) -> bool { -7336 !self.largest_acked.is_empty() -7337 && !self.non_retransmits -7338 && self.stream_frames.is_empty() -7339 && self.retransmits.is_empty(streams) -7340 } -7341 -7342 fn retransmits_mut(&mut self) -> &mut Retransmits { -7343 self.retransmits.get_or_create() -7344 } -7345 -7346 fn record_sent_frame(&mut self, frame: frame::EncodableFrame<'_>) { -7347 use frame::EncodableFrame::*; -7348 match frame { -7349 PathAck(path_ack_encoder) => { -7350 if let Some(max) = path_ack_encoder.ranges.max() { -7351 self.largest_acked.insert(path_ack_encoder.path_id, max); -7352 } -7353 } -7354 Ack(ack_encoder) => { -7355 if let Some(max) = ack_encoder.ranges.max() { -7356 self.largest_acked.insert(PathId::ZERO, max); -7357 } -7358 } -7359 Close(_) => { /* non retransmittable, but after this we don't really care */ } -7360 PathResponse(_) => self.non_retransmits = true, -7361 HandshakeDone(_) => self.retransmits_mut().handshake_done = true, -7362 ReachOut(frame::ReachOut { round, ip, port }) => { -7363 let (recorded_round, reach_outs) = self -7364 .retransmits_mut() -7365 .reach_out -7366 .get_or_insert_with(|| (round, FxHashSet::default())); -7367 // Only record reach outs for the current round or a newer than the recorded one. -7368 if *recorded_round == round { -7369 // Same round, simply append. -7370 reach_outs.insert((ip, port)); -7371 } else if *recorded_round < round { -7372 // New round. -7373 *recorded_round = round; -7374 reach_outs.drain(); -7375 reach_outs.insert((ip, port)); -7376 } else { -7377 // ignore old reach out that was sent -7378 } -7379 } +7291/// Error when the multipath extension was not negotiated, but attempted to be used. +7292#[derive(Debug, Error, Clone, Copy)] +7293#[error("Multipath extension not negotiated")] +7294pub struct MultipathNotNegotiated { +7295 _private: (), +7296} +7297 +7298/// Events of interest to the application +7299#[derive(Debug)] +7300pub enum Event { +7301 /// The connection's handshake data is ready +7302 HandshakeDataReady, +7303 /// The connection was successfully established +7304 Connected, +7305 /// The TLS handshake was confirmed +7306 HandshakeConfirmed, +7307 /// The connection was lost +7308 /// +7309 /// Emitted if the peer closes the connection or an error is encountered. +7310 ConnectionLost { +7311 /// Reason that the connection was closed +7312 reason: ConnectionError, +7313 }, +7314 /// Stream events +7315 Stream(StreamEvent), +7316 /// One or more application datagrams have been received +7317 DatagramReceived, +7318 /// One or more application datagrams have been sent after blocking +7319 DatagramsUnblocked, +7320 /// (Multi)Path events +7321 Path(PathEvent), +7322 /// n0's nat traversal events +7323 NatTraversal(n0_nat_traversal::Event), +7324} +7325 +7326impl From<PathEvent> for Event { +7327 fn from(source: PathEvent) -> Self { +7328 Self::Path(source) +7329 } +7330} +7331 +7332fn get_max_ack_delay(params: &TransportParameters) -> Duration { +7333 Duration::from_micros(params.max_ack_delay.0 * 1000) +7334} +7335 +7336// Prevents overflow and improves behavior in extreme circumstances +7337const MAX_BACKOFF_EXPONENT: u32 = 16; +7338 +7339/// Minimal remaining size to allow packet coalescing, excluding cryptographic tag +7340/// +7341/// This must be at least as large as the header for a well-formed empty packet to be coalesced, +7342/// plus some space for frames. We only care about handshake headers because short header packets +7343/// necessarily have smaller headers, and initial packets are only ever the first packet in a +7344/// datagram (because we coalesce in ascending packet space order and the only reason to split a +7345/// packet is when packet space changes). +7346const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32; +7347 +7348/// Largest amount of space that could be occupied by a Handshake or 0-RTT packet's header +7349/// +7350/// Excludes packet-type-specific fields such as packet number or Initial token +7351// https://www.rfc-editor.org/rfc/rfc9000.html#name-0-rtt: flags + version + dcid len + dcid + +7352// scid len + scid + length + pn +7353const MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE: usize = +7354 1 + 4 + 1 + MAX_CID_SIZE + 1 + MAX_CID_SIZE + VarInt::from_u32(u16::MAX as u32).size() + 4; +7355 +7356#[derive(Default)] +7357struct SentFrames { +7358 retransmits: ThinRetransmits, +7359 /// The packet number of the largest acknowledged packet for each path +7360 largest_acked: FxHashMap<PathId, u64>, +7361 stream_frames: StreamMetaVec, +7362 /// Whether the packet contains non-retransmittable frames (like datagrams) +7363 non_retransmits: bool, +7364 /// If the datagram containing these frames should be padded to the min MTU +7365 requires_padding: bool, +7366} +7367 +7368impl SentFrames { +7369 /// Returns whether the packet contains only ACKs +7370 fn is_ack_only(&self, streams: &StreamsState) -> bool { +7371 !self.largest_acked.is_empty() +7372 && !self.non_retransmits +7373 && self.stream_frames.is_empty() +7374 && self.retransmits.is_empty(streams) +7375 } +7376 +7377 fn retransmits_mut(&mut self) -> &mut Retransmits { +7378 self.retransmits.get_or_create() +7379 } 7380 -7381 ObservedAddr(_) => self.retransmits_mut().observed_addr = true, -7382 Ping(_) => self.non_retransmits = true, -7383 ImmediateAck(_) => self.non_retransmits = true, -7384 AckFrequency(_) => self.retransmits_mut().ack_frequency = true, -7385 PathChallenge(_) => self.non_retransmits = true, -7386 Crypto(crypto) => self.retransmits_mut().crypto.push_back(crypto), -7387 PathAbandon(path_abandon) => { -7388 self.retransmits_mut() -7389 .path_abandon -7390 .entry(path_abandon.path_id) -7391 .or_insert(path_abandon.error_code); -7392 } -7393 PathStatusAvailable(frame::PathStatusAvailable { path_id, .. }) -7394 | PathStatusBackup(frame::PathStatusBackup { path_id, .. }) => { -7395 self.retransmits_mut().path_status.insert(path_id); -7396 } -7397 MaxPathId(_) => self.retransmits_mut().max_path_id = true, -7398 PathsBlocked(_) => self.retransmits_mut().paths_blocked = true, -7399 PathCidsBlocked(path_cids_blocked) => { -7400 self.retransmits_mut() -7401 .path_cids_blocked -7402 .insert(path_cids_blocked.path_id); -7403 } -7404 ResetStream(reset) => self -7405 .retransmits_mut() -7406 .reset_stream -7407 .push((reset.id, reset.error_code)), -7408 StopSending(stop_sending) => self.retransmits_mut().stop_sending.push(stop_sending), -7409 NewConnectionId(new_cid) => self.retransmits_mut().new_cids.push(new_cid.issued()), -7410 RetireConnectionId(retire_cid) => self -7411 .retransmits_mut() -7412 .retire_cids -7413 .push((retire_cid.path_id.unwrap_or_default(), retire_cid.sequence)), -7414 Datagram(_) => self.non_retransmits = true, -7415 NewToken(_) => {} -7416 AddAddress(add_address) => { -7417 self.retransmits_mut().add_address.insert(add_address); -7418 } -7419 RemoveAddress(remove_address) => { -7420 self.retransmits_mut().remove_address.insert(remove_address); -7421 } -7422 StreamMeta(stream_meta_encoder) => self.stream_frames.push(stream_meta_encoder.meta), -7423 MaxData(_) => self.retransmits_mut().max_data = true, -7424 MaxStreamData(max) => { -7425 self.retransmits_mut().max_stream_data.insert(max.id); -7426 } -7427 MaxStreams(max_streams) => { -7428 self.retransmits_mut().max_stream_id[max_streams.dir as usize] = true -7429 } -7430 } -7431 } -7432} -7433 -7434/// Compute the negotiated idle timeout based on local and remote max_idle_timeout transport parameters. -7435/// -7436/// 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.> -7437/// -7438/// 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.> -7439/// -7440/// Returns the negotiated idle timeout as a `Duration`, or `None` when both endpoints have opted out of idle timeout. -7441fn negotiate_max_idle_timeout(x: Option<VarInt>, y: Option<VarInt>) -> Option<Duration> { -7442 match (x, y) { -7443 (Some(VarInt(0)) | None, Some(VarInt(0)) | None) => None, -7444 (Some(VarInt(0)) | None, Some(y)) => Some(Duration::from_millis(y.0)), -7445 (Some(x), Some(VarInt(0)) | None) => Some(Duration::from_millis(x.0)), -7446 (Some(x), Some(y)) => Some(Duration::from_millis(cmp::min(x, y).0)), -7447 } -7448} -7449 -7450#[cfg(test)] -7451mod tests { -7452 use super::*; -7453 -7454 #[test] -7455 fn negotiate_max_idle_timeout_commutative() { -7456 let test_params = [ -7457 (None, None, None), -7458 (None, Some(VarInt(0)), None), -7459 (None, Some(VarInt(2)), Some(Duration::from_millis(2))), -7460 (Some(VarInt(0)), Some(VarInt(0)), None), -7461 ( -7462 Some(VarInt(2)), -7463 Some(VarInt(0)), -7464 Some(Duration::from_millis(2)), -7465 ), -7466 ( -7467 Some(VarInt(1)), -7468 Some(VarInt(4)), -7469 Some(Duration::from_millis(1)), -7470 ), -7471 ]; -7472 -7473 for (left, right, result) in test_params { -7474 assert_eq!(negotiate_max_idle_timeout(left, right), result); -7475 assert_eq!(negotiate_max_idle_timeout(right, left), result); -7476 } -7477 } -7478} \ No newline at end of file +7381 fn record_sent_frame(&mut self, frame: frame::EncodableFrame<'_>) { +7382 use frame::EncodableFrame::*; +7383 match frame { +7384 PathAck(path_ack_encoder) => { +7385 if let Some(max) = path_ack_encoder.ranges.max() { +7386 self.largest_acked.insert(path_ack_encoder.path_id, max); +7387 } +7388 } +7389 Ack(ack_encoder) => { +7390 if let Some(max) = ack_encoder.ranges.max() { +7391 self.largest_acked.insert(PathId::ZERO, max); +7392 } +7393 } +7394 Close(_) => { /* non retransmittable, but after this we don't really care */ } +7395 PathResponse(_) => self.non_retransmits = true, +7396 HandshakeDone(_) => self.retransmits_mut().handshake_done = true, +7397 ReachOut(frame::ReachOut { round, ip, port }) => { +7398 let (recorded_round, reach_outs) = self +7399 .retransmits_mut() +7400 .reach_out +7401 .get_or_insert_with(|| (round, FxHashSet::default())); +7402 // Only record reach outs for the current round or a newer than the recorded one. +7403 if *recorded_round == round { +7404 // Same round, simply append. +7405 reach_outs.insert((ip, port)); +7406 } else if *recorded_round < round { +7407 // New round. +7408 *recorded_round = round; +7409 reach_outs.drain(); +7410 reach_outs.insert((ip, port)); +7411 } else { +7412 // ignore old reach out that was sent +7413 } +7414 } +7415 +7416 ObservedAddr(_) => self.retransmits_mut().observed_addr = true, +7417 Ping(_) => self.non_retransmits = true, +7418 ImmediateAck(_) => self.non_retransmits = true, +7419 AckFrequency(_) => self.retransmits_mut().ack_frequency = true, +7420 PathChallenge(_) => self.non_retransmits = true, +7421 Crypto(crypto) => self.retransmits_mut().crypto.push_back(crypto), +7422 PathAbandon(path_abandon) => { +7423 self.retransmits_mut() +7424 .path_abandon +7425 .entry(path_abandon.path_id) +7426 .or_insert(path_abandon.error_code); +7427 } +7428 PathStatusAvailable(frame::PathStatusAvailable { path_id, .. }) +7429 | PathStatusBackup(frame::PathStatusBackup { path_id, .. }) => { +7430 self.retransmits_mut().path_status.insert(path_id); +7431 } +7432 MaxPathId(_) => self.retransmits_mut().max_path_id = true, +7433 PathsBlocked(_) => self.retransmits_mut().paths_blocked = true, +7434 PathCidsBlocked(path_cids_blocked) => { +7435 self.retransmits_mut() +7436 .path_cids_blocked +7437 .insert(path_cids_blocked.path_id); +7438 } +7439 ResetStream(reset) => self +7440 .retransmits_mut() +7441 .reset_stream +7442 .push((reset.id, reset.error_code)), +7443 StopSending(stop_sending) => self.retransmits_mut().stop_sending.push(stop_sending), +7444 NewConnectionId(new_cid) => self.retransmits_mut().new_cids.push(new_cid.issued()), +7445 RetireConnectionId(retire_cid) => self +7446 .retransmits_mut() +7447 .retire_cids +7448 .push((retire_cid.path_id.unwrap_or_default(), retire_cid.sequence)), +7449 Datagram(_) => self.non_retransmits = true, +7450 NewToken(_) => {} +7451 AddAddress(add_address) => { +7452 self.retransmits_mut().add_address.insert(add_address); +7453 } +7454 RemoveAddress(remove_address) => { +7455 self.retransmits_mut().remove_address.insert(remove_address); +7456 } +7457 StreamMeta(stream_meta_encoder) => self.stream_frames.push(stream_meta_encoder.meta), +7458 MaxData(_) => self.retransmits_mut().max_data = true, +7459 MaxStreamData(max) => { +7460 self.retransmits_mut().max_stream_data.insert(max.id); +7461 } +7462 MaxStreams(max_streams) => { +7463 self.retransmits_mut().max_stream_id[max_streams.dir as usize] = true +7464 } +7465 } +7466 } +7467} +7468 +7469/// Compute the negotiated idle timeout based on local and remote max_idle_timeout transport parameters. +7470/// +7471/// 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.> +7472/// +7473/// 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.> +7474/// +7475/// Returns the negotiated idle timeout as a `Duration`, or `None` when both endpoints have opted out of idle timeout. +7476fn negotiate_max_idle_timeout(x: Option<VarInt>, y: Option<VarInt>) -> Option<Duration> { +7477 match (x, y) { +7478 (Some(VarInt(0)) | None, Some(VarInt(0)) | None) => None, +7479 (Some(VarInt(0)) | None, Some(y)) => Some(Duration::from_millis(y.0)), +7480 (Some(x), Some(VarInt(0)) | None) => Some(Duration::from_millis(x.0)), +7481 (Some(x), Some(y)) => Some(Duration::from_millis(cmp::min(x, y).0)), +7482 } +7483} +7484 +7485#[cfg(test)] +7486mod tests { +7487 use super::*; +7488 +7489 #[test] +7490 fn negotiate_max_idle_timeout_commutative() { +7491 let test_params = [ +7492 (None, None, None), +7493 (None, Some(VarInt(0)), None), +7494 (None, Some(VarInt(2)), Some(Duration::from_millis(2))), +7495 (Some(VarInt(0)), Some(VarInt(0)), None), +7496 ( +7497 Some(VarInt(2)), +7498 Some(VarInt(0)), +7499 Some(Duration::from_millis(2)), +7500 ), +7501 ( +7502 Some(VarInt(1)), +7503 Some(VarInt(4)), +7504 Some(Duration::from_millis(1)), +7505 ), +7506 ]; +7507 +7508 for (left, right, result) in test_params { +7509 assert_eq!(negotiate_max_idle_timeout(left, right), result); +7510 assert_eq!(negotiate_max_idle_timeout(right, left), result); +7511 } +7512 } +7513} \ No newline at end of file diff --git a/pr/545/docs/src/noq_proto/connection/timer.rs.html b/pr/545/docs/src/noq_proto/connection/timer.rs.html index 76a9907ce..1ce4d7503 100644 --- a/pr/545/docs/src/noq_proto/connection/timer.rs.html +++ b/pr/545/docs/src/noq_proto/connection/timer.rs.html @@ -155,354 +155,364 @@ 155 self.heap.as_mut().and_then(|h| h.remove(key)) 156 } 157 -158 #[cfg(test)] -159 fn get(&self, key: &K) -> Option<&V> { -160 for (k, v) in self.stack.iter().filter_map(|v| v.as_ref()) { -161 if k == key { -162 return Some(v); -163 } -164 } -165 -166 self.heap.as_ref().and_then(|h| h.get(key)) -167 } -168 -169 fn get_mut(&mut self, key: &K) -> Option<&mut V> { -170 for (k, v) in self.stack.iter_mut().filter_map(|v| v.as_mut()) { -171 if k == key { -172 return Some(v); -173 } -174 } -175 -176 self.heap.as_mut().and_then(|h| h.get_mut(key)) -177 } -178 -179 #[cfg(test)] -180 fn iter(&self) -> impl Iterator<Item = (&K, &V)> { -181 let a = self -182 .stack -183 .iter() -184 .filter_map(|v| v.as_ref().map(|(k, v)| (k, v))); -185 let b = self.heap.iter().flat_map(|h| h.iter()); -186 a.chain(b) -187 } -188 -189 fn values(&self) -> impl Iterator<Item = &V> { -190 let a = self.stack.iter().filter_map(|v| v.as_ref().map(|(_, v)| v)); -191 let b = self.heap.iter().flat_map(|h| h.values()); -192 a.chain(b) -193 } -194 -195 fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> { -196 let a = self -197 .stack -198 .iter_mut() -199 .filter_map(|v| v.as_mut().map(|(k, v)| (&*k, v))); -200 let b = self.heap.iter_mut().flat_map(|h| h.iter_mut()); -201 a.chain(b) -202 } -203 -204 fn retain<F>(&mut self, mut f: F) -205 where -206 F: FnMut(&K, &mut V) -> bool, -207 { -208 let mut to_remove = [false; SIZE]; -209 for (i, el) in self.stack.iter_mut().enumerate() { -210 if let Some((key, value)) = el { -211 to_remove[i] = !f(key, value); -212 } -213 } -214 for (i, to_remove) in to_remove.into_iter().enumerate() { -215 if to_remove { -216 self.stack[i] = None; -217 } -218 } -219 -220 if let Some(ref mut heap) = self.heap { -221 heap.retain(f); -222 } -223 } -224 -225 fn clear(&mut self) { -226 for el in self.stack.iter_mut() { -227 *el = None; -228 } -229 self.heap = None; -230 } -231} -232 -233#[derive(Debug, Clone, Copy, Default)] -234struct PathTimerTable { -235 timers: [Option<Instant>; PathTimer::VALUES.len()], -236} -237 -238impl PathTimerTable { -239 fn set(&mut self, timer: PathTimer, time: Instant) { -240 self.timers[timer as usize] = Some(time); -241 } -242 -243 fn stop(&mut self, timer: PathTimer) { -244 self.timers[timer as usize] = None; -245 } -246 -247 /// Remove the next timer up until `now`, including it -248 fn expire_before(&mut self, now: Instant) -> Option<(PathTimer, Instant)> { -249 for timer in PathTimer::VALUES { -250 if self.timers[timer as usize].is_some() -251 && self.timers[timer as usize].expect("checked") <= now -252 { -253 return self.timers[timer as usize].take().map(|time| (timer, time)); -254 } -255 } -256 -257 None -258 } -259} -260 -261impl TimerTable { -262 /// Sets the timer unconditionally. -263 /// -264 /// If the timer is already set, this will change the timer's value. -265 pub(super) fn set(&mut self, timer: Timer, time: Instant, qlog: QlogSinkWithTime<'_>) { -266 match timer { -267 Timer::Conn(timer) => { -268 self.generic[timer as usize] = Some(time); -269 } -270 Timer::PerPath(path_id, timer) => match self.path_timers.get_mut(&path_id) { -271 None => { -272 let mut table = PathTimerTable::default(); -273 table.set(timer, time); -274 self.path_timers.insert(path_id, table); -275 } -276 Some(table) => { -277 table.set(timer, time); +158 fn get(&self, key: &K) -> Option<&V> { +159 for (k, v) in self.stack.iter().filter_map(|v| v.as_ref()) { +160 if k == key { +161 return Some(v); +162 } +163 } +164 +165 self.heap.as_ref().and_then(|h| h.get(key)) +166 } +167 +168 fn get_mut(&mut self, key: &K) -> Option<&mut V> { +169 for (k, v) in self.stack.iter_mut().filter_map(|v| v.as_mut()) { +170 if k == key { +171 return Some(v); +172 } +173 } +174 +175 self.heap.as_mut().and_then(|h| h.get_mut(key)) +176 } +177 +178 #[cfg(test)] +179 fn iter(&self) -> impl Iterator<Item = (&K, &V)> { +180 let a = self +181 .stack +182 .iter() +183 .filter_map(|v| v.as_ref().map(|(k, v)| (k, v))); +184 let b = self.heap.iter().flat_map(|h| h.iter()); +185 a.chain(b) +186 } +187 +188 fn values(&self) -> impl Iterator<Item = &V> { +189 let a = self.stack.iter().filter_map(|v| v.as_ref().map(|(_, v)| v)); +190 let b = self.heap.iter().flat_map(|h| h.values()); +191 a.chain(b) +192 } +193 +194 fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> { +195 let a = self +196 .stack +197 .iter_mut() +198 .filter_map(|v| v.as_mut().map(|(k, v)| (&*k, v))); +199 let b = self.heap.iter_mut().flat_map(|h| h.iter_mut()); +200 a.chain(b) +201 } +202 +203 fn retain<F>(&mut self, mut f: F) +204 where +205 F: FnMut(&K, &mut V) -> bool, +206 { +207 let mut to_remove = [false; SIZE]; +208 for (i, el) in self.stack.iter_mut().enumerate() { +209 if let Some((key, value)) = el { +210 to_remove[i] = !f(key, value); +211 } +212 } +213 for (i, to_remove) in to_remove.into_iter().enumerate() { +214 if to_remove { +215 self.stack[i] = None; +216 } +217 } +218 +219 if let Some(ref mut heap) = self.heap { +220 heap.retain(f); +221 } +222 } +223 +224 fn clear(&mut self) { +225 for el in self.stack.iter_mut() { +226 *el = None; +227 } +228 self.heap = None; +229 } +230} +231 +232#[derive(Debug, Clone, Copy, Default)] +233struct PathTimerTable { +234 timers: [Option<Instant>; PathTimer::VALUES.len()], +235} +236 +237impl PathTimerTable { +238 fn set(&mut self, timer: PathTimer, time: Instant) { +239 self.timers[timer as usize] = Some(time); +240 } +241 +242 fn get(&self, timer: PathTimer) -> Option<Instant> { +243 self.timers[timer as usize] +244 } +245 +246 fn stop(&mut self, timer: PathTimer) { +247 self.timers[timer as usize] = None; +248 } +249 +250 /// Remove the next timer up until `now`, including it +251 fn expire_before(&mut self, now: Instant) -> Option<(PathTimer, Instant)> { +252 for timer in PathTimer::VALUES { +253 if self.timers[timer as usize].is_some() +254 && self.timers[timer as usize].expect("checked") <= now +255 { +256 return self.timers[timer as usize].take().map(|time| (timer, time)); +257 } +258 } +259 +260 None +261 } +262} +263 +264impl TimerTable { +265 /// Sets the timer unconditionally. +266 /// +267 /// If the timer is already set, this will change the timer's value. +268 pub(super) fn set(&mut self, timer: Timer, time: Instant, qlog: QlogSinkWithTime<'_>) { +269 match timer { +270 Timer::Conn(timer) => { +271 self.generic[timer as usize] = Some(time); +272 } +273 Timer::PerPath(path_id, timer) => match self.path_timers.get_mut(&path_id) { +274 None => { +275 let mut table = PathTimerTable::default(); +276 table.set(timer, time); +277 self.path_timers.insert(path_id, table); 278 } -279 }, -280 } -281 qlog.emit_timer_set(timer, time); -282 } -283 -284 pub(super) fn set_or_stop( -285 &mut self, -286 timer: Timer, -287 time: Option<Instant>, -288 qlog: QlogSinkWithTime<'_>, -289 ) { -290 match time { -291 Some(time) => self.set(timer, time, qlog), -292 None => self.stop(timer, qlog), -293 } -294 } -295 -296 pub(super) fn stop(&mut self, timer: Timer, qlog: QlogSinkWithTime<'_>) { -297 match timer { -298 Timer::Conn(timer) => { -299 self.generic[timer as usize] = None; -300 } -301 Timer::PerPath(path_id, timer) => { -302 if let Some(e) = self.path_timers.get_mut(&path_id) { -303 e.stop(timer); -304 } -305 } -306 } -307 qlog.emit_timer_stop(timer); -308 } -309 -310 /// Stops all per-path timers -311 pub(super) fn stop_per_path(&mut self, path_id: PathId, qlog: QlogSinkWithTime<'_>) { -312 for timer in PathTimer::VALUES { -313 if let Some(e) = self.path_timers.get_mut(&path_id) { -314 e.stop(timer); -315 qlog.emit_timer_stop(Timer::PerPath(path_id, timer)); -316 } -317 } +279 Some(table) => { +280 table.set(timer, time); +281 } +282 }, +283 } +284 qlog.emit_timer_set(timer, time); +285 } +286 +287 pub(super) fn get(&self, timer: Timer) -> Option<Instant> { +288 match timer { +289 Timer::Conn(timer) => self.generic[timer as usize], +290 Timer::PerPath(path_id, timer) => self.path_timers.get(&path_id)?.get(timer), +291 } +292 } +293 +294 pub(super) fn set_or_stop( +295 &mut self, +296 timer: Timer, +297 time: Option<Instant>, +298 qlog: QlogSinkWithTime<'_>, +299 ) { +300 match time { +301 Some(time) => self.set(timer, time, qlog), +302 None => self.stop(timer, qlog), +303 } +304 } +305 +306 pub(super) fn stop(&mut self, timer: Timer, qlog: QlogSinkWithTime<'_>) { +307 match timer { +308 Timer::Conn(timer) => { +309 self.generic[timer as usize] = None; +310 } +311 Timer::PerPath(path_id, timer) => { +312 if let Some(e) = self.path_timers.get_mut(&path_id) { +313 e.stop(timer); +314 } +315 } +316 } +317 qlog.emit_timer_stop(timer); 318 } 319 -320 /// Get the next queued timeout -321 pub(super) fn peek(&mut self) -> Option<Instant> { -322 // TODO: this is currently linear in the number of paths -323 -324 let min_generic = self.generic.iter().filter_map(|&x| x).min(); -325 let min_path = self -326 .path_timers -327 .values() -328 .flat_map(|p| p.timers.iter().filter_map(|&x| x)) -329 .min(); -330 -331 match (min_generic, min_path) { -332 (None, None) => None, -333 (Some(val), None) => Some(val), -334 (Some(a), Some(b)) => Some(a.min(b)), -335 (None, Some(val)) => Some(val), -336 } -337 } -338 -339 /// Remove the next timer up until `now`, including it -340 pub(super) fn expire_before( -341 &mut self, -342 now: Instant, -343 qlog: &QlogSink, -344 ) -> Option<(Timer, Instant)> { -345 let (timer, instant) = self.expire_before_inner(now)?; -346 qlog.with_time(now).emit_timer_expire(timer); -347 Some((timer, instant)) -348 } -349 -350 fn expire_before_inner(&mut self, now: Instant) -> Option<(Timer, Instant)> { -351 // TODO: this is currently linear in the number of paths -352 -353 for timer in ConnTimer::VALUES { -354 if self.generic[timer as usize].is_some() -355 && self.generic[timer as usize].expect("checked") <= now -356 { -357 return self.generic[timer as usize] -358 .take() -359 .map(|time| (Timer::Conn(timer), time)); -360 } -361 } +320 /// Stops all per-path timers +321 pub(super) fn stop_per_path(&mut self, path_id: PathId, qlog: QlogSinkWithTime<'_>) { +322 for timer in PathTimer::VALUES { +323 if let Some(e) = self.path_timers.get_mut(&path_id) { +324 e.stop(timer); +325 qlog.emit_timer_stop(Timer::PerPath(path_id, timer)); +326 } +327 } +328 } +329 +330 /// Get the next queued timeout +331 pub(super) fn peek(&mut self) -> Option<Instant> { +332 // TODO: this is currently linear in the number of paths +333 +334 let min_generic = self.generic.iter().filter_map(|&x| x).min(); +335 let min_path = self +336 .path_timers +337 .values() +338 .flat_map(|p| p.timers.iter().filter_map(|&x| x)) +339 .min(); +340 +341 match (min_generic, min_path) { +342 (None, None) => None, +343 (Some(val), None) => Some(val), +344 (Some(a), Some(b)) => Some(a.min(b)), +345 (None, Some(val)) => Some(val), +346 } +347 } +348 +349 /// Remove the next timer up until `now`, including it +350 pub(super) fn expire_before( +351 &mut self, +352 now: Instant, +353 qlog: &QlogSink, +354 ) -> Option<(Timer, Instant)> { +355 let (timer, instant) = self.expire_before_inner(now)?; +356 qlog.with_time(now).emit_timer_expire(timer); +357 Some((timer, instant)) +358 } +359 +360 fn expire_before_inner(&mut self, now: Instant) -> Option<(Timer, Instant)> { +361 // TODO: this is currently linear in the number of paths 362 -363 let mut res = None; -364 for (path_id, timers) in self.path_timers.iter_mut() { -365 if let Some((timer, time)) = timers.expire_before(now) { -366 res = Some((Timer::PerPath(*path_id, timer), time)); -367 break; -368 } -369 } -370 -371 // clear out old timers -372 self.path_timers -373 .retain(|_path_id, timers| timers.timers.iter().any(|t| t.is_some())); -374 res -375 } -376 -377 pub(super) fn reset(&mut self) { -378 for timer in ConnTimer::VALUES { -379 self.generic[timer as usize] = None; -380 } -381 self.path_timers.clear(); -382 } -383 -384 #[cfg(test)] -385 pub(super) fn values(&self) -> Vec<(Timer, Instant)> { -386 let mut values = Vec::new(); -387 +363 for timer in ConnTimer::VALUES { +364 if self.generic[timer as usize].is_some() +365 && self.generic[timer as usize].expect("checked") <= now +366 { +367 return self.generic[timer as usize] +368 .take() +369 .map(|time| (Timer::Conn(timer), time)); +370 } +371 } +372 +373 let mut res = None; +374 for (path_id, timers) in self.path_timers.iter_mut() { +375 if let Some((timer, time)) = timers.expire_before(now) { +376 res = Some((Timer::PerPath(*path_id, timer), time)); +377 break; +378 } +379 } +380 +381 // clear out old timers +382 self.path_timers +383 .retain(|_path_id, timers| timers.timers.iter().any(|t| t.is_some())); +384 res +385 } +386 +387 pub(super) fn reset(&mut self) { 388 for timer in ConnTimer::VALUES { -389 if let Some(time) = self.generic[timer as usize] { -390 values.push((Timer::Conn(timer), time)); -391 } -392 } +389 self.generic[timer as usize] = None; +390 } +391 self.path_timers.clear(); +392 } 393 -394 for timer in PathTimer::VALUES { -395 for (path_id, timers) in self.path_timers.iter() { -396 if let Some(time) = timers.timers[timer as usize] { -397 values.push((Timer::PerPath(*path_id, timer), time)); -398 } -399 } -400 } -401 -402 values -403 } -404} -405 -406#[cfg(test)] -407mod tests { -408 use std::time::Duration; -409 -410 use crate::connection::qlog::QlogSink; +394 #[cfg(test)] +395 pub(super) fn values(&self) -> Vec<(Timer, Instant)> { +396 let mut values = Vec::new(); +397 +398 for timer in ConnTimer::VALUES { +399 if let Some(time) = self.generic[timer as usize] { +400 values.push((Timer::Conn(timer), time)); +401 } +402 } +403 +404 for timer in PathTimer::VALUES { +405 for (path_id, timers) in self.path_timers.iter() { +406 if let Some(time) = timers.timers[timer as usize] { +407 values.push((Timer::PerPath(*path_id, timer), time)); +408 } +409 } +410 } 411 -412 use super::*; -413 -414 #[test] -415 fn timer_table() { -416 let mut timers = TimerTable::default(); -417 let sec = Duration::from_secs(1); -418 let now = Instant::now() + Duration::from_secs(10); -419 timers.set( -420 Timer::Conn(ConnTimer::Idle), -421 now - 3 * sec, -422 QlogSink::default().with_time(now), -423 ); -424 timers.set( -425 Timer::Conn(ConnTimer::Close), -426 now - 2 * sec, -427 QlogSink::default().with_time(now), -428 ); -429 -430 assert_eq!(timers.peek(), Some(now - 3 * sec)); -431 assert_eq!( -432 timers.expire_before(now, &QlogSink::default()), -433 Some((Timer::Conn(ConnTimer::Idle), now - 3 * sec)) -434 ); -435 assert_eq!( -436 timers.expire_before(now, &QlogSink::default()), -437 Some((Timer::Conn(ConnTimer::Close), now - 2 * sec)) +412 values +413 } +414} +415 +416#[cfg(test)] +417mod tests { +418 use std::time::Duration; +419 +420 use crate::connection::qlog::QlogSink; +421 +422 use super::*; +423 +424 #[test] +425 fn timer_table() { +426 let mut timers = TimerTable::default(); +427 let sec = Duration::from_secs(1); +428 let now = Instant::now() + Duration::from_secs(10); +429 timers.set( +430 Timer::Conn(ConnTimer::Idle), +431 now - 3 * sec, +432 QlogSink::default().with_time(now), +433 ); +434 timers.set( +435 Timer::Conn(ConnTimer::Close), +436 now - 2 * sec, +437 QlogSink::default().with_time(now), 438 ); -439 assert_eq!(timers.expire_before(now, &QlogSink::default()), None); -440 } -441 -442 #[test] -443 fn test_small_map() { -444 let mut map = SmallMap::<usize, usize, 2>::default(); -445 -446 // inserts only on the stack -447 assert_eq!(map.insert(1, 1), None); -448 assert!(map.heap.is_none()); -449 assert_eq!(map.insert(2, 2), None); -450 assert!(map.heap.is_none()); +439 +440 assert_eq!(timers.peek(), Some(now - 3 * sec)); +441 assert_eq!( +442 timers.expire_before(now, &QlogSink::default()), +443 Some((Timer::Conn(ConnTimer::Idle), now - 3 * sec)) +444 ); +445 assert_eq!( +446 timers.expire_before(now, &QlogSink::default()), +447 Some((Timer::Conn(ConnTimer::Close), now - 2 * sec)) +448 ); +449 assert_eq!(timers.expire_before(now, &QlogSink::default()), None); +450 } 451 -452 // replace on the stack -453 assert_eq!(map.insert(1, 2), Some(1)); -454 -455 assert_eq!(map.remove(&1), Some(2)); -456 assert_eq!(map.insert(3, 3), None); -457 assert!(map.heap.is_none()); -458 -459 // spill -460 assert_eq!(map.insert(4, 4), None); -461 assert!(map.heap.is_some()); -462 -463 assert_eq!( -464 map.iter() -465 .map(|(&a, &b)| (a, b)) -466 .collect::<Vec<(usize, usize)>>(), -467 vec![(3, 3), (2, 2), (4, 4)] -468 ); -469 assert_eq!( -470 map.iter() -471 .map(|(a, b)| (*a, *b)) -472 .collect::<Vec<(usize, usize)>>(), -473 map.iter_mut() -474 .map(|(a, b)| (*a, *b)) -475 .collect::<Vec<(usize, usize)>>(), -476 ); -477 -478 assert_eq!(map.heap.as_ref().unwrap().len(), 1); -479 -480 for i in 0..10 { -481 map.insert(10 + i, 10 + i); -482 } -483 assert_eq!(map.heap.as_ref().unwrap().len(), 11); -484 map.retain(|k, _v| *k < 10); -485 -486 assert_eq!(map.heap.as_ref().unwrap().len(), 1); +452 #[test] +453 fn test_small_map() { +454 let mut map = SmallMap::<usize, usize, 2>::default(); +455 +456 // inserts only on the stack +457 assert_eq!(map.insert(1, 1), None); +458 assert!(map.heap.is_none()); +459 assert_eq!(map.insert(2, 2), None); +460 assert!(map.heap.is_none()); +461 +462 // replace on the stack +463 assert_eq!(map.insert(1, 2), Some(1)); +464 +465 assert_eq!(map.remove(&1), Some(2)); +466 assert_eq!(map.insert(3, 3), None); +467 assert!(map.heap.is_none()); +468 +469 // spill +470 assert_eq!(map.insert(4, 4), None); +471 assert!(map.heap.is_some()); +472 +473 assert_eq!( +474 map.iter() +475 .map(|(&a, &b)| (a, b)) +476 .collect::<Vec<(usize, usize)>>(), +477 vec![(3, 3), (2, 2), (4, 4)] +478 ); +479 assert_eq!( +480 map.iter() +481 .map(|(a, b)| (*a, *b)) +482 .collect::<Vec<(usize, usize)>>(), +483 map.iter_mut() +484 .map(|(a, b)| (*a, *b)) +485 .collect::<Vec<(usize, usize)>>(), +486 ); 487 -488 assert_eq!( -489 map.iter() -490 .map(|(&a, &b)| (a, b)) -491 .collect::<Vec<(usize, usize)>>(), -492 vec![(3, 3), (2, 2), (4, 4)] -493 ); -494 -495 assert_eq!( -496 map.iter() -497 .map(|(a, b)| (*a, *b)) -498 .collect::<Vec<(usize, usize)>>(), -499 map.iter_mut() -500 .map(|(a, b)| (*a, *b)) +488 assert_eq!(map.heap.as_ref().unwrap().len(), 1); +489 +490 for i in 0..10 { +491 map.insert(10 + i, 10 + i); +492 } +493 assert_eq!(map.heap.as_ref().unwrap().len(), 11); +494 map.retain(|k, _v| *k < 10); +495 +496 assert_eq!(map.heap.as_ref().unwrap().len(), 1); +497 +498 assert_eq!( +499 map.iter() +500 .map(|(&a, &b)| (a, b)) 501 .collect::<Vec<(usize, usize)>>(), -502 ); -503 -504 map.clear(); -505 assert_eq!(map.iter().collect::<Vec<_>>(), Vec::new()); -506 assert!(map.heap.is_none()); -507 } -508} \ No newline at end of file +502 vec![(3, 3), (2, 2), (4, 4)] +503 ); +504 +505 assert_eq!( +506 map.iter() +507 .map(|(a, b)| (*a, *b)) +508 .collect::<Vec<(usize, usize)>>(), +509 map.iter_mut() +510 .map(|(a, b)| (*a, *b)) +511 .collect::<Vec<(usize, usize)>>(), +512 ); +513 +514 map.clear(); +515 assert_eq!(map.iter().collect::<Vec<_>>(), Vec::new()); +516 assert!(map.heap.is_none()); +517 } +518} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/clone/trait.Clone.js b/pr/545/docs/trait.impl/core/clone/trait.Clone.js index 8235b9c43..37e224391 100644 --- a/pr/545/docs/trait.impl/core/clone/trait.Clone.js +++ b/pr/545/docs/trait.impl/core/clone/trait.Clone.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl Clone for CipherSuite"],["impl Clone for RuntimeType"],["impl Clone for Opt"]]],["noq",[["impl Clone for ReadError"],["impl Clone for ReadExactError"],["impl Clone for ReadToEndError"],["impl Clone for ResetError"],["impl Clone for SendDatagramError"],["impl Clone for StoppedError"],["impl Clone for WriteError"],["impl Clone for Connection"],["impl Clone for Endpoint"],["impl Clone for EndpointStats"],["impl Clone for Path"],["impl Clone for WeakConnectionHandle"],["impl Clone for WeakPathHandle"]]],["noq_proto",[["impl Clone for ClosePathError"],["impl Clone for ConfigError"],["impl Clone for ConnectError"],["impl Clone for ConnectionError"],["impl Clone for Dir"],["impl Clone for EcnCodepoint"],["impl Clone for FinishError"],["impl Clone for FrameType"],["impl Clone for LongType"],["impl Clone for MaybeFrame"],["impl Clone for PacketDecodeError"],["impl Clone for PathAbandonReason"],["impl Clone for PathError"],["impl Clone for PathEvent"],["impl Clone for PathStatus"],["impl Clone for ProtectedHeader"],["impl Clone for ReadError"],["impl Clone for ReadableError"],["impl Clone for SendDatagramError"],["impl Clone for SetPathStatusError"],["impl Clone for Side"],["impl Clone for WriteError"],["impl Clone for Event"],["impl Clone for Error"],["impl Clone for UnexpectedEnd"],["impl Clone for Bbr"],["impl Clone for BbrConfig"],["impl Clone for Cubic"],["impl Clone for CubicConfig"],["impl Clone for NewReno"],["impl Clone for NewRenoConfig"],["impl Clone for NoInitialCipherSuite"],["impl Clone for QuicClientConfig"],["impl Clone for QuicServerConfig"],["impl Clone for AckFrequencyConfig"],["impl Clone for ApplicationClose"],["impl Clone for ClientConfig"],["impl Clone for ClosedPath"],["impl Clone for ClosedStream"],["impl Clone for ConnectionClose"],["impl Clone for ConnectionHandle"],["impl Clone for ConnectionId"],["impl Clone for ConnectionStats"],["impl Clone for Datagram"],["impl Clone for DatagramInfo"],["impl Clone for EndpointConfig"],["impl Clone for FourTuple"],["impl Clone for FrameStats"],["impl Clone for IdleTimeout"],["impl Clone for InvalidCid"],["impl Clone for MtuDiscoveryConfig"],["impl Clone for MultipathNotNegotiated"],["impl Clone for PathId"],["impl Clone for PathStats"],["impl Clone for ProtectedInitialHeader"],["impl Clone for RandomConnectionIdGenerator"],["impl Clone for RttEstimator"],["impl Clone for ServerConfig"],["impl Clone for ShouldTransmit"],["impl Clone for StreamId"],["impl Clone for StreamInfo"],["impl Clone for TransportConfig"],["impl Clone for Error"],["impl Clone for Code"],["impl Clone for UdpStats"],["impl Clone for ValidationTokenConfig"],["impl Clone for VarInt"],["impl Clone for VarIntBoundsExceeded"],["impl Clone for Written"],["impl Clone for TransportParameters"]]],["noq_udp",[["impl Clone for EcnCodepoint"],["impl Clone for RecvMeta"],["impl<'a> Clone for Transmit<'a>"]]],["perf",[["impl Clone for CongestionAlgorithm"],["impl Clone for NoProtectionClientConfig"],["impl Clone for NoProtectionServerConfig"],["impl Clone for OpenStreamStats"]]]]); + var implementors = Object.fromEntries([["bench",[["impl Clone for CipherSuite"],["impl Clone for RuntimeType"],["impl Clone for Opt"]]],["noq",[["impl Clone for ReadError"],["impl Clone for ReadExactError"],["impl Clone for ReadToEndError"],["impl Clone for ResetError"],["impl Clone for SendDatagramError"],["impl Clone for StoppedError"],["impl Clone for WriteError"],["impl Clone for Connection"],["impl Clone for Endpoint"],["impl Clone for EndpointStats"],["impl Clone for Lagged"],["impl Clone for Path"],["impl Clone for WeakConnectionHandle"],["impl Clone for WeakPathHandle"]]],["noq_proto",[["impl Clone for ClosePathError"],["impl Clone for ConfigError"],["impl Clone for ConnectError"],["impl Clone for ConnectionError"],["impl Clone for Dir"],["impl Clone for EcnCodepoint"],["impl Clone for FinishError"],["impl Clone for FrameType"],["impl Clone for LongType"],["impl Clone for MaybeFrame"],["impl Clone for PacketDecodeError"],["impl Clone for PathAbandonReason"],["impl Clone for PathError"],["impl Clone for PathEvent"],["impl Clone for PathStatus"],["impl Clone for ProtectedHeader"],["impl Clone for ReadError"],["impl Clone for ReadableError"],["impl Clone for SendDatagramError"],["impl Clone for SetPathStatusError"],["impl Clone for Side"],["impl Clone for WriteError"],["impl Clone for Event"],["impl Clone for Error"],["impl Clone for UnexpectedEnd"],["impl Clone for Bbr"],["impl Clone for BbrConfig"],["impl Clone for Cubic"],["impl Clone for CubicConfig"],["impl Clone for NewReno"],["impl Clone for NewRenoConfig"],["impl Clone for NoInitialCipherSuite"],["impl Clone for QuicClientConfig"],["impl Clone for QuicServerConfig"],["impl Clone for AckFrequencyConfig"],["impl Clone for ApplicationClose"],["impl Clone for ClientConfig"],["impl Clone for ClosedPath"],["impl Clone for ClosedStream"],["impl Clone for ConnectionClose"],["impl Clone for ConnectionHandle"],["impl Clone for ConnectionId"],["impl Clone for ConnectionStats"],["impl Clone for Datagram"],["impl Clone for DatagramInfo"],["impl Clone for EndpointConfig"],["impl Clone for FourTuple"],["impl Clone for FrameStats"],["impl Clone for IdleTimeout"],["impl Clone for InvalidCid"],["impl Clone for MtuDiscoveryConfig"],["impl Clone for MultipathNotNegotiated"],["impl Clone for PathId"],["impl Clone for PathStats"],["impl Clone for ProtectedInitialHeader"],["impl Clone for RandomConnectionIdGenerator"],["impl Clone for RttEstimator"],["impl Clone for ServerConfig"],["impl Clone for ShouldTransmit"],["impl Clone for StreamId"],["impl Clone for StreamInfo"],["impl Clone for TransportConfig"],["impl Clone for Error"],["impl Clone for Code"],["impl Clone for UdpStats"],["impl Clone for ValidationTokenConfig"],["impl Clone for VarInt"],["impl Clone for VarIntBoundsExceeded"],["impl Clone for Written"],["impl Clone for TransportParameters"]]],["noq_udp",[["impl Clone for EcnCodepoint"],["impl Clone for RecvMeta"],["impl<'a> Clone for Transmit<'a>"]]],["perf",[["impl Clone for CongestionAlgorithm"],["impl Clone for NoProtectionClientConfig"],["impl Clone for NoProtectionServerConfig"],["impl Clone for OpenStreamStats"]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[752,3319,19185,802,1214]} \ No newline at end of file +//{"start":57,"fragment_lengths":[752,3559,19185,802,1214]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/cmp/trait.Eq.js b/pr/545/docs/trait.impl/core/cmp/trait.Eq.js index a01545a18..b04d56555 100644 --- a/pr/545/docs/trait.impl/core/cmp/trait.Eq.js +++ b/pr/545/docs/trait.impl/core/cmp/trait.Eq.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl Eq for CipherSuite"]]],["noq",[["impl Eq for ReadError"],["impl Eq for ReadExactError"],["impl Eq for ReadToEndError"],["impl Eq for ResetError"],["impl Eq for SendDatagramError"],["impl Eq for StoppedError"],["impl Eq for WriteError"],["impl Eq for WeakPathHandle"]]],["noq_proto",[["impl Eq for ClosePathError"],["impl Eq for ConfigError"],["impl Eq for ConnectError"],["impl Eq for ConnectionError"],["impl Eq for Dir"],["impl Eq for EcnCodepoint"],["impl Eq for FinishError"],["impl Eq for FrameType"],["impl Eq for LongType"],["impl Eq for MaybeFrame"],["impl Eq for PacketDecodeError"],["impl Eq for PathAbandonReason"],["impl Eq for PathError"],["impl Eq for PathEvent"],["impl Eq for PathStatus"],["impl Eq for ReadError"],["impl Eq for ReadableError"],["impl Eq for SendDatagramError"],["impl Eq for SetPathStatusError"],["impl Eq for Side"],["impl Eq for StreamEvent"],["impl Eq for WriteError"],["impl Eq for Error"],["impl Eq for UnexpectedEnd"],["impl Eq for ExportKeyingMaterialError"],["impl Eq for ApplicationClose"],["impl Eq for Chunk"],["impl Eq for ClosedPath"],["impl Eq for ClosedStream"],["impl Eq for ConnectionClose"],["impl Eq for ConnectionHandle"],["impl Eq for ConnectionId"],["impl Eq for DatagramInfo"],["impl Eq for FourTuple"],["impl Eq for FrameStats"],["impl Eq for IdleTimeout"],["impl Eq for InvalidFrameId"],["impl Eq for PathId"],["impl Eq for PathStats"],["impl Eq for ShouldTransmit"],["impl Eq for StreamId"],["impl Eq for StreamInfo"],["impl Eq for Error"],["impl Eq for Code"],["impl Eq for UdpStats"],["impl Eq for VarInt"],["impl Eq for VarIntBoundsExceeded"],["impl Eq for Written"],["impl Eq for TransportParameters"]]],["noq_udp",[["impl Eq for EcnCodepoint"]]]]); + var implementors = Object.fromEntries([["bench",[["impl Eq for CipherSuite"]]],["noq",[["impl Eq for ReadError"],["impl Eq for ReadExactError"],["impl Eq for ReadToEndError"],["impl Eq for ResetError"],["impl Eq for SendDatagramError"],["impl Eq for StoppedError"],["impl Eq for WriteError"],["impl Eq for Lagged"],["impl Eq for WeakPathHandle"]]],["noq_proto",[["impl Eq for ClosePathError"],["impl Eq for ConfigError"],["impl Eq for ConnectError"],["impl Eq for ConnectionError"],["impl Eq for Dir"],["impl Eq for EcnCodepoint"],["impl Eq for FinishError"],["impl Eq for FrameType"],["impl Eq for LongType"],["impl Eq for MaybeFrame"],["impl Eq for PacketDecodeError"],["impl Eq for PathAbandonReason"],["impl Eq for PathError"],["impl Eq for PathEvent"],["impl Eq for PathStatus"],["impl Eq for ReadError"],["impl Eq for ReadableError"],["impl Eq for SendDatagramError"],["impl Eq for SetPathStatusError"],["impl Eq for Side"],["impl Eq for StreamEvent"],["impl Eq for WriteError"],["impl Eq for Error"],["impl Eq for UnexpectedEnd"],["impl Eq for ExportKeyingMaterialError"],["impl Eq for ApplicationClose"],["impl Eq for Chunk"],["impl Eq for ClosedPath"],["impl Eq for ClosedStream"],["impl Eq for ConnectionClose"],["impl Eq for ConnectionHandle"],["impl Eq for ConnectionId"],["impl Eq for DatagramInfo"],["impl Eq for FourTuple"],["impl Eq for FrameStats"],["impl Eq for IdleTimeout"],["impl Eq for InvalidFrameId"],["impl Eq for PathId"],["impl Eq for PathStats"],["impl Eq for ShouldTransmit"],["impl Eq for StreamId"],["impl Eq for StreamInfo"],["impl Eq for Error"],["impl Eq for Code"],["impl Eq for UdpStats"],["impl Eq for VarInt"],["impl Eq for VarIntBoundsExceeded"],["impl Eq for Written"],["impl Eq for TransportParameters"]]],["noq_udp",[["impl Eq for EcnCodepoint"]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[251,1940,12519,261]} \ No newline at end of file +//{"start":57,"fragment_lengths":[251,2167,12519,261]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/cmp/trait.PartialEq.js b/pr/545/docs/trait.impl/core/cmp/trait.PartialEq.js index fe3b6418b..440d06fcd 100644 --- a/pr/545/docs/trait.impl/core/cmp/trait.PartialEq.js +++ b/pr/545/docs/trait.impl/core/cmp/trait.PartialEq.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl PartialEq for CipherSuite"]]],["noq",[["impl PartialEq for ReadError"],["impl PartialEq for ReadExactError"],["impl PartialEq for ReadToEndError"],["impl PartialEq for ResetError"],["impl PartialEq for SendDatagramError"],["impl PartialEq for StoppedError"],["impl PartialEq for WriteError"],["impl PartialEq for Path"],["impl PartialEq for WeakPathHandle"]]],["noq_proto",[["impl PartialEq for ClosePathError"],["impl PartialEq for ConfigError"],["impl PartialEq for ConnectError"],["impl PartialEq for ConnectionError"],["impl PartialEq for Dir"],["impl PartialEq for EcnCodepoint"],["impl PartialEq for FinishError"],["impl PartialEq for FrameType"],["impl PartialEq for LongType"],["impl PartialEq for MaybeFrame"],["impl PartialEq for PacketDecodeError"],["impl PartialEq for PathAbandonReason"],["impl PartialEq for PathError"],["impl PartialEq for PathEvent"],["impl PartialEq for PathStatus"],["impl PartialEq for ReadError"],["impl PartialEq for ReadableError"],["impl PartialEq for SendDatagramError"],["impl PartialEq for SetPathStatusError"],["impl PartialEq for Side"],["impl PartialEq for StreamEvent"],["impl PartialEq for WriteError"],["impl PartialEq for Error"],["impl PartialEq for UnexpectedEnd"],["impl PartialEq for ExportKeyingMaterialError"],["impl PartialEq for ApplicationClose"],["impl PartialEq for Chunk"],["impl PartialEq for ClosedPath"],["impl PartialEq for ClosedStream"],["impl PartialEq for ConnectionClose"],["impl PartialEq for ConnectionHandle"],["impl PartialEq for ConnectionId"],["impl PartialEq for DatagramInfo"],["impl PartialEq for FourTuple"],["impl PartialEq for FrameStats"],["impl PartialEq for IdleTimeout"],["impl PartialEq for InvalidFrameId"],["impl PartialEq for PathId"],["impl PartialEq for PathStats"],["impl PartialEq for ShouldTransmit"],["impl PartialEq for StreamId"],["impl PartialEq for StreamInfo"],["impl PartialEq for Error"],["impl PartialEq for Code"],["impl PartialEq for UdpStats"],["impl PartialEq for VarInt"],["impl PartialEq for VarIntBoundsExceeded"],["impl PartialEq for Written"],["impl PartialEq for TransportParameters"]]],["noq_udp",[["impl PartialEq for EcnCodepoint"]]]]); + var implementors = Object.fromEntries([["bench",[["impl PartialEq for CipherSuite"]]],["noq",[["impl PartialEq for ReadError"],["impl PartialEq for ReadExactError"],["impl PartialEq for ReadToEndError"],["impl PartialEq for ResetError"],["impl PartialEq for SendDatagramError"],["impl PartialEq for StoppedError"],["impl PartialEq for WriteError"],["impl PartialEq for Lagged"],["impl PartialEq for Path"],["impl PartialEq for WeakPathHandle"]]],["noq_proto",[["impl PartialEq for ClosePathError"],["impl PartialEq for ConfigError"],["impl PartialEq for ConnectError"],["impl PartialEq for ConnectionError"],["impl PartialEq for Dir"],["impl PartialEq for EcnCodepoint"],["impl PartialEq for FinishError"],["impl PartialEq for FrameType"],["impl PartialEq for LongType"],["impl PartialEq for MaybeFrame"],["impl PartialEq for PacketDecodeError"],["impl PartialEq for PathAbandonReason"],["impl PartialEq for PathError"],["impl PartialEq for PathEvent"],["impl PartialEq for PathStatus"],["impl PartialEq for ReadError"],["impl PartialEq for ReadableError"],["impl PartialEq for SendDatagramError"],["impl PartialEq for SetPathStatusError"],["impl PartialEq for Side"],["impl PartialEq for StreamEvent"],["impl PartialEq for WriteError"],["impl PartialEq for Error"],["impl PartialEq for UnexpectedEnd"],["impl PartialEq for ExportKeyingMaterialError"],["impl PartialEq for ApplicationClose"],["impl PartialEq for Chunk"],["impl PartialEq for ClosedPath"],["impl PartialEq for ClosedStream"],["impl PartialEq for ConnectionClose"],["impl PartialEq for ConnectionHandle"],["impl PartialEq for ConnectionId"],["impl PartialEq for DatagramInfo"],["impl PartialEq for FourTuple"],["impl PartialEq for FrameStats"],["impl PartialEq for IdleTimeout"],["impl PartialEq for InvalidFrameId"],["impl PartialEq for PathId"],["impl PartialEq for PathStats"],["impl PartialEq for ShouldTransmit"],["impl PartialEq for StreamId"],["impl PartialEq for StreamInfo"],["impl PartialEq for Error"],["impl PartialEq for Code"],["impl PartialEq for UdpStats"],["impl PartialEq for VarInt"],["impl PartialEq for VarIntBoundsExceeded"],["impl PartialEq for Written"],["impl PartialEq for TransportParameters"]]],["noq_udp",[["impl PartialEq for EcnCodepoint"]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[272,2350,13548,282]} \ No newline at end of file +//{"start":57,"fragment_lengths":[272,2598,13548,282]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/error/trait.Error.js b/pr/545/docs/trait.impl/core/error/trait.Error.js index f81818e38..d2884bc31 100644 --- a/pr/545/docs/trait.impl/core/error/trait.Error.js +++ b/pr/545/docs/trait.impl/core/error/trait.Error.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["noq",[["impl Error for ReadError"],["impl Error for ReadExactError"],["impl Error for ReadToEndError"],["impl Error for ResetError"],["impl Error for SendDatagramError"],["impl Error for StoppedError"],["impl Error for WriteError"],["impl Error for RetryError"]]],["noq_proto",[["impl Error for ClosePathError"],["impl Error for ConfigError"],["impl Error for ConnectError"],["impl Error for ConnectionError"],["impl Error for FinishError"],["impl Error for PacketDecodeError"],["impl Error for PathError"],["impl Error for ReadError"],["impl Error for ReadableError"],["impl Error for SendDatagramError"],["impl Error for SetPathStatusError"],["impl Error for WriteError"],["impl Error for Error"],["impl Error for Error"],["impl Error for UnexpectedEnd"],["impl Error for NoInitialCipherSuite"],["impl Error for ClosedPath"],["impl Error for ClosedStream"],["impl Error for InvalidFrameId"],["impl Error for MultipathNotNegotiated"],["impl Error for RetryError"],["impl Error for Error"],["impl Error for VarIntBoundsExceeded"]]]]); + var implementors = Object.fromEntries([["noq",[["impl Error for ReadError"],["impl Error for ReadExactError"],["impl Error for ReadToEndError"],["impl Error for ResetError"],["impl Error for SendDatagramError"],["impl Error for StoppedError"],["impl Error for WriteError"],["impl Error for Lagged"],["impl Error for RetryError"]]],["noq_proto",[["impl Error for ClosePathError"],["impl Error for ConfigError"],["impl Error for ConnectError"],["impl Error for ConnectionError"],["impl Error for FinishError"],["impl Error for PacketDecodeError"],["impl Error for PathError"],["impl Error for ReadError"],["impl Error for ReadableError"],["impl Error for SendDatagramError"],["impl Error for SetPathStatusError"],["impl Error for WriteError"],["impl Error for Error"],["impl Error for Error"],["impl Error for UnexpectedEnd"],["impl Error for NoInitialCipherSuite"],["impl Error for ClosedPath"],["impl Error for ClosedStream"],["impl Error for InvalidFrameId"],["impl Error for MultipathNotNegotiated"],["impl Error for RetryError"],["impl Error for Error"],["impl Error for VarIntBoundsExceeded"]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[2031,6331]} \ No newline at end of file +//{"start":57,"fragment_lengths":[2271,6331]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/fmt/trait.Debug.js b/pr/545/docs/trait.impl/core/fmt/trait.Debug.js index 7f8a8c251..ef9f0a234 100644 --- a/pr/545/docs/trait.impl/core/fmt/trait.Debug.js +++ b/pr/545/docs/trait.impl/core/fmt/trait.Debug.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl Debug for CipherSuite"],["impl Debug for RuntimeType"],["impl Debug for TransferResult"],["impl Debug for Opt"]]],["certificate",[["impl Debug for SkipServerVerification"]]],["noq",[["impl Debug for ReadError"],["impl Debug for ReadExactError"],["impl Debug for ReadToEndError"],["impl Debug for ResetError"],["impl Debug for SendDatagramError"],["impl Debug for StoppedError"],["impl Debug for WriteError"],["impl Debug for Connecting"],["impl Debug for Connection"],["impl Debug for Endpoint"],["impl Debug for EndpointStats"],["impl Debug for Incoming"],["impl Debug for IncomingFuture"],["impl Debug for Path"],["impl Debug for RecvStream"],["impl Debug for RetryError"],["impl Debug for SendStream"],["impl Debug for SmolRuntime"],["impl Debug for Stopped"],["impl Debug for TokioRuntime"],["impl Debug for UnorderedRecvStream"],["impl Debug for WeakConnectionHandle"],["impl Debug for WeakPathHandle"]]],["noq_proto",[["impl Debug for ClosePathError"],["impl Debug for ConfigError"],["impl Debug for ConnectError"],["impl Debug for ConnectionError"],["impl Debug for Dir"],["impl Debug for EcnCodepoint"],["impl Debug for Event"],["impl Debug for FinishError"],["impl Debug for FrameType"],["impl Debug for LongType"],["impl Debug for MaybeFrame"],["impl Debug for PacketDecodeError"],["impl Debug for PathAbandonReason"],["impl Debug for PathError"],["impl Debug for PathEvent"],["impl Debug for PathStatus"],["impl Debug for ProtectedHeader"],["impl Debug for ReadError"],["impl Debug for ReadableError"],["impl Debug for SendDatagramError"],["impl Debug for SetPathStatusError"],["impl Debug for Side"],["impl Debug for StreamEvent"],["impl Debug for WriteError"],["impl Debug for Error"],["impl Debug for Event"],["impl Debug for Error"],["impl Debug for UnexpectedEnd"],["impl Debug for Bbr"],["impl Debug for BbrConfig"],["impl Debug for ControllerMetrics"],["impl Debug for Cubic"],["impl Debug for CubicConfig"],["impl Debug for NewReno"],["impl Debug for NewRenoConfig"],["impl Debug for NoInitialCipherSuite"],["impl Debug for CryptoError"],["impl Debug for ExportKeyingMaterialError"],["impl Debug for UnsupportedVersion"],["impl Debug for AcceptError"],["impl Debug for AckFrequencyConfig"],["impl Debug for ApplicationClose"],["impl Debug for Chunk"],["impl Debug for ClientConfig"],["impl Debug for ClosedPath"],["impl Debug for ClosedStream"],["impl Debug for Connection"],["impl Debug for ConnectionClose"],["impl Debug for ConnectionEvent"],["impl Debug for ConnectionHandle"],["impl Debug for ConnectionId"],["impl Debug for ConnectionStats"],["impl Debug for Datagram"],["impl Debug for DatagramInfo"],["impl Debug for Endpoint"],["impl Debug for EndpointConfig"],["impl Debug for EndpointEvent"],["impl Debug for FourTuple"],["impl Debug for FrameStats"],["impl Debug for IdleTimeout"],["impl Debug for Incoming"],["impl Debug for InvalidCid"],["impl Debug for InvalidFrameId"],["impl Debug for MtuDiscoveryConfig"],["impl Debug for MultipathNotNegotiated"],["impl Debug for PartialDecode"],["impl Debug for PathId"],["impl Debug for PathStats"],["impl Debug for ProtectedInitialHeader"],["impl Debug for QlogFileFactory"],["impl Debug for RandomConnectionIdGenerator"],["impl Debug for RetryError"],["impl Debug for RttEstimator"],["impl Debug for ServerConfig"],["impl Debug for ShouldTransmit"],["impl Debug for StreamId"],["impl Debug for StreamInfo"],["impl Debug for TokenMemoryCache"],["impl Debug for Transmit"],["impl Debug for TransportConfig"],["impl Debug for Error"],["impl Debug for Code"],["impl Debug for UdpStats"],["impl Debug for ValidationTokenConfig"],["impl Debug for VarInt"],["impl Debug for VarIntBoundsExceeded"],["impl Debug for Written"],["impl Debug for TransportParameters"]]],["noq_udp",[["impl Debug for EcnCodepoint"],["impl Debug for RecvMeta"],["impl Debug for UdpSocketState"],["impl<'a> Debug for Transmit<'a>"]]]]); + var implementors = Object.fromEntries([["bench",[["impl Debug for CipherSuite"],["impl Debug for RuntimeType"],["impl Debug for TransferResult"],["impl Debug for Opt"]]],["certificate",[["impl Debug for SkipServerVerification"]]],["noq",[["impl Debug for ReadError"],["impl Debug for ReadExactError"],["impl Debug for ReadToEndError"],["impl Debug for ResetError"],["impl Debug for SendDatagramError"],["impl Debug for StoppedError"],["impl Debug for WriteError"],["impl Debug for Connecting"],["impl Debug for Connection"],["impl Debug for Endpoint"],["impl Debug for EndpointStats"],["impl Debug for Incoming"],["impl Debug for IncomingFuture"],["impl Debug for Lagged"],["impl Debug for NatTraversalUpdates"],["impl Debug for ObservedExternalAddr"],["impl Debug for Path"],["impl Debug for PathEvents"],["impl Debug for RecvStream"],["impl Debug for RetryError"],["impl Debug for SendStream"],["impl Debug for SmolRuntime"],["impl Debug for Stopped"],["impl Debug for TokioRuntime"],["impl Debug for UnorderedRecvStream"],["impl Debug for WeakConnectionHandle"],["impl Debug for WeakPathHandle"]]],["noq_proto",[["impl Debug for ClosePathError"],["impl Debug for ConfigError"],["impl Debug for ConnectError"],["impl Debug for ConnectionError"],["impl Debug for Dir"],["impl Debug for EcnCodepoint"],["impl Debug for Event"],["impl Debug for FinishError"],["impl Debug for FrameType"],["impl Debug for LongType"],["impl Debug for MaybeFrame"],["impl Debug for PacketDecodeError"],["impl Debug for PathAbandonReason"],["impl Debug for PathError"],["impl Debug for PathEvent"],["impl Debug for PathStatus"],["impl Debug for ProtectedHeader"],["impl Debug for ReadError"],["impl Debug for ReadableError"],["impl Debug for SendDatagramError"],["impl Debug for SetPathStatusError"],["impl Debug for Side"],["impl Debug for StreamEvent"],["impl Debug for WriteError"],["impl Debug for Error"],["impl Debug for Event"],["impl Debug for Error"],["impl Debug for UnexpectedEnd"],["impl Debug for Bbr"],["impl Debug for BbrConfig"],["impl Debug for ControllerMetrics"],["impl Debug for Cubic"],["impl Debug for CubicConfig"],["impl Debug for NewReno"],["impl Debug for NewRenoConfig"],["impl Debug for NoInitialCipherSuite"],["impl Debug for CryptoError"],["impl Debug for ExportKeyingMaterialError"],["impl Debug for UnsupportedVersion"],["impl Debug for AcceptError"],["impl Debug for AckFrequencyConfig"],["impl Debug for ApplicationClose"],["impl Debug for Chunk"],["impl Debug for ClientConfig"],["impl Debug for ClosedPath"],["impl Debug for ClosedStream"],["impl Debug for Connection"],["impl Debug for ConnectionClose"],["impl Debug for ConnectionEvent"],["impl Debug for ConnectionHandle"],["impl Debug for ConnectionId"],["impl Debug for ConnectionStats"],["impl Debug for Datagram"],["impl Debug for DatagramInfo"],["impl Debug for Endpoint"],["impl Debug for EndpointConfig"],["impl Debug for EndpointEvent"],["impl Debug for FourTuple"],["impl Debug for FrameStats"],["impl Debug for IdleTimeout"],["impl Debug for Incoming"],["impl Debug for InvalidCid"],["impl Debug for InvalidFrameId"],["impl Debug for MtuDiscoveryConfig"],["impl Debug for MultipathNotNegotiated"],["impl Debug for PartialDecode"],["impl Debug for PathId"],["impl Debug for PathStats"],["impl Debug for ProtectedInitialHeader"],["impl Debug for QlogFileFactory"],["impl Debug for RandomConnectionIdGenerator"],["impl Debug for RetryError"],["impl Debug for RttEstimator"],["impl Debug for ServerConfig"],["impl Debug for ShouldTransmit"],["impl Debug for StreamId"],["impl Debug for StreamInfo"],["impl Debug for TokenMemoryCache"],["impl Debug for Transmit"],["impl Debug for TransportConfig"],["impl Debug for Error"],["impl Debug for Code"],["impl Debug for UdpStats"],["impl Debug for ValidationTokenConfig"],["impl Debug for VarInt"],["impl Debug for VarIntBoundsExceeded"],["impl Debug for Written"],["impl Debug for TransportParameters"]]],["noq_udp",[["impl Debug for EcnCodepoint"],["impl Debug for RecvMeta"],["impl Debug for UdpSocketState"],["impl<'a> Debug for Transmit<'a>"]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[1017,318,5780,23688,1058]} \ No newline at end of file +//{"start":57,"fragment_lengths":[1017,318,6817,23688,1058]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/fmt/trait.Display.js b/pr/545/docs/trait.impl/core/fmt/trait.Display.js index 9da5932e1..98f74d37a 100644 --- a/pr/545/docs/trait.impl/core/fmt/trait.Display.js +++ b/pr/545/docs/trait.impl/core/fmt/trait.Display.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["noq",[["impl Display for ReadError"],["impl Display for ReadExactError"],["impl Display for ReadToEndError"],["impl Display for ResetError"],["impl Display for SendDatagramError"],["impl Display for StoppedError"],["impl Display for WriteError"],["impl Display for RetryError"]]],["noq_proto",[["impl Display for ClosePathError"],["impl Display for ConfigError"],["impl Display for ConnectError"],["impl Display for ConnectionError"],["impl Display for Dir"],["impl Display for FinishError"],["impl Display for FrameType"],["impl Display for MaybeFrame"],["impl Display for PacketDecodeError"],["impl Display for PathError"],["impl Display for ReadError"],["impl Display for ReadableError"],["impl Display for SendDatagramError"],["impl Display for SetPathStatusError"],["impl Display for WriteError"],["impl Display for Error"],["impl Display for Error"],["impl Display for UnexpectedEnd"],["impl Display for NoInitialCipherSuite"],["impl Display for ApplicationClose"],["impl Display for ClosedPath"],["impl Display for ClosedStream"],["impl Display for ConnectionClose"],["impl Display for ConnectionId"],["impl Display for Datagram"],["impl Display for DatagramInfo"],["impl Display for FourTuple"],["impl Display for InvalidFrameId"],["impl Display for MultipathNotNegotiated"],["impl Display for PathId"],["impl Display for RetryError"],["impl Display for StreamId"],["impl Display for StreamInfo"],["impl Display for Error"],["impl Display for Code"],["impl Display for VarInt"],["impl Display for VarIntBoundsExceeded"]]]]); + var implementors = Object.fromEntries([["noq",[["impl Display for ReadError"],["impl Display for ReadExactError"],["impl Display for ReadToEndError"],["impl Display for ResetError"],["impl Display for SendDatagramError"],["impl Display for StoppedError"],["impl Display for WriteError"],["impl Display for Lagged"],["impl Display for RetryError"]]],["noq_proto",[["impl Display for ClosePathError"],["impl Display for ConfigError"],["impl Display for ConnectError"],["impl Display for ConnectionError"],["impl Display for Dir"],["impl Display for FinishError"],["impl Display for FrameType"],["impl Display for MaybeFrame"],["impl Display for PacketDecodeError"],["impl Display for PathError"],["impl Display for ReadError"],["impl Display for ReadableError"],["impl Display for SendDatagramError"],["impl Display for SetPathStatusError"],["impl Display for WriteError"],["impl Display for Error"],["impl Display for Error"],["impl Display for UnexpectedEnd"],["impl Display for NoInitialCipherSuite"],["impl Display for ApplicationClose"],["impl Display for ClosedPath"],["impl Display for ClosedStream"],["impl Display for ConnectionClose"],["impl Display for ConnectionId"],["impl Display for Datagram"],["impl Display for DatagramInfo"],["impl Display for FourTuple"],["impl Display for InvalidFrameId"],["impl Display for MultipathNotNegotiated"],["impl Display for PathId"],["impl Display for RetryError"],["impl Display for StreamId"],["impl Display for StreamInfo"],["impl Display for Error"],["impl Display for Code"],["impl Display for VarInt"],["impl Display for VarIntBoundsExceeded"]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[2047,10075]} \ No newline at end of file +//{"start":57,"fragment_lengths":[2289,10075]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/marker/trait.Freeze.js b/pr/545/docs/trait.impl/core/marker/trait.Freeze.js index f72437c89..5881f0079 100644 --- a/pr/545/docs/trait.impl/core/marker/trait.Freeze.js +++ b/pr/545/docs/trait.impl/core/marker/trait.Freeze.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl Freeze for CipherSuite",1,["bench::CipherSuite"]],["impl Freeze for RuntimeType",1,["bench::RuntimeType"]],["impl Freeze for Stats",1,["bench::stats::Stats"]],["impl Freeze for StreamStats",1,["bench::stats::StreamStats"]],["impl Freeze for TransferResult",1,["bench::stats::TransferResult"]],["impl Freeze for Opt",1,["bench::Opt"]]]],["bulk",[["impl Freeze for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl Freeze for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl !Freeze for ReadError",1,["noq::recv_stream::ReadError"]],["impl !Freeze for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl !Freeze for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl !Freeze for ResetError",1,["noq::recv_stream::ResetError"]],["impl !Freeze for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl !Freeze for StoppedError",1,["noq::send_stream::StoppedError"]],["impl !Freeze for WriteError",1,["noq::send_stream::WriteError"]],["impl !Freeze for Incoming",1,["noq::incoming::Incoming"]],["impl !Freeze for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl !Freeze for Stopped",1,["noq::send_stream::Stopped"]],["impl Freeze for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl Freeze for Connecting",1,["noq::connection::Connecting"]],["impl Freeze for Connection",1,["noq::connection::Connection"]],["impl Freeze for Endpoint",1,["noq::endpoint::Endpoint"]],["impl Freeze for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl Freeze for OnClosed",1,["noq::connection::OnClosed"]],["impl Freeze for OpenPath",1,["noq::path::OpenPath"]],["impl Freeze for Path",1,["noq::path::Path"]],["impl Freeze for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl Freeze for RetryError",1,["noq::incoming::RetryError"]],["impl Freeze for SendStream",1,["noq::send_stream::SendStream"]],["impl Freeze for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl Freeze for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl Freeze for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl Freeze for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl Freeze for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl Freeze for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'a> !Freeze for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> !Freeze for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> !Freeze for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> !Freeze for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> !Freeze for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> !Freeze for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> !Freeze for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl Freeze for Commands",1,["noq_perf::Commands"]],["impl Freeze for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl !Freeze for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl !Freeze for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl !Freeze for Event",1,["noq_proto::connection::Event"]],["impl !Freeze for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl !Freeze for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl !Freeze for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl !Freeze for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl !Freeze for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl !Freeze for Connection",1,["noq_proto::connection::Connection"]],["impl !Freeze for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl !Freeze for Datagram",1,["noq_proto::frame::Datagram"]],["impl !Freeze for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl !Freeze for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl !Freeze for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl !Freeze for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl Freeze for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl Freeze for ConfigError",1,["noq_proto::config::ConfigError"]],["impl Freeze for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl Freeze for Dir",1,["noq_proto::Dir"]],["impl Freeze for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl Freeze for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl Freeze for FrameType",1,["noq_proto::frame::FrameType"]],["impl Freeze for LongType",1,["noq_proto::packet::LongType"]],["impl Freeze for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl Freeze for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl Freeze for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl Freeze for PathError",1,["noq_proto::connection::PathError"]],["impl Freeze for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl Freeze for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl Freeze for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl Freeze for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl Freeze for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl Freeze for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl Freeze for Side",1,["noq_proto::Side"]],["impl Freeze for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl Freeze for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl Freeze for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl Freeze for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl Freeze for Error",1,["noq_proto::transport_parameters::Error"]],["impl Freeze for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl Freeze for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl Freeze for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl Freeze for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl Freeze for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl Freeze for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl Freeze for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl Freeze for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl Freeze for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl Freeze for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl Freeze for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl Freeze for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl Freeze for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl Freeze for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl Freeze for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl Freeze for Keys",1,["noq_proto::crypto::Keys"]],["impl Freeze for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl Freeze for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl Freeze for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl Freeze for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl Freeze for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl Freeze for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl Freeze for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl Freeze for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl Freeze for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl Freeze for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl Freeze for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl Freeze for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl Freeze for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl Freeze for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl Freeze for FourTuple",1,["noq_proto::FourTuple"]],["impl Freeze for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl Freeze for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl Freeze for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl Freeze for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl Freeze for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl Freeze for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl Freeze for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl Freeze for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl Freeze for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl Freeze for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl Freeze for PathId",1,["noq_proto::connection::paths::PathId"]],["impl Freeze for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl Freeze for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl Freeze for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl Freeze for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl Freeze for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl Freeze for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl Freeze for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl Freeze for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl Freeze for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl Freeze for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl Freeze for StreamId",1,["noq_proto::StreamId"]],["impl Freeze for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl Freeze for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl Freeze for Transmit",1,["noq_proto::Transmit"]],["impl Freeze for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl Freeze for Error",1,["noq_proto::transport_error::Error"]],["impl Freeze for Code",1,["noq_proto::transport_error::Code"]],["impl Freeze for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl Freeze for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl Freeze for VarInt",1,["noq_proto::varint::VarInt"]],["impl Freeze for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl Freeze for Written",1,["noq_proto::connection::streams::send::Written"]],["impl Freeze for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> Freeze for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> Freeze for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> Freeze for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> Freeze for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> Freeze for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> Freeze for KeyPair<T>
where\n T: Freeze,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl !Freeze for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl Freeze for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl Freeze for RecvMeta",1,["noq_udp::RecvMeta"]],["impl<'a> Freeze for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> Freeze for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl !Freeze for StreamStats",1,["perf::stats::StreamStats"]],["impl Freeze for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl Freeze for Opt",1,["perf::client::Opt"]],["impl Freeze for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl Freeze for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl Freeze for Opt",1,["perf::server::Opt"]],["impl Freeze for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl Freeze for Stats",1,["perf::stats::Stats"]],["impl Freeze for CommonOpt",1,["perf::CommonOpt"]]]]]); + var implementors = Object.fromEntries([["bench",[["impl Freeze for CipherSuite",1,["bench::CipherSuite"]],["impl Freeze for RuntimeType",1,["bench::RuntimeType"]],["impl Freeze for Stats",1,["bench::stats::Stats"]],["impl Freeze for StreamStats",1,["bench::stats::StreamStats"]],["impl Freeze for TransferResult",1,["bench::stats::TransferResult"]],["impl Freeze for Opt",1,["bench::Opt"]]]],["bulk",[["impl Freeze for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl Freeze for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl !Freeze for ReadError",1,["noq::recv_stream::ReadError"]],["impl !Freeze for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl !Freeze for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl !Freeze for ResetError",1,["noq::recv_stream::ResetError"]],["impl !Freeze for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl !Freeze for StoppedError",1,["noq::send_stream::StoppedError"]],["impl !Freeze for WriteError",1,["noq::send_stream::WriteError"]],["impl !Freeze for Incoming",1,["noq::incoming::Incoming"]],["impl !Freeze for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl !Freeze for Stopped",1,["noq::send_stream::Stopped"]],["impl Freeze for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl Freeze for Connecting",1,["noq::connection::Connecting"]],["impl Freeze for Connection",1,["noq::connection::Connection"]],["impl Freeze for Endpoint",1,["noq::endpoint::Endpoint"]],["impl Freeze for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl Freeze for Lagged",1,["noq::event_stream::Lagged"]],["impl Freeze for NatTraversalUpdates",1,["noq::event_stream::NatTraversalUpdates"]],["impl Freeze for ObservedExternalAddr",1,["noq::event_stream::ObservedExternalAddr"]],["impl Freeze for OnClosed",1,["noq::connection::OnClosed"]],["impl Freeze for OpenPath",1,["noq::path::OpenPath"]],["impl Freeze for Path",1,["noq::path::Path"]],["impl Freeze for PathEvents",1,["noq::event_stream::PathEvents"]],["impl Freeze for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl Freeze for RetryError",1,["noq::incoming::RetryError"]],["impl Freeze for SendStream",1,["noq::send_stream::SendStream"]],["impl Freeze for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl Freeze for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl Freeze for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl Freeze for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl Freeze for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl Freeze for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'a> !Freeze for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> !Freeze for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> !Freeze for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> !Freeze for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> !Freeze for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> !Freeze for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> !Freeze for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl Freeze for Commands",1,["noq_perf::Commands"]],["impl Freeze for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl !Freeze for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl !Freeze for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl !Freeze for Event",1,["noq_proto::connection::Event"]],["impl !Freeze for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl !Freeze for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl !Freeze for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl !Freeze for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl !Freeze for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl !Freeze for Connection",1,["noq_proto::connection::Connection"]],["impl !Freeze for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl !Freeze for Datagram",1,["noq_proto::frame::Datagram"]],["impl !Freeze for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl !Freeze for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl !Freeze for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl !Freeze for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl Freeze for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl Freeze for ConfigError",1,["noq_proto::config::ConfigError"]],["impl Freeze for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl Freeze for Dir",1,["noq_proto::Dir"]],["impl Freeze for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl Freeze for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl Freeze for FrameType",1,["noq_proto::frame::FrameType"]],["impl Freeze for LongType",1,["noq_proto::packet::LongType"]],["impl Freeze for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl Freeze for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl Freeze for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl Freeze for PathError",1,["noq_proto::connection::PathError"]],["impl Freeze for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl Freeze for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl Freeze for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl Freeze for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl Freeze for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl Freeze for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl Freeze for Side",1,["noq_proto::Side"]],["impl Freeze for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl Freeze for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl Freeze for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl Freeze for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl Freeze for Error",1,["noq_proto::transport_parameters::Error"]],["impl Freeze for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl Freeze for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl Freeze for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl Freeze for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl Freeze for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl Freeze for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl Freeze for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl Freeze for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl Freeze for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl Freeze for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl Freeze for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl Freeze for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl Freeze for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl Freeze for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl Freeze for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl Freeze for Keys",1,["noq_proto::crypto::Keys"]],["impl Freeze for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl Freeze for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl Freeze for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl Freeze for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl Freeze for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl Freeze for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl Freeze for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl Freeze for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl Freeze for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl Freeze for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl Freeze for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl Freeze for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl Freeze for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl Freeze for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl Freeze for FourTuple",1,["noq_proto::FourTuple"]],["impl Freeze for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl Freeze for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl Freeze for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl Freeze for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl Freeze for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl Freeze for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl Freeze for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl Freeze for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl Freeze for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl Freeze for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl Freeze for PathId",1,["noq_proto::connection::paths::PathId"]],["impl Freeze for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl Freeze for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl Freeze for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl Freeze for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl Freeze for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl Freeze for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl Freeze for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl Freeze for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl Freeze for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl Freeze for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl Freeze for StreamId",1,["noq_proto::StreamId"]],["impl Freeze for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl Freeze for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl Freeze for Transmit",1,["noq_proto::Transmit"]],["impl Freeze for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl Freeze for Error",1,["noq_proto::transport_error::Error"]],["impl Freeze for Code",1,["noq_proto::transport_error::Code"]],["impl Freeze for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl Freeze for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl Freeze for VarInt",1,["noq_proto::varint::VarInt"]],["impl Freeze for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl Freeze for Written",1,["noq_proto::connection::streams::send::Written"]],["impl Freeze for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> Freeze for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> Freeze for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> Freeze for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> Freeze for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> Freeze for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> Freeze for KeyPair<T>
where\n T: Freeze,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl !Freeze for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl Freeze for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl Freeze for RecvMeta",1,["noq_udp::RecvMeta"]],["impl<'a> Freeze for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> Freeze for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl !Freeze for StreamStats",1,["perf::stats::StreamStats"]],["impl Freeze for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl Freeze for Opt",1,["perf::client::Opt"]],["impl Freeze for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl Freeze for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl Freeze for Opt",1,["perf::server::Opt"]],["impl Freeze for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl Freeze for Stats",1,["perf::stats::Stats"]],["impl Freeze for CommonOpt",1,["perf::CommonOpt"]]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[1749,297,369,10132,561,35860,1517,2824]} \ No newline at end of file +//{"start":57,"fragment_lengths":[1749,297,369,11364,561,35860,1517,2824]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/marker/trait.Send.js b/pr/545/docs/trait.impl/core/marker/trait.Send.js index 2100aa612..31cc8fd4a 100644 --- a/pr/545/docs/trait.impl/core/marker/trait.Send.js +++ b/pr/545/docs/trait.impl/core/marker/trait.Send.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl Send for CipherSuite",1,["bench::CipherSuite"]],["impl Send for RuntimeType",1,["bench::RuntimeType"]],["impl Send for Stats",1,["bench::stats::Stats"]],["impl Send for StreamStats",1,["bench::stats::StreamStats"]],["impl Send for TransferResult",1,["bench::stats::TransferResult"]],["impl Send for Opt",1,["bench::Opt"]]]],["bulk",[["impl Send for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl Send for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl Send for ReadError",1,["noq::recv_stream::ReadError"]],["impl Send for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl Send for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl Send for ResetError",1,["noq::recv_stream::ResetError"]],["impl Send for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl Send for StoppedError",1,["noq::send_stream::StoppedError"]],["impl Send for WriteError",1,["noq::send_stream::WriteError"]],["impl Send for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl Send for Connecting",1,["noq::connection::Connecting"]],["impl Send for Connection",1,["noq::connection::Connection"]],["impl Send for Endpoint",1,["noq::endpoint::Endpoint"]],["impl Send for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl Send for Incoming",1,["noq::incoming::Incoming"]],["impl Send for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl Send for OnClosed",1,["noq::connection::OnClosed"]],["impl Send for OpenPath",1,["noq::path::OpenPath"]],["impl Send for Path",1,["noq::path::Path"]],["impl Send for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl Send for RetryError",1,["noq::incoming::RetryError"]],["impl Send for SendStream",1,["noq::send_stream::SendStream"]],["impl Send for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl Send for Stopped",1,["noq::send_stream::Stopped"]],["impl Send for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl Send for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl Send for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl Send for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl Send for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'a> Send for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> Send for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> Send for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> Send for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> Send for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> Send for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> Send for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl Send for Commands",1,["noq_perf::Commands"]],["impl Send for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl Send for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl Send for ConfigError",1,["noq_proto::config::ConfigError"]],["impl Send for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl Send for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl Send for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl Send for Dir",1,["noq_proto::Dir"]],["impl Send for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl Send for Event",1,["noq_proto::connection::Event"]],["impl Send for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl Send for FrameType",1,["noq_proto::frame::FrameType"]],["impl Send for LongType",1,["noq_proto::packet::LongType"]],["impl Send for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl Send for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl Send for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl Send for PathError",1,["noq_proto::connection::PathError"]],["impl Send for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl Send for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl Send for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl Send for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl Send for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl Send for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl Send for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl Send for Side",1,["noq_proto::Side"]],["impl Send for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl Send for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl Send for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl Send for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl Send for Error",1,["noq_proto::transport_parameters::Error"]],["impl Send for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl Send for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl Send for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl Send for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl Send for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl Send for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl Send for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl Send for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl Send for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl Send for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl Send for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl Send for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl Send for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl Send for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl Send for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl Send for Keys",1,["noq_proto::crypto::Keys"]],["impl Send for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl Send for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl Send for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl Send for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl Send for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl Send for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl Send for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl Send for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl Send for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl Send for Connection",1,["noq_proto::connection::Connection"]],["impl Send for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl Send for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl Send for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl Send for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl Send for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl Send for Datagram",1,["noq_proto::frame::Datagram"]],["impl Send for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl Send for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl Send for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl Send for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl Send for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl Send for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl Send for FourTuple",1,["noq_proto::FourTuple"]],["impl Send for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl Send for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl Send for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl Send for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl Send for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl Send for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl Send for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl Send for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl Send for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl Send for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl Send for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl Send for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl Send for PathId",1,["noq_proto::connection::paths::PathId"]],["impl Send for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl Send for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl Send for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl Send for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl Send for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl Send for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl Send for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl Send for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl Send for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl Send for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl Send for StreamId",1,["noq_proto::StreamId"]],["impl Send for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl Send for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl Send for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl Send for Transmit",1,["noq_proto::Transmit"]],["impl Send for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl Send for Error",1,["noq_proto::transport_error::Error"]],["impl Send for Code",1,["noq_proto::transport_error::Code"]],["impl Send for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl Send for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl Send for VarInt",1,["noq_proto::varint::VarInt"]],["impl Send for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl Send for Written",1,["noq_proto::connection::streams::send::Written"]],["impl Send for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> Send for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> Send for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> Send for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> Send for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> Send for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> Send for KeyPair<T>
where\n T: Send,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl Send for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl Send for RecvMeta",1,["noq_udp::RecvMeta"]],["impl Send for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> Send for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> Send for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl Send for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl Send for Opt",1,["perf::client::Opt"]],["impl Send for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl Send for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl Send for Opt",1,["perf::server::Opt"]],["impl Send for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl Send for Stats",1,["perf::stats::Stats"]],["impl Send for StreamStats",1,["perf::stats::StreamStats"]],["impl Send for CommonOpt",1,["perf::CommonOpt"]]]]]); + var implementors = Object.fromEntries([["bench",[["impl Send for CipherSuite",1,["bench::CipherSuite"]],["impl Send for RuntimeType",1,["bench::RuntimeType"]],["impl Send for Stats",1,["bench::stats::Stats"]],["impl Send for StreamStats",1,["bench::stats::StreamStats"]],["impl Send for TransferResult",1,["bench::stats::TransferResult"]],["impl Send for Opt",1,["bench::Opt"]]]],["bulk",[["impl Send for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl Send for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl Send for ReadError",1,["noq::recv_stream::ReadError"]],["impl Send for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl Send for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl Send for ResetError",1,["noq::recv_stream::ResetError"]],["impl Send for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl Send for StoppedError",1,["noq::send_stream::StoppedError"]],["impl Send for WriteError",1,["noq::send_stream::WriteError"]],["impl Send for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl Send for Connecting",1,["noq::connection::Connecting"]],["impl Send for Connection",1,["noq::connection::Connection"]],["impl Send for Endpoint",1,["noq::endpoint::Endpoint"]],["impl Send for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl Send for Incoming",1,["noq::incoming::Incoming"]],["impl Send for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl Send for Lagged",1,["noq::event_stream::Lagged"]],["impl Send for NatTraversalUpdates",1,["noq::event_stream::NatTraversalUpdates"]],["impl Send for ObservedExternalAddr",1,["noq::event_stream::ObservedExternalAddr"]],["impl Send for OnClosed",1,["noq::connection::OnClosed"]],["impl Send for OpenPath",1,["noq::path::OpenPath"]],["impl Send for Path",1,["noq::path::Path"]],["impl Send for PathEvents",1,["noq::event_stream::PathEvents"]],["impl Send for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl Send for RetryError",1,["noq::incoming::RetryError"]],["impl Send for SendStream",1,["noq::send_stream::SendStream"]],["impl Send for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl Send for Stopped",1,["noq::send_stream::Stopped"]],["impl Send for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl Send for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl Send for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl Send for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl Send for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'a> Send for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> Send for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> Send for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> Send for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> Send for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> Send for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> Send for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl Send for Commands",1,["noq_perf::Commands"]],["impl Send for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl Send for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl Send for ConfigError",1,["noq_proto::config::ConfigError"]],["impl Send for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl Send for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl Send for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl Send for Dir",1,["noq_proto::Dir"]],["impl Send for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl Send for Event",1,["noq_proto::connection::Event"]],["impl Send for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl Send for FrameType",1,["noq_proto::frame::FrameType"]],["impl Send for LongType",1,["noq_proto::packet::LongType"]],["impl Send for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl Send for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl Send for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl Send for PathError",1,["noq_proto::connection::PathError"]],["impl Send for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl Send for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl Send for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl Send for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl Send for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl Send for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl Send for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl Send for Side",1,["noq_proto::Side"]],["impl Send for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl Send for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl Send for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl Send for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl Send for Error",1,["noq_proto::transport_parameters::Error"]],["impl Send for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl Send for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl Send for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl Send for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl Send for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl Send for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl Send for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl Send for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl Send for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl Send for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl Send for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl Send for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl Send for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl Send for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl Send for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl Send for Keys",1,["noq_proto::crypto::Keys"]],["impl Send for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl Send for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl Send for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl Send for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl Send for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl Send for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl Send for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl Send for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl Send for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl Send for Connection",1,["noq_proto::connection::Connection"]],["impl Send for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl Send for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl Send for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl Send for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl Send for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl Send for Datagram",1,["noq_proto::frame::Datagram"]],["impl Send for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl Send for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl Send for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl Send for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl Send for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl Send for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl Send for FourTuple",1,["noq_proto::FourTuple"]],["impl Send for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl Send for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl Send for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl Send for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl Send for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl Send for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl Send for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl Send for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl Send for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl Send for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl Send for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl Send for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl Send for PathId",1,["noq_proto::connection::paths::PathId"]],["impl Send for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl Send for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl Send for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl Send for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl Send for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl Send for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl Send for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl Send for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl Send for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl Send for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl Send for StreamId",1,["noq_proto::StreamId"]],["impl Send for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl Send for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl Send for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl Send for Transmit",1,["noq_proto::Transmit"]],["impl Send for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl Send for Error",1,["noq_proto::transport_error::Error"]],["impl Send for Code",1,["noq_proto::transport_error::Code"]],["impl Send for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl Send for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl Send for VarInt",1,["noq_proto::varint::VarInt"]],["impl Send for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl Send for Written",1,["noq_proto::connection::streams::send::Written"]],["impl Send for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> Send for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> Send for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> Send for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> Send for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> Send for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> Send for KeyPair<T>
where\n T: Send,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl Send for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl Send for RecvMeta",1,["noq_udp::RecvMeta"]],["impl Send for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> Send for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> Send for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl Send for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl Send for Opt",1,["perf::client::Opt"]],["impl Send for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl Send for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl Send for Opt",1,["perf::server::Opt"]],["impl Send for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl Send for Stats",1,["perf::stats::Stats"]],["impl Send for StreamStats",1,["perf::stats::StreamStats"]],["impl Send for CommonOpt",1,["perf::CommonOpt"]]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[1713,291,363,9911,549,35179,1486,2769]} \ No newline at end of file +//{"start":57,"fragment_lengths":[1713,291,363,11119,549,35179,1486,2769]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/marker/trait.StructuralPartialEq.js b/pr/545/docs/trait.impl/core/marker/trait.StructuralPartialEq.js index fb3fdf3e6..ab3fd56a4 100644 --- a/pr/545/docs/trait.impl/core/marker/trait.StructuralPartialEq.js +++ b/pr/545/docs/trait.impl/core/marker/trait.StructuralPartialEq.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl StructuralPartialEq for CipherSuite"]]],["noq",[["impl StructuralPartialEq for ReadError"],["impl StructuralPartialEq for ReadExactError"],["impl StructuralPartialEq for ReadToEndError"],["impl StructuralPartialEq for ResetError"],["impl StructuralPartialEq for SendDatagramError"],["impl StructuralPartialEq for StoppedError"],["impl StructuralPartialEq for WriteError"]]],["noq_proto",[["impl StructuralPartialEq for ClosePathError"],["impl StructuralPartialEq for ConfigError"],["impl StructuralPartialEq for ConnectError"],["impl StructuralPartialEq for ConnectionError"],["impl StructuralPartialEq for Dir"],["impl StructuralPartialEq for EcnCodepoint"],["impl StructuralPartialEq for FinishError"],["impl StructuralPartialEq for FrameType"],["impl StructuralPartialEq for LongType"],["impl StructuralPartialEq for MaybeFrame"],["impl StructuralPartialEq for PacketDecodeError"],["impl StructuralPartialEq for PathAbandonReason"],["impl StructuralPartialEq for PathError"],["impl StructuralPartialEq for PathEvent"],["impl StructuralPartialEq for PathStatus"],["impl StructuralPartialEq for ReadError"],["impl StructuralPartialEq for ReadableError"],["impl StructuralPartialEq for SendDatagramError"],["impl StructuralPartialEq for SetPathStatusError"],["impl StructuralPartialEq for Side"],["impl StructuralPartialEq for StreamEvent"],["impl StructuralPartialEq for WriteError"],["impl StructuralPartialEq for Error"],["impl StructuralPartialEq for UnexpectedEnd"],["impl StructuralPartialEq for ExportKeyingMaterialError"],["impl StructuralPartialEq for ApplicationClose"],["impl StructuralPartialEq for Chunk"],["impl StructuralPartialEq for ClosedPath"],["impl StructuralPartialEq for ClosedStream"],["impl StructuralPartialEq for ConnectionClose"],["impl StructuralPartialEq for ConnectionHandle"],["impl StructuralPartialEq for ConnectionId"],["impl StructuralPartialEq for DatagramInfo"],["impl StructuralPartialEq for FourTuple"],["impl StructuralPartialEq for FrameStats"],["impl StructuralPartialEq for IdleTimeout"],["impl StructuralPartialEq for InvalidFrameId"],["impl StructuralPartialEq for PathId"],["impl StructuralPartialEq for PathStats"],["impl StructuralPartialEq for ShouldTransmit"],["impl StructuralPartialEq for StreamId"],["impl StructuralPartialEq for StreamInfo"],["impl StructuralPartialEq for Code"],["impl StructuralPartialEq for UdpStats"],["impl StructuralPartialEq for VarInt"],["impl StructuralPartialEq for VarIntBoundsExceeded"],["impl StructuralPartialEq for Written"],["impl StructuralPartialEq for TransportParameters"]]],["noq_udp",[["impl StructuralPartialEq for EcnCodepoint"]]]]); + var implementors = Object.fromEntries([["bench",[["impl StructuralPartialEq for CipherSuite"]]],["noq",[["impl StructuralPartialEq for ReadError"],["impl StructuralPartialEq for ReadExactError"],["impl StructuralPartialEq for ReadToEndError"],["impl StructuralPartialEq for ResetError"],["impl StructuralPartialEq for SendDatagramError"],["impl StructuralPartialEq for StoppedError"],["impl StructuralPartialEq for WriteError"],["impl StructuralPartialEq for Lagged"]]],["noq_proto",[["impl StructuralPartialEq for ClosePathError"],["impl StructuralPartialEq for ConfigError"],["impl StructuralPartialEq for ConnectError"],["impl StructuralPartialEq for ConnectionError"],["impl StructuralPartialEq for Dir"],["impl StructuralPartialEq for EcnCodepoint"],["impl StructuralPartialEq for FinishError"],["impl StructuralPartialEq for FrameType"],["impl StructuralPartialEq for LongType"],["impl StructuralPartialEq for MaybeFrame"],["impl StructuralPartialEq for PacketDecodeError"],["impl StructuralPartialEq for PathAbandonReason"],["impl StructuralPartialEq for PathError"],["impl StructuralPartialEq for PathEvent"],["impl StructuralPartialEq for PathStatus"],["impl StructuralPartialEq for ReadError"],["impl StructuralPartialEq for ReadableError"],["impl StructuralPartialEq for SendDatagramError"],["impl StructuralPartialEq for SetPathStatusError"],["impl StructuralPartialEq for Side"],["impl StructuralPartialEq for StreamEvent"],["impl StructuralPartialEq for WriteError"],["impl StructuralPartialEq for Error"],["impl StructuralPartialEq for UnexpectedEnd"],["impl StructuralPartialEq for ExportKeyingMaterialError"],["impl StructuralPartialEq for ApplicationClose"],["impl StructuralPartialEq for Chunk"],["impl StructuralPartialEq for ClosedPath"],["impl StructuralPartialEq for ClosedStream"],["impl StructuralPartialEq for ConnectionClose"],["impl StructuralPartialEq for ConnectionHandle"],["impl StructuralPartialEq for ConnectionId"],["impl StructuralPartialEq for DatagramInfo"],["impl StructuralPartialEq for FourTuple"],["impl StructuralPartialEq for FrameStats"],["impl StructuralPartialEq for IdleTimeout"],["impl StructuralPartialEq for InvalidFrameId"],["impl StructuralPartialEq for PathId"],["impl StructuralPartialEq for PathStats"],["impl StructuralPartialEq for ShouldTransmit"],["impl StructuralPartialEq for StreamId"],["impl StructuralPartialEq for StreamInfo"],["impl StructuralPartialEq for Code"],["impl StructuralPartialEq for UdpStats"],["impl StructuralPartialEq for VarInt"],["impl StructuralPartialEq for VarIntBoundsExceeded"],["impl StructuralPartialEq for Written"],["impl StructuralPartialEq for TransportParameters"]]],["noq_udp",[["impl StructuralPartialEq for EcnCodepoint"]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[308,2088,15001,318]} \ No newline at end of file +//{"start":57,"fragment_lengths":[308,2372,15001,318]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/marker/trait.Sync.js b/pr/545/docs/trait.impl/core/marker/trait.Sync.js index 25818f110..2db90824a 100644 --- a/pr/545/docs/trait.impl/core/marker/trait.Sync.js +++ b/pr/545/docs/trait.impl/core/marker/trait.Sync.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl Sync for CipherSuite",1,["bench::CipherSuite"]],["impl Sync for RuntimeType",1,["bench::RuntimeType"]],["impl Sync for Stats",1,["bench::stats::Stats"]],["impl Sync for StreamStats",1,["bench::stats::StreamStats"]],["impl Sync for TransferResult",1,["bench::stats::TransferResult"]],["impl Sync for Opt",1,["bench::Opt"]]]],["bulk",[["impl Sync for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl Sync for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl Sync for ReadError",1,["noq::recv_stream::ReadError"]],["impl Sync for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl Sync for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl Sync for ResetError",1,["noq::recv_stream::ResetError"]],["impl Sync for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl Sync for StoppedError",1,["noq::send_stream::StoppedError"]],["impl Sync for WriteError",1,["noq::send_stream::WriteError"]],["impl Sync for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl Sync for Connecting",1,["noq::connection::Connecting"]],["impl Sync for Connection",1,["noq::connection::Connection"]],["impl Sync for Endpoint",1,["noq::endpoint::Endpoint"]],["impl Sync for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl Sync for Incoming",1,["noq::incoming::Incoming"]],["impl Sync for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl Sync for OnClosed",1,["noq::connection::OnClosed"]],["impl Sync for OpenPath",1,["noq::path::OpenPath"]],["impl Sync for Path",1,["noq::path::Path"]],["impl Sync for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl Sync for RetryError",1,["noq::incoming::RetryError"]],["impl Sync for SendStream",1,["noq::send_stream::SendStream"]],["impl Sync for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl Sync for Stopped",1,["noq::send_stream::Stopped"]],["impl Sync for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl Sync for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl Sync for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl Sync for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl Sync for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'a> Sync for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> Sync for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> Sync for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> Sync for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> Sync for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> Sync for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> Sync for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl Sync for Commands",1,["noq_perf::Commands"]],["impl Sync for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl Sync for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl Sync for ConfigError",1,["noq_proto::config::ConfigError"]],["impl Sync for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl Sync for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl Sync for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl Sync for Dir",1,["noq_proto::Dir"]],["impl Sync for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl Sync for Event",1,["noq_proto::connection::Event"]],["impl Sync for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl Sync for FrameType",1,["noq_proto::frame::FrameType"]],["impl Sync for LongType",1,["noq_proto::packet::LongType"]],["impl Sync for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl Sync for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl Sync for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl Sync for PathError",1,["noq_proto::connection::PathError"]],["impl Sync for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl Sync for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl Sync for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl Sync for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl Sync for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl Sync for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl Sync for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl Sync for Side",1,["noq_proto::Side"]],["impl Sync for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl Sync for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl Sync for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl Sync for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl Sync for Error",1,["noq_proto::transport_parameters::Error"]],["impl Sync for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl Sync for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl Sync for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl Sync for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl Sync for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl Sync for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl Sync for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl Sync for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl Sync for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl Sync for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl Sync for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl Sync for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl Sync for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl Sync for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl Sync for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl Sync for Keys",1,["noq_proto::crypto::Keys"]],["impl Sync for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl Sync for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl Sync for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl Sync for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl Sync for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl Sync for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl Sync for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl Sync for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl Sync for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl Sync for Connection",1,["noq_proto::connection::Connection"]],["impl Sync for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl Sync for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl Sync for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl Sync for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl Sync for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl Sync for Datagram",1,["noq_proto::frame::Datagram"]],["impl Sync for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl Sync for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl Sync for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl Sync for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl Sync for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl Sync for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl Sync for FourTuple",1,["noq_proto::FourTuple"]],["impl Sync for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl Sync for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl Sync for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl Sync for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl Sync for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl Sync for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl Sync for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl Sync for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl Sync for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl Sync for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl Sync for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl Sync for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl Sync for PathId",1,["noq_proto::connection::paths::PathId"]],["impl Sync for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl Sync for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl Sync for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl Sync for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl Sync for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl Sync for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl Sync for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl Sync for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl Sync for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl Sync for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl Sync for StreamId",1,["noq_proto::StreamId"]],["impl Sync for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl Sync for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl Sync for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl Sync for Transmit",1,["noq_proto::Transmit"]],["impl Sync for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl Sync for Error",1,["noq_proto::transport_error::Error"]],["impl Sync for Code",1,["noq_proto::transport_error::Code"]],["impl Sync for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl Sync for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl Sync for VarInt",1,["noq_proto::varint::VarInt"]],["impl Sync for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl Sync for Written",1,["noq_proto::connection::streams::send::Written"]],["impl Sync for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> Sync for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> Sync for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> Sync for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> Sync for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> Sync for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> Sync for KeyPair<T>
where\n T: Sync,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl Sync for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl Sync for RecvMeta",1,["noq_udp::RecvMeta"]],["impl Sync for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> Sync for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> Sync for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl Sync for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl Sync for Opt",1,["perf::client::Opt"]],["impl Sync for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl Sync for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl Sync for Opt",1,["perf::server::Opt"]],["impl Sync for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl Sync for Stats",1,["perf::stats::Stats"]],["impl Sync for StreamStats",1,["perf::stats::StreamStats"]],["impl Sync for CommonOpt",1,["perf::CommonOpt"]]]]]); + var implementors = Object.fromEntries([["bench",[["impl Sync for CipherSuite",1,["bench::CipherSuite"]],["impl Sync for RuntimeType",1,["bench::RuntimeType"]],["impl Sync for Stats",1,["bench::stats::Stats"]],["impl Sync for StreamStats",1,["bench::stats::StreamStats"]],["impl Sync for TransferResult",1,["bench::stats::TransferResult"]],["impl Sync for Opt",1,["bench::Opt"]]]],["bulk",[["impl Sync for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl Sync for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl Sync for ReadError",1,["noq::recv_stream::ReadError"]],["impl Sync for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl Sync for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl Sync for ResetError",1,["noq::recv_stream::ResetError"]],["impl Sync for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl Sync for StoppedError",1,["noq::send_stream::StoppedError"]],["impl Sync for WriteError",1,["noq::send_stream::WriteError"]],["impl Sync for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl Sync for Connecting",1,["noq::connection::Connecting"]],["impl Sync for Connection",1,["noq::connection::Connection"]],["impl Sync for Endpoint",1,["noq::endpoint::Endpoint"]],["impl Sync for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl Sync for Incoming",1,["noq::incoming::Incoming"]],["impl Sync for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl Sync for Lagged",1,["noq::event_stream::Lagged"]],["impl Sync for NatTraversalUpdates",1,["noq::event_stream::NatTraversalUpdates"]],["impl Sync for ObservedExternalAddr",1,["noq::event_stream::ObservedExternalAddr"]],["impl Sync for OnClosed",1,["noq::connection::OnClosed"]],["impl Sync for OpenPath",1,["noq::path::OpenPath"]],["impl Sync for Path",1,["noq::path::Path"]],["impl Sync for PathEvents",1,["noq::event_stream::PathEvents"]],["impl Sync for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl Sync for RetryError",1,["noq::incoming::RetryError"]],["impl Sync for SendStream",1,["noq::send_stream::SendStream"]],["impl Sync for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl Sync for Stopped",1,["noq::send_stream::Stopped"]],["impl Sync for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl Sync for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl Sync for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl Sync for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl Sync for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'a> Sync for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> Sync for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> Sync for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> Sync for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> Sync for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> Sync for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> Sync for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl Sync for Commands",1,["noq_perf::Commands"]],["impl Sync for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl Sync for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl Sync for ConfigError",1,["noq_proto::config::ConfigError"]],["impl Sync for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl Sync for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl Sync for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl Sync for Dir",1,["noq_proto::Dir"]],["impl Sync for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl Sync for Event",1,["noq_proto::connection::Event"]],["impl Sync for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl Sync for FrameType",1,["noq_proto::frame::FrameType"]],["impl Sync for LongType",1,["noq_proto::packet::LongType"]],["impl Sync for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl Sync for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl Sync for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl Sync for PathError",1,["noq_proto::connection::PathError"]],["impl Sync for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl Sync for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl Sync for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl Sync for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl Sync for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl Sync for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl Sync for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl Sync for Side",1,["noq_proto::Side"]],["impl Sync for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl Sync for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl Sync for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl Sync for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl Sync for Error",1,["noq_proto::transport_parameters::Error"]],["impl Sync for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl Sync for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl Sync for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl Sync for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl Sync for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl Sync for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl Sync for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl Sync for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl Sync for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl Sync for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl Sync for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl Sync for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl Sync for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl Sync for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl Sync for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl Sync for Keys",1,["noq_proto::crypto::Keys"]],["impl Sync for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl Sync for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl Sync for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl Sync for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl Sync for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl Sync for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl Sync for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl Sync for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl Sync for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl Sync for Connection",1,["noq_proto::connection::Connection"]],["impl Sync for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl Sync for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl Sync for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl Sync for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl Sync for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl Sync for Datagram",1,["noq_proto::frame::Datagram"]],["impl Sync for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl Sync for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl Sync for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl Sync for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl Sync for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl Sync for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl Sync for FourTuple",1,["noq_proto::FourTuple"]],["impl Sync for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl Sync for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl Sync for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl Sync for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl Sync for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl Sync for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl Sync for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl Sync for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl Sync for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl Sync for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl Sync for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl Sync for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl Sync for PathId",1,["noq_proto::connection::paths::PathId"]],["impl Sync for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl Sync for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl Sync for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl Sync for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl Sync for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl Sync for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl Sync for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl Sync for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl Sync for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl Sync for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl Sync for StreamId",1,["noq_proto::StreamId"]],["impl Sync for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl Sync for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl Sync for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl Sync for Transmit",1,["noq_proto::Transmit"]],["impl Sync for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl Sync for Error",1,["noq_proto::transport_error::Error"]],["impl Sync for Code",1,["noq_proto::transport_error::Code"]],["impl Sync for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl Sync for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl Sync for VarInt",1,["noq_proto::varint::VarInt"]],["impl Sync for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl Sync for Written",1,["noq_proto::connection::streams::send::Written"]],["impl Sync for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> Sync for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> Sync for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> Sync for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> Sync for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> Sync for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> Sync for KeyPair<T>
where\n T: Sync,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl Sync for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl Sync for RecvMeta",1,["noq_udp::RecvMeta"]],["impl Sync for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> Sync for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> Sync for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl Sync for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl Sync for Opt",1,["perf::client::Opt"]],["impl Sync for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl Sync for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl Sync for Opt",1,["perf::server::Opt"]],["impl Sync for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl Sync for Stats",1,["perf::stats::Stats"]],["impl Sync for StreamStats",1,["perf::stats::StreamStats"]],["impl Sync for CommonOpt",1,["perf::CommonOpt"]]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[1713,291,363,9911,549,35179,1486,2769]} \ No newline at end of file +//{"start":57,"fragment_lengths":[1713,291,363,11119,549,35179,1486,2769]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/marker/trait.Unpin.js b/pr/545/docs/trait.impl/core/marker/trait.Unpin.js index 748d4f991..ab667fe44 100644 --- a/pr/545/docs/trait.impl/core/marker/trait.Unpin.js +++ b/pr/545/docs/trait.impl/core/marker/trait.Unpin.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl Unpin for CipherSuite",1,["bench::CipherSuite"]],["impl Unpin for RuntimeType",1,["bench::RuntimeType"]],["impl Unpin for Stats",1,["bench::stats::Stats"]],["impl Unpin for StreamStats",1,["bench::stats::StreamStats"]],["impl Unpin for TransferResult",1,["bench::stats::TransferResult"]],["impl Unpin for Opt",1,["bench::Opt"]]]],["bulk",[["impl Unpin for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl Unpin for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl Unpin for ReadError",1,["noq::recv_stream::ReadError"]],["impl Unpin for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl Unpin for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl Unpin for ResetError",1,["noq::recv_stream::ResetError"]],["impl Unpin for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl Unpin for StoppedError",1,["noq::send_stream::StoppedError"]],["impl Unpin for WriteError",1,["noq::send_stream::WriteError"]],["impl Unpin for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl Unpin for Connecting",1,["noq::connection::Connecting"]],["impl Unpin for Connection",1,["noq::connection::Connection"]],["impl Unpin for Endpoint",1,["noq::endpoint::Endpoint"]],["impl Unpin for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl Unpin for Incoming",1,["noq::incoming::Incoming"]],["impl Unpin for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl Unpin for OnClosed",1,["noq::connection::OnClosed"]],["impl Unpin for OpenPath",1,["noq::path::OpenPath"]],["impl Unpin for Path",1,["noq::path::Path"]],["impl Unpin for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl Unpin for RetryError",1,["noq::incoming::RetryError"]],["impl Unpin for SendStream",1,["noq::send_stream::SendStream"]],["impl Unpin for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl Unpin for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl Unpin for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl Unpin for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl Unpin for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl Unpin for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'__pin> Unpin for Stopped
where\n PinnedFieldsOf<__Origin<'__pin>>: Unpin,
"],["impl<'__pin, 'a> Unpin for Accept<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for AcceptBi<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for AcceptUni<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for OpenBi<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for OpenUni<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for ReadDatagram<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for SendDatagram<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"]]],["noq_perf",[["impl Unpin for Commands",1,["noq_perf::Commands"]],["impl Unpin for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl Unpin for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl Unpin for ConfigError",1,["noq_proto::config::ConfigError"]],["impl Unpin for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl Unpin for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl Unpin for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl Unpin for Dir",1,["noq_proto::Dir"]],["impl Unpin for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl Unpin for Event",1,["noq_proto::connection::Event"]],["impl Unpin for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl Unpin for FrameType",1,["noq_proto::frame::FrameType"]],["impl Unpin for LongType",1,["noq_proto::packet::LongType"]],["impl Unpin for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl Unpin for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl Unpin for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl Unpin for PathError",1,["noq_proto::connection::PathError"]],["impl Unpin for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl Unpin for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl Unpin for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl Unpin for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl Unpin for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl Unpin for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl Unpin for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl Unpin for Side",1,["noq_proto::Side"]],["impl Unpin for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl Unpin for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl Unpin for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl Unpin for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl Unpin for Error",1,["noq_proto::transport_parameters::Error"]],["impl Unpin for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl Unpin for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl Unpin for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl Unpin for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl Unpin for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl Unpin for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl Unpin for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl Unpin for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl Unpin for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl Unpin for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl Unpin for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl Unpin for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl Unpin for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl Unpin for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl Unpin for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl Unpin for Keys",1,["noq_proto::crypto::Keys"]],["impl Unpin for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl Unpin for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl Unpin for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl Unpin for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl Unpin for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl Unpin for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl Unpin for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl Unpin for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl Unpin for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl Unpin for Connection",1,["noq_proto::connection::Connection"]],["impl Unpin for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl Unpin for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl Unpin for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl Unpin for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl Unpin for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl Unpin for Datagram",1,["noq_proto::frame::Datagram"]],["impl Unpin for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl Unpin for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl Unpin for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl Unpin for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl Unpin for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl Unpin for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl Unpin for FourTuple",1,["noq_proto::FourTuple"]],["impl Unpin for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl Unpin for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl Unpin for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl Unpin for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl Unpin for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl Unpin for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl Unpin for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl Unpin for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl Unpin for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl Unpin for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl Unpin for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl Unpin for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl Unpin for PathId",1,["noq_proto::connection::paths::PathId"]],["impl Unpin for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl Unpin for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl Unpin for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl Unpin for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl Unpin for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl Unpin for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl Unpin for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl Unpin for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl Unpin for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl Unpin for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl Unpin for StreamId",1,["noq_proto::StreamId"]],["impl Unpin for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl Unpin for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl Unpin for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl Unpin for Transmit",1,["noq_proto::Transmit"]],["impl Unpin for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl Unpin for Error",1,["noq_proto::transport_error::Error"]],["impl Unpin for Code",1,["noq_proto::transport_error::Code"]],["impl Unpin for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl Unpin for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl Unpin for VarInt",1,["noq_proto::varint::VarInt"]],["impl Unpin for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl Unpin for Written",1,["noq_proto::connection::streams::send::Written"]],["impl Unpin for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> Unpin for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> Unpin for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> Unpin for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> Unpin for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> Unpin for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> Unpin for KeyPair<T>
where\n T: Unpin,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl Unpin for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl Unpin for RecvMeta",1,["noq_udp::RecvMeta"]],["impl Unpin for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> Unpin for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> Unpin for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl Unpin for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl Unpin for Opt",1,["perf::client::Opt"]],["impl Unpin for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl Unpin for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl Unpin for Opt",1,["perf::server::Opt"]],["impl Unpin for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl Unpin for Stats",1,["perf::stats::Stats"]],["impl Unpin for StreamStats",1,["perf::stats::StreamStats"]],["impl Unpin for CommonOpt",1,["perf::CommonOpt"]]]]]); + var implementors = Object.fromEntries([["bench",[["impl Unpin for CipherSuite",1,["bench::CipherSuite"]],["impl Unpin for RuntimeType",1,["bench::RuntimeType"]],["impl Unpin for Stats",1,["bench::stats::Stats"]],["impl Unpin for StreamStats",1,["bench::stats::StreamStats"]],["impl Unpin for TransferResult",1,["bench::stats::TransferResult"]],["impl Unpin for Opt",1,["bench::Opt"]]]],["bulk",[["impl Unpin for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl Unpin for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl Unpin for ReadError",1,["noq::recv_stream::ReadError"]],["impl Unpin for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl Unpin for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl Unpin for ResetError",1,["noq::recv_stream::ResetError"]],["impl Unpin for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl Unpin for StoppedError",1,["noq::send_stream::StoppedError"]],["impl Unpin for WriteError",1,["noq::send_stream::WriteError"]],["impl Unpin for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl Unpin for Connecting",1,["noq::connection::Connecting"]],["impl Unpin for Connection",1,["noq::connection::Connection"]],["impl Unpin for Endpoint",1,["noq::endpoint::Endpoint"]],["impl Unpin for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl Unpin for Incoming",1,["noq::incoming::Incoming"]],["impl Unpin for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl Unpin for Lagged",1,["noq::event_stream::Lagged"]],["impl Unpin for NatTraversalUpdates",1,["noq::event_stream::NatTraversalUpdates"]],["impl Unpin for ObservedExternalAddr",1,["noq::event_stream::ObservedExternalAddr"]],["impl Unpin for OnClosed",1,["noq::connection::OnClosed"]],["impl Unpin for OpenPath",1,["noq::path::OpenPath"]],["impl Unpin for Path",1,["noq::path::Path"]],["impl Unpin for PathEvents",1,["noq::event_stream::PathEvents"]],["impl Unpin for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl Unpin for RetryError",1,["noq::incoming::RetryError"]],["impl Unpin for SendStream",1,["noq::send_stream::SendStream"]],["impl Unpin for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl Unpin for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl Unpin for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl Unpin for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl Unpin for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl Unpin for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'__pin> Unpin for Stopped
where\n PinnedFieldsOf<__Origin<'__pin>>: Unpin,
"],["impl<'__pin, 'a> Unpin for Accept<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for AcceptBi<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for AcceptUni<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for OpenBi<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for OpenUni<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for ReadDatagram<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"],["impl<'__pin, 'a> Unpin for SendDatagram<'a>
where\n PinnedFieldsOf<__Origin<'__pin, 'a>>: Unpin,
"]]],["noq_perf",[["impl Unpin for Commands",1,["noq_perf::Commands"]],["impl Unpin for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl Unpin for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl Unpin for ConfigError",1,["noq_proto::config::ConfigError"]],["impl Unpin for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl Unpin for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl Unpin for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl Unpin for Dir",1,["noq_proto::Dir"]],["impl Unpin for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl Unpin for Event",1,["noq_proto::connection::Event"]],["impl Unpin for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl Unpin for FrameType",1,["noq_proto::frame::FrameType"]],["impl Unpin for LongType",1,["noq_proto::packet::LongType"]],["impl Unpin for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl Unpin for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl Unpin for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl Unpin for PathError",1,["noq_proto::connection::PathError"]],["impl Unpin for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl Unpin for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl Unpin for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl Unpin for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl Unpin for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl Unpin for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl Unpin for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl Unpin for Side",1,["noq_proto::Side"]],["impl Unpin for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl Unpin for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl Unpin for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl Unpin for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl Unpin for Error",1,["noq_proto::transport_parameters::Error"]],["impl Unpin for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl Unpin for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl Unpin for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl Unpin for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl Unpin for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl Unpin for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl Unpin for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl Unpin for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl Unpin for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl Unpin for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl Unpin for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl Unpin for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl Unpin for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl Unpin for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl Unpin for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl Unpin for Keys",1,["noq_proto::crypto::Keys"]],["impl Unpin for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl Unpin for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl Unpin for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl Unpin for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl Unpin for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl Unpin for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl Unpin for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl Unpin for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl Unpin for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl Unpin for Connection",1,["noq_proto::connection::Connection"]],["impl Unpin for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl Unpin for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl Unpin for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl Unpin for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl Unpin for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl Unpin for Datagram",1,["noq_proto::frame::Datagram"]],["impl Unpin for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl Unpin for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl Unpin for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl Unpin for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl Unpin for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl Unpin for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl Unpin for FourTuple",1,["noq_proto::FourTuple"]],["impl Unpin for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl Unpin for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl Unpin for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl Unpin for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl Unpin for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl Unpin for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl Unpin for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl Unpin for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl Unpin for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl Unpin for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl Unpin for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl Unpin for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl Unpin for PathId",1,["noq_proto::connection::paths::PathId"]],["impl Unpin for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl Unpin for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl Unpin for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl Unpin for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl Unpin for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl Unpin for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl Unpin for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl Unpin for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl Unpin for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl Unpin for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl Unpin for StreamId",1,["noq_proto::StreamId"]],["impl Unpin for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl Unpin for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl Unpin for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl Unpin for Transmit",1,["noq_proto::Transmit"]],["impl Unpin for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl Unpin for Error",1,["noq_proto::transport_error::Error"]],["impl Unpin for Code",1,["noq_proto::transport_error::Code"]],["impl Unpin for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl Unpin for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl Unpin for VarInt",1,["noq_proto::varint::VarInt"]],["impl Unpin for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl Unpin for Written",1,["noq_proto::connection::streams::send::Written"]],["impl Unpin for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> Unpin for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> Unpin for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> Unpin for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> Unpin for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> Unpin for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> Unpin for KeyPair<T>
where\n T: Unpin,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl Unpin for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl Unpin for RecvMeta",1,["noq_udp::RecvMeta"]],["impl Unpin for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> Unpin for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> Unpin for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl Unpin for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl Unpin for Opt",1,["perf::client::Opt"]],["impl Unpin for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl Unpin for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl Unpin for Opt",1,["perf::server::Opt"]],["impl Unpin for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl Unpin for Stats",1,["perf::stats::Stats"]],["impl Unpin for StreamStats",1,["perf::stats::StreamStats"]],["impl Unpin for CommonOpt",1,["perf::CommonOpt"]]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[1731,294,366,11621,555,35512,1501,2796]} \ No newline at end of file +//{"start":57,"fragment_lengths":[1731,294,366,12841,555,35512,1501,2796]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/marker/trait.UnsafeUnpin.js b/pr/545/docs/trait.impl/core/marker/trait.UnsafeUnpin.js index acd3f0863..0ba259e40 100644 --- a/pr/545/docs/trait.impl/core/marker/trait.UnsafeUnpin.js +++ b/pr/545/docs/trait.impl/core/marker/trait.UnsafeUnpin.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl UnsafeUnpin for CipherSuite",1,["bench::CipherSuite"]],["impl UnsafeUnpin for RuntimeType",1,["bench::RuntimeType"]],["impl UnsafeUnpin for Stats",1,["bench::stats::Stats"]],["impl UnsafeUnpin for StreamStats",1,["bench::stats::StreamStats"]],["impl UnsafeUnpin for TransferResult",1,["bench::stats::TransferResult"]],["impl UnsafeUnpin for Opt",1,["bench::Opt"]]]],["bulk",[["impl UnsafeUnpin for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl UnsafeUnpin for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl !UnsafeUnpin for Stopped",1,["noq::send_stream::Stopped"]],["impl UnsafeUnpin for ReadError",1,["noq::recv_stream::ReadError"]],["impl UnsafeUnpin for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl UnsafeUnpin for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl UnsafeUnpin for ResetError",1,["noq::recv_stream::ResetError"]],["impl UnsafeUnpin for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl UnsafeUnpin for StoppedError",1,["noq::send_stream::StoppedError"]],["impl UnsafeUnpin for WriteError",1,["noq::send_stream::WriteError"]],["impl UnsafeUnpin for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl UnsafeUnpin for Connecting",1,["noq::connection::Connecting"]],["impl UnsafeUnpin for Connection",1,["noq::connection::Connection"]],["impl UnsafeUnpin for Endpoint",1,["noq::endpoint::Endpoint"]],["impl UnsafeUnpin for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl UnsafeUnpin for Incoming",1,["noq::incoming::Incoming"]],["impl UnsafeUnpin for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl UnsafeUnpin for OnClosed",1,["noq::connection::OnClosed"]],["impl UnsafeUnpin for OpenPath",1,["noq::path::OpenPath"]],["impl UnsafeUnpin for Path",1,["noq::path::Path"]],["impl UnsafeUnpin for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl UnsafeUnpin for RetryError",1,["noq::incoming::RetryError"]],["impl UnsafeUnpin for SendStream",1,["noq::send_stream::SendStream"]],["impl UnsafeUnpin for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl UnsafeUnpin for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl UnsafeUnpin for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl UnsafeUnpin for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl UnsafeUnpin for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl UnsafeUnpin for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'a> !UnsafeUnpin for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> !UnsafeUnpin for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> !UnsafeUnpin for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> !UnsafeUnpin for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> !UnsafeUnpin for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> !UnsafeUnpin for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> !UnsafeUnpin for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl UnsafeUnpin for Commands",1,["noq_perf::Commands"]],["impl UnsafeUnpin for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl UnsafeUnpin for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl UnsafeUnpin for ConfigError",1,["noq_proto::config::ConfigError"]],["impl UnsafeUnpin for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl UnsafeUnpin for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl UnsafeUnpin for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl UnsafeUnpin for Dir",1,["noq_proto::Dir"]],["impl UnsafeUnpin for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl UnsafeUnpin for Event",1,["noq_proto::connection::Event"]],["impl UnsafeUnpin for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl UnsafeUnpin for FrameType",1,["noq_proto::frame::FrameType"]],["impl UnsafeUnpin for LongType",1,["noq_proto::packet::LongType"]],["impl UnsafeUnpin for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl UnsafeUnpin for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl UnsafeUnpin for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl UnsafeUnpin for PathError",1,["noq_proto::connection::PathError"]],["impl UnsafeUnpin for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl UnsafeUnpin for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl UnsafeUnpin for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl UnsafeUnpin for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl UnsafeUnpin for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl UnsafeUnpin for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl UnsafeUnpin for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl UnsafeUnpin for Side",1,["noq_proto::Side"]],["impl UnsafeUnpin for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl UnsafeUnpin for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl UnsafeUnpin for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl UnsafeUnpin for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl UnsafeUnpin for Error",1,["noq_proto::transport_parameters::Error"]],["impl UnsafeUnpin for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl UnsafeUnpin for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl UnsafeUnpin for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl UnsafeUnpin for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl UnsafeUnpin for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl UnsafeUnpin for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl UnsafeUnpin for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl UnsafeUnpin for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl UnsafeUnpin for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl UnsafeUnpin for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl UnsafeUnpin for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl UnsafeUnpin for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl UnsafeUnpin for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl UnsafeUnpin for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl UnsafeUnpin for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl UnsafeUnpin for Keys",1,["noq_proto::crypto::Keys"]],["impl UnsafeUnpin for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl UnsafeUnpin for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl UnsafeUnpin for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl UnsafeUnpin for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl UnsafeUnpin for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl UnsafeUnpin for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl UnsafeUnpin for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl UnsafeUnpin for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl UnsafeUnpin for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl UnsafeUnpin for Connection",1,["noq_proto::connection::Connection"]],["impl UnsafeUnpin for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl UnsafeUnpin for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl UnsafeUnpin for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl UnsafeUnpin for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl UnsafeUnpin for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl UnsafeUnpin for Datagram",1,["noq_proto::frame::Datagram"]],["impl UnsafeUnpin for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl UnsafeUnpin for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl UnsafeUnpin for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl UnsafeUnpin for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl UnsafeUnpin for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl UnsafeUnpin for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl UnsafeUnpin for FourTuple",1,["noq_proto::FourTuple"]],["impl UnsafeUnpin for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl UnsafeUnpin for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl UnsafeUnpin for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl UnsafeUnpin for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl UnsafeUnpin for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl UnsafeUnpin for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl UnsafeUnpin for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl UnsafeUnpin for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl UnsafeUnpin for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl UnsafeUnpin for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl UnsafeUnpin for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl UnsafeUnpin for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl UnsafeUnpin for PathId",1,["noq_proto::connection::paths::PathId"]],["impl UnsafeUnpin for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl UnsafeUnpin for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl UnsafeUnpin for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl UnsafeUnpin for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl UnsafeUnpin for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl UnsafeUnpin for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl UnsafeUnpin for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl UnsafeUnpin for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl UnsafeUnpin for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl UnsafeUnpin for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl UnsafeUnpin for StreamId",1,["noq_proto::StreamId"]],["impl UnsafeUnpin for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl UnsafeUnpin for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl UnsafeUnpin for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl UnsafeUnpin for Transmit",1,["noq_proto::Transmit"]],["impl UnsafeUnpin for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl UnsafeUnpin for Error",1,["noq_proto::transport_error::Error"]],["impl UnsafeUnpin for Code",1,["noq_proto::transport_error::Code"]],["impl UnsafeUnpin for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl UnsafeUnpin for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl UnsafeUnpin for VarInt",1,["noq_proto::varint::VarInt"]],["impl UnsafeUnpin for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl UnsafeUnpin for Written",1,["noq_proto::connection::streams::send::Written"]],["impl UnsafeUnpin for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> UnsafeUnpin for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> UnsafeUnpin for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> UnsafeUnpin for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> UnsafeUnpin for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> UnsafeUnpin for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> UnsafeUnpin for KeyPair<T>
where\n T: UnsafeUnpin,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl UnsafeUnpin for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl UnsafeUnpin for RecvMeta",1,["noq_udp::RecvMeta"]],["impl UnsafeUnpin for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> UnsafeUnpin for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> UnsafeUnpin for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl UnsafeUnpin for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl UnsafeUnpin for Opt",1,["perf::client::Opt"]],["impl UnsafeUnpin for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl UnsafeUnpin for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl UnsafeUnpin for Opt",1,["perf::server::Opt"]],["impl UnsafeUnpin for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl UnsafeUnpin for Stats",1,["perf::stats::Stats"]],["impl UnsafeUnpin for StreamStats",1,["perf::stats::StreamStats"]],["impl UnsafeUnpin for CommonOpt",1,["perf::CommonOpt"]]]]]); + var implementors = Object.fromEntries([["bench",[["impl UnsafeUnpin for CipherSuite",1,["bench::CipherSuite"]],["impl UnsafeUnpin for RuntimeType",1,["bench::RuntimeType"]],["impl UnsafeUnpin for Stats",1,["bench::stats::Stats"]],["impl UnsafeUnpin for StreamStats",1,["bench::stats::StreamStats"]],["impl UnsafeUnpin for TransferResult",1,["bench::stats::TransferResult"]],["impl UnsafeUnpin for Opt",1,["bench::Opt"]]]],["bulk",[["impl UnsafeUnpin for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl UnsafeUnpin for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl !UnsafeUnpin for Stopped",1,["noq::send_stream::Stopped"]],["impl UnsafeUnpin for ReadError",1,["noq::recv_stream::ReadError"]],["impl UnsafeUnpin for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl UnsafeUnpin for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl UnsafeUnpin for ResetError",1,["noq::recv_stream::ResetError"]],["impl UnsafeUnpin for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl UnsafeUnpin for StoppedError",1,["noq::send_stream::StoppedError"]],["impl UnsafeUnpin for WriteError",1,["noq::send_stream::WriteError"]],["impl UnsafeUnpin for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl UnsafeUnpin for Connecting",1,["noq::connection::Connecting"]],["impl UnsafeUnpin for Connection",1,["noq::connection::Connection"]],["impl UnsafeUnpin for Endpoint",1,["noq::endpoint::Endpoint"]],["impl UnsafeUnpin for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl UnsafeUnpin for Incoming",1,["noq::incoming::Incoming"]],["impl UnsafeUnpin for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl UnsafeUnpin for Lagged",1,["noq::event_stream::Lagged"]],["impl UnsafeUnpin for NatTraversalUpdates",1,["noq::event_stream::NatTraversalUpdates"]],["impl UnsafeUnpin for ObservedExternalAddr",1,["noq::event_stream::ObservedExternalAddr"]],["impl UnsafeUnpin for OnClosed",1,["noq::connection::OnClosed"]],["impl UnsafeUnpin for OpenPath",1,["noq::path::OpenPath"]],["impl UnsafeUnpin for Path",1,["noq::path::Path"]],["impl UnsafeUnpin for PathEvents",1,["noq::event_stream::PathEvents"]],["impl UnsafeUnpin for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl UnsafeUnpin for RetryError",1,["noq::incoming::RetryError"]],["impl UnsafeUnpin for SendStream",1,["noq::send_stream::SendStream"]],["impl UnsafeUnpin for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl UnsafeUnpin for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl UnsafeUnpin for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl UnsafeUnpin for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl UnsafeUnpin for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl UnsafeUnpin for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl<'a> !UnsafeUnpin for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> !UnsafeUnpin for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> !UnsafeUnpin for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> !UnsafeUnpin for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> !UnsafeUnpin for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> !UnsafeUnpin for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> !UnsafeUnpin for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl UnsafeUnpin for Commands",1,["noq_perf::Commands"]],["impl UnsafeUnpin for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl UnsafeUnpin for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl UnsafeUnpin for ConfigError",1,["noq_proto::config::ConfigError"]],["impl UnsafeUnpin for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl UnsafeUnpin for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl UnsafeUnpin for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl UnsafeUnpin for Dir",1,["noq_proto::Dir"]],["impl UnsafeUnpin for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl UnsafeUnpin for Event",1,["noq_proto::connection::Event"]],["impl UnsafeUnpin for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl UnsafeUnpin for FrameType",1,["noq_proto::frame::FrameType"]],["impl UnsafeUnpin for LongType",1,["noq_proto::packet::LongType"]],["impl UnsafeUnpin for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl UnsafeUnpin for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl UnsafeUnpin for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl UnsafeUnpin for PathError",1,["noq_proto::connection::PathError"]],["impl UnsafeUnpin for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl UnsafeUnpin for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl UnsafeUnpin for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl UnsafeUnpin for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl UnsafeUnpin for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl UnsafeUnpin for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl UnsafeUnpin for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl UnsafeUnpin for Side",1,["noq_proto::Side"]],["impl UnsafeUnpin for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl UnsafeUnpin for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl UnsafeUnpin for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl UnsafeUnpin for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl UnsafeUnpin for Error",1,["noq_proto::transport_parameters::Error"]],["impl UnsafeUnpin for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl UnsafeUnpin for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl UnsafeUnpin for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl UnsafeUnpin for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl UnsafeUnpin for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl UnsafeUnpin for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl UnsafeUnpin for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl UnsafeUnpin for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl UnsafeUnpin for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl UnsafeUnpin for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl UnsafeUnpin for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl UnsafeUnpin for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl UnsafeUnpin for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl UnsafeUnpin for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl UnsafeUnpin for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl UnsafeUnpin for Keys",1,["noq_proto::crypto::Keys"]],["impl UnsafeUnpin for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl UnsafeUnpin for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl UnsafeUnpin for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl UnsafeUnpin for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl UnsafeUnpin for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl UnsafeUnpin for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl UnsafeUnpin for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl UnsafeUnpin for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl UnsafeUnpin for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl UnsafeUnpin for Connection",1,["noq_proto::connection::Connection"]],["impl UnsafeUnpin for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl UnsafeUnpin for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl UnsafeUnpin for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl UnsafeUnpin for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl UnsafeUnpin for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl UnsafeUnpin for Datagram",1,["noq_proto::frame::Datagram"]],["impl UnsafeUnpin for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl UnsafeUnpin for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl UnsafeUnpin for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl UnsafeUnpin for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl UnsafeUnpin for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl UnsafeUnpin for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl UnsafeUnpin for FourTuple",1,["noq_proto::FourTuple"]],["impl UnsafeUnpin for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl UnsafeUnpin for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl UnsafeUnpin for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl UnsafeUnpin for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl UnsafeUnpin for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl UnsafeUnpin for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl UnsafeUnpin for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl UnsafeUnpin for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl UnsafeUnpin for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl UnsafeUnpin for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl UnsafeUnpin for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl UnsafeUnpin for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl UnsafeUnpin for PathId",1,["noq_proto::connection::paths::PathId"]],["impl UnsafeUnpin for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl UnsafeUnpin for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl UnsafeUnpin for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl UnsafeUnpin for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl UnsafeUnpin for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl UnsafeUnpin for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl UnsafeUnpin for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl UnsafeUnpin for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl UnsafeUnpin for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl UnsafeUnpin for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl UnsafeUnpin for StreamId",1,["noq_proto::StreamId"]],["impl UnsafeUnpin for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl UnsafeUnpin for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl UnsafeUnpin for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl UnsafeUnpin for Transmit",1,["noq_proto::Transmit"]],["impl UnsafeUnpin for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl UnsafeUnpin for Error",1,["noq_proto::transport_error::Error"]],["impl UnsafeUnpin for Code",1,["noq_proto::transport_error::Code"]],["impl UnsafeUnpin for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl UnsafeUnpin for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl UnsafeUnpin for VarInt",1,["noq_proto::varint::VarInt"]],["impl UnsafeUnpin for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl UnsafeUnpin for Written",1,["noq_proto::connection::streams::send::Written"]],["impl UnsafeUnpin for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> UnsafeUnpin for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> UnsafeUnpin for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> UnsafeUnpin for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> UnsafeUnpin for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> UnsafeUnpin for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> UnsafeUnpin for KeyPair<T>
where\n T: UnsafeUnpin,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl UnsafeUnpin for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl UnsafeUnpin for RecvMeta",1,["noq_udp::RecvMeta"]],["impl UnsafeUnpin for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> UnsafeUnpin for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> UnsafeUnpin for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl UnsafeUnpin for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl UnsafeUnpin for Opt",1,["perf::client::Opt"]],["impl UnsafeUnpin for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl UnsafeUnpin for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl UnsafeUnpin for Opt",1,["perf::server::Opt"]],["impl UnsafeUnpin for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl UnsafeUnpin for Stats",1,["perf::stats::Stats"]],["impl UnsafeUnpin for StreamStats",1,["perf::stats::StreamStats"]],["impl UnsafeUnpin for CommonOpt",1,["perf::CommonOpt"]]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[981,312,384,5771,591,21637,876,1671]} \ No newline at end of file +//{"start":57,"fragment_lengths":[981,312,384,6491,591,21637,876,1671]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js b/pr/545/docs/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js index ef5dc3531..028b48137 100644 --- a/pr/545/docs/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js +++ b/pr/545/docs/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl RefUnwindSafe for CipherSuite",1,["bench::CipherSuite"]],["impl RefUnwindSafe for RuntimeType",1,["bench::RuntimeType"]],["impl RefUnwindSafe for Stats",1,["bench::stats::Stats"]],["impl RefUnwindSafe for StreamStats",1,["bench::stats::StreamStats"]],["impl RefUnwindSafe for TransferResult",1,["bench::stats::TransferResult"]],["impl RefUnwindSafe for Opt",1,["bench::Opt"]]]],["bulk",[["impl RefUnwindSafe for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl !RefUnwindSafe for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl !RefUnwindSafe for ReadError",1,["noq::recv_stream::ReadError"]],["impl !RefUnwindSafe for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl !RefUnwindSafe for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl !RefUnwindSafe for ResetError",1,["noq::recv_stream::ResetError"]],["impl !RefUnwindSafe for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl !RefUnwindSafe for StoppedError",1,["noq::send_stream::StoppedError"]],["impl !RefUnwindSafe for WriteError",1,["noq::send_stream::WriteError"]],["impl !RefUnwindSafe for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl !RefUnwindSafe for Connecting",1,["noq::connection::Connecting"]],["impl !RefUnwindSafe for Endpoint",1,["noq::endpoint::Endpoint"]],["impl !RefUnwindSafe for Incoming",1,["noq::incoming::Incoming"]],["impl !RefUnwindSafe for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl !RefUnwindSafe for OnClosed",1,["noq::connection::OnClosed"]],["impl !RefUnwindSafe for OpenPath",1,["noq::path::OpenPath"]],["impl !RefUnwindSafe for RetryError",1,["noq::incoming::RetryError"]],["impl !RefUnwindSafe for Stopped",1,["noq::send_stream::Stopped"]],["impl !RefUnwindSafe for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl RefUnwindSafe for Connection",1,["noq::connection::Connection"]],["impl RefUnwindSafe for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl RefUnwindSafe for Path",1,["noq::path::Path"]],["impl RefUnwindSafe for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl RefUnwindSafe for SendStream",1,["noq::send_stream::SendStream"]],["impl RefUnwindSafe for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl RefUnwindSafe for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl RefUnwindSafe for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl RefUnwindSafe for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl RefUnwindSafe for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl<'a> !RefUnwindSafe for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> !RefUnwindSafe for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> !RefUnwindSafe for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> !RefUnwindSafe for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> !RefUnwindSafe for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> !RefUnwindSafe for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> !RefUnwindSafe for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl RefUnwindSafe for Commands",1,["noq_perf::Commands"]],["impl RefUnwindSafe for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl !RefUnwindSafe for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl !RefUnwindSafe for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl !RefUnwindSafe for Event",1,["noq_proto::connection::Event"]],["impl !RefUnwindSafe for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl !RefUnwindSafe for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl !RefUnwindSafe for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl !RefUnwindSafe for Keys",1,["noq_proto::crypto::Keys"]],["impl !RefUnwindSafe for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl !RefUnwindSafe for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl !RefUnwindSafe for Connection",1,["noq_proto::connection::Connection"]],["impl !RefUnwindSafe for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl !RefUnwindSafe for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl !RefUnwindSafe for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl !RefUnwindSafe for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl !RefUnwindSafe for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl !RefUnwindSafe for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl !RefUnwindSafe for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl !RefUnwindSafe for Error",1,["noq_proto::transport_error::Error"]],["impl !RefUnwindSafe for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl RefUnwindSafe for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl RefUnwindSafe for ConfigError",1,["noq_proto::config::ConfigError"]],["impl RefUnwindSafe for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl RefUnwindSafe for Dir",1,["noq_proto::Dir"]],["impl RefUnwindSafe for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl RefUnwindSafe for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl RefUnwindSafe for FrameType",1,["noq_proto::frame::FrameType"]],["impl RefUnwindSafe for LongType",1,["noq_proto::packet::LongType"]],["impl RefUnwindSafe for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl RefUnwindSafe for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl RefUnwindSafe for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl RefUnwindSafe for PathError",1,["noq_proto::connection::PathError"]],["impl RefUnwindSafe for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl RefUnwindSafe for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl RefUnwindSafe for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl RefUnwindSafe for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl RefUnwindSafe for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl RefUnwindSafe for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl RefUnwindSafe for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl RefUnwindSafe for Side",1,["noq_proto::Side"]],["impl RefUnwindSafe for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl RefUnwindSafe for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl RefUnwindSafe for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl RefUnwindSafe for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl RefUnwindSafe for Error",1,["noq_proto::transport_parameters::Error"]],["impl RefUnwindSafe for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl RefUnwindSafe for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl RefUnwindSafe for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl RefUnwindSafe for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl RefUnwindSafe for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl RefUnwindSafe for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl RefUnwindSafe for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl RefUnwindSafe for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl RefUnwindSafe for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl RefUnwindSafe for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl RefUnwindSafe for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl RefUnwindSafe for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl RefUnwindSafe for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl RefUnwindSafe for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl RefUnwindSafe for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl RefUnwindSafe for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl RefUnwindSafe for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl RefUnwindSafe for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl RefUnwindSafe for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl RefUnwindSafe for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl RefUnwindSafe for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl RefUnwindSafe for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl RefUnwindSafe for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl RefUnwindSafe for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl RefUnwindSafe for Datagram",1,["noq_proto::frame::Datagram"]],["impl RefUnwindSafe for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl RefUnwindSafe for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl RefUnwindSafe for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl RefUnwindSafe for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl RefUnwindSafe for FourTuple",1,["noq_proto::FourTuple"]],["impl RefUnwindSafe for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl RefUnwindSafe for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl RefUnwindSafe for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl RefUnwindSafe for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl RefUnwindSafe for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl RefUnwindSafe for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl RefUnwindSafe for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl RefUnwindSafe for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl RefUnwindSafe for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl RefUnwindSafe for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl RefUnwindSafe for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl RefUnwindSafe for PathId",1,["noq_proto::connection::paths::PathId"]],["impl RefUnwindSafe for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl RefUnwindSafe for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl RefUnwindSafe for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl RefUnwindSafe for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl RefUnwindSafe for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl RefUnwindSafe for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl RefUnwindSafe for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl RefUnwindSafe for StreamId",1,["noq_proto::StreamId"]],["impl RefUnwindSafe for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl RefUnwindSafe for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl RefUnwindSafe for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl RefUnwindSafe for Transmit",1,["noq_proto::Transmit"]],["impl RefUnwindSafe for Code",1,["noq_proto::transport_error::Code"]],["impl RefUnwindSafe for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl RefUnwindSafe for VarInt",1,["noq_proto::varint::VarInt"]],["impl RefUnwindSafe for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl RefUnwindSafe for Written",1,["noq_proto::connection::streams::send::Written"]],["impl RefUnwindSafe for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> !RefUnwindSafe for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> !RefUnwindSafe for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> !RefUnwindSafe for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<'a> RefUnwindSafe for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> RefUnwindSafe for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<T> RefUnwindSafe for KeyPair<T>
where\n T: RefUnwindSafe,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl RefUnwindSafe for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl RefUnwindSafe for RecvMeta",1,["noq_udp::RecvMeta"]],["impl RefUnwindSafe for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> RefUnwindSafe for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> RefUnwindSafe for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl !RefUnwindSafe for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl !RefUnwindSafe for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl RefUnwindSafe for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl RefUnwindSafe for Opt",1,["perf::client::Opt"]],["impl RefUnwindSafe for Opt",1,["perf::server::Opt"]],["impl RefUnwindSafe for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl RefUnwindSafe for Stats",1,["perf::stats::Stats"]],["impl RefUnwindSafe for StreamStats",1,["perf::stats::StreamStats"]],["impl RefUnwindSafe for CommonOpt",1,["perf::CommonOpt"]]]]]); + var implementors = Object.fromEntries([["bench",[["impl RefUnwindSafe for CipherSuite",1,["bench::CipherSuite"]],["impl RefUnwindSafe for RuntimeType",1,["bench::RuntimeType"]],["impl RefUnwindSafe for Stats",1,["bench::stats::Stats"]],["impl RefUnwindSafe for StreamStats",1,["bench::stats::StreamStats"]],["impl RefUnwindSafe for TransferResult",1,["bench::stats::TransferResult"]],["impl RefUnwindSafe for Opt",1,["bench::Opt"]]]],["bulk",[["impl RefUnwindSafe for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl !RefUnwindSafe for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl !RefUnwindSafe for ReadError",1,["noq::recv_stream::ReadError"]],["impl !RefUnwindSafe for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl !RefUnwindSafe for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl !RefUnwindSafe for ResetError",1,["noq::recv_stream::ResetError"]],["impl !RefUnwindSafe for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl !RefUnwindSafe for StoppedError",1,["noq::send_stream::StoppedError"]],["impl !RefUnwindSafe for WriteError",1,["noq::send_stream::WriteError"]],["impl !RefUnwindSafe for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl !RefUnwindSafe for Connecting",1,["noq::connection::Connecting"]],["impl !RefUnwindSafe for Endpoint",1,["noq::endpoint::Endpoint"]],["impl !RefUnwindSafe for Incoming",1,["noq::incoming::Incoming"]],["impl !RefUnwindSafe for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl !RefUnwindSafe for NatTraversalUpdates",1,["noq::event_stream::NatTraversalUpdates"]],["impl !RefUnwindSafe for ObservedExternalAddr",1,["noq::event_stream::ObservedExternalAddr"]],["impl !RefUnwindSafe for OnClosed",1,["noq::connection::OnClosed"]],["impl !RefUnwindSafe for OpenPath",1,["noq::path::OpenPath"]],["impl !RefUnwindSafe for PathEvents",1,["noq::event_stream::PathEvents"]],["impl !RefUnwindSafe for RetryError",1,["noq::incoming::RetryError"]],["impl !RefUnwindSafe for Stopped",1,["noq::send_stream::Stopped"]],["impl !RefUnwindSafe for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl RefUnwindSafe for Connection",1,["noq::connection::Connection"]],["impl RefUnwindSafe for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl RefUnwindSafe for Lagged",1,["noq::event_stream::Lagged"]],["impl RefUnwindSafe for Path",1,["noq::path::Path"]],["impl RefUnwindSafe for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl RefUnwindSafe for SendStream",1,["noq::send_stream::SendStream"]],["impl RefUnwindSafe for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl RefUnwindSafe for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl RefUnwindSafe for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl RefUnwindSafe for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl RefUnwindSafe for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl<'a> !RefUnwindSafe for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> !RefUnwindSafe for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> !RefUnwindSafe for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> !RefUnwindSafe for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> !RefUnwindSafe for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> !RefUnwindSafe for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> !RefUnwindSafe for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl RefUnwindSafe for Commands",1,["noq_perf::Commands"]],["impl RefUnwindSafe for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl !RefUnwindSafe for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl !RefUnwindSafe for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl !RefUnwindSafe for Event",1,["noq_proto::connection::Event"]],["impl !RefUnwindSafe for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl !RefUnwindSafe for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl !RefUnwindSafe for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl !RefUnwindSafe for Keys",1,["noq_proto::crypto::Keys"]],["impl !RefUnwindSafe for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl !RefUnwindSafe for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl !RefUnwindSafe for Connection",1,["noq_proto::connection::Connection"]],["impl !RefUnwindSafe for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl !RefUnwindSafe for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl !RefUnwindSafe for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl !RefUnwindSafe for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl !RefUnwindSafe for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl !RefUnwindSafe for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl !RefUnwindSafe for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl !RefUnwindSafe for Error",1,["noq_proto::transport_error::Error"]],["impl !RefUnwindSafe for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl RefUnwindSafe for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl RefUnwindSafe for ConfigError",1,["noq_proto::config::ConfigError"]],["impl RefUnwindSafe for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl RefUnwindSafe for Dir",1,["noq_proto::Dir"]],["impl RefUnwindSafe for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl RefUnwindSafe for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl RefUnwindSafe for FrameType",1,["noq_proto::frame::FrameType"]],["impl RefUnwindSafe for LongType",1,["noq_proto::packet::LongType"]],["impl RefUnwindSafe for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl RefUnwindSafe for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl RefUnwindSafe for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl RefUnwindSafe for PathError",1,["noq_proto::connection::PathError"]],["impl RefUnwindSafe for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl RefUnwindSafe for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl RefUnwindSafe for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl RefUnwindSafe for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl RefUnwindSafe for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl RefUnwindSafe for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl RefUnwindSafe for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl RefUnwindSafe for Side",1,["noq_proto::Side"]],["impl RefUnwindSafe for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl RefUnwindSafe for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl RefUnwindSafe for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl RefUnwindSafe for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl RefUnwindSafe for Error",1,["noq_proto::transport_parameters::Error"]],["impl RefUnwindSafe for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl RefUnwindSafe for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl RefUnwindSafe for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl RefUnwindSafe for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl RefUnwindSafe for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl RefUnwindSafe for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl RefUnwindSafe for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl RefUnwindSafe for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl RefUnwindSafe for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl RefUnwindSafe for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl RefUnwindSafe for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl RefUnwindSafe for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl RefUnwindSafe for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl RefUnwindSafe for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl RefUnwindSafe for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl RefUnwindSafe for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl RefUnwindSafe for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl RefUnwindSafe for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl RefUnwindSafe for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl RefUnwindSafe for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl RefUnwindSafe for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl RefUnwindSafe for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl RefUnwindSafe for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl RefUnwindSafe for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl RefUnwindSafe for Datagram",1,["noq_proto::frame::Datagram"]],["impl RefUnwindSafe for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl RefUnwindSafe for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl RefUnwindSafe for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl RefUnwindSafe for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl RefUnwindSafe for FourTuple",1,["noq_proto::FourTuple"]],["impl RefUnwindSafe for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl RefUnwindSafe for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl RefUnwindSafe for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl RefUnwindSafe for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl RefUnwindSafe for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl RefUnwindSafe for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl RefUnwindSafe for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl RefUnwindSafe for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl RefUnwindSafe for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl RefUnwindSafe for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl RefUnwindSafe for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl RefUnwindSafe for PathId",1,["noq_proto::connection::paths::PathId"]],["impl RefUnwindSafe for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl RefUnwindSafe for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl RefUnwindSafe for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl RefUnwindSafe for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl RefUnwindSafe for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl RefUnwindSafe for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl RefUnwindSafe for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl RefUnwindSafe for StreamId",1,["noq_proto::StreamId"]],["impl RefUnwindSafe for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl RefUnwindSafe for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl RefUnwindSafe for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl RefUnwindSafe for Transmit",1,["noq_proto::Transmit"]],["impl RefUnwindSafe for Code",1,["noq_proto::transport_error::Code"]],["impl RefUnwindSafe for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl RefUnwindSafe for VarInt",1,["noq_proto::varint::VarInt"]],["impl RefUnwindSafe for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl RefUnwindSafe for Written",1,["noq_proto::connection::streams::send::Written"]],["impl RefUnwindSafe for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> !RefUnwindSafe for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> !RefUnwindSafe for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> !RefUnwindSafe for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<'a> RefUnwindSafe for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> RefUnwindSafe for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<T> RefUnwindSafe for KeyPair<T>
where\n T: RefUnwindSafe,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl RefUnwindSafe for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl RefUnwindSafe for RecvMeta",1,["noq_udp::RecvMeta"]],["impl RefUnwindSafe for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> RefUnwindSafe for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> RefUnwindSafe for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl !RefUnwindSafe for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl !RefUnwindSafe for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl RefUnwindSafe for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl RefUnwindSafe for Opt",1,["perf::client::Opt"]],["impl RefUnwindSafe for Opt",1,["perf::server::Opt"]],["impl RefUnwindSafe for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl RefUnwindSafe for Stats",1,["perf::stats::Stats"]],["impl RefUnwindSafe for StreamStats",1,["perf::stats::StreamStats"]],["impl RefUnwindSafe for CommonOpt",1,["perf::CommonOpt"]]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[2013,341,414,11635,649,40751,1736,3221]} \ No newline at end of file +//{"start":57,"fragment_lengths":[2013,341,414,13046,649,40751,1736,3221]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js b/pr/545/docs/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js index 31d30f482..61556ea3f 100644 --- a/pr/545/docs/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js +++ b/pr/545/docs/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["bench",[["impl UnwindSafe for CipherSuite",1,["bench::CipherSuite"]],["impl UnwindSafe for RuntimeType",1,["bench::RuntimeType"]],["impl UnwindSafe for Stats",1,["bench::stats::Stats"]],["impl UnwindSafe for StreamStats",1,["bench::stats::StreamStats"]],["impl UnwindSafe for TransferResult",1,["bench::stats::TransferResult"]],["impl UnwindSafe for Opt",1,["bench::Opt"]]]],["bulk",[["impl UnwindSafe for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl !UnwindSafe for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl !UnwindSafe for ReadError",1,["noq::recv_stream::ReadError"]],["impl !UnwindSafe for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl !UnwindSafe for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl !UnwindSafe for ResetError",1,["noq::recv_stream::ResetError"]],["impl !UnwindSafe for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl !UnwindSafe for StoppedError",1,["noq::send_stream::StoppedError"]],["impl !UnwindSafe for WriteError",1,["noq::send_stream::WriteError"]],["impl !UnwindSafe for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl !UnwindSafe for Connecting",1,["noq::connection::Connecting"]],["impl !UnwindSafe for Endpoint",1,["noq::endpoint::Endpoint"]],["impl !UnwindSafe for Incoming",1,["noq::incoming::Incoming"]],["impl !UnwindSafe for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl !UnwindSafe for OnClosed",1,["noq::connection::OnClosed"]],["impl !UnwindSafe for OpenPath",1,["noq::path::OpenPath"]],["impl !UnwindSafe for RetryError",1,["noq::incoming::RetryError"]],["impl !UnwindSafe for Stopped",1,["noq::send_stream::Stopped"]],["impl !UnwindSafe for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl UnwindSafe for Connection",1,["noq::connection::Connection"]],["impl UnwindSafe for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl UnwindSafe for Path",1,["noq::path::Path"]],["impl UnwindSafe for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl UnwindSafe for SendStream",1,["noq::send_stream::SendStream"]],["impl UnwindSafe for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl UnwindSafe for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl UnwindSafe for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl UnwindSafe for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl UnwindSafe for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl<'a> !UnwindSafe for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> !UnwindSafe for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> !UnwindSafe for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> !UnwindSafe for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> !UnwindSafe for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> !UnwindSafe for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> !UnwindSafe for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl UnwindSafe for Commands",1,["noq_perf::Commands"]],["impl UnwindSafe for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl !UnwindSafe for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl !UnwindSafe for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl !UnwindSafe for Event",1,["noq_proto::connection::Event"]],["impl !UnwindSafe for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl !UnwindSafe for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl !UnwindSafe for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl !UnwindSafe for Keys",1,["noq_proto::crypto::Keys"]],["impl !UnwindSafe for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl !UnwindSafe for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl !UnwindSafe for Connection",1,["noq_proto::connection::Connection"]],["impl !UnwindSafe for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl !UnwindSafe for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl !UnwindSafe for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl !UnwindSafe for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl !UnwindSafe for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl !UnwindSafe for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl !UnwindSafe for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl !UnwindSafe for Error",1,["noq_proto::transport_error::Error"]],["impl !UnwindSafe for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl UnwindSafe for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl UnwindSafe for ConfigError",1,["noq_proto::config::ConfigError"]],["impl UnwindSafe for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl UnwindSafe for Dir",1,["noq_proto::Dir"]],["impl UnwindSafe for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl UnwindSafe for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl UnwindSafe for FrameType",1,["noq_proto::frame::FrameType"]],["impl UnwindSafe for LongType",1,["noq_proto::packet::LongType"]],["impl UnwindSafe for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl UnwindSafe for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl UnwindSafe for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl UnwindSafe for PathError",1,["noq_proto::connection::PathError"]],["impl UnwindSafe for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl UnwindSafe for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl UnwindSafe for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl UnwindSafe for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl UnwindSafe for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl UnwindSafe for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl UnwindSafe for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl UnwindSafe for Side",1,["noq_proto::Side"]],["impl UnwindSafe for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl UnwindSafe for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl UnwindSafe for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl UnwindSafe for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl UnwindSafe for Error",1,["noq_proto::transport_parameters::Error"]],["impl UnwindSafe for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl UnwindSafe for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl UnwindSafe for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl UnwindSafe for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl UnwindSafe for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl UnwindSafe for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl UnwindSafe for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl UnwindSafe for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl UnwindSafe for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl UnwindSafe for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl UnwindSafe for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl UnwindSafe for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl UnwindSafe for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl UnwindSafe for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl UnwindSafe for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl UnwindSafe for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl UnwindSafe for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl UnwindSafe for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl UnwindSafe for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl UnwindSafe for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl UnwindSafe for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl UnwindSafe for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl UnwindSafe for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl UnwindSafe for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl UnwindSafe for Datagram",1,["noq_proto::frame::Datagram"]],["impl UnwindSafe for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl UnwindSafe for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl UnwindSafe for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl UnwindSafe for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl UnwindSafe for FourTuple",1,["noq_proto::FourTuple"]],["impl UnwindSafe for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl UnwindSafe for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl UnwindSafe for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl UnwindSafe for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl UnwindSafe for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl UnwindSafe for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl UnwindSafe for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl UnwindSafe for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl UnwindSafe for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl UnwindSafe for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl UnwindSafe for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl UnwindSafe for PathId",1,["noq_proto::connection::paths::PathId"]],["impl UnwindSafe for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl UnwindSafe for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl UnwindSafe for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl UnwindSafe for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl UnwindSafe for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl UnwindSafe for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl UnwindSafe for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl UnwindSafe for StreamId",1,["noq_proto::StreamId"]],["impl UnwindSafe for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl UnwindSafe for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl UnwindSafe for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl UnwindSafe for Transmit",1,["noq_proto::Transmit"]],["impl UnwindSafe for Code",1,["noq_proto::transport_error::Code"]],["impl UnwindSafe for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl UnwindSafe for VarInt",1,["noq_proto::varint::VarInt"]],["impl UnwindSafe for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl UnwindSafe for Written",1,["noq_proto::connection::streams::send::Written"]],["impl UnwindSafe for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> !UnwindSafe for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> !UnwindSafe for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> !UnwindSafe for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> !UnwindSafe for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> !UnwindSafe for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> UnwindSafe for KeyPair<T>
where\n T: UnwindSafe,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl UnwindSafe for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl UnwindSafe for RecvMeta",1,["noq_udp::RecvMeta"]],["impl UnwindSafe for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> UnwindSafe for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> UnwindSafe for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl !UnwindSafe for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl !UnwindSafe for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl UnwindSafe for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl UnwindSafe for Opt",1,["perf::client::Opt"]],["impl UnwindSafe for Opt",1,["perf::server::Opt"]],["impl UnwindSafe for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl UnwindSafe for Stats",1,["perf::stats::Stats"]],["impl UnwindSafe for StreamStats",1,["perf::stats::StreamStats"]],["impl UnwindSafe for CommonOpt",1,["perf::CommonOpt"]]]]]); + var implementors = Object.fromEntries([["bench",[["impl UnwindSafe for CipherSuite",1,["bench::CipherSuite"]],["impl UnwindSafe for RuntimeType",1,["bench::RuntimeType"]],["impl UnwindSafe for Stats",1,["bench::stats::Stats"]],["impl UnwindSafe for StreamStats",1,["bench::stats::StreamStats"]],["impl UnwindSafe for TransferResult",1,["bench::stats::TransferResult"]],["impl UnwindSafe for Opt",1,["bench::Opt"]]]],["bulk",[["impl UnwindSafe for ClientStats",1,["bulk::ClientStats"]]]],["certificate",[["impl !UnwindSafe for SkipServerVerification",1,["certificate::SkipServerVerification"]]]],["noq",[["impl !UnwindSafe for ReadError",1,["noq::recv_stream::ReadError"]],["impl !UnwindSafe for ReadExactError",1,["noq::recv_stream::ReadExactError"]],["impl !UnwindSafe for ReadToEndError",1,["noq::recv_stream::ReadToEndError"]],["impl !UnwindSafe for ResetError",1,["noq::recv_stream::ResetError"]],["impl !UnwindSafe for SendDatagramError",1,["noq::connection::SendDatagramError"]],["impl !UnwindSafe for StoppedError",1,["noq::send_stream::StoppedError"]],["impl !UnwindSafe for WriteError",1,["noq::send_stream::WriteError"]],["impl !UnwindSafe for AddressDiscovery",1,["noq::path::AddressDiscovery"]],["impl !UnwindSafe for Connecting",1,["noq::connection::Connecting"]],["impl !UnwindSafe for Endpoint",1,["noq::endpoint::Endpoint"]],["impl !UnwindSafe for Incoming",1,["noq::incoming::Incoming"]],["impl !UnwindSafe for IncomingFuture",1,["noq::incoming::IncomingFuture"]],["impl !UnwindSafe for NatTraversalUpdates",1,["noq::event_stream::NatTraversalUpdates"]],["impl !UnwindSafe for ObservedExternalAddr",1,["noq::event_stream::ObservedExternalAddr"]],["impl !UnwindSafe for OnClosed",1,["noq::connection::OnClosed"]],["impl !UnwindSafe for OpenPath",1,["noq::path::OpenPath"]],["impl !UnwindSafe for PathEvents",1,["noq::event_stream::PathEvents"]],["impl !UnwindSafe for RetryError",1,["noq::incoming::RetryError"]],["impl !UnwindSafe for Stopped",1,["noq::send_stream::Stopped"]],["impl !UnwindSafe for ZeroRttAccepted",1,["noq::connection::ZeroRttAccepted"]],["impl UnwindSafe for Connection",1,["noq::connection::Connection"]],["impl UnwindSafe for EndpointStats",1,["noq::endpoint::EndpointStats"]],["impl UnwindSafe for Lagged",1,["noq::event_stream::Lagged"]],["impl UnwindSafe for Path",1,["noq::path::Path"]],["impl UnwindSafe for RecvStream",1,["noq::recv_stream::RecvStream"]],["impl UnwindSafe for SendStream",1,["noq::send_stream::SendStream"]],["impl UnwindSafe for SmolRuntime",1,["noq::runtime::smol::SmolRuntime"]],["impl UnwindSafe for TokioRuntime",1,["noq::runtime::tokio::TokioRuntime"]],["impl UnwindSafe for UnorderedRecvStream",1,["noq::recv_stream::UnorderedRecvStream"]],["impl UnwindSafe for WeakConnectionHandle",1,["noq::connection::WeakConnectionHandle"]],["impl UnwindSafe for WeakPathHandle",1,["noq::path::WeakPathHandle"]],["impl<'a> !UnwindSafe for Accept<'a>",1,["noq::endpoint::Accept"]],["impl<'a> !UnwindSafe for AcceptBi<'a>",1,["noq::connection::AcceptBi"]],["impl<'a> !UnwindSafe for AcceptUni<'a>",1,["noq::connection::AcceptUni"]],["impl<'a> !UnwindSafe for OpenBi<'a>",1,["noq::connection::OpenBi"]],["impl<'a> !UnwindSafe for OpenUni<'a>",1,["noq::connection::OpenUni"]],["impl<'a> !UnwindSafe for ReadDatagram<'a>",1,["noq::connection::ReadDatagram"]],["impl<'a> !UnwindSafe for SendDatagram<'a>",1,["noq::connection::SendDatagram"]]]],["noq_perf",[["impl UnwindSafe for Commands",1,["noq_perf::Commands"]],["impl UnwindSafe for Cli",1,["noq_perf::Cli"]]]],["noq_proto",[["impl !UnwindSafe for ConnectionError",1,["noq_proto::connection::ConnectionError"]],["impl !UnwindSafe for DatagramEvent",1,["noq_proto::endpoint::DatagramEvent"]],["impl !UnwindSafe for Event",1,["noq_proto::connection::Event"]],["impl !UnwindSafe for QuicClientConfig",1,["noq_proto::crypto::rustls::QuicClientConfig"]],["impl !UnwindSafe for QuicServerConfig",1,["noq_proto::crypto::rustls::QuicServerConfig"]],["impl !UnwindSafe for TlsSession",1,["noq_proto::crypto::rustls::TlsSession"]],["impl !UnwindSafe for Keys",1,["noq_proto::crypto::Keys"]],["impl !UnwindSafe for AcceptError",1,["noq_proto::endpoint::AcceptError"]],["impl !UnwindSafe for ClientConfig",1,["noq_proto::config::ClientConfig"]],["impl !UnwindSafe for Connection",1,["noq_proto::connection::Connection"]],["impl !UnwindSafe for Endpoint",1,["noq_proto::endpoint::Endpoint"]],["impl !UnwindSafe for EndpointConfig",1,["noq_proto::config::EndpointConfig"]],["impl !UnwindSafe for Incoming",1,["noq_proto::endpoint::Incoming"]],["impl !UnwindSafe for QlogConfig",1,["noq_proto::config::qlog::QlogConfig"]],["impl !UnwindSafe for RetryError",1,["noq_proto::endpoint::RetryError"]],["impl !UnwindSafe for ServerConfig",1,["noq_proto::config::ServerConfig"]],["impl !UnwindSafe for TransportConfig",1,["noq_proto::config::transport::TransportConfig"]],["impl !UnwindSafe for Error",1,["noq_proto::transport_error::Error"]],["impl !UnwindSafe for ValidationTokenConfig",1,["noq_proto::config::ValidationTokenConfig"]],["impl UnwindSafe for ClosePathError",1,["noq_proto::connection::ClosePathError"]],["impl UnwindSafe for ConfigError",1,["noq_proto::config::ConfigError"]],["impl UnwindSafe for ConnectError",1,["noq_proto::endpoint::ConnectError"]],["impl UnwindSafe for Dir",1,["noq_proto::Dir"]],["impl UnwindSafe for EcnCodepoint",1,["noq_proto::shared::EcnCodepoint"]],["impl UnwindSafe for FinishError",1,["noq_proto::connection::streams::send::FinishError"]],["impl UnwindSafe for FrameType",1,["noq_proto::frame::FrameType"]],["impl UnwindSafe for LongType",1,["noq_proto::packet::LongType"]],["impl UnwindSafe for MaybeFrame",1,["noq_proto::frame::MaybeFrame"]],["impl UnwindSafe for PacketDecodeError",1,["noq_proto::packet::PacketDecodeError"]],["impl UnwindSafe for PathAbandonReason",1,["noq_proto::connection::paths::PathAbandonReason"]],["impl UnwindSafe for PathError",1,["noq_proto::connection::PathError"]],["impl UnwindSafe for PathEvent",1,["noq_proto::connection::paths::PathEvent"]],["impl UnwindSafe for PathStatus",1,["noq_proto::connection::paths::PathStatus"]],["impl UnwindSafe for ProtectedHeader",1,["noq_proto::packet::ProtectedHeader"]],["impl UnwindSafe for ReadError",1,["noq_proto::connection::streams::recv::ReadError"]],["impl UnwindSafe for ReadableError",1,["noq_proto::connection::streams::recv::ReadableError"]],["impl UnwindSafe for SendDatagramError",1,["noq_proto::connection::datagrams::SendDatagramError"]],["impl UnwindSafe for SetPathStatusError",1,["noq_proto::connection::paths::SetPathStatusError"]],["impl UnwindSafe for Side",1,["noq_proto::Side"]],["impl UnwindSafe for StreamEvent",1,["noq_proto::connection::streams::StreamEvent"]],["impl UnwindSafe for WriteError",1,["noq_proto::connection::streams::send::WriteError"]],["impl UnwindSafe for Error",1,["noq_proto::n0_nat_traversal::Error"]],["impl UnwindSafe for Event",1,["noq_proto::n0_nat_traversal::Event"]],["impl UnwindSafe for Error",1,["noq_proto::transport_parameters::Error"]],["impl UnwindSafe for UnexpectedEnd",1,["noq_proto::coding::UnexpectedEnd"]],["impl UnwindSafe for Bbr",1,["noq_proto::congestion::bbr::Bbr"]],["impl UnwindSafe for BbrConfig",1,["noq_proto::congestion::bbr::BbrConfig"]],["impl UnwindSafe for ControllerMetrics",1,["noq_proto::congestion::ControllerMetrics"]],["impl UnwindSafe for Cubic",1,["noq_proto::congestion::cubic::Cubic"]],["impl UnwindSafe for CubicConfig",1,["noq_proto::congestion::cubic::CubicConfig"]],["impl UnwindSafe for NewReno",1,["noq_proto::congestion::new_reno::NewReno"]],["impl UnwindSafe for NewRenoConfig",1,["noq_proto::congestion::new_reno::NewRenoConfig"]],["impl UnwindSafe for HandshakeData",1,["noq_proto::crypto::rustls::HandshakeData"]],["impl UnwindSafe for NoInitialCipherSuite",1,["noq_proto::crypto::rustls::NoInitialCipherSuite"]],["impl UnwindSafe for CryptoError",1,["noq_proto::crypto::CryptoError"]],["impl UnwindSafe for ExportKeyingMaterialError",1,["noq_proto::crypto::ExportKeyingMaterialError"]],["impl UnwindSafe for UnsupportedVersion",1,["noq_proto::crypto::UnsupportedVersion"]],["impl UnwindSafe for AckFrequencyConfig",1,["noq_proto::config::transport::AckFrequencyConfig"]],["impl UnwindSafe for ApplicationClose",1,["noq_proto::frame::ApplicationClose"]],["impl UnwindSafe for BloomTokenLog",1,["noq_proto::bloom_token_log::BloomTokenLog"]],["impl UnwindSafe for Chunk",1,["noq_proto::connection::assembler::Chunk"]],["impl UnwindSafe for ClosedPath",1,["noq_proto::connection::paths::ClosedPath"]],["impl UnwindSafe for ClosedStream",1,["noq_proto::connection::streams::ClosedStream"]],["impl UnwindSafe for ConnectionClose",1,["noq_proto::frame::ConnectionClose"]],["impl UnwindSafe for ConnectionEvent",1,["noq_proto::shared::ConnectionEvent"]],["impl UnwindSafe for ConnectionHandle",1,["noq_proto::endpoint::ConnectionHandle"]],["impl UnwindSafe for ConnectionId",1,["noq_proto::shared::ConnectionId"]],["impl UnwindSafe for ConnectionStats",1,["noq_proto::connection::stats::ConnectionStats"]],["impl UnwindSafe for Datagram",1,["noq_proto::frame::Datagram"]],["impl UnwindSafe for DatagramInfo",1,["noq_proto::frame::DatagramInfo"]],["impl UnwindSafe for DecryptedInitial",1,["noq_proto::endpoint::DecryptedInitial"]],["impl UnwindSafe for EndpointEvent",1,["noq_proto::shared::EndpointEvent"]],["impl UnwindSafe for FixedLengthConnectionIdParser",1,["noq_proto::packet::FixedLengthConnectionIdParser"]],["impl UnwindSafe for FourTuple",1,["noq_proto::FourTuple"]],["impl UnwindSafe for FrameStats",1,["noq_proto::connection::stats::FrameStats"]],["impl UnwindSafe for HashedConnectionIdGenerator",1,["noq_proto::cid_generator::HashedConnectionIdGenerator"]],["impl UnwindSafe for IdleTimeout",1,["noq_proto::config::transport::IdleTimeout"]],["impl UnwindSafe for IncomingAlpns",1,["noq_proto::endpoint::IncomingAlpns"]],["impl UnwindSafe for InvalidCid",1,["noq_proto::cid_generator::InvalidCid"]],["impl UnwindSafe for InvalidFrameId",1,["noq_proto::frame::InvalidFrameId"]],["impl UnwindSafe for MtuDiscoveryConfig",1,["noq_proto::config::transport::MtuDiscoveryConfig"]],["impl UnwindSafe for MultipathNotNegotiated",1,["noq_proto::connection::MultipathNotNegotiated"]],["impl UnwindSafe for NoneTokenLog",1,["noq_proto::token::NoneTokenLog"]],["impl UnwindSafe for NoneTokenStore",1,["noq_proto::token::NoneTokenStore"]],["impl UnwindSafe for PartialDecode",1,["noq_proto::packet::PartialDecode"]],["impl UnwindSafe for PathId",1,["noq_proto::connection::paths::PathId"]],["impl UnwindSafe for PathStats",1,["noq_proto::connection::stats::PathStats"]],["impl UnwindSafe for ProtectedInitialHeader",1,["noq_proto::packet::ProtectedInitialHeader"]],["impl UnwindSafe for QlogFileFactory",1,["noq_proto::config::qlog::QlogFileFactory"]],["impl UnwindSafe for RandomConnectionIdGenerator",1,["noq_proto::cid_generator::RandomConnectionIdGenerator"]],["impl UnwindSafe for RttEstimator",1,["noq_proto::connection::paths::RttEstimator"]],["impl UnwindSafe for ShouldTransmit",1,["noq_proto::connection::streams::ShouldTransmit"]],["impl UnwindSafe for StdSystemTime",1,["noq_proto::config::StdSystemTime"]],["impl UnwindSafe for StreamId",1,["noq_proto::StreamId"]],["impl UnwindSafe for StreamInfo",1,["noq_proto::frame::StreamInfo"]],["impl UnwindSafe for TokenMemoryCache",1,["noq_proto::token_memory_cache::TokenMemoryCache"]],["impl UnwindSafe for TokenReuseError",1,["noq_proto::token::TokenReuseError"]],["impl UnwindSafe for Transmit",1,["noq_proto::Transmit"]],["impl UnwindSafe for Code",1,["noq_proto::transport_error::Code"]],["impl UnwindSafe for UdpStats",1,["noq_proto::connection::stats::UdpStats"]],["impl UnwindSafe for VarInt",1,["noq_proto::varint::VarInt"]],["impl UnwindSafe for VarIntBoundsExceeded",1,["noq_proto::varint::VarIntBoundsExceeded"]],["impl UnwindSafe for Written",1,["noq_proto::connection::streams::send::Written"]],["impl UnwindSafe for TransportParameters",1,["noq_proto::transport_parameters::TransportParameters"]],["impl<'a> !UnwindSafe for Chunks<'a>",1,["noq_proto::connection::streams::recv::Chunks"]],["impl<'a> !UnwindSafe for Datagrams<'a>",1,["noq_proto::connection::datagrams::Datagrams"]],["impl<'a> !UnwindSafe for RecvStream<'a>",1,["noq_proto::connection::streams::RecvStream"]],["impl<'a> !UnwindSafe for SendStream<'a>",1,["noq_proto::connection::streams::SendStream"]],["impl<'a> !UnwindSafe for Streams<'a>",1,["noq_proto::connection::streams::Streams"]],["impl<T> UnwindSafe for KeyPair<T>
where\n T: UnwindSafe,
",1,["noq_proto::crypto::KeyPair"]]]],["noq_udp",[["impl UnwindSafe for EcnCodepoint",1,["noq_udp::EcnCodepoint"]],["impl UnwindSafe for RecvMeta",1,["noq_udp::RecvMeta"]],["impl UnwindSafe for UdpSocketState",1,["noq_udp::imp::UdpSocketState"]],["impl<'a> UnwindSafe for Transmit<'a>",1,["noq_udp::Transmit"]],["impl<'a> UnwindSafe for UdpSockRef<'a>",1,["noq_udp::UdpSockRef"]]]],["perf",[["impl !UnwindSafe for NoProtectionClientConfig",1,["perf::noprotection::NoProtectionClientConfig"]],["impl !UnwindSafe for NoProtectionServerConfig",1,["perf::noprotection::NoProtectionServerConfig"]],["impl UnwindSafe for CongestionAlgorithm",1,["perf::CongestionAlgorithm"]],["impl UnwindSafe for Opt",1,["perf::client::Opt"]],["impl UnwindSafe for Opt",1,["perf::server::Opt"]],["impl UnwindSafe for OpenStreamStats",1,["perf::stats::OpenStreamStats"]],["impl UnwindSafe for Stats",1,["perf::stats::Stats"]],["impl UnwindSafe for StreamStats",1,["perf::stats::StreamStats"]],["impl UnwindSafe for CommonOpt",1,["perf::CommonOpt"]]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[1959,332,405,11329,631,39754,1691,3140]} \ No newline at end of file +//{"start":57,"fragment_lengths":[1959,332,405,12704,631,39754,1691,3140]} \ No newline at end of file diff --git a/pr/545/docs/trait.impl/futures_core/stream/trait.Stream.js b/pr/545/docs/trait.impl/futures_core/stream/trait.Stream.js index 0a32d2714..286ae1016 100644 --- a/pr/545/docs/trait.impl/futures_core/stream/trait.Stream.js +++ b/pr/545/docs/trait.impl/futures_core/stream/trait.Stream.js @@ -1,9 +1,9 @@ (function() { - var implementors = Object.fromEntries([["noq",[["impl Stream for AddressDiscovery"]]]]); + var implementors = Object.fromEntries([["noq",[["impl Stream for AddressDiscovery"],["impl Stream for NatTraversalUpdates"],["impl Stream for ObservedExternalAddr"],["impl Stream for PathEvents"]]]]); if (window.register_implementors) { window.register_implementors(implementors); } else { window.pending_implementors = implementors; } })() -//{"start":57,"fragment_lengths":[151]} \ No newline at end of file +//{"start":57,"fragment_lengths":[580]} \ No newline at end of file