From ed4308cf0c86525a81cf34ea7998e450245ea606 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Wed, 15 Nov 2023 23:46:31 +0000 Subject: [PATCH] deploy: 5a74ac5b489857de502aad9dbb5ebe06d6717b2e --- .buildinfo | 4 + .doctrees/architecture.doctree | Bin 0 -> 25729 bytes .doctrees/backpressure.doctree | Bin 0 -> 7799 bytes .doctrees/dlqs.doctree | Bin 0 -> 29691 bytes .doctrees/environment.pickle | Bin 0 -> 627749 bytes .doctrees/getstarted.doctree | Bin 0 -> 22281 bytes .doctrees/index.doctree | Bin 0 -> 5231 bytes .doctrees/intro.doctree | Bin 0 -> 4392 bytes .doctrees/metrics.doctree | Bin 0 -> 39885 bytes .doctrees/offsets.doctree | Bin 0 -> 8000 bytes .doctrees/strategies/batching.doctree | Bin 0 -> 25670 bytes .doctrees/strategies/commit_offsets.doctree | Bin 0 -> 6657 bytes .doctrees/strategies/filter.doctree | Bin 0 -> 15369 bytes .doctrees/strategies/healthcheck.doctree | Bin 0 -> 14329 bytes .doctrees/strategies/index.doctree | Bin 0 -> 102132 bytes .doctrees/strategies/produce.doctree | Bin 0 -> 11964 bytes .doctrees/strategies/reduce.doctree | Bin 0 -> 22838 bytes .doctrees/strategies/run_task.doctree | Bin 0 -> 9793 bytes .../strategies/run_task_in_threads.doctree | Bin 0 -> 12803 bytes .../run_task_with_multiprocessing.doctree | Bin 0 -> 49169 bytes .doctrees/strategies/unfold.doctree | Bin 0 -> 11082 bytes .doctrees/what_for.doctree | Bin 0 -> 30633 bytes .nojekyll | 0 _images/arroyo-banner.png | Bin 0 -> 71723 bytes _images/arroyo_processing.png | Bin 0 -> 19166 bytes _images/consumer_groups.png | Bin 0 -> 23512 bytes _images/kafka_producer.png | Bin 0 -> 16532 bytes _sources/architecture.rst.txt | 120 +++ _sources/backpressure.rst.txt | 43 + _sources/dlqs.rst.txt | 21 + _sources/getstarted.rst.txt | 226 +++++ _sources/index.rst.txt | 16 + _sources/intro.rst.txt | 15 + _sources/metrics.rst.txt | 53 + _sources/offsets.rst.txt | 37 + _sources/strategies/batching.rst.txt | 10 + _sources/strategies/commit_offsets.rst.txt | 8 + _sources/strategies/filter.rst.txt | 5 + _sources/strategies/healthcheck.rst.txt | 74 ++ _sources/strategies/index.rst.txt | 38 + _sources/strategies/produce.rst.txt | 5 + _sources/strategies/reduce.rst.txt | 7 + _sources/strategies/run_task.rst.txt | 5 + .../strategies/run_task_in_threads.rst.txt | 5 + .../run_task_with_multiprocessing.rst.txt | 5 + _sources/strategies/unfold.rst.txt | 7 + _sources/what_for.rst.txt | 276 ++++++ _static/arroyo-banner.png | Bin 0 -> 71723 bytes _static/arroyo-logo.png | Bin 0 -> 13031 bytes _static/basic.css | 921 ++++++++++++++++++ _static/custom.css | 10 + _static/diagrams/arroyo_processing.png | Bin 0 -> 19166 bytes _static/diagrams/consumer_groups.png | Bin 0 -> 23512 bytes _static/diagrams/kafka_producer.png | Bin 0 -> 16532 bytes _static/doctools.js | 156 +++ _static/documentation_options.js | 14 + _static/file.png | Bin 0 -> 286 bytes _static/language_data.js | 199 ++++ _static/minus.png | Bin 0 -> 90 bytes _static/plus.png | Bin 0 -> 90 bytes _static/print.css | 29 + _static/pygments.css | 63 ++ _static/searchtools.js | 566 +++++++++++ _static/shibuya.css | 1 + _static/shibuya.js | 1 + _static/sphinx_highlight.js | 144 +++ architecture.html | 321 ++++++ backpressure.html | 249 +++++ dlqs.html | 283 ++++++ genindex.html | 551 +++++++++++ getstarted.html | 427 ++++++++ index.html | 228 +++++ intro.html | 205 ++++ metrics.html | 366 +++++++ objects.inv | Bin 0 -> 1299 bytes offsets.html | 243 +++++ py-modindex.html | 210 ++++ search.html | 154 +++ searchindex.js | 1 + strategies/batching.html | 293 ++++++ strategies/commit_offsets.html | 235 +++++ strategies/filter.html | 248 +++++ strategies/healthcheck.html | 291 ++++++ strategies/index.html | 559 +++++++++++ strategies/produce.html | 241 +++++ strategies/reduce.html | 269 +++++ strategies/run_task.html | 232 +++++ strategies/run_task_in_threads.html | 239 +++++ strategies/run_task_with_multiprocessing.html | 353 +++++++ strategies/unfold.html | 238 +++++ what_for.html | 482 +++++++++ 91 files changed, 10002 insertions(+) create mode 100644 .buildinfo create mode 100644 .doctrees/architecture.doctree create mode 100644 .doctrees/backpressure.doctree create mode 100644 .doctrees/dlqs.doctree create mode 100644 .doctrees/environment.pickle create mode 100644 .doctrees/getstarted.doctree create mode 100644 .doctrees/index.doctree create mode 100644 .doctrees/intro.doctree create mode 100644 .doctrees/metrics.doctree create mode 100644 .doctrees/offsets.doctree create mode 100644 .doctrees/strategies/batching.doctree create mode 100644 .doctrees/strategies/commit_offsets.doctree create mode 100644 .doctrees/strategies/filter.doctree create mode 100644 .doctrees/strategies/healthcheck.doctree create mode 100644 .doctrees/strategies/index.doctree create mode 100644 .doctrees/strategies/produce.doctree create mode 100644 .doctrees/strategies/reduce.doctree create mode 100644 .doctrees/strategies/run_task.doctree create mode 100644 .doctrees/strategies/run_task_in_threads.doctree create mode 100644 .doctrees/strategies/run_task_with_multiprocessing.doctree create mode 100644 .doctrees/strategies/unfold.doctree create mode 100644 .doctrees/what_for.doctree create mode 100644 .nojekyll create mode 100644 _images/arroyo-banner.png create mode 100644 _images/arroyo_processing.png create mode 100644 _images/consumer_groups.png create mode 100644 _images/kafka_producer.png create mode 100644 _sources/architecture.rst.txt create mode 100644 _sources/backpressure.rst.txt create mode 100644 _sources/dlqs.rst.txt create mode 100644 _sources/getstarted.rst.txt create mode 100644 _sources/index.rst.txt create mode 100644 _sources/intro.rst.txt create mode 100644 _sources/metrics.rst.txt create mode 100644 _sources/offsets.rst.txt create mode 100644 _sources/strategies/batching.rst.txt create mode 100644 _sources/strategies/commit_offsets.rst.txt create mode 100644 _sources/strategies/filter.rst.txt create mode 100644 _sources/strategies/healthcheck.rst.txt create mode 100644 _sources/strategies/index.rst.txt create mode 100644 _sources/strategies/produce.rst.txt create mode 100644 _sources/strategies/reduce.rst.txt create mode 100644 _sources/strategies/run_task.rst.txt create mode 100644 _sources/strategies/run_task_in_threads.rst.txt create mode 100644 _sources/strategies/run_task_with_multiprocessing.rst.txt create mode 100644 _sources/strategies/unfold.rst.txt create mode 100644 _sources/what_for.rst.txt create mode 100644 _static/arroyo-banner.png create mode 100644 _static/arroyo-logo.png create mode 100644 _static/basic.css create mode 100644 _static/custom.css create mode 100644 _static/diagrams/arroyo_processing.png create mode 100644 _static/diagrams/consumer_groups.png create mode 100644 _static/diagrams/kafka_producer.png create mode 100644 _static/doctools.js create mode 100644 _static/documentation_options.js create mode 100644 _static/file.png create mode 100644 _static/language_data.js create mode 100644 _static/minus.png create mode 100644 _static/plus.png create mode 100644 _static/print.css create mode 100644 _static/pygments.css create mode 100644 _static/searchtools.js create mode 100644 _static/shibuya.css create mode 100644 _static/shibuya.js create mode 100644 _static/sphinx_highlight.js create mode 100644 architecture.html create mode 100644 backpressure.html create mode 100644 dlqs.html create mode 100644 genindex.html create mode 100644 getstarted.html create mode 100644 index.html create mode 100644 intro.html create mode 100644 metrics.html create mode 100644 objects.inv create mode 100644 offsets.html create mode 100644 py-modindex.html create mode 100644 search.html create mode 100644 searchindex.js create mode 100644 strategies/batching.html create mode 100644 strategies/commit_offsets.html create mode 100644 strategies/filter.html create mode 100644 strategies/healthcheck.html create mode 100644 strategies/index.html create mode 100644 strategies/produce.html create mode 100644 strategies/reduce.html create mode 100644 strategies/run_task.html create mode 100644 strategies/run_task_in_threads.html create mode 100644 strategies/run_task_with_multiprocessing.html create mode 100644 strategies/unfold.html create mode 100644 what_for.html diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..fc936790 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 9db9da0647afe63ce71f2b065b7306e5 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/architecture.doctree b/.doctrees/architecture.doctree new file mode 100644 index 0000000000000000000000000000000000000000..90a3016abb986181e57a11bf579d448a6eb72fc8 GIT binary patch literal 25729 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 literal 0 HcmV?d00001 diff --git a/.doctrees/backpressure.doctree b/.doctrees/backpressure.doctree new file mode 100644 index 0000000000000000000000000000000000000000..59223eb20d4ecd64a1628a3b2c15e3c64d47ae87 GIT binary patch literal 7799 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 literal 0 HcmV?d00001 diff --git a/.doctrees/dlqs.doctree b/.doctrees/dlqs.doctree new file mode 100644 index 0000000000000000000000000000000000000000..4efc44a2fdd6be8450e58c42b4cde1f38cfe01e7 GIT binary patch literal 29691 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 literal 0 HcmV?d00001 diff --git a/.doctrees/getstarted.doctree b/.doctrees/getstarted.doctree new file mode 100644 index 0000000000000000000000000000000000000000..be0a912275b3f32ea05b0b5e056f522825e1f8db GIT binary patch literal 22281 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 W#Xp1MhuJ|)k+2RLR5X^O;XeUngweJD literal 0 HcmV?d00001 diff --git a/.doctrees/intro.doctree b/.doctrees/intro.doctree new file mode 100644 index 0000000000000000000000000000000000000000..4cbdf306890e48354f9bf1c985fd34b0c6fb02a2 GIT binary patch literal 4392 zcmcIn-;W$e5w?BVz1zLJy&tio0I@VkBsrVhE;3k3PKv;a07WPK5D+Lrr*Y3r&vt8P zrYGG!zS{>2B4HGxeoOO+5dQ;0{BOMQ)y(Yd?i~rf7*1NC=eq|t z>OZ$3Rr(2LD8?}p4;Eu+f9Q}S#>CI()(%{XJmK#1>N!Sd#7E2+xmAY$=M z^R!u08}e=gmb~jXcD%dw!9&O@Exr5JS2_wWVpb$FVT~8==6x@|Ybv*C*_6zAF?9Ws z0U+zeh8u((q8RlTKt7xZmGgGFfo{xQfKU z4Pb>$H7ms`+`oNPV;e{luppC>W_li26+{)TEihJdmdj!qu(Hf#jN4F!39Mi?i1CHH z4^pl2A?3*CFcxsb64q%}NC+s#AFKcNLlv!?;(NIY-{R}A>&F+N;9 z24LK?(q=paEjj3d_*%pqJUzJLSOfk8w|B|o6$3wCHSqN~{S^3o2y7m>qnADLilOzB z{H()wXBCx&!^0&~D=I$yCcfSruV`3vg1;0iw*Dh4j@ys{-=9jP!60X{$PhI`bA&@x z#1thglNQ7|Ssd${yOuQg?B!3sVDt8h-vhTDRawSum`S9BC1*sRvg8qE2AT<_<@w6A z`}k2{xD8Yqun2j8)u%FnEKDgiPbkb|mFM6#GN@tGD_NpM{^hzbZ64^tN_;_vL8bqp zg(X~nx;|XHfa{O{EmQmfi#~63Q^ug2`n)6ZPkxE?yp9v#F)~NeOy|HbB`9-N;IX6U zGN62^dBieS!~pIJM1O4|dUeH1Wd3%2WJWmjUtS5BA3rKU8BiowcvvE>W?ZiVMKtPg zI@gF9JT_G!ZGZ>UUggd|T3}vT?-G}PULTh|;PUtD_@1`5Ym8K#jY;`?$ zI}1ruL%1zam~IDU-$7T#;qfmlFA~&6zh-zBO_xDjUsblOtbgo!^}~ga!IYzZVOD7x z)HRW1d5OVxV-`88m|-|308SG zsBC)t{;`qxertU)#?|wEy$1G{=tuc=SZjVCG{j(s()vp z9+Aq3ugKkF$!%KOKn|D)n`baKuq;9dp&j$5Tkb9hnTK6$cJ*p#N@Bz=+dBRlDrFC`l31h4YMQWjD9-PS|o*;hba6xcxVdPGXRkM(z z{>wr%#guDnw+~1&T{$%YO-_5^HhA%rS~0iPm)c6ar9>h-&^q-Gli zp`(#d6fV{^j;%_Xb!ULa%=1WP-Hq2vZ(kC2s|RZu2Meq9ro%P;$fnv-`o42nS385J z3^^iJ6=eYLwqu1lw<%L`{*PMumpJot{|Wex1{jgkRI5#h9(Ji>O}yQS>r2{}MVwU$ VB2-Q3eufEUvo`Rlc&MWBzX8u?nHK;6 literal 0 HcmV?d00001 diff --git a/.doctrees/metrics.doctree b/.doctrees/metrics.doctree new file mode 100644 index 0000000000000000000000000000000000000000..932cf45ec8e2ad781efbd5eb00d857f07870dfb0 GIT binary patch literal 39885 zcmeHQdyE}ddG~s~PuuH95|h+%GGGPon%!$cp-r9GG(e%ocmX>hfaPA#y?5@NnVmax zGY_v90WAbV+>Y8tT!f&a^dYr>6g6$tN>G$P+DcFgYLS{0QU2pCQ3+bLQp-#IedjT+ zJNMk#y=ym>Hd5AiX3ja^<9z4)zVm(O@oQ5b`P<*w#r}&A1U=Jouh;Ze%k^4D(2r+Z zUNh<%ZrJ~Df9ZYw_w*OzIbUB7yvT1F{dgBjG)>EC`G(uS(vKIYcxX96P1K(WjAm$g zZc^QxGN;X%EB!@tE}jal&@nQf;+YFZ=v&R8Peo8-&m+cl0-b*NV4q_#-O~Xx?3;(; zxq5=6IT=q2+*ac~j^!Ht)u^Gz^LmJO8&L?Fh=xh46%f8NO-By`yu|M*SMTy)v#qF? zJ~Z^^ns2nJOcc+AdWSys%>(99bDw#)IcXk?fBux|b&XSgEuUVeY!1WBj?fG5ZZ5o=_rtg-YVpP)}F^wRFgpSd|jh@xi9cM!e z^e&*aG|!)JMD4cW7rl09xSB_B@j-(yd2VZ| z#>L~v4u6L6M~o7P=qWCutL8m45X^fa{pO1?wvOZf`|$q>{J#XrHeY70n8(azNaVDX zY)EE}4|;Pde(D@L!iS8Iq(N**3erwr);7FI>qZbSbWz*tL=XZ!5k4A229qoZAr*i$ z1=J9Unv_roMCdg=XTD+JyP-9GLk}&tLrtgRCOiKHgiy-uGn?o3d?~l@dc?E>t*N^h zh+4~Y4b8FE42pno5yE=2A{cjzhi}luRHaI<2Bc^y6Nu8UAx-8*VVYD zt8uk2`_k(6JU`Sfa9y`7eyl=s&d+O1>1r1?#Medf@6zdcjs9yHZD=v{KG~f`{*K-U zhSOfwNc*17w70BX)13&f9(7@7E?aK6thF6a53guvwELGeDD2?0_U0a0A>FzB2p;Ln zDtOA9UeZ?1vPS`)Kpof4NdzFpO)ql61+B5c_V07+`6F&BL#>wC~;noUP=W?KM zP~s{01ekK%h!;$&V>F91J(mVJ$-P;IF zOhd@ed57?G5)U4J&R*%~$l1w3`652_@HO3X^afmJVW^}DF8Pw0-k`eaB}96>ICH?3 zfzUf8{I{PxC=4z6)bNIcX?+tn%=7acsa2R9m^JbCGBY>FwbiKGfZ>AAj;T!mP6V*5 zP?z1v2`%_rO}wQx8+zC@S)G>%bDqvHYM9p4Lp@lllUl78s@7Q5T424)sC9$ROO^*9 zH#RWqx|v`ZfD*tJNY->rFyPTLFO)Gz!_3MJ*ldS9hOP0$i^5(M!gzqIO9RNE3$e*DM;0J)sWFeKq)STLGhFUoVOHouO5j#mEh(+sY)Fwz zAc#^hy{yX$(0xK9v8Vd9^GgLM>yG3cU@;R~t})o@d1tX1QF zyAA+X8EigpsgruT$~*r0So~p)*1T&7h&bN*);ZLRAb^9^395|8Bi$i%3p~__j^)Zc z6s_f^lEyV1K^``(hLQsSpZWm3lx3aNUo_`ScqdwGTjOz%w>`*05$7@?1udg#wJ@H* z0N+@VGC_lt5Q0#pfrzHpgll$u#3B)` zGD6~wXro+)bQ0bbnn3bNAR%=1V&pyo8~GSaVVV%UP01{!i3bchqWMT2t-OiBQgsCMHt;^K|otpqTvIp(=?q{t!0GlYtr%?D8f+F zE}7nXpy3ZEUXse~d4ayvXj#%SB~x4&Hc0grIgmh2uzLh{R9lQ(iv0({61)k7d9%K>jhP>80gV9|s1Bd9r_sueNYpEbT3qGHUuxoFs|cZWdF)~Ny? z)WT%87_YCMt!2xedhHJRoEtoEJn*lX3>F$WPG;%qVPm>tqXHB^o;BdQIws@=mfn%dLn{Mgl2= zK@1Lr5#ceO6Bt1(-X%v0nHop$X&zVtlghs>GZuDfo=Ofgg14|!#4{vB(AyXULr|4K zE22w$VEkju$cj|~Y0-@WJ#BlDmc5Zj`mK=x$tKf9Q&8e$2kr(W>v8shrKB?KhF{2% z0`Q011~m1kk)KwrgbsZyzB8UaSAmY`8G5pN;?)#HYT5O}@iU@CfvCMa?Q z^ zu~mU$$#Wg6--23iqi;H9SGk^JFRk2mu~u34!~Xe+AiHX#CKpRYNa@JstnndTF49=x zk)EKh%Qdcp9VF<0iP%H?UeE2Qr?s~1rF&->kn%R$!^3N+G zl$Be!**B+G!@f=o|5GqpAjnq_o6pEKDVsuSn&RD9<{zKnD^&t*kuLzH01I2(o?kn< z1Om$5*F<$Cio4=H*tgIeVBjKnyFgzM9mE2Dq{?&q4(=3fFP@|&Ma$aBlWXhri?8CN z$_H3wmUBn;G`FE4e#Pa7j)&N&a9TUTC_8a>S$jwVtFv`Ur?sSrcH-<=EV^cUAdbXS ztVTZ-p|52{D2p|3C_`C1p-C~sue614Wn0KE`Hm;nA^L@N-`_w-e=R$jib6)?l_cV; zDEK^YJl40M0BG=^rmYZ=SfoG@5?1%~J?AIbpxDQGk4-5Eoo5+vM`?Y@lp$YJM*Uq4i#7Ws#_?7gFy`rQ%p6~`_*nSx!(LRBHn8>jHqOo2ta()k6 zG|2WB9f|ov3i<2^$nGHIhq91Ui!@{m+4u3{FJ_3^FU3Dnsm8NX>u~Pb%h`{+PbR#g zpDD_ZQG;w7QrR94`vH6|j(EwfOZXNw>@!(7(_Hb%evywUJVOodTp2vUBMxtqJW>~r z?_yKZIynsWL?H19NxlJ{W#3Ea4#<9{(JwJS0b9Z#Ed6+%29?*KlxsgX$m3~lHT&`H zWl9Iz$G9Rlr{h`dsB)Ot*@plxmLwhf&+tK*@&M9b zrhd(6K+LVN9V$CScwLIqyprtFgxNj!uFkIMcc5##drMyT;6ak}67y+jH_oYzxPU zmuDMaN;l^~d6v`RPJxq5?UxGcP9Qik*V5q{gRfh7rsLJ&I?TP!;i`-@y z4NN^IlKp`AmBRk95_UY%8}ws-NL7y70`y3^-@98y-4MCwjprSX%>D&#cy`76up*2W z9@Vd7AxOqw6w}TlakfrM^u217GP54+VK>?>ud7>bKi-XqL_C8R&__n!{&nzyeMj)2 zV}x)CxQbh)xktPg<*;C_X|=5;_M*&TLL>YFX4$d(WaBh<1elR059Ao3b=1BK{}gxN zRuF=Wr&8FmE60xTD8I>MCht)m7F#1T+P6%Mr&ux0eGF~>l=Ag;O1>&-_(evv{UhL( zjNl<6dr=K#2A_+%)D|+!p^VnmSCt@!$gChCH}3ZiGV~s_ElEt|bQ0wL3li{dDQgq&&akJiY~NN%Kvfd{KnY@q1PBsJ zdw7a%HO>(6XKDyr?PCFF>|V~RlL})uUm@$JSI|HA@y*vGJiIcMw1;X+Dd7*PLV8Zg zVgq%XUa~O*SZ%bu&MpVj3@9s&ZRj($! z@gyeDnB9^|6*hDs@9U3aM}Jz@gO{bKOkB=T^CBfRN`)ezl=5v7lavgU`;<_!BPQ#1 zjMnM|WsLD&%BSUoPsM;2mdjN znz)kb1WQT5wsgX}5`?-F@*1<;fPYZg{GP38jO14}}^s-SGQr02Kx45L(G8 zKn`YXNy=N}3YKp4$o#CD;Bv1{*q~g5dg4r?T+U<|`UPeC%J_6uGx`-Jh#^8D8lQ`& zEtjIlnR#Z+drQvi3lj1jB{a$uwRJ3$s`F`7Zq5?l7DPQd7^jY1tbX`-{!OZKAXjB^i5+f%{6P{s0}X$Hf;@|0|2BRWW~gb};6%m4f#eXc zTt4;MUr|{qL;}G6b3z_5K+thYR91B#1zUcLs-$FRm{E+kF7m+7beBcsi^(1l9J0@` z9)Lf~gF|nmN0x2PJkPk;Tt=%lZp8bG?j4o^a?-TWj(28&UN2wx6{q)w$|MD~oZ7h*!fE)1H{ z_S`SjsFaW(FvS59(Jw_DYfy zj}?;!$>DUFfZ-NIjuE$*kL`}1p!kH6D@y0`W2jm&jPfUHD5@|Dhca5^KcfUO#Qzf{ z(F-m1Gpp@$4LUw3& zT50hsvTVRD95*ph%BS+|(A`Q3D)4Evpr2HN7$WGK=!6H3ut-n}k&u1sb7+d{%MB?vVMrGvSc9r}P8Kt(|sP=I4+hxk~?8)KzwRn-LjuA1O- z*Gib6Dz4S1lcr6k@ zGc&maP$sx3lR&o(RLvxUWSkOF+olL^z`Io@f>zGSi!bP|2!1rPFHcXyxtO>=B6IzP zjJj^JRvI-s2m*&MlFmwtObRuK5S|p;FDk3LHIo#QEI?97GNu^wRwae(RY0~+0H*zB z`n5>E-je)!D}LRuFS5Uv=x<4;hvPm@riaeg!^-Hz%4weC$}|seZFr6c*9UpZi>-L; zxozH?+vO<;!cABscABh7K^GjT5^8@TZ#8*MLGnj?$!{#w$VYRB7%~D=l=AGb5^9fS zcFraM;#=AAgK3>u#LHb_my>Ed9L7NN@A4yL_jGW@`YT%A1k3`2aGCo zGT?QLn=2^gQ+cl7vq}mo@M*N5e?bXih@fwx6TYHuzoOjUnocOs6?{)g!M1e5|0qGI zJ0b7EmFEg(=2ZT{wvcd#5`>zB(!pE|gdSG|s3=GS3Xp>tWA?zuLf#lxFm$6w<{34? zMqlB`RTmeTR-=|r7A%olEtN`v{sf!Qf z3d+MJW915-R5BtIVweP=S6naHRT6*oKB<%l7pj$7f2&`&s6Su8Tda< z=<&e+r$l8{A7ujnk}w4RCAr0r=;*-z=Kzxj{y$H@Sm2-isuK9;xFf=yN<}dSlj6(I z{gUT^73&C0#c^Z#{YET9@mzxF^9iEtmkLpw^eL94Zg~^RE0d$YlRL4IrNAMd{D73w zvmS8}R{1`ZfwuBF3VAT;&D?=dg2JdA#oGqz$m@Lz>5`cO9CK-ZFKOXc_rPGX z;LrfmWmdA}OUi_wCM1lJLP+^w|Ag8rNg+Jg<>%{dMFL9qeI)G(onE${enu3MoJgKi z`fs0C34zifJcz0lBOfnOLs3OOIF!+D=gXBKhWKoPgk0n!cP4B3Vuz$i%E#BJ!B=$i z2j+|FBajvD|B(HrnUkqj$<&Bbsm`*l+(asYGj6yUldh5QH21Og^QnZ}N_1VB5Q`h% zg;onil+Xf8jaCboQbD!5!_cKWQcedX-5s-S#P2|_I> zx!LIy^Dm@v5KpOGd{qf&EAvxM;U=|)y7<8SwA>btH9!4tB_nR){8TYO{u4MA2S^qZ zser}Yw3I6;XYFsnZ5eNFYEH8g4D4M%j2~NY=U)7x$0x-}1-A{jXqg$Pbe!N;epmQp zqh_Ej;rh^h^IFGnak99ByOBK?e;P*SK6t!p;==UErK^UykBzH}aM5!R7_E5^Hv&hE z0Jp7Ub3X0?#yzyUW4((VvY8%(d~1NEqwgMYZ@71!?P@tQ{*G`x!NH@VvPweInP$Rp z%#39>44H4@P-`4ON*5pGCIx&^+^eX=*`m0gqhD-p%zllUa@rjA+{Ad%d^VocdlmqR z6EFFr^2!d}o{yg{(Eo-#}vDYwtpVye#T62s6I^YP?Ur zVW-fn#jpz7ipmX-| z(9&_fOsIEzc-YGU(n;xSc$^oHk?-JXKb=rc_w&+M0G{HfRm6weo)_Z&b|drg{6xGz z!1?HI)U98KE7!#hE%5?QE3@;8QKus3zOL%hz8Mg{VKC@RniIL0-@>7U;n&zrcBw=N#1;zM*7bRE=$QINi!Y8j2FgZ371Ux!O)#-d$A@8ZoI zoq>*vp_^;{r{V>6*I(Umn;xAki___%u)XrY3On@u?)=BPfm=!ZI=d#@z!_}QglZEf z!5-k8&a^VcTIt8f3SSCM*gl3uyujN{agep|&VMLWjt{acsKF=`EOJ0oKi-eqt~-(5 zF~IQ_o_8BK$o4j$#pQ6#4xOJ1Fmx@Q)t6pG4Ew6sPOCog;m)3iMQP0+7QqsiH zNLFBR5j{|ES%Kbgh!D4p6Zlu-896jC%=Uqp0JmH7bB`f4qF9}-Xr?=F;v@76Kmx-j z?S#Ie)>`QDy}rJlJVHbd(fESoxE%a$Hw(?v zo3#0t%H}axbrRV%TL;ZT)#0}&Q-9p}v_c$Jj{yuj26fVnVr%yeFL#fiksOpY~`^PzJk2Ou)4AMl$ z^YI2QGZv!sTGYeoHVeQmv_kNo>wz1P9ICB#qKM;pEDVmY&d;M{f^&#WKd^#+MH_TA71VcpIQN#;7_--Ct(`nf(-3O0 z_cQd8|6a7;K(_C7_+x(D{HXnEdU^rnn zpos@$v4{Ul=JV`eEOvSp+aULKmxR`Qv`-(*D;C|fidFFaF=7v z3@1a5rM*ayUIeI7qBofW&2=vO41I=N^anK*k>iY%710Bh<`CRnGyjZwbu8Y3u=}5=C(`8OylSvY39in2?Rnlk-e(o;cCoK*g^J(dHo6i_D(WO{3eZNs%oG|m1#@pt(I7)fBU5uC+Fs<`w zRA{V}R(2u^6|G_+h?!Do#B(oYiF;ZMi>!Sav0yjnV;WPK1wi#CZ8^oZs?`p21?^wBaiSPu&3!C~O>&lru8}_e zm6hU!k}EHj+GB;5USKU(TW#pQtG!5hMdqPzDhv9Tu(V)tJUuYh+Y>zXvRnpSDYE=n z=AITz53q8@CY%I8d=_)f!=ZD?IrG0(qw+ZnzU2(QEnXnEiWlKa@e+dOW&B>j?=pTH z@RN8|ToISVChXg*{RBG?U0{oz`TDNlwQ&Miik$52MRDwnxR+5(gk;B#sg%x{=98)S zAY$Im?Z$@hRqgMvK+AkO404Wf{$8Yo52qsV0SdJ<9Q*;UQ9>4RXeWT(VQkEyp-Cg0 zrJ*O-15S?2+h$VHeNZ`nT%;Clo=gL7MdVy*#DsmWygBHoFPOs8;Qdgh+28Q>4dTefv;=nNz#Uw!B0u40aMX7g#jdvN51B>_A6k&_eDOmd8 zC#k{~5_;oYCYxR~sq!3*_lJk-Vr+K3Vk|`e2b%#9k+F4 zJx;+>je?bHYu#3A-CTP|)buE7{oL(|-za1{b3RV}i;en+gjKziAJU=1I+Q%#I6gP$G7w5o6dMCAO^!k!oz}<)k1$U}69G8ovY3dh(4ZO1 z8M%l3$)e0|!bnRoHikg#Xt88=GbYkeQ>A$_99*+Gkg7M-2}j~(6CN-ZN!Lg>!=bn1 z#@&{26ij!Bz(`1yRe{M!yvleGji;0jRjf14`G*DetSQLifQUg-V4I!E5v*DoyM9u0 zj?6a^RZ$>7m$BS~mhBYGOQJMNisX^WymcgFiQ_xktMwjj*G?t1Q7^e(omH2mq>9>& zvJ9+ixi95B#Phl(->}HtvML)ZQRq!}P;XGS3G zv1MoE+%^wY1s;UlgZ(s=Y#hGn?cCbFcHO^y{f__M^=r4be`Af#JeWtxl#OESG8tt= zEscKuy^Wp@2*2opu*0J(vk_J!d#M|D9Wj6Jig`M7eqovO%_GHaXV&jX`F|Wm`G5WZ z5%UbDUFxE$j*3Bxw2p``k7Cwe6Xw1hQadUaJj)^pw_mxs|r zyJgL2`D|O(sl&D`^YL9!oXzII<+Ka9gIJ;5NveYMEmxJ;X-{Exi{c(i2H5B{&nPoy zULY9$VPox9SNMKGWY%;;SlSRGVJR zQ2gTg13dQZ7F#|vi!nET$@Elr9sT zCs?H`U-z`sEG}=%nL#~Ka&g>4OCRPBI4!FDlUa#U*vQAhQHB^*ntq|jSAKa#MR>kA+v#&u z_H$pLloj(F7AI8$U7A&A>5i11l~S5Z2YL>OxW9uqHY-kUt3&{Y zFi~t#wOk_z77qcV@4GmI;eQA!3z}qy19Mn-#jS z@Y^PHJVJOaheeY4O$frUwgEdH&r=qYz*XB~gPYvnHf4$zq4a@%j5_6tcz*Xw8zq7E zA4DkU*$`dz!${H56AP)dT&SS|m@Q#33Sh7}gV5z_m_LqUcOP_)o-heG#$u7%gKP+w zpTrFrTt&ixzhh>N@P)`pC#e3%5iYpOo2M?Dm5gU?C7c$sL@gtxxKH3P=Y`gpy1KQ6 zW;M(#UkznG*(%Lh8fg{4NFT)yxJO&k6{7>=q6GAh$(TbUT?g)#h?!)>LqK>66$IxRlbj7OYS-rpi(((OCn8#_ z_F8qRiC~S#j@BNU6FhxD*NSG*(FyR2P>j+r0ywmGEWe~9VOZqsL?&&e-jwL|2plBrccd!nnBNxO55>JiI?z5-C{|Z z<*wtbq~#!j`$-i@cP)g^dYn_a+v3JyA#ijul5rCYcIfj58k^Dm8HxRRR{PQE8Tp{v zToZ849+Xw}V21;H1hOD*D9y=0#xabHHDCu>xK_1)1`~W*-T@MjR0C6W6^(pwx*?I7 f=95jcb>GP-4dNoCaGB6ogOGTxq6FH!i_!2u;&zve literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/batching.doctree b/.doctrees/strategies/batching.doctree new file mode 100644 index 0000000000000000000000000000000000000000..993fd922d1b02cda8e854e51d1ca65418e01bc2b GIT binary patch literal 25670 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 RC>E{ULMP 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 eK2!!@EEcH literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/healthcheck.doctree b/.doctrees/strategies/healthcheck.doctree new file mode 100644 index 0000000000000000000000000000000000000000..cc69e6c6cfe487857749d5a2f064fd4412183700 GIT binary patch literal 14329 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 P;4O~~MyXqM5ZC!H6=g(I literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/index.doctree b/.doctrees/strategies/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..eeab2bcccf3cd4eae8f07427470b27c2684b1eb9 GIT binary patch literal 102132 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 C?1b3> literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/reduce.doctree b/.doctrees/strategies/reduce.doctree new file mode 100644 index 0000000000000000000000000000000000000000..9168159b75e0879581376fd0c01f039259253ffc GIT binary patch literal 22838 zcmeHPdyE~|S@+uBr|sSNwQc1%og_`XZq|26)k^6SyUIhM)N~se1Br~enZ0-J&Wz{I z+|0wfTau87wq(^)QIVm5DF09iq*4?iR8)j0f0QCpBqSs#ul|7|At;qnPzzQ5;PLy; zW9HnM*>kVgPLoPlvVG^wIp6tS=R4nb&NtullfQi5ll%A|wvY^5FWhR`-EJ6log`;7 z-KdlGoiNQ`%Fn)#KbtSH+1TDpqAcz>IopRG9oGxGu@mN3b2d-iQ!hwba{P4SbW$%0 zi{b91JLOJa&6nI+Hko>9;ApSdkxNcD>p0fZV^PpOn^Q;hJ9ydIA_S_hKb{MWrUo|V zPjmMun{5{ey9d~m#B+@u47||E*Rpk+&Dm)hd+S*W`iPzbUN<4!r#pe2BxuC%$Dfh5@yL-Sr%^q5DqrS5eXJP2XE1OY#ZN-k` zXggB>0l{QNAhwdEv7I^_o|CM^obpzjfQ~yZ?$6di_$&ysH)4C>>P%XFr~{c~0Y+ND zGO;(D#9Fr#r)x!_Wm}yrNu$1Ht6ouT^|DZifpc_`-3$oHb&$LwNM3XAAjZ1y1UKC~ zA+fvh_a6K`gTH6NDfd42oO{|`23-dgr#O96sU2@PrEV$ZC_u4y_oHqWIOhZlTZ1_2 zfMPG)XqBvM3D)Iybz(N@B^aN-NEn=lY&J*9MoOxjra?l3?Nt&XbST`gqMkJlYM^{V zqkJDQ3%kyiCRMR23c_ooOhdtA=m|7$i5(o+UYxW01ap3PJQN;vr`FQkCSF`rxVWc< z@Z290i@PQOGageU39MlDKDBQ78nQg7A=i1Mz|Q9E-D7lX3D~&_{eA2p%vGnx&n0&s zY!cqI6Ax=O&0^i$Jn`j;eftFTrM|t@UboYZi=H2KRzX6#Y?Y0v*GFS7h-@@#D{Iwy zF5MoGK0aaxfxR9$SFSua4pEmcIY|}(nCcBMPSSc9%lIelAallq^0>VXoVr)9mVip- zt*?=moEF`^&`Ui#XkVw&G~#rO<3z4R-$|V~@Ze&UOn>4JU<6A;_y5*U z81Wwj>nDwr+TsccYtm)M8$?@-<9be8W4o%c^TWf`nyWUK8vGZ#YcQJ#>qhMrsOnew zk~zWElaLsYmzveg_r$829>2;NzhRnjP@nN1GCVS^?Y>FzBe`atKBsQ)$0t!)bk!kk_=>f2tJv;Bi@L@#I{7Xq=1 z*s*vQ>0gUk*dYpC22RK8d7XR*(Z%+v@E~(`_ZXI!_Ll8c0ey{3;D3Xouh%^Puh&>4 zWxe|brflk00Ps)1%Reo6d9u_)%>|PRT(Vr#OX{ZdrP^HZ*}oS?&%o+N8vMI32-y8& zfnBp^`tLOZ|CbtrpqdK!DDCtgHUn=|PzAhX*d%vl1)u&$(Nid;d|R^XvU$>7G}AwV zVWnpJ3-m~utJG4?V^B>01dXZdo&Px6$5TB?{9d&0!jPw5diaI&Ub^d-HBVeQ*)=si zq`^}HS6v zv{(5oO8HdIJ8qFEnit9`Gbu(<)VVdIY`w;;v*sE0%B)w}^$}>;qxy#8r*J z^JW5#EYuvPX5bfZ4e;i5_~cChAGr=U%)oDO9X43W%sjzf73)o~lFg#uG1F(#tBOb0 z?6V8UqS964+U}vpyDBH7%8R&i1!n`hx_C#1MyZXV(ptKCzilSJnWoQS&^U3(7tO$% zc`JdB)cmiQfj4Wu1YWv%Crw;!Fukg~W|{uRjEE*{J!-DTCSSycdh0#8zp6>9d4u|< znTBRbjSKvHw+49g`kg#r^b*F!yxDXgzX{+Y75Gjw@MZ;;Jg;kJgXvx|PcWup)`I3Y z+;rFVs#)}pnCUZ#zG9C}X0Fmz^#nyVNz zj?s?Hz?-=$fsfSrXU)KybzTB5jrOV0JgqN~WA#Cr5&uOqVw%)VM!dFG9x(dPhHJ<@ z`O=@PiMZL?f6h#7vxp_|I%69w&+nNh*ef^RaLZF?V6)}-WQMY&Lp-Eq|nl$1iyqqytDmY4EwPRH@C zJKf?=`K^drx$nGgR(nlBNlZw&VsC{jf81^SmqZ+jQmVn)M?z%!kx1_1i8ptVL`WT% zd1E13q_y!J6?&ay>wPax(UeBK7j4)UrJNKZyi|aF_4&_oz^^|48#f8M6v50vqq|!d zfj>gSc5nk*c(XgORT3pERy>!IkeoJ?o*bt)o}*22*9WqDSlwy zTsPVbG1{^FoDYfR^{9Ot8Cb;K7_S9ymT;u=j$J3y_Tt3~jYvdX;F+3jT-`XxkwE5W znLoge*6>u$(?W#+Z4Rq4$8Z{qo^JtF_V1wHr+h*TDzwPnzjscQqO6js+1%y?MkUIr zVU3<;b3M-qy27HDjFGo#NOR?{HI|7tlmRP8R&U?u9#_d4iQ=W+RMPP14YBcI!Nw2J zf5LnBY0`!KdzFK)~nCIq-A;e^hUqHgW5i@XL?I4t6)cI?J56fIEv;4_S1rz zCwW)@D*jWuwbbHLjBzPOzA-B?X4qCUJ_l&?3l6`$8!P63>jq(qR8ii*-G6A-zhMe+iy&FmT8bJnrAqfxo`~NvHkp; zo1`hRqlA9<+OQ2+atEq`-7grxdoR)Yi!x-_@|+Uu8EcKq^?Cl^S?k;d{)5}!CHD&j zh=YO;A|p~flyrB=_Ya4n9~F=x0n-0QG4`#(Or9J1<%06tO$-zJRG9!Z zy7Q8jdNwUVtKF`6E?N7%f<29PusI<94hBIZw2QpPoIHPW(j+&xIWU*NM;=}sHv?}z zypq7n!>hx(mP)OxAF9+cpzbkGt~vfUbU-ym1{4M2S_YK+G6i=?z4Pw`N)XCOzP;a! zdNbc7a82URD5aWsMswtU#0%y<>(xrbufSM`9XN-p>e$ zRyJPaiX18YXU#-5vrsOYee7tFn;Q+_XQxrDyVw)w3zayp@%2;2DcM9+%gyyaNkdNg z<645x8fR!u(pA7`*_0RZuK~+YjR~2_kK?L(@&)5;^szwC#tEPJl4h7Tc09=jgDA#l zF?}4XJ)K4L)ghhw`JdNGu83SyJ+-qTHP-(&x5B%-aMaiTXP66htf=jU{%d6S)n^Lg z3yj#o2T@_7i&SI8=mqqbM#kttyvZis$_4Z_U{uQrt#i}=bHV)5RnXW|%EJFTcqWct z{cnP;{=ea$A-}_ajg0eH$ zK@e@y6F*$TVJi-)gu83;?-1z#j)!U-Oec%!3tW7KiZAG_FhZn`Q@VI=(-pBDO(os| z49=>$+jO{#Z?!~hhv4b0hnVIvjjiXjHRIgX|2w(ZAeryV!6vmNd+=R|O%tRh-fGaa zBr^V|ggC0#0P?EdGuO*PAOU+^8zeOrz@6duN>JDTzRE%PU1gNGT+FWIUYB$sL>csyAOO zYJ3=j#)%p)n}IjS5EA%E2YB5Kyx9Skz)Ke0Jw9LSe$%uZtog{P87s|YF}Y5)e1{X# z9uC<6V=lw4vB;n%yyj$v7tNG33r_;CvudHDw;IbnW1eWQEW3S(W!35T6vj#FMylrL z%@j4OW?e4Lf%%urz>RVliTR(Ifg3Te3%x0!{;$n5>{Z&gE}{Mg7EW^#%fFf_Gzq8- zQFwih<`V*8!zx`hzUh(W1>jbRL;)GZYxM<{q*_XS0k1I|v0SnFCk56e0FJR6kO8!3Yy8$vJQQ zM5Vv;zOmI&g?wk^Dgf)=BL~CxDeg_5Xd%Je5Jk(|PgLGgA-HtP=47VJFefbziV{aC z4~B};Anjw5Zp}H<=4v?^WyVC2I${k6`O9+{-?76o1%(Tx$T_h#J=}I>DZQ6Pn5e@X zNmSz65@?|kPP8e`7f@2;x))`X;NlE;(oT%blns2hKBvIpfa@2oGq|BK!RxL>ZP#s>;vO zHdc#FRhATLhG|R6I82?QDC31w6lKzGYT;V7z~Ve)Z|s$>P@{e(m^g@?KuEX&8BS-Y31)@J&Aj*H45JkZ{S^TTSki1&DY$8H8#89pmHC->%c>oj!ILzKgicmB#4(i zq)gsxc$|}uSsdW$2<6UFeL#APi6_Oe89UaCq7)~cj`s561Uo{75yPzC-a^((KS#?v z&SJemyA$CkAw&l58apLgoWS8NZL*kcUVj6Z2$)e0kYx+k*x}gWcMXAa-2wadvpLts zy@Y(6WJjGXj|z054q8&SPIjI3Yy}XfGL>@>4a#R1^YV=5tYBl=DiR+Y9swG zqCEXb8 zs?FvF+!6;h`u5=$mBH*bq5-;=xL{ELnovtJu)~cEwG+YdE}r+Jf+ahS{Syho?XE+0 zTQCh(+*@N)I123{{Tdwcy3kdp=WXF2kz#9qDHMLAy{vFqSu9pL62S z4hY}^Z{f;K;xC&9iIa7sHtKny*KN+$AWEFJK9Xxm2bWD=;?Z>+V70qmLPd)}h{SSQ zEe$NQ!yqQXVi09@pf$2vyXOTU4#h4P=@%wJ)iAymQ3MOnP&N_fz}|$Y#3NMnD6KDO zPPhR@3_PUb<{!T844WS~gEBXih(Xz#0rVZX)8b%nchhu`tgft}IcW{H;YWn6DBf7f z*-7fj5kSv2QV1cQ6ylgc`?-65=)K_QeBA3)z*9>J{$2$hi`6ETz2?L%&q;fH4j6zH zH|+n_rw^r=gSmcCkE*rPsc3=nE6Tubg zK?js!I7X%d-hHK?*C*wr>VJGSQiaoNIdrDK?sTz)w}FD|pt$A^JJ~_6Yi$SRf`T?Y zOfs|({fq3Vtj-E$4SK???XUw*c%3SxvKe7cuzsP6xF_(iIMTML-NF^;D3F3`rKtD{ z6OL<8GT-djP%EXj@@7Em6%SLigiv-B-KVKh{PsUa+t&;DCtL=*YTSPxB4`@Mu zJqij%;ayKu8jIeuLl9@xtbEY1A^5PvaY}~&WEGZtgY6Hdr4!-H2(qDvI=GXA1i))- zFVm06_Lsn)kLQ=LOz`0b7Myg&#e{{0(VLO6JD+UBA@8eJ?FP7dV$05 z5W#^+&Q4WVzj`0P_g>X|{iVh?KlaR&`cE!}KDXWdj$v7@XR$DrvzBK@L*|P3VSMe& z@$2!LYzM~u(2D|-#c~QOOl~_?z})ywEEj3Hu${1zzTXO&DQwTpU*`?p)0-f zccQK#=L{hNyBi5eMN-VzR!AJTOveaAOyYOLHHOKrSu663LDw+%0@kB7k!%U0Pmf~0 z#4quAewokkRr&lT_l9gUh+LNioAXf{rfj3x?#V>B2ANO9d?(!?o+yNT^Eg|kmMs)I(W3sr78xCOar>Ir zJDCgxYf6(-@+{oY97DnyK(a_r^w0(xMHH0X=;aShPfevVuJs~UdEl1zhB)xa`p+AV zV{{$1yZc6}E<9ji=O)l$^jT&0_KOKx4_+`19M7=s+*#MM_X-V6f>h`BEfz+OzzZ(C zSPupB!9}f!j4ol*6rC4xv}XHP`1-8v2o^9aWlMW-4CM^yIak+Ij3G@fDNP!#>j|S0 ztmH>_Z#*r){g!rBq4DZ->)MS>^LpqTCfm~TCEC^Jo`XxO__iV&>Ww%JSa6fwBwD0y zQZivesAOh2ttBCFg?<$jSeb$`;#qR~er%MZ0y(EiyGC6$va-BLw)cn5mXZTO)(=?7 zf_p5ccVEG~FQxJAf5a!Yr&WBMPYi}EMS(cWOuQkVsRdUKflRe0U0&$_i%08!O`d}@ zZa{^KE4e^SDg>x8D{Gy9fxkv7e!WmJe}M3xh}Tx)Rb^}CQHxUJip<9aci*VvZkD)9 zSevB{j^^r}iCir!u8?%0b9kO(BV!e+fB6Z-od3rfmDTg4n#YgHseFt#`z>U@x}7WiNYr3hl8yor|nSmdJpFK6ZH0rTyN96xt(`Q z68^JB!rzXWgRFcKvV&QKoKsQ$bH;FPmsV=#g6Y9ZJ@q3j!~a$?OL_npG0eqDXRbQy z@V}o{?}KOSML1gZ;|e-ojX)($eWHGw6KHC11tdn)v^t`uvCV7Hd?I}%hcsl-={qGs zZq^HOw7yCnFq!i1e}M9O?py06p6%08J}!t3?$=YE97oA<$I;VDb5)7&x9X{%3N$CY z{$&%&I%Ub=uyxLJ+gr7CBO zA~UvgN*NkUGkIno{Ip&P6NMZ61TT%IlZnTM!LRCxPtIFczPK8qh8F(=1z%^ zt8}RX_L4qZXKK$Ar_$%;kvvx2`%xoMrn6&Fe5qcP$tWH-$b-zuryrE`bgiCvtwE0E z{Nwe+YdIgc_JqXqnfeV*W##ud@nmK{_L%WXy=--ssic*<2whoP(pV(})i0D!3{f4l zbt=;9`IQ($6c!HYe(@dTv9th{RYyt`w+$+Tqmqw%XDsKax`A5|+70nYsYNy)@s^`v zB5z7uksU`}r1?WRrwh*{CPf$z-XtwQ{0c5yYBpU%9KXm{6HdYT3v@L>I-8P7xytlh zQEsGU<#FnSv`PGaVEDXrX_TM(v=Q2-Mio)C3l22lX((Z7hGs^g@P?Y7*GRSOey@4- ze3(>nJDKIKbkEiL3; zls+RU@#3Gg`ZVlIiXCHyFQiS|=MM*Gm%dtVCED*+XpdHb%T-1)!1rkNr2#PnEUw5~?}M@ma8%_kxof3mRRPD$2sr9rds~T= z_*dp{)e`qwQXxq%;FW-o9)t$J1|iu(&`?E`!Eb1&N~5K5%k`3G+@YLLe^RgQ02P!a z*GqjmOs6OW?5K(abp{pe(GM%6S>re4EL?blT7C#qsZP|Krsj;SrAMUZ5JhH^0ta7D znuA9hJ8ygPb$JmH!wnr(hST9feU$Z+wr4}2$Kk}=Q*tg_!z>IV+HYDeno&SaRXuN^ z&Sx`8D^<>h@Do(H&>OyxH+y@5ifvXbo1ZtF2z|(`Ff5y1B;aWA4qw`l?LI?$)DT_} zV_?BuLtzYk49+DRQZCrTa4sE2frHTk#a?Q{(o<~QNYpKtd!8rIv|*)(+tYG^dd_Y% z)c1Q{FpM#?h!AS~y6Fw6l^ufQrDTRVOwH)`ZNYU_+5+>~F?}KJ4e!YLfcah^bcfwz zP~RCj#|l-SwT^@a?GxU`MogBK!LLIo>M=D= zhPvaKMylFXljF=}!tjZ|LCZ>oczZAM5uWK=6!n2g8V3%69?!Jh9x#vvhGhyBVbrax zvxfv;>UJw{q|Zq9Vqj+2Wfolc04#8ZD*K^)+{CIqouMl4==f}g0tM?t_>;ROB*DALgd&LQw22-WTta4vu;Kuh3b8oL5X$CYNK_ArM)R}ywgVWD8e<_j+WmGCP zEtq!F_a{$CW+?b%>k@mEXOeYrZ=iVC^_(2&YU#zwWWKsRLb09gs$NfKv4nB} literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/run_task_in_threads.doctree b/.doctrees/strategies/run_task_in_threads.doctree new file mode 100644 index 0000000000000000000000000000000000000000..96622b19db1494b1f97abc150fd29a1c0ea1996f GIT binary patch literal 12803 zcmeHNOKc=Z8MfCuw#V;%WC_YTbQCS?RqSydNLkD(QWPmtWY!yPHV|a3T0Px0Q$6nK zZu+tIz$U!3D3(f!!ZrsE9DoBL1ROXZAwjrsLWl!L#33LK9JxhENPK_wb9&nC^(2BI zCDO*z_4w<5eE(m6RsCOWeEYqpCggu&*>|~VAG9>XupNW>k(f0cJ?t|(i0(&Mz81Y6 zt%;_m?fXvX=`0cx7@>31GCXESwM2w&hA`4nFjJDc3;vrR9wZRTz6JKo-==6TM*N&kRBe=}xm(+@l?U|o~> zG(ioZ1=YmgSPL!Bhft4hp95{`=;G(<-D{ic!|Wb@zjkI&*alPL8OKJ3BHl* zX@@@wYw%VKuoNK=D9ki53>1ma0y_kqm+S;M%9^wyLFuG?UWvr>C!NzOuOC$kE53gm zDB^`Tb8{RA4R^3bK!SnouHtk~ENunn(jXJ!G=hLW0<$$BaEW?U-vsJ|&?`FeYX_4P z6J=ej<?wnnwSnbm z#_ikdN;)rJ<`@jOZrx;lXa$(7JGLHrh#LA}3t$P>mA-bMy397f8@MI;{G`W53{w4o zxnRB)AX=MzNDo>sXI_=ET@vR-(+Zf!j6@pc?lF`r95NH;iVT)ypJizu&9IET$Ubk`MGuFT53<#cQu`DDcKO^@^jB2ipZFKK{VuyC<(Xl;oUgaB|cmL zMog#x9xOVCf$sALp)Ur!z!?(Mi^seZnUo)ZL~EpkGQY_ zy-QxjBC#%EBfnYERQyZ)%Vd|=bGz`n*yduPn^Neq#4F|Ck_t51k@Nd@9lx{0Z_Mm0 zEqOGbZ&mVnR`Q9=1Ga%LTPF7E+(fT+5D@dg^iljvBWE1sKgjr(gsC(NWfmz|L%dLF zihK)7H=U|&Cfzi$btJZF8&u0EJy)?z3e?KJ9IHP+8mnT`9u0^;1t@K8qnA83?*oyb$9SWrH!ZLq>3g5|8IJujde77L% zziNd2{fK4A;15E!H;Y&|7UjRD3}+^qNi3c--Mdgv{RkuRe-Y%ta&<^0#~nq_OtP63_`X+9eJs#iJ!wcw z4>RxE|EjJ2oq8FM#8c_G@vD&#ne4))aRr^Fx$X}UOMd{9{3wlhVx@cpm8e=P?1S@# z5h>(`+Ooa8_se<#D;e+o0+WV!jmku!_q%%HmD)>*9}Dh3)f2A-cS<}@8K!WAk5x2^ zdD)k%>hJXn7HlWuV6x{Ix0BHzDVI2DDD1r}^*?<0<#nbS2WAf+b+0i3w{sOEQ`lAZ zV|ewXTrSHmwMJ{J6*tzYoJ2)}2f{vQZ_vB2ZN z?`q-ltm0N|^c+|^ZRI*{W|UG;7Fu#B?$+zK8j7Enswn2q)sfJwCteN3g!r*g+^;8I z4aJ0buBMG~v^*L#&yJEQ*xhs!Lz3!Ds!=>@kh`gqPu?x)=@0e9YYlQN=YOsz zUd#EYwJS31f7CB9mX+(hrs^g*Jpqi1fMbtX|E?Fa&Pb&lrY=~Qh8C1pO1bL?ijVj4 zAY`iaJgjC{hxo*8?jhZ+d=H6x@_3M5QWq$0YxL@hH)LGDMPiPwlyMn^=kI9f##>B} zf7v6mO+GDVJE3LC3rBum%&CE+6Tg8U^)62#`?~*4TtUg!WDGI?3SW(xh7d2)4Gr?G z2@yXl;BXNX-}uufSbC&yk|w&I=JLWdnz(k0o4!I%TzIk`D7t1VZKi}iGnBwlfHmc% z8yjsWwDFBMS)U$ZiI8P6tCjlm`y-O?^Usjb^2I%Vg(~GS1w23zy{BmOD!)#z4E&K^ zE14X&dr#wMdM11AA~Nz@T*~Ar$#os`6-~+Sb(QobQ(4oXg7^(n3Ah$O=sh{OAHQH; zX(=x{p29SpD@l{$F`b!rm@x;{1X#!q+kG=YcfcKEUBOSN(T~Yhtl3g-*gC`GW#6^% z=ztkSBqdJ9k@V0r2a8Z2B~36HbCtDyGvKn#jh|5I4K%=gCOsh2P&}Ez73eLQzA9F~ zk{aWHS{At`xugV|tf^U7v^$Pzz+q*{ zfDBWN6Gx23aDO^wkJ?(*lUmZMA+rV{PjiLa|Kt+J)MnH|pSdPBur?~j=@s-=* z#<+Hvsj)-&l5`f2q5J~oa2!+-*aIbbhd`*1Wd!TWK2wr=?VF5t2Sm)wMw*!fP`uik zoq;qeVl318sSi3Hd9!ah`-c@kln#KG zggjK0QGiMm+ftzaLZCtbG#r~reJ7E%90pr+n1YRqp(M*w934d+v++klB5=Cs!=Y|Sc{*_k|&r_T9n+b z^}Y^5Vg{*`d{OItgFfY}eBpb>cH#=SL$Q$jqyo1Ap3|0XCrM}gq=~Yh9ho0cWuDym zQErw?v&OH9bBK={l&Nf(_?r|Svb2m&cFRPj5JT}QnpD@(0)R0}{$vuu*W)_9qtlSA z7?H1w^T?rW-;yu2DgfNY-WwMqHUiY{Skd-`m`len1D_$SHz}6lq9v3g#l@IAVj*pb z3mnC)&w>B}9(9~&vck-cCzCxR64Rg4tPmxEX{CagcEZ37gJ_2@?}%oXp=ePH952F$ zfjrL-w7!dv`FKIfllSmBmwbkvg|9_QMyWKCda-aLHi9_Yahw2QjTJh#C&ePwhuUFZ zJ%DHTBeX0b;F+!pC#SMgA0!`%TbRXUi%Q9hDxW;TJXTC5Bo&)bgU4LQ3sj5UVNl;G zF~>D4`)r6a?7*ZVE)=f$>7a&a7_1$3L2qea^C%I*2#UODX;LK@BcY-<#gb`5M=Gkt zutD0$^qXPO*|@qPv;K?2ovI8iD%WhoVyL*BCRTAE5X-Tq3sf4CN+ecGJtY#oUz0m5 z#dLEX(%Bb>J4%zq3dsPh`2e_UL8eG7TAJMrQDg^=8~8qjLSDd~>5gZp2BYl@%TVR$ zj+lmHb#S$3g*(V@+MxGEYW_JNZ%S6^5U0=B@ zmR#nlPzq&AD5M4Fs6udockoWmAs*&I;QCven`ri1?f{9t-EzF{W+Wb>k&*$7R0D>j z9v(-p`^??A^yH_Y&n2&;m&j8~PX3cAc{r;^klkZm%Va@Eu7Los$%DRy#hQWEh8GzD zkG5yUDlpksGxy8{Nb2_v#fm?`;ov~!W|v#|2mGG49D@FW-^a02{bC5e_MxbA@;m-i zkq&B!YFBlRvmbIDFZMTRS*j4T_d*vzo9f18F?bRO4uKv=H|-8EkOqdc6e_Tlm&TcW z0x#8pN^hj%?!5?@>9?5y7ao8G&QOSPC?3)=YENY-+^|%XxKp5&Y@bPr)B#qj6Nj}! zF~#gVR3t8D<8T811r)LCm~f5&<=Ir;A%SxSOaWQ}3f}=6gG$0*kHp!bRyv5wW>D*7 zAJgPQs5r;)8ETAw_r3)m@4bcp`Jze9wDHj(*>ULe$57=h`>~x}!x4QtsWnLhd3t=$ z3nZ_}yNP1q9ZJZ3r1;UBw0BRPrX#U<`$JcmOcn1qq{jvIxUksfuZCi=h*hb)Mcs_6 zT**J;779t}xY$a?mUtYT9@y@;9V>&s9D2Ugn2l}@QEaBG%1LL3=wo;B0@}_VD$`1O zu&E

bN0+SK!)ON16*<0YTU_XI@C!@5Ac%qMLAjT%I6|B**)B!7OeLHP2_w60!3* X9a^D59@3>KH)l|2PoiLa4b=J%iuJ`{ literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/run_task_with_multiprocessing.doctree b/.doctrees/strategies/run_task_with_multiprocessing.doctree new file mode 100644 index 0000000000000000000000000000000000000000..fa60d009185b980781de9014ef4bb075e4380d8a GIT binary patch literal 49169 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 G)&CC&%h|F3 literal 0 HcmV?d00001 diff --git a/.doctrees/strategies/unfold.doctree b/.doctrees/strategies/unfold.doctree new file mode 100644 index 0000000000000000000000000000000000000000..a927401c3d82eebc854c556b71d68ce47775ffff GIT binary patch literal 11082 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 literal 0 HcmV?d00001 diff --git a/.doctrees/what_for.doctree b/.doctrees/what_for.doctree new file mode 100644 index 0000000000000000000000000000000000000000..5ece2d408154ffbdae892b0ff87a15fe22d1347e GIT binary patch literal 30633 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 I$s4u*2SM{!5&!@I literal 0 HcmV?d00001 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/_images/arroyo-banner.png b/_images/arroyo-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..90482cb669dcc531ab025eb4e1c7afe9282381b7 GIT binary patch literal 71723 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

#M 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

?H$}{j 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 o$bt4xlA4 literal 0 HcmV?d00001 diff --git a/_images/arroyo_processing.png b/_images/arroyo_processing.png new file mode 100644 index 0000000000000000000000000000000000000000..21004ddec1f5b65e4d272411acb2bff5724232d2 GIT binary patch literal 19166 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 literal 0 HcmV?d00001 diff --git a/_images/consumer_groups.png b/_images/consumer_groups.png new file mode 100644 index 0000000000000000000000000000000000000000..09aa7440e8124155500b3f926c49c8331a2f22af GIT binary patch literal 23512 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 literal 0 HcmV?d00001 diff --git a/_images/kafka_producer.png b/_images/kafka_producer.png new file mode 100644 index 0000000000000000000000000000000000000000..53a90d9d95a203732b2380077dc2e9646a1f5db8 GIT binary patch literal 16532 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 JE0NIi`5%ZO4Bh|$ literal 0 HcmV?d00001 diff --git a/_sources/architecture.rst.txt b/_sources/architecture.rst.txt new file mode 100644 index 00000000..0fedb49e --- /dev/null +++ b/_sources/architecture.rst.txt @@ -0,0 +1,120 @@ +=================== +Arroyo Architecture +=================== + +Arroyo is a set of high level abstractions to interact with Kafka. +These are meant to help the developer in writing performant consumers with +specific delivery guarantees. + +Common problems addressed by Arroyo are guaranteeing at-least-once delivery, +providing a dead letter queue abstraction, support parallel (multi-processing) +message processing, etc. + +The library is divided into three layers: the basic Kafka connectivity, the +streaming engine and the high level abstractions. + +The basic connectivity layer is a simple wrapper around the Confluent python +library, which is itself based on librdkafka. Besides some cosmetic changes, +this level provides a Fake in memory broker and consumer to make unit test quick +to run. + +The streaming engine provides an asynchronous processing interface to write +consumers. The consumer is written as a pipeline where each segment is an +asynchronous operation. The streaming engine implements the main consumer loop +and delegates the processing to the pipeline. + +On top of the streaming engine, the library provides high-level abstractions that +are common when writing Kafka consumers like: *map*, *reduce*, *filter* together +with some common messaging application patterns like the dead letter queue. + +Streaming Interface and Streaming Engine +---------------------------------------- + +A Kafka consumer is built as a pipeline where each segment processes messages in +an asynchronous way. The Streaming engine provides a message to a segment. The +segment is not supposed to execute small CPU work in a blocking way or do IO in a +non-blocking way. We generally use futures for this, and heavier CPU work in a +separate process. + +Arroyo provides an interface to implement to write a pipeline segment. +The segment interface is called *ProcessingStrategy* and is in +`this module `_. +(TODO: bring the docstrings to the docs and reference that). + +In most cases, when developing a consumer, the developer would not implement +that interface directly. A higher level abstraction would be used. + +.. figure:: _static/diagrams/arroyo_processing.png + +The main consumer loop is managed by the `stream engine `_. +These are the phases: + +* Poll from the Kafka consumer through the basic library. If a message is there + proceed or repeat. + +* Submit the message to the first *ProcessingStrategy*. This is supposed to deliver + work for the strategy to do. It is not supposed to be a blocking operation. The + strategy should return immediately. + +* Poll the strategy to execute work or to forward results to the following step + in the pipeline. Ideally all IO should be done in separate threads and heavy cpu + work should be done in separate processes so the *poll* method should check for + completed work, dispatch to the next step and return. In practice, work is executed + here in a blocking way if the overhead of offloading the work is too high. + +The *ProcessingStrategy* may decide not to take the message and instead apply back-pressure. +This is done by raising the *MessageRejected* exception. In this case, the streaming +engine pauses the consumer till the strategy is ready to accept the message. + +The *ProcessingStrategy* decides when it is time to commit a message. This is done +through a commit callback provided to the strategy when it is instantiated. + +The streaming engine orchestrates the life cycle of the *ProcessingStrategy*, thus +when it thinks it is time to shut the strategy down it would wait for all in-flight +work to be completed and then destroy the strategy. + +There are two scenarios where this can happen: + +* The consumer is being terminated. +* A rebalancing happened. A rebalancing revokes partitions and assigns new ones. + After a rebalancing is complete it is impossible to commit a message from a partition + that was revoked. In order to ensure the consumer behaves in a consistent way, + upon rebalancing, the streaming engine destroys the strategy and builds a new one. + This allows the strategy to complete all in-flight work before being terminated. + +High level strategies +----------------------- + +Most consumers follow the same few patterns, so Arroyo provides abstractions that +are based on the *ProcessingStrategy* but are simpler to implement for the common +use cases. + +Common examples are: + +* ``run task, run task in threads, run task with multiprocessing``. The run task + set of strategies are designed to be the most flexible and simple to use. They take + a function provided by the user and execute it on every message, passing the output + to the next step. The library includes synchronous and asynchronous versions depending + on the kind of concurrency required by the user. + +* ``filter, map and forward``. This type of consumer inspects a message, decides + whether to process it or discard it, transforms its content, and produces the result + on a new topic. In this case, Arroyo provides three implementations of the + *ProcessingStrategy*: *filter*, *transform*, and *produce*. The developer only needs + to wire them together and provide the map and filtering logic. + +* ``consume, apply side effects, produce``. This is a variation of the one above. + In this case, the transform operation can have side-effects like storing the content + of the message somewhere. + +* ``high throughput cpu intensive transform``. The python GIL does not allow CPU intensive + work to take advantage of parallelism. Arroyo provides an implementation of the *map* + pattern that batches messages and dispatches the work to separate processes via shared + memory. This is largely transparent to the developers. + +* ``map, reduce and store``. The reduce function is carried out by the *Collector*, which + batches messages and executes some logic with side-effects when the batch is full. + This is a typical way to write messages on a storages in batches to reduce the + round trips. + +All strategies included with Arroyo are in `the strategies module `_. diff --git a/_sources/backpressure.rst.txt b/_sources/backpressure.rst.txt new file mode 100644 index 00000000..2dcc20df --- /dev/null +++ b/_sources/backpressure.rst.txt @@ -0,0 +1,43 @@ +Backpressure +============ + +.. py:currentmodule:: arroyo.processing.strategies + +Arroyo's own processing strategies internally apply backpressure by raising +:py:class:`~abstract.MessageRejected`. Most +consumers do not require additional work to deal with backpressure correctly. + +If you want to slow down the consumer based on some external signal or +condition, you can achieve that most effectively by raising the same exception +from within a callback passed to :py:class:`~run_task.RunTask` while the +consumer is supposed to be paused + +.. code-block:: Python + + class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]): + def __init__(self): + self.is_paused = False + + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]: + if self.is_paused: + raise MessageRejected() + + print(f"MSG: {message.payload}") + return message + + return RunTask(handle_message, CommitOffsets(commit)) + +It is not recommended to apply backpressure by just ``sleep()``-ing in +:py:class:`~abstract.ProcessingStrategy.submit` (or, in this example, +``handle_message``) for more than a few milliseconds. While this definitely +pauses the consumer, it will block the main thread for too long and and prevent +things like consumer rebalancing from occuring. + +A 0.01 second sleep is applied each time :py:class:`~abstract.MessageRejected` is +raised to prevent the main thread spinning at 100% CPU. However background thread +performance may be impacted during this time. diff --git a/_sources/dlqs.rst.txt b/_sources/dlqs.rst.txt new file mode 100644 index 00000000..62562a39 --- /dev/null +++ b/_sources/dlqs.rst.txt @@ -0,0 +1,21 @@ +================== +Dead letter queues +================== + +.. warning:: + Dead letter queues should be used with caution as they break some of the ordering guarantees + otherwise offered by Arroyo and Kafka consumer code. In particular, it must be safe for the + consumer to drop a message. If replaying or later re-processing of the DLQ'ed messages is done, + it is critical that ordering is not a requirement in the relevant downstream code. + +Arroyo provides support for routing invalid messages to dead letter queues in consumers. +Dead letter queues are critical in some applications because messages are ordered in Kafka +and a single invalid message can cause a consumer to crash and every subsequent message to +not be processed. + +The dead letter queue configuration is passed to the `StreamProcessor` and, if provided, any +`InvalidMessage` raise by a strategy will be produced to the dead letter queue. + + +.. automodule:: arroyo.dlq + :members: InvalidMessage, DlqLimit, DlqPolicy, DlqProducer, KafkaDlqProducer, NoopDlqProducer diff --git a/_sources/getstarted.rst.txt b/_sources/getstarted.rst.txt new file mode 100644 index 00000000..1051739f --- /dev/null +++ b/_sources/getstarted.rst.txt @@ -0,0 +1,226 @@ +=========================== +Getting started with Arroyo +=========================== + +This tutorial shows how to create a Kafka consumer with Arroyo from scratch. + +Setup +===== + +This section explains how to setup Kafka, Zookeeper and install the library + +Kafka and Zookeeper +------------------- + +In order to run an arroyo Kafka consumer you will need a working Kafka broker. +If you already have one, you can skip this step. +If you do not have a running Kafka broker, this command will install and start +a Kafka docker container. (It requires Docker to be installed). + +.. code-block:: Bash + + docker network create arroyo + + docker run --rm \ + -v zookeeper_volume:/var/lib/zookeeper \ + --env ZOOKEEPER_CLIENT_PORT=2181 \ + --name=sentry_zookeeper \ + --network=arroyo \ + -p 2181:2181 \ + confluentinc/cp-zookeeper:6.2.0 + + docker run --rm \ + -v kafka_volume:/var/lib/kafka \ + --env KAFKA_ZOOKEEPER_CONNECT=sentry_zookeeper:2181 \ + --env KAFKA_LISTENERS=INTERNAL://0.0.0.0:9093,EXTERNAL://0.0.0.0:9092 \ + --env KAFKA_ADVERTISED_LISTENERS=INTERNAL://127.0.0.1:9093,EXTERNAL://127.0.0.1:9092 \ + --env KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT \ + --env KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL \ + --env KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \ + --env CONFLUENT_SUPPORT_METRICS_ENABLE=false \ + --env KAFKA_LOG4J_LOGGERS=kafka.cluster=WARN,kafka.controller=WARN,kafka.coordinator=WARN,kafka.log=WARN,kafka.server=WARN,kafka.zookeeper=WARN,state.change.logger=WARN \ + --env KAFKA_LOG4J_ROOT_LOGLEVEL=WARN \ + --env KAFKA_TOOLS_LOG4J_LOGLEVEL=WARN \ + --name=sentry_kafka \ + --network=arroyo \ + -p 9092:9092 \ + confluentinc/cp-kafka:6.2.0 + +Now you should see Kafka and Zookeeper running with + +.. code-block:: Bash + + docker ps + +Install Kafkacat +---------------- + +This tool will be useful to produce onto and consume from topics. + +.. code-block:: Bash + + https://docs.confluent.io/platform/current/app-development/kafkacat-usage.html#kcat-formerly-kafkacat-utility + + +Development environment +----------------------- + +You will need to install the library. Most likely in a python venv. So first, create a python virtual +environment. Then you can install arroyo with this. + +.. code-block:: Bash + + pip install sentry-arroyo + +Create two Kafka topics +----------------------- + +Our example will consume from one topic and produce the same messages on another topic. So we need +two topics. + +.. code-block:: Bash + + docker exec sentry_kafka kafka-topics \ + --create \ + --topic source-topic \ + --bootstrap-server 127.0.0.1:9092 + + docker exec sentry_kafka kafka-topics \ + --create \ + --topic dest-topic \ + --bootstrap-server 127.0.0.1:9092 + +Now you should be ready to develop with Arroyo. + +Create a basic consumer +======================= + +Arroyo provides two level of abstractions when writing a consumer: the basic consumer/producer library +and the Streaming library. The first is just a thin wrapper around a librdkafka consumer/producer that +adds some features around offset management. The second provides a more abstract streaming interface +that hides details like rebalancing and the consumer lifecycle. + +Creating a basic consumer +------------------------- + +This initializes a basic consumer and consumes a message. + +.. code-block:: Python + + from arroyo.backends.kafka.configuration import ( + build_kafka_consumer_configuration, + ) + from arroyo.backends.kafka.consumer import KafkaConsumer + from arroyo.types import Topic + + TOPIC = Topic("source-topic") + + consumer = KafkaConsumer( + build_kafka_consumer_configuration( + default_config={}, + bootstrap_servers=["127.0.0.1:9092"], + auto_offset_reset="latest", + group_id="test-group", + ) + ) + + consumer.subscribe([TOPIC]) + + while True: + msg = consumer.poll(timeout=1.0) + if msg is not None: + print(f"MSG: {msg.payload}") + +Start this script and use kcat to produce a message: + +.. code-block:: Bash + + echo "MESSAGE" | kcat -P -b 127.0.0.1:9092 -t source-topic + +In a while the message should appear on the console: + +.. code-block:: Bash + + MSG: KafkaPayload(key=None, value=b'MESSAGE', headers=[]) + + +Create a streaming consumer +--------------------------- + +Add a `ProcessingStrategy` and `ProcessingStrategyFactory`. +Here we are using the `RunTask` strategy which runs a custom function over each message. + +.. code-block:: Python + + def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]: + print(f"MSG: {message.payload}") + return message + + class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]): + """ + The factory manages the lifecycle of the `ProcessingStrategy`. + A strategy is created every time new partitions are assigned to the + consumer, while it is destroyed when partitions are revoked or the + consumer is closed + """ + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + return RunTask(handle_message, CommitOffsets(commit)) + +The code above is orchestrated by the Arroyo runtime called `StreamProcessor`. + +.. code-block:: Python + + processor = StreamProcessor( + consumer=consumer, + topic=TOPIC, + processor_factory=ConsumerStrategyFactory(), + ) + + processor.run() + +The main consumer loop is managed by the `StreamProcessor` no need to periodically poll the +consumer. The `ConsumerStrategy` works by inversion of control. + +Add some useful logic +--------------------- + +Now we will chain the `Produce` strategy to produce messages on a second topic after the message is logged + +.. code-block:: Python + + class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]): + """ + The factory manages the lifecycle of the `ProcessingStrategy`. + A strategy is created every time new partitions are assigned to the + consumer, while it is destroyed when partitions are revoked or the + consumer is closed + """ + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + producer = KafkaProducer( + build_kafka_configuration( + default_config={}, + bootstrap_servers=BOOTSTRAP_SERVERS, + ) + ) + + return RunTask( + handle_message, + Produce(producer, Topic("dest-topic"), CommitOffsets(commit)) + ) + +The message is first passed to the `RunTask` strategy which simply logs the message and submits +the output to the next step. The `Produce` strategy produces the message asynchronously. Once +the message is produced, the `CommitOffsets` strategy commits the offset of the message. + +Further examples +================ + +Find some complete `examples of usage `_. diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 00000000..fb702775 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,16 @@ +.. include:: intro.rst + +Contents: +--------- + +.. toctree:: + :maxdepth: 2 + + what_for + getstarted + architecture + strategies/index + offsets + dlqs + backpressure + metrics diff --git a/_sources/intro.rst.txt b/_sources/intro.rst.txt new file mode 100644 index 00000000..72b0d4e2 --- /dev/null +++ b/_sources/intro.rst.txt @@ -0,0 +1,15 @@ +.. image:: _static/arroyo-banner.png + :width: 583 + :height: 95 + +Arroyo is a library to build streaming applications that consume from +and produce to Kafka. + +It relies on the `confluent_kafka` python library, which itself relies +on `librdkafka`. + +Arroyo provides mainly three functionalities: + +* A set of abstractions inspired to common messaging applications patterns. +* Some abstractions to simplify offset management and rebalancing. +* An in memory broker abstraction to simplify writing unit tests. diff --git a/_sources/metrics.rst.txt b/_sources/metrics.rst.txt new file mode 100644 index 00000000..94011dbe --- /dev/null +++ b/_sources/metrics.rst.txt @@ -0,0 +1,53 @@ +================== +Metrics +================== + + +Arroyo consumers and strategies attempt to auto instrument some metrics that most people find useful +to understand the behavior and performance of their consumers. These metrics are typically sampled or +buffered as appropriate and flushed periodically (often once per second). + +In order to use these metrics, you must configure a metrics backend that conforms to the metrics protocol +before creating your consumer. + +This can be done like so: + +.. code:: python + + from arroyo.utils.metrics import Metrics, MetricName + + class MyMetrics(Metrics): + def increment( + self, name: MetricName, value: Union[int, float] = 1, tags: Optional[Tags] = None + ) -> None: + # Increment a counter by the given value. + record_incr(name, value, tags) + + def gauge( + self, name: MetricName, value: Union[int, float], tags: Optional[Tags] = None + ) -> None: + # Sets a gauge metric to the given value. + record_gauge(name, value, tags) + + def timing( + self, name: MetricName, value: Union[int, float], tags: Optional[Tags] = None + ) -> None: + # Emit a timing metric with the given value. + record_timing(name, value, tags) + + metrics_backend = MyMetrics() + + configure_metrics(metrics_backend) + + +Available Metrics +==================== + +.. literalinclude:: ../../arroyo/utils/metric_defs.py + +API +======= + +.. automodule:: arroyo.utils.metrics + :members: + :undoc-members: diff --git a/_sources/offsets.rst.txt b/_sources/offsets.rst.txt new file mode 100644 index 00000000..6316e653 --- /dev/null +++ b/_sources/offsets.rst.txt @@ -0,0 +1,37 @@ +================== +Committing offsets +================== + +Arroyo does not auto commit offsets. It is up to you to manually commit offsets when processing for that +message is completed. + +The commit callback will be passed to processing strategy via `ProcessingStrategyFactory.create_with_partitions`. +You should pass this to the strategy and have your strategy call this commit function once the rest of the message +processing has been done. + +The offset to be committed in Kafka is always the next offset to be consumed from, i.e. message's offset + 1. +In Arroyo, this means you should commit `Message.next_offset` and never `Message.offset` when done processing +that message. Arroyo exposes `Message.position_to_commit` to make this easier. + +It is not safe to commit every offset in a high throughput consumer as this will add a lot of load to the system. +Commits should generally be throttled. `CommitPolicy` is the Arroyo way of specifying commit frequency. A `CommitPolicy` +must be passed to the stream processor, which allows specifying a minimum commit frequency (or messages between commits). +Commit throttling can be skipped when needed (i.e. during consumer shutdown) by passing `force=True` to the commit callback. +If you are not sure how often to commit, `ONCE_PER_SECOND` is a reasonable option. + +The easiest way is to use the `CommitOffsets` strategy as the last step in a chain of processing strategies to commit offsets. + +.. code-block:: Python + + class MyConsumerFactoryFactory(ProcessingStrategyFactory[KafkaPayload]): + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + def my_processing_function(message: Message[KafkaPayload]) -> None: + # do something (synchronous) with the message + do_something() + + + return RunTask(my_processing_function, CommitOffsets(commit)) diff --git a/_sources/strategies/batching.rst.txt b/_sources/strategies/batching.rst.txt new file mode 100644 index 00000000..540d7d8a --- /dev/null +++ b/_sources/strategies/batching.rst.txt @@ -0,0 +1,10 @@ +Batch and Unbatch +----------------------------- + +Accumulate messages into a batch and pass to the next step. +The batch and unbatch strategies are based on reduce and unfold. +Use reduce/unfold instead if you want to provide custom +accumulator/generator functions. + +.. automodule:: arroyo.processing.strategies.batching + :members: diff --git a/_sources/strategies/commit_offsets.rst.txt b/_sources/strategies/commit_offsets.rst.txt new file mode 100644 index 00000000..64d3504c --- /dev/null +++ b/_sources/strategies/commit_offsets.rst.txt @@ -0,0 +1,8 @@ +Commit offsets +----------------------------- + +Should be used as the last strategy in the chain, to ensure +that offsets are only committed once all processing is complete. + +.. automodule:: arroyo.processing.strategies.commit + :members: diff --git a/_sources/strategies/filter.rst.txt b/_sources/strategies/filter.rst.txt new file mode 100644 index 00000000..22cba221 --- /dev/null +++ b/_sources/strategies/filter.rst.txt @@ -0,0 +1,5 @@ +Filter +----------------------------- + +.. automodule:: arroyo.processing.strategies.filter + :members: diff --git a/_sources/strategies/healthcheck.rst.txt b/_sources/strategies/healthcheck.rst.txt new file mode 100644 index 00000000..89fe7a3c --- /dev/null +++ b/_sources/strategies/healthcheck.rst.txt @@ -0,0 +1,74 @@ +Healthchecks +============ + +If your code blocks for too long in the main thread, the consumer can turn +unhealthy. + +Kafka has a setting called ``max.poll.interval.ms`` for this that tells Kafka +to kick the consumer out of the broker after this many milliseconds of not polling. + +You can pass this option into :py:class:`arroyo.backends.kafka.consumer.KafkaConsumer` like so: + +.. code-block:: Python + + consumer = KafkaConsumer( + { + "max.poll.interval.ms": 300000, # default 5 minutes + } + ) + +However, this will not shut down the consumer, it will just keep running doing +nothing (because it is blocked in the main thread). You want a pod-level +healthcheck as well. + +Arroyo supports touching a file repeatedly from the main thread to indicate +health. Start your pipeline with the +:py:class:`arroyo.processing.strategies.healthcheck.Healthcheck` strategy. + +.. code-block:: Python + + def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]: + ... + return message + + class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]): + def __init__(self): + self.is_paused = False + + def create_with_partitions( + self, + commit: Commit, + partitions: Mapping[Partition, int], + ) -> ProcessingStrategy[KafkaPayload]: + step = RunTask(handle_message, CommitOffsets(commit)) + return Healthcheck("/tmp/health.txt", step) + +The Kubernetes `liveness +`_ +command would look like: + +.. code-block:: YAML + + apiVersion: v1 + kind: Pod + metadata: + labels: + test: liveness + name: liveness-exec + spec: + containers: + - name: liveness + image: registry.k8s.io/busybox + args: + - bin/my_arroyo_consumer + livenessProbe: + exec: + command: + - rm + - /tmp/health.txt + initialDelaySeconds: 5 + periodSeconds: 320 # should be higher than max.poll.interval.ms + + +.. automodule:: arroyo.processing.strategies.healthcheck + :members: diff --git a/_sources/strategies/index.rst.txt b/_sources/strategies/index.rst.txt new file mode 100644 index 00000000..1c373df0 --- /dev/null +++ b/_sources/strategies/index.rst.txt @@ -0,0 +1,38 @@ +Processing Strategies +===================== + +The processing strategies are the components to be wired together to +build a consumer. + +Strategy interface +------------------------- + +We normally don't recommend writing your own strategy, and encourage you to use +built-in ones such as "reduce" or "run task" to plug in your application logic. +Nevertheless, all arroyo strategies are written against the following interface: + +.. automodule:: arroyo.processing.strategies.abstract + :members: + :undoc-members: + :show-inheritance: + +Messages +------------ + +.. automodule:: arroyo.types + :members: + :undoc-members: + +.. toctree:: + :hidden: + + filter + reduce + unfold + batching + run_task + run_task_in_threads + run_task_with_multiprocessing + produce + commit_offsets + healthcheck diff --git a/_sources/strategies/produce.rst.txt b/_sources/strategies/produce.rst.txt new file mode 100644 index 00000000..d40c3ba8 --- /dev/null +++ b/_sources/strategies/produce.rst.txt @@ -0,0 +1,5 @@ +Produce +----------------------------- + +.. automodule:: arroyo.processing.strategies.produce + :members: diff --git a/_sources/strategies/reduce.rst.txt b/_sources/strategies/reduce.rst.txt new file mode 100644 index 00000000..41be2365 --- /dev/null +++ b/_sources/strategies/reduce.rst.txt @@ -0,0 +1,7 @@ +Reduce (Fold) +----------------------------- + +Accumulate messages based on a custom accumulator function + +.. automodule:: arroyo.processing.strategies.reduce + :members: diff --git a/_sources/strategies/run_task.rst.txt b/_sources/strategies/run_task.rst.txt new file mode 100644 index 00000000..bce67b48 --- /dev/null +++ b/_sources/strategies/run_task.rst.txt @@ -0,0 +1,5 @@ +Run Task +----------------------------- + +.. automodule:: arroyo.processing.strategies.run_task + :members: diff --git a/_sources/strategies/run_task_in_threads.rst.txt b/_sources/strategies/run_task_in_threads.rst.txt new file mode 100644 index 00000000..84ea0c08 --- /dev/null +++ b/_sources/strategies/run_task_in_threads.rst.txt @@ -0,0 +1,5 @@ +Run Task in Threads +----------------------------- + +.. automodule:: arroyo.processing.strategies.run_task_in_threads + :members: diff --git a/_sources/strategies/run_task_with_multiprocessing.rst.txt b/_sources/strategies/run_task_with_multiprocessing.rst.txt new file mode 100644 index 00000000..1855dbbd --- /dev/null +++ b/_sources/strategies/run_task_with_multiprocessing.rst.txt @@ -0,0 +1,5 @@ +Run Task with Multiprocessing +----------------------------- + +.. automodule:: arroyo.processing.strategies.run_task_with_multiprocessing + :members: diff --git a/_sources/strategies/unfold.rst.txt b/_sources/strategies/unfold.rst.txt new file mode 100644 index 00000000..113dc3b7 --- /dev/null +++ b/_sources/strategies/unfold.rst.txt @@ -0,0 +1,7 @@ +Unfold +----------------------------- + +Generates a sequence of messages from a single message based on a custom generator function + +.. automodule:: arroyo.processing.strategies.unfold + :members: diff --git a/_sources/what_for.rst.txt b/_sources/what_for.rst.txt new file mode 100644 index 00000000..7e2d04fd --- /dev/null +++ b/_sources/what_for.rst.txt @@ -0,0 +1,276 @@ +What is Arroyo for? +=================== + +Arroyo is a library for writing high-throughput, testable kafka +consumers and producers. This document attempts to outline the +intricacies of writing such consumers. + +Goals +----- + +1. Make it easy to build consumers that provide delivery guarantees +2. Make it easy to write high-throughput kafka consumers +3. Make it easy to write reliable, high throughput kafka producers +4. Abstract away rebalancing such that users of the library do not have + to worry about it +5. Make it possible to test kafka consumer logic without having to + reproduce the entire kafka environment +6. Provide a way for the application logic to signal backpressure + +Why Simple Doesn’t Cut It +------------------------- + +When visualizing event-driven architecture, Kafka is viewed as an +abstract queue with groups of producers pushing to it, and consumers +consuming from it (as in the diagram below). + +.. mermaid:: + + graph TD + Producer --> Kafka_Topic + Kafka_Topic --> Consumer + Consumer --> Destination + +A more accurate model is that kafka is like a log file which is +persistent and there are offsets of the file that different consumers +have read or not read. + +The most simple kafka consumer looks something like this: + +.. code:: python + + from confluent_kafka import Consumer + + conf = { + "bootstrap.servers": "localhost:9092", + "group.id": "my_group", + "auto.offset.reset": "latest", + } + + consumer = Consumer(conf) + consumer.subscribe(["my_topic"]) + + while True: + message = consumer.poll() + send_to_destination(process_message(message)) + +This simple consumer would not satisfy the goals mentioned at the top of +this page. The following subsections will explain why + +Providing delivery guarantees +----------------------------- + +By default, a consumer in the ``confluent_kafka`` library will +auto-commit on poll. To understand what it means to commit to a kafka +topic, see the Appendix. This can lead to the following issue: + +.. code:: python + + # get message from kafka, commit immediately + message = consumer.poll() + # ❗❗❗ throws exception due to a network issue + send_to_destination(process_message(message)) + # this message is now lost and we're on to the next one + +This can be fixed by only committing after we know that the message has +reached its destination in the following way: + +.. code:: python + + # add this value to the config: + "enable.auto.commit": "false" + # ------- + message = consumer.poll(timeout=0) + send_to_destination(process_message(message)) + consumer.commit(message.offset()) + +High Throughput +--------------- + +The previous section has allowed us to not commit messages that are not +processed however committing every message severely hurts throughput. +Every call to commit is a network operation, it also makes the broker +persist and replicate the information. If we can reduce the number of +commit calls, our throughput can be much higher. And so we commit in +batches + +.. code:: python + + # this code is purely descriptive. + # We have to commit to each partition separately + # but that code is not helpful for this example + message = consumer.poll(timeout=0) + batch.append(process_message(message)) + if len(batch) == batch_size: + consumer.commit(offsets=[m.offset() for m in batch]) + +This will get us faster throughput however we are currently hand-waving +away how we send the message to its destination + +Reliable High Throughput Batched Producers +------------------------------------------ + +Producing to Kafka reliably and at high throughput is not a simple +operation. Here is how a simple Kafka Producer looks in code: + +.. code:: python + + from confluent_kafka import Producer + + conf = { + "bootstrap.servers": "localhost:9092", + } + producer = Producer(conf) + def send_to_destination(message): + # ❗ This does not do what it says + # it writes to a buffer + producer.produce("destination_topic", message) + # this will actually block until the messages are produced + # calling this after produce every time is very expensive, + # how often we flush has high impacts on the producer throughput + producer.flush() + + +At a high level, the producer is actually buffering the messages +produced to the topic + +.. image:: _static/diagrams/kafka_producer.png + +A kafka producer writes to an internal buffer. This batches the IO +(good) but you don’t know when it will ever make it to the +destination + +In order to allow for reliability of transmission, the +``confluent_kafka`` library provides `a callback to +produce `__ +like so + +.. code:: python + + def delivery_callback(error, message): + # do something here to make sure your message is in the state + # you want it to be + + producer.produce("destination_topic", message, on_delivery=delivery_callback) + +Dealing With Rebalancing +------------------------ + +What is Rebalancing +~~~~~~~~~~~~~~~~~~~ + +A kafka topic is divided into n partitions, each partition can be +consumed by exactly one consumer per `consumer +group `__. A consumer can +consume multiple partitions + +.. figure:: _static/diagrams/consumer_groups.png + +When Rebalancing Can Happen +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Rebalancing can happen due to: + +- An addition or removal of a consumer to a consumer group + + - (Every deploy does this) + +- A rebalance being kicked off manually +- A consumer pod dies and now its partition needs to be re-assigned +- Whenever the broker decides it’s a good idea (it can happen at any + time) +- TODO: More things? + +How Rebalancing Affects a Consumer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Rebalancing is annoying to handle for a consumer that processes batches, +imagine the following scenario: + +.. mermaid:: + + sequenceDiagram + Broker->>Consumer: message + activate Consumer + note right of Consumer: start building batch + Broker->>Consumer: message + Broker->>Consumer: Revoke Partition + deactivate Consumer + Consumer->>Broker: commit batch + note left of Broker: Received commit from revoked Consumer! + +Once a partition is revoked for a consumer, it cannot commit to it. This +is bad news for the batch that the consumer has built up. Each consumer +has different requirements but a decision has to be made as to whether +to flush the batch or to discard its work and let the next consumer +assigned to this partition pick it up. The rebalancing behavior can be +customized by providing an ``on_revoke`` callback to the consumer when +subscribing. + +.. code:: python + + from confluent_kafka import Consumer + + conf = { + "bootstrap.servers": "localhost:9092", + "group.id": "my_group", + "auto.offset.reset": "latest", + } + + def flush_current_batch(consumer, partitions): + # flush the current batch + pass + + consumer = Consumer(conf) + consumer.subscribe(["my_topic"], on_revoke=flush_current_batch) + +librdkafka’s Callback Hell +-------------------------- + +librdkafka uses callbacks as a core mechanic for control flow. A few +such examples have been mentioned in this document already. What is not +clear however, is that **callbacks are only called when ``poll`` is +called** + +This means that: + +- this line could possibly do a lot of work: + +.. code:: python + + # any scheduled callbacks will run within this call + message = consumer.poll() + +- No callbacks will be invoked until the consumer or producer call + ``poll`` again (for their respective callbacks) +- ``poll`` has to be called periodically on a consumer otherwise the + broker will kick the consumer out of the consumer group + + - The handling of that revocation won’t happen until ``poll`` is + called + +Conclusion +---------- + +There are many intricacies and gotchas to writing high performant, +reliable kafka consumers. This document does not outline all of them but +all of what is outlined here should be kept in mind when designing any +kafka consumer library. + +Appendix +-------- + +Committing to a Kafka Topic +--------------------------- + +A consumer comitting to a topic signals to the broker that this message +has been processed. When ``poll`` is called next by that consumer, it +will return the next message. + +`API +Doc `__ + +What is a Kafka Consumer Group +------------------------------ + +https://www.educba.com/kafka-consumer-group/ diff --git a/_static/arroyo-banner.png b/_static/arroyo-banner.png new file mode 100644 index 0000000000000000000000000000000000000000..90482cb669dcc531ab025eb4e1c7afe9282381b7 GIT binary patch literal 71723 zcmYg%byQnl&~1PKp-6G};O@nWJH?^6LxJM%6fF)7+G0fuw79#wyA^k*XmQ@{?|biC zkAJcjxw)Bp&di*>_v}QfD$An3B7Ow|fzajUq|`wm6jBff&JThF{HL&c=LL8na+B6^ z({TLY=4t9;2@P!2RJSy>@OB=w6b8W&jLJ)iYkDmmw;I}!TBV)+{jynq zJDG3s?PkDZ`22&F6#eop@N+eO&;RA@`mvpHnvorxTYq(ZXYUf z->LU!wKX)he-J(jSiXJ^*FB~D_Yp!tl{Miv^LO{>N}t}=0auT@`j#&UBYRGIKUn=1 z`R*=Sw|h{%EdD2$P2&H41@MB&0({GgQsihl&Y57j{GzTLu9iXN)NX8i%!8-l*{832 zk^e3Z#2lT~7z;l=dY$S0;9;sZv&bTK-&@xxgbXn;#w3ON-y7a`{LmOLtJpW>bWH4G z<{JCu;AWAD%K6`O-EyjU?rop?t>EDnM2w*}z|;5}I_;iBz&emRvHtfCVkCA;6>@`@ zTvm+KTPUZypN;g|l%(Z|y5Rp^f<6YsVeo{$HydB|!C885N7pJV3kw6S2LmkozqbIP zZ#LjJlHi@aBEiq3W_HI)NUny}Fvx4yPQpPtj;QR5N|$aomFV!DSjV&CpD3@Q>2GA_r|f)w>PotH(OMWlLlsOFR!m2Hz2u>=fPnhDp~U`yEho@$$xb~B zHAb16jbwb+TkuF03$7EZfs8Nx$oX4KX^GLX;Dhlf=Bq%%2T4QgHfV+&+yaWeAI&v( zmQDu3v1of6y^esSj&nxzd(t4a^v&G&eK_+9#{DqeP&v>XU zbwPo8-~Dl6jC4hDylT!QA~lx63_7h6VPKs-DU)Ct720}@mSSeewHui;TxqR4uQIZ4qg!{ZsdQN7?s5_QOY zidcYj=yQ$f3Vr~Ccm&w!3)*bX;mloI z`g`zXEoNv=fAksJKAJwUko$kW!Fe4aWw9GkVviuuq-*Uf(n)Mqvh-tY+OS_O@WURQ z=&ZM(zs#Pv6YklVp8_UHZ+dNQv*Al`FE<#z;}nPDix>QDl=36@MGF#lB_5OTH9tmObF)edp?hzJrcA7i_|1t=MGREZ zG}IvuTvc`G52GlUB+{sc+``g?F%GGMDzX+}que723ZYB*&;c?~r<$LTo3d>n>dtJS z$ob86&9zIU90;uNzNiyzH%;`7B(OIX5=f! zTFtaqj-G7EyVnhQxq0zetz4<$svS#w$FpT;9PAM^{rpAN+k_86s%+?wvU>-jwfC49 zC}2o%o|ngQ5_<57Dha{nD*MR-&+^H7}0bqYP~55+Xh!l=swHk`haa*Z9-yrfY3R(Wpdcoa&n?oXnGNQ@v*0h0))L8PEWN`LN zENuGrf=YzcYe

q=tKk^3?Efd9Ig4nZKYWR}^5`^P~03FQF^^ok;9GHO4bNi5Cf= z4T(h13d=KMAr_^?mi&~Dw-il>h7;#Ug88s6cTqEL!j2eD?fJUpQPjEmO^MsEdhWSv zjh-^tsXqBcp;THla3FZaas*Ci6^34~GDzyyTGzKH35#NaFr!4I56fh^L%S$2Nqful z+CR1$P-0ggRKK_K4dxI-dyrOc28E`_j+*tzVqTm}?Ja0Wf@{JYve=R>-HUOh!c^$?}qIo(>e*B5F;cQOP>A~)b(|1mne1xtI)f3}v$It$Vg+~d;Z9lc0Z&li z*X!5}6NHHO>KxE(9F&F&@r6DdaLEL5Q%;jk0+96Jpjdi`Mc$qg&<2IMMi=9OS4=oi zuNufu?u;isKAw_Fx?%J!_S zbNgdv{t|M9c7=$fV{%NwQ!<8p{Ts`|04J4LGDGm^%!L~6tF7erf+ju^OpU=Mn}|$f z0TT(bvLHyCq{N+mn}jjzyvw!qZvTOFE*#Cq@!#^NaP-uX*(wLb%Si#7470YSfFPey z-dmI$nKLohEL!2f)9HbJH`uwC*mQw74=Hq2;Uh%SFdvh8K!UEW1YI~o=PAZjRQ^|5eHe z14d_CyI~$mm1NJdGcs*sWn$0{y?#0;l9&{R#BFjx9vxq{$coD{%d|*-d9Kc`uuiSj zUq>U%?cKYZa3Pz_(GYcF1?oly>4y{5i$HvYO-*r(LS1as5a*$RV=)C9!4m_dGoy|L z*q%X?4i?}IHNuDNnrY-9IQx>Lr`IZ2pBHLPNBafb9FYz`1bpTQE%T@13FiNT7b>e1 zvd)0CJvFWO#&vc0Y;k^#er084%0K(}vzKIcemR0a`0ag0CoQ}gkFJap*o3@E&2L^F zqbd{uo>&Eww9^$oDk5e?ygxC15f|x?J6a}osLW)c0hTV?@S#F4KB1QOuO5p}Zg%2c zxLIv-581L(U4+W+tuIve(HW$fEGP%=pvtKC-k>C&ip!u{a56d+&Wy|EUqpO2GMuQfm>phSn;({SSq6VX zx%9NHpd9E!rEp%N9?B>ZdDfdrvcI&L)Y)dqVzN&%cBspIa`sc*(EX$22;tad&p$R7 zmZk~;kugLs-0`_D`!q6@xWZW*yQQ>-wE}G!!R5dv(>fEQ`z+T%&gc3kNrF+tmoA0X zL*afDgdU5Fm~{vxxwX2}w{4IgDX=QNFa@o-3q(fNWG9!1*Sf{cY9qiIo6`S|j9q|{ zj8?(2S$HW*gE*FR{EeHP+6LB6j?la)En+G(v15lp#9sTieF6|z_=b=u#-Xr(lr_js zd=KZC^%y=F+I^mvkv3lhvN3TI!zcm``XslJI~ee1mk{?@V#lsS0=GdO(dXb!H3L=c z@ZJQL9n_m2%snY3l)~`V9wqM-p7O73ak74&&CHIxbh8lzbcWUDvaC-+W^u=P|P59 z>a1jEK{IgX*Jd7!3U=z?U=c2;^s8G~k&qH8(FVYm=QL1Ae8+DfEZ6}*?Q~Qab!FhF z1>y!)M}RpE38ASJV$II0&0ME=_Ct>z(~k9rlKgcS3v4~4Fz>WQdwfr*>x6p~k13=D zT}j@bLO`4cMBF7pDfa1_6fFBWQBg&-!YEGm?yVg^CHiZ%VAfj<9A1GQQwd->C|7|3 z&*fbm#eQY&DlG0~L7n__20yxPAmW0v;oPm zmabAKA-Oj

w%ZZrYb1Vxm1AMw!e6?do*QKf)My;Q-z(GE4riIod!s048>ym&aI z?AO+f2~vskv@+G>x&yA=?@oW*4xv*)*Vu(ubZWL=N0V$Et^NI1L=1&rPCU6@dgrSy zwu=WODjg8e1OAXx0lb88G@YEEUKfrst|)!7x`jo=hvjljSlSL;nlN=vlbY3LX=oQ9 z#^St;G~-NC2{TR_s^fp(&uU1be}5P`@*??uw|b87#!LBPZr=R~trEt$@8u$&d0fgY z&HvcH$Z`Kwj zU9M1kF?3YH8T^1y&{}ISc@x61vf@p&Kb_dbk|k--*Ohzjo$as+7Uyo1O zk+>6<^RGqvUWyy6wX=#46O~2BXB)CriD7(Jslx&Sb?8~ez)Snr5v3!q-HS&F?EWJ2 zIdu1a*!c2P2}L`clB9j|Pk+w2zHZAZYAMyV63!VR{wj>oWJ$DeYm2L0)SwPq@-bB1 zeic3EeDV1NVQ`AGvHp+$p!S@-nm~Ss)cB7j7w6W3;bMH-gVdC}SbDjQY+3=k}_dziV73rgK>|iJe z6aoDho>qnJy37cQk;fgX(qmYXfI{$p+ZQ$a{)(`kaK=#Qge~5s`BM%MtJulD;%n-l z$(Ww<1W%s4H{hIHYMNoXuKHlvUkMS%;&~)2{X1M3?KsF@YHRrvX8D*O$GSJZqFtEB zGkJkd)+~zMlSG&OSGBjYCUt-OZOx0ModrfJN>KU9&d>Fa;E70q{@JC`PuHi9^D1M? z`Q?P|NTJ>TE%_ylg#IMrX-K4+LRoEJWy4~-cnRGKkQ!o83!2X!MH4e#!QEF>UfnGJz7Uh`l(w*Wv;LB$X0moN}>E*UkrTo2>eblBQqy8YV}-7 zwR>e7$a!D!mUZe}yll3YP11wJ@(e%sj9}mqBX_Ft<2)^yslB>H%%BlA0UCSLYq#IX z0(@ZUNhVu-J}04IIiSfI*WQQ4PEVz;3>)wnjMU-eV@|pgFOB`=mC>wEnQ>E0v%kwY zM+kn$_p{rj{13u6*0#BiWiIDH;&4k%r8Yi8b8urBM|3XBt3#=(?A3m6K&eg9tV(XY zQaQX@2eIZzLkU8vvy5KqP-D?C7!{pa@ zDOT!=T)#|9bwRk^3jusZ*q*|Jh~D%QVTb5Hnw)Hx`ul=z{x?#kp*%p?W70z?`MF|% z)kntF^2#%?hsPsAi^ou$zh#I%Xm$+_bKOC`bqN-wAFtKU9Jb?cgCtk|4Q2B?|;|| zx!gP5g5P8Xs+04bK>8&nD;pNP`2Z!~1;#JY>GNlRh{OM}?lP*JCr)kiF*`zXYgIFx zdCOE^dUr)e-_D0b8i&^HBUYJo1#uTXoOQ8n0=-sPO#{c_AaPWzmGIs>GIm2i&0kjF{1E$d2NK--a55~Z-rXgzMI74L%%y>r zD2>Tde8VUPx~G_{s>t^VOLu0SCNCYvUc?qAc5# zSW~!jPN~}rTmH_cp`6)~TZyA?FAQ8Cpv;iY_NLxot?O7k2%(;v6~s+?HI#lvdpNhO3y7mbBIA) zXcf3YHS!)i5q?d#vKJLRi-X3J{kVAK&SJSw0_|gevEF_~$VI-ehmiLKtk$5cyl(qw zs3C=rjaZXA=%V{RMZu#s5yLE1A`9TtG6ES%n%t;J_!O$VTaQ};y3bD;t({n|t6PyE z%-`}kU)TqLR%xd%t;;ZH+Xyd~F)8&Dl>CRA0^v_cZ^B!Od2jEG9vKqaNh1-Kt@3uJ ztrv%jUKeW<>iUxNZG6)}<;{p#hEdQ2b+uyuag|Mdn}6Z78C2Re$rotbg*0aA{F_N= zFb*UGaq7V8u>=4KI;CLNtk7YP{Rc;Rf}&z}QLoi)7W+MlYcQf?dj{(%`0qU3_6CFv zcTL{L=rkdTjgZA((adlv^aYywTa8Aa<(0`wc1tFifkBpi#LT*4kwh5{SCIgt+Px58 zBJxCYXPx?`t(aTvip3VCYWO`l>r`Xgcp`|@M&WQw1~dWI7B)E7@xvP~*+ z&unzQq$w*o8GUdciywvwth?Yo^Zgz0k;g`XnzWWY-DLZAcv|Ct(ACQZ^l}&gaSC@1 zzqV!R9d38b`T!B$Vpu_D(aD*r%yKXH`4lz2bA_4VgY&4oqa)B=Etj8%_3nAP4?Ki0(fZ8P=!$Sm{->>2RNBR3B?Q=_+z5V z=5H>iSxGSgtsHQ#fjt$qkUzNm1c$sP(Ax zPNdY`q~v*B`IR8>r{$aaA7iUNf*!IHzut*%+v)cu)2p0taey#~8yDa9?-GKDbJUZU z0OaO(r*knr;=-$LIw@mQv#mztd*pub={mx#cU}OGc&~vwYyAUS+rI+@kM9~pEHnJ$ z$>Oy9q{;>hi-ggGCXc>je+5s&7)$<HCVO`%YAgOo>dr+- zPL_gj=ofl~C6+O9et|ZIyW7pU$5*6j$(veF7W+o!D;cMu}#;6y8eWKpcxcI zP%SO;+fPfzQF7#ApYSwwaH2b#jwU3mISz zaw*x*A?rmb3YNM7DfNoDvUp&b3DX5k1olg+9+}U%=E+ZoF&Z~tXHO!c(kv@!eks!C zEkj7sI<&*>VUr;R^QH0OG345qWVIOx6X9ve)xQuFvs6QK?F$e+p-cEDV*La?GN5y8 zB71u5Tqsx;Nlc*jPi|q43>`MLc{g3#TNaMaB#|2Y&ufwosCX3av1l4D=p6=_WJGAe zc}Niz6LN->Zd*5j4s+zB9XXg?pj_x5Y67!7;oJrc=^=b^*k%~!`<3XFp}K)0O_tuV zQHEw0DRLHC%eq^=l0G~sS=JqpeCN&pjgu*gY;)I2gom_{m>t-;5U2#RNs&L8lCVh+ z33fpVCtPQsyi0NX!{tIrRx$|vY;tQgEH-x1c-2}4RuB>HC-oKr=$pq?=b;K^a9<(0 zP)Tv88sunN-7x}cTAr!c<(v(wgV|C2R!oHcR0Xa4rS;9ZfP#n?A$^ibm0reb)Y&DbcuCCW7w|Jrhx@1&Z> zc=c7*Cf&=vfV$THl%$Ejw(TYt8s6jbTZI*v$WuSubsm)K5oUNVs&6~WH2KVP>e;}24 zQV%p@hvwOJw9{1GkotLJZY(e;pnM;j(DyIn7a*GjiyI(;&0>s4;v57(gov~9u=!72+BN!carOI+6p zJ~#MIHI4Chkq2OV$XQa%^xGPhBo5p{*BQD16pSWuH;*K@B`m^(@2by@#d|Le z*DmqS;FuocJp0)1U4)oA zlWK6P{$)F2KoCmGTcsvczj{fd6V|fgKYA|V-=x0Z6m(5Sxy!#z5oT$nWvx_mXdt z743wJ55x(V-uacb5&q3J6zo2%5H@(u0&pQ6?X)l<&_}1-^9@LXJs1|SJ!npuiKX1iV{fO}dm)!6Gsn}03$ z%0%@u#}^ezjdh2aTi5SSy9fP|NM94`tp{sz-NS4~IYx?LflY*qN8gZ<^#pi|lW_zC z_yY|G_AjugI9_Y{92Rd>O3n$J`|&Wf-z4#JHbpQahY1_BJ!Ash9lg>W1~VTI+^H6BvrxsfMky*LQwV zkQ7qiOoZ8SVBWgGcuw@XHj?c8BiGnsq;Yn$s})7xXO6u{wkv+qr8Jph3+y>@HcqAd0sZIHDbd= ziC_VGrY?&*S1DZG@o4R?Sq(+?m|uZ;_}IWe?x2l?iHJ{B>BTh;5gA2tnPiSA?q!zy zsM9>CE82nMXL5m#_PD3r9DL|keZZqo&0;M9L5iDz{0lfiSk(d9$b>01>)DRle}_0H zg8ndr!EV*vkH!6AFYTJMEBD4pT1JnJ)p!R}iM}rx0EeGEwsz(FlKm$TXx>wljPV1L z4sZkMosjW2vo<@waBs2=afz>JjbqfX&U1^7e6jBKP8fftT8MWU^;E+Wp|~ z{G`%=Dsqp7qWCEIBjnHn_Y^(F{Jlixj)OS(VMZ@wt=(ZWjz&h>ZF4#tgNTx5JJUH? zogb@_4NxK zZ$7F6_%M8UEm4JFP09i{*Lml^Oup)N-ik^7zDA4IR)crbGy>|Tg})>tzq^3MqE;@loKxJKdKNzjv48dz@G%E{yi!E3%ZqrBUNc! ziWMeU*PzxbtLHN6t1k<(#=!qbEwha%ONB{H#kGXEGGN3u{Bz5ohmp$~TfavT))pMW zE3$=kBx9uUlf7g<1M#NnQULW-#9c3Lz}n-${oAh?>@QAn%=8Y+!ry3dA8z^~j3eTP z5%E|^Iz3z{Q@es__cd*%KnPg&@DI38;<9|sTR6BEa)@hm-A zsVN;Isrc6r@fhxVEAIp5lvg_$VIKzl&v`F)IE+Aort|^LuEW#BLODxeJN@E&0 zk$a>9r1%g4p9}TEP@mwBW>5UCfIeb#Erz!w+pl{!7|c|a(G6s9@?6%PsO=;`LqElF zAGAp0a^D8QbC4-VNQVvxkZS#`N*n%7pG>GPI6@bMmHvAjN&tvJ{FG+TI{DOr(^tR7 zAJpfQt*gHj>6LEc6Tnw7%WhxpoKbN_vCRVu>}a?vDcZ}RHi;`7*=QxWrf7O z3--@>`hJHxH>^bsmy>S*oAnb{=*13S^`Hzs`pU#N^){>{qYR5wI^v(o7t3FaL}I-d z2}^w)K6p}OeoY0pw6Bjv$}3bkrT%8aRTqIH8Q`iAF7d#*h?w=F5Q#kWzb%y;UZO0@ zku^JJC_z}@QQ(YB*6lLc=jXX>H~7+K#LdT9^L@E)!tnQ;amt&>C`?T0?YgqRiXJ<( z-VKjG|K}(qJR|A&26U2DS~TBXNE*d56rkxu1ZFBrVNE0lo%i5Lj$oo+h8e)yB9}?R zpZ^2_u!qn|hil@=hpXB8oSZ6fbU%3MajWrucXWG$qk*iL0RtE_R=Q4H-y_w!7q2@H zq}h?Fo@3EEfgWiXuW?jaR>geX`|{Y8RtKT6K83zOc5r0fSy40vp4!eDg!{(#)&-ua=J#TKv@uqH3O3+Hea1|~Qv`Q`a2 zVFEgT-TIZ#424(6rO{J){~*+BF6CXA{wr6^YUhXV8lh$?Zrmb(pTc`ri>2G(r!;`f z=}S}NBSJYxR2A%vYuqRccyp@PKh!XPj*O{u9VYg)3fV7g_D;$T(oja9eRIrdR5JWn zzczSrws%-qB!rBDAU5LED|=}y3InLO^e$@VX*lTJc8V+0t87ky;blH3?^eenV3F7a zi=+`IpU)d7!^~x+`((Fh`KFx5iC^5e{hl z{ko)0;;%b9Cdxjc55)OYNcZ-lvh`EU!oC0#7xAaNikMb!O`qD}FWzQQ*j_k-A98r! z{vSB1K$!`gsO0kR0}DA){(1CXZrIX`1c6`8QhgpJm3x|wxdab=aJ9oxL5}hY{-$wL z1r=`!s#rvak$3e>Q*X$K_;@+j(tEMlWH7ZDNKAu zx4)#@dcJJE9KgrzHHQFl5Y51-ez)_RG-~YKE87N=le-oT1$4oF3AGedX;S-o(=+X2 zXmgpVM}J=;z2&tmLCN!d+IP|X=ziu${+oqMDR{j@VPlcyNNicF;Gd`{>*5sp&{uHR zvJvs1mUVD}Vs~V6%SxiM12vd|C(0(c%~ZU#N;9Df&++4mWKSbMtj#5sLrO4yvNji4 zoq!hMcF4d|g1oeard>ZknmqY67UshGLI=0N+jGx^ea11ptygAqt(Rd!>Y_y`pM{?z zSkoL3nA*NlW6ON;ToTJto!FC<1B4S+;|jwu-Etpg70390%62MwO3YbX(#ZeLO71N1Ed&A0FcLpC5jC{@H(P)=@G7JAUeEYZ9dBVmsv*& zxtozn+UIRIAJk>aveK_3GGP4D}4v2T~ zn`C=}#f!#Y#r{%fTKiaLo7`&V!-#IdcHJ!wwik5uW`D!sc0j{1za^}k%o=~Nx%Y*j zy(O&INm8$rVj%@)qV}>kMuy#Jt6!i=8lJ^MWp{Ojf!%80iiFy+tP~{Zgi}%WbdfZ4T1E|r08p$X-WDIDhKH);%{E&L6meV+FPq?x@M9h9=*TNLa&k9HY_(OMS*2bEaU4?L80gebN)0}I0?{6U{8ZIPZYfd_G2%IvSogk7G3s10 z9WJM-zv0JAL`I!dWA}ww2c4A|4C^%#f@V`G8PF?|ZY)Vfd|mebNH7lqJk&be9ASL> zs%K3;w=ie4G-+1F@T;70qs+FE)Eh4#zHvZX(cmvNBR*>T0O`##pa%DSsb#zWYv`na zY($B@&Im^)5`&%e&X#CJtKb6V?>Ed(RGBbC)8LgdYB@jAW2iwc??VY>w%2x3zSHyvJ|t=V4?^8%gtK zHdUjTfa3aV0s>T!jCUi;PWgAaO;w4enUewEW&!toiE|8)eGW-in4fr06D9?mT{cOq zkHR0891c&lPWEVv6UEulBE_S${!VEO7+{mwN2$jNrNTDA?vbhR|EhmhzY@L6WbRIo zcR>{lZ$G(an5<#`efT%D-IiXvQK77gJ8pQ=vh%tZSG|GsWRO+D1WmU`rrG=&K?9&Z zEhae(!(q9tpHR~=@_wabC3CcprpJ2=w$uLDpiRx1>p^>X3n`f<_r9wbmrMXd_T&(t;Hv zuz6>L{-h~K(LC5)?I2YT}5aiaWO*#n4~9*g}+d360F4(HGit>vn(OM*6sdjE>v|S zE`Q_yxLGw@SlD|1L9VlF)J6g%o)fb0uNLV=ycd}3^S1Qr=MHOh3_u{``_j#iYCUNY zo}Z3pPPEP^JK;o0e}lSSvB}b{ZynI;YnBxT&NwVwwM}9XvFcWqlxTXDfzl{cK0qY* z&#-!8{M;K(jcU>=$YPw>;oJH7{=5rFx{ZBzv(xfe=kpaGs}IAi^~JQ!ZC85 zO;#g<^J_C9+Nq3hULTfx7f4Ct-xO&-z1w>xA`|LsbvKaKY%ncQO#e5|>od;YHZcM& zShNjKQT_R%GKNec0wAI{cO6ZDT|BVdn#|nS?DXB3{ds;=JQDKPjNpTJ#blyvvasU@ zyBrt=hVaTt97H2b=11!H8Gg1D3(I1QadWtA%Y??OD_l0&4XLwO)!a@mO#{GcplNZ{ z<722xp9=R${wis^f9n(b8in6+f4#~9aXoLHMZ{H{L3LR?I2EcP*3ufebaDjY7y%gc z!nLjnzrTQ(IscJPbfd6?3`PTyI~_XaYemY$+Rv%4A#iREE&8dz+#!1{f`9w38g`N4#rQ>3R8tjjte&RAfjPo7%OF59T`u}}KOpT^cZ#aRp8 zVj|ihY_ff@o}HpNXvcaZA2KTuFy%gua#(S5VUmHA)-d1I&rj>qB6o+%n6ZnG4YbKunr6iWGuQq;4EiR&EYKp zpJW~Hh-@S(xs)u&4B_dznhk8C1v+MQMN+%n4FSIFXgMjjeZ8~#FzLk$MXq*_34DT4 zEg2Lvx1_D^_EZXbk;I@=ytRPO4wTo2o!@;{{ek2u69_GP5yifNdq-t!NWYntu0QUs zhe=A5Oaa*CkE*lW?wtZx0Gpdj8|BUpS7ikuA?X+KzZEp0K}5ge9e?jY26Z5SzNM0A zA@-F)C&bhdMTb$)&-1u5KkWITU`PVfPukz9#%9)F&)}@92T}fv#GV;_|keSP|GazZU)i0k$0S}m9SMHG zk-@{PYE%?@5+QQC&CVc}LR!I{;ztJr!KUlXd>CWb<=5Zq+H zUr>Zs#8yT=abX+FUIq^i%94@OGq+Ds1;=Zf<>@pK3D8dSKOti3VKaFE-u7=)xMX2U z&3sOX(q)Qjjqg7h8lBY|$)aEq4qF(D2M9lZqj~s#fAMrOMaZsHlZLwGQuC&Pl!zxa z!N)sc0m6rALfDUHt2i=kO5o@6CZ6d=@CSKHzJk=ux2nF2;nJHYNSuTeV9Q9X0y1nM zw!AkXsZ`v<%}=ul<3u<2jt3PL)2AeIGTUg5yY-PJ{tv`R>`ng(`h{Po2PF|9@s|L1 z5p`sm<@oGNRV4c0p1#om#&3POXks)SyyYS54mEGezRC@z7*`puR9RilivO;JP&!!O z)%;($aJlnvRD2DKlxoiPau*O>0sP_o*=Hc2drr>v8G^+FP4QDvI>+{Nd~(#49-T18 z)Tr{}%FI7XM;K+2R8g2A;T<)yu^#EHCg`LUQW|i`iHG+8zTUH(GZJa}El-bMN+qZ> z{%3uHrVF}IfA-r+^j>nzD3nZ)p9a|uZVGghGf{j;6Py=;iTVamZsDYolgOje00RVe zR2-(_-=oH%&?MXI0tIckZ9yEyBq4-_Z~q@+xI8N*Q9vi6W-hZp!gF z<;`iX)XB|t(z=5MHbDGF5sRC@ijz9c)m*KUT27O~HIb*xxWBu3o2%4FU1gAhcQn;~ zJ(hN&$@bRYncBbLKtbB#U?bS&Bc}H;mu>u>o%<1nod@Pl+w)mM=#B8yz3xzT zOf0yXvH!1U4*#7OuswsJl)p)Gv;WhOTt4E0Y}^y2*cYWDQxt46V!%YlCJPu^5CQmb ziA5Cw2k2&F1PiDx*>-7gNhMa^1!kx*HD;6K@Pc?+KhmFWEUu_J84EpxKepHV-m@6L zZ7|i%H1uwZsA*ZXeM+Bv+a9j>+_qHzr)BHVD0y(T$;)Bt{$9*e8XH+5VL#_eBLBW@ zWw@mHvWu4*4C}@t|4(Jpz(69FNW>Q6^iC;!BnA)qb`@_p(e3?c{_lx-u2ePCINWGX z$tC8$b(^%@y~HCn~L`XnOR_(n_P7IUfba7VR~-+*PrxfZp*I5QW&7f*bb6 z|LE)D(2|Y?G~#!AJyQ3t*l;^zX`6yLzZ(in-DbBRfEJYP*yQUnl}k@RVn-Ro4+hU> z+o;Avh4%XGm+8*TR)emxo<9I6h}wuK)qL>N7jK*?l=LJqe)7%PU5n@!2(fI3ND_0^ zVUiNU&=2W5fjMlO;g3jDZQS#VfF}6uM;6Jcm^D9Hnw3lI8b01Za8jEH6U8f~FIP1g zMz1YhwrtBJ)vI1!*FofspX8cy+<}Z;6HX3#1c;O0E&tr03E2Pbl#sVhA3ZiCK6|IF zvf<;~H)GY)^J`Y9UoaLhB1cFTHYy6fDBHJ%d)-C_%YzxU~Rz|_t_YE3`=~@p~#@IM2%#(R3$8MVU z$oPt!G4V*)Szx0|&(-pYFV;kCKw^j)U~{jUFnFd%K8ZQu!vB-j^Aj>3$*!)J_W;RW zcBdOw-SJ-05l`A4U#1vmsxs)z?i>p~AM^Ut(zzwYa8MRGerYEuA4>ekXlcd~f)?^+ zDmrTyb9(;wx#psJkT2P98Ghk&AY+hz=?n>(`Zd`2X@_1A71%)u={7-@yV}y|AOMZA zKQ=ech9=GX8sGYagh#tU52zBRR(MRWHTtYodV{HqAMfvjG1H zZrYe}Fdm1PVQ9$N9B?8S#+A9)j(+<*MgNA!L42lIbFq8zvtTtzYl_W8^)L85z!{3C z7$DkSY~Uj(01#38D^W`Rr~|PAHkt42?H`R_D<<|K&bUk5ORd(3&TEK$626Un99$Pw z4`v0IX#HZ*3-P|XmYdHBjfss{7)`6-vI(o(`||G*-Adjn5(b-Jt$B|wgr)%7^<35H zHwU1y2i4fjdPnB4*_;dQL121A?+6SMc9id;@%ED3ZaIj1qDII+rBVxL%95?T{6FB_ z)}HcACX|Fpbhgkrou31b#y;tHiUqV%{W ziYbm`YS6k5osm{Aohy)*vG{<>gRMtEVooRD(sXLD5uQ8>S8nUN-Gnwd+~xIHwUMQf z5|bx94|ba_m`nx4`&kl{7_iyyxN)nqiy|Y9jB4eZugnuku8z|>6suh#?cP7^NuqRN za%R+)_WDu1L*8F@r*Fky_MVWsSD3!c0XCd!{4dtkHM&(?*3!w#en6MFJ2x@O?i~cW z6Ey>v{UUiv31>{*o+H;8n2Pqh&Vmjvck;NJuVjv;WSVbwXQ}S;|NQVTzTIb+Y3sQw z;#NIG9O=U&KZq31T-d$fm%Qy)DV6tLT5k+ar)h``Y5TzkmOITatMA9Byl#T0u~W?v znfm}i;2ANKe~%xnCUCxkTs`OIGPHi)V;G?zIN!WEdCw$p$G$h0pEyOyiT&D21%6NKJ-XcBJ;fak-@n4rJj`voM?2<~u*p{w zzqT`Nr=6GjIywd|Y=>24*1@>NNtwC3u?{k?SvCPQrAPZLxUlh%3n6F<$T@f^`0Qno`8lKwyzF{jUr7dj|IPw z>crX;*uFIwH-`TkKiA9==Pc#TaEh^uNO`-=2yEc;T&fq*D2mXe|B*0Tt%mimt6Y$9 zKg@%Bv&W$^R4?Gr|m0x09VhL6yJiCNpSb_wh#a8GBxr!fyw=r^Eq`g*oMTj|aZ& z0-Yq>&DlyQ+}xAz?BLkse=MgBMBZPvDMWAa%4DBi=ZJ5=PDm6ce%6bjZ~x)6Xc3-= zw1=C<@J{}zXS7VdJB7>6XCoLFxlf=Nf5FQ|CASKqRjgoN$sldZA^~m=iy6d_RoX5R z%<`l8%qDTLk@2`R@mX?m`J=?pQL8fnE^pVr$EfJqqI}*g76<%?ElbewykRk0*MA(Wr52pM)GWvtVzsfLf)>1tsk}YfEJ8D zu3Rw+c(Hv^*ZM~X5N6B2&G&k4Vzcj`rQD2s<0+aNvC8xG) z2>cMv_-ZDGt&1g@&^$Z&oW{J>f^=h&6=efHX}8Dqm-&T~r2+n&rYaAeN{QlYSm0hh zB|cDu5E)HIRbPo$bLIgpp`CE=fB;{L71K-lG|Du_Lc2ZuOfcE@xcnO{)pyKMbpemrVXS zzqGVFT+xE;d0o&K8!+UZZ>U7Z+$EoesV{kWP(>{Xe&&_D>oT$PkL zVP<+SD!k)XV2s3Ky~t}k@b}=H=jB-d>`TpnrjI|R?*@)ean2i z)6h6YgNyYRf~~^q1sO~&kar}8ntGF=r!4 z99JMJ^i2bBO(q_)xcbW*N2HvNX%MfY6MxLPoHJ~LN{@)BrDGcQc0rTa_!oyUQtA<* zY!{(Cvzd?o(Hy`Q+}3~boe5(9XiRk8Qs+5OTzz23x!t+wNG@@`des)#(d~1wa>$f9!4iQ^@^q>4iWKDgC=iMXItIzWpfap!#8ZiHg>k?(POQ zl*HEW&qec-f`yG2KZA*@|9w&-N})QXEAIagI3)&Mo(R!6v&NtsioxRi1u^L)(bcJ~DEIPpkb`~CRie?jO>%ji#hN+PPI*xq}DRPzolxXTD*&V6h zh}B_{QJcELo80H<0gH(Zm8?{4pH4%R%}!5%#O6opvK6nGf%n(Sd4ICX+f8CY$NJ>3 z0N$={nfT8n>PO$8STu5DJ#|j*y5??@(vOU-hdhGnMlZ@aYb0IE9 zOgNdgnIB|f>mI+v;RplE6zLUiRZSk8`;8ApYhDHfxoIUhkeuj@t)5QRn8 zf=`tb2+RmX$G?inC|g!G%yC{-d|U2Q%FDs9kz|7~*~76IUGc-61U(ipm=474dB)*R z45f*=d*%;>&;-o8wR3(2@FL1i@t;c;j8GUV>88a!IMky=!y8i)Oz4CNsF6BjsnflS zc%MRA7xT%KeAjS>2yn&(ab|j*v~+={ zGW3sr+0kF>9I_3PZ5CsP9OxZTT#5El<3!Zz(1dvCi#+YH{yiHTU!G=kW-=T}381LntY1S})bS`4(8cA?Uro-iOy|=NKA4lh z`ild+S5KZ4Uip7U0(nRfTZC4RmQw<;7O@`O@%dpZnJv@Ae!dZfdQt(3l&)63>}Z2x zDIi+c^2!z~469Zs;NTLql^7Js&!QmC&K;@YW=$a{%;+aJDUu?Rytn}Az z>U*p4ewafLeHW>yD~v-h`KEI$^&ufZ3eyhi!JVz4b%rG-a06pC4Q4*T9t$J?b~h0+EBMv$B<;(Evqw{#~GApt?HHr+2J z_2GM0;=`a5OO6ly)mvOc)!xR$(!$?WH>JAQXuZEEX8L=$+yfd?9lIZ6uVzDWk3D7& zoVOyYPR)Pzea!CznxS)qz4#r`1hlvhBHAPz%U<7VM%6_bfO+`*__(1pByy4F@(Oj_*o^E7@i_h7 zJMR^#c7K_1(CO%C*UoSF;(T+dHn+ei3Gm(e&>tX+otGgD+kdqRE11*FYJ|CJ3xdpr ze)KFjRuCQ-kT?y0&S(Eov`)|FPX&((utNCr?W0d`D?fUE9E=Y;$SzC%T6MJ3eieb0 zZnI2KSzE5O&NvBOSeWOO{%#4`Re_X>5QA&{J4l%&`t=jiR&C-j6@2hT_5B&dd$pd{ zGlDk)!z}JP7f^yR4BvcIZJck1x=>8Uh{NCF$6&oSkz)AoQMSw{UzKy+iK&7 z-bxKK2CxFgv3w&0PDM3!@V714Mnsgf*!6?ZLaB!d)Hi`2nXVCEtg^<;Xav6&gN(dY z#0j<(hmJ`_08b6q{IlrC&rJRNAJ=E)mTg(>N}ALrMTd$^or6fVp|O{yH^Zw zQj`N`PT4-kzS)gu)*9JwGOHNI3J?I#h-}pGo8rX^k!!CswqUnQQil$rEI2R@9YyCS6^e*6YeXt)v|mZNyPlhN5}*l4OGOnq+W-GU5PY z!oyGLS)ej~J~Vlupy)=?7*^4$HoD^))N2xxsnFriewMN~=LwrH^-C{H{r0r~*@*m0 z0?=KU1tIrx#Zf?I`zx!oSC0m9@Ac+hI8e@#RgmjuauV|`VSnE0PzLyYTEzP&9%y>APPM@!xcXq4hH%8A)Z8V1HB1eb;c5+W$Q3onxm z6%PUQJ~w?ho}%T>%dU(7Lt<}V+Q2QT7J$Rgl=2sn^FWZA47_>p84yM}7Ihg6GL!gf zd%j%D@4xco8DaWM?1?z;4aeFv(YgP)gM;vwzrGpzL5|6CyRV1`h_-BpQF1lH=c1}5 zEqP-=M9*d`M~ov{!kNtuS0-w%HR>>6176E_Unn*7fi#D2nm5-UVgV|r=FzY^<%~+4DvpT zhaehxbf^Z*@;ZW!hf6?0mHV88hCAUPyh+?(?x8H_22qcgp%+D6&G}gv4d3jY_@Y8O z-D(yI{$(@!&bZ$WokPC01V02Y*qCSjI0aTr5d3v?&Liix)jhdGZ|cUi=d`LorU>t& zqE+?k7-iJn3*$oys4ZB}wHDNz=*-x`?Yi8x)Lji3qOp0lFJdC&LhuJ3%gWwtm?#ak z4q+&U^;cmp2)KxNQao?lX~rfFUY>6)4Y)ha1g7CZQxxz&VlhX}Juu%-ip(fcV-ST_ z-;W9}WMhE&yRAlyFh-cvLN@xPkz7EXQxk`1B0R}x%QQ)bL9Ugz)US^+?fq~ipD6QELCjbbJ&j;2iO6eX+9F_AM4?iw)@tcH*}N6|8l(?xmU zQHB6oWts=g8N%Gy-7*o!tD~p@bk&K<@&~t3UJR3RxUfguD;CP`o(SznV08MOC<

#M zsrC150PE6;FZ&)@I%?@%r#{w; zd(V&SnB!%AeI_+G8m?a(0&I~c?z27_q3z8m^_nKTyx)NtF$5ys3bgp!<%K}%+Y9Pj zytk6O@;)v2={9**=7N~YYHPQ$PJ!7A@PeH}i6r-x3fudh=00;>`~;ezz8j*F;A3_o zRe!X}1@iYE#Z1@rWnXy8L`JpvD~Rk73It+utSk$HFhC6R8>jZ#*&k*z{DC4pfSuaEtc>(xpuRhS+J=#sD_!XkT@3CsVJ zR6lvD@V6%xTQK=HzaVO0-=pr$_6|>Q_z*}_hc0bfJ01fo%J6-@N$pS1&<{WcMFV^y zaJ^mmKFLOHdzw&j5&T5lp#?z=yepV{#q(;o?EXyh3Q#}|{H6+d+mR9HIdp_FY9l!$ zEf`NduCITn)lFSJKBjJbO3>3nkRwcMZ2K~7RB~3SQW@7)4=7i}x65#WMH4&SYsD^O z1a3ewii*|*UQzej(3^+kdisV>RHC9JY*;e6Yj7b9LDVgI%M0QO#^Vssw8Y8`Wjb{a zFcj@y&Q!nVFAw>#+^NqWi|U+X2k`k?@$ifSTSPCLNn?(WaHZPW7P7oZAab>9q$vIGIUCwVtN z27wF!mTPQ(2LJ~9@PTg{4%zW2<$FHLc+~gTsd0gf%z+aD=HSZ}Qal_{McOqWBW_82qJH0mP;o4f zoHOzElb2q0WW+PJNMMwCZONZd$nPf^RNk)nS8s+{>dAWY`{C8kKXrLn?)E;4)@mUenj|`CfBzol2_5@!>x5H8M*|AhAQA;gH||HPy)TNWF%+a0h%OF- zAWM`YLWj5o9kTj?2CuM{WrC${;u-y1NmC4BcM=?!P<|g1RlvczlSU2ER=TD9FPe4;#XT0J94*EG;mw zH_YX=-z-PdofhRipWAar%;->(sHZ`c5Yc4Qf#IG2)D&x@!}2 zDVhB8>N%W&Q9O1eG~kupo(lm^6a)Q}O0S-pEh{b0G+^?{{8L!8L;xK|3(O{6Xh_Ki zV@B?$r0|Fcf9-0qB?Qnb0`EK)Fka=NkTKLf;E}@NNNi%??@s|MX3(EE4fv}0>dQa% zes_}eIB|52jQa#&R@=?Qz_cb{H{(@s>(JqUHuZv5t-bxzA7?^`LWh7lKFeXmTc{d< z4DNwM?h33J49U0uAClxbSnEi={T58?i_`1PvYkSB#rCxekP0SPmCNxKgBaj`=w(cQ zc)%|Sw7hs;S2UCh`9dLRX~`yKoAQ{pAb)>ggQdbjDDW`3*w^qNKYG46UNGpy1boOd z!v|0XMRqd*Fcrzc$ov?c4rnrFIks$20l&{t8TEg?o8J&AiGK#Gb5aKZD{CFC7~_?+ ztp+j3r_f^zK~#At5*gB!(Oqn$J}*9f(A~!MNqG@b1Nz)X)JwGY$HMkdpq@HGIFJo) z(74!WiGx+ENDb;E>|e6CwN*dC-M}qm;Ykj_S}8Vyj@U3tDQpRlutF;oB3Bs}mi58g zIPr?6g}sE!uy?tIXY5Fw9G2&NT)S=SZ)jUGu=cbx_Mi%Qo%ksLe|myd(o>vKJ}0Rl zg8I<6OeTbY?Pqg3D$Z;32{lwJ9L-fD2C&AY0ls z(SX<}gI78vDbCRnu3Gvz9||N?#1I7P4q;x@0UkCfL7w_%hGgr%DpTZcHz0BG*>kfb zH1-KM*|A-M2F{EN~k)W%Rgp`w*Q^G*JMTpd17 z5#UL)(VlgDVB-}_G`8i~!cNVuAIoleicihzpNJq~Kk&$eptXnXqX|sp#FfeW(hL0j zN(r{&`bdenZ8O5~vBNGxNdQMs7NIiIEWM|M9 zOpft!(-cQ5Lh6|kVs8MvIi3yu$6mSh5TjXphDKo60U{58H~ES4x&ghMtO)EaYiMb$ zv}Q^%>DN36*`K_bjPE=2g#=HIVfHYVaby4^8iC{}FZz0&<)VIp+AO6j)vNid8svZ3 zu>erCJgnEm8ZB*U&L{*XXeOoEH>L4uJl z+F<5G>-w9$I1p6uF5J?bR{+^Vep@*Z-y^lMjSJO#`(zrv%H&S1;SJ>Ls;VsA-9^>mbNc0?kh=!NV+ z_mRa&>oo5l5VLr{#QYu)aRozai6ydlKKl?X46HpfTlBKi)y-Ou^eVEi7n z%5NkjXVq#Zj9ny9S>_%coaBU#S#JNG9wtEcynAnmo*w{4z7;?&$H&&$wll#YCNKC0 zQ%2|^Ag>-j1(-e%#O5os3&c3VrzT-07MF!3&Fz}Hf!@u}d_Q$P`4UX0we0G653+^1 z8{!(zVMa?@L~F~_Be(L&8Ol=j<6%G<@ub`ax`CpQNP@a;v;D>D(Bhsq%(Ac+ur4pN zj+PEG{~$ml_AEgpScl@`gY%~7gb&gQKniYs&xl>3-=c;3MOs7S*UyQy?sU(&&&2n0 z$?B|wdS(D%w--^49ig;uZ!>CB9vy=ciG=Ka!5~0hnrAS7%~@<6_n(GBi-ke_*&h6I zndya)*l0f;wMa7!WEdpIs+2xyJP_!cbp9HPr51~V4D2$s8yY@Dedgu_FgEOZIV*S` z9emUA<$p5|iw2RK^Eu!y+}r*B1q z%>X^t??G8E?Vi{A&W(bzCwZsZ`@@f7U(uSA_t&@*r5>2+cRf)&KXKkbz)vT zI{ZKdENe$&S218Spd5Rt41C{61o7`nkDo;jnP>m{N#Nw($nG%6fVNyVDCnIu=~e1f z=EQ$D8ktkQ>f0d&#Q=*|$KGWt8pOZCLeLMzb0WeS&u&ox+VZooDN-~3!%WO4W1lq~ zyb8wDLKS+=oJ!0NoGF*-ttmt9Tsv|8ig+z!BBvYsJz4QFzI|Fu7Hv-vUtRAkc1b9S zPQcv-#{k@E`GV0>zVrJiEJE4SWKjr^zxgK3g4uRdH(d7{l)gObUYQ6K#VQ3n1n7!Z zB=4I@a~iUYb_PSI*|_S!F2IP;)Xej9^?6K~0y`QpJ_5#(vK?91)UGbkFkqNKevY?t z^_}kBQBclBMs9)X;&m>-rQ+s(mx?rnvc}6->l6ztawB5&lQ&D%8`HaLU?#$`MxWjschdU_wbPK;1z&DP%*6^OPVDKqgr+D$d0W+f&r*s z112Fs-=IT(*yrKn_FJxrrZFP-J#-Ior6<0i-EE|2zRA#FX6LSR4#eHs{(L*E$;_Pjbw z*AGe7{tisdxhzXE(<7zc695JwWv1&O1+cuHml9^1jAMYL9@tf|RLHs8GkrWiC<4_- zFaY->-rfjnTP_97UOwFraCZOy$i)qbCpu-*QxrFfw2+J(JCQqQ2gsekRq3-bP5!`Q zn@>3-jsYg4W&4X5eFCZrK+D@l2gtYk1lWV>9RQ}=DYd^X9K!A*_pX(C&xc0XG4b zu5;>O&b@{Hg}t2UH}M$aJ`)(8kk(({fNC$vT{v5bfdJ-`fg?dG9+H&#b<+yy@bZ(| zx6F1wO1%UouW?i-Xf%~$2E{f4pd?L0ZM+|CDxRuu!F?41#7nJ&Z%j)yU9jNGH_4zI z_+g&DiJCD+3=}UU^NUaCm8d9eJDJs*D46_9AK|k9Pj4}}UhcIpr3~e%n=ErbyRUq| z27Kv;UyD|I2mxi8GH~JX$hP=6gY9@vzh7XwW0NMj?{%0?4z|$vn zjn$HfMgib#Xe08gWop6AL#>mZK8qw#aWr3?fJdQbJZRLfY^N9RIo6HuSx+1&3gOL% zhwgygF!O!w`p^fEyY$F8@g@((5;3v+>qSVKB;Kb@Id>%XG16x4{h+aw^=g@51r~;R zg@9F^p&pX6FGY~&#HHKTw=PyEP7jgsO!+60C{rWob9<7g&Uz%DKzTsEg~QS|VdJ6C zw-cY@-yAj^#SO?%G&kI95+ks_$BKue%uZ5vVs0rqvv7Q^dVShC zwzigy_V~~S7kDylru}M2Tx0}7l0TapK1}RyI(eW3akKi5C;9zNH>U01G_?I%) z{Dr;XCJEm`-C&Yt`iK6{czkIj=CE*zZBYO4ToQ;CslkVlQ5;uzZX8MXjs_yAyuM1_ zG6446>Nci+!VsQhc@yxu!y#Dk0iHpqIC#op^%Du)k1tHfTD6}|$$n1<7AO#j080^E z3#BJ*lIiyO;ri|kPqo6x=-TiPNTIG0q)k({3u%{NQK9*e%&kk6@~zA{*9&Na5=b0% zjKgag&?B%R3TO~0?4r$pUuVPj@`d&3h6$75oJ@6k@GXt8Cxvo;le^;;&#YMg@^Ez0#jI{=y{+i>g6s8>QrYEX?r?0gE zGJ;)-pDflFDX*0nC456#GH)f`1FC}Lazxo$_D-!KWYNa_4Ks)>Ty4A>Rd>;^0q zwoGbS6rDMps;STAr@A0_Or3@MH27;%Adm5p7~YN(Ws zT?00%4}V~yEn9iz$twGumDd{Y)1lkDar)S3g#$}PcmuEb22wzxhWjx}q3kGtliFNk z%7T~RR72hxaA5%bl9_ zQDX*&vmq^Eb~h@l<|o6#^?pO6&ecO0u7bBY9E9u041E4@68!{ql+!%M!VzPh?M(eh z(Ry7-2eWoNYyGF1Dmu#Nwe0uDq%p1NZuU>*`|;)yT{|?$z&wRX|B#vg8V&xVWT99T z#BGPgw`rN9RllF)Ttn(C%5-4FtZNa8p4z!+NduQA8d8w|$fdHM`m+y1!9wD>?#BIij?#$dH$mIL}*4TvGo-5Cx`G9g9BBIjPr(b=M@v z_|HXU=ud~lN9by*i>gw~C7SKCYUA701>n?zdU$itrfU)WkHDkcM?GO2BL^u)n`NHp z2&|!<$12tJXaU*<%qQGM<09vH@w6|^pAIlV1UWXn(!8F$Y@|#f0&&#>f672@(>(6C zt7Ds=Wr<>K?&`Fp)T74T2F=y@OW`@E8etc?JDS8?$anke=JwAhcVC64GoNPvdfCt3 z^fx>B)EsrqaEvdd2{96!&Ym2fvOFVC)T`EU(Hs>oaA{`ECUdo8gL1#9a5~-!dRg+< zuuQe_{fS?UQymXu>0e|h#rJ^0z5*>Kn^(D2QS*#dv~96^RBmA&!Hxa1>bA3({*C|e zTCJ8`oe=xX?h8K`TA-!<80QUzwaq&hU5&@rXhlgrp_(l7Ym8PL@uE)+k$%gdUe;-t zIRXtU%GK&tHRdlzwiWO?C8rg+o?Z#ID?lJ*@}y=%1!1P9x9<>>=dtL#7o( z`RV8phb};5ezfO@0JRb2?!b;kt648b&-c`cum%>@BRCdJzNxQx4n|#+;^GfW2(Ggk z-VzuJRtnm7e`C3vWoBEUvK?M@{c;W;IvE@*&~`^-JG0u8`N4z<#~|0QKs}AOp=?X3 zQMt~&rXszcR7zr5%{Hv*18DdA!)35go^JUEaih;I#E~*a{DyLyXHcpjL*&2g!-wW~ zC^Bq>WF$2E?k$7&lM)oXKd#_Gixsu)FP5&$t_p`!-oC9^D`Gi*3+>Yko;_Ov$mrIrwR!pC@v#o)LBsd-4 zs2XX(q_B6}@P2+a^8>{lTd za#U?TBCCLSb*(~5jUP8ewPJ*l*f^XA{MQc5T-9i<{aaw<^5n9pyG4?V0Q z#YK>=Ai}Iqi2qoMYkI)*u^}Sf;iNz|{onwTEU3pvl52!`Sp3%Ibh{9|v-fDMXIExc z<1rntMn=8`2Wq^-`FMZ($vu^1m}UVP@{|ya__X&ZOg$H+fHSao=&~b%8vifKK^W9s zSr3`vpht$LU5ydj`x?|f$xFL-V+;kIVMWOMm6z4ssyS)FGp52D3qiV}W)44R{&@WA zpf4qdAq5Hc zRfFSmyn*iIHx?F5)D8uB*#qwA9UvTKwa`l&f9qbsqxWv|>(uO?Qwkese^=Z5?%4=L z>422PTD|HA{|W~E&VM2HPR*Br=hM`9d!MKd&wlw#R*e%U+#R4Q0Z*TGQegVv#vvZI zLj(?#hXA2te~O#X^eZQ!%t=C$x7YPglJzSI=Yu4sqcAdQ$rJ*K>vz_IaNz;ta*jrE z%kg8gHnsa|EqL1nrJ>Taf`BEHVD@3D#}-Vj8IK>yk_AyOotb(|cUp7(-qHB_RbG6V zq!!q!3A7!L*>e=+b+TGMlP{{{^OU*?22k#(@Dd)lhs5D<*fA$3($KHJihwF?lj-c- zy9n&i2l#NlvV{O1Nn$MZnEbe<~-YkoruV&TG=(*P0W*r}C#$lHzKe zDFc^tU0(!h>7hN-AZd(f0pyMkFY!RSG}Jk=EH^H!-2iKo?p$!Li4g-bAWVp+&8?LZ z$I0q5qU?+W!arHOHoj?a6PVzvnltZkmJzTD8z7>q#1jIFXh8faX4HU3GUOgO*bBH96Ldk{jqBx` z8@Jxt?2*WcF=RmgY}JOHV8KHH8Bu+*4Bsppn3rW65mfKS`|u9|h^KAuLktzx09h&w zNxhp&3rd`45NJdKGj=_ikfZ4=WMVh?SL{igJC@;uidtbQf$cy!1{*iIkeWGxGdH`onw z!ZB9MMFMV|Xu!<05}$nUlxywjY%{mHzB=uFlVw@T?~wNleahtpzzugh1H zR@|BrNnGRR&$UNQ=*Hq$f-V(~Wk$C)lL$()5(ba?_3LPU1c6VpNT6;B@6;S!C;{|q zR#yPlV_b!BU%K2w^z`-AwLsS9xx=Vs%lQJk!|{zp%W1stk0VhjUJqjwb1YT)U*X6Z z(cf46Bv2p%L2dZD#r&{=1h1%5{C(Q}kLePHZN5>t?r~~SX?VQs6daY#Ex&HkckB7A z;JBGA1+^3LR;=(jUi8Q;sYn^jFd=RDQGbjhThD#zHArkqcZixa7Hdd0!1~v1>trin zK_DXeMHu=pf03wnlYsC?8n2$4Hd)Uw!$;yc`+7dR>7|7X4tJz_Rqa7>DG5Vkv{h@J zc74Mt(7yzmCpJD#%V{>u)BXZF-!n=R#l$F#;o4NLjn7oInIdI)FZ8czKTSm0$yKyC zrX&Y{S2^(u;Q(+)E_e8rFDMUdp_J6a`tfrMkDF+xo}Y5I?QK{dZ^FE;p7j?Q1 zmN(=%fn~&+Y?jhFA~K1ye;0VDiW$Wv z2U?6$WA@~|4tAcC8v*vKd*~l0+Sdo$4Bx}WS2KL2NSIW!{g4h2{?sbs zh4azXblaVioDe|W-*~4Bz<#ZF#U3Ktz=fEvSMm4a&KsFBn^zaOT)3xHA=WCfQX-z^ zm;SRt`j}Q%vB(Bt>4T9#g*_QF?pkaYG(B1pvR?q52%;4!OXDX>k0W=CwTj zCkkG*rFb151uXP9A(E4HZNLXf>QNOLVFn+51F0xZrpmCYA2m%|-CoNxU10e_7J(}Q z4BTJw!N(elv2x#n`a&h3!BTY*I%v=zO->9ds9026sW~z#?N6dFnlXb6pdyVAQmDB@ zRp5Q(&z2u?q&4kqa$&>-HG(UqTaUk|Cr3p%pyvEMt?|`d zetjPIB9)?7&B&pio*P)eZUOnth?5pnEaPCJa!B$_-(8@2eej<#O^hU4I?WKy@ZX-A z?!AI{+KX*io)QaL>bVtu4=OoI{g?ZOlZPN_@x?zYz~8FI>u4mD@%^ns`XYQ~A;f^Y zNxwuZanNUawRKDf0eu{xv=C?8g@eTP2LIRTOC#;h439C5R?)_&n#i_HK zuee6?pvv2EAnIUr|M7M<_B4e0$`*zjjaI(4RKbg1!E>Vi0e>@FGLcXK4DDnCT$9KL zi6XTQb8SSf%&zZXlO*=ISLz?MEYSU6xZF*=T+icwBt^vESj@f`>YMXcMSO zSOSL~Z!`5@O*}n{Zs0ug7SUV3%649eO@5lV`-7AnarhVi7K($#Z>MpVlfBuxx7*7z zD5H2$&J}u6n0KoX;_=JZ&e~$LT`o^Pzw|F4)bPK}sb4^#%R;9g=L0Ai+HSwiFK-?l zmMdB$fgbQbE|_~=LPm}(K^5IH`A-Gzg@&G_^uF&vd6+1Rl3qx& zzzgnh5kQjUQqgl;*DgsGi8_#>1x8uhz8JB%2PFOvfKKOcPLJlfR);?)>y6MSuM zdhIefo2c((E4|52Q#Z!ghM$zj%`g(wL}({7I98GCRe=u?*|Ws*VoUO{G&-F?*z~pg z=jd=BJz76wl%h&C$lAc1_3mKjTPhsB0bT=Q!glQa`^dJ@0ri9`ht)<=4(#%rHGG`*H zEIj~VHkyx8QBM6DFGqmkjgw42PcF1^RJ46^4i~?MI8^wQt@`ndA>9vno<48Z zi!ILp1f1teChzZ9@7Qn3{|T$ z&xYJ@Cv?KS=$E-=Fh+_y%~m#@Uzg^jZ}O6N$#vI0bay&m{?!vssWqL@gf>~RrdoLP zcvgH6YnP!?l7;%p`i0+6n7z?ASO}M!djo8!kPMnOeDUyOID}# z%aVOc81peQJO~`URGF0y+}7t#OKmmg<++SJ2ffZh?S+HdW(7KOOxw%YCT-3#Z#KIk zS1X+5QtbV|tLQ&F^qH8NUfXs2YBQ1*XlB#rq}}>5Dd5KYN0Wf;DUI7@AdgXyuVcSRfRZ-2NUNJxU9GWo!lSqU*(8Hc z%c)4j)X(-TR9$3+OQ&|pIU5Z}CH^?g2NkR$NR>%RsU=hVcI5a>&dEId<8;MYFXXSd zUP6VA^M-p?f)138`!`YaL-y;s=&l;sQ6r3)`C*_O0kVIR+S4xvCw0<*-7d;RrpFYVi;s4zy1LcxWo_%`!S zP^EU`W4s)O3TM#jS`i@)bru&3%xS&k3bP&B2T%n2A81f+LH*jYy!l&niwmc>85Plz zX+KBf{Qnazx`%kApMo{@p`|_otLLJY6UIsd`p5>y_b8}KXyGe-_1exPIKOE~+bDQY zt(@7i9%KG&Oc*xFADGB7mT1`;PuKFWEl^5e)8j-buZQmLskdETIQ~9T7oD@n!JHEW z4((7X5h$OFT3uwZy{nq8=WY3})O1m5T(#WTMQ%IiYDP9k@qP8B>C*9-seoKzT3Qd? z_}_{xQos>OOQ}au=|op{IyfQ8G5ZBnZge;baN&$VTb=Lqg`W(kzlva3*L~YEHGL! z`O|0>`BvCi-DTgowOCe<>X=|NM_*dgvw@LnQe|DM2N^$W8Pm<>Y1;|3M9H2U%HdxM zAnxX*AgXRHU^zZ@o3DVUCfX_10eB9Ijq3R!okk8Ncy#2wr9C4rRdFtLgmk!aMlV!T z^8Z|q93rAa zRnu>IRnXRz?)0&j&R*j@I%>3p_M9P&jSm77YK+~F7l6+jpKFs~6>ZDJd(lUv)v1pP z{MniRDR`LBlJvZM517l|S7ZM&f|8mfXXOxx3))O(<^px^IsdVzZwVD#Bvy?XF#$_U zO4C(Zixs3V`-j=po0Jt?sj6_+b{sm_XV8GEBenFke2XqHk1Ss&9b&VBzzx#tazdPrr)Mf)5uh zsMV2BC-icO`@$uhh6bt*JV@tH&i)lkup*uo1TO#a8h@swhm>ehZ>>&nt5M=ukEnhS zGj#Ie>Ctj?PHaGXe{WwLz9JZ8-PynG~%TVPXOyJwv0ICNm zKxk>c(i&FBj+c_!riJZt^20QnYCr)LuL3iDZxGlSx@fQeA5$Uum!0B4TUFIrS%;f{ zf>NdUa}TVSZJ}o)O(?5*F3V@_N7aJ>(qhz&B#sMLsU!IQ_GD!4d^?Vm%_DUKyZDpJ zwl8%XHLH7E%73+XNU()M*=#O<&si%WJQ<2St3KdGE@$B3^phb7gw=xveC7`n{AB?A z8)$VyqUF89LON_y!U~*U6~B}G9i){Np3VqY5gSQWqTuPB(e=VqADmQ#i_?jsS-qtDL-lq`KZrJ`Q$v&(v=PlE@aXZof=j;TV zYI5sK#*LZ2Q*99jhU<&4OgMd^DfdmTQM_-Eu|hN?$hDXpEs$FMfi%dX%XDa(Nd$V zFlwSl&aBW`{J5SI0uxnTSH=YH;nf8J5GZ51RJ^0&O}F>8*_J3VS*PIOu2it`PzXX5 zRf-FvE-Rgi7^_14AU?(80aZRq%65&charXz#b-=~n-($)tIPQg|8gxwU)t?OqsF&F zjSZiy)xI@4A#T20cpCA8H8zI9aHB9QW@IgPq_Zi0xY!>7(?*o+y;Yd*I_KVj=@WTL znVaXo3xq$o;U9@I4|?a|wPjCERD`6yH9)`oy%N}`ga(0J{b?o6%*F|ARq&*s>)<8J z;H7vtHBYak+ZwG^IDzkdiIsi2Ve`|t7_8A66P#Fqrut~RX-z>;;a-B5-!%~Bl^6~fi#~t-s+z%UJ%pfA_R{Nc9Kd`DKDka&G zLC&1SnJFdq+ChHYDJiuMI}I`gDQVE0}7_{9|W(s9U$PE$~HZM+%8$$vIEkSzbUPOqKF9bQ50vT3FG#}bs; zYo(i_9XwIcyLj7N2n3Lz9SqgCaW1OUq0;{jg)7|2DZJDc8y*ynD9g5!x5FE8N zyF?G8;opbvR$e`tV9jmI2F5krvsE8Ll!iErRH>CBKWlPyHr`@ZOjL(o0Yf!#5QJdi zQACAYozIfAYW`}3XtGv+aDasi*svEkW1bx!u=7ZQ+s?)~2;ysl*{e0_+Z$6;#Pr|0 zQsUQaQVMZQ#Ta=rByIN_@ z9r``~W$61Y0yJ{*W~!mcfhFb2=g0C4oREwBO(| z3tj%5+yk>2!m?X*_VO6vd)j_Qcs|`P=I@nLA{Q3-+xFUUy?kZ2>v9j1eOxV zKGE7fYV-SQTXd`9_3bemmo-0i|4>0I#-=F6X|te0E4%~fzy*h|(jb3sX=RO#(v-DtHrW(?5V zlMRHPo%+g^ed>7LgZH@Y{@5-uGCBo}Y3o(#a{8nEiWuhEF6`6bAVCBGRtIquFiev5 zShAK#mf>J~C48t9om;>FD*eB_bJ+qd%9fMVi(S3<7Q^W%ZdHyw!&nO>CR7ODEnce{ z<9srbuhTq^#&8A!YN=1Z2aqDxjT?;B2c@p6wfnwKCm6l#@x!$Kn8Q?Y`#jf9^9-; zhk~IgT(vh>w~oD2;T5kJE3ieocPM^xhz%nigJKf^A!Yh2vF`nHX*Sw{u?vrb%wgnj zfLhQYybA)Mhsdkta-zCG;Ww#P;aK^HF#e*yV|wLr zgYqQy`we(mEjoxCedLH)Q3gF+aq%BT~J&&F|MCoM*}BnSjM z)o9fUmkERpPlxZX_roFUl4y)^{~uL<9o6;oeSyMnN(pJ{k`NH2yF*%9O1isC8brDq zX{5WmMLMOsySt>G;q(1H_pbXdvX;ZV&N;Ks-uuin_e@uS#l@-861G;2acC_G(?!4i zDm7@&O(*%d7^Nw3`~;`8fz!Uyem*u^wC~%)@z{JszT4AI~AT1*6H ze1s#BK8YYfbPYDZ%T*myKzd8iq3nk@vQ0&6m@y8Pz${c@L6^jgs=+^fNjFIph+vZZ z7Q8IZa9acvL@;3o<0Z3L3*W`uw;JfQ(v1?|b~egMEo2N+8JY3xQQ{^c2x56l;7N92 zZW|+j##<#ea{rTtvY@>(4;zxz)Zv<2)+c_MHtJ`uQ3m#=;OzL(fFKM=M~`e(2#Re+ zg#hU&yBCd4ImyaLCSvM3@C7gOB09nx`-YOwY=H>?^YiezXi@ir1RDiJun@Gddt}Ko z!LJBIKmz+9@A;-@jYlZ^V>uS$GN^F6_5aHm$%rNqcw`u{{FNsu26%eTcJ{*F5f#iR zN|T{$i(mhulmb(xsYtZ!&MYG9%-J)iBAx~}SCE#p$^6bUHaRP6p#qb0RcLhhFqR7Xsal&BAv>7DR_5rK!&)tMi6 zGCrL|ST44GS402>VHc3h`DE!YVZarv4H7tiLSRf2nUarDzQ&){F#7C`uA4Lp|U!{m^p7lB83`7ryy}#+x zk$&L0OY4zq3jb}*5qk;%9hXUJVgLfnswD$!q?Fu6AS`q|t28ZJT&IepM6yp#umtxu zD4Ik?gul(oRUweNE1kUbXcFg#w7IqxT;mgI$q9X_q6H1B`&2%lLja=wmg8Hm8;M0m z<@1lU(81QEf;s0QgXQZEhn&)6nLWfIAj>+si~7CPCpt|FB3}0xM#zXVkeI-UInIw9 zpQn5dwxMc{8Ud668W7sXWaDa8!?#Vrf>1tzpdz3MJCS#Mu$k_5_SH3jc_i0k;2i}Z z=s#-VvF_WjogGtG78AlpirlAY_GsM>=h3;(K#xtcjO*_^x0KfJ+3u+`yK8w~TznyN z*-Qv&!@^UVAwD5G1b7RBeo(e$5rQQJu}B^CrWPZ1ojwD^m?p$DwB;PIZ4$M8;oa;T z2C-aBNRZQMwvbA#_irk=KnSxZ3{4K)U!dR3wf+gCIxJtHl~cl*H8n}orx%u{%cF3* zsAKg{$!Vhdm{mG$+4&hkoa*pjM?!wKwk&Iv=Gm-6?m)DsD5xTC^xE9q($o+LR@bl| zAX%!=`^7XaW^TJr7%ZiPsZ@FSt(SuxwAB`20#Vv5PLdZK!bwteCPI)QEuss7qi@pj z+4+x1@hb}Tz^bluu#{F_3_0ts;a^!w0`|!cII5OTlRT&%gvQi?VU%3wBfSirjG~dH zvjp$CNaq+3@X#v_rc=LZu6-Ci~41G{Cu0A9-UGiKat(7Ufkn-mCYTJW9ivR&dK3TE)lViB{%HYD05=R#v_ui)0$ zpbjig%0F9MgD+V`ahu9Sg^GVI{6ChHYx}2NDj)}Fm|nfC&r;7@e|XrQVgcAiHq0|8V`RuB}BFloz(Q^l~T(YjKa|uN2eY5tmNx zPRBtHFVgqfUz~HzKUAo-gewTNXA)thzY2xSJ9}<9ajEYwE~Gl6`Q{6A$E!Hm$b(&c zzfG&F^8QOLv^UgQ17&3yfNMo9Xo$S*Mko0EXX+0~WnNzD-4awxMNSyxs~sQUJcs6b zOM@jFB_;C=rA#ahT}d00!#4l!OEA=+q=%nJ_#M1DcxrImQHq*S9s%jYoW5v5Nj4UM zY)dy{b}SZ8K6~Yakm(ELKD>or!ewWFM39~Hg2mO(BsjDxZe2`;n?7-b#CW`o#M>}5 zK$?cjEh`iPpt-I{yiAT$z0E_Y8jl>yn{YxQc(|uUt&@+$#{HCQLS^`=rW7AR9O7d? zhH#nK$n}PEML4e~e)KbD_~9f;n_(60?;_#ffaqo+mFzuF4y*YY^S(5wCN5!9c)VK|o_E3bK)Rtd(CywGi-F zTGzJK5TeNT|C;}>SCqD>3>`C~ytkclDOo_Olu#tD?ULW7IM$vnG0@8M#hP|ld-5hW z5qQ~5i?`uhd-xFv?n4OL!Gbya!B!L1v_>u;jdE_H z)RYt~F-MVeKPM%@E+Ncqk}4PALe)7qP4y0-U?WSr@#n#*wnYFdUX8V<+0a6j_h}J?$n!=o8eo0mX6>v|V2P&yzC2yEg$PL56m)_^Cq^pb(bfXqhPA+zwaxJdPOdy2qd zv3L10X7Uyo!&+LuzoSp_;rQ0|kQpDv4dZ}On8vD6Wrm^1KNVHO7?D)1Z~1-R=j&ZT z5x-JRBfo09dm@9*U&HSbbI***;fQAuff+mi$;i>>Afvy62qGXyTf#O(%Eq<+U&U$p zdl~KbXxGc1n8zHa?VOfMk@N2`?*evkZZkXQ%oSn2REK4RsuzL3f)67K(or`8k04&r zdw?bwOuJ&V@c6T%GF6)gy7KZ_7H52=l3}}9KpOQtR^FF^_l^3YZ9S$ zrRjDt4M z5V`Wo|EeqIy~OG3kf$eeW{zkWu8qZ`*eH8ik~T`u~;Alh*ISX%jZd+Ix+p@?{ zknVp-E3{9L`u2mir(0w4fC;ULkZX<8J_6LR5X+y2K6+u{k}d&4Q1x2ml4KrT&ofj05DnH8|4W3y%`c8 zvN3b9lTq=_|7?82`jnZeb)SXzi_$bFB4l=ctyeZkSmsK(SI|>CHNlVFHfUXu&rlK? zEfmI^K!im*dyJrlV+AC!=$1C?+-*2-_W9ewRtbkV#WGt)rbt*#j}Hm#160K)<&OM&9Iv4Ci&-6RCVdQbkbXFCbcXap**mSe3 z{kujn;XdP47*QWLLXYgDDsam2m;|LyXWtxsmMjmwcYrbXMbriY^uDWsleH2T5VK_ z)f6GA{$aNDlByr5thb^M10lBuNNFm*-@gX0-{^Szr~HAi6FuyxuOxbAQ@qEzrpoDV z*Y!$I$uWFS?O%*p9Q(>&Em=-NhMX21+!q2>SeI*-3#UQ$VQ_9=d=5;I6T5y-Arpk7 zL@1Cl`8MnavE?luK*!pWr&j=7q3R7!ZxY!U*I$d^Pv_bX@8~8#%jGJ*v>g9udxpEc zfdMV{Q|*^x<*1q~b&n4kkGl~Pne4ih@02Z|W6m0BSI!0#8Fmq}YK|sjJ~ZBRYq509 zqR$s@bqT9g>U~S@kmv**+x_P*ORVh5?pA^;3Xa%t03in0(0sBc&No$p&)FoU4lsZu zWw!TbC@DiDSaMrj$NWzYg^aD)^gcJ-rL{PMpDzFaSMHsP8T}$A0*!?rv=kt#dQ0F> zVQ;lzWO3PVIomVK`p(QX`bZ-;ex`(~H`{31Bvi)W5u9M=Q@lJwdlA}*HBf^Xqarvi z8r}pE$LUN01B6T$D@)1xYV(HKjSWLGBbF-Tgm=Hv=3#1-9eS9yz|losGNlU*oE zLo15RB%GN6;0)qgfvvGGHpu$6AP|i+RvE5eeX`&pKsDUgATXyNVcxyjZsVd2Ck8+I#f$(Hb89z-FKhN9&0^H0& zw6zk>Q`07kqQDwv5x;f z?KLevFfn}ASjtL@1E4)E906UxsxP!lTDz3{nq~*{b$^{7DH@>nHrJ`VI!f#>%Lv(v z!80ic!La$cv?)F{ZCH#IFd*ydUS#|K3sp(L|7`VSe>z(zeE)^n+r&HQio%U-Yh@|nWu_*$#qkhw)YB#?#)6*axA)$81*S0D{ZG$_Ez zKOD+Bqp~~z9uCsrz{uBBF z?X8|xt+BPCPj^YXlo7;1t~wHsG=*Lx?W{Aqn}j4v+JSG0`8;Uzd=T$I!h1bG>@MW1 zrvnHYA$UlG4<&9mAVdj5t^D ze`PhxZJvdJAUhr~+zcXKj;tSE@IwRLT0uQ-yP=uB)H)OM(q}&c+mr(C>-}2b3hMEG zxNH}By2Q~T-RoQK#d}2#(RBc)0U$GSClSONYr3B8q#j`e&v*-bYsM-6kRwPKpBFLl z8y>!a@L-a{`p|A^ZJE**Tg_hnvp){HT&p`FLQ(Y2b^8j|1sVjf)G*tBpXKtc zfuLlSg5;PiT_mnQ!H&*x zJIX-w{IJMsB_aC^(1`s$su{oE?c{H4`zslPez=K7YD>kT%sH>cQ!6dDEszp5sUM;$ zy7yPs%H0Nk!2+07`cS=!)xFNwgvj&-mU>p%_21a{BEUhE0?LMx)DTT#L+5GuZ21jR zF<;HmLgc;Xy=3YKNxn$|DL8$eAhtZxM z2v^C&^(%uHPfA=NeOlu9H~y5Kjy`Gua|&3XaF@# zPJ+AY=xm!%58`u<{IeJPW}r*4I*jUO*642uhace48QtL_G&bg>@4OwVhZjYfhW5qf zj=~3G-AzOv%$fx}WLWh*puke#h`fP(u#4N0zv%7miIoH7W0cqVLz~$WwlOpkBfqA? z0Uxob56b1&?p-(ij5%fu2+eOS@r)Pu;1*DX#Ymw(jMCnY=m4`4A z8xRay%$$>N`VX5(9ezQl&jlrmoW{t#bY8Y-*<{4LEiS> z>Nk5tn@59W@9CwaihIcQ$A@qZ?OL`rnjO^s2$ytibLc_o7yks-)KS>!2cf3jUa2UG z0qK=}wCvQ3El}}~&#K$FP7i5l3_J`CKA-sbzzOj84@rr+g+a~i`z&$tubJMR!|~a^ zU6u_u%(l-?Q%|=C7W5VJy}kt2v1kNT2(_(GiPcz76;>D_yTr7?lU01ArkUCFVn9Xi4EbLl4K! zIVIs&VbveCXmR%*K9r6_X45EtG_O&MRz*K*0d|K+78kKcfTGEGUH~pRR@y6ZEQ~wFD8!$#w#Ksz z*nQE3qAPqDO%+O*Q{G~_`NhX5f|yYIm;aYnxL2*IcFI%oC1sx1Iz*T>%3gjxKrRdq z8RZ1BowWne=-jsWND%u$HaL}h{bbH0hp*^wgM%P}g zmr$h~q2_hC8(Mpw(ufoJM4eu_O=!cCEi!4(VQQy)Gu zouaXjPh>n;3mh>1N_^w{E>y)4t=!TSd^Uf&MIaE}nHqDM3=?{4c1dCLGX{wqXGLyk z2V-W%S(2Ujv(p3E*}ibaM|~N_@jIoZo*1hdNtji0*>;OK9UiuraCuU^jam+O6DfS` z7{!TYn)M5;qi?Z}hDa}5NE^s46m&$0Y%X7C_MD0-=4ZVmnZOoqc;dwPYqLKsG!URF z?T^KKA2D*s@Va@e)BwGl{oYQ7ek??6Cy20$^{ylk^i=Yi*5&qbsI&+l>T5kq8R*i$ zB!Y|}K$t||@yY{s38%v4Q7CYsPMLct319s7o=@ldSM{fNT3~$&XKI?zJr))JF^QR` z?W(a6!cSpek4dnyt)_tb18JTJ5$%`u>BxI0`AG_Q`o1FchPG_pMb|J;3p zLfV1Ns|->|Jxv`m%03pb>vaZ5Lz17bT2$4mME&>0sHZ|{mnvd34K24dX&p)+EoPd} z8=HvYuF4$h$vqK zvv^}6qyzhhR;kLRXp!i4m2#-@gwrM5N@|@P&j=GCM7{vn_g35wFLtA^lW@Seq+56& z5L%otp*u8yWXHO9&z4omCKIG46Vg{_sG)=W;V>gn;z+BWck4y*PC5}%*cFydvuUlI zrOcpQ80zAO_*`H{xYgf7$*_+PF#Dtp$&N@crbjg~)Z&zOCzlmHem{%O$qw0zjh`BV z$lI%DebX=enziS~5*=hN+B^=1b|B5aj;5d16SdaJ>5lZWpdeVimAI#rpoi-9fwocs zOOTTY^%i=O`*u*IMaD(Qw+||-apdaUqDLC{^+&EwP$B*VU|NwB@p!AxFZ<=35XGB2 z4>UHQAoyKZv#+v0p)tNVM~{Jsz4gs}d`$4l^R8b!(2(?qyl?9Y5e661%?eQOW|a;| z$>DORsOG3b(!zpUM`lG;AruT?fVU1Cna*J6e}jq8L16q!&c84jz=cfZPynDt2r|+s z@wakTy?C97KkQ8cfx-5kae?Pb1S8zCRHg~YA4tb+%k|Zr= zY$GG_r9l#K=b`63fG>|GnV}oVcv`2WAd0_(?!lcDtMOy_1&KnX`%_%=wj4#@NjGI^ zlChvP46}#HBglXgqMPXE*qv_2k4O2|hhrPcj{pxm-P447=?66IoH}5un6@0ALYTw( z8E;!lNuiuW4FQWwoZxsC_g$4ueeJ{SuuoJv46uF73smJp>J1V#z)+KrdL*|Z``vLo zniGC;zLEbd>UFLl0uBg_)$=_}8be6b>#5+91e5+PpGGM$1>c#vAM#pouBq}sYS}|J zI3Rli%G4AmX@_%xz0%i|_hf~D`GS4%onUH}hD<83n0VM!DxvOBOoc-r)Fi#{|4X`l zF#;1R$}h~{?&;mJB4X90CI3zPv7Rt#&(k&ABxXyBd!JtRo|AZ=DaS+%h|`uMW4zkI zOTVYP$S&(Z_@|gleA@ZDL?p{_TL?N@IVs55Bw~gGG#LRjfRWS+!QF}F-|%1-0kk?b zevernj&g)$pOkPDJrU~Tf>^&qb4eKMGVr5W*n#OEm$c(9L~(-pFN21L$J2gud5E@T z)!p-(VXzwrh4+fhK{knWV-IF5d%NvVgHU(93#G6PmzUeZHz51U(Gg9+xQF4N6OCM- z;WQ1N#(#W7w=@{BsdDa);wOPs8Rbgkiq$sA+kZ*oZXeeLvidlAI*^*F-`RWiu+%DBdi`@|+HH{K}n9Oc?1{Og{Na z>pYE`URoq|z?C~N{x2u<3M4bf)6@DgodI&3PnqunH;^ey|7T7EzaBf;tzWyiNx1!$ z3iL4}Kv??90S}H?qg-X{<#%t6uXQVT(-$96Ktv3gA&8^aerfjpCbnM5>5fsBQ*QMv ztcYJbuRz^UymGbKCdoA$6(#W4tt!DylXfcjEO7#Y;pXOUHt?<4@8tLv1 znJ*1W^>&0OED;-@{Ge?E7GakcyOtJdeyo|xEZ5HbWa7ZP2~`Sp)r!*elFyC2D7ol` ztBUDz1KCw3TKvi#h?EfSJdU30d@f3t0Y(QdNEMhlmDi4t{EwPvKyjb;aGV&@5Au&U~b+_?iQc{5v2x8@j1IoHQ|0vv6#ZS(Y#=9q2^x0;x7y6&Dm zcbj3L5K+DLp#|RRd$=v31&c#8<%pL0b|^uAgzt2ov1kqB4Ntw2)o~X8u?ZYpf2{pX zOzpLFNk3evA5r7Z-Z7l#Z=t5&$v+*4YrQzx5iAiRlmQ5&YE(dmL|`%1&4gJ+$wP8Y zYB@qD%P26+gcV+bHKQ^eFVd2EJi1B4BJfX=dXkzsdolU&5^55HBn8ew%<`riNU*Z5 z@HYhGhDI^=P}D_)t^TUpk_uYm176n4+RPmq!efA`s9FoYM#fx^5Ah3YnZGQlct@EHNR@ za>YDm%;W#||K}bs)Bo_%pr3u?fYMj_D__rDP9VX%^!)p0Ry|uHb+*}|7r+=@Z}h?u zr3g^WU=qQ?`P9|7O5tio?u*T$r`@phSip9sk;TaP`IKHGXbzwwh|f8j7sK4$jY_cl z){Ew6V+2t-YaQ+Od&ZtqAtN-N4*p@TMSEA#{eMV>Gl4R4Km2#BA9SCNwZ4Lblkhd1 zG11DuAv4xs3s17dIwJzPV>bTdTtr2q-8(~Iw>@TIaiIZY`p&5mv!N<*li;y>Mlczf zAz9kT^v^-!}C92>R^!D!Go_CTz|oTj=t8TqNK4JoGu zy1ea1%flJV%oYQ`ixQX_La?+m)u?5RXM%K$X|qIZ?R;oQvXs{NReOsG&I&eKY(TwY zT=yb`A(xi>=yT zYjwmcSb$Ez%}wda`tY;;mQIq#hZueX9&y~4^>NfCBEYni(Q>xtnUDQr*S1Z#0*o#6 z_-<#S>2DQv^)1sNMi*?3!KGqxH7+Zv;gm-hS-H4?mc4B zW)Tr|k6TBWk!)uF*RBn_g-S5LcZg*<TqvcNgcj5qi@u|mRYd@rU&U=)V;;~^r0t*bg3Fe@VF!kGG_@J5Nt{=^H;he!)2 zt3=8k1qDb|>pCvG_tEqHbkFVTI`f+HN#%x=?=TCu>Aa2gKUh9!4kw=s=N<4?_x(n| zijb9{B)|BU7lw+r9Mgea1O3yRpENwO=BQy_!Q`{_)8U=Yn0_fd4(m%(r+xf23Ff*69^uka_#+>nNXBsll zW~Jmv1uT{Mq>RnC9`Ax44wvALx}Nfde>R`j_@;6cgl*A1Zesbv4+=t9+KZccjSn+P>jy2H_v3P; zBeijW3L~{-_Z`uQ-cp!nTPf^sL$w-|Ys@e146iEs(ds$k%VicWiK zcjLR%-00oT+u@esZ^9N3l!vV3UbmD58H#PoeO;jNhKl|K%;~e)39pJB>6z-3C274lw zDG1sbj~@5@uf;@c$Ae*X1i?ho$Ya9RaX5T6NHgCPwS2F}QjTwxPLxg(Y~wwwb`8 z9Tl&Zx7c?+{`fqEDL>8Y8|1YubxIQq-&4d_N{#O~&Mve37;|SBmStu_IgG0#O?_N1 zgUuEyoao9HT(i0Rzw%MxrxRNN#_&%NbeYt#Xk=L5JI zfrv8cm+mMuYJaN~SF(LS5?$&%nQ$(( zRo~j>)H@|4!n{U%r8@q|EsaZaoYMVZM4-&K&a2vZz#{BJHr@^A>GvD!9-TU2?GP7P zlO&53P-&#JAI!4NC7aY3|MN>OE50XRs^G6YqLyS?Ha?McID7q8=moE()aU-^*7QSq zhI^{H!zRqCxmHsakaNRvD2y3a z0vu4Z+N)9^%X`Dm&Z1^7w}Ymfk9gM9fz>U};v&!x40RCIHv%ktp7&qhkj^X)uNg{! zcm4NEkVFidceg;=b-aJ#;oMoCtx zoxkAv^%Wn>cd~JF@fVMVft}f;x%e;L-{46-a0X4;NPky?iB#qmU~968`qv<4*J4c-lXP-6H#UKes=o6bfh z`PB#&*Iflm)PEV)2>+%Mnc+-DQR$j`CLe5Ob}oGP+=wM8$IR&eB5ho zlQ6L5zne1WjtR?%E>JN8LVDWCrd4n5zdkUzGI&K5iFbdRLI5`M5soFl-|=qnP-nfz zy}Z+l+GSv(sjl2sqzYaB)x5Elv%T1H_!5TXTmCaV>(oR6m+enQL{{ZCV9-h$7h(ez zLmRm#Ev!4!gVoSQsL|fd8f+}2m--_$C(o!~2B%Znx;%mnW$s{bW-_%}GDlVs{k#^l| zFq`qqR-Kg-yel!QPLRTRc($m`7H~CILSe5`cR-RBgkE+IKx-H{@Pqh|s}PK`d74w= zrg7b>8h=%nX;W+GhCS`P+XR-?3qISbi)WUFQnPr5@^m@1pQ|5ca+oN>weEAbqS-Mb z7vD3pxPDTw>Vnvo*q*DIesUZ^7vj#9;5U=GEyk@w&Ll<#(eI7>P5k>^K z2Ld+-1}oEQ+PK%I|J+e&kOb@US@FnJ!|)t>Igjp(8r=pl-%EJ=L1}0c++iA%`2#jp zdq&{!R>NV62SMz=TZ8_rXVvkkBd>2wXABmOWVl@glu#11_Rub{5Njf_b4YCbl0`T{ z2p!!aXFl#&mt1dKbEU6uTG=4o9zqoP%mxv3EuUBuqk(B7$fIt{c0=g_e_ zvNbQOjf)_bZf2F{_>kFaO|<|9>L2mB+WHtm4?=pS^H$9$m9l&1xQ9zSXjOtDka`~c zGRgj>o(o&YtP$P@M?g11EGG6p}8cpko09Y=YhI&)!Kq4dY)-52usKZ z`KQ(Nv2=e6CGmU2&%{~tV|hP)U|Wt-8TIz-ew&l%`D}ULk3U;2i;QFAHzgBMW7R8j zsmrZ=N_NRPdfn_hp*@@1w0^=`ZYhVma@x$Fp;TWl_1Uo94_{cM|MyJ5oN@~_Ci$}G zdWZ5vvf({Av5R-OBkQr3#zChS7z_=`)Sub2#VjI>zv0#@AG;6oD=ux6y_q|NGaYPO z@JY?uTVqVKrw zY%2zoz^7sVqQ-I^&kPb;f4xG7w$UnHDD6b&*nmor>cV8^@%o%VnJ2=W)bcD)>U^1< zFTORaYV$cwVB?C>d4eA5lou=~lz2ji{0(Ga_((Zon$Q#&4X6IpDF0IVZd*CyYSgR& zbifPu(Ewk?Z<(LeiOn#*!!tU#K97Q#k)8*mD6N|Ljf93|c72q354E5*dvI9IXcjL3nJ`idc2*?8=fioZHsXLm3#C4-hKvGyQ*=P?#oO-4lRHeIxA)b~YD2S0`IGXKa(9&QXUj!P0 zDuMPhaz?ne&-_km3Y!m%A-H8uR(!aNJZV_qdqJJG!oT!~@Hf0%lvYk3$^*(1Rnb;m z0dmG^^~$Az^QjtC;W}T;DHz0z~#1gIYk6+(oj2Kx%xI)<)w$lJDGjnym>4d8eM%2Lo+1ey3zSlj$tYE0 zusD6uQzqTddzY`x^CL9Qun&q8W0Z9FJQQj;6d~8W6z*oO^ju#?U0)nxsTWV`5d!C^ z#+{|F)yu*!6kkK)(1Xi}8)fqqJ@@37`dIkY!1l;!`~2I^+kd?(zn5Dxw46lq@vJW+ z!N$px-rMVP#y-br*@86Nk=)0@ufwT83M%su+}ei{+-uXfC!<#Sl*yqBvd!8>O4_Gs z;n>;`cu)QpL)pX0t!DAr#GUdUa}928C|ru}Gtv!wQ+Hpgx75YoZ4d0Yg1EMRfQAgX zF5^)mF8>r}WC!`S&8=lH*okE0vdg_hUyWJw1x8bsDp-8p_()tXasbuqATM#gBw81N zF=&cL{F6whR_`@{sKlL+Oz06b-*|!w&!a!q61*Ysn3>ipsRX+qd_XDkyJ3t6{Bbts zObp^b?BN89ml|6=zv3X1(NwrK&*%Kx;82{SXt3)y8s5ply>N{+MOSYo^c+ReF7+f9qMjHGgyS zRPFj{xIg&;Y4H^3!_YeO_7pL>#B5XW=<@9CU^!T;)^tpCO#${8 zT=Fv#m!f<5C!+XV{Ce~GLc|`BGr-G2@A=@2tfGmU`p#mv{Np} zxDP+Hc~2{A5<6enY~f_(DoxmG@W&s@`R8{Re@_^fPhdf5bWC>}+3m~=C18x#`VGR= z5+pJk;FTA%wi+o+CWeImlHao95tx4dm|Ip%Otk5Aolc9Kc%EpHQoH@*g=xy(cGrau=2qWD}@=Nnw8$V!aJZT`j&gA+Yh8pa2P zWLDMJCZo?%=_jdn8q}u6uLSLW%zDax=|&N3RM;|gSC`UK<=cnN{iHs030MK*>(pi? zFg)F`>D{#xn;gMjJ*-|qFY%YQoPh@~6541(>@cJciVhrrpMe29YardK=LCU8Qav{J zs!6n%-5lBp%=R)phiy|={53I|+3Ol{&jKagYECg6ihNZM2pw4y3Q6~u(^BgS=Aq*w zPc@cltYltj~M}Zs~oYo!z!5zq0yC~hRUel!52vQk|t2= zZjnU1;W6I3Y@c?%+-GXdxKQGM!$_j3XJbgUQ;8fCKJb|qV%`mDtu(3CEY=l1W^{*z z$P1+g4glVU4$NH)pz@R@m+JiAiY1fG#?eE?FPddhP0A+YJuC*lyQ|r`|~f9XBa-pTf2zSwnTu>r7i|o zJlRqtJ{x*hN>Yo>?1J4QRc_Iw;m~_*C$@-B&n);be;9PPIS)WwsRJGcqpx%`tfZ>6 zZ+62wnDIv=!l57q@Eg22GkYJ`KTLI32iPHwRV^nL+ zmQz!N!E$1}isNbenoK?c&245wKZ@>`e*c^yFFVzjE+8q~3@-=S`}n0x>>briTxO7y z0O+GDe_jUe4dmS5&T2U@G? z>)O!vp3xC%0U2&LffS`5P7>@@sKp@N;V0`T-Ml`28m!eLLxog8jfjg@DWtHL7O4fW zoAEd$Uz?|B=WAF^l8O9@eF@fbtLw;kY0j*0G#{(n#BpXGE^>zqK`<9n$2NA6y-YEgK&76PDbn9~f(D+JLAK?ehbtwtj0MZf zJ(^nXt3&xwLXY^@kX(OVOJhXmmgcf^(l8tT{*_=GbJCDhbM2W%O1;J)CGq3kn9kru z8jGx(8-*@(1@I`8O?-+chhPcDXKVe9PvHJgWHmh?KTN8_T`6ww+dR827Et%qf`9e{ zvJCQJ^tpRl3f?xa-Rx|ceVD^5E7z=egv(c1b)WXEZ%cl*r?YPWQ{$?KQlH=yF3Z7{ z&lIH$?dydCnR(f(ekt0`pqU$+kt|3|c#GBGU8oeD9snxPy7~4CrF3%QBt>pYpr;0u z`H*C=IJ&hMj68r!bSmaBFWZK-N48{Hef@2FUpj?ThR0a7ax^^5N5`CdKF7#A5ca_L zFzI|hHa-P!N!#PR=i-=&KMYR;l>u&N%$XWoXS3MSSWv16y2a)@CvXxl_K$-B9+naD zjh;X|vP!N}_>v=)Qg$;pKHZI%J)PM(F$pbjIpgN*%z|uI==hWWN`CD__Se}0Fc)91 zOwX>D0*i>h28#od%MxE)>Ac?BLv&voJ|vs{r1yQ%TjtoXdp{*#@R& z-!T}3V?^lE{|CgVyME1zmWy%a z&Q~@CE{6XIYfz?Uxz2(_q#=|5K};Wj<69F3hC1cYumdfc8inq4 zdF~nzt4bNP`UA(o@IuoZd70iQ0p9-~>NMPsi^dk!WPJh73xDhFcZJ+ z>Lv85KWLQ}S8mV&Qg z!qq=}#Td$s4JHVT%EzULAj&^`;*#P^`;*nf;!O=roPl|^Ij+i3;kWK7kw;hRbFjmY z#9#05C{8vO-JbpK)kk6)pCGk=-A zQ?BLdc=ji9*~r%)4SLm{wO=m?3x3?TKyh6jO&EH!?No5)%c?Ug({1jM%9BW&ngG^x zWv-1KaAeKj8a$$_2 zWFqDA;DCSkD$&lny>=TdPiUjfple&&TV;i($5j=^PZzs9iqjY{g}HhW;};2q{wj1Klvpn=(<6i{@H~^M%^#bCPg@@TZfKvx_bd=UT=NKX_3eIQ%rlWxP~9f{<3q z+!UYJ)8BitRgw_8AMm84C9ip^G&QglaIpXUiYAprMxEPraYR3Ic0rSYXX=PwH$eGR zBDfk*bWBT#C@kUA!DbWkXO+(s@1pgPq|=_K)9oB(#b1q)AlQU8G5R;h=)mfF)yKAi zuDo;1{B@_*p9uDrY(`g~_y_kr0Llavd6c0(3C z;*#q2C~`DmLRKTkAXWVia)0H~6XaL(v!MI~k>u4)=;d{dJ~>xMIQ8`EjWwq7nnQi| zXouJHG@Z))VocAp3hgU@L4-;pSVXs`{Q=CHKj^eq2&B`Qw0PnH$#gT5S$e^zy90qF ztvr9eQE~3tzD3gCvo$;(WtjXNZDV)nGpLaC2aVzX`MF#Z;hnUEwRjkjzTn0h427#e z_#|p;HF>zddUcv>m|zwk(%P61R>SAws>&Kd<4`X6h<77DYsaqo2(@)vT{G<7?8TH7 zIe#+Jh5V;S!dusOsqS(=@864?BzzKtC+#|SqEW28ys;nM9RBXwgbOF9kbKn7 zFMq#L)%eYe*m#f)%LIFv|51G1@t0IFE>+rEvk^g(79Y%_uiI2STZTpGn_fCIcX9ly zrU;>{EgS9HMXOZ29LMmZ$-c96rkU@7%{ZIHJRDI--+Ubf9<8n6qv))FeXIjwce zG7LqD&+xyII0YRnt>3>zky+@z^dCvCY7lluhQv;4i7}79DaJZH*VM7)Ii77 zEL~EJiRHhV-+6kbj6^K`p3QXnPRFf%p&d78b@$cDt97yFH+VQ?gh7W~u#&<8eM8GI z8F2?4JMqC;R-J#50wp)OFvUgO_{4k@ZY8$2S|3O@+qwBD+e=#BN2aGG)Rqb!e}-p0 zIZJ!zhr4V4R_?gyfCvSKi&fVlIEe7BmZ)BG)v%8-ui3K z*0B$p`GX4b(h*N$%OgPINPGTLXub9DBPa|h4vcDWVpy>kOoM>>2$8NEah5ZZHbRRHYWx>vdN+-ZBKGRG*-^# zZ#dbR8p3xII*8x8t;$rJn4k-eGr206A`^xS)#1&u*TNAv&9Rf^ki$neIg=q%uvnEi zg?iM-`jbs^MY+^#(;Pc(DUqXF*K>q+ypw-mi^pv$`Sj+_GfE_PW-H&R@_9!+ zpFb2loNp1FpA_5l_e7LWP|X)9*owg0L2H0Sjzzd?lU;keb;dV zQ%_#R>Q4-FZxHq{&?X$F(visnujeicANQo-v z{@8n`yMG%!e_n6(o!p288mei9Cn^`xP3o`l2VUu|^|KtcrTM3f331W!XhzN_v6efg zQ?c7;yd*IN^t%X@T29@TcFG-=3vkGxDiYoXoJjZyJ)w5{?>h;9JKy^(*EHf~W9Ju? z&p9HoZ_mwEixkbykxVx~&kAe0pmlt`0IQ66&%ZL}vaY0Q;CrY{av*ikpz>85L44Cl zI}P!aFIGY$L%c4FGj*~j>tXJ%_urX~_=_ePUpcHnPQUb9fIq%&iNf1u4l3|A8pU8! z^l%=1C+)Q1!d$EU@dFhh=xNCXu1xa2DYOTZ@KENA5`OpYWG;$iM_^|9TEP7dMj#YB zPwBxn#VX0*%wsuR^w5KbA=`kwiccqAy%sx^<8}Yc71gMSDlyJ^;7;qIEgxBzvoRN} zADS?k;Hq_wEz>{kV+*cweaWs^N2U;B+2~*V0wjMs$?)ybQmp?bpqWLIV_d?}STCum zb15!tWGa!CWCe3ZR7jA-3Cec`GyRJVIy|~)5Dzo_|MBz{Y*BXK*McB}C=5t5#K1@? zB}g~OfFL2=64D^u&CuOQN_R?k3P^W%cXz$F&+mV|pJ3*kd!N16UTf`h3Yu0zIw#+x z{3N^=)&?pljYrKn>5c9~%+wOH@RyfiASf~L@#8X_wIz2S7_4YBun?bIF8|unQsR48 zzl|L|PcCDS{?(Y`Mmc7v-P4ltlumBt^Bh4R&p8`uprlL5X>E8uP0(v; zfz)R!5qYMf4_ZyRXa1!Z_Vr}gx?RZ*F$KoLz}I~*OXz;EOO-q!b$#PDXsBgkg*|K2 z!4fY@cWxXMY^wz>`2;2$N$?THUjNPdFyXZ_ANlgRYs=ibY~z5?AXk4%Tc+=~4Uca*n27%~?-b4P7TWpAtYER1%tE8# zc6$-1+v*##qDlKT-CQ6TJ%C-JI>4663%{ZAhMW2pC*f7{1y~vid%am|GMk*UBQU!g z=em>QwxZ5rqf!Be=Y~T)tpKKLD*BT%!IPZiOuZY7o0cyu zL5B0cZ;5hRky<~rHCFhwzcJ?Mdzwi)wyqdX#H{I!;fEIkrP_d&>#?d%;eQ_l7CFgK1#0qE*y#W0ujM( zkTv7|ZYVu~U!2~R>FO1_@BK{k-(oDf4{s4DqUpAVVT|w<7Oq*Vma8mok|K+-DMb*U8PGKV-;F0in#U0hWURp>91@G>Qg;^U>zmqHFsqeoh z&FaL&y=e;{Ky&%n!k|E$Fp{0}vkIf=OC`-7gkj*m7RObzWW zPSG)OfJ+s_IEbJqtw>w56Y%N%g;gWbH=vM933^vqx-UzHl1KpX1oDsQxA3Rvla|Pt zziB-`l=5T_t)LtEuJx$wmwUWz z6?KPiW6!qi)e~oYB)?r~3f*>`>APK13V&ho{`3ZHC?Y~!=d>c=H$SJ^zH;>0PbVjy zJ2cHQ>3zd+myvHdJT&scs~u~=4~2){hP&cHe%hN9wPPWj2X`Vsk#h7&I_hjpUKbaW zaRfiUx_;6gAPZ;U$SPvB07EDC)DXB1G_YxH=~wRQOqJ?)4cQ*<$sH*D>B`r`*uom~ z@>8!5OEcQAqhHo=Zbi4Yt{mPjcJ%+@cVT6KEL~nQ6S91kIVwa?Qc&~Fbu)+3uMukh z>Wd^jX-`XYhqb8PmfT;ow;Z2J>hb+t0l^dXD@RC4qefPe+3-!i$}2+UuOT;bI{FYeS)$( zpoqx{NM7yk&%QpjH6w`cbUNIw2^ta@zjM|0hAzZUMpH5@U_SGwm(DP-k!(1s++3;l z!G+nj7t#8BdxZwPxL)LNl$IS4V*NxqN6`Mb*&Y)$UjpjogqoLp)QnhF>)NVRFSK~w zyTtHhbMq9pv|YWR_6WoRfx!K?=B(5kVK!T?3KA7652mXsY5HGRx7fvzx%AmPG8D+m z;!)8sy!m!$K%+XjI_#4FaA>p{KFG=7v2dqLEfR*T8TNkJzvD@wl!UBWMZ|OyYdm#@ z49-!}FaC9QyWob$?!R2E=7_k|w-Uq%Z+;Z}FcG3ZVsemollZ@u#Y7{VJudFMol~sL zi@*U0+)x?FZE~VrD&O%;SBeZ|49UAkAXcRFW`PTpgJWnmk358SI7n>?>BV`^PCDEf zax--oe+6S)5%o#=JLc()Kr3I{#=MNS-aWnesmG`6{vaAVYO4jDoF{bPcyyZ%PM?*Pv6+le98?9li9(gVpq^0-JXciYbwHYdhSS_L@qt9jcmK zaASFVzjnWM>)dFqZC-@wVx(bE767x?R*XF#H#CNwkyY7m9hjXgmKVHL1OMt z8QrLoiw5VXU45UKr#}lUr)7MnIxQ`~Y3w1fYQ3+5qW;sZ=Sv8;8v6ADnM@|7NACG(KInK^(|= z^&Ba2DEy75e|#|YMqsRhYtJskg-(9mfAK6jcsMS z?AyC2PAOo6P{P%VgkoNme-5M~QN=W$0!!YGjdHlF{dwsGkR_deCc59OU`K7~QGEyq zW|$JU{V88QsE7F+NIH3^EAXQXOEl9N6gU;}vYDG;7a?gEZJ0{W1YS2bn1zXe|6ovN zVHbJcLee7g>)xw*YCTMsR-*Irl!^z1; zY3F2kXOHzQMC9wRE^HylJa5B0tMFcV^7|YpBBOaZGx6r@%F%}Q7TP+Himz<=yghCF z9Nt4aQ8mMm+ZS9O2+c>sIyBRNYw}tJ1|{1!;|{Aw)v8Dy5)#H|R@|2L@U&wlLroe z)=B>%z!$$bmjRN2ZJ4W8V4qt~PCO>$YM#`Gl+c;j>T7qHP_MOkn%CT^)l)fBrUKm; z0$;@_xCiU)XcS4m1QUu_N1fwi6c}HK&ID5pqJv!?uGAM)HF!l|(6$mXZt?{?28{k! z{=)UV0E1!r#g`=PfQetcVJ4I~cmrs)WJ0Z69Su?7Rl#_wC&KNSsG1LFI+t2Z1x@D) z>9+o7?l3Afz4D^VnmL0sNo>BrXPozX72}j;mr`jDrZ+Wb0x?XJGAZklI%$@^RKz=m zHuNJ@5&x^Q3FzSznC&0gKET|3?|Y-Bfr6Uxd_HuO^A&*lGBB;}V@KI^iz(q9?z5WK zAgi^ol*@Okman)43-uzXJ_pIXt9et!cPSayWpAQ6YRy92-zD?bpWfo)mj$s7_Pg4( z8o&UR>w*wZFoTMo&ZQLQ=1%xAxO|409`b=A$~Z+?Mkd=Xj81_Z`bmlAjqq#&_RBEd z72x#SGtnDpO^>=fSY)&Dsnag#@C<;;kFhjzB-nH+#-(K=nC%RtAM05LvmrczUoGrK4EC{p?_&^klpDtrlrkWkd7qxQV-m~gk4=-JsZqx3RbM? zky4j$C|6RuVRIO$w2UpE#Kk<>9O;*A1%r$**lYG8S6BUMw$mg)f#hIlhGNh$c(*6y zYHHmTKqP~YZTMbtJVvosUiF_{Yd}z>HvRnUd(Nji{I19S4Xm&^-PgJmTw(fIXFt*Lj?(I+hG#JRfx~sNO?a>0$^s9cANn`f>nx)QOd|ONWyX{w+&0WE@q<5O>q9 zsx*}@<}l_46G!;oulH*MfI&n{QdMLBk6g)ow5iRO9^If#9NsV@S8x>wp=|!Id8Om! z4$u(09sd{b4Mj(; zC;5jy-@c!RA{@Q=-)XyC3{`>XQY=!F*39Nuj*bua8w*O3v|OPAG0X(f&LW+{`ud#& zb0il%RcVwXe|Eff@S!U|+b7VFa2N$r-?xd3uk6?Og z{A6Rh?sw>P!Rk~TAtB0BB_13S;;B0~A7IN&DTj<+x-qaZxg~3* zy9)8V?g`&2Z+e(@*2FlUj8pC~VG5`=At(>rSP%pmQ%y3$w^*5~%0T{w=wQMsR&+Um zHy4Nq3USS5%=pZPRs4?$565{kSZB<$n2Uq_k%fjz8@Xp5^b^Gz98V}mJ7~M~R_ByA zW=a#kowO4VlzMeKH5_9|{`LyGuh%LT-9_)jFG>mdW&hf`8!!pgmAC$?!Uj+|Fmwtg zo?aaa1fthHOq}`DlTaebX}=!2aQ=4zDx;kXFGqtYIkKTl%(kDEj5s%}|H9@fwAQ1?kVog+~u z{AthMS<}{czU5WRpVVbl=5hkB3smHuE@FiDyDo9K*VD0QkCAe1CU;E^134Mc*-+kP z?-1!==mSK$k$KN-ssMeVlj)znqm>zBUJVYI!Q`N&jF+Yr(|pLi(ZV_b=rLaDdq+S> z!mDGl?l`ldEw>bM8guo@Ih*Av(|sxwoAH3+p_*zH3D;)~Xs|Kw*B1KXtrx}guDQ+KAPo2`w>Q;cGG&C#VF(l2M_wa}0e;0i48 z$9Yb+W)9u^wsLGD(LxJ6kFTz{yp|7lz1J<#GVh-1c(ooc)B8%;y7WV6CkqtzJFxza-0==>Sgutg|{Bq`n#@;TK_%{j(8BNIye6hW}$f5g)>B; zL*-h}l4buEG67J+gPz5TbChpnMSs0YuuUc;7#rE0+A$mpg&v%^Gqp%2A*Ar(Tc-h- zaAw`YH|sGDn>_!jvHUj`&m2$jRhorTX-2fANL|idWE!O~)$N?Zk(Ugfr?TVrKIv2m zzlkMo2Klht^+>~8OrPd7fj4~&uHAR0*8HqYYi^1Mx-l|LXQ6vx74?g9XCAR4IyCfT z6^}Pm{vUEv%P}A?A^|#0MLB$`K5#X2_R z+}@;Jd@#fbD!w!Y6JQ!Nx*eWWiTP*AXl8EmP5W)s zIcxC|J5(wrt-SdH+VNE6>zE-MkPq6u71Vr-iOR*?YQtq!-C${NyNCeIm0la#rTJ)7 z(U^~4y_B18cY3%P#O$J98BOUMX}0P1CMmOdle$z1R@P+y+FcAMAS9@dSUiJQsVd^Rg8o%?7$RvIlDAD9*<(1y4bV&rmMd+rUXdB0WOTk)Ie=5B{Q?7B6~)mpp8XFk7d z!zI7LLTM2odLp^GP7;U)^r(l&Sxvj9j*%eh{JtqkfFn}jJJ3m9{9kXzz41oFVAVanXuZPLjfktI4Jsba@FY^s9n~OT{8gZ_5H0~QK?6s$ z6N&b3JjLZ|w9eGBwxv5)&N8bcI#-5X{ZInJ!@U+#r=A&_G$l3k0*wdd!%RP#C8<{f z5}d03PPLMEj*33x+oHNgvA?{5_8ur&Ed$ogB5`m-oa2_X79*PIxM^K^R}3=na~)fn

?H$}{j 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 o$bt4xlA4 literal 0 HcmV?d00001 diff --git a/_static/arroyo-logo.png b/_static/arroyo-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8c7952081ab4e8cb1704ba302e4c6b62d5744f73 GIT binary patch literal 13031 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 O0Qb~&)oN61qy8T(_&SyV literal 0 HcmV?d00001 diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..cfc60b86 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,921 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/custom.css b/_static/custom.css new file mode 100644 index 00000000..a738cff4 --- /dev/null +++ b/_static/custom.css @@ -0,0 +1,10 @@ +/* fix mermaid diagrams in dark mode of shibuya theme we use */ + +html.dark .mermaid path { + stroke: #fff !important; +} + +html.dark .mermaid .marker { + stroke: #fff !important; + fill: #fff !important; +} diff --git a/_static/diagrams/arroyo_processing.png b/_static/diagrams/arroyo_processing.png new file mode 100644 index 0000000000000000000000000000000000000000..21004ddec1f5b65e4d272411acb2bff5724232d2 GIT binary patch literal 19166 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 literal 0 HcmV?d00001 diff --git a/_static/diagrams/consumer_groups.png b/_static/diagrams/consumer_groups.png new file mode 100644 index 0000000000000000000000000000000000000000..09aa7440e8124155500b3f926c49c8331a2f22af GIT binary patch literal 23512 zcmce;Ra9I-*EWa+Pk_cHNYfD9-KBxX-8#6tHXbZ!;}9S~0txQ!5Fls>P6(2qfgk~b zThKYY@At2n_0L?)nv1!h`}8?=N_OqqwfFPv0;#2;^c0s07X=07sWJ?zgMxyZ3j966 z#suzw=YFCAU#Q+XN^&SQ6EuHNP%sS<3PuQ5e>+DPTNEaK`Tt%q@$opgdn1_mp-g;y z3NE(R2rqXx;1am+>Tcs`=V)v5-)DS0e0-cdLYzDzdc49+{IWccAA-DG0wTQd|CYD3 zw{`oUiUhfMfC^aDEv+5h5boX%O#E`dZ)G=xtqbrC+y*{1b%75f;E$KboLA6Xm=(B` z_3&`9HMF%-bwn`nDGKrnbMXrSw^>wSdg^LSeDc7xi=(qG@TFvH?d<;eij9}0AD5#$ zP@GqYOOT5fxFzr49;^7hy5)$Cz<$dhX|2e+L!aQ8Uz&%|{J4-Le|4VC+ zL-)1y@^%E|@E@uCuX-OJ*di?L|9e-D-`|E)OVrt4m0yovSyxL}Q_JtaazF%l*#5VS zjjgYvHP8`0CVmA#;x>+!_Fk5*KsAp4BUCRB7jrpTgh!w)uZO5Q+}SNa*5<#(`Qa`) zR)XGs3hIEY6!i=Q+??bUJe>S_5t^>9RtAo)dZIo7aHl?05P4eXp0bZvQfoOm_l zRbBYBtbO_XylmZs_3h>L3>EbBbp<@_1ns@`J-kG%;rx2O?rs4dsywbb&VoP(oc)zt z-F+{PQyLu|{Bm6X#96bV@oOl$VI>19m2VQF>K=%{{`Lx}gZJj-wJ&c5{RQ2Sb2m@h5 zJ7;5{3ka3Rei+CG$nx{68VbtGdg>dv**LoRBSh8t>^%@7a1R|3C4Yn()RRX}+tJ@m z-dVs?UDeH10Z?p3U0H1?LP>|u*vi`1N6(E{$;m^9$IeH9KhV)w2;l)W5cRVc(Gb>F z64nrgIymWD%fsZf^)#&=H3hVJ;qC&4nj*r+c0OM6BA(tN0#HAFBN1_cg6|Ai6Z4vhJvb^5zB5tZi`r2-uvi`DOD&B?yc1|v` zDuG@a0!F%CM&7{6lGAYobW2xW)KACCP*>F3h)2gq&c;X6AL=9Q?x2ORwsqG~(uM)G zD?-&Z{Z+NRL><+PoHaxg6$1P`xZ0)F#q zz~y+HeSM7dcnuwOtv%I@twn*`B2I8kTLA+FKUXy;UPomgc_Z|rF8 zIh6vCyvXu+q;WadLSAe@Jd1z>9=>x;@*D&Vi<+t*7 zHue?v)G+ilLg-owB5ZW*5IzQeE*g4kpT{QLyn#*&>f0LY!0o+x-JC>( z1A)5^JOaD{0j`2BT7gRbif#dR0&cQ=Hir5zd!V#{vaya053e5_;l^VrY-MkyW~2+( zgsL05yJ^S?`U`6qLAAB)_yY}XZ4^9&ffuwy?0D<|^95A=zbx2)%o*_efA$c51#auy zJ`@ys6lJKap1;{&(DG(Gf4*-svX}F+53&un$8dfe)CBreUN48}=%-2rU!UP%vbDOeMqhLW zU2+|)_9SBw(5_7vD*4}D@#aYcytbdr`}Oa1+yCE5@pV_gsp8#AcX0gW;p#?z41q=K zRXho6+OuoRO4duzO4m!|O07y?mll-vm9D=)O~JMrN+^#F$B-?E1u@}* zm6BX!FE_p<#~H131(k+C-p|*Xv!ewbuSbE4N;N;Qy#{MbzPi#PBF9O9D(ZCl>}7Uv z+m56k9UaM3=#{51t5X%JzJ2y*rc`Mtfih!E2Ln}BhS1{$#=at0@0(H*P4Dr>7ti$p zocCfrxIlddDiXRSYASzp{*|b|Ghnq=7gb88U9P)o)D(7K(Th|%>Gax+1NX&~bFbh2 zJB|C)U^gD;@}q$PsA)Kx|Ap7~M0Ko296dcYHd;+=m>WdSw!`nxY=5zp0GN@1eEFD^ z7n-!cM>6p8^74lBBs+C#YHph~*yEuAC%=^y@*vZ|gs{`#lCXri_uP?1;gK8sW>p|0 z#K1r`l%ZdO$hA%a{i^fXGjLgKQEz`8N6KE3Zj&z;mHrKXN5|_)UEd7WkS(m@=JL=G z(&;?UwVA}OU4YU3a37S;s;k(3RP>)IvQWfu0jCCC9#{^>ks38SknD)@7;<-AW>jBb+(GY!3+M?o zBOx17Emw^64YRtAv8MFHEkBi@6GYZZT!YLme*C>Cap?WOQm10u(M*Twf~e;&(<`1l z&Rr}8T5sC$dr@y5n_e3}sQZ_xFOb>7(Fwt$CXmL=A@3x;J!cFU? z62!@~NWVm4+WGLZ|BoI_DAIr19DOV8sV~S$RI;nWD})BQZgE{)-9fC!hLcXkT>qIc7e$#=>{dH+ z)d9Qx_ZKLBPq(;+7G&HtaUG z$3Yfl>~nbI^9s9F88?>v6g1`_@=nNxv0}IJ0Z;GmZ`_SvSiRQXn!7Q1!RI{3@x5GE z2{wRX%?!pxt4RuDs^emxOO*UBAM@-<=uD}mVJ7xuBG8!y>n-d*A_RbDPC)6kd^7iR zH^=g^yItXQT|t)y+vDE4V;sf}Wz$uoH6vmq=cYhQf8zB&+ymii+6+)KT>WiIZZoAfCX>xg8KeyBe_hk zT&FBC?xb!tE34ct8_SN0bNGrn?$Ae^|qz4=R7zdKR_qPGic(SL)jduDr*^Elhevf4n zOH?x1jb(LQDyPRBq~tWnWn-1l2)!lxSpxxqRBqv=--=I)&*g0Qx3^=Q=WAFu-_y&Y z`Q(XklGP+yB+zRYKzC7?JA!v`Ssn1&qAfo8y!S zJcFg0KJGMPK28cDO>D4eh=LN_xIn^WOEN)A>GeCTSEUX(tKGpb$7jF_ab;!@6s8W4$6ZRf{&`?=_4HeIwy=wKU%BvFDsUt%6z^27a2ZRcmpw;>%8$b~0@ z5qfM8tCVn$28y2&^u|+NBg;=Q3213xY#pr~h(E7^eXao5S+5Rz9;Uj3gEGuC_TF_e zOuf!`&N@GO2#~<=Q?oF6WBwP|u6yUrL#wN90NrITSpS-%Mn=hRm*Dm8cr*_$-MH4^ zQ&-pVxbW&n^>;!$t35qlj5Bv?qp`i+Si>@h8Ic zTqU`gX7x)x&CB0+>5279wBO08i2lNP zG?O!boy5SLm3($Q;# zcJ`<-{Ld-486q2g$LoW-P}zA;U>%b5dU#JZ+E2nS>~H?IuBHcN%{|T72b{Ay?`@4& zm&<+>;=Wa0#L3jc8iSmEhbz@24av!x9}{Kc$v7)uu|5J0Qz)m~lZH4inw@5KE}air z=Bi&-cC_1s@oA&JL0q5xi2ydTN-mGg$$+YUH0|_V(mmCm~0>5AaER`I$21#%}h8+ z>)j9rEl-@F}=drPAn$@j+PHG7lJ) z7;zXCO>Al-s|>L)cSNS#GOOpW{wS0m^=uSgH!}o7dNS= zyKUBfa2X5m-n=K$rem#D^f+D(Bi)uZC&m`32+Zpl7jQ5G)N9^2EZ(4j5 z6YwMZ@JoZjb+JXiMz}iVRoN7h)YNr6M^KlGe?{qJR>eUiYSu6f+gfso3TZ9-LvUT_ z(B;PD1UnU59eypJy{lvn#zQx}1u>j9PF2~(nHxpPO63*yl8BJyRG&?I1(AfDN0Nx( zRj!21|5GSXzfH+2qzNRXi0~5V{MYaVzv>6r-RKe*85xxlWJ2IZ>mmDmRh><&BkJ{H zXJTBUN=|u`N%MH13+t;d?MV?o^khHS{^atDwXhH^h{{CYAV(xlcMYP1_~ZHzH;(R{ zG+wklX(1-lV0g3+!DkNPgxmO(d}XG5Ce_ebsK`HTdUXRnj&W7Cpe@D5qcEnB3?tnu zpXnlH;?e3R#jLz9pIq&7F~%QSN+v#DPMOSiJIDp*5pzl`Hegk2G7^nP5z+?q2P(oK z9Fa>K9b@R$NsWr&rgf9{9Yrwy$TZeS6qG}N*bxkW>ELv^|3f!;mgh7go9gE}T^B5} z(m{|o6o_L-cJo;^KGYbLoe5qN3%lYU2C&?otbt#EI9q#Lm54Si3G~JdOCKwzGZ##{WfN3SCl`!0{l2=Kt0i@rJ*RKIN1$o9cE(Dw9J;JmD1HLCllvyT7XlikN` zLsork*y4!$BU9g?G~9_kxDG!Q1*?b~KS%xWa|>I^o}WuberXZLvgpM%16zRWbiI&o=q4 zl*!HfFZn>5MEA%;70nR|kK$fSWK|(7}ZC?we8s zgv~tq#}QI_2Nd6Pi#LB^1xI_msp=z+0ff~}K0yl_m8iq2&?#-k-jM^NQqNq><6H^D z@k}U3WJEciVYW7rmMyJ>nI8fc@du6bT$OgR^8v?})eN7drJ3*y$aqJJQI_{K(g4*| zF9$D?l0N@A1}P14s=|Ve7HLJb%K1Xn2MCw~aHo&1)tMTAO1}>PUI#KbdcZJ112d2NqK!dC()xzjHuvYkuP! zwS7k3EYpa1$Qa|~%=Y$pPU|>83TEZmqhDfr9E0%qH7P#XKiB)6Q0x#D9>AH)+t!Pn z1QnoM(D=;BKrv&%9M>Y7s|Yr6RrMpmGc`a&OgC8MSjm8X4LQSInAQqjz%9ol@<~BC zRSfFP+O&27-iA5Mw?T-jG?rE@hc#Xee~X%5mkg}x02QI{C#@c6I3#tPH)7-KX3n-SL2&)rulfAbkX z;vqe3g@pZPaILYHt`eedW;|}t>^?u2RDOlufFmzC9*a41e@Ed=KMV%b1Kco^Pzl*m5_&AnlL?br@qwC-;-#Q$n3Yto+!|s zV4mGxVhT(|Q4I#6`S_L5S6&7-;5MZ)Xh2U7v3dfNb^lc$SM%{jcBG%uw1>dW4@SUP z$xPq+3`_7lP~@~@$$^<^CADdpX(gU3ybbusn5C03j*X36z|Z!iCET=pU++-@;UjpD z>~7+OSgniFkM#e?MdTwuVCYsfP@*yry<^~?KrfI;;3u0%hXNqQ^xKvwsG0;8G$70W z2ti`H6`o|FqA$b<^oQSOC_pAX#&f7IJ8f9PgZcVf3*fnJhp`Y46XYcoj7m%qsg;k| zVMIb*qQ^uCVo!J`j6`%n*;o@$^PglO-eVe|OY6Ne+K6l{vDd8nKN7-HV#iY`w^6le zhbZyvRluj8vv*V%fkEW~T~d?q7mMRMl~Lj;W_t&?H1(8x8xj_X&0fhNTB%nQ*mVF> zQ^~)1&L#odUuyRTP_Tacm&Y-_>a`b%TFKMf;Y2(j%KaFijk~($pm9Y*S^(M8D^pymIE7EK=^^1=kc}C#)yDGlpTOD>%fl44mv`fX$qsGt&t`0kV_9`O2-UAxuAxpt+CgEdc*XjHBGcluPu2^wwWX$U* zUrv+6>@|kMNpxZv7O)};DnlxE*!I3sVvU3Vs6FH^kiIPB-zK?Qo&+VGbco&y@f!0U zv*&)FtiL?_J^qed!nZBpbZa*ofMD4QuGZtZdF;k00DM80h*gx;Zp@b0~ z2JNG(4UJr}e89!ak_zq^VW%UAVTn8Kn?UChD3{?YOXW`Z-5xSaM4N zSPh@7OS{*lgRgBCXdQS{K};$vl;)rOQO(WG&)wm~5^(>+l`gg<-q8D30|}J6tcQ^} z#03Cvu(Q5-%U4qAy9$b?5L$hf^7+>#dal#Zh8HNl5@= z_=HD@b?>Qy|6fP=M0_kg=+t%;BU! zyb*M`ZBppD@ddss!2OKFrQKt@l|G7DhPk?jlj}ZadVibAkOzGB3kZ$Ck=5J!^9sSTr1e#5Nr zy-YizdJDh;V#zpjMs{%FeH}x37H|#-ftAC>y2|P2ed}LICwRy#|L+R_e_Bm@c7ht{ zc68k8tJ9|i0O4b4(H2VT_j4Rr;*on^rMT}U36^l2|Lko8GR*Qf5P2Ek5#&>Icy)8w zqYaoTY{sw4i1zBv)K)K?nl}Kg_GJJ`JS%0crt6FFypZrfgceI$GXM%$bzG-RWzR<7 z_G9AB6M$C1JNP!Lze>bu60EVuteGc4R6UYE>79tzS}l#(Nf9F$oF2?R{X89pU#35z zNfAXrSkDCYTIld$f26Mf{mR#`G*}x-k|>Py(NavC0mux}>1MZO_}5;0m=+MNZr+_0!|2MZG?7=gEI-^R%8C-yUAC3RoMKQh7P_sL5^C#3eRB zuM@(LRC8rLhEU?jIO71Owc@VQ$UloXL!wsq>nS}89DV69j+!ePk$7Y4$V&tl(K}n} z$W_VhJY?2*f5i{N@xR9s)`d`N9lwD(RD0Z{i+HZHsK#RC54sDafm5e)=#7t2*x>ve zO%4kLdD3$1FPhLR2XaZb^fIVTC;;bzn4qQ+7TLLal2V3>j>&Qc@Uy5L1%Mw{d-Udo zW(7Vw2zydy8#7+-+tRLNlQSwOQ678WQ_w%*Y7!PL8Qa%SnxOt5u&|3wxmj0-mo3m3 zfRrTw+jyBXqWak1)Gmw(mLg-SnkUg7w>h<`h*t;%^eT#Ew2P{Jzfg^r3fX}UJz6{v za)(IqvmBVHMw!h67cFVRra<*;f4_Wt7+T5s$svN>^PLY_o)&Cyyf%o9Qq&Q0lNMECJo2t7E2-u$!)5PhKM|Es)WrX>0 z6t+>DD$fU;zn|F((}tTIXLy``W4{*-T4D8`$)FxTQD<&CoKk+SZ*gYj{@juwl~p$( z$e?u^>#Olev&)|={y9pK5>=I(g86F=VZ!8kTf&?Xc3}5qG3{vT_~h|R&Nh`N2-%ZT za~v?9dk%OW5#^1DsQOPqml}UNUe=h1E-OdYgG#o)sT8OtL_KT?ok57~60#GaBAC`n ziJyylbG4gfxa`%n-@5u;_7+|hFY>&X@TLvi)##oHoPPmXZb78m%>cB3$UF8hv+vkE~ z;v3C89}@ZU0boRp)u05bk&f*EPAv$~4zI(}u`1N~Y0VTWqun~!Ca7@y5nP;{AjXJ& zMBy&CquSIrmJEyy;1FJ5UTFes?f+C#pBY$|uq2&*v{Ai)UqvE~bSY~TJc(3|V! zRBIZ_9mGHx5`mG7@mL?_y7Aq=#rWI^GxFaOx0Y;@=@YAqg8~Z6n;|vUv_ThoJDtxj zC<4+B?F<;s_iD4YPSyEM3__CNAkad;y}5g>QSz3X?$@vWz3_XQ7aCRr$+d^OD*#l% zsPP^Gl8s+N z*n&ugv|to2@nq!5d(FiuupS_lLG|NmrahxqZ3+xJ6~E9Z2i7`lSympH_d_kwtbO?5 zU^`}nzd7O~n?#e*CzuvPz&#j4aF`xV>VYtEGEQ{9+EQ@g6$-rc`Jo^KT?9 zRqkG-o|)O}-${ttd!wiF(I)cW%XsB7W{AZ4@*&@P9*iMsSt`M~pfx5{v0n@I85F$h zZgq3=Muj5Qis+w0?(kPu?q9kswRz$nuQSPi@;3)0XF2OUdX7bKJJl2V?DvTNbA>p8 z!NK^>dM{hetE(y;VNv*EHzRXwbHh&XDnLfgc03!>q_`>xLdH|K%bBWJ0M@-vn(@|c zNiIppN4x74jzG2H^91iR8ZjbgyJW@UZwmcYA`no(!#$^B5=Rt}5|OW%*z141j=DAB ziahLgPRtREi8OL|fOwtn%9?cT#;d~#{(l+Mdv9(2QU#ppD0;mMLg_XGb<#Q`qP3>XFaV4R@grTYR83Eh{tryv2nw(Rn_JUOngb>i7%mZs1gdow~Hk&oeB=q*q}q+6CpK z=vZ6&HghH8(v}*1u}f>QI3S{bXMq=k@#N144EC5h8F!J`NVTkXqu?m%kZYP|wv5+) z*4#Fu?=_H;!S}cc@9MD)YaU`gi8fkz2-A^_?Dh0}%_=_EYK2ptpLYjrqZVmo)AaZ` zCW4~wE}t#7S@#5n+_iKKXEPOU{v52FKlZ-4&*E($=POY!KFF=NVDfz~^14Uya&T8& zoY!#fQ~z^|OEM zECxK}fz9rilU3Q@1#2@+wd?hWXe0u0x4HgVj;)qykQq#qReG5x*o0>4E;3`Kdys!1HsBOA=G)VoRdZYIkXhM1a9q-ZFmB z#h6wWIg1wE6I_AM75ZHy40;vciT|C>H?}oONO)QP`8LsOR#>?=DIMAuj_$2pyMh5^ zH&8pzKa)vk(Vp(S#2GvSf+Fp|>6|yzQX#LB$KNS2m`iaBxOeX~%9akE?#>e11~^2W z14K3vqv8^dH%Rd}rXNFUti|tVlhJRXB@?F6nYmc`rl;4ix7W@Ic|zvBK9-YSV5gzE?)lXTiF~=8A3niBmL62&8=N1r%W>T<~jP8tDbk76MwZr zANWrFjvUvEhwblA&KH_aQS$Ou%dx+n-UNz#^33ykUVlc(`$TolrMLWVJn6B(;hA_E zvqo&D^sFA_chFf=NAh{s!x8Emd+xyo%6|RDm%emR$J#j-eF5oD73sa}vq1JxEBC~q zaS3dM(OqGw&4=7`V?dGoaA@avZ!)|Dihh{qf3n}+AklQ9`)(yJ>wspJV(SbC3HAM( z6W#9p(&FSd0of(#Ir%w-B;VJxCq05mf(KQ(;-wZVp9~I^!M6paOvis_uuR(ORG(@^ z;Vx@+UDKO%G?Bj(N|c!?In6*SZZ3BR%js1u5CbN*B?SgdW~xMcPa45)11<$I&L1jk z(yl;TJq(=!sIxwS`ao|4-bejP+X}ZdZ1t&=O(3)keON|SO0F6B9R617onDg|4E~h* zx(CYPJa_hGcQzPJ{UeXPwTK%)-e5U!UBUd7A;uF8yQ9Hhn=Elj;iR^^Ee25SA}8Hf zm#(xNdFzLP0q56G(>6H@O{5C1eY7AtA|GDNO5e1L)^I@>v}EzUSffi>7<^H|F1pY8hK zv+8c?`S6OYcK9G>$&{lZ-`Y=Ui!{xROiLGC2IFWc__zMpOYSd=^M5PhjAd50ds%aL zIw?cy0OamG5o|&2B%uWboc(46*|A0)ql@=Z9X|) zEDL=j0s}8E-dAyuW-`8*WYGM9sggZ|Hmp|^-GH*I$C`*+j9cjS#|oClf|~T9-GUVP z>3p$vNp=3dGx7UBcI)#h?J|>+EGKsF>6|j1mNqX(g>#mVOSUfZ>`es%Xb_}8nK7z- z;MFK?Qymvvr}4{0s|l6JmgeSqd@NIghb1+QSd&P~v$dGhSfar}5YD7{Q7UXI3--Cg z0f|p-fT4Gi;8~>h2RRtOm~S;mOZK=2WBzP0rDFggsfAhXCR`|30IoQv)lcnvl_*JG zo<1q^Y(Id4mbU%j19ZrGFzx_IO`{7<*Mod-Z+yt4{CgQ0i1Pcmk})>G3#i;(kBetD z`#+s?`;mC}kf(JiAS&Pjzl`@4YV$xo(~ zN3&{VC74rX%wMAa8wPTmIm1G@{q5NdoziLWRRx?}+D^m!$v0E^hcHs}>8h$JJ8f9z zBmbO~!5(C})JDD=ksYNBC4OP>rAYaZP_!ZRmdSxg6@t-J%|HYvRZD#?aaDmU##`C@ z<%KW3DwF_}e}4Lfj%n?07nP{DfdS~|-(9?H#7VyGXiq9w!S@|3GO|AC5}}|1FBu3! z&5OfUR=MB++)(JegbyH-l~2L(S&q1c!SUA=KUyPp_gCb<=u24rOCTCHsbUUsUMB1h zY|)?JQH;y1_&8V%RfRx6?ZKC*S?AwB$v!>ji1~RQRfuFc7kv@w)Mm#e?3qHl0C*S;ww0`JYrefnncxH9J5Ms2$e_+g0_S#ep ziO+vny*x^ZRiuD_BisXm{3MakkRW<@AU7c6Fk2APCv!EC`)0awUYj)5YK}NKE&-`m z{gc3Z>k*vEmRyuBZZYjtXY&!UP=gdXGpYDjX2I469H*;($UzgSOxs5&*65^eTX2sS zt&ms$p7(u}{ioeflx!P}+sGp3yA-XKtzv}Kx^g21;n2C&T9K}NuL@dx4%o|+HxhQ|;49Tk#Zy4>Jfhp5WCV;sGJ{;Qn008i~FcV*Y->x zqo0;;+~2WN2-kos4E`poWCTVT6&ryW;Nbi6PZ3x*thRI}?Ln8|q2$`4bq0X{}8r0+WBN}V*M1}5;<23Z;mb>;|d~YAPQo1NxJS= z1^XRJL;r4>>IHJ*&3MNk+zYKRgb$bGtL<_*Ygo((D5P;zz+W^zDAjyB_k1-fr+|G9 z_xrM1Df|+}1zt;4^6W4lZMG*lFWjvER@e1U+(^nC`in_3+ze<7cW%Wx4F|$rpWR%} zSXuK!m&}H5aQ&-gA=Q@&v-tbF9|Yt-q)EYizB*zH5D!BlwQ4fIa@wNFLnjtFG^?!K~*0S1SIgYXGVHvRGk@Jd$)z^_+s7 zX(;}!0CepRYlj%fm%cRS&o|w;P7(K;C~tnQ{KgL3$D%s*;qT(xxUlZ)UFvv(?>XCG zujI#Y$2->^5C#<*Bw=T|fWcGlp@_WNqj!6DuT>A1qdIl1;hmg(>T$xm)#H5!bbn@wpnX>#_FmUfSgh7M?~gG`}PRdHy|aZt?TVi*1Je3HtE<#d>mS zTjN=-;j?OW*g(DqbxZvk45}g2bm;N*YxG0E;e=7^p-E%V-wUbhZwJp)Fu@5j03ffj znQ)FRPi^(YYbcNhVl^pWzAv19VA^N|K9IbJAIgJ?WR(a#FwoW~yf8+5o#bHy8lQ8j z;0#1>o@T`(*#Y(kl@y?0*8Z?`q{RN0(pe(}rSi|Y(vnxw0_+Mdv#A@r(e5dm;l--+ zxPt<0z=3hy>_j9IYI2w0<2rH#8Neg=t?*W+(T;@Dg!4^(ltt$-@1_A@V;!Xns%mT` zg)4MPl{O|VmOZb2;*Zzu6_wB2SHQOgQvFk97W)>x#c+@d#LEw}%dPI_j|qw0-QB}L z&^(k(cbFAj?E*BZ^6|G&C;gfh$a9c?PLxf;A^HX%z&Jdco$Wt2D(v$)J(!oL#7a&- zRRiDl07*;v+J%a3euuOG4-xg4Kgf#~ISm**hUi|`C=V)R+X&?zs{I5IEFJGmhsuGu zF2trmmN-|d0Di~=PS*3TF`oKb01z%~9ufN=JDq=7w5GEdk&uR*0m^Fz{5 z;$3pAj{y8?^NlN10=|8`#Omh?SXDvyN#w81mdm%hh7EK8X~Hst1^Ecn*{Q+)f= z=OmX|Dp0-zF|(RXtJ^Zrr!wt+OYlel_*uktWAtwcqL|cJ=MVKY;~aU64_C*bJKr5k zh1o7+4$6gO9Pfz%yY_!;T@!CNUQv9mLS{=&FO z3U{^FDg$>d01RFgTV(S!&6h|74B@lfvP#IUCrthzrBtm_ytcf6_k-^ylvVRX588$u zM_8HTw(yfQdfY;4n{Znsug%Z!eYCfFt${Ar^wbDfV#*R~#v37()(iIgr zD-&b>ZdU%=0M3;AZ-J$@04$%%jKL{dS0W}A8`YN)U&aUioEmCXS#X^>t>Why^OrlD zadsA1m4ik6&qyXrPx>1nIO zl^z~v1LCtk-XK;T8$4gGNGQ0w`<@}(bHj{2@N8lChvx)bj|;H0g5)?EUI;XSc(3$CvSRC)FFLW%DZ(nlg zLN-%d!EQ?(@ok<~h4FsYXIJOjgvYgu71Z~gK8EC=N7rE@cd=qg9Ux}(U2BY{(f8(_ z_JyHtrwTYK0v@J#e$T6a6iDJy{Xa{FH8h{6@>dH?+PTV%y<<~i58N}}>9Ihp^1`KF zUDbipfOJrcg*wX)Tv{`ba%N-IwU;^HxH;|rJv^-aXx0@HVIw;F(XnfnVzxE{oZ9zK zqCVta#3y(&`gz$(5u+Q;JyuLouJ(geoi7>g?}-vv@#=87!)zUyS$Ci-DRTd%q^_}K zjOKfV6)$NvG)mz*{*|7Gut;Oo0^Q0FQ=RhOB-L|zv!O1duVuVi+^13Q#G3UWeO_*t zd;>|O*HpBU%8(tD!&PZ4etRJ(fJ&}yG&1WI)BR*^tTmIA?esn7oFt&#kBP*&1W1X%6B3-p^uDX` z++WKB>?s@sbkYh1RmD7(TI5Y`CSSa&U)>4qu0o!r!7f{**;S*Wc%vk2sab3_@aT0@ zsYcMsbc+Sp(%BM5isKoS3ou4(Z4#MI=G>(L6e!O5VOeqaHlsdpjzy14SFJgt-9cTC z^`%LBQ$Zk!78grPJ}F$A3N;N%^}Q;LLGsp?pn4$!N-Om#`U&1EkJ~FJ681SXpWWO1 zbx1zz9grwep9!F$Y^pYkEyp8#yb0o}nzkf!7GHgW38#W4Aq+&pLriV(1Usb3#SOuq zp6ci)Z!mwwIN72jt4wE16n_pLc7@0`m1%QA_{!cTHxRx~!_K%qf9J>Jd`wlf+(3Qv zAeny<;BQxX9i#<1K9C|=yu7C#&OQIL#c-aW2wu!os~>nN0Q$37|76{cBS}KEyMDk) z0649nRymvs`Bw6WU}verGAp7|7`gN*0K}*iQVZMoLRU(!n)%IggiuHA_fX=-?vHd< zZ}{%j_J>sfUggH8@IZZZ*jn6T;9%e!KvL~50Jq>>O2J@HAtMG7+412`4*8u^zv}<@ z5Gl>^Fn@!Mw*J)+whfm7aZj^btfk~)g)@RtK~;Zh-JpO81i1g*Hz*;(ZutS|4^Q6W zm)LWd$hY^7kZ?!tGj-`Lg=cGVAe1EoPsZ#(l+&HL4Y9yfzE*gH_0q$(L53=sq)e}) zYz78c7_6NYNlrc+7J&Y`2hL5H8wnl&ZrUW<&rUz)X#94!a{Kw3@+|RICVvgx2Alii z;*Wq2!nUw{$;?2sku2HR2y7~m0BuLjC0=Q{xMEZvB0lu&>S?>TO|)NYz6y|7Q6mc= zPYWH}gmdH6@ne5u9XV;LfiqDxEa@=-JtA)a~}Jm~+Sp)7Q27{=-34i+ZS* zfxc1k3itBy>ffM+_E&JDR(MTJlLmBj0Jo;VZTT4hSEC7~VoNHVZZ)G-6I4S~GjYb> zaYx1|9T0Akst)YtBPOZ;%7PoLB(K^@@<{iL8*F;Nmp=sk`75Z}zcGQ!f``Kx*yI3v ze-vsg{b{0^*sylB?~VOrh9JnmS9j{3H_!9*Leh3~AeL5gYIB?0jEy`~DbA+jb07VE zwfJSKl)4Hef$jv?&6EmH3t8AI8E~=BMN##z9v{iZuBuA+tlS((UQTX{pDh(ewoyoQ z_5zf*ay%t%v$yfWM5f5T@PGm>?in z{RU7wvG?G>w?LSF3iaJz$Vc1p%7a0Pguk2ufy0A{F&Q;3GRt}$GabnC=d~uA`x<_tLKw%B%pfVCPv>6@9SxKZ%vLJMXi^klp#%= z=uK|o;Dz6@hH508mkU(vrI<&U^AboTJH#r@Yn zwt%UHk6Lko1WknZV?N5Oe_kGRRla|Jik4_o!&3t+(2cw*4}g4zooD46Y$Th%M5^Yi zj3a;(DdIJ<)bOp z-Nbt&S8iy3*A0QoYfj~LD214dh(BgLi8sTV4#bLUhmor~HC<^Sh*2<-9F=iAqDUEJ z{dZq`_yc>T`tq@4AXNrc%a`S#OV>aRH(x0kk!r(vfuU%gJX z+O7v&XH9$M32P?aT`>Rw96{bE1T(EnE|eTJjRPxZHUY*Ti6>+&VFTH;#D^~F;xdk- z*F%@wp8-1JKbBY|p@v`hM?v_T1YnZy5Do3HFbQVKhZBQP&OgIVByCC9skFe^hgxVNGu78di$*5{iIG3!xXOh9W8uBory3 zcLiw*qEwMCy=g+<_kJGT2)d|kv7g0hKOtL3LNPFXBD?H*V|D;sxD*pA$%FC!sJWZx42B*8wBY~B zJAxtUjJ;MgA7}xRaInK7*$~W#`x;uGPLwD{iU!sVH&=F8562@*zBf?pykR4|*{qK2 zz1GTO+I+vt{|-8~gDH_Itj~n~oRUr1Q**m5VXa#xe2f0^A7*`oVT+rR?F}bhvKn2c zGPd1~HOM!9H}Fu^D);i#b^}9X{l1RhoIJMxjaTO!@a^{%}(O-0_#2oB@;clhXvR^eA?pz{E$dpgo}Yo8py! zI~z6xE;U;TM+L-6(cI~7{B0DCE^(RZJVtN>P3}5^HRNZ1Au;TL!6(VU#pKUoBkrnr z%MjQu)p6~#AKEPUfp3PCNACX~zm)IgM0Dm1BNILs;I|_O!-yS+@*J?Ro#nM;)X#5T6;2t_R(6%F7`sXLM?D-BpxQIWaq$UAvAGX_1Dt} z43^D(u&Aw>Z(eG|tOTJW)(YYW*#6Fbf>$o;&uG(u_j5rG(gH-Qt<&j^t)ZLn$k~?H zO3=-#glW?ORfx3cfDlu7+;)VH>hc09*DbJglaL`{qX|HrNpbyv3%wk-EhZk5&oujU z=6^2U-=SGC@CvoyCST;w(R~K5MMkE$&)~Nd`E!j3XK*Df!rWSY@*P=nHKKH*<&P%> znEDa>=pXopze@A0>Yfz1)@4+=NID>a*{yO8zz1LDW{C3r7icShb7gE6G}Z2~%h3Bd znt{1+1GMc=XOu1bDrvsHtt2=!er{xhH?zHPnm}Yfp?&rxXFPdE4QSi{(*F647Y17` z=v5kN{i{A7H>k_SB2YF1aP#)NUWkm_e)Gc+4~W_e-*~bOd3Pm%&r;5F`(Q~aB8}as z!xu(eCC{4G#t`{v)53$_CCpMiMIbr<0H5gXzwK4py84Kr&7CzY-hR-`BMejHw;*3u zAnF1(7<%#8wmlR z2Bm*ON~8*1cY)K8UH81fiHhPHeh@qh9&wrDA|B4j7qsh9jPMwQ%25!nkeYmP^uVlO&G#>zR9a%xcI$9$-0{W z-P-)AFdeUE-jfa>U3A6qq(AubK|O}~A>0_tB^*M!f}I!w9Srr^$4fopUD3$^k?;#0 zE)O-RFewL%!!{R~AkYzh->Aww?;)1~pKy5ijXREafHpsC9Ni0O%mkh|VH3NbL$OG$ z3IfX3d9A);OGz`+l4iE)80xX^E8}rjVgJi_`p-jK*Vo^9V}y*TK%HYg+Xmd1pf7V_ z1aPEfX0Nk!o`-#?bxvzc5;60B=}^Tymj7O5uGumRdv~d4p~LcRd_hvN{inVR8GtIx zwFN}GvCLIFG+F53%fPy{E;YQtdl0vCo%lF8;vOz0!ruIya{LE^0* z%ibi}bOPHW93wN_22yT*O5^Qj*YWZGRsIBcc%xyBF3Gzx!*joSv30Galc42nU2$`H z(&`L@CFL$NRaOdZ{?nGr{c$6%8;kF;hYfxK{mhdTEMxhogF)j;x+dz29acHV)_eKs zDN^^yE_fUCtU6MB-QSSMO_j2PHg}*ucfmr>fPA4@nQ+*?Lo`5#&899~xzDSW+4jVm z*zLK|vEA4HR5gp8yOWHJ8jKwsIRy_k<2Y)CGZ-A&JI5>^NcI3-&+^gnK2Nd!8q-Q{ zbr=HYvB0WdJ~Lf>WS)co6B%5jhh3a$C}Wmh=UV-Y9pP?qbskah_|$jSY5Fp|-*JZ0 z_Ogk%kEi69NlE1(!>sFm4E)1qN(}cA+Vso_J-zZ$dmZQmY0L38W{<7 zze>wvdSHHcDz%V5103fnTXTHv6=7HXUKD!vC7n=lTx)&3GLVD5l*yC|x7wY|+L%*d zb6b&8?N52Ao2PD-rqIO5r&X#Fd@f$6`B8}&i7XTjTuwv^6W-&7bic@Xv6yW!#2-)j68D5EycKsFxhsX0Ib-2>p;OX~7gysTec5R~oWduWTloS_*IWIILm6#| zSaKd+F>O!Ei%X|kSN|Q&XZDn$@!!;Z1d;}r%ctgE9CNDs)Z8e_{=Q(4M|r+tE~Ko< z@1g&YgbIq?TWGPTtSN$(?{ecK_>E^)0n}0-YipTCoxs`Am7dqxl;4dwRMFO094nxy ze{egwxIroOexaowt*FHm9u&%Q9QzK4;(XNH#xx(IJ4!*f+}xf5v_gF@yoo;+`kp0P z5-5&AmwP`pRIadOVGK&(A2EIJwpV=V9F1s}Z%pa0FjP*@Eudf;SezbjQOi7b=Q&5+ z%m9sa-)tsX8)Gt@INl!seYsZUlOuYM>z9@VfdEHd;V4*_hyd6?N$X6qCTso?vLst` zc07tdO5ZtZt92l_TQ98eUWH|w;)^uf;g^;kG3yhG803O)hVixed5TKcPHKIZQ3#y+ zG+6odU||4b4cfRiIbjPy3)~#Nl zW%MoJas4|n00(Emoi`G^Ax`m_(m<&E2izsz;L2P+) zX`QP=;Pm=8G8Rirpo%uov#Mc9y_L6BuJa5rtM(;i7&q6m2^xL@tSOMTvz({*K*|RA z;dX^5<=J{M$X z^|qeIU5Y;mReNSl`3*5Iqvw52o;c{{m?H1!z&UKWh&vbPX6^^mg^NiG1$>OeQIY z7;d%Pn`0cq4IZ63YF(-OAqb@a1xnzn5FAXKjOhrjfSSHE77QKu>z@AV;Xn5DxgdHa z`UmuL;Gyp9i&*Ci#O#Z#+uWI_CNFIXe_HaWYnz1|-C%qZH{QqnxdtZ+Sdva^JidL<$HE^suV+!9u|5)Se>t8s zQSMWrPBH2Eo9s?34|pkZzafLv^PqgXnEikDL?b|>Yu@K@q z!{-gp`hyx!8}e(z>smDF@nog5OQ~@in+*vrY(`e1vuRo<4|n1_krm{n?KJB~id~6S zS=lWTw>u)(WtM=nV(qvy?G5vq!SB4L1CF8(DG zeY3`FiQK*RH`U2XJeUoQf?^pGidmEQeaSk8qht1$hU+b?gstiZM$g+w6E+?3y&X<} zU%N)rS4>_G%t~3CrRXUN$0MX>m!detY;NAHZm@7e$GZCnrO=}i2{={*@vx8NOsoW% zw32qsL!#lHu~_BJ8QE|=j;V5;>%B|#m#3{05G$6aoAEF06@+`5yUFP)+wPIF-Ce#%IzM&c_ub^PnEjb-mI{qMOoi@?YDQWMe+xLq!Bh$>ZKQ_WHY+2Z|_)T%a6ZnH|O#^cW(gDc7McO9^wl&~$_?jh)i zofWGPGtVxf$VxOSXcmIrL42WpSV`6E4gFCG96t6x)<%o*t;W<=Iv{C%Q|1S;MKo@p zneNY=tD-<#d9ZT#aWB8e2d1Ep$Pf|G*4^*47&N8{Lm*ftU0zL=te_LZTc+Y4$3_O? z4dl^HNZTqz2%;apoPDJqZnuv%UI|jrNt7$Y+apYKDIaC>(-2Ze(Ieu#KN1b+sZoGW z%$q^^|DrVezgju7kh$8KS2K_HH}36pZU?$SKBl~>m-V8I83x^6$c+v^TOC-Ogl(Vp zbgi>;7$wUL6IuKo4rF}so4kMlf8u?KH!9{Wz!EpYs#`R4o`@mx@bJ(VIL_G5QD1a; zTkTpw4*?!95)h~q1voxgU2?}MQlMEe-)5LGI;R3nzGU?yLEh`WFbG=9Q%`iYlF}UA z0Y;u|(8ZT=T_zpPzj=?YNJY~JZ$7$oC(rU8tqyD(n8dU}ESqA^jo3=-ZgOD0>q)i$ z#LmZA={Ux#Ut!5sZ8xB_F;$b!86@Q>1<>x8%g{}pXQ7A>&Zbb{8&ggewRrb44^7UU z|L|AfKzxA!>0OBHNWAS8LW+Pg0Ar=(>Qs%;=3GnkkCWqQgT?-l@29nne!H8qtiY+$ zjpkAYrqT0+NFFFNG0;(RVnTfSzOjJdE%2YJ0>Vc#(>3?PL3UshpOV&>J)o_MKi+i! z@pLMXW9@4v%LvC@#~dj5RPQhkX&OMhSJ|;%fmS!Da%e?NrEs{NA;J4}LWaTz*I$#h z`0lMIMtR|YNBhyiCL7)*`qE+K6e=D9Ln-&? z3$A82p{8D2vrPpIbHHtN-5PKH1hQ%YD%fqgci}>zOcoQLR@xao54h8ZKoEi@^s3Ob zrWm>cQ;Ui-VIoG#{+bgnCUDjl*d3X7^CXs|4*0Y)vW%;&`OWLaK=U$$ zfS8=qb-8y1aYMD}nm;Zgn1sgq^vB5uz<&arH}p~)4pk<@_gx}S&L4LuSIckEKo9oj zrqomq_Ff1Q=HMl2)moac-0F9nFnYy(l@6Uh4roFh$%(&MP<1BN;#Ow&CLpY}G=MAt7hl#*5sGd>vbK zSb$k~VXEeyx-1_OeFlU>8J(w?xFL1}4XQ?9krgQ2dJAA^h9MF*MNgM0-v@CmU&h)Znn{b z0%Yf*?j#Eu2<8G$0*0fEJdR6kB(Y3buipXA0J;uTB(v8oJV9c~`_t(<7vTOZ921Apo#R%~Ae&pE~S%uUf&bi^AHoh~MD;XBka^kCqhN*aM2Fy3bq zMxa#c@gX{J_w6jsTa@_G#i=(1L(vgUPn&nAZSj}=<++rtD$r|XouDr{zg{Ccq|<;9 erA4-%o)zL@{n(g@wE$7wXVg@*5amj@p8O5r8(NY8 literal 0 HcmV?d00001 diff --git a/_static/diagrams/kafka_producer.png b/_static/diagrams/kafka_producer.png new file mode 100644 index 0000000000000000000000000000000000000000..53a90d9d95a203732b2380077dc2e9646a1f5db8 GIT binary patch literal 16532 zcmeIaXE>Zu7cQ(b(K8XfGlU36L@#0V2_gs)ogkt{@4ZFuqt}RD6TJ%t(R=SLMDN0R zBzezyzw0_b&h`B`zs?WL#k2Rb_u6Z(a<6*{R#ue3zejNo1qB6PP8Ozuf`SGHK9AsF z0pEp2qiRu5=uqTf&sCjJcilk^ier~zNrNXJdFc-7t1tc85k0xq_|@I9TKv>hl7SsI zcr35hap(m<bCZ+T!NR`dY7Ccs3P|Tc%G4HSc+xSvUPW5-@4r zn>QEvskvaXd*ZghyAH-;5XT5YA*MrvE#Ainrxt?jHQzQB=`_AsA4unnfxL)r^~F{= z`!$#QBKg^HjvP4uRbIGi@f)?CICd7}p4h16@1GQgvZQjAGbL=llf0JoM#E(Cyt$6% z)D^Y=e#TzfpmLA&NzpR>jqc4M=_B2yhFO~~YL#kBZL{$rM3wo3qRa6neR}|Y3^InL zx6L2d_(u|Nh3lE6fX#9TbKSH%WBS}ZF3(9xSDlnArCfl{1;WB+mvxTNcBO{~k&7o}L&QS6S(;)`u-zO8sN9#W-%qN~)ti~v< zc1JPx45f>@zv)jAVB8o;PrxO8vdTu$v~n{bcKdk2^S03q7;^ZXRJZ%)_m%NRe`oR|Z4U$?+(DjHa)~fC)(ySaUb?4V3@;CS%A{R!%%f!qqB^^qZ znZliN0SJF>w)P`vjC;6G`Lkpo0Wtue(&*Q0Z3tc_6|ebtta(YTbV>7#i&W_F@UYQ( zAL8(I#){nsY$m$Y$%4QkebmW_2J^xpLVZn#!tzP?)H=s;-Z_uL;EQ^3QqJekJ+Y5o z8O_z%f4g>3VshF{)oAu;gr^Fs)!A)j1t@dP`eZ)98+oizCLZaG68{_PmKU5;r-5~^;V3-GH!3!k ziEq~0H-N-#4%Cb_U9OayykEoYuBk-@cx*`splXTzJ0Chu4X}av*&rMCB=lm2`5dz|L6VUK1Am` zl>?*BB$KKktrs{A*N45^!qIz8SBkQb6f4g6vUjT44aUjI%PaJ)I)v$qsK`=D2ec2! zLWB*JANt;%`=SGee8LlVWQS;V0`lkOimKX9mK=1+UZK+Mk3Fb!k+>+^#yT|^@FOikLjMdD_5lW-A*=(r%L!$d+Wg}h zWg)ZrJn!ZH?WE-qy)`!6B$-ku<{`T}d_^kBAGS zwfen&xVO6<9b!;+U;ghc{l=&V0ly(nqbP_f+Y3Q&vVPC5i0?1rhK}^(WVlxR_YnPJ z1l-j4-9Q?LT7ha5aOr#d5Ik$Z*Clc3Lpl^UZ=QXuUoB$FbO;V-y)<64D=^T|Ia`ooIv1piYff` znwpx!MVdVJF2*aJVaA86$it;T+HKZ`0B@9iG|LuFzzpA0TD<4hj?V;MV)*X#PiF2qQY! zRN0W?pO#{HnJ{K09=(56w9*xE1vwgZ zj3rE#&un1j>mhXW#uSdOJmdbd5bO)<~!7>Ms5ugZ9rtFMU-rgoA(C z(<5+H+nv(?F7AG~coq`&1&v0?0Y2|}>#o`8^0hBrOc(MZDTjdJ=X_&5;B=&uo|-Y( zZ;wV5s1+8}VgnL>8BVjI_JB=QR^S>9^WK->Fjh(k|FTdJN*W_g5bCi0FSJ#0npFwW z!`A0-x=Al22{+LjQyu_U-UxqN;?G4{!Ql^scZ^Vxa_WTU@yj3?5Z18*U-0e@h0cm` z(HOd9+#3ydnyPzDdH1^(W1L8MO`l$Kp#pSCvHqp`oicc_5Yr*7^EBlkvu1qnU);^R z&xFPV{`Hg{=_j-+UHsPyz`TswQr|HHPtJYe{WDq2-DD$0z>`&!U;h|zr~9bUAjhOQ z;7Nz<@jptd#IUFi_15MnS38-iG~uZ3^}M~(jUz2l1TldX%P~&=s1FgUJ&{_2ehWd2 zwZo(clm=Cis$%~P@Dc1$?CM3z&K=2k`h^y&l^(xcBu|>$uL>I8eEVQFTX_Xs=edV^ zH~+2&9g&p@UTe?LS}zN5JD(l~ueF~ocv^K|pRYv3u@-iB0FqbLp@RvULJwNd2{*OA z>B>Pq@S&3YTSS!RvsM;I70bq%emF{WUKi1V+F_*fsdg&7;`+{+4WtaEB<^X!~W z=UJKHl!Fl^F%G~-sF~U9KMX(XTzaGHagm!LBQ7xDc9CPV(uo$>Y%%l9Z1hW1mFbWK z^7$TS+7e;oL)lk#c4oOVz&$lw1@!2VJp-$q)E@e>lHK)4xDv1DDQ>-k&lyYtmK2QqXIq29H4)>+d-S30~1;36MVnrx5e7l;E+`B_?W zs(>ghzqNQ28V4nY-d%*lwdqQ9cru|&2|ac{BFVu~o6?QpFZU*Hnao}{mgcP&$mtF`567LXPWz%GcX6P^(oVu1>B2D@wQ1;xbmevw&DK`h5E?B5XTZ~BXu#-En>~Sg(Poo9k@fCJ(zff&Hw#P=Y#>G7!!gOVtXL@FvOs#Lp+zwtkwM+fV-2asP%5~#<8QtL zuq>RH1kxA0F14JMblXjd^SyTO)@$D1Q`3x912R}35J2>IvkM6cks<~^vOTk$HSHKGRI$61ExlJL3+5ID z71|bGT9=XV(BM`m6fe4-42<>9C%((ZVByBV(>|SZOI11Qz zU!n3Mn^BHVmX4tW{R`h0u`e=s&R}niZa)O8DRx>+j3GZfGMI0{ZRGssSN$Gaq}c8C zM`TZriYM8)*Q-w20KUPGUZ77&74xuhuqhucu%uFSa%)`Ix6b}hGws3RAV?_ zM1$~JHy4Hah8kTRSWUsR>3b{~l$vn?9n{TK^dwce9 z(RmzKgKdup~O!QAV=&#*Z7NqriLZRn#DwY)F=T)szE6M2C{ znHx^VwQAL$c|G=eApWEq11+UK%_JlBNdW0!vX>VPNMtr6y&pPx>=u)UWr!qlh?He zRK{L3ICZ2QvplFpcJoy0%3KHOsW^+IOcWlcWKQ*6Ed*CtI^}_F{nbJT&h53|DY#0X z6TZZV@oyw|*qNkv32NngavJB={#`jh%;b|B5q2Sq0f_8bYY6T!9mc&)d(8r@}cL^(3drV7Zf#%$mkiEAuQhsY`cts3AYSAdMS;^9 zFqu2j@8YUP?Y4Zjm9+MA4Fhqj8T|8 z(!-+^B27ZV61YEMcotv6V~4A6Y$g@63D6%q?lXZ;`JD{t_JX>G3fuO06_GWA~7C~NM=(-(;zM5p}ePjOV;qo>lG4% zV7;wX@AhKAbD5xN-mj;@3O37Au0e!-lsrV*%*n3yA*V-|`IZ?*96~(t7&jfef9~^gsP0Mba}Bo@JMwys?}*yp%>h(I_o+FJW#glo$9*R@ zyD_$@&r$w56xuLZgNv8vnH-B9a%Zt`Sx);p{a>bVz8>0>*VbM z<$jx%e5ZvYFEqt&t&StdvT)%vXX1c?8N8X=V)Qb#>1CI}B;?1h6RS)rLq%c0Va9|FU8#6-^* zeNCf<7{cBkQDuVStnty972?#pWUrz@yW;Mp5#hQnAOx4=?_^iv#lDkLhvR#unqPk@ zseOEU?1)FZxfGH1>NWY@n%qsSxQ6E!EMlYh0<^>(#Gk&~tjdht|K) zi2nqq;|MUcd#jWEGkE_yepf>F4Yw01YQu^mu6Dfx@3(%e{6v16EEVD-Dl9^p4=LBq zM?d%!-n>Z?#DOQ!KYAnwBq2siy4~r-Hm$ECam&?eRfa2b24(-|pp3gO%3|7{uKzufRRBpUAmhhv zKdZfIaz1)T(&dK%%Q9PaX+ z;*J(&e@ja14+1_AFn`fc0K_Yhk)Rb0Sm`8oL;8uHfLT12;Y3t%C2PwqPgt;W)4?R! ziv3b3aneG7mJgnxY4ak)Iei5PAY9v|xj($NIxEXd-7ROkIDZoh(2_6wC={3GxLP68 zeF3=?Im51;05e6gs5@>ph(r3E4H-U<YPiCiltad;W_z38 zlmC+j=k0S0aVGJn$Gv$-KW9@kCai-#5y~J!D7OKUhH;l8&K$WKwovFQNZU9KD;0mP zgxq{hP#~AhF)Ur^OcI2fDhF9sps=GpYHV}(E9?_ya1xOofuBGIAF8n_0A1DW>B-3sO~XLM7WceW$SL0O2z z!kOck5!w;!Q~G^U!n5PyL2)e~MuGtINUI1Fb&NjJ_GjG@Mm|Pugw?-djPQdblPvO-m%b?fB0=RAAl0PK6{ElL5hnHNB|(PS_2k7#TVE0G|=o|I~_SW z`L@8iTn09Vr&ZI%=emt5&w^RSS0R`Dl&GpnrrofMZTwN(RiQpq&BPDE^q9XHw%J{9 z2R~*WNeUlTyy|E_RPOFDnTzo{*TB!(c)Lix{8aXr@oFZhr{gQjbsD!1eu-UEjX}j{ z&gU0eVXl~sbWUlX;5h{SapR8z(+wG^%b0RkP%!bqLYOWrU} z($BXGCfn!i%yo+?9t@c`^kp>!^X2eWiXNzw{mm5ml?%YKQX7$aojBHD}}Py zp58lcL;)R;2A&x(;%4qk{x;lyf~NS@N>MRDa zFIOZ4JQ>*oXX4sGJ7OfdJliY937AI(OH$9(Z_G<#`xyW!N5I=WcjYz5Bo$}vbU?n+ z4!>r%G{}_ABzVu=EQ=+7^qvcjP5B+Qc^rHvt*~8_Cn3>Z0RW_XESfF+CjBW<0I1wm z9&?DsMziWYvg^9s0lEONDBHNj$#O#gO@RYK7|gI{uBWX8{(aK+;BvfiX;7D;*{+@0lIn(Gs~o@(8plzfV5PRk(Y%dNbz z(6@Gm2G_XY4_uO@B`r7(caLa^M} z=_jZQ_5Shc*hsjcVKN5?d^7kX%#`Ig@+jC*@32SnMowwgK2QiPo=qJ6^TAAD&p z<>`cG#Ktb1Du`d#e%xRi_Bx)lBpEn?W_Y7xvvoxrC&9f~&zs(w!Y_}vvJczSemRBj z(UH;dowt|LKBjNu>4SFe7>dlC1JFZQMn{6QKU~m!50LZB_?df6Re<1LKLA&gfLiJ= zfNV=!0-_8dLZd$Z6*Bo{6OhQZh_sgPDf)&WooMGSFQVm4hQ_%gu{-aKfADbD&OY0H z&aYIhuFaAOOq@{&Si8{s&1B*@L{AZu)mG`39*ZrgC(FLFn`MSwR$Zo?x=n9+3Aoy3 zteT5y3#VF_qCs;j8Q`DNI2S&48D}tTF2inWQMZ~Vk};A?!9Nm@rmhyGJf`r$p*uf? zXTZJxX4%t`yED~=RdmFgTOC3r0CFQ^-!hLu$6<+Y`L$H*AUt6nz^Y*wrthKpiqMbi z@RJHdesm)=^I&_8^5yCu;m4mLH2~0Rg{`44n`1JN*3+78Gla_0oODwynQo9x=nWZl$q!xSL5vBh~6Nv$fyDd(frcOYQ~~x`R)sMrbU^tunnh^;$yY#9FcUglROxx>>p0dix$+4y0U^8S+)c$mh(uopF{py(d zb;RP+!o2Fwqw9^ydT?r^0>L!@L2-8u^{M(tp)XQ zKGSZOQA%<_y-8kg+H~ZYeX#U{E)yC_4ERb|VNT-}t+wz);zfh_#xbn6i?)mSKD~R9 zFAiC3IN`2DAzDeS%R@7gNPk(%D{h6l&c<5i$#O55&uTnktbph@9)K~|Qy8H&5^8Mc zrW7Rdv*JfWU0!}s_O#aP0MQl+Gy*+ z=@lQs^-fq2o>F1yJZI??;e9l8c0!W#oR%tk4^dh-(e9??DNT4!J<_kRP?2;qMBXsB zGUG#Zl%74x$-pO6NyHr*!_=w^Cb`EOC@)NDi{O z<164=m_9V+^!d?&7SZ$s=i~5ZIVf>vaM{kiqx*-pbO<^`SrQjUjFQR9?s(v-eV+Rt zWLfJg1o#Wi`cAQjw29%*pH|N6Ri$f0TG6OTKjtzQEmkB3(r?U*B$G*Ij1d7%A!3+gMX*qxRG0>CxE{n@AmorbZefWXqwD6TJ!F~tA1#H;E1FCbM|=i#YB)gPv^ ztiHSDx*G-zK15{#C-ZCY{D%whttD*|Uas}-;&5&3xzRy40tl!W5-Y1O$x~kl&o6Hp z0oaYKW{q{`TZbv*_X@Y0IqQm2SL>ba918{zu4xhmgha?VdC zkZP~BA6*=6y!Jc~b#)5h5Bl^}wpULC%@pNV)0JhuMtN4l*}N;ai7fOvRG(KL2a?_o zS%1y{9u&P~wrFl&=it;?Kc8yO%Z&M2c*ksDVRR(|m7McV3V_L-4yCf5D>^)R3Q3 zR-w3Fd4hQME`w_NwBR|}Q=6dUd*qRrh{!PENK(mbA}&6ZpA)68^FqSOc_7<(cgj!% z!E0R|nS%Y^?o1h+jmNk@o~J~c50u9R*Z7rF^v=u{^fvj=G-aXQzIimXgGx`DuWh%E zOkJm{&CL2R7>JgM_51U&SUVxrr7`o1Tk;h>XJB?|^5&H6sgU8s9Q zO{keR$G%=hSqp}ZxyuVZJ(sza_oW%!DG2mR??FnoAXoQ4kCR=yMRMZzQD7#~m7 z#f~;UD0itD#&gn^J~TurYR5m%^r3wWWXbq^!4 zX{M*;UIc@fg50n`aV{uo@Mg$km7Jgqb7+eAfAmO<2ocnQ^nW!#&f#fiYn^_$nX3mY)hSA$%NJN2TXDdx2?zksh&TK$Y^q+pL z4@~*J>XIBY7p;DX3cq~v>T{^xeW$X;fu`2wBLojow-h7*kAju(nfWF^Lna8*&Nmz{ zik`?)^3&Q|jqx#{fZ7Tz75Bc&QQo%^!JEWPz?Rg6s(H?0+&Frgg7JAK#>SX^gX!+* z((CA5bb67&_>|9N5tItZ{0Kh&c(^#r`=8@##<--F0GXo@-?WT4tocqB#C=m*zx&cFhxR@-U-q~HH3!NKee_0vYjUO5 zm+t;sdi8}2J@7WHlN}}VU;;CNTT>dx2CfAtn?~08MyJxJc$Pj~!3t9u!0s-&y@}7a zO6b9ZB!V)Olly)VRNu`D&=g?&2iC_eYhlJ{Z034}n|r25RpM3F$UIeSjY% zkTE>D1WRNI#@|K(Kw1m<&W3e2#<$h3@$1Pfu_W;;Y2T#ZW)BeEpRVBi`XdF(^@ag1 zCAuHp{;>IxZl5AsNWoW}wc^0$oLw1wY!R+|t+xyMw%Db9JsC}_btFS+x?mbr$p;*o z^7CCUf$x|?dWz)aM+Awir5=wC+tk2$)`b++BakR-wkW*;SdCRV?}44`7CW`pUIIW0 z7)cA}}7BI&Z2CzWP+d|jSp)Jr7%73js^U@Mb{jYl2{=I)XtUOO1a6mZ@f*d_$|XV_4{3bRJ@o;l2|5ZrKP( zNh0lSRoI<3y&<;0K3RN=xwna;odK4#!`Z}Y(cK1tA+o{unK8`U?kE$jppGI(PWknK zS0UC2F_!5q7hW;JWb1{|^DarP=(MzwZ{uC_Jn9(J6Zce$6SflIbTb|iC-EVk?Cd`i z`YXbe>8ya+$+BeVh!C68UkgV|w6)3&TF_L;#l;Z#wVCqHpddm|tj!x-i}zeN z_f6Y82aMUufe;e*bT17&d{_R7F90HnM-A~HLU~B!&pWnV1mPwNz=x|ncCPZ>nW-9u zs-RAFqdU_pt^ObqLVE`-2Ws|@0K>kB(QGPNWRx|xs5uM()MM;k^Y{1{g3Xm=tMd}r z+fauO^agBtY#gb$U&}ANk^4Pub=qxxhn{bX;>ZAyno5%ky0g=&TmD#9WfeJ>cF+7v zr4z4FCHVxP9-wA30%>H})D+j*3?^&dR^OM68$iRGT$Nxl?q2xoDqgC0ZA@$_qcZsPhrNv8^aQoT z;TV(&F$fB$5n*c&Ac$Ati;cyy{}pX!h}E5GQQ8TAOov`U2d;?1J~RlTMN5Jk85_&B z`d}K%g*J+mM}zoZcbnd9$~xO!tE|}_IJY%N^rW6a56`4SYlftv?{qz`7t{y_d zSv=f=^nopErefC@r1@&GO{gpkp+_HUe7>A@JjHT$m=R#6#n9XLaa7xD6Pr1GsVEHW zlX#QgE&LAgWkB!7mE`TN2Y~&M22+!WJvt1fQh_Iqe0w?FFK;&%prR3OX3Z{G9CMZtv1OBiCmeF&FFE5T4eAfMJ?v7RI zyw`YU(2o%ZQIRpBSw}&LD|yG?q0F7uzRro+!(vGrw$s)-WFF#zksy9c4j?`EgL&SX z`)?0>Y<@iKyWGo}@iX2QbrBmh^sWga4TWcfZgRIS+{TxF?gkyh>coxE1~MdzuU@GM zADIwQMbg8&VGS>PMb)9{9xIc~#;qT3Fgv~O!r#duG*exfWR?uuGOZ4yw#OEG^Nmoe zdEu=q4O+ALs&dr=r{o9CH-fd>1?-qzek+9OHiQF2*fvpEX5>XObU<;tCxMgmj?wrQ zDw!KRIt3Jk0UsSHJ$6aRig*V_UCv4<*&>W~oLA1c+im`Ff0$|5yGr!*F1c;=~ zxu_@E(G(2Ri%_}n1BALn^caaKnnuDVqvf=3VgO)QGhX5pLfF#jJ9iXKdeUPy2mkm9;NEVdSso|kL&On1V6!B zS_#OZu>Mq`Je|#Sk4w4regxz0G^E#pq^Fk`V8oV--D>vCyL_s0%kYP%KjSD6A+uH= z_PTM;RV=O_8{E5n@F=Uq{{0*?`sEo|IO3@uC(aHddLzKJYWO^v9yh-`Eu7;}3Uek> z7X7o|MG-@5TC_4sjt$ZJsRC}c7dhci-a=6iy_~_3gxI0;!9%4~vBBm|>K`AKt==DS zqqe4l4hb4YzX|pZPLA}Z#}$c!PI6(#I~uT}c{b)X)6=nRl6W6s)3+XRvx~;i<1V~n zVtjz`!jqB)ZpU%;0PC=~Gx=a|_2Vdmu6h<4+% zy6=Z`O((Y7EBF#LY z*qRMa6Wqbs+0)KTL9c70v@BNQiYDNl&UI{wxdm+gTmF- zhTSekIj{26J@g}k3EI>6j&Wd+&e9us0gu(N<|{#wl2!c+6Q(P;_)P|;kgCTZYCH2F z?(4o=Ao}*$vwtZ9{!EkTIxX@p78Ax`xGvai9Q zPM#!JtBc8-rU~lSoGo0O#20-G`^AYNab>6oQz?Ot(MOp z1UV9adI@vs+w6q27X*qc>4ZMD%4y#wYAkvniML4|q#7(nLQ}Qy#j2KDUoYaW*&tf zPp_ucsnjU9zO937f6_jEp?cAfM2Pfz&0(%z3xF>lJ-kyG_GALHwfonn4W!n>zK>+v zURtkj%6YBu1@2%Tt+l?x&yEMx%BH6_wmeo}1Dh!YBCIn~CbW+>-a^4A-=ADT3fy#l z1RAv!#(yn)%LE=0cpe>izW6SovK4xEOEX0ivvR9|pj_KuYVVwxD%~@L>YJ7(8Zo#x zd${8xA|u@TR_TTZSXur{0|8bcG6}?ni-ftQFd(Ju_@~!C$U^Rqv`iW=bj0@8*G9sf zCceeTg&HvkvdA71(a!GJKBHPME0RMpPd>R?SMkwhkoGcSFz8OCQ-OM;7gIP=(ed4! zs6SH9@G2KpQ4<~c6@Q(^IiTn3;&tiel1V6xoA4nsZIXByiu#d`MK7QtRr?e_moyz) zM*QnSYxe#l;_fgMwih+{Vh*7VC9p?ZQ}q!$^Nm_h-qu8Fku|T$VJH(S(<*Z+izzF$ z6~A&2pj<7C5BMxo{?zV4LO_7l&~AlQ%_Vo5Cx#xMt7(&`yVC?FpmTmB`zxd@RNnzs z4dausI~tRa!%ieXzeNbz7lhJ?ys_3JFF6mtate1+BzP=i`ZL2LBh7C{Qa_>cc~k#P z)i%NlMW)$oOk}o-jjq6r2nR@P#Jl%B#4*}{QhZw{=YVxPz&y@%9I(rGbCr6evCmeU zEiYv@){vQ#2kDKRPc?=ult6PF3oie>Bxs@jbsb$J7_FDMRzz7zS+|Wo-yte^cE&6s zy0Emz-c^n;X_ze5&l6J{#Nd=B*7{oVF9yOOlLqNT{4({ey?^IF*HtPk<=Xt=>@^)<|?i72oU%aC9eato2Xb6u1lpe88Ye?Y456 zqLZHcjIT@qp7y9E(_7+qWW<2aFw=uYa@#%*^H>PgQQ7)-SYhTI&&<@e)3Q%~K_|9K zInZM3r^M9v4D>ESV_QwwLP7JCK^&^jc{8-G2qosQb>`Qu3iFUp4$Lt=lD-4OK=k*g zgXzUqlZQ_;Yc#^vg2H9}DrBlo*q%t|5_QpuLzl>2!E$hrFqkzrlql%)&|dWP%jvK0 z)0FRLrY1Bo+&;-qHGneo5>rMEerp+`{Y?crNf1uKsFSeRmUqWf`XHDaK(JlK3Gqr2QQqx8F!!{|_Zey_nJL zSnP6>@hfSEcQL1s4_usZ=LKpb1L(2Lbub2w{}fHsXrb(fu9{yGz#Fwsho__Arc6%w zl-{xwzrP`ijjzi@!|Co{PH-K2>qKG1w*x7EvZ*UfrIewZdZiBcj_Nz5V6Fhoj9TRV zfWcsPTv~rhQF}gCAI<c;Nt@y>AnOPIu&qIhXuXE*_FdtPVgJAv>wG7vrRWcKFmHF79f-Cs?U?9n?w zDGcsV*1IkQj=_4q5o=@z5Nh<8AMsGjK{6&9Z;NQ-iHRcC%HrWD3+A6lm=QRI(k?>x z?^s-aNY7IR_BBRX)|ozsfENyD0uSPDIQfD9jnEw>WwFYmR@Bx{nFI`c5VfQbQzU%S zyRP>L56BYJM%EQJ^$9lP#5`}x9(y}I4*Y6_b}p?_+6JX!ti6vqijH+gk5WHm`>Qg! zm_pZiP3>@JyprBiDjKfw)9ZO?11zMC9{i6@bH}It_J>dXVXV$5fB0~;hf^XNMDS5V z3DWTNEx4Zx`yVOfj-GAt4@7S&bkIg79=wx-c?5#jKOE~W8yibr|J_+NegPk;Eb}23VF(h2xTL*6Z{y?mv>Ao02dLm z_$&1i`#{Bf`anVDS|{;%UZXZQadoD+R^%y;6ojk8+ofyK;t!op_aB|E+G^p+#DcP* z(E!GSwV}BKmIpe*@*)oq;_i}-hWpR%=;>9Q|Co6((^WC+5#e~UtbJh;38Ue|C2AkF z9NS?x+A2cd{iu71#SB)>BY=Y13EoLq>lIGo4E|oixDYcFVn3V%tP>5;p7XhP0N&<_ z0;?OPf9x|tx!(1#)twD3usmBN?cocvE9JLb1_B0*54?AXgWwq+`Xw0Kl)h)g`xbl+ zx&~IUkw$Hl4pqeuDoqCBZ|jSb7O1&@^WJmkagocN>FNEvrU{~daMw$);Di;=C@4YP zM*|@74h^v15+a7(lsM<+e23D=Ic<4h^D_g)(}r`m3zStgIgSj<*=1a=-funUz7B5; z5ghK$+s8-V>-KkBt>kiTV&*TWS^|ey?<_^YGjwcpK?((>hW=RZ`KSuHNL~TPpp2md z6Sc2Grrk=kGF#jm&335`v-wadP52RcqpLj7`;=?-MrNw{BDV&ZbSrsW4hhU`XsicV z(h%$2I|H3{h7cE#a9`fWXE!h9F^+-rk37k&0?P0}S4&_RipTRTg*OA4H3y~DJ-_Da zeLsu2otFuVW~2)eH1una8P5*RR~U}@1O;I(M^FwcMA87YRhm@@v~FVw7{Y)uJW7e~A<)!}G#{j9Jy z!!FoMb{LmYkMt1-vfu8$p(*Yl0Tm|Lkt8sXi4cH`sX zd)Y2&4cf-t#(!<$*V)(0eMbt_{-ebt zZw!4iuPFH90Q&tK03*!|5JvlvX)Wdb#b}mDT%=_XYa8=!FkemxWkbnB7|@b&6a{ot zSe6W50?esHpzA;$z_gfw8gngBq}N@ax^R7MT>cQn9bId!_$N{ zMFC(*W^2pN*o)K}-J^xr3GMYFr5q4~U~qIY--(6@wTs>w==wn-kx`a&b#k?~YdJu< zb-2#n9NE_w3*g5{e_T?kyh`eOsMw3BZ@mbu(R5ny&r!Qf(UGvKZf@$oBIdvE4LCeG z2ZwJtxw*(x$NBuaokF!jNPd1k)VSxt*GJ*f*JO1lG%c9t zD0xnp(ZNpiasvN!Ll)z|8~*OfKquQ{F+iqN*m(c_=of%<`^cxg0O-48q2#lS^~EL> z^q|37=Mz`j#BIzJ>+wF+BgBa%T!T5kw2Y=xha7L1N}F%$ zKFl|00>xJ5bhpD`Dgj&A4_OUNnQ)Fx1QEe-|l>*<&bEii`BiE)U|5jri`S4KcW)S^SoHNh=mN3K`Mj3I)Ap%T?A}6H? JE0NIi`5%ZO4Bh|$ literal 0 HcmV?d00001 diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..d06a71d7 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..b57ae3b8 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 00000000..250f5665 --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,199 @@ +/* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, is available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..d96755fdaf8bb2214971e0db9c1fd3077d7c419d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK literal 0 HcmV?d00001 diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..7107cec93a979b9a5f64843235a16651d563ce2d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz literal 0 HcmV?d00001 diff --git a/_static/print.css b/_static/print.css new file mode 100644 index 00000000..e77b0820 --- /dev/null +++ b/_static/print.css @@ -0,0 +1,29 @@ +.sy-head-inner { + padding: 0; +} + +h1, h2, h3, h4, h5, h6 { + page-break-inside: avoid; + page-break-after: avoid; +} + +.code-block-caption, +pre, code { + page-break-inside: avoid; + white-space: pre-wrap; + + -webkit-print-color-adjust: exact; +} + +.admonition { + -webkit-print-color-adjust: exact; +} + +.sy-head { + position: static; + border-bottom: 1px solid var(--sy-c-divider); +} + +.highlight .linenos { + box-shadow: none; +} diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 00000000..a69833b6 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,63 @@ +.highlight { color: var(--syntax-text); background-color: transparent } +.highlight .hll { display: block; background-color: var(--syntax-highlight-bg) } +.highlight .c { color: var(--syntax-comment) } /* Comment */ +.highlight .err { color: var(--syntax-invalid-illegal-text); background-color: var(--syntax-invalid-illegal-bg) } /* Error */ +.highlight .g { color: var(--syntax-meta) } /* Generic */ +.highlight .k { color: var(--syntax-keyword) } /* Keyword */ +.highlight .l { color: var(--syntax-meta) } /* Literal */ +.highlight .o { color: var(--syntax-constant) } /* Operator */ +.highlight .x { color: var(--syntax-meta) } /* Other */ +.highlight .cm { color: var(--syntax-comment) } /* Comment.Multiline */ +.highlight .cp { color: var(--syntax-constant) } /* Comment.Preproc */ +.highlight .c1 { color: var(--syntax-comment) } /* Comment.Single */ +.highlight .cs { color: var(--syntax-comment); background-color: var(--syntax-special-bg) } /* Comment.Special */ +.highlight .gd { color: var(--syntax-markup-deleted-text); background-color: var(--syntax-markup-deleted-bg) } /* Generic.Deleted */ +.highlight .ge { color: var(--syntax-markup-italic); font-style: italic } /* Generic.Emph */ +.highlight .gr { color: var(--syntax-invalid-illegal-text); background-color: var(--syntax-invalid-illegal-bg) } /* Generic.Error */ +.highlight .gh { color: var(--syntax-markup-heading) } /* Generic.Heading */ +.highlight .gi { color: var(--syntax-markup-inserted-text); background-color: var(--syntax-markup-inserted-bg) } /* Generic.Inserted */ +.highlight .go { color: var(--syntax-meta) } /* Generic.Output */ +.highlight .gp { color: var(--syntax-meta) } /* Generic.Prompt */ +.highlight .gs { color: var(--syntax-markup-bold); font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: var(--syntax-markup-heading) } /* Generic.Subheading */ +.highlight .gt { color: var(--syntax-meta) } /* Generic.Traceback */ +.highlight .kc { color: var(--syntax-constant) } /* Keyword.Constant */ +.highlight .kd { color: var(--syntax-keyword) } /* Keyword.Declaration */ +.highlight .kn { color: var(--syntax-keyword) } /* Keyword.Namespace */ +.highlight .kp { color: var(--syntax-keyword) } /* Keyword.Pseudo */ +.highlight .kr { color: var(--syntax-keyword) } /* Keyword.Reserved */ +.highlight .kt { color: var(--syntax-entity) } /* Keyword.Type */ +.highlight .ld { color: var(--syntax-meta) } /* Literal.Date */ +.highlight .m { color: var(--syntax-constant) } /* Literal.Number */ +.highlight .s { color: var(--syntax-string) } /* Literal.String */ +.highlight .il { color: var(--syntax-constant) } /* Literal.Number.Integer.Long */ +.highlight .na { color: var(--syntax-constant) } /* Name.Attribute */ +.highlight .nb { color: var(--syntax-builtin) } /* Name.Builtin */ +.highlight .nc { color: var(--syntax-definition) } /* Name.Class */ +.highlight .no { color: var(--syntax-constant) } /* Name.Constant */ +.highlight .nd { color: var(--syntax-entity) } /* Name.Decorator */ +.highlight .ni { color: var(--syntax-entity) } /* Name.Entity */ +.highlight .ne { color: var(--syntax-exception) } /* Name.Exception */ +.highlight .nf { color: var(--syntax-definition) } /* Name.Function */ +.highlight .nt { color: var(--syntax-tag) } /* Name.Tag */ +.highlight .ow { color: var(--syntax-constant) } /* Operator.Word */ +.highlight .w { color: var(--syntax-meta) } /* Text.Whitespace */ +.highlight .mf { color: var(--syntax-constant) } /* Literal.Number.Float */ +.highlight .mh { color: var(--syntax-constant) } /* Literal.Number.Hex */ +.highlight .mi { color: var(--syntax-constant) } /* Literal.Number.Integer */ +.highlight .mo { color: var(--syntax-constant) } /* Literal.Number.Oct */ +.highlight .sb { color: var(--syntax-meta) } /* Literal.String.Backtick */ +.highlight .sc { color: var(--syntax-string) } /* Literal.String.Char */ +.highlight .sd { color: var(--syntax-comment) } /* Literal.String.Doc */ +.highlight .s2 { color: var(--syntax-string) } /* Literal.String.Double */ +.highlight .se { color: var(--syntax-string) } /* Literal.String.Escape */ +.highlight .sh { color: var(--syntax-comment) } /* Literal.String.Heredoc */ +.highlight .si { color: var(--syntax-string) } /* Literal.String.Interpol */ +.highlight .sx { color: var(--syntax-string) } /* Literal.String.Other */ +.highlight .sr { color: var(--syntax-regexp) } /* Literal.String.Regex */ +.highlight .s1 { color: var(--syntax-string) } /* Literal.String.Single */ +.highlight .ss { color: var(--syntax-string) } /* Literal.String.Symbol */ +.highlight .bp { color: var(--syntax-variable) } /* Name.Builtin.Pseudo */ +.highlight .vc { color: var(--syntax-variable) } /* Name.Variable.Class */ +.highlight .vg { color: var(--syntax-variable) } /* Name.Variable.Global */ +.highlight .vi { color: var(--syntax-variable) } /* Name.Variable.Instance */ diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 00000000..97d56a74 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,566 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = docUrlRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = docUrlRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms) + ); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent !== undefined) return docContent.textContent; + console.warn( + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + // array of [docname, title, anchor, descr, score, filename] + let results = []; + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + results.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // lookup as object + objectTerms.forEach((term) => + results.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); + + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + results = results.reverse(); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/shibuya.css b/_static/shibuya.css new file mode 100644 index 00000000..a4db341e --- /dev/null +++ b/_static/shibuya.css @@ -0,0 +1 @@ +/*! tailwindcss v3.3.5 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.collapse{visibility:collapse}.order-last{order:9999}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mr-3{margin-right:.75rem}.mr-4{margin-right:1rem}.block{display:block}.flex{display:flex}.table{display:table}.contents{display:contents}.hidden{display:none}.w-64{width:16rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0}.max-w-6xl{max-width:72rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.flex-grow{flex-grow:1}.-translate-x-1{--tw-translate-x:-0.25rem}.-translate-x-1,.-translate-x-2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-x-2{--tw-translate-x:-0.5rem}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.break-words{overflow-wrap:break-word}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pr-3{padding-right:.75rem}.pt-12{padding-top:3rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-sm{font-size:.875rem;line-height:1.25rem}@font-face{font-family:Twemoji Country Flags;unicode-range:u+1f1e6-1f1ff,u+1f3f4,u+e0062-e0063,u+e0065,u+e0067,u+e006c,u+e006e,u+e0073-e0074,u+e0077,u+e007f;src:url(https://cdn.jsdelivr.net/npm/country-flag-emoji-polyfill@0.1/dist/TwemojiCountryFlags.woff2) format("woff2")}html.light{color-scheme:light}html.dark{color-scheme:dark}::-moz-selection{color:rgba(var(--sy-rc-theme),1);background-color:rgba(var(--sy-rc-theme),.2)}::selection{color:rgba(var(--sy-rc-theme),1);background-color:rgba(var(--sy-rc-theme),.2)}body{font-family:var(--sy-f-text);color:var(--sy-c-text)}.win{font-family:"Twemoji Country Flags",var(--sy-f-text)}h1,h2,h3,h4,h5{color:var(--sy-c-heading);font-family:var(--sy-f-heading)}em,strong{color:var(--sy-c-bold)}.sy-container{max-width:90rem}.sy-scrollbar{overflow-y:auto;scrollbar-gutter:stable}.sy-scrollbar::-webkit-scrollbar{height:.75rem;width:.75rem}.sy-scrollbar::-webkit-scrollbar-thumb{border-radius:10px}.sy-scrollbar::-webkit-scrollbar-track{background-color:initial}.sy-scrollbar:hover::-webkit-scrollbar-thumb{background-color:#9b9b9b33;background-clip:content-box;border:3px solid #0000}.i-icon{-webkit-mask:var(--icon-url) no-repeat;mask:var(--icon-url) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;width:1em;height:1em;display:inline-block;vertical-align:middle;font-style:normal;background-color:currentColor}.theme-switch .theme-icon{--icon-url:var(--i-sun-url)}html.dark .theme-switch .theme-icon{--icon-url:var(--i-moon-url)}html.dark .dark-hidden,html.light .light-hidden{display:none}:root{--i-alert-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3zM12 9v4m0 4h.01'/%3E%3C/svg%3E");--i-arrows-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 15 5 5 5-5M7 9l5-5 5 5'/%3E%3C/svg%3E");--i-award-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='6'/%3E%3Cpath d='M15.477 12.89 17 22l-5-3-5 3 1.523-9.11'/%3E%3C/svg%3E");--i-bell-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9m-4.27 13a2 2 0 0 1-3.46 0'/%3E%3C/svg%3E");--i-bitbucket-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M.778 1.213a.768.768 0 0 0-.768.892l3.263 19.81c.084.5.515.868 1.022.873H19.95a.772.772 0 0 0 .77-.646l3.27-20.03a.768.768 0 0 0-.768-.891zM14.52 15.53H9.522L8.17 8.466h7.561z'/%3E%3C/svg%3E");--i-bookmark-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z'/%3E%3C/svg%3E");--i-calendar-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E");--i-check-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");--i-chevron-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");--i-close-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--i-discord-url:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z'/%3E%3C/svg%3E");--i-external-link-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M13 5h6v6M19 5 5 19'/%3E%3C/svg%3E");--i-flame-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'/%3E%3C/svg%3E");--i-git-fork-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='18' r='3'/%3E%3Ccircle cx='6' cy='6' r='3'/%3E%3Ccircle cx='18' cy='6' r='3'/%3E%3Cpath d='M18 9v1a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V9M12 12v3'/%3E%3C/svg%3E");--i-github-url:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E");--i-gitlab-url:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m23.6 9.593-.033-.086L20.3.98a.851.851 0 0 0-.336-.405.875.875 0 0 0-1 .054.875.875 0 0 0-.29.44L16.47 7.818H7.537L5.332 1.07a.857.857 0 0 0-.29-.441.875.875 0 0 0-1-.054.859.859 0 0 0-.336.405L.433 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009.03.021 4.977 3.727 2.462 1.863 1.5 1.132a1.008 1.008 0 0 0 1.22 0l1.499-1.132 2.461-1.863 5.006-3.75.013-.01a6.068 6.068 0 0 0 2.01-7.002z'/%3E%3C/svg%3E");--i-help-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3m.08 4h.01'/%3E%3C/svg%3E");--i-languages-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='lucide lucide-languages'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E");--i-laptop-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='12' rx='2' ry='2'/%3E%3Cpath d='M2 20h20'/%3E%3C/svg%3E");--i-link-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71'/%3E%3Cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71'/%3E%3C/svg%3E");--i-mastodon-url:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z'/%3E%3C/svg%3E");--i-menu-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='lucide lucide-menu'%3E%3Cpath d='M4 12h16M4 6h16M4 18h16'/%3E%3C/svg%3E");--i-milestone-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6H5a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h13l4-3.5L18 6zM12 13v8M12 3v3'/%3E%3C/svg%3E");--i-moon-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3a6.364 6.364 0 0 0 9 9 9 9 0 1 1-9-9z'/%3E%3C/svg%3E");--i-outdent-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 8-4 4 4 4M21 12H11M21 6H11M21 18H11'/%3E%3C/svg%3E");--i-rocket-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09zM12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z'/%3E%3Cpath d='M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5'/%3E%3C/svg%3E");--i-skull-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='12' r='1'/%3E%3Ccircle cx='15' cy='12' r='1'/%3E%3Cpath d='M8 20v2h8v-2m-3.5-3-.5-1-.5 1h1z'/%3E%3Cpath d='M16 20a2 2 0 0 0 1.56-3.25 8 8 0 1 0-11.12 0A2 2 0 0 0 8 20'/%3E%3C/svg%3E");--i-star-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E");--i-sun-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32 1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E");--i-x-twitter-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z'/%3E%3C/svg%3E");--i-youtube-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'/%3E%3C/svg%3E");--i-zap-url:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13 2 3 14h9l-1 8 10-12h-9l1-8z'/%3E%3C/svg%3E")}.i-icon.alert{--icon-url:var(--i-alert-url)}.i-icon.arrows{--icon-url:var(--i-arrows-url)}.i-icon.award{--icon-url:var(--i-award-url)}.i-icon.bell{--icon-url:var(--i-bell-url)}.i-icon.bitbucket{--icon-url:var(--i-bitbucket-url)}.i-icon.bookmark{--icon-url:var(--i-bookmark-url)}.i-icon.calendar{--icon-url:var(--i-calendar-url)}.i-icon.check{--icon-url:var(--i-check-url)}.i-icon.chevron{--icon-url:var(--i-chevron-url)}.i-icon.close{--icon-url:var(--i-close-url)}.i-icon.discord{--icon-url:var(--i-discord-url)}.i-icon.external-link{--icon-url:var(--i-external-link-url)}.i-icon.flame{--icon-url:var(--i-flame-url)}.i-icon.git-fork{--icon-url:var(--i-git-fork-url)}.i-icon.github{--icon-url:var(--i-github-url)}.i-icon.gitlab{--icon-url:var(--i-gitlab-url)}.i-icon.help{--icon-url:var(--i-help-url)}.i-icon.languages{--icon-url:var(--i-languages-url)}.i-icon.laptop{--icon-url:var(--i-laptop-url)}.i-icon.link{--icon-url:var(--i-link-url)}.i-icon.mastodon{--icon-url:var(--i-mastodon-url)}.i-icon.menu{--icon-url:var(--i-menu-url)}.i-icon.milestone{--icon-url:var(--i-milestone-url)}.i-icon.moon{--icon-url:var(--i-moon-url)}.i-icon.outdent{--icon-url:var(--i-outdent-url)}.i-icon.rocket{--icon-url:var(--i-rocket-url)}.i-icon.skull{--icon-url:var(--i-skull-url)}.i-icon.star{--icon-url:var(--i-star-url)}.i-icon.sun{--icon-url:var(--i-sun-url)}.i-icon.x-twitter{--icon-url:var(--i-x-twitter-url)}.i-icon.youtube{--icon-url:var(--i-youtube-url)}.i-icon.zap{--icon-url:var(--i-zap-url)}.hamburger{position:relative;display:inline-block;width:16px;height:14px;overflow:hidden;cursor:pointer}.hamburger>span{position:absolute;width:16px;height:2px;left:0;background-color:var(--sy-c-text);transition:top .25s,transform .25s}.hamburger_1{top:0}.hamburger_2{top:6px}.hamburger_3{top:12px}button[aria-expanded=true] .hamburger .hamburger_1{top:6px;transform:translate(0) rotate(225deg)}button[aria-expanded=true] .hamburger .hamburger_2{top:6px;transform:translate(18px)}button[aria-expanded=true] .hamburger .hamburger_3{top:6px;transform:translate(0) rotate(135deg)}.searchbox{position:relative}.searchbox input{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;padding:6px 12px;font-size:.92rem;font-family:var(--sy-f-text);border-radius:6px;outline:0;background:var(--sy-c-bg-weak)}.searchbox button,.searchbox kbd{position:absolute;font-size:.68rem;font-weight:600;font-family:var(--sy-f-mono);padding:2px 6px;margin:6px;right:0;border-radius:3px;border:1px solid var(--sy-c-border);background-color:var(--sy-c-bg);opacity:1;transition:opacity .2s ease}.searchbox input:focus+kbd{opacity:0}.searchform{display:flex;position:relative;align-items:center}.searchform input[name=q]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;padding:6px 12px;font-size:.92rem;font-family:var(--sy-f-text);border-radius:6px;outline:0;background:var(--sy-c-bg-weak)}.searchform input[name=q]+button{position:absolute;font-size:.68rem;font-weight:600;font-family:var(--sy-f-text);padding:2px 6px;margin:6px;right:0;border-radius:3px;border:1px solid var(--sy-c-divider);background-color:var(--sy-c-bg);opacity:1;transition:opacity .2s ease}.search .highlighted{background-color:var(--syntax-highlight-bg)}.demo{border:1px solid var(--sy-c-border);border-radius:6px}.demo-code .highlight>pre{border-bottom-left-radius:0;border-bottom-right-radius:0}.demo-result{padding:1rem}#ethical-ad-placement .ethical-sidebar{position:relative;background-color:var(--sy-c-bg-weak);border:none;padding:.8rem}#ethical-ad-placement .ethical-text a{color:var(--sy-c-text)!important}.sy-main #ethical-ad-placement .ethical-sidebar{margin-left:0;max-width:380px}.sy-main #ethical-ad-placement .ethical-image-link{flex-shrink:0;margin-right:.4rem}.sy-main #ethical-ad-placement .ethical-content{display:flex}.sy-main #ethical-ad-placement .ethical-text{margin-top:0}.sy-main #ethical-ad-placement .ethical-callout{position:absolute;right:.4rem;bottom:.4rem}#carbonads{margin:1rem 0;position:relative;display:block;background-color:var(--sy-c-bg-weak);border:none;border-radius:8px;padding:.8rem .8rem 1.6rem}#carbonads a{border:0;font-weight:400}#carbonads img{margin:0}.carbon-wrap{display:flex;align-items:center;justify-content:space-between;flex-direction:column}.carbon-text{display:block;margin:.5rem 0;line-height:1.42;font-size:.78rem;text-align:center}.carbon-text:hover{color:var(--sy-c-link)}.carbon-poweredby{position:absolute;right:.8rem;bottom:.5rem;font-size:.68rem;text-transform:uppercase}.carbon-poweredby:hover{text-decoration:underline}.sy-main #carbonads{max-width:380px;padding:1rem;margin-top:1.6rem}.sy-main .carbon-wrap{flex-direction:row;align-items:flex-start}.sy-main .carbon-text{text-align:left;margin-top:0;margin-left:1rem;font-size:.86rem}.bsa-bar{justify-content:space-between;padding:15px 20px;border-radius:10px;box-shadow:inset 0 0 2px #00000026;text-decoration:none}.bsa-bar,.bsa-main{display:flex;flex-flow:row nowrap;align-items:center}.bsa-main{flex-grow:1;justify-content:center;margin:0 auto}.bsa-img{max-height:40px;margin-right:20px;line-height:0}.bsa-details{display:flex;flex-flow:column nowrap;margin-right:20px}.bsa-tagline{margin-bottom:3px;font-weight:600;font-size:9px;line-height:1;letter-spacing:1.5px;text-transform:uppercase}.bsa-desc{max-width:600px;font-weight:400;font-size:12px;line-height:1.4;letter-spacing:1px}.bsa-cta{padding:10px 16px;transform:translateY(-1px);border-radius:3px;font-weight:600;font-size:10px;line-height:1;letter-spacing:1px;text-transform:uppercase;white-space:nowrap;transition:all .3s ease-in-out}@media (max-width:940px){.bsa-details{font-size:14px;margin-right:0}.bsa-cta{display:none}}@media (min-width:768px) and (max-width:820px){.bsa-img{display:none}}@media (max-width:480px){.bsa-img{display:none}}.repo-stats{margin-bottom:1rem;padding:.5rem 0;border-top:1px solid var(--sy-c-divider);border-bottom:1px solid var(--sy-c-divider)}.repo-stats-count{color:var(--sy-c-text-weak)}.repo-stats:hover .repo-stats-count{color:var(--sy-c-text)}.repo-stats strong{font-weight:500;font-family:var(--sy-f-mono);color:inherit}.edit-this-page{border-top:1px solid var(--sy-c-divider);margin:1rem 0;padding:.5rem 0;font-size:.8rem;font-weight:600}.repo-stats+.edit-this-page{border-top:0;margin-top:0;padding-top:0}.edit-this-page a{color:var(--sy-c-text-weak)}.edit-this-page a:hover{color:var(--sy-c-text)}.edit-this-page a:after{content:" →"}.announcement{position:sticky;top:0;left:0;width:100%;padding:.8rem 2rem;display:flex;align-items:center;color:var(--sy-c-banner,#fff);background-color:var(--sy-c-banner-bg,rgba(var(--sy-rc-theme),1));z-index:20}.announcement a{text-decoration:underline}.announcement ::-moz-selection{color:var(--sy-c-banner,#fff)}.announcement ::selection{color:var(--sy-c-banner,#fff)}.announcement-inner{width:100%;text-align:center}.announcement-close{position:absolute;top:.8rem;right:1rem}.sy-head{position:sticky;top:var(--sy-s-banner-height);height:var(--sy-s-navbar-height);background-color:initial;z-index:20}.sy-head-blur{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background-color:rgba(var(--sy-rc-bg),.85);z-index:-1;--tw-shadow:0 2px 4px rgba(var(--sy-rc-invert),.02),0 1px 0 rgba(var(--sy-rc-invert),.06);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.sy-head-inner{display:flex;padding-left:max(env(safe-area-inset-right),1.5rem);padding-right:max(env(safe-area-inset-right),1rem);justify-content:space-between;align-items:center;height:var(--sy-s-navbar-height)}.sy-head .i-icon{font-size:1.25rem}.sy-head-brand img{height:28px}.sy-head-brand .dark-logo,.sy-head-brand img+strong{display:none}.dark .sy-head-brand .dark-logo{display:inline}.dark .sy-head-brand .light-logo{display:none}.light .sy-head-brand .light-logo{display:inline}.light .sy-head-brand .dark-logo{display:none}.sy-head-nav a,.sy-head-nav button{padding:.5rem;font-size:.95rem;font-weight:500;white-space:nowrap}.sy-head-nav .link i.external-link{font-size:68%;opacity:.6;color:var(--sy-c-text-weak);margin-left:2px}.sy-head-nav .link>ul a{display:block}.sy-head-nav .link>ul a:hover{background:var(--sy-c-bg-weak);border-radius:6px}.sy-head-nav .link>ul small{display:block;color:var(--sy-c-text-weak);font-weight:400}.sy-head-social a{padding:.5rem}.sy-head-actions button{height:var(--sy-s-navbar-height);padding:0 .5rem}@media (max-width:767px){body[data-expanded-navlinks=true]{overflow:hidden}.sy-head-links{display:none;position:fixed;top:var(--sy-s-offset-top);bottom:0;left:0;right:0;padding:4rem 1.8rem 0;width:100%;box-sizing:border-box;border-top:1px solid var(--sy-c-divider);background-color:var(--sy-c-bg);overflow-y:auto}.sy-head-links._expanded{display:block}.sy-head-nav{margin-left:auto;margin-right:auto}.sy-head-nav .link{margin:.5rem 0}.sy-head-nav .link i.chevron{display:none}.sy-head-nav .link>ul{margin:.5rem 0 .5rem 1rem}.sy-head-extra form.searchbox{position:absolute;top:1rem;left:1.8rem;right:1.8rem}.sy-head-extra{flex-direction:column;padding:2rem 0 1rem;width:100%}}@media (min-width:768px){.sy-head-inner{padding-right:max(env(safe-area-inset-right),1.5rem)}.sy-head-links{display:flex;flex-grow:1;align-items:center;justify-content:space-between}.sy-head-nav{white-space:nowrap;overflow:auto}.sy-head-nav .link{display:inline-flex;align-items:center;height:var(--sy-s-navbar-height)}.sy-head-nav a:hover{color:rgba(var(--sy-rc-invert),1)}.sy-head-nav .link:hover>a{background-color:var(--sy-c-bg-weak);border-radius:6px}.sy-head-nav .link i.chevron{opacity:.6;font-size:1rem;transform:rotate(90deg)}.sy-head-nav .link>ul{position:absolute;height:0;visibility:hidden;background-color:var(--sy-c-bg);top:var(--sy-s-offset-top);margin-top:-10px;padding:15px;border-radius:6px;border:1px solid var(--sy-c-divider);box-shadow:0 12px 32px rgba(var(--sy-rc-invert),.1),0 2px 6px rgba(var(--sy-rc-invert),.08);z-index:9}.sy-head-nav .link:hover>ul{height:auto;visibility:visible}.sy-head-nav .link>ul>li{padding:.2rem 0}.sy-head-social{margin-left:.5rem}.sy-head-social a{padding:.5rem}}.sy-foot{border-top:1px solid var(--sy-c-foot-divider);padding-top:1.5rem;padding-bottom:1rem;color:var(--sy-c-foot-text);background-color:var(--sy-c-foot-bg)}.sy-foot-inner{padding-left:max(env(safe-area-inset-right),1.5rem);padding-right:max(env(safe-area-inset-right),1.5rem)}.sy-foot-copyright{font-size:.84rem}.sy-foot-copyright a{font-weight:500}.sy-foot-socials a{font-size:1.4rem;color:var(--sy-c-foot-text)}.sy-foot-socials a+a{margin-left:.5rem}.sy-lside li{margin:.6rem 0}.sy-lside li.link>span{font-size:.86rem;font-weight:500;font-family:var(--sy-f-heading);color:var(--sy-c-text-weak);text-transform:uppercase;letter-spacing:.4px}.sy-lside li.link .i-icon{display:none}.sy-lside li.link>ul{margin-left:1rem}.sy-lside li.link>ul small{display:none}.sy-lside .sidebar-links{margin-bottom:2rem}.sy-lside .sidebar-links span{display:inline-block;vertical-align:middle}.sy-lside .sidebar-links .icon{padding:.1rem;border-radius:6px;border:1px solid var(--sy-c-border);margin-right:.4rem;opacity:.8}.sy-lside .sidebar-links svg{width:1.5rem;height:1.5rem}.sy-lside .sidebar-links a:hover .icon{opacity:1}@media (min-width:768px){.sy-lside .sy-lside-inner{top:var(--sy-s-offset-top)}.sy-lside .sy-scrollbar{height:calc(100vh - var(--sy-s-offset-top));overflow-x:hidden}}.yue *{scroll-margin-top:calc(var(--sy-s-offset-top) + 68px)}.sy-content{max-width:64rem;min-height:calc(100vh - var(--sy-s-offset-top) - 80px)}@media (max-width:767px){#lside{position:fixed;z-index:18;top:var(--sy-s-offset-top);left:0;bottom:0;width:300px;max-width:100%;height:calc(100vh - var(---sy-s-offset-top));overflow:auto;background:rgba(var(--sy-rc-bg),.98);transform:translateX(-100%);transition:transform .2s ease}#lside._expanded{transform:translateX(0)}.lside-overlay{position:fixed;top:var(--sy-s-offset-top);left:0;width:0;height:0;background-color:rgba(var(--sy-rc-invert),.24);opacity:0;transition:width 0 .25s,height 0 .25s,opacity .25s}#lside._expanded+.lside-overlay{width:100%;height:100%;opacity:1;z-index:16}}@media (max-width:1279px){.sy-rside{position:fixed;z-index:25;top:0;right:0;bottom:0;width:20rem;max-width:100%;padding-top:2rem;padding-bottom:1rem;overflow:auto;background:var(--sy-c-bg);transform:translateX(110%);transition:transform .2s ease;--tw-shadow:-12px 0 16px rgba(var(--sy-rc-bg),0.16);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}#rside._expanded{transform:translateX(0)}.rside-close{position:absolute;top:16px;right:16px;width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;font-size:1.4rem}.rside-overlay{position:fixed;top:0;left:0;width:0;height:0;background-color:rgba(var(--sy-rc-invert),.24);opacity:0;transition:width 0 .25s,height 0 .25s,opacity .25s}#rside._expanded+.rside-overlay{width:100%;height:100%;opacity:1;z-index:22}}@media (min-width:768px){.sy-main{width:calc(100% - 18rem);max-width:52rem}}@media (min-width:1280px){.sy-main{width:calc(100% - 34rem);max-width:none}.sy-rside .sy-scrollbar{max-height:calc(100vh - var(--sy-s-offset-top) - env(safe-area-inset-bottom))}.yue *{scroll-margin-top:calc(var(--sy-s-offset-top) + 24px)}}.nav-languages button,.nav-versions button{cursor:pointer;padding:0;margin:0;background:#0000;border:0;white-space:nowrap}.nav-versions .chevron{font-size:.72rem;font-weight:400;transform:rotate(90deg);color:var(--sy-c-text-weak)}@media (max-width:767px){.nav-languages,.nav-versions{width:100%;background-color:var(--sy-c-bg-weak);border-radius:6px;padding-bottom:.6rem;margin-bottom:1rem}.nav-languages button,.nav-versions button{padding:.5rem 1rem;font-weight:500;font-size:.76rem;color:var(--sy-c-text-weak)}.nav-languages button .i-icon,.nav-versions button .i-icon{display:none}.nav-versions ul{padding:0 .6rem}.nav-versions li{padding:.2rem .4rem;display:inline-block}.nav-languages li{font-size:.94rem;padding:.32rem 1rem}}@media (min-width:768px){.nav-languages,.nav-versions{display:flex;align-items:center;position:relative;width:auto;height:var(--sy-s-navbar-height);background:#0000;color:var(--sy-c-text)}.nav-languages button,.nav-versions button{padding:0 .5rem;border-right:1px solid var(--sy-c-divider-weak)}.nav-languages-choices,.nav-versions-choices{position:absolute;visibility:hidden;top:3rem;right:-.6rem;min-width:120px;box-sizing:border-box;background-color:var(--sy-c-bg);border-radius:6px;overflow:hidden;padding:.8rem 1rem;box-shadow:0 12px 32px rgba(var(--sy-rc-invert),.1),0 2px 6px rgba(var(--sy-rc-invert),.08)}.nav-languages:hover .nav-languages-choices,.nav-versions:hover .nav-versions-choices{visibility:visible}.nav-languages li,.nav-versions li{padding:.1rem 0}.nav-languages a,.nav-versions a{display:block;padding:.2rem .6rem;color:var(--sy-c-text);white-space:nowrap}.nav-languages a:hover,.nav-versions a:hover{color:var(--sy-c-link);background:var(--sy-c-bg-weak);border-radius:6px}}.sy-breadcrumbs{position:sticky;top:var(--sy-s-offset-top);background-color:var(--sy-c-bg);padding:0 1.5rem;z-index:5}.sy-breadcrumbs-inner{padding:.8rem 0;border-bottom:1px solid var(--sy-c-divider)}.sy-breadcrumbs ul{display:flex;font-size:.94rem;white-space:nowrap;overflow:auto}.sy-breadcrumbs button{display:flex;align-items:center}.sy-breadcrumbs ul a{color:var(--sy-c-text-weak)}.sy-breadcrumbs ul a:hover{color:var(--sy-c-bold)}.sy-breadcrumbs ul a+span{padding:0 .4rem;font-weight:300;color:var(--sy-c-text-weak)}@media (min-width:1280px){.sy-breadcrumbs{display:none}}@media (min-width:768px){.sy-breadcrumbs-inner{padding:1.5rem 0 1rem}}.globaltoc{padding-bottom:20px}.globaltoc .caption{font-size:.86rem;font-weight:500;font-family:var(--sy-f-heading);color:var(--sy-c-text-weak);text-transform:uppercase;letter-spacing:.4px;padding:.8rem 0 .4rem;border-top:1px solid var(--sy-c-divider)}.globaltoc>p.caption:first-of-type{padding-top:0;border-top:none}.globaltoc .caption+ul{margin-bottom:1.5rem}.globaltoc ul+.caption{margin-top:3rem}.globaltoc li{margin:.6rem 0}.globaltoc li>ul{margin-left:.6rem;font-size:.96rem}.globaltoc li.toctree-l1>ul{margin-left:.2rem;border-left:1px solid var(--sy-c-divider-weak)}.globaltoc li.toctree-l2{padding-left:.9rem;margin-left:-1px;border-left:1px solid #0000}.globaltoc li.toctree-l2.current{border-color:var(--sy-c-link)}.globaltoc>ul a.current{font-weight:500;color:var(--sy-c-link)}.globaltoc>ul a:hover{color:var(--sy-c-link-weak)}.globaltoc li{position:relative}.globaltoc li>button{position:absolute;top:.2rem;right:0;display:flex;justify-content:center;align-items:center;width:1.2rem;height:1.2rem;border-radius:3px}.globaltoc li>button:hover{background-color:var(--sy-c-bg-weak)}.globaltoc li._expand>ul,.globaltoc li.current>ul{display:block}.globaltoc li._collapse>ul,.globaltoc li>ul{display:none}.globaltoc li>button .chevron{transform:rotate(0deg);transition:transform .2s ease}.globaltoc li._expand>button .chevron,.globaltoc li.current>button .chevron{transform:rotate(90deg)}.globaltoc li._collapse>button .chevron{transform:rotate(0deg)}.sy-deprecated{padding:.8rem;font-size:.85rem;background-color:#ffdd001a;border-radius:6px}.sy-deprecated a{color:var(--sy-c-link);text-decoration:underline}.sy-deprecated a:hover{color:var(--sy-c-link-weak)}.sy-rside-inner>div{margin-bottom:1rem}.sy-rside-inner>div>h3{font-size:.8rem;font-weight:500;letter-spacing:.4px;text-transform:uppercase;margin-bottom:1rem}html[lang=ja] .sy-rside-inner>div>h3,html[lang=ko] .sy-rside-inner>div>h3,html[lang=zh-TW] .sy-rside-inner>div>h3,html[lang=zh] .sy-rside-inner>div>h3{letter-spacing:0;font-size:.86rem;font-weight:600}.localtoc>ul li{margin-top:.36rem;margin-bottom:.36rem}.localtoc>ul li>a:hover{color:var(--sy-c-link-weak)}.localtoc>ul li.active>a{font-weight:500;color:var(--sy-c-link)}.localtoc>ul>li ul{padding-left:.8rem}.sy-rside ul.this-page-menu{margin-top:-.6rem}.sy-rside ul.this-page-menu a{font-size:.96rem}.sy-rside ul.this-page-menu a:hover{color:var(--sy-c-link-weak)}.navigation{gap:2rem;margin-top:2rem;padding-top:1rem;border-top:1px solid var(--sy-c-divider)}.navigation>div{width:100%}.navigation a{display:inline-flex;align-items:center}.navigation a:hover{color:rgba(var(--sy-rc-invert),1)}.navigation-prev i.chevron{transform:rotate(180deg)}.navigation-next{text-align:right}.navigation-next a{justify-content:end}.navigation .page-info{padding:0 8px}.navigation .page-info>span{font-size:.8rem;color:var(--sy-c-text-weak)}.yue{--yue-c-black:#111827;--yue-c-text:var(--sy-c-text);--yue-c-heading:var(--sy-c-heading);--yue-c-bold:var(--sy-c-bold);--yue-c-link-1:var(--sy-c-text);--yue-c-link-2:var(--yue-c-black);--yue-c-link-border-1:rgba(var(--sy-rc-theme),0.8);--yue-c-link-border-2:rgb(var(--sy-rc-theme));--yue-c-ol-marker:#6b7280;--yue-c-ul-marker:#d1d5db;--yue-c-hr:#e5e7eb;--yue-c-quote:var(--yue-c-black);--yue-c-quote-border:#cfd3db;--yue-c-quote-symbol:rgba(var(--sy-rc-theme),1);--yue-c-caption:#6b7280;--yue-c-code:var(--yue-c-black);--yue-c-code-bg:#fff4d4;--yue-c-th-bg:#eff3f8;--yue-c-th-border:#d1d5db;--yue-c-td-border:#e5e7eb}html.dark .yue{--yue-c-link-1:var(--sy-c-text);--yue-c-link-2:#fff;--yue-c-ol-marker:#9ca3af;--yue-c-ul-marker:#4b5563;--yue-c-hr:#374151;--yue-c-quote:#f3f4f6;--yue-c-quote-border:#374151;--yue-c-caption:#9ca3af;--yue-c-code:#fff;--yue-c-code-bg:#312f29;--yue-c-th-bg:#24282e;--yue-c-th-border:#4b5563;--yue-c-td-border:#374151}.yue{font-size:1rem;line-height:1.75;color:var(--yue-c-text)}.yue p{margin-top:1rem;margin-bottom:1.25rem}.yue a{color:var(--yue-c-link-1);font-weight:500;text-decoration:none;border-bottom:1px solid var(--yue-c-link-border-1)}.yue a:hover{color:var(--yue-c-link-2);border-bottom:2px solid var(--yue-c-link-border-2)}.yue strong{color:var(--yue-c-bold);font-weight:600}.yue a strong,.yue blockquote strong,.yue thead th strong{color:inherit}.yue ol{margin-top:1.25em;margin-bottom:1.25em;padding-left:1.625em}.yue ol,.yue ol[type="1"]{list-style-type:decimal}.yue ol.upperalpha,.yue ol[type=A]{list-style-type:upper-alpha}.yue ol.loweralpha,.yue ol[type=a]{list-style-type:lower-alpha}.yue ol.upperroman,.yue ol[type=I]{list-style-type:upper-roman}.yue ol.lowerroman,.yue ol[type=i]{list-style-type:lower-roman}.yue ul{list-style-type:disc;margin-top:1.25em;margin-bottom:1.25em;padding-left:1.625em}.yue ol>li::marker{font-weight:400;color:var(--yue-c-ol-marker)}.yue ul>li::marker{color:var(--yue-c-ul-marker)}.yue dl{margin-top:1.5rem;margin-bottom:1.5rem}.yue dt{color:var(--yue-c-bold);font-weight:600}.yue dd{margin-left:1.5rem}.yue hr{border-color:var(--yue-c-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.yue blockquote{color:var(--yue-c-quote);border-left-width:.25rem;border-left-color:var(--yue-c-quote-border);margin-top:1.2rem;margin-bottom:1.2rem;padding-left:1rem}.yue blockquote .attribution{font-size:.85em;font-style:italic}[lang=ja] .yue blockquote .attribution,[lang=ko] .yue blockquote .attribution,[lang^=zh] .yue blockquote .attribution{font-style:normal}.yue h1{color:var(--yue-c-heading);font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.yue h1 strong{font-weight:900;color:inherit}.yue h2{color:var(--yue-c-heading);font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.yue h2 strong{font-weight:800;color:inherit}.yue h3{color:var(--yue-c-heading);font-weight:600;font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.yue h3 strong{font-weight:700;color:inherit}.yue h4{color:var(--yue-c-heading);font-weight:600;margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.yue h4 strong{font-weight:700;color:inherit}.yue img{margin-top:2em;margin-bottom:2em}.yue figure>*{margin-top:0;margin-bottom:0}.yue figcaption{color:var(--yue-c-caption);font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.yue code{color:var(--yue-c-code);font-weight:600;font-size:.875em}.yue a code,.yue blockquote code,.yue h1 code,.yue h2 code,.yue h3 code,.yue h4 code,.yue th code{color:inherit}.yue h2 code{font-size:.875em}.yue li>code,.yue p>code{padding-left:4px;padding-right:4px;border-radius:3px;font-weight:500;background-color:var(--yue-c-code-bg)}.yue h3 code{font-size:.9em}.yue figure,.yue video{margin-top:2em;margin-bottom:2em}.yue li{margin-top:.5em;margin-bottom:.5em}.yue ol>li,.yue ul>li{padding-left:.375em}.yue ol ol,.yue ol ul,.yue ul ol,.yue ul ul{margin-top:.75em;margin-bottom:.75em}.yue h2+*,.yue h3+*,.yue h4+*,.yue hr+*{margin-top:0}.yue table{width:100%;table-layout:auto;text-align:left;margin-top:2em;margin-bottom:2em;font-size:.86em;line-height:1.7}.yue table>caption{margin-bottom:.4rem;color:var(--yue-c-caption)}.yue thead tr{border-bottom-width:1px;border-bottom-color:var(--yue-c-th-border)}.yue thead th{color:var(--yue-c-heading);font-weight:600;vertical-align:middle}.yue tbody tr{border-bottom-width:1px;border-bottom-color:var(--yue-c-td-border)}.yue tbody tr:last-child{border-bottom-width:0}.yue tbody td{vertical-align:middle}.yue tfoot{border-top-width:1px;border-top-color:var(--yue-c-th-border)}.yue tfoot td{vertical-align:top}.yue td>p{margin:.25rem 0}.yue thead th>p{margin:0}.yue tbody td,.yue tfoot td,.yue thead th{padding:.5rem}.yue section>div{margin-bottom:2rem}.yue dd>p:first-child{margin-top:0}.yue p.lead{font-size:1.2rem;color:var(--sy-c-text-weak);margin-bottom:0}.yue p.lead+hr{margin-top:1rem}.yue p.rubric{color:var(--yue-c-heading);font-weight:600;font-size:1.25em;margin-top:2em}.yue dl.simple>dd>p,.yue ol.simple>li>p,.yue ul.simple>li>p{margin:0}.yue a.headerlink{visibility:hidden;margin-left:6px;color:rgba(var(--sy-rc-text),.6);font-weight:300;font-size:58%;font-family:var(--sy-f-mono);--icon-url:var(--i-link-url);-webkit-mask:var(--icon-url) no-repeat;mask:var(--icon-url) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;width:1em;height:1em;display:inline-block;vertical-align:middle;font-style:normal;background-color:currentColor}.yue .math a.headerlink,h1:hover a.headerlink,h2:hover a.headerlink,h3:hover a.headerlink,h4:hover a.headerlink,h5:hover a.headerlink,h6:hover a.headerlink{visibility:visible}.yue .toctree-wrapper a{border-bottom:none}.yue .toctree-wrapper p.caption{font-size:.86rem;font-weight:500;font-family:var(--sy-f-heading);color:var(--sy-c-text-weak);text-transform:uppercase;letter-spacing:.4px;padding:.8rem 0 .4rem;border-bottom:1px solid var(--sy-c-divider)}.yue .align-center{display:block;text-align:center}.yue .align-center,.yue figure.align-center img{margin-left:auto;margin-right:auto}a.footnote-reference{font-size:.65rem;vertical-align:top}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>p,div.citation>p{margin-bottom:.5rem;margin-top:.5rem;margin-left:2rem}.yue kbd.kbd:not(.compound){font-size:.86rem;padding:2px 5px;border-radius:3px;margin-right:.25rem}.yue kbd.compound>kbd{margin-left:.25rem}.light .yue kbd.kbd:not(.compound){background:linear-gradient(-225deg,#e6e6e6,#f8f8f8);box-shadow:inset 0 -2px #dbdbdb,inset 0 0 1px 1px #fff,0 1px 2px 1px #50505066}.dark .yue kbd.kbd:not(.compound){background:linear-gradient(-225deg,#353434,#141414);box-shadow:inset 0 -2px #373737,inset 0 0 1px 1px #222,0 1px 2px 1px #000}.hlist td{vertical-align:top}p.centered{text-align:center}.dark .light-only,.light .dark-only{display:none}.yue .genindex-jumpbox,.yue .modindex-jumpbox{border-top:1px solid var(--sy-c-border);border-bottom:1px solid var(--sy-c-border);padding:2px .4rem}.yue table.modindextable td:first-of-type{width:28px}.yue table.modindextable img.toggler{margin:0}.yue table.modindextable tr.cap{font-size:1.12rem;background:var(--sy-c-bg-weak);font-family:var(--sy-f-mono)}.yue h2+table.indextable,.yue table.indextable ul{margin-top:0}:root,html.light{--admonition-bg-opacity:0.03;--admonition-head-opacity:0.08;--admonition-border-opacity:1}@media (prefers-color-scheme:dark){:root{--admonition-bg-opacity:0.08;--admonition-head-opacity:0.15;--admonition-border-opacity:0.8}}html.dark{--admonition-bg-opacity:0.08;--admonition-head-opacity:0.15;--admonition-border-opacity:0.8}:root{--attention-icon:var(--i-alert-url);--attention-color:247,89,171;--caution-icon:var(--i-zap-url);--caution-color:247,186,42;--danger-icon:var(--i-skull-url);--danger-color:255,92,47;--error-icon:var(--i-close-url);--error-color:255,92,47;--hint-icon:var(--i-bell-url);--hint-color:0,200,80;--important-icon:var(--i-flame-url);--important-color:179,127,235;--note-icon:var(--i-calendar-url);--note-color:3,169,244;--tip-icon:var(--i-rocket-url);--tip-color:0,200,80;--warning-icon:var(--i-zap-url);--warning-color:255,145,0;--seealso-icon:var(--i-link-url);--seealso-color:60,140,255;--todo-icon:var(--i-bookmark-url);--todo-color:220,150,0;--versionadded-color:0,200,80;--versionchanged-color:247,186,42;--deprecated-color:255,92,47}.admonition{--color-rgb:var(--sy-rc-theme);--icon-url:var(--i-bell-url);position:relative;padding:0 16px .8rem;margin-top:1rem;margin-bottom:1rem;border-left:4px solid rgba(var(--color-rgb),var(--admonition-border-opacity));background-color:rgba(var(--color-rgb),var(--admonition-bg-opacity))}.admonition:before{position:absolute;content:"";top:6px;left:-12px;width:20px;height:20px;border-radius:100%;background-color:rgb(var(--color-rgb))}.admonition p.admonition-title{position:relative;margin:0 -16px .8rem -19px;padding:4px 18px;font-size:.85rem;font-weight:600;line-height:1.72;color:rgb(var(--color-rgb));background-color:rgba(var(--color-rgb),var(--admonition-head-opacity));--yue-c-code:rgb(var(--color-rgb));--yue-c-bold:rgb(var(--color-rgb))}.admonition p.admonition-title svg{display:inline-block}.admonition-title:before{position:absolute;content:"";top:10px;left:-5px;-webkit-mask:var(--icon-url) no-repeat;mask:var(--icon-url) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;font-style:normal;width:12px;height:12px;background-color:#fff}.admonition.attention{--icon-url:var(--attention-icon);--color-rgb:var(--attention-color)}.admonition.caution{--icon-url:var(--caution-icon);--color-rgb:var(--caution-color)}.admonition.danger{--icon-url:var(--danger-icon);--color-rgb:var(--danger-color)}.admonition.error{--icon-url:var(--error-icon);--color-rgb:var(--error-color)}.admonition.hint{--icon-url:var(--hint-icon);--color-rgb:var(--hint-color)}.admonition.important{--icon-url:var(--important-icon);--color-rgb:var(--important-color)}.admonition.note{--icon-url:var(--note-icon);--color-rgb:var(--note-color)}.admonition.tip{--icon-url:var(--tip-icon);--color-rgb:var(--tip-color)}.admonition.warning{--icon-url:var(--warning-icon);--color-rgb:var(--warning-color)}.admonition.seealso{--icon-url:var(--seealso-icon);--color-rgb:var(--seealso-color)}.admonition.admonition-todo{--icon-url:var(--todo-icon);--color-rgb:var(--todo-color)}.admonition p.admonition-title+p{margin-top:0}.admonition>:last-child{margin-bottom:0}span.versionmodified{color:var(--sy-c-bold);font-weight:600}div.deprecated,div.versionadded,div.versionchanged{--version-color:var(--sy-rc-theme);position:relative;padding:6px 1rem;margin:1rem 0;border-left:4px solid rgba(var(--version-color),1);background-color:rgba(var(--version-color),.08);line-height:1.72}div.deprecated:before,div.versionadded:before,div.versionchanged:before{position:absolute;content:var(--version-icon);top:10px;left:-12px;color:#fff;width:20px;height:20px;border-radius:100%;background-color:rgba(var(--version-color),1);text-align:center;font:normal 700 14px/20px var(--sy-f-mono)}div.versionadded{--version-color:var(--versionadded-color);--version-icon:"#"}div.versionchanged{--version-color:var(--versionchanged-color);--version-icon:"%"}div.deprecated{--version-color:var(--deprecated-color);--version-icon:"!"}div.deprecated>p,div.versionadded>p,div.versionchanged>p{margin:0}.yue blockquote.epigraph{padding:1rem 2.4rem;border-left:0;text-align:center}.yue blockquote.highlights{border-left-width:4px;padding-top:.2rem;padding-bottom:.2rem;background-color:var(--sy-c-bg-weak)}.yue blockquote.pull-quote{position:relative;font-size:1.24rem;padding:2.4rem 3.6rem 1.2rem;border-left:0}.yue blockquote.pull-quote:before{content:"\201c";position:absolute;top:0;left:.5rem;color:var(--yue-c-quote-symbol);font:700 4rem/1 Times New Roman,Georgia,Palatino,Times,serif}.yue blockquote.pull-quote .attribution{text-align:right}pre.literal-block{line-height:1.48;padding:1rem;font-size:.96rem;background-color:var(--syntax-pre-bg);border-radius:6px;overflow:auto}.highlight,.literal-block-wrapper{--margin:1rem;--radius:6px}.highlight>pre{line-height:1.48;padding:var(--margin);font-size:.96rem;font-family:var(--sy-f-mono);background-color:var(--syntax-pre-bg);border-radius:var(--radius);overflow:auto}.win .highlight>pre{font-family:"Twemoji Country Flags",var(--sy-f-mono)}.highlight .linenos{display:inline-block;box-shadow:-.05rem 0 rgba(var(--sy-rc-invert),.2) inset;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:.8rem;padding-right:.8rem;opacity:.6}.highlight .hll{margin-left:calc(0rem - var(--margin));margin-right:calc(0rem - var(--margin));padding:0 var(--margin)}.code-block-caption{font-size:.84rem;font-weight:600;color:var(--syntax-text);background-color:var(--syntax-cap-bg);padding:.4rem var(--margin);border-radius:var(--radius) var(--radius) 0 0}.code-block-caption+div>.highlight>pre{border-top-left-radius:0;border-top-right-radius:0}div[class^=highlight]>.highlight>pre{display:grid}.yue .table-wrapper{width:100%;overflow-x:auto;margin-top:2rem;margin-bottom:2rem}.yue .table-wrapper>table{margin:0}.yue .table-wrapper thead tr{border-top:1px solid var(--yue-c-td-border)}.yue .table-wrapper th{background-color:var(--yue-c-th-bg);border-left:1px solid var(--yue-c-td-border)}.yue .table-wrapper td,.yue .table-wrapper th:last-child{border-right:1px solid var(--yue-c-td-border)}.yue .table-wrapper td{border-left:1px solid var(--yue-c-td-border)}.yue .table-wrapper tbody tr:first-child{border-top:1px solid var(--yue-c-td-border)}.yue .table-wrapper tbody tr:last-child{border-bottom-width:1px}.yue .table-wrapper thead+tbody tr:first-child{border-top-width:0}.yue table.hlist td{vertical-align:top}.table-wrapper{overflow-x:auto;scrollbar-gutter:stable}.table-wrapper::-webkit-scrollbar{height:.75rem;width:.75rem}.table-wrapper::-webkit-scrollbar-thumb{border-radius:10px}.table-wrapper::-webkit-scrollbar-track{background-color:initial}.table-wrapper:hover::-webkit-scrollbar-thumb{background-color:#9b9b9b33;background-clip:content-box;border:3px solid #0000}html.light{--sig-property:var(--syntax-light-keyword);--sig-name:var(--syntax-light-property);--sig-typehint:var(--syntax-light-constant)}html.dark{--sig-property:var(--syntax-dark-keyword);--sig-name:var(--syntax-dark-property);--sig-typehint:var(--syntax-dark-constant)}dt.sig{position:relative;font-size:.92rem;padding:.25rem .5rem .25rem 3rem;text-indent:-2.4rem;border-radius:6px}dt.sig:after{content:"";display:table;clear:both}dt.sig:hover{background:var(--sy-c-bg-weak)}dt.sig+dd{font-size:.92rem;margin-left:2rem}dt.sig>em.property:first-child{color:var(--sig-property)}dl.field-list a{font-weight:400}dt.sig+dd>div{margin-bottom:1rem}dt.sig+dd>dl.field-list>dt{text-transform:uppercase;font-size:.76rem}em.property,em.sig-param{font-style:normal}em.sig-param{color:var(--sy-c-text-weak)}span.sig-name,span.sig-prename{color:var(--sig-name)}span.sig-name{font-weight:600}span.sig-return-icon{color:var(--sy-c-text-weak)}span.sig-return-typehint,span.sig-return-typehint>a{color:var(--sig-typehint)}span.pre,span.sig-paren{font-family:var(--sy-f-mono)}dt.sig>a.internal{font-size:.82rem;border:0;color:var(--sy-c-text-weak)}dt.sig>a.internal:before{content:"\a";white-space:pre}.viewcode-block{position:relative}.viewcode-back{position:absolute;top:-1.5rem;font-size:.8rem}.classifier{font-style:oblique;font-weight:400}.classifier:before{font-style:normal;margin-left:.1rem;margin-right:.5rem;content:":";display:inline-block}.yue .table-wrapper table.autosummary td{border:none;padding-top:.25rem;padding-bottom:.25rem}.yue p.rubric+div.autosummary{margin-top:0}:root{--syntax-light-pre-bg:rgba(var(--sy-rc-theme),0.1);--syntax-light-cap-bg:rgba(var(--sy-rc-theme),0.2);--syntax-light-highlight-bg:rgba(var(--sy-rc-theme),0.2);--syntax-light-text:#24292f;--syntax-light-meta:#807c87;--syntax-light-comment:#6e7781;--syntax-light-constant:#0550ae;--syntax-light-entity:#268bd2;--syntax-light-property:#8250df;--syntax-light-definition:#24292f;--syntax-light-tag:#085;--syntax-light-builtin:#b58900;--syntax-light-keyword:#cf222e;--syntax-light-exception:#e6212e;--syntax-light-string:#0a3069;--syntax-light-regexp:#e40;--syntax-light-variable:#a4480f;--syntax-light-invalid-illegal-text:#f6f8fa;--syntax-light-invalid-illegal-bg:#82071e;--syntax-light-markup-heading:#0550ae;--syntax-light-markup-italic:#24292f;--syntax-light-markup-bold:#24292f;--syntax-light-markup-deleted-text:#82071e;--syntax-light-markup-deleted-bg:#ffebe9;--syntax-light-markup-inserted-text:#116329;--syntax-light-markup-inserted-bg:#dafbe1;--syntax-light-markup-changed-text:#953800;--syntax-light-markup-changed-bg:#ffd8b5;--syntax-light-markup-ignored-text:#eaeef2;--syntax-light-markup-ignored-bg:#0550ae;--syntax-light-meta-diff-range:#8250df;--syntax-light-special-bg:#dccafa;--syntax-dark-pre-bg:rgba(var(--sy-rc-theme),0.2);--syntax-dark-cap-bg:rgba(var(--sy-rc-theme),0.1);--syntax-dark-highlight-bg:rgba(var(--sy-rc-theme),0.2);--syntax-dark-text:#c9d1d9;--syntax-dark-meta:#6e7781;--syntax-dark-comment:#8b949e;--syntax-dark-constant:#79c0ff;--syntax-dark-entity:#47b0fa;--syntax-dark-property:#d2a8ff;--syntax-dark-definition:#c9d1d9;--syntax-dark-tag:#7ee787;--syntax-dark-builtin:#ffd34c;--syntax-dark-keyword:#ff7b72;--syntax-dark-exception:#da473c;--syntax-dark-string:#a5d6ff;--syntax-dark-regexp:#ef954e;--syntax-dark-variable:#ffa657;--syntax-dark-invalid-illegal-text:#f0f6fc;--syntax-dark-invalid-illegal-bg:#8e1519;--syntax-dark-markup-heading:#1f6feb;--syntax-dark-markup-italic:#c9d1d9;--syntax-dark-markup-bold:#c9d1d9;--syntax-dark-markup-deleted-text:#ffdcd7;--syntax-dark-markup-deleted-bg:#67060c;--syntax-dark-markup-inserted-text:#aff5b4;--syntax-dark-markup-inserted-bg:#033a16;--syntax-dark-markup-changed-text:#ffdfb6;--syntax-dark-markup-changed-bg:#5a1e02;--syntax-dark-markup-ignored-text:#c9d1d9;--syntax-dark-markup-ignored-bg:#1158c7;--syntax-dark-meta-diff-range:#d2a8ff;--syntax-dark-special-bg:#4f425d}:root,html.light{--syntax-pre-bg:var(--syntax-light-pre-bg);--syntax-cap-bg:var(--syntax-light-cap-bg);--syntax-highlight-bg:var(--syntax-light-highlight-bg);--syntax-text:var(--syntax-light-text);--syntax-meta:var(--syntax-light-meta);--syntax-comment:var(--syntax-light-comment);--syntax-constant:var(--syntax-light-constant);--syntax-entity:var(--syntax-light-entity);--syntax-property:var(--syntax-light-property);--syntax-definition:var(--syntax-light-definition);--syntax-tag:var(--syntax-light-tag);--syntax-builtin:var(--syntax-light-builtin);--syntax-keyword:var(--syntax-light-keyword);--syntax-exception:var(--syntax-light-exception);--syntax-string:var(--syntax-light-string);--syntax-regexp:var(--syntax-light-regexp);--syntax-variable:var(--syntax-light-variable);--syntax-invalid-illegal-text:var(--syntax-light-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-light-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-light-markup-heading);--syntax-markup-italic:var(--syntax-light-markup-italic);--syntax-markup-bold:var(--syntax-light-markup-bold);--syntax-markup-deleted-text:var(--syntax-light-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-light-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-light-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-light-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-light-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-light-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-light-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-light-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-light-meta-diff-range);--syntax-special-bg:var(--syntax-light-special-bg)}@media (prefers-color-scheme:dark){:root{--syntax-pre-bg:var(--syntax-dark-pre-bg);--syntax-cap-bg:var(--syntax-dark-cap-bg);--syntax-highlight-bg:var(--syntax-dark-highlight-bg);--syntax-text:var(--syntax-dark-text);--syntax-meta:var(--syntax-dark-meta);--syntax-comment:var(--syntax-dark-comment);--syntax-constant:var(--syntax-dark-constant);--syntax-entity:var(--syntax-dark-entity);--syntax-property:var(--syntax-dark-property);--syntax-definition:var(--syntax-dark-definition);--syntax-tag:var(--syntax-dark-tag);--syntax-builtin:var(--syntax-dark-builtin);--syntax-keyword:var(--syntax-dark-keyword);--syntax-exception:var(--syntax-dark-exception);--syntax-string:var(--syntax-dark-string);--syntax-regexp:var(--syntax-dark-regexp);--syntax-variable:var(--syntax-dark-variable);--syntax-invalid-illegal-text:var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-dark-markup-heading);--syntax-markup-italic:var(--syntax-dark-markup-italic);--syntax-markup-bold:var(--syntax-dark-markup-bold);--syntax-markup-deleted-text:var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-dark-meta-diff-range);--syntax-special-bg:var(--syntax-dark-special-bg)}}html.dark{--syntax-pre-bg:var(--syntax-dark-pre-bg);--syntax-cap-bg:var(--syntax-dark-cap-bg);--syntax-highlight-bg:var(--syntax-dark-highlight-bg);--syntax-text:var(--syntax-dark-text);--syntax-meta:var(--syntax-dark-meta);--syntax-comment:var(--syntax-dark-comment);--syntax-constant:var(--syntax-dark-constant);--syntax-entity:var(--syntax-dark-entity);--syntax-property:var(--syntax-dark-property);--syntax-definition:var(--syntax-dark-definition);--syntax-tag:var(--syntax-dark-tag);--syntax-builtin:var(--syntax-dark-builtin);--syntax-keyword:var(--syntax-dark-keyword);--syntax-exception:var(--syntax-dark-exception);--syntax-string:var(--syntax-dark-string);--syntax-regexp:var(--syntax-dark-regexp);--syntax-variable:var(--syntax-dark-variable);--syntax-invalid-illegal-text:var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-dark-markup-heading);--syntax-markup-italic:var(--syntax-dark-markup-italic);--syntax-markup-bold:var(--syntax-dark-markup-bold);--syntax-markup-deleted-text:var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-dark-meta-diff-range);--syntax-special-bg:var(--syntax-dark-special-bg)}.dark-code{--syntax-pre-bg:#2c283b;--syntax-cap-bg:#342f47;--syntax-highlight-bg:#423551;--syntax-text:var(--syntax-dark-text);--syntax-meta:var(--syntax-dark-meta);--syntax-comment:var(--syntax-dark-comment);--syntax-constant:var(--syntax-dark-constant);--syntax-entity:var(--syntax-dark-entity);--syntax-property:var(--syntax-dark-property);--syntax-definition:var(--syntax-dark-definition);--syntax-tag:var(--syntax-dark-tag);--syntax-builtin:var(--syntax-dark-builtin);--syntax-keyword:var(--syntax-dark-keyword);--syntax-exception:var(--syntax-dark-exception);--syntax-string:var(--syntax-dark-string);--syntax-regexp:var(--syntax-dark-regexp);--syntax-variable:var(--syntax-dark-variable);--syntax-invalid-illegal-text:var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-dark-markup-heading);--syntax-markup-italic:var(--syntax-dark-markup-italic);--syntax-markup-bold:var(--syntax-dark-markup-bold);--syntax-markup-deleted-text:var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-dark-meta-diff-range);--syntax-special-bg:var(--syntax-dark-special-bg)}.sy-lside{--height:42px}.sy-lside-bottom{position:sticky;bottom:0;padding:0;border-top:1px solid var(--sy-c-divider);background-color:var(--sy-c-bg);--tw-shadow:0 -12px 16px var(--sy-c-bg);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.sy-lside .rst-versions{position:static;width:100%;background-color:var(--sy-c-bg-weak);font-family:var(--sy-f-text)}.sy-lside .rst-versions a{color:var(--sy-c-link)}.sy-lside .rst-versions .rst-current-version{background-color:var(--sy-c-bg);color:var(--sy-c-text);padding:0 1rem;height:var(--height);line-height:var(--height)}.sy-lside .rst-versions.rst-badge .rst-current-version{text-align:left;font-size:.94rem;padding:0 1rem;height:var(--height);line-height:var(--height)}.sy-lside .rst-versions .rst-current-version .fa{color:var(--sy-c-text)}.sy-lside .rst-versions.rst-badge.shift-up .rst-current-version{text-align:left}.sy-lside .rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:none}.sy-lside .rst-other-versions{font-size:.86rem;border-top:1px solid var(--sy-c-divider)}.sy-lside .rst-other-versions dt{font-size:.68rem;font-weight:500;padding:4px 6px;color:var(--sy-c-text-weak)}.sy-lside .rst-versions .rst-other-versions dd a{color:var(--sy-c-text)}.sy-lside .rst-versions .rst-other-versions dd a:hover{text-decoration:underline;color:var(--sy-c-link)}.sy-lside .rst-versions input{width:100%;padding:6px 12px;font-size:.92rem;font-family:var(--sy-f-text);border-radius:6px;outline:0;background:var(--sy-c-bg);border:1px solid var(--sy-c-border)}.sy-lside .rst-versions .rst-other-versions hr{border-color:var(--sy-c-divider)}@media (min-width:90rem){.sy-lside .rst-versions{background:var(--sy-c-bg)}}.yue button.copybtn{align-items:center;justify-content:center;background-color:initial;border:none;color:var(--syntax-text)}.yue button.copybtn>svg{width:1.4rem;height:1.4rem}.yue .highlight button.copybtn:hover{background-color:initial;color:var(--syntax-meta)}.yue .o-tooltip--left:after{background-color:initial;color:var(--syntax-text)}.yue{--sd-color-primary:rgb(var(--sy-rc-theme));--sd-color-success:#00c850;--sd-color-warning:#ff9100;--sd-color-danger:#ff5c2f;--sd-color-card-border-hover:var(--sy-c-border);--sd-color-card-border:var(--sy-c-divider);--sd-color-tabs-label-inactive:var(--sy-c-bold);--sd-color-tabs-label-active:var(--sd-color-primary);--sd-color-tabs-underline-active:var(--sd-color-primary)}.light .yue{--sd-color-shadow:#f3f4f6}.dark .yue{--sd-color-shadow:#010409}.yue .sd-container-fluid{margin-top:2rem;padding:.5rem}.yue .sd-row{--sd-gutter-x:1rem;--sd-gutter-y:1rem}.yue .sd-row-cols-1{display:grid;grid-template-columns:1fr;grid-gap:1rem}.yue .sd-row-cols-2{display:grid;grid-template-columns:1fr 1fr;grid-gap:1rem}.yue .sd-row-cols-1>.sd-col,.yue .sd-row-cols-2>.sd-col{width:100%;padding:0;margin:0}.yue .sd-card-hover:hover{transform:scale(1)}.yue .sd-card-hover:hover .sd-card-title{color:var(--sy-c-link)}.yue .sd-card a,.yue .sd-card a:hover{border-bottom:0}@media (max-width:880px){.yue .sd-row-cols-2{grid-template-columns:1fr}}.yue .sd-tab-set>label{padding:1rem .25rem .5rem;font-size:.84rem;font-weight:500}.yue .sd-tab-set>label~label{margin-left:1rem}.yue .sd-tab-content{padding:0;box-shadow:0 -.0625rem var(--sy-c-divider)}.light .sd-tab-content .highlight{--syntax-pre-bg:var(--syntax-light-pre-bg);--syntax-cap-bg:var(--syntax-light-cap-bg);--syntax-text:var(--syntax-light-text);--syntax-meta:var(--syntax-light-meta);--syntax-comment:var(--syntax-light-comment);--syntax-constant:var(--syntax-light-constant);--syntax-entity:var(--syntax-light-entity);--syntax-property:var(--syntax-light-property);--syntax-definition:var(--syntax-light-definition);--syntax-tag:var(--syntax-light-tag);--syntax-builtin:var(--syntax-light-builtin);--syntax-keyword:var(--syntax-light-keyword);--syntax-exception:var(--syntax-light-exception);--syntax-string:var(--syntax-light-string);--syntax-regexp:var(--syntax-light-regexp);--syntax-variable:var(--syntax-light-variable);--syntax-invalid-illegal-text:var(--syntax-light-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-light-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-light-markup-heading);--syntax-markup-italic:var(--syntax-light-markup-italic);--syntax-markup-bold:var(--syntax-light-markup-bold);--syntax-markup-deleted-text:var(--syntax-light-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-light-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-light-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-light-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-light-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-light-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-light-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-light-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-light-meta-diff-range);--syntax-highlight-bg:var(--syntax-light-highlight-bg);--syntax-special-bg:var(--syntax-light-special-bg)}.yue .sd-tab-content .highlight pre{border-radius:0}@media (print){.yue .sd-card{page-break-inside:avoid}}.yue a.sd-text-wrap{border-bottom:0}.sphinx-tabs [role=tablist]{border-color:var(--sy-c-divider)}.yue .sphinx-tabs-tab{color:var(--sy-c-text);line-height:inherit;padding:1rem .25rem .5rem;font-size:.84rem;font-weight:500;border:none;border-bottom:.125rem solid #0000}.yue .sphinx-tabs-tab:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.yue .sphinx-tabs-tab[aria-selected=true]{border:none;border-bottom:.125rem solid var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active);background-color:initial}.yue .sphinx-tabs-tab+.sphinx-tabs-tab{margin-left:1rem}.yue .sphinx-tabs-panel{border:none;padding:0;margin:0;border-radius:0;background-color:initial}.yue .sphinx-tabs-panel.code-tab{padding:0}.yue .sphinx-tabs-panel.code-tab .highlight pre{border-radius:0}.yue .jupyter_container{background-color:var(--sy-c-bg);border:3px solid var(--sy-c-border);border-radius:6px;overflow:hidden;box-shadow:none}.document .yue .jupyter_container div[class^=highlight]{padding:0}.yue .jupyter_container div.cell_input{background-color:var(--syntax-pre-bg);border:0;border-radius:0}.yue .jupyter_container div.code_cell pre{padding:0}.jupyter_container div.cell_output>.output,.jupyter_container div.cell_output>.stderr,.jupyter_container div.cell_output>.thebelab-output,.jupyter_container div.cell_output>.widget-subarea{padding:.5rem}.jupyter_container div.code_cell .highlight>pre{padding:1rem}.jupyter_container div.code_cell .highlight .hll{margin-left:-1rem;margin-right:-1rem;padding:0 1rem}.jupyter_container div.code_cell .highlight .linenos{margin-right:.8rem}.yue .jupyter_container .stderr{background-color:var(--stderr-bg)}html.light .stderr{--stderr-bg:#ff8d8d}html.dark .stderr{--stderr-bg:#e02323}html.light .jupyter_container .cell_output{--syntax-pre-bg:var(--syntax-light-pre-bg);--syntax-cap-bg:var(--syntax-light-cap-bg);--syntax-text:var(--syntax-light-text);--syntax-meta:var(--syntax-light-meta);--syntax-comment:var(--syntax-light-comment);--syntax-constant:var(--syntax-light-constant);--syntax-entity:var(--syntax-light-entity);--syntax-property:var(--syntax-light-property);--syntax-definition:var(--syntax-light-definition);--syntax-tag:var(--syntax-light-tag);--syntax-builtin:var(--syntax-light-builtin);--syntax-keyword:var(--syntax-light-keyword);--syntax-exception:var(--syntax-light-exception);--syntax-string:var(--syntax-light-string);--syntax-regexp:var(--syntax-light-regexp);--syntax-variable:var(--syntax-light-variable);--syntax-invalid-illegal-text:var(--syntax-light-invalid-illegal-text);--syntax-invalid-illegal-bg:var(--syntax-light-invalid-illegal-bg);--syntax-markup-heading:var(--syntax-light-markup-heading);--syntax-markup-italic:var(--syntax-light-markup-italic);--syntax-markup-bold:var(--syntax-light-markup-bold);--syntax-markup-deleted-text:var(--syntax-light-markup-deleted-text);--syntax-markup-deleted-bg:var(--syntax-light-markup-deleted-bg);--syntax-markup-inserted-text:var(--syntax-light-markup-inserted-text);--syntax-markup-inserted-bg:var(--syntax-light-markup-inserted-bg);--syntax-markup-changed-text:var(--syntax-light-markup-changed-text);--syntax-markup-changed-bg:var(--syntax-light-markup-changed-bg);--syntax-markup-ignored-text:var(--syntax-light-markup-ignored-text);--syntax-markup-ignored-bg:var(--syntax-light-markup-ignored-bg);--syntax-meta-diff-range:var(--syntax-light-meta-diff-range);--syntax-highlight-bg:var(--syntax-light-highlight-bg);--syntax-special-bg:var(--syntax-light-special-bg)}.nbinput .highlight{--radius:1px}.yue div.nblast.container{padding-top:5px}.yue div.nbinput.container div.input_area{border-color:var(--sy-c-border)}.yue div.nboutput.container div.output_area.stderr{background-color:var(--stderr-bg)}.yue div.nboutput.container div.output_area>.math-wrapper>div.math{padding-top:0}@media print{.print\:hidden{display:none}.print\:pt-6{padding-top:1.5rem}}@media not all and (min-width:640px){.max-sm\:max-w-full{max-width:100%}}@media (min-width:768px){.md\:sticky{position:sticky}.md\:inline{display:inline}.md\:flex{display:flex}.md\:hidden{display:none}.md\:w-72{width:18rem}.md\:shrink-0{flex-shrink:0}}@media (min-width:1280px){.xl\:sticky{position:sticky}.xl\:top-16{top:4rem}.xl\:hidden{display:none}.xl\:px-12{padding-left:3rem;padding-right:3rem}.xl\:pl-0{padding-left:0}} \ No newline at end of file diff --git a/_static/shibuya.js b/_static/shibuya.js new file mode 100644 index 00000000..fce65719 --- /dev/null +++ b/_static/shibuya.js @@ -0,0 +1 @@ +(()=>{function y(t){let e=t.getAttribute("aria-controls"),s=document.getElementById(e),c="data-expanded-"+e;t.addEventListener("click",function(){document.body.hasAttribute(c)?(document.body.removeAttribute(c),s.classList.remove("_expanded"),m(e,"false")):(document.body.setAttribute(c,"true"),s.classList.add("_expanded"),m(e,"true"))})}function m(t,e){let s=document.querySelectorAll('[aria-controls="'+t+'"]');for(el of s)el.setAttribute("aria-expanded",e)}var f=document.querySelectorAll(".js-menu");for(let t=0;t{r.parentNode.removeChild(r),document.head.removeChild(t)}),e(),window.addEventListener("resize",e)}var L;var v=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches,d=document.documentElement;function A(){let t=d.classList.contains("dark"),e=t?"dark":"light";d.classList.remove(e);let s=t?"light":"dark";h(s),sessionStorage._theme=s}var i=document.querySelector(".js-theme");function h(t){d.classList.add(t);let e=i.getAttribute("data-aria-"+t);i.setAttribute("aria-label",e)}if(i){let t=v?"dark":"light",e=sessionStorage._theme||t;h(e),i.addEventListener("click",A)}function x(){let t=document.querySelector(".globaltoc");if(!t)return;let e=parseInt(t.getAttribute("data-expand-depth"),10),s=n=>{if(!e)return!1;let o=0;for(;n.parentNode&&n.parentNode!==t;)n=n.parentNode,n.nodeName==="UL"&&(o+=1);return e>=o};t.querySelectorAll("li > ul").forEach(n=>{let o=n.parentNode;o.classList.contains("current")||s(o)?o.classList.add("_expand"):o.classList.add("_collapse");let a=_(n);o.appendChild(a)})}function _(t){let e=document.createElement("button");e.innerHTML='';let s=t.parentNode,c=t.previousSibling,n=c.textContent,o=()=>{s.classList.contains("_expand")?e.setAttribute("arial-label","Collapse "+n):e.setAttribute("arial-label","Expand "+n)};o();let a=g=>{g.preventDefault(),s.classList.contains("_expand")?(s.classList.remove("_expand"),s.classList.add("_collapse")):(s.classList.remove("_collapse"),s.classList.add("_expand")),o()};return c.getAttribute("href")==="#"&&c.addEventListener("click",a),e.addEventListener("click",a),e}x();function b(){let t='.localtoc a[href="'+location.hash+'"]',e=document.querySelector(t);e&&(document.querySelectorAll(".localtoc li").forEach(c=>{c.classList.remove("active")}),e.parentNode.classList.add("active"))}b();window.addEventListener("hashchange",()=>{b()},!1);var l=document.querySelector(".js-repo-stats");async function w(t,e){let s=`https://api.github.com/repos/${t}/${e}`,n=await(await fetch(s)).json(),o={stars:n.watchers,forks:n.forks};u(o),sessionStorage.setItem("_sy/repo/stats",JSON.stringify(o))}async function E(t,e){let s="https://gitlab.com/api/v4/projects/"+encodeURIComponent(t+"/"+e),n=await(await fetch(s)).json(),o={stars:n.star_count,forks:n.forks_count};u(o),sessionStorage.setItem("_sy/repo/stats",JSON.stringify(o))}function u({stars:t,forks:e}){t&&(document.querySelector(".js-repo-stars").textContent=t),e&&(document.querySelector(".js-repo-forks").textContent=e)}function k(){let t=sessionStorage.getItem("_sy/repo/stats");if(t)u(JSON.parse(t));else{let e=l.getAttribute("data-user"),s=l.getAttribute("data-repo"),c=l.getAttribute("data-type");c==="github"?w(e,s):c==="gitlab"&&E(e,s)}}l&&k();function q(t,e){let s=document.createElement("script");s.id="_carbonads_js",s.src=`//cdn.carbonads.com/carbon.js?serve=${t}&placement=${e}`;let c=document.querySelector(".yue > section"),n=document.querySelector(".yue > section > section");if(n)c.insertBefore(s,n);else{let o=document.querySelector(".yue > section > p");o?c.insertBefore(s,o.nextSibling):c.appendChild(s)}}var p=document.querySelector(".js-carbon");if(p){let t=p.getAttribute("data-carbon-code"),e=p.getAttribute("data-carbon-placement");t&&e&&q(t,e)}/windows/i.test(navigator.userAgent)&&document.body.classList.add("win");})(); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 00000000..aae669d7 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,144 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '

" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(SphinxHighlight.highlightSearchWords); +_ready(SphinxHighlight.initEscapeListener); diff --git a/architecture.html b/architecture.html new file mode 100644 index 00000000..9145e6e1 --- /dev/null +++ b/architecture.html @@ -0,0 +1,321 @@ + + + + + + Arroyo Architecture - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Arroyo Architecture

+

Arroyo is a set of high level abstractions to interact with Kafka. +These are meant to help the developer in writing performant consumers with +specific delivery guarantees.

+

Common problems addressed by Arroyo are guaranteeing at-least-once delivery, +providing a dead letter queue abstraction, support parallel (multi-processing) +message processing, etc.

+

The library is divided into three layers: the basic Kafka connectivity, the +streaming engine and the high level abstractions.

+

The basic connectivity layer is a simple wrapper around the Confluent python +library, which is itself based on librdkafka. Besides some cosmetic changes, +this level provides a Fake in memory broker and consumer to make unit test quick +to run.

+

The streaming engine provides an asynchronous processing interface to write +consumers. The consumer is written as a pipeline where each segment is an +asynchronous operation. The streaming engine implements the main consumer loop +and delegates the processing to the pipeline.

+

On top of the streaming engine, the library provides high-level abstractions that +are common when writing Kafka consumers like: map, reduce, filter together +with some common messaging application patterns like the dead letter queue.

+
+

Streaming Interface and Streaming Engine

+

A Kafka consumer is built as a pipeline where each segment processes messages in +an asynchronous way. The Streaming engine provides a message to a segment. The +segment is not supposed to execute small CPU work in a blocking way or do IO in a +non-blocking way. We generally use futures for this, and heavier CPU work in a +separate process.

+

Arroyo provides an interface to implement to write a pipeline segment. +The segment interface is called ProcessingStrategy and is in +this module. +(TODO: bring the docstrings to the docs and reference that).

+

In most cases, when developing a consumer, the developer would not implement +that interface directly. A higher level abstraction would be used.

+
+_images/arroyo_processing.png +
+

The main consumer loop is managed by the stream engine. +These are the phases:

+
    +
  • Poll from the Kafka consumer through the basic library. If a message is there +proceed or repeat.

  • +
  • Submit the message to the first ProcessingStrategy. This is supposed to deliver +work for the strategy to do. It is not supposed to be a blocking operation. The +strategy should return immediately.

  • +
  • Poll the strategy to execute work or to forward results to the following step +in the pipeline. Ideally all IO should be done in separate threads and heavy cpu +work should be done in separate processes so the poll method should check for +completed work, dispatch to the next step and return. In practice, work is executed +here in a blocking way if the overhead of offloading the work is too high.

  • +
+

The ProcessingStrategy may decide not to take the message and instead apply back-pressure. +This is done by raising the MessageRejected exception. In this case, the streaming +engine pauses the consumer till the strategy is ready to accept the message.

+

The ProcessingStrategy decides when it is time to commit a message. This is done +through a commit callback provided to the strategy when it is instantiated.

+

The streaming engine orchestrates the life cycle of the ProcessingStrategy, thus +when it thinks it is time to shut the strategy down it would wait for all in-flight +work to be completed and then destroy the strategy.

+

There are two scenarios where this can happen:

+
    +
  • The consumer is being terminated.

  • +
  • A rebalancing happened. A rebalancing revokes partitions and assigns new ones. +After a rebalancing is complete it is impossible to commit a message from a partition +that was revoked. In order to ensure the consumer behaves in a consistent way, +upon rebalancing, the streaming engine destroys the strategy and builds a new one. +This allows the strategy to complete all in-flight work before being terminated.

  • +
+
+
+

High level strategies

+

Most consumers follow the same few patterns, so Arroyo provides abstractions that +are based on the ProcessingStrategy but are simpler to implement for the common +use cases.

+

Common examples are:

+
    +
  • run task, run task in threads, run task with multiprocessing. The run task +set of strategies are designed to be the most flexible and simple to use. They take +a function provided by the user and execute it on every message, passing the output +to the next step. The library includes synchronous and asynchronous versions depending +on the kind of concurrency required by the user.

  • +
  • filter, map and forward. This type of consumer inspects a message, decides +whether to process it or discard it, transforms its content, and produces the result +on a new topic. In this case, Arroyo provides three implementations of the +ProcessingStrategy: filter, transform, and produce. The developer only needs +to wire them together and provide the map and filtering logic.

  • +
  • consume, apply side effects, produce. This is a variation of the one above. +In this case, the transform operation can have side-effects like storing the content +of the message somewhere.

  • +
  • high throughput cpu intensive transform. The python GIL does not allow CPU intensive +work to take advantage of parallelism. Arroyo provides an implementation of the map +pattern that batches messages and dispatches the work to separate processes via shared +memory. This is largely transparent to the developers.

  • +
  • map, reduce and store. The reduce function is carried out by the Collector, which +batches messages and executes some logic with side-effects when the batch is full. +This is a typical way to write messages on a storages in batches to reduce the +round trips.

  • +
+

All strategies included with Arroyo are in the strategies module.

+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/backpressure.html b/backpressure.html new file mode 100644 index 00000000..d77c30a6 --- /dev/null +++ b/backpressure.html @@ -0,0 +1,249 @@ + + + + + + Backpressure - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Backpressure

+

Arroyo’s own processing strategies internally apply backpressure by raising +MessageRejected. Most +consumers do not require additional work to deal with backpressure correctly.

+

If you want to slow down the consumer based on some external signal or +condition, you can achieve that most effectively by raising the same exception +from within a callback passed to RunTask while the +consumer is supposed to be paused

+
class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]):
+    def __init__(self):
+        self.is_paused = False
+
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]:
+            if self.is_paused:
+                raise MessageRejected()
+
+            print(f"MSG: {message.payload}")
+            return message
+
+        return RunTask(handle_message, CommitOffsets(commit))
+
+
+

It is not recommended to apply backpressure by just sleep()-ing in +submit (or, in this example, +handle_message) for more than a few milliseconds. While this definitely +pauses the consumer, it will block the main thread for too long and and prevent +things like consumer rebalancing from occuring.

+

A 0.01 second sleep is applied each time MessageRejected is +raised to prevent the main thread spinning at 100% CPU. However background thread +performance may be impacted during this time.

+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dlqs.html b/dlqs.html new file mode 100644 index 00000000..93d88c8f --- /dev/null +++ b/dlqs.html @@ -0,0 +1,283 @@ + + + + + + Dead letter queues - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Dead letter queues

+
+

Warning

+

Dead letter queues should be used with caution as they break some of the ordering guarantees +otherwise offered by Arroyo and Kafka consumer code. In particular, it must be safe for the +consumer to drop a message. If replaying or later re-processing of the DLQ’ed messages is done, +it is critical that ordering is not a requirement in the relevant downstream code.

+
+

Arroyo provides support for routing invalid messages to dead letter queues in consumers. +Dead letter queues are critical in some applications because messages are ordered in Kafka +and a single invalid message can cause a consumer to crash and every subsequent message to +not be processed.

+

The dead letter queue configuration is passed to the StreamProcessor and, if provided, any +InvalidMessage raise by a strategy will be produced to the dead letter queue.

+
+
+class arroyo.dlq.DlqLimit(max_invalid_ratio: float | None = None, max_consecutive_count: int | None = None)
+

Defines any limits that should be placed on the number of messages that are +forwarded to the DLQ. This exists to prevent 100% of messages from going into +the DLQ if something is misconfigured or bad code is deployed. In this scenario, +it may be preferable to stop processing messages altogether and deploy a fix +rather than rerouting every message to the DLQ.

+

The ratio and max_consecutive_count are counted on a per-partition basis.

+
+ +
+
+class arroyo.dlq.DlqPolicy(producer: DlqProducer[TStrategyPayload], limit: DlqLimit | None = None, max_buffered_messages_per_partition: int | None = None)
+

DLQ policy defines the DLQ configuration, and is passed to the stream processor +upon creation of the consumer. It consists of the DLQ producer implementation and +any limits that should be applied.

+
+ +
+
+exception arroyo.dlq.InvalidMessage(partition: Partition, offset: int, needs_commit: bool = True)
+

InvalidMessage should be raised if a message is not valid for processing and +should not be retried. It will be placed a DLQ if one is configured.

+

It can be raised from the submit, poll or join methods of any processing strategy.

+

Once a filtered message is forwarded to the next step, needs_commit should be set to False, +in order to prevent multiple filtered messages from being forwarded for a single invalid message.

+
+ +
+
+class arroyo.dlq.KafkaDlqProducer(producer: Producer[KafkaPayload], topic: Topic)
+

KafkaDLQProducer forwards invalid messages to a Kafka topic

+

Two additional fields are added to the headers of the Kafka message +“original_partition”: The partition of the original message +“original_offset”: The offset of the original message

+
+ +
+
+class arroyo.dlq.NoopDlqProducer(*args, **kwds)
+

Drops all invalid messages

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html new file mode 100644 index 00000000..82cffd75 --- /dev/null +++ b/genindex.html @@ -0,0 +1,551 @@ + + + + + + Index - Arroyo documentation + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+
+ + +

Index

+ +
+ A + | B + | C + | D + | F + | G + | H + | I + | J + | K + | M + | N + | O + | P + | R + | S + | T + | U + | V + +
+

A

+ + + +
    +
  • + arroyo.dlq + +
  • +
  • + arroyo.processing.strategies.abstract + +
  • +
  • + arroyo.processing.strategies.batching + +
  • +
  • + arroyo.processing.strategies.commit + +
  • +
  • + arroyo.processing.strategies.filter + +
  • +
  • + arroyo.processing.strategies.healthcheck + +
  • +
  • + arroyo.processing.strategies.produce + +
  • +
    +
  • + arroyo.processing.strategies.reduce + +
  • +
  • + arroyo.processing.strategies.run_task + +
  • +
  • + arroyo.processing.strategies.run_task_in_threads + +
  • +
  • + arroyo.processing.strategies.run_task_with_multiprocessing + +
  • +
  • + arroyo.processing.strategies.unfold + +
  • +
  • + arroyo.types + +
  • +
  • + arroyo.utils.metrics + +
  • +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

F

+ + + +
+ +

G

+ + +
+ +

H

+ + +
+ +

I

+ + + +
+ +

J

+ + +
+ +

K

+ + +
+ +

M

+ + +
+ +

N

+ + + +
+ +

O

+ + +
+ +

P

+ + + +
+ +

R

+ + + +
+ +

S

+ + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ + + +
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/getstarted.html b/getstarted.html new file mode 100644 index 00000000..9bb4f027 --- /dev/null +++ b/getstarted.html @@ -0,0 +1,427 @@ + + + + + + Getting started with Arroyo - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Getting started with Arroyo

+

This tutorial shows how to create a Kafka consumer with Arroyo from scratch.

+
+

Setup

+

This section explains how to setup Kafka, Zookeeper and install the library

+
+

Kafka and Zookeeper

+

In order to run an arroyo Kafka consumer you will need a working Kafka broker. +If you already have one, you can skip this step. +If you do not have a running Kafka broker, this command will install and start +a Kafka docker container. (It requires Docker to be installed).

+
docker network create arroyo
+
+docker run --rm \
+    -v zookeeper_volume:/var/lib/zookeeper \
+    --env ZOOKEEPER_CLIENT_PORT=2181 \
+    --name=sentry_zookeeper \
+    --network=arroyo \
+    -p 2181:2181 \
+    confluentinc/cp-zookeeper:6.2.0
+
+docker run --rm \
+    -v kafka_volume:/var/lib/kafka \
+    --env KAFKA_ZOOKEEPER_CONNECT=sentry_zookeeper:2181 \
+    --env KAFKA_LISTENERS=INTERNAL://0.0.0.0:9093,EXTERNAL://0.0.0.0:9092 \
+    --env KAFKA_ADVERTISED_LISTENERS=INTERNAL://127.0.0.1:9093,EXTERNAL://127.0.0.1:9092 \
+    --env KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT \
+    --env KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL \
+    --env KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \
+    --env CONFLUENT_SUPPORT_METRICS_ENABLE=false \
+    --env KAFKA_LOG4J_LOGGERS=kafka.cluster=WARN,kafka.controller=WARN,kafka.coordinator=WARN,kafka.log=WARN,kafka.server=WARN,kafka.zookeeper=WARN,state.change.logger=WARN \
+    --env KAFKA_LOG4J_ROOT_LOGLEVEL=WARN \
+    --env KAFKA_TOOLS_LOG4J_LOGLEVEL=WARN \
+    --name=sentry_kafka \
+    --network=arroyo \
+    -p 9092:9092 \
+    confluentinc/cp-kafka:6.2.0
+
+
+

Now you should see Kafka and Zookeeper running with

+
docker ps
+
+
+
+
+

Install Kafkacat

+

This tool will be useful to produce onto and consume from topics.

+
https://docs.confluent.io/platform/current/app-development/kafkacat-usage.html#kcat-formerly-kafkacat-utility
+
+
+
+
+

Development environment

+

You will need to install the library. Most likely in a python venv. So first, create a python virtual +environment. Then you can install arroyo with this.

+
pip install sentry-arroyo
+
+
+
+
+

Create two Kafka topics

+

Our example will consume from one topic and produce the same messages on another topic. So we need +two topics.

+
docker exec sentry_kafka kafka-topics \
+    --create \
+    --topic source-topic \
+    --bootstrap-server 127.0.0.1:9092
+
+docker exec sentry_kafka kafka-topics \
+    --create \
+    --topic dest-topic \
+    --bootstrap-server 127.0.0.1:9092
+
+
+

Now you should be ready to develop with Arroyo.

+
+
+
+

Create a basic consumer

+

Arroyo provides two level of abstractions when writing a consumer: the basic consumer/producer library +and the Streaming library. The first is just a thin wrapper around a librdkafka consumer/producer that +adds some features around offset management. The second provides a more abstract streaming interface +that hides details like rebalancing and the consumer lifecycle.

+
+

Creating a basic consumer

+

This initializes a basic consumer and consumes a message.

+
from arroyo.backends.kafka.configuration import (
+    build_kafka_consumer_configuration,
+)
+from arroyo.backends.kafka.consumer import KafkaConsumer
+from arroyo.types import Topic
+
+TOPIC = Topic("source-topic")
+
+consumer = KafkaConsumer(
+    build_kafka_consumer_configuration(
+        default_config={},
+        bootstrap_servers=["127.0.0.1:9092"],
+        auto_offset_reset="latest",
+        group_id="test-group",
+    )
+)
+
+consumer.subscribe([TOPIC])
+
+while True:
+    msg = consumer.poll(timeout=1.0)
+    if msg is not None:
+        print(f"MSG: {msg.payload}")
+
+
+

Start this script and use kcat to produce a message:

+
echo "MESSAGE" | kcat -P -b 127.0.0.1:9092 -t source-topic
+
+
+

In a while the message should appear on the console:

+
MSG: KafkaPayload(key=None, value=b'MESSAGE', headers=[])
+
+
+
+
+

Create a streaming consumer

+

Add a ProcessingStrategy and ProcessingStrategyFactory. +Here we are using the RunTask strategy which runs a custom function over each message.

+
def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]:
+    print(f"MSG: {message.payload}")
+    return message
+
+class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]):
+    """
+    The factory manages the lifecycle of the `ProcessingStrategy`.
+    A strategy is created every time new partitions are assigned to the
+    consumer, while it is destroyed when partitions are revoked or the
+    consumer is closed
+    """
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        return RunTask(handle_message, CommitOffsets(commit))
+
+
+

The code above is orchestrated by the Arroyo runtime called StreamProcessor.

+
processor = StreamProcessor(
+    consumer=consumer,
+    topic=TOPIC,
+    processor_factory=ConsumerStrategyFactory(),
+)
+
+processor.run()
+
+
+

The main consumer loop is managed by the StreamProcessor no need to periodically poll the +consumer. The ConsumerStrategy works by inversion of control.

+
+
+

Add some useful logic

+

Now we will chain the Produce strategy to produce messages on a second topic after the message is logged

+
class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]):
+    """
+    The factory manages the lifecycle of the `ProcessingStrategy`.
+    A strategy is created every time new partitions are assigned to the
+    consumer, while it is destroyed when partitions are revoked or the
+    consumer is closed
+    """
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        producer = KafkaProducer(
+            build_kafka_configuration(
+                default_config={},
+                bootstrap_servers=BOOTSTRAP_SERVERS,
+            )
+        )
+
+        return RunTask(
+            handle_message,
+            Produce(producer, Topic("dest-topic"), CommitOffsets(commit))
+        )
+
+
+

The message is first passed to the RunTask strategy which simply logs the message and submits +the output to the next step. The Produce strategy produces the message asynchronously. Once +the message is produced, the CommitOffsets strategy commits the offset of the message.

+
+
+
+

Further examples

+

Find some complete examples of usage.

+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..c902b63b --- /dev/null +++ b/index.html @@ -0,0 +1,228 @@ + + + + + + Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+ _images/arroyo-banner.png +

Arroyo is a library to build streaming applications that consume from +and produce to Kafka.

+

It relies on the confluent_kafka python library, which itself relies +on librdkafka.

+

Arroyo provides mainly three functionalities:

+
    +
  • A set of abstractions inspired to common messaging applications patterns.

  • +
  • Some abstractions to simplify offset management and rebalancing.

  • +
  • An in memory broker abstraction to simplify writing unit tests.

  • +
+
+

Contents:

+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/intro.html b/intro.html new file mode 100644 index 00000000..65a54197 --- /dev/null +++ b/intro.html @@ -0,0 +1,205 @@ + + + + + + <no title> - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+ _images/arroyo-banner.png +

Arroyo is a library to build streaming applications that consume from +and produce to Kafka.

+

It relies on the confluent_kafka python library, which itself relies +on librdkafka.

+

Arroyo provides mainly three functionalities:

+
    +
  • A set of abstractions inspired to common messaging applications patterns.

  • +
  • Some abstractions to simplify offset management and rebalancing.

  • +
  • An in memory broker abstraction to simplify writing unit tests.

  • +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/metrics.html b/metrics.html new file mode 100644 index 00000000..56fd91c4 --- /dev/null +++ b/metrics.html @@ -0,0 +1,366 @@ + + + + + + Metrics - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Metrics

+

Arroyo consumers and strategies attempt to auto instrument some metrics that most people find useful +to understand the behavior and performance of their consumers. These metrics are typically sampled or +buffered as appropriate and flushed periodically (often once per second).

+

In order to use these metrics, you must configure a metrics backend that conforms to the metrics protocol +before creating your consumer.

+

This can be done like so:

+
from arroyo.utils.metrics import Metrics, MetricName
+
+ class MyMetrics(Metrics):
+     def increment(
+         self, name: MetricName, value: Union[int, float] = 1, tags: Optional[Tags] = None
+     ) -> None:
+         # Increment a counter by the given value.
+         record_incr(name, value, tags)
+
+     def gauge(
+         self, name: MetricName, value: Union[int, float], tags: Optional[Tags] = None
+     ) -> None:
+         # Sets a gauge metric to the given value.
+         record_gauge(name, value, tags)
+
+     def timing(
+         self, name: MetricName, value: Union[int, float], tags: Optional[Tags] = None
+     ) -> None:
+         # Emit a timing metric with the given value.
+         record_timing(name, value, tags)
+
+ metrics_backend = MyMetrics()
+
+ configure_metrics(metrics_backend)
+
+
+
+

Available Metrics

+
from typing import Literal
+
+MetricName = Literal[
+    # Number of messages in a multiprocessing batch
+    "arroyo.strategies.run_task_with_multiprocessing.batch.size.msg",
+    # Number of bytes in a multiprocessing batch
+    "arroyo.strategies.run_task_with_multiprocessing.batch.size.bytes",
+    # Number of messages in a multiprocessing batch after the message transformation
+    "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.msg",
+    # Number of bytes in a multiprocessing batch after the message transformation
+    "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.bytes",
+    # Number of times the consumer is spinning
+    "arroyo.consumer.run.count",
+    # Number of times the consumer encounted an invalid message.
+    "arroyo.consumer.invalid_message.count",
+    # How long it took the Reduce step to fill up a batch
+    "arroyo.strategies.reduce.batch_time",
+    # Counter, incremented when a strategy after multiprocessing applies
+    # backpressure to multiprocessing. May be a reason why CPU cannot be
+    # saturated.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.backpressure",
+    # Counter, incremented when multiprocessing cannot fill the input batch
+    # because not enough memory was allocated. This results in batches smaller
+    # than configured. Increase `input_block_size` to fix.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow",
+    # Counter, incremented when multiprocessing cannot pull results in batches
+    # equal to the input batch size, because not enough memory was allocated.
+    # This can be devastating for throughput. Increase `output_block_size` to
+    # fix.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow",
+    # Arroyo has decided to re-allocate a block in order to combat input buffer
+    # overflow. This behavior can be disabled by explicitly setting
+    # `input_block_size` to a not-None value in `RunTaskWithMultiprocessing`.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.input.resize",
+    # Arroyo has decided to re-allocate a block in order to combat output buffer
+    # overflow. This behavior can be disabled by explicitly setting
+    # `output_block_size` to a not-None value in `RunTaskWithMultiprocessing`.
+    "arroyo.strategies.run_task_with_multiprocessing.batch.output.resize",
+    # How many batches are being processed in parallel by multiprocessing.
+    "arroyo.strategies.run_task_with_multiprocessing.batches_in_progress",
+    # Counter. A subprocess by multiprocessing unexpectedly died.
+    "sigchld.detected",
+    # Gauge. Shows how many processes the multiprocessing strategy is
+    # configured with.
+    "arroyo.strategies.run_task_with_multiprocessing.processes",
+    # Time (unitless) spent polling librdkafka for new messages.
+    "arroyo.consumer.poll.time",
+    # Time (unitless) spent in strategies (blocking in strategy.submit or
+    # strategy.poll)
+    "arroyo.consumer.processing.time",
+    # Time (unitless) spent pausing the consumer due to backpressure (MessageRejected)
+    "arroyo.consumer.backpressure.time",
+    # Time (unitless) spent in handling `InvalidMessage` exceptions and sending
+    # messages to the the DLQ.
+    "arroyo.consumer.dlq.time",
+    # Time (unitless) spent in waiting for the strategy to exit, such as during
+    # shutdown or rebalancing.
+    "arroyo.consumer.join.time",
+    # Time (unitless) spent in librdkafka callbacks. This metric's timings
+    # overlap other timings, and might spike at the same time.
+    "arroyo.consumer.callback.time",
+    # Time (unitless) spent in shutting down the consumer. This metric's
+    # timings overlap other timings, and might spike at the same time.
+    "arroyo.consumer.shutdown.time",
+    # Queue size of background queue that librdkafka uses to prefetch messages.
+    "arroyo.consumer.librdkafka.total_queue_size",
+    # Counter metric to measure how often the healthcheck file has been touched.
+    "arroyo.processing.strategies.healthcheck.touch",
+    # Number of messages dropped in the FilterStep strategy
+    "arroyo.strategies.filter.dropped_messages",
+]
+
+
+
+
+

API

+
+
+class arroyo.utils.metrics.Metrics(*args, **kwargs)
+

An abstract class that defines the interface for metrics backends.

+
+
+abstract gauge(name: MetricName, value: int | float, tags: Mapping[str, str] | None = None) None
+

Sets a gauge metric to the given value.

+
+ +
+
+abstract increment(name: MetricName, value: int | float = 1, tags: Mapping[str, str] | None = None) None
+

Increments a counter metric by a given value.

+
+ +
+
+abstract timing(name: MetricName, value: int | float, tags: Mapping[str, str] | None = None) None
+

Records a timing metric.

+
+ +
+ +
+
+arroyo.utils.metrics.configure_metrics(metrics: Metrics, force: bool = False) None
+

Metrics can generally only be configured once, unless force is passed +on subsequent initializations.

+
+ +
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..2d626a23faac6c45d982df3e6e6ac062d681adc6 GIT binary patch literal 1299 zcmV+u1?>7GAX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkGa&m8Z zZwezIR%LQ?X>V>iAPOTORA^-&a%F8{X>Md?av*PJAarPHb0B7EY-J#6b0A}HZE$jB zb8}^6Aa!$TZf78RY-wUH3V7PRSkH5uHWa?|S7@d^qzBXH>glwTIOE2Xq}{Qd=D4F3 zZx_Wv!jg!+|9u4#Aa)Tfu-g+Lz3+QJB%bshmQw6RoUmt<@2@kF6b#UB$b73f)fxNA z4qg3>t|HvX#vj=8XPQx6f(XM(p|>99Sa>BECHs@4@AwbQXz~S=!aFD-@Jb-pRPZ6# zC%k>ar6y?%CLmAJ^|uiD6ihA!F?LbDiOMu(O>tIzM|%m{8TCW}s7%Tt>-vLHVV1rlnU{bQHZ zqCsYqoA(PVx;4W>UU-8!B{7j;zSl2Qr|TR`P0Jrf{XZVYDlK#(Ue2-yH&~O@jD?a* zJwGkKG^qFG%Y%kIuq<8r8N7o(<8t=lUt})-SH3xKT!_eOGkez1&aTCFt3a!1D`~Ou zP4)Q4G6ZbyQ!~oHrA*tCvCnclJI!K;xvd@pA@;dPNmIZ~rz8dP6tdM5nP#vL{Mgmg zWA>4nQU2UsKSFl9>1j6CpjFG=V{3eAwQXQP0cek=WC+I%=Sd*dEgT`XYTl8t9-z#Bi*Mf zt!@oj!8C0JM_ug$&2+k#%DMl|%zZgFZ72|7%SKHq_*SqaeNS0V*79JjCEXOJ(wRln)DdUlTC(&W(Rmg>)-(g9ahA{Y?WVcl zPTWKG8VJd%4ah_WuTwM+xqR=|M2lASfMjj5po`5iz6Cp^rub1Oh#5O$<^MGk7pTF; zmDExTVl8q?X0kli*oi(=xR~Q?ZUE)at{khsRp7A z#;j3tod|-i-Xedzl1A?;edf_lL>o+=a%ob>0oot8==a`8RCe5b@umZhKA1~9VxY@L z#B%`!sAvb=ri2o}@CH~3sYfmBu6#9;+8k`MY@U1M?WmRg%dnThtwqZ_vvV$L6*;h{ z<3@08R#jaaDJ?};$_!Yk-?>001u^&|s#m}h^uv$bVn=32_c)mEuj&aWZhr^ss_X3d z+0m?y|} z<)UCqE5O&&_i~|V!f@1f3Q&1HDP(UhQGe?vfIn;wA+Mj*vEpdY^=3-c_Mp*2BM=>T zcmhm*{|C8NQFPSH2!Opt2XY;pH@Bv4`z7irLPH#W3j&!E7nL<`G+fS)a2*!@4Xybj zk?S2qr`E}1x`MTJtF=lc2PJ!SRP6>7d8IJ2HFNZmV!hsq&K9l5tl&5Eg{Z2Nvl;(0 J`VU6C4^6PUdvyQ+ literal 0 HcmV?d00001 diff --git a/offsets.html b/offsets.html new file mode 100644 index 00000000..58aec6c0 --- /dev/null +++ b/offsets.html @@ -0,0 +1,243 @@ + + + + + + Committing offsets - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Committing offsets

+

Arroyo does not auto commit offsets. It is up to you to manually commit offsets when processing for that +message is completed.

+

The commit callback will be passed to processing strategy via ProcessingStrategyFactory.create_with_partitions. +You should pass this to the strategy and have your strategy call this commit function once the rest of the message +processing has been done.

+

The offset to be committed in Kafka is always the next offset to be consumed from, i.e. message’s offset + 1. +In Arroyo, this means you should commit Message.next_offset and never Message.offset when done processing +that message. Arroyo exposes Message.position_to_commit to make this easier.

+

It is not safe to commit every offset in a high throughput consumer as this will add a lot of load to the system. +Commits should generally be throttled. CommitPolicy is the Arroyo way of specifying commit frequency. A CommitPolicy +must be passed to the stream processor, which allows specifying a minimum commit frequency (or messages between commits). +Commit throttling can be skipped when needed (i.e. during consumer shutdown) by passing force=True to the commit callback. +If you are not sure how often to commit, ONCE_PER_SECOND is a reasonable option.

+

The easiest way is to use the CommitOffsets strategy as the last step in a chain of processing strategies to commit offsets.

+
class MyConsumerFactoryFactory(ProcessingStrategyFactory[KafkaPayload]):
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        def my_processing_function(message: Message[KafkaPayload]) -> None:
+            # do something (synchronous) with the message
+            do_something()
+
+
+        return RunTask(my_processing_function, CommitOffsets(commit))
+
+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/py-modindex.html b/py-modindex.html new file mode 100644 index 00000000..8003e264 --- /dev/null +++ b/py-modindex.html @@ -0,0 +1,210 @@ + + + + + + Python Module Index - Arroyo documentation + + + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+
+ + +

Python Module Index

+ +
+ a +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ a
+ arroyo +
    + arroyo.dlq +
    + arroyo.processing.strategies.abstract +
    + arroyo.processing.strategies.batching +
    + arroyo.processing.strategies.commit +
    + arroyo.processing.strategies.filter +
    + arroyo.processing.strategies.healthcheck +
    + arroyo.processing.strategies.produce +
    + arroyo.processing.strategies.reduce +
    + arroyo.processing.strategies.run_task +
    + arroyo.processing.strategies.run_task_in_threads +
    + arroyo.processing.strategies.run_task_with_multiprocessing +
    + arroyo.processing.strategies.unfold +
    + arroyo.types +
    + arroyo.utils.metrics +
+ + +
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 00000000..a5d5b730 --- /dev/null +++ b/search.html @@ -0,0 +1,154 @@ + + + + + + Search - Arroyo documentation + + + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + +
+

+ + + +
+ +
+ + +
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 00000000..064acf7e --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["architecture", "backpressure", "dlqs", "getstarted", "index", "intro", "metrics", "offsets", "strategies/batching", "strategies/commit_offsets", "strategies/filter", "strategies/healthcheck", "strategies/index", "strategies/produce", "strategies/reduce", "strategies/run_task", "strategies/run_task_in_threads", "strategies/run_task_with_multiprocessing", "strategies/unfold", "what_for"], "filenames": ["architecture.rst", "backpressure.rst", "dlqs.rst", "getstarted.rst", "index.rst", "intro.rst", "metrics.rst", "offsets.rst", "strategies/batching.rst", "strategies/commit_offsets.rst", "strategies/filter.rst", "strategies/healthcheck.rst", "strategies/index.rst", "strategies/produce.rst", "strategies/reduce.rst", "strategies/run_task.rst", "strategies/run_task_in_threads.rst", "strategies/run_task_with_multiprocessing.rst", "strategies/unfold.rst", "what_for.rst"], "titles": ["Arroyo Architecture", "Backpressure", "Dead letter queues", "Getting started with Arroyo", "Contents:", "<no title>", "Metrics", "Committing offsets", "Batch and Unbatch", "Commit offsets", "Filter", "Healthchecks", "Processing Strategies", "Produce", "Reduce (Fold)", "Run Task", "Run Task in Threads", "Run Task with Multiprocessing", "Unfold", "What is Arroyo for?"], "terms": {"i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "set": [0, 2, 4, 5, 6, 11, 17], "abstract": [0, 3, 4, 5, 6, 12, 19], "interact": 0, "kafka": [0, 2, 4, 5, 7, 11, 12, 13], "These": [0, 6], "ar": [0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19], "meant": 0, "help": [0, 19], "develop": 0, "write": [0, 3, 4, 5, 12, 19], "perform": [0, 1, 6, 12, 17, 19], "consum": [0, 1, 2, 4, 5, 6, 7, 10, 11, 12, 13], "specif": 0, "deliveri": 0, "guarante": [0, 2], "common": [0, 4, 5], "problem": 0, "address": 0, "least": [0, 17], "onc": [0, 2, 3, 6, 7, 9, 11, 12, 14, 16, 17, 19], "provid": [0, 2, 3, 4, 5, 8, 12, 15, 18], "dead": [0, 4, 15], "letter": [0, 4, 15], "queue": [0, 4, 6, 15, 19], "support": [0, 2, 11], "parallel": [0, 6, 16, 17], "multi": 0, "process": [0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 18, 19], "messag": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19], "etc": [0, 12], "The": [0, 2, 3, 7, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19], "librari": [0, 3, 4, 5, 19], "divid": [0, 19], "three": [0, 4, 5], "layer": 0, "basic": [0, 10, 15], "connect": 0, "simpl": 0, "wrapper": [0, 3], "around": [0, 3], "confluent": [0, 3], "python": [0, 3, 4, 5, 17], "which": [0, 3, 4, 5, 7, 8, 13, 16, 19], "itself": [0, 4, 5, 13], "base": [0, 1, 8, 12, 14, 18], "librdkafka": [0, 3, 4, 5, 6], "besid": 0, "some": [0, 1, 2, 4, 5, 6, 13, 17], "cosmet": 0, "chang": [0, 3], "thi": [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19], "fake": 0, "memori": [0, 4, 5, 6, 17], "broker": [0, 3, 4, 5, 9, 11, 12, 19], "make": [0, 7, 10, 17, 19], "unit": [0, 4, 5], "test": [0, 3, 4, 5, 11, 17, 19], "quick": 0, "run": [0, 3, 6, 11, 12, 14, 19], "an": [0, 3, 4, 5, 6, 13, 16, 17, 19], "asynchron": [0, 3, 12], "written": [0, 12], "pipelin": [0, 11], "where": [0, 13, 17], "each": [0, 1, 3, 12, 13, 14, 16, 17, 19], "segment": 0, "oper": [0, 19], "implement": [0, 2, 12, 18], "main": [0, 1, 3, 11, 17], "loop": [0, 3, 12], "deleg": 0, "On": [0, 13, 16], "top": [0, 19], "when": [0, 3, 6, 7, 8, 12, 17], "like": [0, 1, 3, 6, 11, 17, 19], "map": [0, 1, 3, 6, 7, 11, 12], "reduc": [0, 6, 8, 12, 17, 19], "filter": [0, 2, 6], "togeth": [0, 8, 12, 14], "applic": [0, 2, 4, 5, 12, 17, 19], "pattern": [0, 4, 5], "A": [0, 1, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 17, 19], "built": [0, 12, 19], "wai": [0, 7, 19], "suppos": [0, 1], "execut": [0, 12], "small": [0, 17], "cpu": [0, 1, 6, 17], "work": [0, 1, 3, 12, 17, 19], "block": [0, 1, 6, 11, 12, 17, 19], "do": [0, 1, 3, 7, 10, 11, 17, 19], "io": [0, 3, 11, 16, 19], "non": 0, "we": [0, 3, 8, 12, 13, 14, 16, 19], "gener": [0, 6, 7, 8, 12, 17, 18], "us": [0, 2, 6, 7, 8, 9, 12, 13, 16, 17, 19], "futur": [0, 13, 16], "heavier": 0, "separ": [0, 19], "call": [0, 3, 7, 8, 11, 12, 18, 19], "processingstrategi": [0, 1, 3, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18], "modul": [0, 17], "todo": [0, 19], "bring": 0, "docstr": 0, "doc": [0, 3, 19], "refer": [0, 13], "In": [0, 2, 3, 6, 7, 17, 19], "most": [0, 1, 3, 6, 11, 12, 17, 19], "case": [0, 13, 17], "would": [0, 8, 11, 19], "directli": 0, "higher": [0, 11, 19], "manag": [0, 3, 4, 5], "phase": 0, "poll": [0, 2, 3, 6, 8, 11, 12, 13, 16, 18, 19], "from": [0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19], "through": 0, "If": [0, 1, 2, 3, 7, 8, 10, 11, 12, 13, 16, 17, 18, 19], "proce": 0, "repeat": 0, "submit": [0, 1, 2, 3, 6, 8, 10, 12, 13, 14, 16, 18], "first": [0, 3, 8, 14, 17], "deliv": 0, "It": [0, 1, 2, 3, 4, 5, 7, 9, 12], "should": [0, 2, 3, 7, 8, 9, 10, 11, 12, 14, 15, 17, 19], "return": [0, 1, 3, 7, 10, 11, 12, 18, 19], "immedi": [0, 12, 19], "forward": [0, 2, 10, 17], "result": [0, 6, 10, 16, 17], "follow": [0, 8, 12, 14, 17, 19], "step": [0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18], "ideal": 0, "all": [0, 2, 8, 9, 12, 17, 19], "done": [0, 2, 6, 7, 12, 16], "thread": [0, 1, 11, 12, 13], "heavi": 0, "so": [0, 3, 6, 8, 10, 11, 12, 14, 17, 19], "method": [0, 2, 8, 12, 13, 14, 16], "check": [0, 12, 13, 16], "complet": [0, 3, 7, 9, 12, 13, 16], "dispatch": 0, "next": [0, 2, 3, 7, 8, 10, 13, 14, 16, 17, 18, 19], "practic": 0, "here": [0, 3, 17, 19], "overhead": 0, "offload": 0, "too": [0, 1, 11, 13, 16, 17], "mai": [0, 1, 2, 6, 10, 12, 17], "decid": [0, 6, 19], "take": [0, 10, 11, 16, 17], "instead": [0, 8, 10, 17], "appli": [0, 1, 2, 6, 13, 17], "back": [0, 9, 17], "pressur": 0, "rais": [0, 1, 2, 12, 13, 15, 16], "messagereject": [0, 1, 6, 8, 12, 13, 14, 16, 18], "except": [0, 1, 2, 6, 8, 12, 13, 14, 16, 18, 19], "paus": [0, 1, 6], "till": 0, "readi": [0, 3, 8, 14], "accept": [0, 12], "time": [0, 1, 3, 6, 8, 10, 11, 12, 14, 17, 19], "commit": [0, 1, 3, 4, 10, 11, 12], "callback": [0, 1, 6, 7, 10], "instanti": [0, 12], "orchestr": [0, 3], "life": 0, "cycl": 0, "thu": [0, 8], "think": 0, "shut": [0, 6, 11, 12], "down": [0, 1, 6, 11, 12, 13, 16], "wait": [0, 6, 17], "flight": 0, "destroi": [0, 3], "There": [0, 19], "two": [0, 2, 17], "scenario": [0, 2, 10, 19], "can": [0, 1, 2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17], "happen": [0, 11], "being": [0, 2, 6, 12, 13, 19], "termin": [0, 8, 12, 14], "rebalanc": [0, 1, 3, 4, 5, 6, 12], "revok": [0, 3, 12, 19], "partit": [0, 1, 2, 3, 7, 8, 10, 11, 12, 19], "assign": [0, 3, 12, 19], "new": [0, 3, 6, 8, 14, 17, 19], "ones": [0, 12, 17], "after": [0, 3, 6, 9, 11, 12, 19], "imposs": 0, "wa": [0, 6, 8, 12, 13, 17], "order": [0, 2, 3, 6, 8, 14, 17, 19], "ensur": [0, 9], "behav": 0, "consist": [0, 2], "upon": [0, 2], "build": [0, 4, 5, 12, 19], "one": [0, 2, 3, 8, 13, 14, 18, 19], "allow": [0, 7, 8, 12, 14, 19], "befor": [0, 6, 8, 12, 14, 17], "same": [0, 1, 3, 6, 17], "few": [0, 1, 19], "simpler": 0, "exampl": [0, 1, 12, 19], "task": [0, 12], "multiprocess": [0, 6], "design": [0, 19], "flexibl": [0, 12], "thei": [0, 2, 8, 14, 17], "function": [0, 3, 4, 5, 7, 8, 10, 11, 12, 14, 15, 16, 17, 18], "user": [0, 16, 18, 19], "everi": [0, 2, 3, 7, 10, 19], "pass": [0, 1, 2, 3, 6, 7, 8, 10, 11, 13, 19], "output": [0, 3, 6, 13], "includ": [0, 8], "synchron": [0, 7, 12, 17], "version": 0, "depend": [0, 12], "kind": [0, 11], "concurr": [0, 16], "requir": [0, 1, 2, 3, 8, 19], "type": [0, 3, 6, 10, 12], "inspect": 0, "whether": [0, 8, 14, 19], "discard": [0, 12, 19], "transform": [0, 6, 13, 17], "its": [0, 10, 12, 19], "content": [0, 8], "produc": [0, 2, 3, 4, 5, 12], "topic": [0, 2, 12, 13], "onli": [0, 6, 9, 10, 19], "need": [0, 3, 7, 10, 12, 17, 19], "wire": [0, 12], "them": [0, 8, 10, 17, 18, 19], "logic": [0, 12, 19], "side": 0, "effect": [0, 1, 17], "variat": 0, "abov": [0, 3], "have": [0, 3, 7, 8, 10, 17, 19], "store": [0, 17], "somewher": 0, "throughput": [0, 6, 7, 17], "intens": 0, "gil": 0, "doe": [0, 7, 8, 19], "advantag": 0, "batch": [0, 6, 12, 14], "via": [0, 7], "share": [0, 17], "larg": [0, 17], "transpar": 0, "carri": [0, 10], "out": [0, 8, 11, 17, 19], "collector": 0, "full": [0, 8, 14], "typic": [0, 6, 13], "storag": 0, "round": 0, "trip": 0, "arroyo": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "": [1, 6, 7, 12, 17], "own": [1, 12], "strategi": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18], "intern": [1, 3, 19], "addit": [1, 2, 19], "deal": [1, 10], "correctli": 1, "you": [1, 3, 6, 7, 8, 10, 11, 12, 17, 19], "want": [1, 8, 11, 17, 19], "slow": [1, 12, 13, 16], "extern": [1, 3], "signal": [1, 19], "condit": [1, 14], "achiev": 1, "within": [1, 19], "runtask": [1, 3, 7, 11, 15], "while": [1, 3, 19], "class": [1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "consumerstrategyfactori": [1, 3, 11], "processingstrategyfactori": [1, 3, 7, 11, 12], "kafkapayload": [1, 2, 3, 7, 11], "def": [1, 3, 6, 7, 11, 19], "__init__": [1, 11], "self": [1, 3, 6, 7, 11], "is_paus": [1, 11], "fals": [1, 2, 3, 6, 10, 11, 19], "create_with_partit": [1, 3, 7, 11, 12], "int": [1, 2, 3, 6, 7, 8, 11, 12, 13, 14, 16, 17], "handle_messag": [1, 3, 11], "print": [1, 3], "f": [1, 3], "msg": [1, 3, 6, 17], "payload": [1, 3, 10, 12, 16], "commitoffset": [1, 3, 7, 9, 11], "recommend": [1, 12], "just": [1, 3, 9, 10, 11], "sleep": 1, "ing": 1, "more": [1, 3, 12, 17, 19], "than": [1, 2, 6, 11, 17], "millisecond": [1, 11], "definit": 1, "long": [1, 6, 11], "prevent": [1, 2], "thing": [1, 17, 19], "occur": [1, 13, 16], "0": [1, 3, 19], "01": 1, "second": [1, 3, 6, 8, 11, 14, 17], "spin": [1, 6], "100": [1, 2, 10], "howev": [1, 11, 17, 19], "background": [1, 6], "impact": [1, 19], "dure": [1, 6, 7, 12], "caution": 2, "break": [2, 17], "otherwis": [2, 19], "offer": 2, "code": [2, 3, 11, 12, 19], "particular": 2, "must": [2, 6, 7, 18], "safe": [2, 7], "drop": [2, 6, 10], "replai": 2, "later": [2, 10, 12], "re": [2, 6, 17, 19], "dlq": [2, 6], "ed": 2, "critic": 2, "relev": 2, "downstream": [2, 8, 10, 14], "rout": 2, "invalid": [2, 6, 15], "becaus": [2, 6, 10, 11, 17], "singl": [2, 12, 13, 18], "caus": [2, 10, 17], "crash": [2, 12], "subsequ": [2, 6, 18], "configur": [2, 3, 6, 17], "streamprocessor": [2, 3, 12], "ani": [2, 12, 17, 19], "invalidmessag": [2, 6, 15], "dlqlimit": 2, "max_invalid_ratio": 2, "float": [2, 6, 8, 12, 14, 17], "none": [2, 3, 6, 7, 8, 10, 12, 14, 17], "max_consecutive_count": 2, "defin": [2, 6, 12], "limit": [2, 17], "place": 2, "number": [2, 6, 8, 12, 19], "exist": 2, "go": 2, "someth": [2, 7, 12, 19], "misconfigur": 2, "bad": [2, 19], "deploi": [2, 19], "prefer": 2, "stop": 2, "altogeth": 2, "fix": [2, 6, 17, 19], "rather": [2, 10, 17], "rerout": 2, "ratio": 2, "count": [2, 6], "per": [2, 6, 8, 11, 17, 19], "basi": 2, "dlqpolici": 2, "dlqproduc": 2, "tstrategypayload": [2, 8, 10, 11, 12, 13, 15, 16, 17], "max_buffered_messages_per_partit": 2, "polici": 2, "stream": [2, 4, 5, 7, 10, 12, 13, 16], "processor": [2, 3, 7, 12, 13, 16], "creation": 2, "offset": [2, 3, 4, 5, 8, 10, 12, 17, 19], "needs_commit": 2, "bool": [2, 6, 10], "true": [2, 3, 7, 19], "valid": 2, "retri": [2, 12], "join": [2, 6, 8, 12, 14], "multipl": [2, 11, 19], "kafkadlqproduc": 2, "field": 2, "ad": [2, 8, 14], "header": [2, 3], "original_partit": 2, "origin": [2, 13, 16], "original_offset": 2, "noopdlqproduc": 2, "arg": [2, 6, 11, 12], "kwd": [2, 12], "tutori": 3, "show": [3, 6, 17], "how": [3, 6, 7, 8, 12, 14], "scratch": 3, "section": [3, 17, 19], "explain": [3, 19], "alreadi": [3, 19], "skip": [3, 7], "command": [3, 11], "docker": 3, "contain": [3, 10, 11, 12, 16], "network": [3, 19], "rm": [3, 11], "v": 3, "zookeeper_volum": 3, "var": 3, "lib": 3, "env": 3, "zookeeper_client_port": 3, "2181": 3, "name": [3, 6, 11, 12], "sentry_zookeep": 3, "p": 3, "confluentinc": 3, "cp": 3, "6": 3, "2": 3, "kafka_volum": 3, "kafka_zookeeper_connect": 3, "kafka_listen": 3, "9093": 3, "9092": [3, 19], "kafka_advertised_listen": 3, "127": 3, "1": [3, 6, 7, 12], "kafka_listener_security_protocol_map": 3, "plaintext": 3, "kafka_inter_broker_listener_nam": 3, "kafka_offsets_topic_replication_factor": 3, "confluent_support_metrics_en": 3, "kafka_log4j_logg": 3, "cluster": 3, "warn": 3, "control": [3, 19], "coordin": 3, "log": [3, 19], "server": [3, 19], "state": [3, 17, 19], "logger": 3, "kafka_log4j_root_loglevel": 3, "kafka_tools_log4j_loglevel": 3, "sentry_kafka": 3, "now": [3, 17, 19], "see": [3, 17, 19], "tool": 3, "onto": 3, "http": [3, 19], "platform": 3, "current": [3, 8, 14, 19], "app": 3, "usag": 3, "html": 3, "kcat": 3, "formerli": 3, "util": [3, 6], "venv": 3, "virtual": 3, "Then": [3, 17], "pip": 3, "sentri": 3, "our": [3, 19], "anoth": [3, 13], "exec": [3, 11], "sourc": 3, "bootstrap": [3, 19], "dest": 3, "level": [3, 11, 19], "thin": 3, "featur": [3, 17], "interfac": [3, 6], "hide": 3, "detail": 3, "lifecycl": 3, "initi": [3, 6, 17], "backend": [3, 6, 11], "import": [3, 6, 13, 19], "build_kafka_consumer_configur": 3, "kafkaconsum": [3, 11], "default_config": 3, "bootstrap_serv": 3, "auto_offset_reset": 3, "latest": [3, 19], "group_id": 3, "group": [3, 12], "subscrib": [3, 19], "timeout": [3, 8, 12, 14, 19], "script": 3, "echo": 3, "b": 3, "t": [3, 10, 12, 17], "appear": 3, "consol": 3, "kei": 3, "valu": [3, 6, 12, 14, 17, 19], "custom": [3, 8, 12, 14, 15, 18, 19], "over": [3, 12], "factori": 3, "close": [3, 8, 12, 17], "runtim": 3, "processor_factori": 3, "period": [3, 6, 10, 19], "consumerstrategi": 3, "invers": 3, "chain": [3, 7, 9], "kafkaproduc": 3, "build_kafka_configur": 3, "simpli": 3, "find": [3, 6], "reli": [4, 5], "confluent_kafka": [4, 5, 19], "mainli": [4, 5], "inspir": [4, 5], "simplifi": [4, 5], "what": [4, 10, 17], "get": [4, 17, 19], "start": [4, 11, 17], "architectur": [4, 19], "backpressur": [4, 6, 17, 19], "metric": [4, 17], "attempt": [6, 8, 13, 18, 19], "auto": [6, 7, 19], "instrument": 6, "peopl": 6, "understand": [6, 19], "behavior": [6, 10, 19], "sampl": 6, "buffer": [6, 19], "appropri": 6, "flush": [6, 8, 14, 19], "often": [6, 7, 19], "conform": 6, "protocol": 6, "creat": [6, 8, 14, 18], "your": [6, 7, 10, 11, 12, 19], "metricnam": 6, "mymetr": 6, "increment": [6, 17], "union": [6, 10], "tag": 6, "option": [6, 7, 11], "counter": 6, "given": [6, 17], "record_incr": 6, "gaug": 6, "record_gaug": 6, "emit": [6, 10, 17], "record_tim": 6, "metrics_backend": 6, "configure_metr": 6, "liter": 6, "run_task_with_multiprocess": [6, 17], "size": [6, 14, 17, 18], "byte": [6, 17], "output_batch": 6, "encount": [6, 17], "invalid_messag": 6, "took": 6, "fill": [6, 17], "up": [6, 7, 12, 17, 19], "batch_tim": 6, "reason": [6, 7, 10], "why": 6, "cannot": [6, 10, 19], "satur": 6, "input": 6, "enough": 6, "alloc": [6, 17], "smaller": [6, 17], "increas": [6, 17], "input_block_s": [6, 17], "overflow": [6, 17], "pull": 6, "equal": 6, "devast": 6, "output_block_s": [6, 17], "ha": [6, 7, 8, 11, 12, 13, 19], "combat": 6, "disabl": 6, "explicitli": [6, 17], "runtaskwithmultiprocess": [6, 17], "resiz": [6, 17], "mani": [6, 8, 10, 11, 12, 13, 14, 16, 17, 19], "batches_in_progress": [6, 17], "subprocess": [6, 17], "unexpectedli": 6, "di": [6, 19], "sigchld": 6, "detect": 6, "unitless": 6, "spent": [6, 8, 14, 17], "due": [6, 12, 19], "handl": [6, 10, 19], "send": [6, 8, 17, 19], "exit": [6, 12], "shutdown": [6, 7, 12], "overlap": 6, "other": [6, 10, 12], "might": [6, 17], "spike": 6, "prefetch": 6, "total_queue_s": 6, "measur": 6, "healthcheck": 6, "file": [6, 11, 12, 19], "been": [6, 7, 8, 12, 13, 19], "touch": [6, 11], "filterstep": [6, 10], "dropped_messag": 6, "kwarg": [6, 12], "str": [6, 11, 12], "record": 6, "forc": [6, 7], "unless": 6, "manual": [7, 19], "rest": 7, "alwai": [7, 9, 13], "e": [7, 10, 18], "mean": [7, 17, 19], "next_offset": [7, 12], "never": [7, 17], "expos": 7, "position_to_commit": 7, "easier": 7, "high": [7, 8], "add": [7, 19], "lot": [7, 17, 19], "load": [7, 17], "system": [7, 10], "throttl": 7, "commitpolici": [7, 10], "specifi": [7, 16], "frequenc": 7, "minimum": 7, "between": [7, 17], "sure": [7, 19], "once_per_second": 7, "easiest": 7, "last": [7, 9], "myconsumerfactoryfactori": 7, "my_processing_funct": 7, "do_someth": 7, "accumul": [8, 14], "unfold": 8, "batchstep": 8, "max_batch_s": [8, 14, 17], "max_batch_tim": [8, 14, 17], "next_step": [8, 10, 11, 13, 14, 15, 16, 17, 18], "mutablesequ": 8, "basevalu": [8, 12, 14], "repres": [8, 12], "valuesbatch": 8, "object": [8, 16], "sequenc": [8, 18], "both": 8, "watermark": 8, "maximum": [8, 14], "receiv": [8, 12, 13, 14, 16, 18], "sinc": [8, 12, 16, 17], "sent": 8, "though": 8, "highest": [8, 17], "observ": [8, 17], "still": [8, 17], "committ": [8, 12], "lower": 8, "propag": [8, 14], "thrown": [8, 12, 14], "paramet": [8, 12, 14, 17], "much": [8, 14, 19], "tri": [8, 14], "matter": [8, 14], "filteredpayload": [8, 10, 12, 13, 14, 15, 16, 17, 18], "without": [8, 14, 17, 19], "previou": [8, 12, 14, 17, 19], "try": [8, 14], "again": [8, 14, 17, 19], "introduc": [8, 14], "duplic": [8, 14], "unbatchstep": 8, "explod": [8, 18], "keep": [8, 11, 12, 17, 18], "remain": [8, 18], "prior": [9, 12], "callabl": [10, 14, 15, 16, 17, 18], "commit_polici": 10, "determin": 10, "sometim": 10, "actual": [10, 19], "desir": 10, "regular": 10, "interv": [10, 11, 12], "For": [10, 13, 16, 17], "That": [10, 17], "sentinel": 10, "those": [10, 17], "abl": [10, 17], "subtyp": 10, "doesn": [10, 17], "compos": 10, "default": [10, 11, 19], "despit": 10, "tell": [10, 11, 12], "turn": 11, "unhealthi": 11, "max": [11, 14], "m": [11, 19], "kick": [11, 19], "300000": 11, "5": 11, "minut": 11, "noth": 11, "pod": [11, 19], "well": 11, "repeatedli": 11, "indic": [11, 15], "health": 11, "tmp": 11, "txt": 11, "kubernet": 11, "live": 11, "look": [11, 17, 19], "apivers": 11, "v1": 11, "metadata": 11, "label": 11, "spec": 11, "imag": 11, "registri": 11, "k8": 11, "busybox": 11, "bin": 11, "my_arroyo_consum": 11, "livenessprob": 11, "initialdelaysecond": 11, "periodsecond": 11, "320": 11, "healthcheck_fil": 11, "filepath": 11, "everytim": 11, "overal": 11, "debounc": 11, "compon": 12, "normal": [12, 17], "don": [12, 17, 19], "encourag": 12, "plug": 12, "nevertheless": 12, "against": 12, "unabl": 12, "rate": [12, 17], "incom": 12, "abc": 12, "cours": 12, "intention": 12, "prescript": 12, "afford": 12, "signific": 12, "degre": 12, "variou": 12, "instanc": 12, "No": [12, 19], "finish": 12, "were": [12, 17], "releas": 12, "resourc": 12, "longer": 12, "socket": 12, "until": [12, 14, 19], "previous": 12, "reach": [12, 19], "grace": 12, "revoc": [12, 19], "progress": 12, "continu": [12, 17], "statu": 12, "schedul": [12, 19], "iter": [12, 18], "amount": 12, "exce": 12, "caller": 12, "assum": 12, "successfulli": [12, 13], "impli": 12, "capac": [12, 17], "abandon": 12, "wrap": 12, "seri": 12, "recreat": 12, "recent": 12, "entir": [12, 17, 19], "note": [12, 17], "also": [12, 17, 19], "properti": 12, "tmessagepayload": 12, "replac": 12, "treplac": 12, "brokervalu": 12, "timestamp": 12, "datetim": 12, "present": 12, "either": 12, "els": 12, "payload_unfilt": 12, "index": 12, "span": 12, "max_buffer_s": 13, "10000": 13, "destin": [13, 19], "could": [13, 19], "pend": [13, 16], "notifi": [13, 16], "error": [13, 16, 19], "constructor": 13, "referenc": 13, "tresult": [14, 15, 16, 17], "tpayload": 14, "initial_valu": 14, "hit": [14, 17], "run_task": 15, "put": 15, "run_task_in_thread": 16, "runtaskinthread": 16, "processing_funct": 16, "max_pending_futur": 16, "bound": 16, "avoid": [16, 17], "modifi": 16, "differ": [16, 19], "protect": 16, "lock": [16, 17], "num_process": 17, "max_input_block_s": 17, "max_output_block_s": 17, "across": 17, "stdlib": 17, "spawn": 17, "message_s": 17, "expect": 17, "averag": 17, "implicitli": 17, "broken": 17, "automat": 17, "adjust": 17, "adapt": 17, "traffic": 17, "mind": [17, 19], "experiment": 17, "less": 17, "production": 17, "data": 17, "enabl": [17, 19], "upper": 17, "begin": 17, "parent": 17, "interpret": 17, "django": 17, "point": 17, "line": [17, 19], "bottleneck": 17, "good": [17, 19], "reserv": 17, "But": 17, "faster": [17, 19], "tweak": 17, "optim": 17, "cost": 17, "amort": 17, "spend": 17, "flat": 17, "perfectli": 17, "straight": 17, "constant": 17, "neither": 17, "ey": 17, "ran": 17, "respons": 17, "realli": 17, "expens": [17, 19], "affect": 17, "confus": 17, "best": 17, "anywai": 17, "fetch": 17, "chunk": 17, "veri": [17, 19], "won": [17, 19], "notic": 17, "regress": 17, "sens": 17, "rid": 17, "issu": [17, 19], "backlog": 17, "lag": 17, "remov": [17, 19], "potenti": 17, "tinput": 18, "collect": 18, "toutput": 18, "accord": 18, "testabl": 19, "document": 19, "outlin": 19, "intricaci": 19, "easi": 19, "awai": 19, "worri": 19, "about": 19, "possibl": 19, "reproduc": 19, "environ": 19, "visual": 19, "event": 19, "driven": 19, "view": 19, "push": 19, "diagram": 19, "below": 19, "accur": 19, "model": 19, "persist": 19, "read": 19, "conf": 19, "localhost": 19, "id": 19, "my_group": 19, "reset": 19, "my_top": 19, "send_to_destin": 19, "process_messag": 19, "satisfi": 19, "mention": 19, "page": 19, "subsect": 19, "By": 19, "To": 19, "lead": 19, "throw": 19, "lost": 19, "know": 19, "config": 19, "u": 19, "sever": 19, "hurt": 19, "replic": 19, "inform": 19, "And": 19, "pure": 19, "descript": 19, "append": 19, "len": 19, "batch_siz": 19, "hand": 19, "wave": 19, "sai": 19, "destination_top": 19, "At": 19, "ever": 19, "transmiss": 19, "delivery_callback": 19, "on_deliveri": 19, "n": 19, "exactli": 19, "rebal": 19, "off": 19, "whenev": 19, "idea": 19, "annoi": 19, "imagin": 19, "decis": 19, "made": 19, "let": 19, "pick": 19, "on_revok": 19, "flush_current_batch": 19, "core": 19, "mechan": 19, "flow": 19, "clear": 19, "possibli": 19, "invok": 19, "respect": 19, "gotcha": 19, "kept": 19, "comit": 19, "api": 19, "www": 19, "educba": 19, "com": 19}, "objects": {"arroyo": [[2, 0, 0, "-", "dlq"], [12, 0, 0, "-", "types"]], "arroyo.dlq": [[2, 1, 1, "", "DlqLimit"], [2, 1, 1, "", "DlqPolicy"], [2, 2, 1, "", "InvalidMessage"], [2, 1, 1, "", "KafkaDlqProducer"], [2, 1, 1, "", "NoopDlqProducer"]], "arroyo.processing.strategies": [[12, 0, 0, "-", "abstract"], [8, 0, 0, "-", "batching"], [9, 0, 0, "-", "commit"], [10, 0, 0, "-", "filter"], [11, 0, 0, "-", "healthcheck"], [13, 0, 0, "-", "produce"], [14, 0, 0, "-", "reduce"], [15, 0, 0, "-", "run_task"], [16, 0, 0, "-", "run_task_in_threads"], [17, 0, 0, "-", "run_task_with_multiprocessing"], [18, 0, 0, "-", "unfold"]], "arroyo.processing.strategies.abstract": [[12, 2, 1, "", "MessageRejected"], [12, 1, 1, "", "ProcessingStrategy"], [12, 1, 1, "", "ProcessingStrategyFactory"]], "arroyo.processing.strategies.abstract.ProcessingStrategy": [[12, 3, 1, "", "close"], [12, 3, 1, "", "join"], [12, 3, 1, "", "poll"], [12, 3, 1, "", "submit"], [12, 3, 1, "", "terminate"]], "arroyo.processing.strategies.abstract.ProcessingStrategyFactory": [[12, 3, 1, "", "create_with_partitions"], [12, 3, 1, "", "shutdown"]], "arroyo.processing.strategies.batching": [[8, 1, 1, "", "BatchStep"], [8, 1, 1, "", "UnbatchStep"]], "arroyo.processing.strategies.batching.BatchStep": [[8, 3, 1, "", "join"], [8, 3, 1, "", "submit"]], "arroyo.processing.strategies.commit": [[9, 1, 1, "", "CommitOffsets"]], "arroyo.processing.strategies.filter": [[10, 1, 1, "", "FilterStep"]], "arroyo.processing.strategies.healthcheck": [[11, 1, 1, "", "Healthcheck"]], "arroyo.processing.strategies.produce": [[13, 1, 1, "", "Produce"]], "arroyo.processing.strategies.reduce": [[14, 1, 1, "", "Reduce"]], "arroyo.processing.strategies.reduce.Reduce": [[14, 3, 1, "", "join"], [14, 3, 1, "", "submit"]], "arroyo.processing.strategies.run_task": [[15, 1, 1, "", "RunTask"]], "arroyo.processing.strategies.run_task_in_threads": [[16, 1, 1, "", "RunTaskInThreads"]], "arroyo.processing.strategies.run_task_with_multiprocessing": [[17, 1, 1, "", "RunTaskWithMultiprocessing"]], "arroyo.processing.strategies.unfold": [[18, 1, 1, "", "Unfold"]], "arroyo.types": [[12, 1, 1, "", "BaseValue"], [12, 1, 1, "", "BrokerValue"], [12, 1, 1, "", "Commit"], [12, 1, 1, "", "FilteredPayload"], [12, 1, 1, "", "Message"], [12, 1, 1, "", "Partition"], [12, 1, 1, "", "Topic"], [12, 1, 1, "", "Value"]], "arroyo.types.BaseValue": [[12, 4, 1, "", "committable"], [12, 4, 1, "", "payload"], [12, 3, 1, "", "replace"]], "arroyo.types.BrokerValue": [[12, 4, 1, "", "committable"], [12, 4, 1, "", "next_offset"], [12, 5, 1, "", "offset"], [12, 5, 1, "", "partition"], [12, 4, 1, "", "payload"], [12, 3, 1, "", "replace"], [12, 5, 1, "", "timestamp"]], "arroyo.types.Message": [[12, 4, 1, "", "committable"], [12, 4, 1, "", "payload"], [12, 4, 1, "", "payload_unfiltered"], [12, 3, 1, "", "replace"], [12, 5, 1, "", "value"]], "arroyo.types.Partition": [[12, 5, 1, "", "index"], [12, 5, 1, "", "topic"]], "arroyo.types.Topic": [[12, 5, 1, "", "name"]], "arroyo.types.Value": [[12, 4, 1, "", "committable"], [12, 4, 1, "", "payload"], [12, 3, 1, "", "replace"]], "arroyo.utils": [[6, 0, 0, "-", "metrics"]], "arroyo.utils.metrics": [[6, 1, 1, "", "Metrics"], [6, 6, 1, "", "configure_metrics"]], "arroyo.utils.metrics.Metrics": [[6, 3, 1, "", "gauge"], [6, 3, 1, "", "increment"], [6, 3, 1, "", "timing"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:exception", "3": "py:method", "4": "py:property", "5": "py:attribute", "6": "py:function"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "exception", "Python exception"], "3": ["py", "method", "Python method"], "4": ["py", "property", "Python property"], "5": ["py", "attribute", "Python attribute"], "6": ["py", "function", "Python function"]}, "titleterms": {"arroyo": [0, 3, 19], "architectur": 0, "stream": [0, 3], "interfac": [0, 12], "engin": 0, "high": [0, 19], "level": 0, "strategi": [0, 12], "backpressur": 1, "dead": 2, "letter": 2, "queue": 2, "get": 3, "start": 3, "setup": 3, "kafka": [3, 19], "zookeep": 3, "instal": 3, "kafkacat": 3, "develop": 3, "environ": 3, "creat": 3, "two": 3, "topic": [3, 19], "basic": 3, "consum": [3, 17, 19], "add": 3, "some": 3, "us": 3, "logic": 3, "further": 3, "exampl": 3, "content": 4, "metric": 6, "avail": 6, "api": 6, "commit": [7, 9, 19], "offset": [7, 9], "batch": [8, 17, 19], "unbatch": 8, "filter": 10, "healthcheck": 11, "process": [12, 17], "messag": 12, "produc": [13, 19], "reduc": 14, "fold": 14, "run": [15, 16, 17], "task": [15, 16, 17], "thread": 16, "multiprocess": 17, "number": 17, "input": 17, "output": 17, "buffer": 17, "how": [17, 19], "tune": 17, "your": 17, "unfold": 18, "what": 19, "i": 19, "goal": 19, "why": 19, "simpl": 19, "doesn": 19, "t": 19, "cut": 19, "It": 19, "provid": 19, "deliveri": 19, "guarante": 19, "throughput": 19, "reliabl": 19, "deal": 19, "With": 19, "rebalanc": 19, "when": 19, "can": 19, "happen": 19, "affect": 19, "librdkafka": 19, "": 19, "callback": 19, "hell": 19, "conclus": 19, "appendix": 19, "group": 19}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx": 58}, "alltitles": {"Arroyo Architecture": [[0, "arroyo-architecture"]], "Streaming Interface and Streaming Engine": [[0, "streaming-interface-and-streaming-engine"]], "High level strategies": [[0, "high-level-strategies"]], "Backpressure": [[1, "backpressure"]], "Dead letter queues": [[2, "dead-letter-queues"]], "Getting started with Arroyo": [[3, "getting-started-with-arroyo"]], "Setup": [[3, "setup"]], "Kafka and Zookeeper": [[3, "kafka-and-zookeeper"]], "Install Kafkacat": [[3, "install-kafkacat"]], "Development environment": [[3, "development-environment"]], "Create two Kafka topics": [[3, "create-two-kafka-topics"]], "Create a basic consumer": [[3, "create-a-basic-consumer"]], "Creating a basic consumer": [[3, "creating-a-basic-consumer"]], "Create a streaming consumer": [[3, "create-a-streaming-consumer"]], "Add some useful logic": [[3, "add-some-useful-logic"]], "Further examples": [[3, "further-examples"]], "Contents:": [[4, "contents"]], "Metrics": [[6, "metrics"]], "Available Metrics": [[6, "available-metrics"]], "API": [[6, "module-arroyo.utils.metrics"]], "Committing offsets": [[7, "committing-offsets"]], "Batch and Unbatch": [[8, "batch-and-unbatch"]], "Commit offsets": [[9, "commit-offsets"]], "Filter": [[10, "module-arroyo.processing.strategies.filter"]], "Healthchecks": [[11, "healthchecks"]], "Processing Strategies": [[12, "processing-strategies"]], "Strategy interface": [[12, "strategy-interface"]], "Messages": [[12, "module-arroyo.types"]], "Produce": [[13, "module-arroyo.processing.strategies.produce"]], "Reduce (Fold)": [[14, "reduce-fold"]], "Run Task": [[15, "module-arroyo.processing.strategies.run_task"]], "Run Task in Threads": [[16, "module-arroyo.processing.strategies.run_task_in_threads"]], "Run Task with Multiprocessing": [[17, "module-arroyo.processing.strategies.run_task_with_multiprocessing"]], "Number of processes": [[17, "number-of-processes"]], "Batching": [[17, "batching"]], "Input and output buffers": [[17, "input-and-output-buffers"]], "How to tune your consumer": [[17, "how-to-tune-your-consumer"]], "Unfold": [[18, "unfold"]], "What is Arroyo for?": [[19, "what-is-arroyo-for"]], "Goals": [[19, "goals"]], "Why Simple Doesn\u2019t Cut It": [[19, "why-simple-doesnt-cut-it"]], "Providing delivery guarantees": [[19, "providing-delivery-guarantees"]], "High Throughput": [[19, "high-throughput"]], "Reliable High Throughput Batched Producers": [[19, "reliable-high-throughput-batched-producers"]], "Dealing With Rebalancing": [[19, "dealing-with-rebalancing"]], "What is Rebalancing": [[19, "what-is-rebalancing"]], "When Rebalancing Can Happen": [[19, "when-rebalancing-can-happen"]], "How Rebalancing Affects a Consumer": [[19, "how-rebalancing-affects-a-consumer"]], "librdkafka\u2019s Callback Hell": [[19, "librdkafkas-callback-hell"]], "Conclusion": [[19, "conclusion"]], "Appendix": [[19, "appendix"]], "Committing to a Kafka Topic": [[19, "committing-to-a-kafka-topic"]], "What is a Kafka Consumer Group": [[19, "what-is-a-kafka-consumer-group"]]}, "indexentries": {"dlqlimit (class in arroyo.dlq)": [[2, "arroyo.dlq.DlqLimit"]], "dlqpolicy (class in arroyo.dlq)": [[2, "arroyo.dlq.DlqPolicy"]], "invalidmessage": [[2, "arroyo.dlq.InvalidMessage"]], "kafkadlqproducer (class in arroyo.dlq)": [[2, "arroyo.dlq.KafkaDlqProducer"]], "noopdlqproducer (class in arroyo.dlq)": [[2, "arroyo.dlq.NoopDlqProducer"]], "arroyo.dlq": [[2, "module-arroyo.dlq"]], "module": [[2, "module-arroyo.dlq"], [6, "module-arroyo.utils.metrics"], [8, "module-arroyo.processing.strategies.batching"], [9, "module-arroyo.processing.strategies.commit"], [10, "module-arroyo.processing.strategies.filter"], [11, "module-arroyo.processing.strategies.healthcheck"], [12, "module-arroyo.processing.strategies.abstract"], [12, "module-arroyo.types"], [13, "module-arroyo.processing.strategies.produce"], [14, "module-arroyo.processing.strategies.reduce"], [15, "module-arroyo.processing.strategies.run_task"], [16, "module-arroyo.processing.strategies.run_task_in_threads"], [17, "module-arroyo.processing.strategies.run_task_with_multiprocessing"], [18, "module-arroyo.processing.strategies.unfold"]], "metrics (class in arroyo.utils.metrics)": [[6, "arroyo.utils.metrics.Metrics"]], "arroyo.utils.metrics": [[6, "module-arroyo.utils.metrics"]], "configure_metrics() (in module arroyo.utils.metrics)": [[6, "arroyo.utils.metrics.configure_metrics"]], "gauge() (arroyo.utils.metrics.metrics method)": [[6, "arroyo.utils.metrics.Metrics.gauge"]], "increment() (arroyo.utils.metrics.metrics method)": [[6, "arroyo.utils.metrics.Metrics.increment"]], "timing() (arroyo.utils.metrics.metrics method)": [[6, "arroyo.utils.metrics.Metrics.timing"]], "batchstep (class in arroyo.processing.strategies.batching)": [[8, "arroyo.processing.strategies.batching.BatchStep"]], "unbatchstep (class in arroyo.processing.strategies.batching)": [[8, "arroyo.processing.strategies.batching.UnbatchStep"]], "arroyo.processing.strategies.batching": [[8, "module-arroyo.processing.strategies.batching"]], "join() (arroyo.processing.strategies.batching.batchstep method)": [[8, "arroyo.processing.strategies.batching.BatchStep.join"]], "submit() (arroyo.processing.strategies.batching.batchstep method)": [[8, "arroyo.processing.strategies.batching.BatchStep.submit"]], "commitoffsets (class in arroyo.processing.strategies.commit)": [[9, "arroyo.processing.strategies.commit.CommitOffsets"]], "arroyo.processing.strategies.commit": [[9, "module-arroyo.processing.strategies.commit"]], "filterstep (class in arroyo.processing.strategies.filter)": [[10, "arroyo.processing.strategies.filter.FilterStep"]], "arroyo.processing.strategies.filter": [[10, "module-arroyo.processing.strategies.filter"]], "healthcheck (class in arroyo.processing.strategies.healthcheck)": [[11, "arroyo.processing.strategies.healthcheck.Healthcheck"]], "arroyo.processing.strategies.healthcheck": [[11, "module-arroyo.processing.strategies.healthcheck"]], "basevalue (class in arroyo.types)": [[12, "arroyo.types.BaseValue"]], "brokervalue (class in arroyo.types)": [[12, "arroyo.types.BrokerValue"]], "commit (class in arroyo.types)": [[12, "arroyo.types.Commit"]], "filteredpayload (class in arroyo.types)": [[12, "arroyo.types.FilteredPayload"]], "message (class in arroyo.types)": [[12, "arroyo.types.Message"]], "messagerejected": [[12, "arroyo.processing.strategies.abstract.MessageRejected"]], "partition (class in arroyo.types)": [[12, "arroyo.types.Partition"]], "processingstrategy (class in arroyo.processing.strategies.abstract)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy"]], "processingstrategyfactory (class in arroyo.processing.strategies.abstract)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategyFactory"]], "topic (class in arroyo.types)": [[12, "arroyo.types.Topic"]], "value (class in arroyo.types)": [[12, "arroyo.types.Value"]], "arroyo.processing.strategies.abstract": [[12, "module-arroyo.processing.strategies.abstract"]], "arroyo.types": [[12, "module-arroyo.types"]], "close() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.close"]], "committable (arroyo.types.basevalue property)": [[12, "arroyo.types.BaseValue.committable"]], "committable (arroyo.types.brokervalue property)": [[12, "arroyo.types.BrokerValue.committable"]], "committable (arroyo.types.message property)": [[12, "arroyo.types.Message.committable"]], "committable (arroyo.types.value property)": [[12, "arroyo.types.Value.committable"]], "create_with_partitions() (arroyo.processing.strategies.abstract.processingstrategyfactory method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategyFactory.create_with_partitions"]], "index (arroyo.types.partition attribute)": [[12, "arroyo.types.Partition.index"]], "join() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.join"]], "name (arroyo.types.topic attribute)": [[12, "arroyo.types.Topic.name"]], "next_offset (arroyo.types.brokervalue property)": [[12, "arroyo.types.BrokerValue.next_offset"]], "offset (arroyo.types.brokervalue attribute)": [[12, "arroyo.types.BrokerValue.offset"]], "partition (arroyo.types.brokervalue attribute)": [[12, "arroyo.types.BrokerValue.partition"]], "payload (arroyo.types.basevalue property)": [[12, "arroyo.types.BaseValue.payload"]], "payload (arroyo.types.brokervalue property)": [[12, "arroyo.types.BrokerValue.payload"]], "payload (arroyo.types.message property)": [[12, "arroyo.types.Message.payload"]], "payload (arroyo.types.value property)": [[12, "arroyo.types.Value.payload"]], "payload_unfiltered (arroyo.types.message property)": [[12, "arroyo.types.Message.payload_unfiltered"]], "poll() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.poll"]], "replace() (arroyo.types.basevalue method)": [[12, "arroyo.types.BaseValue.replace"]], "replace() (arroyo.types.brokervalue method)": [[12, "arroyo.types.BrokerValue.replace"]], "replace() (arroyo.types.message method)": [[12, "arroyo.types.Message.replace"]], "replace() (arroyo.types.value method)": [[12, "arroyo.types.Value.replace"]], "shutdown() (arroyo.processing.strategies.abstract.processingstrategyfactory method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategyFactory.shutdown"]], "submit() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.submit"]], "terminate() (arroyo.processing.strategies.abstract.processingstrategy method)": [[12, "arroyo.processing.strategies.abstract.ProcessingStrategy.terminate"]], "timestamp (arroyo.types.brokervalue attribute)": [[12, "arroyo.types.BrokerValue.timestamp"]], "topic (arroyo.types.partition attribute)": [[12, "arroyo.types.Partition.topic"]], "value (arroyo.types.message attribute)": [[12, "arroyo.types.Message.value"]], "produce (class in arroyo.processing.strategies.produce)": [[13, "arroyo.processing.strategies.produce.Produce"]], "arroyo.processing.strategies.produce": [[13, "module-arroyo.processing.strategies.produce"]], "reduce (class in arroyo.processing.strategies.reduce)": [[14, "arroyo.processing.strategies.reduce.Reduce"]], "arroyo.processing.strategies.reduce": [[14, "module-arroyo.processing.strategies.reduce"]], "join() (arroyo.processing.strategies.reduce.reduce method)": [[14, "arroyo.processing.strategies.reduce.Reduce.join"]], "submit() (arroyo.processing.strategies.reduce.reduce method)": [[14, "arroyo.processing.strategies.reduce.Reduce.submit"]], "runtask (class in arroyo.processing.strategies.run_task)": [[15, "arroyo.processing.strategies.run_task.RunTask"]], "arroyo.processing.strategies.run_task": [[15, "module-arroyo.processing.strategies.run_task"]], "runtaskinthreads (class in arroyo.processing.strategies.run_task_in_threads)": [[16, "arroyo.processing.strategies.run_task_in_threads.RunTaskInThreads"]], "arroyo.processing.strategies.run_task_in_threads": [[16, "module-arroyo.processing.strategies.run_task_in_threads"]], "runtaskwithmultiprocessing (class in arroyo.processing.strategies.run_task_with_multiprocessing)": [[17, "arroyo.processing.strategies.run_task_with_multiprocessing.RunTaskWithMultiprocessing"]], "arroyo.processing.strategies.run_task_with_multiprocessing": [[17, "module-arroyo.processing.strategies.run_task_with_multiprocessing"]], "unfold (class in arroyo.processing.strategies.unfold)": [[18, "arroyo.processing.strategies.unfold.Unfold"]], "arroyo.processing.strategies.unfold": [[18, "module-arroyo.processing.strategies.unfold"]]}}) \ No newline at end of file diff --git a/strategies/batching.html b/strategies/batching.html new file mode 100644 index 00000000..630b35e6 --- /dev/null +++ b/strategies/batching.html @@ -0,0 +1,293 @@ + + + + + + Batch and Unbatch - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Batch and Unbatch

+

Accumulate messages into a batch and pass to the next step. +The batch and unbatch strategies are based on reduce and unfold. +Use reduce/unfold instead if you want to provide custom +accumulator/generator functions.

+
+
+class arroyo.processing.strategies.batching.BatchStep(max_batch_size: int, max_batch_time: float, next_step: ProcessingStrategy[MutableSequence[BaseValue[TStrategyPayload]]])
+

Accumulates messages into a batch. When the batch is full, this +strategy submits it to the next step.

+

A batch is represented as a ValuesBatch object which is a sequence +of BaseValue. This includes both the messages and the high offset +watermark.

+

A messages batch is closed and submitted when the maximum number of +messages is received or when the max_batch_time has passed since the +first message was received.

+

This step does not require in order processing. If messages are sent +out of order, though, the highest observed offset per partition is +still the committable one, whether or not all messages with lower +offsets have been observed by this step.

+

This strategy propagates MessageRejected exceptions from the +downstream steps if they are thrown.

+
+
Parameters:
+
    +
  • max_batch_size – How many messages should be reduced into one at maximum.

  • +
  • max_batch_time – How much time (in seconds) should be spent reducing +messages together before flushing the batch.

  • +
+
+
+
+
+join(timeout: float | None = None) None
+

Terminates the strategy by joining the following step. +This method tries to flush the current batch no matter +whether the batch is ready or not.

+
+ +
+
+submit(message: Message[FilteredPayload | TStrategyPayload]) None
+

Accumulates messages in the current batch. +A new batch is created at the first message received.

+

This method tries to flush before adding the message +to the current batch. This is so that, if we receive +MessageRejected exception from the following step, +we can propagate the exception without processing the +new message. This allows the previous step to try again +without introducing duplications.

+
+ +
+ +
+
+class arroyo.processing.strategies.batching.UnbatchStep(next_step: ProcessingStrategy[FilteredPayload | TStrategyPayload])
+

This processing step receives batches and explodes them thus sending +the content to the next step message by message.

+

A batch is represented as a ValuesBatch object.

+

If this step receives a MessageRejected exception from the next +step it would keep the remaining messages and attempt to submit +them at the following call to poll

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/commit_offsets.html b/strategies/commit_offsets.html new file mode 100644 index 00000000..3ff8284a --- /dev/null +++ b/strategies/commit_offsets.html @@ -0,0 +1,235 @@ + + + + + + Commit offsets - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Commit offsets

+

Should be used as the last strategy in the chain, to ensure +that offsets are only committed once all processing is complete.

+
+
+class arroyo.processing.strategies.commit.CommitOffsets(commit: Commit)
+

Just commits offsets.

+

This should always be used as the last step in a chain of processing +strategies. It commits offsets back to the broker after all prior +processing of that message is completed.

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/filter.html b/strategies/filter.html new file mode 100644 index 00000000..261a5b74 --- /dev/null +++ b/strategies/filter.html @@ -0,0 +1,248 @@ + + + + + + Filter - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Filter

+
+
+class arroyo.processing.strategies.filter.FilterStep(function: Callable[[Message[TStrategyPayload]], bool], next_step: ProcessingStrategy[FilteredPayload | TStrategyPayload], commit_policy: CommitPolicy | None = None)
+

Determines if a message should be submitted to the next processing step.

+

FilterStep takes a callback, function, and if that callback returns +False, the message is dropped.

+

Sometimes that behavior is not actually desirable because streams of +messages is what makes the consumer commit in regular intervals. If you +filter 100% of messages for a period of time, your consumer may not commit +its offsets as a result.

+

For that scenario, you can pass your CommitPolicy to FilterStep. That +will cause FilterStep to emit “sentinel messages” that contain no +payload, but only carry forward partition offsets for later strategies to +commit. Those messages have a payload of type FilteredPayload.

+

For that reason, basically every strategy needs to be able to handle +Message[Union[FilteredPayload, T]] instead of Message[T], i.e. it needs +to subtype ProcessingStrategy[Union[FilteredPayload, TStrategyPayload]]. +If it doesn’t, and rather just handles the regular Message[T], it cannot +be composed with this step, and many other default strategies of arroyo.

+

If no CommitPolicy is passed, no “sentinel messages” are emitted and +downstream steps do not have to deal with such messages (despite the type +system telling them so).

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/healthcheck.html b/strategies/healthcheck.html new file mode 100644 index 00000000..7ea359e8 --- /dev/null +++ b/strategies/healthcheck.html @@ -0,0 +1,291 @@ + + + + + + Healthchecks - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Healthchecks

+

If your code blocks for too long in the main thread, the consumer can turn +unhealthy.

+

Kafka has a setting called max.poll.interval.ms for this that tells Kafka +to kick the consumer out of the broker after this many milliseconds of not polling.

+

You can pass this option into arroyo.backends.kafka.consumer.KafkaConsumer like so:

+
consumer = KafkaConsumer(
+    {
+        "max.poll.interval.ms": 300000, # default 5 minutes
+    }
+)
+
+
+

However, this will not shut down the consumer, it will just keep running doing +nothing (because it is blocked in the main thread). You want a pod-level +healthcheck as well.

+

Arroyo supports touching a file repeatedly from the main thread to indicate +health. Start your pipeline with the +arroyo.processing.strategies.healthcheck.Healthcheck strategy.

+
def handle_message(message: Message[KafkaPayload]) -> Message[KafkaPayload]:
+    ...
+    return message
+
+class ConsumerStrategyFactory(ProcessingStrategyFactory[KafkaPayload]):
+    def __init__(self):
+        self.is_paused = False
+
+    def create_with_partitions(
+        self,
+        commit: Commit,
+        partitions: Mapping[Partition, int],
+    ) -> ProcessingStrategy[KafkaPayload]:
+        step = RunTask(handle_message, CommitOffsets(commit))
+        return Healthcheck("/tmp/health.txt", step)
+
+
+

The Kubernetes liveness +command would look like:

+
apiVersion: v1
+kind: Pod
+metadata:
+  labels:
+    test: liveness
+  name: liveness-exec
+spec:
+  containers:
+  - name: liveness
+    image: registry.k8s.io/busybox
+    args:
+      - bin/my_arroyo_consumer
+    livenessProbe:
+      exec:
+        command:
+        - rm
+        - /tmp/health.txt
+      initialDelaySeconds: 5
+      periodSeconds: 320  # should be higher than max.poll.interval.ms
+
+
+
+
+class arroyo.processing.strategies.healthcheck.Healthcheck(healthcheck_file: str, next_step: ProcessingStrategy[TStrategyPayload])
+

A strategy that takes a filepath, and touches that file everytime +Strategy.poll is called. If that function is not called multiple times +per minute, it indicates that the consumer is overall unhealthy.

+

File touches are debounced to happen once per second at most.

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/index.html b/strategies/index.html new file mode 100644 index 00000000..b822c33f --- /dev/null +++ b/strategies/index.html @@ -0,0 +1,559 @@ + + + + + + Processing Strategies - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Processing Strategies

+

The processing strategies are the components to be wired together to +build a consumer.

+
+

Strategy interface

+

We normally don’t recommend writing your own strategy, and encourage you to use +built-in ones such as “reduce” or “run task” to plug in your application logic. +Nevertheless, all arroyo strategies are written against the following interface:

+
+
+exception arroyo.processing.strategies.abstract.MessageRejected
+

Bases: Exception

+

MessageRejected should be raised in a processing strategy’s submit method +if it is unable to keep up with the rate of incoming messages. It tells +the consumer to slow down and retry the message later.

+
+ +
+
+class arroyo.processing.strategies.abstract.ProcessingStrategy(*args, **kwds)
+

Bases: ABC, Generic[TStrategyPayload]

+

A processing strategy defines how a stream processor processes messages +during the course of a single assignment. The processor is instantiated +when the assignment is received, and closed when the assignment is +revoked.

+

This interface is intentionally not prescriptive, and affords a +significant degree of flexibility for the various implementations.

+
+
+abstract close() None
+

Close this instance. No more messages should be accepted by the +instance after this method has been called.

+

This method should not block. Once this strategy instance has +finished processing (or discarded) all messages that were submitted +prior to this method being called, the strategy should commit its +partition offsets and release any resources that will no longer be +used (threads, processes, sockets, files, etc.)

+
+ +
+
+abstract join(timeout: float | None = None) None
+

Block until the processing strategy has completed all previously +submitted work, or the provided timeout has been reached. This method +should be called after close to provide a graceful shutdown.

+

This method is called synchronously by the stream processor during +assignment revocation, and blocks the assignment from being released +until this function exits, allowing any work in progress to be +completed and committed before the continuing the rebalancing +process.

+
+ +
+
+abstract poll() None
+

Poll the processor to check on the status of asynchronous tasks or +perform other scheduled work.

+

This method is called on each consumer loop iteration, so this method +should not be used to perform work that may block for a significant +amount of time and block the progress of the consumer or exceed the +consumer poll interval timeout.

+

This method may raise exceptions that were thrown by asynchronous +tasks since the previous call to poll.

+
+ +
+
+abstract submit(message: Message[TStrategyPayload]) None
+

Submit a message for processing.

+

Messages may be processed synchronously or asynchronously, depending +on the implementation of the processing strategy. Callers of this +method should not assume that this method returning successfully +implies that the message was successfully processed.

+

If the processing strategy is unable to accept a message (due to it +being at or over capacity, for example), this method will raise a +MessageRejected exception.

+
+ +
+
+abstract terminate() None
+

Close the processing strategy immediately, abandoning any work in +progress. No more messages should be accepted by the instance after +this method has been called.

+
+ +
+ +
+
+class arroyo.processing.strategies.abstract.ProcessingStrategyFactory(*args, **kwds)
+

Bases: ABC, Generic[TStrategyPayload]

+

A ProcessingStrategyFactory is used to wrap a series of +ProcessingStrategy steps, and calls create_with_partitions +to instantiate the ProcessingStrategy on partition assignment +or partition revocation if the strategy needs to be recreated.

+
+
+abstract create_with_partitions(commit: Commit, partitions: Mapping[Partition, int]) ProcessingStrategy[TStrategyPayload]
+

Instantiate and return a ProcessingStrategy instance.

+
+
Parameters:
+
    +
  • commit – A function that accepts a mapping of Partition instances to offset values that should be committed.

  • +
  • partitions – A mapping of a Partition to it’s most recent offset.

  • +
+
+
+
+ +
+
+shutdown() None
+

Custom code to execute when the StreamProcessor shuts down entirely.

+

Note that this code will also be executed on crashes of the strategy.

+
+ +
+ +
+
+

Messages

+
+
+class arroyo.types.BaseValue(*args, **kwds)
+
+
+property committable: Mapping[Partition, int]
+
+ +
+
+property payload: TMessagePayload
+
+ +
+
+replace(value: TReplaced) BaseValue[TReplaced]
+
+ +
+ +
+
+class arroyo.types.BrokerValue(payload: TMessagePayload, partition: Partition, offset: int, timestamp: datetime)
+

A payload received from the consumer or producer after it is done producing. +Partition, offset, and timestamp values are present.

+
+
+property committable: Mapping[Partition, int]
+
+ +
+
+property next_offset: int
+
+ +
+
+offset: int
+
+ +
+
+partition: Partition
+
+ +
+
+property payload: TMessagePayload
+
+ +
+
+replace(value: TReplaced) BaseValue[TReplaced]
+
+ +
+
+timestamp: datetime
+
+ +
+ +
+
+class arroyo.types.Commit(*args, **kwargs)
+
+ +
+
+class arroyo.types.FilteredPayload
+
+ +
+
+class arroyo.types.Message(value: BaseValue[TMessagePayload])
+

Contains a payload and partitions to be committed after processing. +Can either represent a single message from a Kafka broker (BrokerValue) +or something else, such as a number of messages grouped together for a +batch processing step (Payload).

+
+
+property committable: Mapping[Partition, int]
+
+ +
+
+property payload: TMessagePayload
+
+ +
+
+property payload_unfiltered: TMessagePayload
+
+ +
+
+replace(payload: TReplaced) Message[TReplaced]
+
+ +
+
+value: BaseValue[TMessagePayload]
+
+ +
+ +
+
+class arroyo.types.Partition(topic: 'Topic', index: 'int')
+
+
+index: int
+
+ +
+
+topic: Topic
+
+ +
+ +
+
+class arroyo.types.Topic(name: 'str')
+
+
+name: str
+
+ +
+ +
+
+class arroyo.types.Value(payload: TMessagePayload, committable: Mapping[Partition, int])
+

Any other payload that may not map 1:1 to a single message from a +consumer. May represent a batch spanning many partitions.

+
+
+property committable: Mapping[Partition, int]
+
+ +
+
+property payload: TMessagePayload
+
+ +
+
+replace(value: TReplaced) BaseValue[TReplaced]
+
+ +
+ +
+
+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/produce.html b/strategies/produce.html new file mode 100644 index 00000000..62c094d2 --- /dev/null +++ b/strategies/produce.html @@ -0,0 +1,241 @@ + + + + + + Produce - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Produce

+
+
+class arroyo.processing.strategies.produce.Produce(producer: Producer[TStrategyPayload], topic: Topic, next_step: ProcessingStrategy[FilteredPayload | TStrategyPayload], max_buffer_size: int = 10000)
+

This strategy can be used to produce Kafka messages to a destination topic. A typical use +case could be to consume messages from one topic, apply some transformations and then output +to another topic.

+

For each message received in the submit method, it attempts to produce a single Kafka message +in a thread. If there are too many pending futures, we MessageRejected will be raised to notify +stream processor to slow down.

+

On poll we check for completion of the produced messages. If the message has been successfully +produced then the message is submitted to the next step. If an error occured the exception will +be raised.

+

Important: The destination topic is always the topic passed into the constructor and not the +topic being referenced in the message itself (which typically refers to the original topic from +where the message was consumed from).

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/reduce.html b/strategies/reduce.html new file mode 100644 index 00000000..cd23f98a --- /dev/null +++ b/strategies/reduce.html @@ -0,0 +1,269 @@ + + + + + + Reduce (Fold) - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Reduce (Fold)

+

Accumulate messages based on a custom accumulator function

+
+
+class arroyo.processing.strategies.reduce.Reduce(max_batch_size: int, max_batch_time: float, accumulator: Callable[[TResult, BaseValue[TPayload]], TResult], initial_value: Callable[[], TResult], next_step: ProcessingStrategy[TResult])
+

Accumulates messages until the max size or max time condition is hit. +The accumulator function is run on each message in the order it is received.

+

Once the “batch” is full, the accumulated value is submitted to the next step.

+

This strategy propagates MessageRejected exceptions from the +downstream steps if they are thrown.

+
+
Parameters:
+
    +
  • max_batch_size – How many messages should be reduced into one at maximum.

  • +
  • max_batch_time – How much time (in seconds) should be spent reducing +messages together before flushing the batch.

  • +
+
+
+
+
+join(timeout: float | None = None) None
+

Terminates the strategy by joining the following step. +This method tries to flush the current batch no matter +whether the batch is ready or not.

+
+ +
+
+submit(message: Message[FilteredPayload | TPayload]) None
+

Accumulates messages in the current batch. +A new batch is created at the first message received.

+

This method tries to flush before adding the message +to the current batch. This is so that, if we receive +MessageRejected exception from the following step, +we can propagate the exception without processing the +new message. This allows the previous step to try again +without introducing duplications.

+
+ +
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/run_task.html b/strategies/run_task.html new file mode 100644 index 00000000..ac0a066d --- /dev/null +++ b/strategies/run_task.html @@ -0,0 +1,232 @@ + + + + + + Run Task - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Run Task

+
+
+class arroyo.processing.strategies.run_task.RunTask(function: Callable[[Message[TStrategyPayload]], TResult], next_step: ProcessingStrategy[FilteredPayload | TResult])
+

Basic strategy to run a custom processing function on a message.

+

The processing function provided can raise InvalidMessage to indicate that +the message is invalid and should be put in a dead letter queue.

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/run_task_in_threads.html b/strategies/run_task_in_threads.html new file mode 100644 index 00000000..9c1d5899 --- /dev/null +++ b/strategies/run_task_in_threads.html @@ -0,0 +1,239 @@ + + + + + + Run Task in Threads - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Run Task in Threads

+
+
+class arroyo.processing.strategies.run_task_in_threads.RunTaskInThreads(processing_function: Callable[[Message[TStrategyPayload]], TResult], concurrency: int, max_pending_futures: int, next_step: ProcessingStrategy[FilteredPayload | TResult])
+

This strategy can be used to run IO-bound tasks in parallel.

+

The user specifies a processing function (a callable that takes a message). For each message received +in the submit method, it runs that processing function. Once completed, the message is submitted +to the next step (with the payload containing the result of the processing function).

+

Since the processing function will be run in threads, avoid using objects which can be modified +by different threads or protect it using locks.

+

If there are too many pending futures, we MessageRejected will be raised to notify the stream processor +to slow down.

+

On poll we check for completion of futures. If processing is done, we submit to the next step. +If an error occured the original exception will be raised.

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/run_task_with_multiprocessing.html b/strategies/run_task_with_multiprocessing.html new file mode 100644 index 00000000..5587b564 --- /dev/null +++ b/strategies/run_task_with_multiprocessing.html @@ -0,0 +1,353 @@ + + + + + + Run Task with Multiprocessing - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Run Task with Multiprocessing

+
+
+class arroyo.processing.strategies.run_task_with_multiprocessing.RunTaskWithMultiprocessing(function: Callable[[Message[TStrategyPayload]], TResult], next_step: ProcessingStrategy[FilteredPayload | TResult], num_processes: int, max_batch_size: int, max_batch_time: float, input_block_size: int | None = None, output_block_size: int | None = None, max_input_block_size: int | None = None, max_output_block_size: int | None = None, initializer: Callable[[], None] | None = None)
+

Run a function in parallel across messages using subprocesses.

+

RunTaskWithMultiprocessing uses the multiprocessing stdlib module to +transform messages in parallel.

+
+
Parameters:
+
    +
  • function – The function to use for transforming.

  • +
  • next_step – The processing strategy to forward transformed messages to.

  • +
  • num_processes – The number of processes to spawn.

  • +
  • max_batch_size – Wait at most for this many messages before “closing” a batch.

  • +
  • max_batch_time – Wait at most for this many seconds before closing a batch.

  • +
  • input_block_size

    For each subprocess, a shared memory buffer of +input_block_size is allocated. This value should be at least +message_size * max_batch_size large, where message_size is the expected +average message size.

    +

    If the value is too small, the batch is implicitly broken up. In that +case, the +arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow +metric is emitted.

    +

    If the value is set to None, the input_block_size is automatically +adjusted to adapt to traffic. Keep in mind that this is a rather +experimental feature and less productionized than explicitly setting a +value.

    +

  • +
  • output_block_size

    Size of the shared memory buffer used to store +results. Like with input data, the batch is implicitly broken up on +overflow, and +arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow +metric is incremented.

    +

    Like with input_block_size, the value can be set to None to enable +automatic resizing.

    +

  • +
  • max_input_block_size – If automatic resizing is enabled, this sets an +upper limit on how large those blocks can get.

  • +
  • max_output_block_size – Same as max_input_block_size but for output +blocks.

  • +
  • initializer

    A function to run at the beginning of each subprocess.

    +

    Subprocesses are spawned without any of the state of the parent +process, they are entirely new Python interpreters. You might want to +re-initialize your Django application here.

    +

  • +
+
+
+
+

Number of processes

+

The metric +arroyo.strategies.run_task_with_multiprocessing.batches_in_progress +shows you how many processes arroyo is able to effectively use at any given +point.

+

The metric arroyo.strategies.run_task_with_multiprocessing.processes +shows how many processes arroyo was configured with.

+

If those two metrics don’t line up, your consumer is not bottlenecked on +number of processes. That’s a good thing, you want to have some reserve +capacity. But it means that increasing num_processes will not make your +consumer faster.

+
+
+

Batching

+

Arroyo sends messages in batches to subprocesses. max_batch_size and max_batch_time +should be tweaked for optimal performance. You can observe the effect in the following metrics:

+
    +
  • arroyo.strategies.run_task_with_multiprocessing.batch.size.msg: The number of messages per batch.

  • +
  • arroyo.strategies.run_task_with_multiprocessing.batch.size.bytes: The number of bytes used per batch.

  • +
+

The cost of batches (locking, synchronization) generally amortizes with +increased batch sizes. Too small batches, and this strategy will spend a +lot of time synchronizing between processes. Too large batches, however, +can cause your consumer to not use all processes effectively, as a lot of +time may be spent waiting for batches to fill up.

+

If batch.size.msg is flat (as in, it’s a perfectly straight line at a +constant), you are hitting max_batch_size. If batch.size.bytes is +flat, you are hitting input buffer overflow (see next section). If neither +are flat, you are hitting max_batch_time.

+
+
+

Input and output buffers

+

You want to keep an eye on these metrics:

+
    +
  1. arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow

  2. +
  3. arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow

  4. +
  5. arroyo.strategies.run_task_with_multiprocessing.batch.backpressure

  6. +
+

If batch.input.overflow is emitted at all, arroyo ran out of memory for +batching and started breaking up your batches into smaller ones. You want +to increase input_block_size in response. Note that when you do this, +you may have to re-tweak max_batch_size and max_batch_time, as you +were never hitting those configured limits before. Input overflow is not +really all that expensive in Arroyo, but since it affects how batching +works it can still make performance tuning of your consumer more confusing. +Best to avoid it anyway.

+

If batch.output.overflow is emitted at all, arroyo ran out of memory +when fetching the data from subprocesses, and so the response from +subprocesses to the main processes is chunked. Output overflow is very +expensive, and you want to avoid it. Increase output_block_size in +response.

+

If batch.backpressure is continuously emitted, you are not bottlenecked +on multiprocessing at all, but instead the next strategy can’t keep up and +is applying backpressure. You can likely reduce num_processes and won’t +notice a performance regression.

+
+
+

How to tune your consumer

+

Note that it doesn’t make sense to fix output overflow without fixing input +overflow first. If you increase output block size to get rid of output +overflows, then increase input block size, your effective batch size may +increase to a point where you encounter output overflow again. If you +encounter a lot of issues at once, best to fix them in this order:

+
    +
  1. First, tune input_block_size to fix input overflow. This will +increase average/effective batch size.

  2. +
  3. Then, tune max_batch_size and max_batch_time so that you get the +highest throughput. Test this by running your consumer on a backlog of +messages and look at consumer offset rate, or time it takes to get consumer +lag back to normal.

  4. +
  5. Then, tune output_block_size to fix output overflow. If in your +previous tests there was a lot of output overflow, this will remove a lot +of CPU load from your consumer and potentially also increase throughput.

  6. +
  7. Now take a look at the batch.backpressure metric. If it is emitted, +you need to optimize the next strategy (next_step) because that’s what +you’re bottlenecked on. If it is not emitted, you may need to increase +num_processes or increase batch size.

  8. +
+
+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/strategies/unfold.html b/strategies/unfold.html new file mode 100644 index 00000000..5f20a2a4 --- /dev/null +++ b/strategies/unfold.html @@ -0,0 +1,238 @@ + + + + + + Unfold - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

Unfold

+

Generates a sequence of messages from a single message based on a custom generator function

+
+
+class arroyo.processing.strategies.unfold.Unfold(generator: Callable[[TInput], Collection[TOutput]], next_step: ProcessingStrategy[FilteredPayload | TOutput])
+

Unfold receives a message and explodes it to generate a collection of +messages submitting them one by one to the next step. The generated +messages are created according to the generator function provided by the user.

+

The generator function provided must return a collection (i.e. a class that +implements sized + iterable).

+

If this step receives a MessageRejected exception from the next +step it keeps the remaining messages and attempts to submit +them on subsequent calls to poll

+
+ +
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/what_for.html b/what_for.html new file mode 100644 index 00000000..60193bf3 --- /dev/null +++ b/what_for.html @@ -0,0 +1,482 @@ + + + + + + What is Arroyo for? - Arroyo documentation + + + + + + + + + + + + +
+
+
+ + + + Arroyo + + +
+ + +
+
+
+
+ + + + +
+ +
+
+
+
+

What is Arroyo for?

+

Arroyo is a library for writing high-throughput, testable kafka +consumers and producers. This document attempts to outline the +intricacies of writing such consumers.

+
+

Goals

+
    +
  1. Make it easy to build consumers that provide delivery guarantees

  2. +
  3. Make it easy to write high-throughput kafka consumers

  4. +
  5. Make it easy to write reliable, high throughput kafka producers

  6. +
  7. Abstract away rebalancing such that users of the library do not have +to worry about it

  8. +
  9. Make it possible to test kafka consumer logic without having to +reproduce the entire kafka environment

  10. +
  11. Provide a way for the application logic to signal backpressure

  12. +
+
+
+

Why Simple Doesn’t Cut It

+

When visualizing event-driven architecture, Kafka is viewed as an +abstract queue with groups of producers pushing to it, and consumers +consuming from it (as in the diagram below).

+
+ graph TD + Producer --> Kafka_Topic + Kafka_Topic --> Consumer + Consumer --> Destination +

A more accurate model is that kafka is like a log file which is +persistent and there are offsets of the file that different consumers +have read or not read.

+

The most simple kafka consumer looks something like this:

+
from confluent_kafka import Consumer
+
+conf = {
+    "bootstrap.servers": "localhost:9092",
+    "group.id": "my_group",
+    "auto.offset.reset": "latest",
+}
+
+consumer = Consumer(conf)
+consumer.subscribe(["my_topic"])
+
+while True:
+    message = consumer.poll()
+    send_to_destination(process_message(message))
+
+
+

This simple consumer would not satisfy the goals mentioned at the top of +this page. The following subsections will explain why

+
+
+

Providing delivery guarantees

+

By default, a consumer in the confluent_kafka library will +auto-commit on poll. To understand what it means to commit to a kafka +topic, see the Appendix. This can lead to the following issue:

+
# get message from kafka, commit immediately
+message = consumer.poll()
+# ❗❗❗ throws exception due to a network issue
+send_to_destination(process_message(message))
+# this message is now lost and we're on to the next one
+
+
+

This can be fixed by only committing after we know that the message has +reached its destination in the following way:

+
# add this value to the config:
+"enable.auto.commit": "false"
+# -------
+message = consumer.poll(timeout=0)
+send_to_destination(process_message(message))
+consumer.commit(message.offset())
+
+
+
+
+

High Throughput

+

The previous section has allowed us to not commit messages that are not +processed however committing every message severely hurts throughput. +Every call to commit is a network operation, it also makes the broker +persist and replicate the information. If we can reduce the number of +commit calls, our throughput can be much higher. And so we commit in +batches

+
# this code is purely descriptive.
+# We have to commit to each partition separately
+# but that code is not helpful for this example
+message = consumer.poll(timeout=0)
+batch.append(process_message(message))
+if len(batch) == batch_size:
+    consumer.commit(offsets=[m.offset() for m in batch])
+
+
+

This will get us faster throughput however we are currently hand-waving +away how we send the message to its destination

+
+
+

Reliable High Throughput Batched Producers

+

Producing to Kafka reliably and at high throughput is not a simple +operation. Here is how a simple Kafka Producer looks in code:

+
from confluent_kafka import Producer
+
+conf = {
+  "bootstrap.servers": "localhost:9092",
+}
+producer = Producer(conf)
+def send_to_destination(message):
+    # ❗ This does not do what it says
+    # it writes to a buffer
+    producer.produce("destination_topic", message)
+    # this will actually block until the messages are produced
+    # calling this after produce every time is very expensive,
+    # how often we flush has high impacts on the producer throughput
+    producer.flush()
+
+
+

At a high level, the producer is actually buffering the messages +produced to the topic

+_images/kafka_producer.png +

A kafka producer writes to an internal buffer. This batches the IO +(good) but you don’t know when it will ever make it to the +destination

+

In order to allow for reliability of transmission, the +confluent_kafka library provides a callback to +produce +like so

+
def delivery_callback(error, message):
+    # do something here to make sure your message is in the state
+    # you want it to be
+
+producer.produce("destination_topic", message, on_delivery=delivery_callback)
+
+
+
+
+

Dealing With Rebalancing

+
+

What is Rebalancing

+

A kafka topic is divided into n partitions, each partition can be +consumed by exactly one consumer per consumer +group. A consumer can +consume multiple partitions

+
+_images/consumer_groups.png +
+
+
+

When Rebalancing Can Happen

+

Rebalancing can happen due to:

+
    +
  • An addition or removal of a consumer to a consumer group

    +
      +
    • (Every deploy does this)

    • +
    +
  • +
  • A rebalance being kicked off manually

  • +
  • A consumer pod dies and now its partition needs to be re-assigned

  • +
  • Whenever the broker decides it’s a good idea (it can happen at any +time)

  • +
  • TODO: More things?

  • +
+
+
+

How Rebalancing Affects a Consumer

+

Rebalancing is annoying to handle for a consumer that processes batches, +imagine the following scenario:

+
+ sequenceDiagram + Broker->>Consumer: message + activate Consumer + note right of Consumer: start building batch + Broker->>Consumer: message + Broker->>Consumer: Revoke Partition + deactivate Consumer + Consumer->>Broker: commit batch + note left of Broker: Received commit from revoked Consumer! +

Once a partition is revoked for a consumer, it cannot commit to it. This +is bad news for the batch that the consumer has built up. Each consumer +has different requirements but a decision has to be made as to whether +to flush the batch or to discard its work and let the next consumer +assigned to this partition pick it up. The rebalancing behavior can be +customized by providing an on_revoke callback to the consumer when +subscribing.

+
from confluent_kafka import Consumer
+
+conf = {
+    "bootstrap.servers": "localhost:9092",
+    "group.id": "my_group",
+    "auto.offset.reset": "latest",
+}
+
+def flush_current_batch(consumer, partitions):
+    # flush the current batch
+    pass
+
+consumer = Consumer(conf)
+consumer.subscribe(["my_topic"], on_revoke=flush_current_batch)
+
+
+
+
+
+

librdkafka’s Callback Hell

+

librdkafka uses callbacks as a core mechanic for control flow. A few +such examples have been mentioned in this document already. What is not +clear however, is that callbacks are only called when ``poll`` is +called

+

This means that:

+
    +
  • this line could possibly do a lot of work:

  • +
+
# any scheduled callbacks will run within this call
+message = consumer.poll()
+
+
+
    +
  • No callbacks will be invoked until the consumer or producer call +poll again (for their respective callbacks)

  • +
  • poll has to be called periodically on a consumer otherwise the +broker will kick the consumer out of the consumer group

    +
      +
    • The handling of that revocation won’t happen until poll is +called

    • +
    +
  • +
+
+
+

Conclusion

+

There are many intricacies and gotchas to writing high performant, +reliable kafka consumers. This document does not outline all of them but +all of what is outlined here should be kept in mind when designing any +kafka consumer library.

+
+
+

Appendix

+
+
+

Committing to a Kafka Topic

+

A consumer comitting to a topic signals to the broker that this message +has been processed. When poll is called next by that consumer, it +will return the next message.

+

API +Doc

+
+
+

What is a Kafka Consumer Group

+

https://www.educba.com/kafka-consumer-group/

+
+
+ +
+ + + +
+
+
+
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file