From 26fbbe525264e72af07584daa4932322d405a236 Mon Sep 17 00:00:00 2001 From: Anton Afanasyeu Date: Thu, 21 May 2026 19:06:10 +0200 Subject: [PATCH] snap next steps egress review --- 20260521_next_gen_steps_egress_review.pdf | 165 ++++++++ .../drawable/settings_app_info_divider.xml | 5 + .../res/layout/fragment_cast_settings.xml | 7 + app/src/main/res/values-night/colors.xml | 1 + app/src/main/res/values/colors.xml | 1 + docs/_pdf_build/build_egress_review_pdf.py | 383 ++++++++++++++++++ docs/_pdf_build/diagram_current_arch.mmd | 15 + docs/_pdf_build/diagram_current_arch.png | Bin 0 -> 24263 bytes .../_pdf_build/diagram_multicast_proposal.mmd | 9 + .../_pdf_build/diagram_multicast_proposal.png | Bin 0 -> 20569 bytes 10 files changed, 586 insertions(+) create mode 100644 20260521_next_gen_steps_egress_review.pdf create mode 100644 app/src/main/res/drawable/settings_app_info_divider.xml create mode 100644 docs/_pdf_build/build_egress_review_pdf.py create mode 100644 docs/_pdf_build/diagram_current_arch.mmd create mode 100644 docs/_pdf_build/diagram_current_arch.png create mode 100644 docs/_pdf_build/diagram_multicast_proposal.mmd create mode 100644 docs/_pdf_build/diagram_multicast_proposal.png diff --git a/20260521_next_gen_steps_egress_review.pdf b/20260521_next_gen_steps_egress_review.pdf new file mode 100644 index 0000000..2abf601 --- /dev/null +++ b/20260521_next_gen_steps_egress_review.pdf @@ -0,0 +1,165 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document (opensource) +1 0 obj +<< +/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 6 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/BaseFont /Symbol /Name /F3 /Subtype /Type1 /Type /Font +>> +endobj +5 0 obj +<< +/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 340 /Length 27546 /Subtype /Image + /Type /XObject /Width 1384 +>> +stream +Gb"-VO'c,aU&XXIl0duGHZu3I3#c"/W@0?6.9;=+W01nbcW/TNF8[F1c9V&dbqC29hTC.DlIZprcDWD(HNU]iMX;N\:mgjSYD]\E7RE+hr:it*@]-c#'HGWpAf8TN*(-g)a8Dt67m#U+j463n`f&4-XGKFgHU+bUCn#U+j463n`f&4-XGKFgHU+bUCn#U+j463n`f&4-XGKFgHU+bUCn#U+j463n`f&4-XGKFgHU+bY6PS3:)!p1u#Tj'9=R@ePgW#U+j463n`UbhI(9E+7g.!":V>[*S3uAG2$Y#U+j463n`UN5m.lap8!"N/sU,2^!bb63n`f/DSSk!/@4,+G::m#U+jPkg17KL8$ULKFgHU+bVE1cl2t>U,O3J&4-XGKIl=WLNE7o=l8%np?Z^dt_I`Dkbuita@,2)9s[&=d(!J\#EiYG,8kDa4ROKFgHU=jU<']g5T-kjDMK7^g?BF"d*V9Ph&4-XGKTHA.-.j1/\7Vo7Qni-Mgu"2H']kSD@l$trS%lrekR@qeDa4ROKFgHU=jUReEp-ERAV8/ard)kEAbLBa^8`oU=,/_d'6SJ/h=DkN]hO.b3KNDbHeQSp#>u'fd<;!Cs&AlN[g;9$\f'.h3_e@-$,T_9%h^])(\Mon7*7Z*JE2Z:d54t_!f3tRE$M`lkJj*8V>8GEQdC.,#(plYKLID>,2G?eNS/T!V2qthuN/_+:264"';@\uG7'C7(H;]Oe7%g;]4i#ZPqUjkbbL9`Hns%Nb%=qp$=>gn5X4*urMq";4Sur[f1\f(kOj[j6b9A8[%S]]';O$+<\m!8N\K'%2@"2S6?X.fRe06?X4k`6Q1HR-c:YWlscr]6f+Y5.NhEX6GeTAscYr*(P;<)pP1;.,,3k(QLbM(m^`KbXPXKb@>jBJL"$s>r95R8Nd&4-Y*crkt6J_)>F:0nnW]2[I2=GUMj9e4`2gP17kLKH_t0_Z@WRCm*&/V\,6-3a:ZYHKOG$+m$?2j3F;RX4"G7:*GkD6ZI1o\VLmI)^piX/R3=",\>t3V>!kn^8+GnR-3CmK\eumdqSW$OH\rLS;0/JeMCHPH7tTl.Ji%T\DCV$El?LMaAKUiOh],'^HDA/&]N#NOl*'3[>g4-Mj<#^-'f$e"%!8:KFgJkK$G"q%6>u8JH=YAd&0Qcq_*3e@(B0kM:)88':5Gj-6m0ucFlO/=iDDEVmCL,p>2HdC;c:M[C9Y:V0pU&gWK=&?:ifhb^=h+Uc56Bkm]+*Qcb"Y`qJ53`M\'8hT6@&Z+H\d0,QZ*3d*6mk&@[dkSP8D=k6:?Cas>o2`]CTc"Hm=OA5?OKFgHU+bYp\SL)o-`-s=JPkO*ap"21mV!m"VkfdfXV0I%6S,F_Qkff;Zc);q!%SZD.6Xdo=BK\pI+LM0_-Xqol[+ZkeNn-kXC8BJ%8!]9:nC^:Llb_aFY>CVhAXDq\0qM,Pbg%J7mp+fYo20:Y=5lG7cX'J*?1./4ru#JUPp%X!a1Dp'AjII.\cJ8s-k@qE9e?%\Gc^FaB6mKt$eqIds=A+bUCn(3GjADZI*HVE^AT_Rn+cO^oQI!?m+-63n`F6&4:sL71q.4?_L1kHd&AOtuj!l/TlLH36J>+bUCnaFXo8!=\(\*-'Uh1qQd`N@r2u5bU+ZKFgHU+bVE9cl2t>b#E9j%fDS(jZ;";"Oql!!&BNH37VckR@MZd2N&c!+>fi%>]k72ZO7TDZBb;JGGs!+=;j"!&,,#!It?u2]=5i4_q;SZWVsfFP22bXXKN0+-jC6VUV5(dt[s3WM)6n-AL@W0GM2$J;)0&3[/D+C.e)FhE;q;iR4/X(6R3I[sTW+#;s4g2>QMU3+;YS!%^#"#/nI,)ZYVe2ZU'IN@?*(Y,:-QU?]8p.\4e/oNpRXI_FSY=p$XkIV4hg-i,WlTihKiB%Y8:o@ZlLeL&"F@ZF>]fP!"nWq/"I'd`bgi@b=H\8cLAWpW%7OKh#4Js`>q<2pKTecqU2fMkeTOYmXjMe+'Mm;kI25D\oC,VXRF_hKi:=OOF&sa8`L?2V9iUgDVYC:E1`ng`'F7UPdiikI`Eb_DWg#oYsM2=T`':8KY!s%"BDa6u)]`DLhH34-TPgat>nR(SHOh3%!hc;4Q'Yes9++6"uGB-*-%27T@lL,15&Xul\iS,2._hN^SLKH_t0Jc)hQp&4C<0KZt8pBXTHDZ%AkaX#c&R3LadqA::b[KZ,#*i*7cX'."Uf^QX"eBfm'+j!41#k&/.EL!#UUM!5JY9e"[t"9?QW,cD0+PH0"W&QXZ$DHX[KY9A;'[Khs*,`QbWoj.[+%As7&>4H6T+e_/rC_0^(g%C?LX1XqhFef+`1Q6j3sWJ72eQlL*'*HDjtETAdZj=bGm=6C@p4GV=`&Vo\6\d"U/.jot)@qJ/J!5KTH#/nGjW])od1#0#Q=B#JX%*sFTTJlkT5\Zj/&8YYb44--`*n5+)&'oT?5J$>AoUN8A133Q=>&*BjNK4BQWTMIa-hbDkKe=!l6s;.DPFVLUtj(:!m+k)ZVPq]`BiBRHb7Gp94p@:!*'H%JhtBWQUq"M_H1SngZTY:7K=]oI^;ueVFeBa44agJmoJgi3eqTm3I6_ETqRo1p+h=)J\b?M?_3fB,0VWS=F$risQ:rS$mOd-'Z`GoGIX+)VX\%$[WO_jH.o/=f(B5a@TdX@\q+8`7.=0U<Z/+..*qlDt%910C&SK!)9E#9V&B4HjOmb6!MB(H5WmdFI>ATGdV2dZV_Zjt(/8\FQV9<\8PnkNC(?Yk7mcZSGUmcpbDie^)PKJ]^_l(d3h]eMZ/%iQNo8>PA?dR.SE7n+&8QbQ5PF>c-Q&1nf-;5g4cK8'ZpG;Nm/a"W!!+ZPP!AQ>$#!c)Y"or%gSqPEK!!"G>#/o$<)ZWIW)ZYC;HKYe<+;oJ-@UeO1J>DB)09!!!"\46R-p*("QD(lI/M!!!#0KAM.&+nPthU$)pc!!&*BkRGTQ6>li@MV\=5!!'Q^hLNfnoEKi>kR@Ll!0B;+%Ha)Mj5ZkIpR1FB/6lpBMqFH>77;pEe9V4H8?&W^8G6L9/;7+t93%r2$I!?fiNW1M[\:/,-O\+4KWnT*i@]2mK>("g]AB_*=c:2R9po9+6aBVPmZG+"P+LAT/#&uqla4T*[(?FJG0qZBe<@gmm#l=R3Vkk_Z90"O61lKp#^%H*X%N9&D/nlV5,.XE9Oj3Hje2UtD=m>Wcl2rb!$HL4)pC,1#4orgkRG0lMH!\Z@MS9i2'.g^V;9m4Wua$Wc='a+c\0L0OQG?_Pg1F@=Io+"q-@:_f$9j&GEX#<@j@,W1T8g7)DYD_BZJWrWXc'@E`ZPp1X+PleJUTTKkM?^,coXC-!C?-Q2VX,AsH@&V&otEa9]WEgRci3@(BRQ$.ju.O1ETdi3!!&*BkRHYlH@u$(%_]^7G?`m@kN0n$fSRW@#3s%%e^[SFM/[sbr9%,/1?t#jCiA8(9GIklgt-AhiFca[G#(a(EkC/)*\u'P2i'VrU4(N@Ca!^kiWTQu7B5jUQ]gHh'e-JlG+G*ap$`0E=Om$J!!!#?*LZ:(#0+^8mlW4*$`oNDZF40=I,"/cpm)"plp^5oA1b)Z8%,TC+$QkKKUs/*09EU^B\RDXfcl)K@[E,DX016#7'`k+'Y>lR`iknh*jH2[+0XOL;R2W[6EDiESia0)I!dpD^c'`rZt17qX&.IlZ2+2^?AIt7'>%MRAHu:&D!"X"/%GFSP)DHN`/JQ[]D-d(KG4&3S-/FLK&%eSZPk:Ui!e%I6Acg)]2X0g3pUhXuAmoNHB'5<5UW!2u*Aom_*ht;boRUq<)CtM8o2mm6cbm.fHc8`08\\9NQ!p]qpBm/$`>>h3E"/(d4h!W:`__LUsKkAIc8s1OY3E&Ue)8Tb)6OjR!&PY,UW9F.C(Nib[tDm%s!9Y:-dR>Lhd+aeWuQ3jG]+;I*+U\tK&2R3UUN;W7=;cSj8nRI6?*6E-igZ_=Ut6+nHgG"Z1h9raQ;]A#jQ3ZDhG-`eLV,J?Be=:t8_r/pSPL'tF0;%I`.Cag::ErNkb/&GJ83c\>N>s!/9=!+UsONnj'II@$Dl2rC[W?AE`D;7FdcIoR9<>UIB1C(&k&$Of;VFX8N:t!XE?"OD7L-3B:=gXQ+l"*anAdJLsper:%h\hB4L9Y&fS#brO=Yc0Yt78)JLe4\n66pqVF+\DG$OV5VH-iN=HHojRO_ZTd;]Xm>ECFg^rLWOP$1]GVSVQ"SMt/7#B\0)n1HUK8Lo*;P?+8kJ&nHDEPXj:)PmB]o#C're.B8.qL`=1!.4Va!PamdsKo>.QlArk8DGCQB`$qHM++c8k.-_3!Ym&!dKjef48)MH&0c/@>%nHb0)EMqm/%8Nh$1o;[S`;N8"Z%!Hh'KdOt]"1,`@U"6DXW]*bXVPs"8(InC>+*YP_3oDJpD.3?,oM]%Xkb8G2dG=(-$B9`Ea&62s<5!k.c(00*_,O($2ZNgX^uCIGhOm,)_l'sk^(N[m#dnP1]t6g/^YjP&(jY&Tbi/Tqe)Si.?gXB\9#UAlmeG(Kiru18qRKnZq:Kn_fi9^^T4iD>rCT4WkVphC_r7l*Z&otaQL3m^Y!@C1jghk8r)-']I/L<.ThoEEFS+aKUI&elo]HaEN/Y8BNT>q-QepLW*#$q\/,+jH552Ri:$7k8?PE0M5I!*7g9o7rcX2m3e`WB%CF=7cN//4\Id+F6rI'%E[H1lnk?U0WPqM(Nh#5(7($b8NY?d?LRm!p$\jq@7JSh#^KZiu_19iD0)S,F9LH-#jD1!C-ilmqCoalI]eN^HMX&o"K(LGb#B?uU*4SRWPdGK0:hQ?bIbVRR5-bfHBX)Yo@h7NEt#Cisf`tQc`^J4\&lDr7MrG60"rlQb;e^_4;oBb3(e4VI^N9q(]gjQYSTDN,NH@r6Cahl+"jt%T+(ll8C]f5fXHKp'oHDs`XO`f[\']eNYSlaHhL#c&@Ge4lbg7/&kA+N%G#lC*co=*'rYb[k5`L3h)6I>WH1U0u2a14P&+f@f]NYtGSh!SF%DD_Z(LLFXEolo=59Cd^HJmu*%NIp_mF-$92gX(8mY+^(GCWgERYcD>"1;5[&_?@':A3^oU;3]q7)*sAc3rnK.6mOKkk[S0k*Y[a(^k:Z.2cI,PH[kG'`g)J,Bg4PPlY9[r<8*uSKN_OFb(9>u_&X(CU(&d+J`&X`!>\n>O0"OY\FN>DJ^tr6A]^f0@DkOfA?r6UXr\E+FoW)UWBko.0d17;rp;J;?nC3cIiR,12Vn+(X4JpAs]/G/iRl0?[q.P>'8m.leASD'k2RKJ9FiW-QMC[5j)%%mo,%&F(Q[A1-D*bWTM"3\5c]oHu_m-^;-lQBmfh`gufmH>U,e"V]'_2]MH@U]BeF2bTb'T#5/':[2isq%VEgAgBSXCg3@iSep3VOK-DJANM,\Ok3\acUi;<4e]>DA?^_8.%^:ct:mbXbQJbF?jhbr:B$]5<*(=i]n+JRS`]DsL#)e0!!'RIT^Ph+%PZYgMsB>pXVFb+^pDtphAseXmsfh5A7T6I2#to4?i?sME;d`l?ar5M?%m@;rrV)@@-Q:SUBHN^N@23gtkM(h\lEVbdA'Zq'fQ2#oKD,c>K8C]LJ*WBk6@7gA=mK2<&,M2:/(tqUYJsB7H&5,US9/4VDrBoL.TCol2e_C@MS-U:VTYMPpHF<,pBF!I27M,IWAB_*pMhE^8d:31ZJ6>li(!.`jeg"rAR0YVJKQLeaLmlPr(=P(pY?d.n;t#d.D,E2h/8cQM2hALX4QED/695oT>^-c_"u7H*2#IcF=BDcp+!pD\._0l@=&WF6Cm:4+=&DqtBXA!NBW(p(Afnm`:g35XBPI>"NC;;eIJCm#.CK/[CV38'VBSk*ls)#,$%:`84nrHE4Ue:S'XTZMf;R86:gNC5;;%@6`@E*>fXGFo7c6Y,t`[FT#bBZIL=XKs6l!R;lt9_Kr6gSD67kr<3M,Y*%#";[qL"hOpgG0X`^_(tT_*gA;UnXXp`7p6M.BO3cA?OfYC3m?P*8ML&t)Dg1jbNn&I\KXEr=l2'[6>$Nq5h7f2XTR'bEbGP70h&Z=bK`&!m8q12eW%ZRQGX@:oXKJn;6(N(RX3E,1lC>6a=DNVgbUU1b)uBC8g:[UU[H`lp0^5*+0CITO5X"J!8t+Q^Q@?TX]76p/kp_f??aUGH'[4T^0)F^23f8OAXU=HDgM*5X8%ohn5%CZLBZYFe%#AUNm2IF2sb*'SQh\eOh5P3RH^ZJ3on.SGGCIC'%%)5kcVid-7M-$F&iM'Sni7Fq'#G%tB$0K_O*IGgVVBD(8r.W8OT1RGeX?8b[d7)+iR8Dng1g?gs0XP/R;;I(OG3@>iUM7l2QL@th6UZoUo12!q(Ff767=eX*p=P.4h6iN+aU*(\o6!./+]q^9-/p0_MZCE5$6#Ui:o`-f*6ts'=X%EW/3hgP*8H6IfknV<>Dij8HVDk/,!!!"$ZKBgZ9MS>h]Qiu)_1Pt#CtZ76>;-m6*ZbfF68rf;q!+o`&s)@8IM+m&+T7h@4tbNt?TGDUj.f5j;X4dB/>G-(!!#:PQpYdG3B;BYm+GHHH0)jI+0;QFgq7q(_1N!=T0N@25PuZ48$%V1F6a:.M8VjE_pfV85.)!FRU-!rr<$j:;.Fi6*dg4Eg)Dk09Ca\DrUh`l=cDO+-W<(TG\RDm4=MDZCW3h>dNU!4a=gD\*0W?@2(I!mbL,,nW059k<&.Fo;=hOBl6]teRQ_9PGOE;+,4I&2ZT#82ZNgX5VBQdj2-?LN=O"B:8e'HGMiAjTDq%RkE^dKVpH@_8^SIW!!'f&s8(@:WDc$2m'65a]nM4lj.P+jl8!!%PsqYPd8o[D?[2ch"[depSh?-tY[]`BiBoEIQYoEG9q!&2\'+*;DQ:pt@Rq71RedlBY+!AQ>$#!c)Y"onW'0Z())YMXj0:S)joa]*1M8;c8SQl(,O+=VU=!!!"0&3Fs(5oPLs6ag>)4K;RkRE?)Tf2t7U,N&P!5L]k9a0F!j2F+KZlD4'o"Y/]YNM5D#/nI,)ZWIW)ZTj<@*\cIcYII3n`"&>X`&--2'XoQ2]sH%h>g*(h>dNU!-<5Ni6-?"@EDJYTV4:e-AL@W8;c7(!!!#Ve`"ELh0%>?XfX6fI*V?g`5H2j2u(oV`mmF.?u\0?pBJ;3!!!#IFQ15iJqEomrN'GQT7!SuhLLu\9_AV+:PJsaJ48S^.(oW]!!$VNp?]&L/+7iLV4E,7lgKd:$G?Hp0q%;9!$k!O!!!#'=:G]6.OuT]]:Clu>Vpb0oEN7Pcl2t>U,N&P!*FVdhYc$nG!>cd]$ES+b0CXa%>]k72ZO7TDZBb;YfOKNg9/T@LX)JSQHb-3)\dNU@*s5^Sc?FiXue^,pLSj%oEN7Pcl2t>U,N&P!*B@fq8?K@]!AU2)2#XU@93")`5L"A!/@4,!!!"$d/NNirYJqCEB6%;N-oU,N&P!*G'TrjPt1=Phd.P3F4=cl3N06Z2rAMV\=5!+972qWi[T[;js0a!W2dR6HudH37VckR@MZd2N&c!%]70D0pa.e,+K=:RF>/3:mEn`6]G'L8$U,!!$+4qYO'l>'8a%rOYcG8Q,0b`5L"A!/@4,!!!#?I4r7;rNXDohmd[BoT>q9Da6u)]`DLhH34-IJ6[9oFF-GFl$Mm,R6D73oEN7Pcl2t>U,N&P!6@m?r9:(QO6kTnPj'Da#JC-m1%Y[#U$)pc!!%&dOX&+8q8n[^rqMhWO!IHl#/nI,)ZYVe2ZNgXa=5`DSU9kBTC1H8Du*#='7'ai@d"7$6dZhQ!!))?rVKrLm'64bYP+>IP4+:bJ=%1""2Ib*"onW'\R9CGrSlfOmHq*E5*EIM2]sH%h>f5D]`A*5JEcdqI=B(gZE^ZmVN595kRE?)Tf2r[7;i/+!+;OP!M@iOiTS[]R6HdZU,O2AL>Dna'YOMI!.\3YHYqB0O04].:JDqQr6ZGp'16[<(lI/M!!"/=IeUH1%m8e6m+c7M82>nUJ=%1""2Ib*"onW'=a'"*e&)^"]m6s1oTkR@Ll!4$3YeA$>&",l*d$kgr,&/.EL!#UUM!!!!A45/Fr?*gCf'`,oCOViZ+J=%1""2Ib*"onW'7[odTZt%.?DnPV7kp%nm]`BiBoEKi>kR@Ll!"=#@A?3VQr5t989HT+bkRE?)Tf2r[7;i/+!+;>!>;u!,]u0JNA-'@E0er;)J>)09!!!"XnDT.@hg=fT++87JoTkR@Ll!&AHdmN#(dosj8(a=nmnfc,KV]e"(Ga'%0/cC)ZTj]k72ZO7TDZBb;0Ro:MQRaR.g:r-Hkp%nj]`BiBoEKi>kR@Ll!9U8mqrk`fhXfE5?)E\$7.^]%`6]G'L8$U,!!&CI]"5"jpHENl0MFuT5YMU"!FR=%!rr=O\JZ7Rh0\TR52Tet8!48D%>]k72ZO7TDZBb;0F%gm1d:d"]#i(;VN2umcl3N06Z2rAMV\=5!8or,R(-+%^?4TCD_c_d3JH=?Ql(,O^ejY-!!!#`4*BiO%`e-JYhSf4j;N=H@UeO1!(5-Q!!!"pWM\g7(LGa3qClq']`BiBoEKi>kR@Ll!+lrO]P"S4rT6%/9clsPU,O2AL>Dna'YOMI!._e3qs(5_+.eo.RQcm>7W1Oc%(u[L.!bsq!.\$dhYamjFQJW0c)-OIpX'ok'16[<(lI/M!!",jO6=:\%ld$J4u@[5$Ne!B0er;)J>)09!!!!3D;Denjd11[5)]YuhLLt1H3:rZ\^h_toD_;Z0f9:h@"1+b^V5,g)E*)9!1EP1h[H!gF2e"u-^Q*HfF7"sbc!N7l#4:;smFR,7X#F^=cMZ4E%!qlO02*HT2Q73#rfcsYA79,uoEN'ZF'*jX1];1lRF8D6>4@a2HI=Q-3S5:@IJ48XX8iXUf3^'*T>"q6IN@aUBDCK`IkcAr!#a;Tru^-fk3lQ[g7B7t*r8+Mf*j>l(OU_02]rJkMl&H&rF/0CQo"\Y!L`MZ?[P:\&0#ot5c-I?Z@^p5a=MW>Z3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDZ3Wd8JDWJl(1f'`GG._@p!.2MKYpF;daPiQAkcCQ4b@aUH2UYgeMB@6cV!lHOSBbg2.O:$2+T&OA]*EOmL%R=O[SdeWAqnLl!t9)j!K"H@n$lpOJuQpJ2QjeHfTi9#=lrO9^3%)Ko_b61p"uWd:;K'%@/TMF*fI]hXk@%9h`_#'!cW]g6:%O[S;-HY%:k8aDbeWZLs-Ud('QVph5'V:O0NlV=-ZWkM/KFnN+bp(UOa=G;Z=l/;2gXg:IXg+d;"H\5S[d;o%@MR1fY"7MQVS(@C?_jF0:6OqUtP)D(5a(Rp6+\M6F('Coor#lgtsjd\L$+'`]ZFqhlK1#pCVJ'TJn!O+S5lE1AV$jl'X"6QLAp'AX9R32?mgZnLjK#a'.YK)>,s[D\/6=d2S=XNX6jQa#2=aGU1@uk.RSU&=LCRoW61aFTSeq'7RAI`-#eXfN;F\\qm/.k5:Dj.)C7TXB@?;r@!>ERIal)p7<6#Fo(:Ws13K2,#1Kmi7YG'AD'gFK)tQ4ij!UO=;^_X3Je%]^j[AWEJP2XM];FXDf:YtNRg[ea7Pe^A4b/=.VT=eX)=mo!e)d68.j-#-ka1MKIo,*;o((kYm1\Q%&2fhbeuTO,kU];;^E-L&]DP:g-R'rc6i;N7`o@4uY9(XZPEP]X^3+[lZLoS2[405GLiX*6s5FkeH@[>H`bgtpt\HgWL8.;E^:r8SlK)kCYIDkPtKg1pfUAh8]]h/@f(9aYa.(a7f(^keQUD9N_/t2SL*R&PGA:Ogt)b\H^IuDFQRW$/.L$tRG/\9EJNYl#>;Y>IM"Zh\DBJtW:JP$dbd6r>`TghLX,?#4J=QJ@7VC>Zg.SQ2`EhFNEN>k?c$Bn^C5:?MPg8<6G4mA2"0r3<&:4M;jbKmuOd4$cTak2=BlhmTqO1S]RS<#Y,fA?>#[flqZrM$<#Wk0fh?X3[4$:1%"pV;'Jcmi-5Sp.1@A^SP2K?qKBDTk*]%\GH%+>j]3k.\8Z]#q=0n@#;+%gTZ!!B77SE>1_TdlY>mFS1V$V7^gjWB0i64Hc(9>Kq_?a:o>+%U:\r9'H.>iNi<7j;H\d]d*gh=l0]WFEdLG)Mqg6Is8KikfHoekHS@52>@J=Qm<.^d<_mXXCU:U-L;K(RUHS\t)Y/W;-FDaN>nNV^B[=2YKjq9u@jj0:eegs3/#HL]c779)ges7V)@Z6K9fh#2P&U'&Q7!^BXM$pd.S[=.N7c@um1&XXQYC[%`Pmkh?iMc^r_tWIEtRa:ML%'mYO$#j;h$G1H(7HMNMJXuc:t(?&LQr"8N/,iD,k5H:35PY>@@=%(hm;HS[G87*L#oDrUQc0h+ObVV]%h[^/j?`ZjTN.X/jE.d+IQILQ$O@L:P"6pV6`VFYCAmXujeK6U2@6^*FmMX-_6Xe1T3-k;rUc`O%l7kW6_'02i(,ppBK>96b@+)$gRo^'paqD+ZXsWGCED;TJc9nl*4F,;CEMnIoCIHZ.B3F$UsAh:m/trLRE-8hfX,lYt+>h]:RR'gK:78cO!&oeQHGiKuX%C',?Kj+nGU)`I7;Vj<&QShE!AS_^W4=%sQQ&oO\'-ZdfqG[Qb8YHA\O^$QA<3N*A\e[utLjWE)mOS@)ErePAD,9Hr;,Lapb6u)Q#TD;6b\Yq\CV-N"kd8XJp)n72C)p9:mR4$mRc(8/_Q4]AcF00V4Si,;G31hiT`30agsL#oRo6F9Sa2Yb+4OGfcEL4VTMH';m;(usIA*luDU%&uk4T#ZrpTk.h955r_bsZAm.DDTXuELc3C/PbG6%SiZk?"I,Y>G]<>pM62S`(S]@2/Fes5SK==#XC&5N&*OGGD3]h/X9Bf\,C\ngZ!EfP.\@k0bpYZ"7s8MK,dm(T^:iDHX"%q?3J,0[(o(:**Wp78aEYM-?X3mn06V)>Q=66uW39O8!9BR1W=$-(bo7S#GHZP%nMr(iH:SK!V,qE9dKX^`*/kSs.^r]fVP,qZXVa/Pjr;>6uHUfT87b]U?ZrL'RoUYW@;V-ZeUf.lMRW3\m_@Ab#/TA1BpYP![96DrEb/<.s':nN<2rMVoRH>/j%\f[o`fXc2ioB3-rnOkp6gXfH.P"`"r`m/5IdPJ%+()5MZ?>J&m?dD7e`tI.Sp3[#F61OZdCiGKV`+SDIIDN&H^Q/Xn7PN+)YJCYYPRV,,'VY8^O>D&(9%el>:V7QI04nG5ui/C<+jLf>@#A\C_"-EiZk>%HfqT])lW,k5gi,!Nd7^_>IP?IHM/jhCW[dsbH5HF4tEldr>$rk<*qVV%*@D;,j'Vp"1ZrH$f+FcP2i]=:i'=h/Qagm#+MZFD?'_bd[bo4CKZiiYi3#dqTW5qO$7DG3/sdRDCUCl^^L8-[DKFmIU]cZB-bpLiPLZS!bG%;7]s4nf5!CXb8iW9?BlliVnfqCn%&Hb@_\G@.';96KpFd>?TK]%HgKJ(_3nOkUsn.M>7Jd9aU()g+cj'CQh3H3;t.PZ7DTks(hgHT*!D8nu&&Y\C<'8p)f=+7;jnF/m3Uo*iblO/6of&f#[8KWD"C]tYR[Em0[qoEG]+2e_GS$:V5dDc33h84Cd7'r>f[9b-p+oIGVnWB*35O`!Joom;FJ-DJANM2M"`fOk[T7fcm=Fj:H(-+:O*Du\a_h;sR\%Fcb;IfDZ_hgc]<\8?+TH3<'64$nX=DieG\EB@.$[!REN@n=3j8A92:dl"_hFJ,@a+/^jQ%`:WN!PAPG62R#46#)SD.Z9c1?XiHm?eQ^E]0pg`>oa[Is2pcu7b0E1n_>!+KDdA3JGadLIB-(NZouB2Y>ae4SE#(HJGkdhn-eD*e8!`7nKL@3-SJqC'c:P!Iqd#CFPIXE0pt=(h7TP*Q$dIgZ'%>_:_mm>N\7\jI%hM=YRIhA#dKb]_q5!Npmb8a0:@*IX^An0#hg`E$Kbp>0kDddsl4%hV;"X5PdsOE;V;5d!%fn`cE_5GaFCI;WTY>2[i:K]F7K/rghkZp=2ct%4J]fiP-!@T&#"=M;Fnb7RhWbqY,\tY$H_pFnQc+sU\Fjn"R4V%o.)>)8.MJ-3F,\!4?sIW3pjptP:V9t=;haKFr=(QpE9)^32;5Yt':1-)HD+*nYc"BHs(%:uehQOoVJ\Wu\$OU&6^k\SWho$_U:=??+/#`!btB%\7sjpMXd>)<4pTVEQ`;u8[>KoNme[^d^%WT8Tr4R!rld/oIeHp2@drP"aO=.k<#'[#nasGS"%fu#<'-5f9f)*q0^D3)Z`WN]eEP1^B+%E5*[AqqW3_e3Y%,n.:hPVG_bN(>UqK(\8aR80TND*R_YY$rn:MgIPSCh1qL0ih]1eY\dcenfDS8@&@nkaaC1BHB7D?Gocl%S`%\)`]kr_KS]he/^"gSE>&DsB.8WqXAr8]4ihR2[K.p"o2N;S&*SHfl-HiBgb6qIn;@[@hs%;*;?96qBj2_gk9:iYr&d-hFNG:9h"fSk%YE\)Nh\E&*W:sq="J*VqW9>=pP`Sp&_l"F:DQeSD:@]f-a=[cD)6XS_9]6@ZZqb2X)f-cfi7AdOaVUotqKN+E4-pW4?XmQo&G$"_%=M8?4=NdW:VB5QFoENd&CNc%HqYf:=rinefVbF\hgCrS<$`+bbIq3k\2Vm7Ld,GA=]Bci-B6?^.lnlJXZ-qMG*9mnWc;nQdC%_b1QEIQOZro7ef_W1-?@T2th-h$6m0R"VJ@1G*W@tN0"p=juaV)(/ghKF2)l-Y+7Vl[KJ"M>ca$7"NhsMI$piU\QdCk+Rl(&O*(AFEaKIn[q:8Ds[bdo#eV:qki[T39s3h;])Dh2WZA#+AjFk2`$F\K@Wp;s)/QDcTUSbpF:IBC1iBlV\%]5UDE:fo5Xhm\bOk4T#:qqh'JXh*uof,MI#lBCF"j*CfE`N&5[no`\=24Ye\X3i.p9*a3%Fm`+*h%kikVb%u%B"bBC]k8YK^iXaf1l!o/e#/e`GNoX#51UubQM0:3lB^>e*>!Cl2Cb8+kj5OQ/uD01lkSr>9DC/(W+Y\np5X>nrP"b#P84?ao1)3>35G4qRgM7Z+JT?-AQ4DRB>nFO%\aK.ol7+a]^5%;,V)nXED\EaS+(GUm*jnKTpDAKWD+PfIN.,"bbA-W7D"Bip,4^X,9!NI.j9Qm;p:qmgZYCQ+>VC?Rui\ht@ecM4__RC=mt"o\.Af:oVp%m'b!eWD$)hpQV\tJ2Vn\gS'$X@,,QsN?S9!1$R,/TN*)Ts"*hP'g[kO,ciq*^Jn+/_-[q>pO4_'YONM"BgPo5uNI2#,rY?FRJtRImEN4.RfIQ5b,R7/BXU!GFd6o@n\rHW)HE>l'uD.*H&Q'+QHf7AU]k1@p'*dJ/]$9DR53sGRb7?`/3`\1A.aLO!4dsC+>39j7LRC3Q[c*N]gp_GdpIK7loT3mO5@YpoEJEFkRB4YoEIn7)j!K"H3<4TH@r`S)]2m(*@i)bSe)[;Y10(&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c0(]?u9Q'oA"haqu=nDo/&VT!@\V]/c/fF!bg38OJfQS?jWAdWqk"NNo5c,O$*MGEJ9r<5haZg9m\-=KliK;p,BDD(Oq)09!!!"@I.PV0VG3-=kL,KXrt#/nI,)ZYVe2ZNgXR+9TZ5?khtJK$O#Qp-\'7;kFb%(u[L.!bsq!.]0E66E=5Fl2`LDjW_OgdH'G9FST8?mp='!!%QAmFbFMH#r)^rj]k72ZO7TDZBb;n=dNU@*WZHr4'+UjbXWU9HT,UkRE?)Tf2r[7;i/+!&.2cD6Ho?5Q&"*>qpaQ-DEFA-AL@W0GM2$!!'h4?+T[bO+(X,mQPC^8BaD=5YMU"!FR=%!rr=O9\H]2M-"&4cLbP4K&2$F(jZ;";"Oql!!!ndeb*N?62og#qkfE"bNKCkM4lj.$q5(7!!&*`J,J>F2f'mXD10OuO^o-=!AQ>$#(WE2%0-A.N,\:Eb>hOQNK8QuqFIoEhLLt1H3:rZoEG9q!!`8YMr3<6?f;XnQ:?0&@UeO1!(5-Q!!!!9lD9hjDVeXobr8]u+,Q]T%>]k72ZO7TDZBb;@'g:XhL51X[:dd,Qp)/Ccl3N06Z2rAMV\=5!$F@HmbD&OlS`9/#ZhI3][rDa6u)]`DLhH34-I!#(n_ET$B-.ft:r9HVA=d2NW16Z2rAMV\=5!5Mihr8V^rWup33H\^i1R1FTG@UeO1!(5-Q!!!#[Js.QdmIhXpp7u]`BiBoEKi>kR@Ll!-66ZmiSf:UopjZ9cqK$6>o+_%(u[L.!bsq!.\>GYC@!GpY=?ERk+O2Vr*q,Qo*20&/.EL!#UUM!!!!A2dO)kDF)+P8!!YnoT>r%hLLt1H3:rZoEG9q!4cq7hWN__9j`;<)q.DS(jZ;";"Oql!!#%IlIE3O4g]O]Sm'T5U4_)09!!!!7U-j^)$4HIOSip]^82TrC`5L"A!/@4,!!!"$T`4G9I^e)-jHGXbNEnAh0_>Rf`6]G'L8$U,!!$-J/m^[9pu<+6c1U3/KAM-G(jZ;";"Oql!!%pB8&r?Um^i#GG?`<1!5/Cf1%Y[#U$)pc!!!diDn[+C]mE7`l,l9L<;)YRDa6u)]`DLhH34-IJAl&0j?oj:iVNDKZi$L%oEN7Pcl2t>U,N&P!*FXHrY*8i.pdO9kMQ8^,s+bq2]sH%h>f5D]`A*5^g_HG`.9$/aEm@6b?7p_]`BiBoEKi>kR@Ll!#E&pesD[S]DLY\@m;`2hLLt1H3:rZoEG9q!/o]@s8'@`]6C>_rP5UdIFt2]cl3N0ZT*8`5MR7XI1V=`s8L?Kl!)b%d2N&c!%\`@E*mIaX0d!1fsA^S5')#P@U^*CDfDRpUndJSn%=)OMoh[HOfQ6n2jaob!<<,8JhStNU"es>^OFH'oC$4/[e'dB`%7A6+E2L%Q5(qtmi;ba)am&3!!!#'J6]Y5]k'jeo?V?u<-plK5YMU"!HJsh6#>`o!!!!7SDX;5N6AW6U8%:t&)WuAXQU+LM4ljncD!7R%D;cB!5JXn3;EK]D3$jPd-BNdk,gYiK\h6H(jZ;F/:)s$cl2rb!%_eN6TmMS4L'0Qja6I(c/I[S#/nI,)^&e@)oRKf!!!",&I=(SHJsRUJ,Ef'Hi#>npr?5-(Siu4-AL@W3K)`:2Y71R!!%qsTDq$XJ,bFPH$;/(e_[t7EB4o02]sH%h>fQohB4`K"onW'MpL-r^[])ANgF)+q=2M?e3>=o!AQ>$#09s>#-jj\!!!"$XSi(,2f3l:Uu_NahJ,XTjop&5@UeO1OL+-[@RG&6!!'75IJN"#]mHBtbIb*S_*'XIS%)D]%>]k72aGZ_2i%pV!<<,8'&iL)HK'cOb0/BV5Q8Z0s8"fo,/""31%Y[k=nDp'Tf2rO!*E-N_`o!!!"bZ;BbOs7K`Z7ils:rql/6mBtOo&4e]HDh+?HD\*k6!rr=OV(DI,Kpt#>G'8$mqWO\C77DRtmd9K3TDqha6M*W`J=K&H&0#ot!!%PG/Fi<@^A@,qUIUA/n\c)*qU(@qH01OhhKr%!T0j9$5j/Z=Zfhj-6Z2r)!3h^PHnOFYrpTl9nA,>_]^Wd6Ie&]qldp?&F9DYrq*4m),T:t2j=GV0f[(Q;!!"Q]Bmu\kPq,pr*BR;-?#?iKe=QsV*rPZZ:Zqa_PUu@O)^&e@)oRKf!!!",.@\6L0OD>4l/9C1O$33h*I$dHZik-@fB.ta\iM[!HJsh6#>`o!!!"bZ8qO]dJWU.s8;N<:Z$Qkc0a8pY?8'hrql0AZ"(hZA&eY%^n:VuVtiPU-&XtZ#3kW4Pc@oJA1n_8;J("g]AB_*=c:2R9c9@'T<)"V29Yq=hd.+%Ods/Z$6dTIXF,>Hf[(Q;!!"Q]oB?_DEqAG<.DkAOYK61to!W`8[()Udn/NC(7%Q]@f%#k],,.k66rA#8M+%mZkmc'2DZBb;JGIArD\/8=^]+)HKaVh5q.F4X]A'c.[)hRrZL='kEA4J.#l8N7\J@_$"MA\n$DO$?r*0]7kYBO#HeOqk$uVb@`^R/aM==\6f89+nMCJ^ZDT,V3tCZOqi9/?LiB6?LfpCIJ9;5s"3=!!!!QJ&_-cM&@6O]5Z`GZ"(g\IedQQe%'r+HAfa?>[1N>?2_VJ0-!*!nGW+=s7kW8LPLZbns@+%B1Ttr/@aQPC:u,^J(`u/Q'X,:(S,5EDpU\D#cZ6ZlUZ>:86/ut!II\?ODI?d9;fC"%Rp@55:A#s[6D^tYY)c4k)fI&lGSSR$#qJL6HFS;[h$![VQ@WMo%#)3Hn_W])g`iWW?al#U!;IuV]MEWSTE59n2Jq0TG4"#]r-YQq>$P<;=]r:Jc^rt)GOOG(s6.k*^\ZKacC[?$q<+AW^OH-BJ,J=krp^L47o&3=L"I>XLYd4OO.=Kc/mUN7(tfk<\eOhI52;Fa\6_79G1Hm\X``IU]rq&M+Vf2k)MY4@c_OiK\lrBFrdi'YY<3MEVa)Z3PV`k0,r%7;%1Q$F#Nl#i+r)sO8]&s?dQ.WXOK@**^8aLm\#7p:2rJN>OX*GH96nrG-_346;Om-j&n078K7=UB^,!ZFSCh3\\0;P7IFs?H35>@3"*]5GK3NnZE,dBoHb&PDpVdZ?dV(&[+jY-0>0Y4kR@Ll!&/o"pBIVfpV6_k*"IJlfk5cKs5_:cmHs:fp[3J/q<,5'g%*3/O/uNmWh?"-0/)e^]C0o&*33/EY,eV(Y--WmFmCj04B#Tos74>dn(Y>?nDV:M"Znb+hL>?=FXFm"eZX:FHHr*FX3U=RKaSuPr:-UVQhpUV#6tK`pUf=rBp$2&9nEB*"mskB7:ai.=r,OjM;rkrX)lZS9&802?H/d,BrRop$_s>o-W,CD#T`(&KkD^DsDa3JqMR+W/I;J7Zgr-]?`h&us=o1#FCoY.\4/;h`s8Mc-DmeH0EF\h!YQ*1HhOpliZ7p;14o7_WL*Q/#k\VkK&#+^AJ\6<.:fgrXGnT#4+A]`\TW6j!,Y+OR\f.-F4J>NOodba5&b\.PB5Xm^e/*ulc_\Q?VcoV&98W?Hm]J"Na:I/h:NonQp4b3/9pV]ahI*Rq>W\o@U^5p!lE!\0)ebd3CP=>kO4"ukMV\=5!!)VWZb8Ynq:jg+2DHq[*oO(hrII5lUQ7V8i.DP8T0DZ4G`Eb(db3ct3hMZ3VMit^9$:H^RVk,PG:ZsOl&oYJ%_C1l*%'/q1r8B@?GhQ^kF4%?p?^oJMo>NG5I6h2XT89*4-$]E.8mJ2qDs0m1WYAKd9(l/-iJZX=`k[JQD!J=Mi]K-2%:g__1.(f2lHO)ePH7HEfpeW&9D[D#G/p:sId[F&:AHb@'f?Lb5&h*O:6p%\PB4quX@QnBflZr7G'%n*9m(If"^IG(\bmD$lHGB9RE4lnb!70C60/Nm97=4[+5KOf,oQD)^*s\Jm*7q/2;%hL/;&/10ttm06X)2io:Vde0pc:n[#qK?='$hKnK@91t3;mX9J3IQ.[[ItR)m^9ZO#:6T,$rURq&o?#Mcc1ZE-R2ZWB4DLR5p[E2^aId6TS6:n;^Ti48bYI"jV`u"Q^Dfj!/!tXt`2Q7uqI4n4B^MABZ/F]:u9=A#>^$bmNhI6,cSQ9lR(W=kodh?WdD8(AD4$;efkCrX"W7gstme0+njEg-U1oX614;a+,j`VkCp3&B@]n\\?LHFhT.KAAV,JX6F?LA$N=b!:IiG*eDJ'dHR:MS-tU[mDA$ZEHm%"H%DU>=bmlirUu8\0@o!t#auDD8Jk]>=8AH>q_SITT0[=-B@VX*-DQL8R6H07MWi\c&aq0$[O]].8fOHi*CBC]1@sgBUMhNO>Q[c!K:D/e*kJ>aTIe*3F%+2gH$FBD$Fk]%nEd(<0-7]TjL_A`6[.GN866]RMtG\\"IS4Sqsg!ZQ%uY%4"N.Ai[I("gT)G[+PoZlirUu8[FrCJ-+C5<8-[CH$09]P,)7+DErd>"tFJ5K06bs,Y?E8B/cJKFp"!f]0W%E5a!C,QEqN,+M31sS)#45DBMN61s=P].$37MV9Nn>B/bnt8Xec-"r,-rT[IF2aKlgVOsJ:mFor(^2c+4p)s#Z],Y=/23P,:qZ5]aLfa[N=#*L6'Z^fj%!ne#^g?]#hFot=!Ufku\5_88+.W'?]4M-.i8^]/&2kWEZ"-kdV6/L4#^\?iVmsOfYh^(jW1kRr9n@*<0cLnrQKK!9t:hd6Tj?7tikj7ZNOsEVffm`nmL[0Fk$#dUsT[IF2!!!!ISD?H,c#*L]!)PYeJP)Ef!!!"lE-;>K2S/ti!'oN0"tFJ5!rr=O_V#Atg?]"D!!%_b)8!_;J,eu4pE+h]NurM.g1pS"2ZNgX.+ZYq%A#f]l.OOXFn6M70E,>127"5%!!#m.)7tH!g?]"D!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o'###`h7"onWgeEdB;d-Lr:!'o&fmE3nULQV`3b:d_E!<<*2YP\'pp[>#C_Y*<*s"+"23WK-[zzzzzzzzz5cO](5k0^A~>endstream +endobj +6 0 obj +<< +/BaseFont /ZapfDingbats /Name /F4 /Subtype /Type1 /Type /Font +>> +endobj +7 0 obj +<< +/Contents 15 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << +/FormXob.b047863372ef41b3004606a033908664 5 0 R +>> +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +8 0 obj +<< +/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 400 /Length 24486 /Subtype /Image + /Type /XObject /Width 763 +>> +stream +Gb"07D3,]7#r+bfIDN>oR8bod'`SAu9EC/C#"8A$$boZ?I#[5;RjZi[p^HC-@c67&c_>VFGpQ`HBmF0l45n!M-cX)*/DlN&n6e]Th8)M&DX"SUB"C:42\7=Y;O.P_7?m'=IR9s!3W&mX))%SO;,Pm&S/+M*08S&Tj_!n@1C_O2F8.g`(p%fGfLa#p;@u%Dq.E&0CQMi?@n!iGeo)O*cNK3#mUl]g6n!]g6n5!5ddQ+?U,=iGicI*b'%!*[cL-\2O\S_a/P&)ha"!)hc6<+?]'$_W,SH*qolt+nc-!E<6E,H\:fI*/)AG6$S4!6$Sn"_W0Jq4:VVTEGlC0@W)f!-\1]r2[GJ^6$V0(KSS2!KZ=BA4RNZqj)>PNpBKS"p'0Jq!XOj6KCCi?KZCblG_j%!GancNj5(n@%L:s4D\*t!D\*s;JFL'-#`lkhGha6kLY*Q!`sEkNmL@%nE"F)b#2pa!#2sP'#`j=bn2MD@a1Xc`LqQ*!S,gFdhB4oj#N9Z@&0>;!&0<3Ln@1C_O2F8.g`(p%fGfLa#p;@u%Dq.E&0CQMi?@n!iGeo)O*cNK3#mUl]g6n!]g6n5!5ddQ+?U,=iGicI*b'%!*[cL-\2O\S_a/P&)ha"!)hc6<+?]'$_W,SH*qolt+nc-!E<;.8St-O9",!'XAU0oBCf"2,kB>KXo?i_p%.-fk;+dZp?/J@,6$OBp3>S4(@UQCmiMk5"Ggq<+4,;FSNZRK([RP>X5i:kk4i5jmG"-c4mHS1-RINZ+Mgi*a<_fXa(&HJ>+(I_f-o&qgM8%:'R;_1'_okiUidD$,DVO/I4!?uIF4H"+We#M)Tkf\G^S;Fe_A:[c]ulcrWlarih0dr5r:UTE7Z<>GPr+/pT-c'V5cGk5%6Sdg%oXr!3h')nI4U>H7k<=K7o2l.\$YW-Cpi;dCKGD.M87\\9qj'ucqm4:%#/g^DI(0q,^Ka?!.LkCCO.:ntS^X/6Ri_[sOXsf/gY^Fd\7X7,a.2i)4_*,DblZs7V8A3Y3Yc]T@XX]QB$FXm<*?#r"qGqFtpQVPq]A>?'6$OAEGD2qor?m#&9m)3E@5?-i>Jo2+orhW(.(sAFn+K[]/m>A4[.AskUC;B0iWp8jUH-=guJ%i\-e\q=3g>Qca0TFE`bb()3kW5t*7<-Y@u=ppnDK1p4*M*nUccf=;KtkbPfH=%O0WoGWbckV@+JJh;aP^K:KN3^6rf6gSiCui`5o(f:Z&`Oobp6GA=V9.Rcs;6Nc&%6F(Zs^\mo8aI;+#EA4;AGNBBn\&=?DP[,LcZJi^m6f(_Vf\0>PS>1&$KYF;@I[W5qA^LfB,cNEiH4Uejm%i&*ma&sWm]:bq10dIngO?cl@CbC=I[D^e\h!/0q_c&B;G^i=R.%m&A2,pE3S&NgNIEFa4^i(%PEF4O`'!^m.TB`KkJ`/hE=BlP_%f[n1%9q_K,b;=Q-6>d\Fh/aDOf"MD[Pgl"p#TjP]asaj3Gp.s[F\#`mCMb`/]MB7pe33=llpMQuE]>b>YSrG59i4Zk&+b%"u6L>E)(Y&f3a31R,W:N3/n^k(>,nGWHL14AG'ZH5'BDlrX[V29$sC,9"hFSZDGP$aOP`>@^med8*Y=Y9)+[H6=5GT&U:_K1/7Vn2BI[WQ%E=`O)LAq]=K`6#k@ZVu6_khdfe6leFr7StMON2^pFZQiEU=e)$k+IGV1hC00CHW_;(n/:T607\Gb&Fok*>=1d->/Z?@+0a)HP$^4#OTT1<%tB@Fig4FT.N^P[m;aL/=O/h8jfO%G$2%p5X>_NP_lap5A6e@m&pN,r\I[0,U!b5irjPSVM?V7GJ)@ir%Jn00QMrbX*fi(]`8CnqV+52"7a0Y^5p2q_B>eDp**:FPZeK1dE1n*,@hE&7&Asd>fUD-j?S-bbU&H8I-Ggu_0lTdBZq=1SepiIQrckAgKCBG!KCCi$KZCblGT741j5(n@`82V!:&s6mD\*tFKCHB0#S41!#`fWaGha6ka5J.'mL@$#lj^hl":uXK#2sP]#`j=bn.9r!n2LH%a1Xc`*"KjGhB4r!hB4pU!9%p9&0?UZn@1C_&$\&!NtXd'g`(pei?18N%DkL!%Dq-.&0CQMiGgg_O*cNK&:9'!3!"]Q]g6l_%`78_+?[U!+?WC!iGicI*f#C;\2O[(Yr;rL'0pft)hc8j+?]'$_F*Z!_W(b1*qoltEB"5bH\:f!H\:fI!JJM,6$O@Z_W0Jq4N-)!4AGn8EGlC0LP,*+2[Br!2[GHX5^;''KZE$o4RNZq6gP9!irfo7pBKSr3!bRlKCBG!KCCi$KZCblGT741j5(n@`82V!:&s6mD\*tFKCHB0#S41!#`fWaGha6ka5J.'mL@$#lj^hl":uXK#2sP]#`j=bn.9r!n2LH%a1Xc`*"KjGhB4r!hB4pU!9%p9&0?UZn@1C_&$\&!Nt]V%IH=<)c)qQ]dRK6Z3LB]qZ#5UFBZ]=2?H\DEhXtkTg;rpXJ,&K9:Nq-g/`b92Y32/#jSiQH*"++A-Q^g7cP):!hq6.c?2oG>On@_o#*\[Q`&)A9cYQTi=J,@]A?L@TVYs%!Uq0?t!mChn`Y.)@+4L"_5_TuQgh:s*a4`FTq_NC%mo5R1cqY092]'$-WgPG^JG@,X\iR]Su3Hmm-q8&WLUYGhJRC@[dBb196flQJ;io$8rq-CHK!p9mSj@`rM^&7e5[i5D,8e<%o%Y=,"]c]E;<^:m03X!;%p4Dc6=97@]kR\"1fF,Ou?j22gTL0ha?nVcrJ/&V:J.@/"JA!'f!*2@0!'18""87?9!*B9\!U((#&(h9,"(2:c#G=F,4CBfJ%tGB+*e4`On:81p49/DIGQ9c-_?9L`n,QPki;r-R#S5Pq_?40LKEn/;+?X$b#S2G#&0??3Jae3'+?TX)5^38i"Mt97K(&bB!T=(C&-rg!$c3!R"b[,R6QeL!0*i)='bDF:%Y=,"]c]E;<^:m03X!;%p4Dc6=97@]kR\"1fF,Ou?j22gTL0ha?nVcrJ/&V:J.@/"JA!'f!*6OAf0WU@;p$0W2dk]R/+=m.Dr%gb5$:/Rr1Y`[&Pfq(c/90aGVtBZ)OPVhX/l+*MJ0Cl(Dc.ZSj_WHF)^gV:P/$=u>:nA.nPGc5/-%2::R!==b.[)TC/h5$qbKVQ7+*fZY5FlYL8r!'2shbX$Kh?4\.X.s+X5`em7$(TL.Ug=p^"6L!1-VA\K3Ws(+piJI?Z<%8bYV"?oSQqop.PFl-Un;,%]61L?Ylg),QGa]+m%Lk=;&0A%lKEo:">nik?+grF-'0!e7L]nldBUg-hKLB1lVN"$]UT*NX.Sr36;T2)AF2e6"c9QWi?4\.X.s+a8`9c^:A,0rr+%`H#f<8tRWJFe7S11M=l4]'jk.c"rdWfBH)[NL5*q3p47+`n`M8Fos<&L;NV.2fd>`d-efeK#@CV$HEN]atTV)aLRr..C2e%B-o`CrtNlmA2Xfb^ElE]dRUI6o$_E58ON6?39Kg;p]A:_t0MXZ)E&G_N2/j]\p262(Q%eq6.L?Yro/.sd+H`2*Pd$$e1*X<4\ok8Ygt2=X2#XX.Y"/g%^;2`E1jA[k(bc7\Hp=WGAXXk$THrSFY/"09#Z=m@:Q120Wi)3!2;ZjEs<[ihWo#7qtl8UN_/sC]diWq8B%"Q@6B!N/^mr=t7<$ol!Z4mikYSVrt^^B6iGj84QF^\Wd18`6]NH7oU;td9G@XA\$.n1ePdsXMfdkolbS'*R]4+Bb@FsR7`YYV-p/h\Oo(`NMV/lSC+18f?nVcrJ/-A;n;*L>RIC>W`Tjjrg6j*fHU2lVXC+nMMIM/CUsbsc*jM-*RqC,B(S8Sn"R=0T_Y>0Ik/>Oo/m&s6uV-mlu5oB,'(#-n\A,b(`,VT,@0Ftk>G1>/2>>-d\h?5KBUF4Q>1[,->WD"UDggnNSM53@:VOg,['A(hS;6)%1Q^;VM"h(?F<[=%Wd:muo<"Bp`U'*'HUU)Obh1qNdA0bhRkn2?4sVa"T?UuB.C#UScJVD9BhJQ.f4?e`.#s.eo>`4oO"^=8eZR)KI)2\of=(1)*qWNPT@Obc:TG"$p5'V$flSd/bBZI3J?\%e*B5D%A[3tk2RI^!RLXiOK<<[)&0>dG#S2G#D#%:=A!=75:fPte>uSWAn'n=$=Klo+0l$;f,aHuoJa.)%?>V5/P!;5Gcd$4\l5dNoY^^[ClO>.U(PXE-WJWnS;`1a[;j1X>r>m"7]g^CKRN<$"8Vb!=58Pk26`XC,c?uanM@k_W<8Ao[)@u_q5]m"&j^sLZV#dKcHd_#ZrBsSJ@P(;S"$Sl3Lb/OV)T.0raN_[kaelhje*;Q9MEZl01u0fg'b,D#-WBK@Ud]LLg03l:WspYRkl=gJfU?[]i;kKYQDZDclQ7oFk+RSaAYkteS5,<#ODWQ!O)XB"4/*hWa9l%AKUm77g"<-/sfeT!5\j3K(&bB!T=&mO8@bm]&]#IY.EmJYLgC1n(u%f&0A%lKEo:"#S01IW/LH?LHg1^jd1JqlX-9RX%l4l&(h9,"(29]4DWNL=o>H^!49RR2>6FlL[]i-+?TX)OM\?qcF`KEJ?trKm9F\R,p2s(7m?O4cV.&-+Zs-c#S2G#\>0;T*g^5_q-qmbp=a9m*BGG^5^:(N&0:g%+?TYkU$MQ,ZT:lGq./Le#S5Pq_?40LKEn/5Y.EmJ@69*oK0j^LrYcs<9oNS,@8ofc-!G'l%8=2MQI,3HG8+;Q<3_:63H0IYQDZDOu!H+R%sVKRNIG'V@%lBeuNPNam)S^KioXjb5#"B$BLS@"3H.tC8kkhPKh$El!ubi/Xi1_\M^8^A:%K1AJo^PVN8`;Rja=/7#9p$.!#H=T%tGB+*fqpAGj84QF^\Wd18`6]NPZ@SPl7VjfNn^"M@iGBFC.kr1em_qA0rPD1W#:HE&=649Vradl"ohIOfccuC/q=ZRI!Qt?h(.BjcjdBhS[gLOld,Jci860_tri)*Vs,;)j$$S)O=2pM8l2hAaYY]P=RGl8"@nIKM,$i;p.a_?1E*Q0XQ;:fAmB>bt8r:>bW2bL2(lHC$8,Qtp\Tm2c%R;C/Z/_Tnc_I%f@C@PfuNK#c5J5*WR]54A[D&W2Q.LTW?1Z,aM,=riiQ*`NbM5.LF,Z_BYpm?S#Q2E%.0rAn%`]`#ggJZgq_jZ)BmZc\7Q#JeTg5sjpe7qajN#@3$u5^+.oVti9&?d].Ocf"hXFP8Dl`E*WR]54OD1%jK(!KcBF>o9SPVCMRA9\$d^9hgB@om:q:haGplRN<$"8Vb!ebAO4tL/t_7SG?>e'dFF9W4Gc@1`l@kJa!#+bKUr>?I`[Y-82uYj4_]&d"(DL1gdoh*c)!*2>T.$4"+?TX)5^38i"FiNJlil>KYQDZDclirAYSVrt^^:>X5_hUL^g7Qn!%T0S!$)."J[=@5Rr4[dSi0^Oi;p.a_?8..&0pp5J/+mL4T]nRsJ+ZlmQ-88)/:d3i=97@]kR\"1S/#+3H0*RX?i>gWHt'AG8.ZgB.j-qS*='$ll]027lI3:X[0*i)U,D=)sR5Rh.,G`"`14oiCZiS#Gp4Dda3=$/#(k`.J"5s9-6$U0bKSNY<_?91Vn:81p4CAZ96S&H#JbD?R^g7Qn0F-P[(5)*AHQYFY0*i)UKCBG16$T%c&0A%lKEo^eG_j<]4O>,T&(h9,"6L^g`*s9!BFfb$lil>KEtBC%0aJ;s#JpT:K(+:N#S40WKEp35i;n9kGeb;PLKFu%"7:[/JA!'f?k1%@/-b'ap-/03'V=-R\b-H.3I!=uoYAs-9Y"thDF5l7E`V5',="ZR!G,N#iS(P3En,7>%HEC.enb(Xg]cQ4pND4cpo.0k09',;T%qKW$#S5Pq_?8ruo?L!o%pZN:f^YWOO([/6:VPRC\YJJS[Da7N,!-;&>Q'*`c&Mb"PtDT/kQD/%fF,Ou-AZ+#mZ4JPXa&tTY)uZ8grXuFDb_kX/3@kGR]]H;(5),/'ncfQ!Q"s4K(+9s]2'98Mr$=?c+Apu]Bce*meAulHbHDZX.D!t-G.!m`kU\Bjh!uZhR0A%fu2.%)(0XYkI]^-'>5L_1IYHTq?-1)^NiPSo0TRF4Ce>Zmn@!a_93PSU=J_G.!>K"`_8^`(Q\#h+1\)SmsVmlZAk3bqq1[$oaM49gO/b_bn^dP0hsL6TL[)b*WXXa%XSotN;V,0\roP/b^@qcflS4DQSCq+`d?ablG&lL:Rr;4$hR?`hIcYoOjK:@I^$5)^$eO:LbMua6_W*@kIq`Ia)MMgD%jO3`*XE;/$c2um%-NR\T)WHkmRnM^hmqImp>J1i_;-C!5u6B4PA[DsR($[-a=Vn%LkGHuitZmkWqu2PC-f?ZX*lA_HKUetg$(j2J`J<[l5SEZ=)Jf&(nBid'/pF(NW]7-FsCcf.&;;QNXQM8Rh'?Bim54FoN5C&B2EnC*VC2GEW]BZ;9PcM]"GYHg6KZE]#CGpZ-m-dYC:J[Bqd>n3/GNZ,/Sn5p[29+'*Xm,CN$UofjpT79K/VU+9*GH4ZVEKn-5^OV9?nVcrR':T1gq-_qcc3!Sg`Y`FV=1EOOnZuglH,+uCrfoV/iggq4NeH#STpB1\le:/d,GAFeWT(f=(h#T$YSsOGM]`2=_9dEm5qG`k/P[7(";]]i:ua%Sp/`29/PMCA'tR,L1c!YhHtNqjc!ENV12Ch$&c;Epq_lGj.Uc<9NH)CI+,q9_UIA%1^[%-*_(CI4V/[=(PE#efK<$EUik\B%lMYInn\-lHfm%r[@.>%hgE&=/3B$,k/bBnlT+\2m>JBgA4cChf881+-G6js"m,FA=@bc$69f^3j)ci+a.s/BGfHqtW2]0ODpamM&_VSOpVg55V;bXdjiVcdceW]_eJBmrWj#?Fg=q`Gp+X>cm=FbW]c]FF_Z&gpbQ%$KhaR4m;lc6@B(gLrf>p;-1Dk>_UGlI&KYTrKEpiIi;jU,O/7>6Q/XeYrlu4dijtVZO/:Ir*\j&f[iO8e;;ONdc+Dl$D3$WJRSB))Y?t/`=*s9*H[$m;ji:,ePo:Hbp>2ib(Sl5r%8EA(mAEg+9\OGTiA'#[/cF/^0T,=RlJ4iU[k21a`oUD>SotW?>iIU\fGedVs*\ccLG$_2]pSnscB?N.SWrDMGV/$dkZMi;q*k][$8Ao&JlM?ur4j19^npT&dW,;q-+8E1^qa9X'=jjt^("_7ie4W!%'tcQ>;62YHKjuM)/cXlJQ;P6n%O4fk1dZ/l2*8^ElMY_VTUnM>Tc/rm7=#A2!n_)#MK:=!II+W^mt3b/b-quhYGV5\%hO4--YO<1&Yt%jego/^0gk99`90URQ_QHLF9aY5=;8;a"o9jS6H3f7-(E\FsDfmoY6f9><*\oY+tKZ>?l9IEJC%lG(6cWXWST*g820dQa^fh5d^P._Y9dD;OE%TCL]rk,UFH^/ZJ=_UJ4=1d75>\;(Y;BFfb$lil>KF84dh`+&N%U!Ohd&(h9,"6L^g`*s9!BFfb$lil>KEtBC%0aJ;s#JpT:K(+:N#S40WKEp35i;n9kGeb;PLKFu%"7:[/JA!'f?k1%@/-b'ap-:8#S49I_?9L`n:3M)&$Zt)#MK:=!II+W^`4L[:H\Ka-[ngZkL#n25PiH?f:1a[m+_8CKEp32i;n9kGefiE8,#1DlsA*iGMg!lXtTh[ULeW).f?O`n+fTd(.d90u[CXe5[Y+("]c]E;FfAWn8r?qcAM=KV^oGn3sZAL$c3!R"m67hElq3YIlaCI8R123(Go-oA0^4e/f(&:fM#CGccn:m0"4hnJabXMp4T=o]k9D4&(h9,"(2;q$Vr$P;,o1nVSCfCECs_?Gj93)`jR+ahDQ7I,XknZjiu)FQPP4>Z(.KN1_WGdU3hCm:hc@6ta0RSVP`Z(OrHaQ8+XKTg[UpZn7d%Jn5$Yu]U_J1q"r*m80U^/..6/!l451R#CGm&Lm0H7Qs.I::NR=Lt1&K&Wo*:X>p_oufK5dGShbmi?IO@H3!^&I$c3!R"m68S5<7iSXr`&BcGr_/q^Q:5k%_4s0IKB'egU2,2WAUAhDk-59#g[Hg=W\$Z3M!e*k7bf"OU.;q0lk4bf]S'%YLnl)PI1)AB8!7Y10-"d!q1*Tm::8Fp"M#1]b,2!i.od7PiCaNG99D(p9=g2Zg]?mon&YEaYf]:O].$5,7:Se-TQ*fhf7c=Z6(&aS-SrB0-<7B]>g>d2Ei0?Qg!-mX32ATGr?<.?2QJ"83RP,hY[nt]n,Y8/VN@uZaDC6ds4L?ab1_R`\kd9UM)-*>0m1YIJZ%BEih&p8Mq\YrW?Z>edB8m6@C]s^>&XD.ZCoolDCmo7cmCXpa+#2oT06$NC2i,IX(M!7f2WsN,i=,uKj\X_3eR=*3tRk+e%Y;)6L=*VTMZ#j"NlXXkSQs]MTj'L-;ancLUg8Us_f;bI6%)N,?K(&bB_;W7p.3"]k/n`&3ZD$TH9I;7g^QOYTB8%C[`.-Di4FpJ:WYp^OTP,0g-lpgfHobT$.er&7E5Q/<@`9:DMs3;@nf"i[PAN1_FQ!h6&ggF+Ul#W*cA4qi6CHMW=R=N>CF6o.^'c7s'1?nr=3+&YDGj',Y*67"RIU/s?1lLoY"P5P<3+kkg$.Zgdb.6OW=4"gS_GhU>r/n;,=HhH&H'3*Z)VGTN9f](JQ+,8l0cOW>,N7iaQ+'.qk&]_Pbs;`&6FQ,>/gofdbqfoc:$%C7TaQOI0sjM=<'-(Rd6U32@<0X'Udc9U\r/Wp:R=bKO!?9?GbRm$)ea/a-gpKCFE)+?TX)E4GC^j-0/8/R,ie(Kep(X)-ERYh9f19je>iXZs6=a'T@i4O@^hZl)^liCX8$c[b=b,9,AYs.XuiOp&L=A>A[@ej9nQtO:QZ\#)fsb.FC&';rKIaKr,:eqp`hl@P!`9L>ns,R<6N_P#bkt?oP,fZ8BfSNg]65e)"ljcV=]'!II+W!3G*hiK:$XjQ#Dmm=3Mc[XOVhPaN!2:B'd(VrSE^7gM19`_BW8"9hgKLBW/W(Ie0&daHC&RNl_q(Q7R=SeQ6c[:=q;msFFP$'Ca(G_t'Gc5Q:26U@@QZhld"F/Jf(!M(JJta$21L`2"MK55E;raq?EBacattjtj=(Z,[oL-/ifFQMgBQ5F!O%r8JN(8LBX`-!RirPpP>dmWW6af=pr9=gE,3:0I.IDgXp:OGKp#g8AW='pB`/.qk.9.n!WE`jSnrpG!FP:tOj>q8R$7ECY,pkunK-,NGgaeq>q.9Ri_;3lV'Z_*L/5QCQ*A]`$7Lb/AD:OXK\rqW2d=dIiin%H$f94.OY/G[S8^*?:ZDr30?m^V9e=cuCRA4[u-OKYQDZDclirAYSVrt^^:>X5_hUL^g7Qn!%T0S!$)."!II+W!3C_?!-AL"#ODWQ!O)XB"4/2&*j?H6#J^ZP%mYn8GedVs*WR]549-B'i;n9kGQ=gqn,RP9KEpiIi;p.a_?8..&0A%lKEo:"#S01U5^:(N&0:g%+?TWE!oX0,6$NC2JFEP\#_WHL"lTKd!l>&d+V5^!(PE%/$4%/-LHp+"?4\.X.j-qS*KYQDZDclirAYSVrt^^:>X=G(q5HD1AL+u\q22mrL$,QfmC'0\RFc,P1*KW=8;YEhgNigEBo(Xc87(A(XbRDsP^l%8=2MRS1$4eITg?8JT+'dXdhH34bijQ'Fm0P8R6,2\C'GAAeP,f3#rW_n"/(#DJ>i`1ukX@[cURBh,G9i[1CfXgU4>@7=.f'g;"m06ipUHr7t0P57d_hA<3"(2:c#HX#T2,l/l#jR\C>[t;UK0Uu[N!@bq<&cTZ>U(?`er&YP`36/(R96UGjUJ,@,XhUb<'EI2T2N@bZ(NEqU*;'Y:AKU?,U8^n-CdV.l\YLL4cRND,A8F`f>&^c^/=!*?,mn3Xo,#H!EWPe*/A@qQMqJk&as,f/-4rehq&jS-\*$C30R(r[kVDg9I9H&\deZ@2G`,M)FBs"9i;esF@m,M!<[Fc.]4QIM78>$KdcQ-4Gk/0FJ@jn!,$:TLD#AnHLYaNpeg+$"(A(@VWPt@1*aSK[f28=peOEY:%iBj9MN-Tc'%b31M^%3XQrNUILPSV@fC-?XH4Ub-li;p.a_?3gM52ao-nOP?r9R9&\:"=!fps.b-4;RVQo=8fqUM8rf$5l]C#t84VE/">(GMNm-B2q*^$#B*'H%>TRGQ=gqn:28EZUQ(#<->CAWZf-$.MK"XrJ5*!1iN%NiC)<_3@,pr=hCP0=h=)>2*Zno-:L(lrd[ej,U,^'W_#"Bn-$C1In8%qOADK@a3N*!i;niZ49/DIGi1]W^#)4;Q7Zj5^3:1+GJus5QA4m]10J=^)S".OY>U>o1`A._[SQGP1eMk=V?Y3AB>34]HBk]r8fTTOsl)'q\8[2B&cs9F3rNn-/^3t@/meYV_IO7_-`l8d9fDbaGAP"54C"6K"55:d%\bkg,>BSONIdr=sh0&+_^A&LsTDm(7\o)h?qMa5f2`K@@?,ORtBC)cSIdr?%jQ2_8DUi$"q8ucBFk>^8Ub'(BY.NEOY&&:\c_Q$YHf&Vh?&q/B=KCl$p"!>Yag9;W.nd;:j>CeRMnEgi=?MA!%W"[$_Tk+8INfN:"'lYc4sDc;>3k>#J^ZP%mYn8Gi5Z*]68$AeWCt:!*2@0!'18"")!GKu^k&]/V0QD=3Bk^H1kbsVA74^**:gS4t=`,D5ol]M//iPG2HIsk'3>l1s*GJ,ZeZZg(HN)(?Tn2*Rp@*EUl?@CiiV`Va1=EcTI!ArE8kNf5LK.D6JBM=cb5lE^=;N^[#cXWHoRa[>r3rL\(_a-A[YRm5`6jk4O4TS;G_V+9r@G[-Zi=,m4nH)B=@kX#O5EGlC0LP,*+2[Br!2[GHX5^;''KZE$o4RNZq6gP9!irfo7pBKSr3!bRlKCBG!KCCi$KZCblGT741j5(n@`82V!:&s6mD\*tFKCHB0#S41!#`fWaGha6ka5J.'mL@$#lj^hl":uXK#2sP]#`j=bn.9r!n2LH%a1Xc`*"KjGhB4r!hB4pU!9%p9&0?UZn@1C_&$\&!NtXd'g`(pei?18N%DkL!%Dq-.&0CQMiGgg_O*cNK&:9'!3!"]Q]g6l_%`78_+?[U!+?WC!iGicI*f#C;\2O[(Yr;rL'0pft)hc8j+?]'$_F*Z!_W(b1*qoltEB"5bH\:f!H\:fI!JJM,6$O@Z_W0Jq4N-)!4AGn8EGlC0LP,*+2[Br!2[GHX5^;''KZE$o4RNZq6gP9!irfo7pBKSr3!bRlKCBG!KCCi$KZCblGT741j5(n@`82V!:&s6mD\*tFKCHB0#S41!#`fWaGha6ka5J.'mL@$#lj^hl"<8pS4"'.p"ue'TnifLqTWX[-mBEYRUEr8Fg7;?@PY0!-^7//Tn2QqZ/3J^,^g=@b;klkQVut4e%^.N+4k,=*NTQ1N^=C\ZL-*(Idj8MKketm9)p_YGarih0dr-,;JpT!WAGt1&Y9@A#7HSjau0i\Te!stTq29j;&".\q4>unnp&qg1A^m"HZfk%*878kI]k879n2Qs+$;[Yt:\r"ul3t))=Vmh&Lo]m1UML>^f)^WaP+'E2O'eU#IgkEG]9e<=r\Pf0sYFs;-"i&OtI*&X+umDTYFi2Q0$K*D5VO^iORlcVXTC-mcdk5XS,C24Dij\Dc'"8XmG:HN,7:[F8+&&%RjN?+Lja/]+?#Z?Z9S;B@#.gg"[`nG^na6U7n-u'[Q@/_%f%UmMHp8H'F5`n(Ng$JLMXKu`@K^^smXpE@0WZ4/aEU`ISO^/Wl^3,:t22J!K33U"QdGsI3h6_Lkc;\b)a2lX(de&47.bV_Zi9:.@A\%_2;YtdG]`.S7:#af5O&A$/Z?U=/4t=:'c]([:#Z%"400JF3$\uhUV!AlA;=7-nm0`(Hbm_W8G2)9l0;L-LR-OfkpV05.6Jplb-RbYik*5&3BAA02@,A]l/GF\eJh4GT$a63V5$'B"%U#c;=jt@")"dA2Nq.@LZ\\J5e1"B8dE;>ej"O)Gd44+@'pHQmFi\C[1ftg>R4+Mh7@=RmDDL&c^mkEH]HB#"2igN+=N6aA(-">50rfrfq-31GYBTOa2kCm]aKj*k60a`3*d,fi(D=H"2!+Br<"*PqUF,-PAr53>3SmV'AF;PB!P%noGOYS^F],;0@%,1'1TaB>2F[BbJAo%1ii#ts#Yu]$\qe>n_l7X,Bd$Hn\_qun&DW$0>\H*(GXVC\\P55Y;JCMtqlt_;c-0B-04Q1g6TaH8)K(*ir`89\uU(1Xu&dsH2g7etrD`qc(AZ,WsLopDgY=u8THmkl+ZNGM_"$k+4Ok\$stiG"?*hR)Y7iO!!Dl;b0Ac&/4uq`G/1"bead7n@l=HN)u9m5"*iiVr+jqr1sIO0X)XVMj>Wr+^P,'bfPgCLp:I&UZU@>[=3%\HE3'6;#$]#^3.=4oT@NQrG.!J*bAf]?E1QYb2Jk83P&X!oau_VWAOd(l!X2=KSf2S,I_U/r]ZBUCN/sL?)\:..8S8>.6Jpl,!97qY!849[.?\HBDLNRlV,=/G\\E]hC%0[4]\n'1poW^F`b+7.]$`5<;"XhrnsABbNgsT/I**/dn"[)96]iD>.fC\:;([YJkK8`)U9%g4bjJhBT(;[EKB)s>e)u+ICO1fi\9/l2:p5f4'rC7o&KL]Q^g/o"^.6T3X'P2N&Q(i/trshi*$5">`8CrQ.6BnG'K!h3sBf43!%tW.([oW4s-A(PU7jgt?NDd)#8n;mc@R5kDK+$XPUq=M(hVlt+J_[Ue4LbRR\Y*o=n;sILiGgjTnPJrai?@n!iGeo)O*cNK3#mUl]g6n!]g6n5!5ddQ+?U,=iGicI*b'%!*[cL-\2O\S_a/P&)ha"!)hc6<+?]'$_W,SH*qolt+nc-!E<6E,H\:fI*/)AG6$S4!6$Sn"_W0Jq4:VVTEGlC0@W)f!-\1]r2[GJ^6$V0(KSS2!KZ=BA4RNZqj)>PNpBKS"p'0Jq!XOj6KCCi?KZCblG_j%!GancNj5(n@%L:s4D\*t!D\*s;JFL'-#`lkhGha6kLY*Q!`sEkNmL@%nE"F)b#2pa!#2sP'#`j=bn2MD@a1Xc`LqQ*!S,gFdhB4oj#N9Z@&0>;!&0<3Ln@1C_O2F8.g`(p%fGfLa#p;@u%Dq.E&0CQMi?@n!iGeo)O*cNK3#mUl]g6n!]g6n5!5ddQ+?U,=iGicI*b'%!*[cL-\2O\S_a/P&)ha"!)hc6<+?]'$_W,SH*qolt+nc-!E<6E,H\:fI*/)AG6$S4!6$Sn"_W0Jq4:VVTEGlC0@W)f!-]h!93r.\Q>osKNNVrA;PN1O]f'O%P/U??RY\lmr#bXhk-u"GU%/'0-e$2*Xq(`b7dg/nb=3(@pVRDgu9h\ZU,dBd5k>reZF)cZXXll&XXA4^cFY18So-HSL$MM6;mWZG\knJ+MMYNpZhg962JOG]Z[8Isb>qKh&l'LiQ4]r1>nYlo[3"jVQf(s.S2b#HCH^qc<^1df$.T`"`m5kR1<:]00n:8\Fmt78-Tb+#@GaH0!i1ZVSendstream +endobj +9 0 obj +<< +/Contents 16 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject << +/FormXob.dc6e6a3e11df0edc665d6adf6db5c37e 8 0 R +>> +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +10 0 obj +<< +/Contents 17 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +11 0 obj +<< +/Contents 18 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 14 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +12 0 obj +<< +/PageMode /UseNone /Pages 14 0 R /Type /Catalog +>> +endobj +13 0 obj +<< +/Author (Android Cast project) /CreationDate (D:20260521190501+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260521190501+02'00') /Producer (ReportLab PDF Library - \(opensource\)) + /Subject (\(unspecified\)) /Title (Android Cast \204 Next-gen egress review) /Trapped /False +>> +endobj +14 0 obj +<< +/Count 4 /Kids [ 7 0 R 9 0 R 10 0 R 11 0 R ] /Type /Pages +>> +endobj +15 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1739 +>> +stream +Gat=+hfG8V&:X@\Z&`p?SWrF$%&OE:*9+d+#0,,UD^SSdl$A"\L?A1M>&[NK6[0d.&KW\b0C(JkJf72Cd_XS3BqMcKO';9"C@*AWOh%(lTSUP.?eCLDHgJbr3?nEkn[idK>SY0bJ&ci]3AW%'Jj]g6Lff^Z2Uh=nM@b\"k!;jl>e2*NsM_;I8[L,@+\&=lA5B2Oo.f)Fr@YB:*>R"JGt_KpoaG5HM?^&E=B*f[B'*8c5d:G+leN'G0q@!ZjhZ@uPHgWM7@`l%/M"*X1\A>XC0Q(Tm02t@(E/QN$qPa!@(OXWq^I2n(O=G/HGf+k__\I+rs$"5!MI$/c85Ka4`)A6Ji_3iD7Y72\@ASA1CJ\#ma'7@+'FeuHDfL+<^haVj4pP;!-WW#X]Wf!/;h]Y)hF'W3\VYNXriO+31atTY_e?G<`-T,"-@AYN&=/@pq4uZ\^W4;e:`]n_=cWMAI.(lC:SqcbK5KK>An]NXei]KoBa.M)G*:fcS?7CIXutN%Su[9qm_N[6<]i2L;qOX2Xu>`GAqi?#^(4%V2>3c;"m>lVZY_Nl]jbLbcHQ;N>N+f061iBft5.H39_iAU5=!4N*S$$oI]YrcLY*5f18Hc38#$U];-$69juD,#u]<_'L6DU<(Qia_&h`#GY[dftV(@ekWucK<4,&ri]Do8?Ar@8";9d'@%DRX&9hp:p9'R>V$T_Yuq6LdBR]0usRo>TQ6nMc+7'OWG>:;sCE5S^J"V*B)c)JKB1*^UAW%`+F\f#ft`SjHS!^fSpj58`A`+P\%iqgFa]`3Zb+i([aTQGNhc"d@k[:i(7q_RUgp/DM=1)/:UdB1LIOn`,]h\#@[^tB;Z>JY2$SbmrGp_n/HZ3fu@rIL14!'4ed/-~>endstream +endobj +16 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1512 +>> +stream +Gat=*hc&Pn&:Vr4Z&e#S_NJch.1[F;#c4@S*+@RHj@-#Ykd/#(H'\>ZcnUbhU&4Z&\^3M;Qi/^3V/7OmcUkPTO0FJ12X\SA0p&YV!,^LUTjcNZ6KrWRN:q;ao9V5jl+]a;'jq:R5!a7]Xpikk*2ibPjd0c1\oZD[TRa)CNk-;/(^GAY[-&dL)%7VZ'A]>S9YUjO\i*I*faN9p$@4E03n]s5WY?mW#hb>fjoLT,s?a7Or>6T/U40ijpg*<-HfN.**k\)M-1CWN[De*GF'P17=cg/OdV1cQte($g-EKHBk,3@N+B1V^uNqAP=]ikJY;P,8*H$FG6X&uTMsKCOh@a934_+CW'?5.)L?Hd6cMk91-\&)`6e3!o>Od&?n"3mgtC;VUg%olkJ5n$hW_+1plf]CeR#0W^+AbrFsmbomEGh+gU[O3aC9oe:B;+`4VgjecUO?i`/Co[EN/N;8.s0PleV.jK14[@[Q06Jm@:b,3i_:Tb(^%HBAil;]lSNr^AZ7pg*OU6[-)R)gTGJ[q91qJ'Z[TbM%eU==b_s/nJ03i<9g$I=-epm9_M/mF>JCWdZ(AsFdd\`]Cmt3gKLs-fR3)['RM;k$q2+uBJ&-]!koHF)ZkL@?lK0u$7H9`lrnE'Yf=IlZm*uA]8'F9ZYPT*+Mf+\%Cf/b@t4<*#G!).ZF:;8@SEq`k>E_?+meQaWN?D:m2^BbL19#m@jaTZq/P7QQj`MHusaa3r0:i"1GDD`$m%,hR/A#jub6r1WN8c9&cFFkWC`4lbj0VLi7+m_6"AsHT?ZKDlKlU/_d'T8'Rd=O7cQJ#)dW"4f!W+W1+^/bM'I~>endstream +endobj +17 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1245 +>> +stream +GatU29lo&I&A@C2lqpM.Q2j-LT,^Sb:8a[EZ/T#1JP!pL9G.a68_'ZP]aKpr8D1;=F>u0ImI%mH\'&%hnF7^jIoZW`T>PRh#nRI8-'6I]@K%'jR#etB8F%->Skk!+6BVm58:6#/B_J!"4cU))FJ(),9*D$rAH=6fE9"`d>:"'a=n+S)E@%"meDMeDJn/4!;V100mPig7G`[R-%6$OhVjA5=*\\EoT6'ruAg@S_B5iqG;\K\>`k)fN)V(7%k7"%I)qDH;rfPeuAK3T#XOlc"SP"tf&g97/t3>.j&1Vb-&j,Z[0;([E;Y>!*MsR9giKR\J@:DadSQ'iI8^$WZt@NTd#k].l(YD'pq].D^Mg.8c2OQVZr,*e)qK.KlOgKF%Hr%&U\H7G[/b\U>jISn8T5kKYH^$PbmRKlY-96P2]NllZ&R\XNGY`raj4#I;9?':?C_V6UhrSBS[HZ?@J],dTK"P%5I7&/!>Pf^i#[i4!#HNVt++08\mL,aM&6j*Vrc(hXD:,FD<'aC4lS61*5!UbB<(%PNLqHQ*Zk`smM&QbJLGegH0NPEWGeZ_r'WBjsLQs6\n6WS)>:8aPE(aklc`X'B24kM._gmA*h/M]7VErBTc]\`7s_L/&-LR:ifVE=(XCh@T/;TGYO(d;$E!E/2bW^S#&"k5!58D>[X2i;_<>dQ#,"8hB<63s8;"9q0MAqjH7l!gf%=)5;/ni\YAHn/29Zb,rT@gN?j]ao*I]"#=kHgH:]1)Jnktp0&V9!>kNe6H_7"[kbendstream +endobj +18 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1521 +>> +stream +Gat=+gN)%,&:N/3m%YQT1]cInLQ8+]Bq!]7=E:=1d7f)GaB"3r>jNPYH3Eq59AQj4d,7An'&<=IQ"(.rQ!u3Uge!tAVT&-b^"^+Yl_LA0+f_5466#,Y('`)9F!&;N!?/3WRh1GV^ga_^\iK3pO=u/0e'i)m)6>7*gONjsZ]KH$OMnAlQ>tinH*KCJRC]'eeW'NTli(9g+O_W=<))ED>o+?Ea<5;1C5rNJ)#m`5D_'bb[FQqeoN]&r'm3,L-bqVXbB$c5=@"lTk;#'YrU!GR[BKCTn@T`Z#eh@n@&]X+"m[FAP9jeoYZsNYrk4NWLV.T4icksO[$'W-Lfob=OGAVU_`Na"\1fj5iksC$D7?[\ao$nNmh<[;Q>R8d^YXI/-jI?*Q4gSe)kTH!mi+J0+]ZOl;;M]@\%U)AoQnu\MQ.8@GM^4;?#K^1@UM*':ofL+`.5XtN$:48_=uC8TI:4AJRp9j5qN`Yc0k?GOTM7d$8na4Ne*d=+,#SdJN;#VruYQnS6#uP4k-0JYUe\'IeK0kYT^!CW!9DCJ\5T4*h[cU1'"cm744BJiAYWc@gA!Kp*_7u=T5Cj"#f%&H'4kY!PPXN+7-$$?<8`-0Sk4#Hd50RKWA\H`d+"`"VuLQH:\`D1+\l2?Rrr`*4.0b8.5R@:B_X-(dC%&F2:C,@O+D81UWL&&m3Hg/!_PojpelPTj+!bTh8WC=8phnI:HAg\%PY&gKdu)_h-,KQPZ8m)R?"6<;\\GjS^uO3uEJ6.A\lf.qK+T5R*&2T&l5n9#E.kQ%i?a.LhAn'&qF*kN:p#SHH,gSbC2Y+'Q:Rg3%ipTp6/:4t*fC&sW0.!UsZo*=f'LO1,8R>]/%8=O@*E:3@Fc1)H7H1qkp\iS#']uokk"32q2Tj;2O2(+dk#\1)^UddBeJkkR-^c'p0".jf$@hH_GdtI-7,elB#K*OX&^nqbP[`j`8n)5N!p/AV.i5$0.Dg]FIYO%er@.Gs#W0*)~>endstream +endobj +xref +0 19 +0000000000 65535 f +0000000061 00000 n +0000000122 00000 n +0000000229 00000 n +0000000341 00000 n +0000000418 00000 n +0000028157 00000 n +0000028240 00000 n +0000028508 00000 n +0000053186 00000 n +0000053454 00000 n +0000053660 00000 n +0000053866 00000 n +0000053936 00000 n +0000054251 00000 n +0000054331 00000 n +0000056162 00000 n +0000057766 00000 n +0000059103 00000 n +trailer +<< +/ID +[<69103a44ba79ad224f4c4d9612cf06ea><69103a44ba79ad224f4c4d9612cf06ea>] +% ReportLab generated PDF document -- digest (opensource) + +/Info 13 0 R +/Root 12 0 R +/Size 19 +>> +startxref +60716 +%%EOF diff --git a/app/src/main/res/drawable/settings_app_info_divider.xml b/app/src/main/res/drawable/settings_app_info_divider.xml new file mode 100644 index 0000000..9542d46 --- /dev/null +++ b/app/src/main/res/drawable/settings_app_info_divider.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/layout/fragment_cast_settings.xml b/app/src/main/res/layout/fragment_cast_settings.xml index ffa68db..e6ef28f 100644 --- a/app/src/main/res/layout/fragment_cast_settings.xml +++ b/app/src/main/res/layout/fragment_cast_settings.xml @@ -285,6 +285,13 @@ + + #FF000000 #FFFFFFFF #99000000 + #66FFFFFF diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 749ca67..e788592 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -11,4 +11,5 @@ #FF212121 #AA000000 #FFFFFFFF + #66000000 diff --git a/docs/_pdf_build/build_egress_review_pdf.py b/docs/_pdf_build/build_egress_review_pdf.py new file mode 100644 index 0000000..16af3d5 --- /dev/null +++ b/docs/_pdf_build/build_egress_review_pdf.py @@ -0,0 +1,383 @@ +#!/usr/bin/env python3 +"""Build 20260521_next_gen_steps_egress_review.pdf from summary text and diagram PNGs.""" + +from __future__ import annotations + +import subprocess +import sys +from pathlib import Path + +from reportlab.lib import colors +from reportlab.lib.enums import TA_LEFT +from reportlab.lib.pagesizes import A4 +from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet +from reportlab.lib.units import cm +from reportlab.platypus import ( + Image, + PageBreak, + Paragraph, + SimpleDocTemplate, + Spacer, + Table, + TableStyle, +) + +ROOT = Path(__file__).resolve().parents[2] +BUILD = Path(__file__).resolve().parent +OUT_PDF = ROOT / "20260521_next_gen_steps_egress_review.pdf" + +MM = [ + ("diagram_current_arch.mmd", "diagram_current_arch.png", "Current sender path (1 encode, N unicast sends)"), + ("diagram_multicast_proposal.mmd", "diagram_multicast_proposal.png", "Proposed multicast setup (handshake then one media flow)"), +] + + +def render_mermaid() -> None: + for mmd, png, _ in MM: + src = BUILD / mmd + dst = BUILD / png + subprocess.run( + [ + "npx", + "--yes", + "@mermaid-js/mermaid-cli@11.4.0", + "-i", + str(src), + "-o", + str(dst), + "-b", + "white", + "-w", + "1400", + "-H", + "900", + ], + cwd=str(ROOT), + check=True, + timeout=180, + ) + + +def p(text: str, style) -> Paragraph: + return Paragraph(text.replace("\n", "
"), style) + + +def build_pdf() -> None: + styles = getSampleStyleSheet() + title = ParagraphStyle( + "DocTitle", + parent=styles["Title"], + fontSize=18, + spaceAfter=12, + textColor=colors.HexColor("#1565C0"), + ) + h1 = ParagraphStyle("H1", parent=styles["Heading1"], fontSize=14, spaceBefore=14, spaceAfter=8) + h2 = ParagraphStyle("H2", parent=styles["Heading2"], fontSize=12, spaceBefore=10, spaceAfter=6) + body = ParagraphStyle("Body", parent=styles["Normal"], fontSize=10, leading=14, alignment=TA_LEFT) + small = ParagraphStyle("Small", parent=body, fontSize=9, textColor=colors.grey) + + story = [] + story.append(p("Android Cast — Next-gen egress review", title)) + story.append( + p( + "Summary of sender 1:N behavior, bandwidth model, limitations, and feasibility " + "of single-stream multicast plus multi-tier (full / 720p / 480p) renditions. " + "Generated 2026-05-21.", + small, + ) + ) + story.append(Spacer(1, 0.4 * cm)) + + # --- Current state --- + story.append(p("1. Current sender behavior", h1)) + story.append( + p( + "How many receivers? Up to 5 when MULTI_RECEIVER_ENABLED " + "(CastConfig.MAX_RECEIVERS). Sender opens one CastSession per selected device; " + "failed handshakes are skipped if at least one peer connects.", + body, + ) + ) + story.append(Spacer(1, 0.2 * cm)) + story.append( + p( + "CPU / GPU / memory: Capture and encode run once per cast. " + "CastFanoutPump duplicates each encoded frame to every session. " + "Network send and per-peer UDP/FEC state scale with N; encode cost does not.", + body, + ) + ) + story.append(Spacer(1, 0.2 * cm)) + story.append( + p( + "Bandwidth: Per-receiver unicast duplicate of the same bitstream — not IP multicast. " + "Rough LAN egress ≈ (video + ~96 kbps audio) × N, plus per-peer protocol overhead.", + body, + ) + ) + story.append(Spacer(1, 0.5 * cm)) + + img1 = BUILD / MM[0][1] + if img1.exists(): + story.append(p(MM[0][2], h2)) + iw = 16 * cm + story.append(Image(str(img1), width=iw, height=iw * 0.45)) + story.append(Spacer(1, 0.4 * cm)) + + # Table current limits + story.append(p("1.1 Current limitations (sender-focused)", h2)) + limits = [ + ["Area", "Limitation"], + ["Primary peer", "First connected peer sets negotiated MIME, adaptive tuning, and network feedback."], + ["Codec", "Single encoder; all peers must tolerate the same bitstream."], + ["Send path", "One CastFanoutPump thread; serial fan-out to N sessions."], + ["Wi‑Fi", "Uplink often saturates before CPU on 3–5 receivers."], + ["Topology", "Sender dials out; no shared LAN broadcast stream today."], + ] + t = Table(limits, colWidths=[3.2 * cm, 13.3 * cm]) + t.setStyle( + TableStyle( + [ + ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#1565C0")), + ("TEXTCOLOR", (0, 0), (-1, 0), colors.white), + ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"), + ("FONTSIZE", (0, 0), (-1, -1), 9), + ("VALIGN", (0, 0), (-1, -1), "TOP"), + ("GRID", (0, 0), (-1, -1), 0.5, colors.lightgrey), + ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, colors.HexColor("#F5F5F5")]), + ("LEFTPADDING", (0, 0), (-1, -1), 6), + ("RIGHTPADDING", (0, 0), (-1, -1), 6), + ("TOPPADDING", (0, 0), (-1, -1), 4), + ("BOTTOMPADDING", (0, 0), (-1, -1), 4), + ] + ) + ) + story.append(t) + story.append(PageBreak()) + + # --- Proposal 1 --- + story.append(p("2. Proposal: single outgoing stream (multicast)", h1)) + story.append( + p( + "Goal: One encoded stream on the air; only handshake-authorized receivers consume it; " + "save ~(N−1) × bitrate vs today’s unicast fan-out.", + body, + ) + ) + story.append(Spacer(1, 0.2 * cm)) + story.append( + p( + "Feasible with UDP IP multicast + unicast handshake (group address, port, sessionId, PIN). " + "Handshake-only targeting without multicast does not reduce bandwidth. " + "TCP/QUIC cannot deliver true 1× Wi‑Fi airtime.", + body, + ) + ) + story.append(Spacer(1, 0.3 * cm)) + + img2 = BUILD / MM[1][1] + if img2.exists(): + story.append(p(MM[1][2], h2)) + iw = 16 * cm + story.append(Image(str(img2), width=iw, height=iw * 0.55)) + story.append(Spacer(1, 0.4 * cm)) + + story.append(p("2.1 Approach comparison", h2)) + approaches = [ + ["Approach", "1× sender airtime?", "Notes"], + ["Unicast fan-out (today)", "No", "Same encode; N × send()."], + ["UDP multicast", "Yes on good LAN", "MulticastLock; AP client isolation risk."], + ["Sender server, N TCP clients", "No", "Flip connect direction; still N wire copies."], + ["LAN relay receiver", "Sender 1×", "Relay pays duplicate bandwidth."], + ] + t2 = Table(approaches, colWidths=[4.5 * cm, 3.2 * cm, 8.8 * cm]) + t2.setStyle( + TableStyle( + [ + ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#1565C0")), + ("TEXTCOLOR", (0, 0), (-1, 0), colors.white), + ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"), + ("FONTSIZE", (0, 0), (-1, -1), 9), + ("VALIGN", (0, 0), (-1, -1), "TOP"), + ("GRID", (0, 0), (-1, -1), 0.5, colors.lightgrey), + ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, colors.HexColor("#F5F5F5")]), + ("LEFTPADDING", (0, 0), (-1, -1), 6), + ("RIGHTPADDING", (0, 0), (-1, -1), 6), + ("TOPPADDING", (0, 0), (-1, -1), 4), + ("BOTTOMPADDING", (0, 0), (-1, -1), 4), + ] + ) + ) + story.append(t2) + story.append(Spacer(1, 0.3 * cm)) + story.append( + p( + "Protocol notes: CastFramingContext.sessionId and CastSessionGate already support " + "session binding. FEC/NACK must become group-scoped (one retransmit cache, resend to multicast). " + "Existing code paths: MultiCastCoordinator, CastFanoutPump, UdpCastTransport.", + body, + ) + ) + story.append(PageBreak()) + + # --- Proposal 2 --- + story.append(p("3. Proposal: multi-tier streams (e.g. full + 720p + 480p)", h1)) + story.append( + p( + "Goal: Several encoded renditions from one capture; each receiver picks a tier at handshake " + "(e.g. full quality vs 480p for bandwidth-limited devices).", + body, + ) + ) + story.append(Spacer(1, 0.2 * cm)) + story.append( + p( + "Feasible via multiple encoders fed from one capture (EGL / scaled Surfaces into separate " + "MediaCodec instances). Cost scales with active tiers (~2–3 HW encoders typical phone limit; " + "3× software VP9 is heavy). Audio usually stays one AAC stream.", + body, + ) + ) + story.append(Spacer(1, 0.2 * cm)) + story.append( + p( + "Bandwidth: Unicast per tier → egress ≈ sum of each peer’s tier bitrate. " + "Multicast per tier → one group per tier; airtime ≈ sum of tiers with ≥1 subscriber.", + body, + ) + ) + story.append(Spacer(1, 0.3 * cm)) + story.append(p("3.1 Tier architecture options", h2)) + tiers = [ + ["Option", "Verdict"], + ["Multiple HW encoders from one capture", "Recommended v1."], + ["One encode + CPU re-encode", "Too expensive for live cast."], + ["SVC / simulcast in one bitstream", "Poor Android HW support; defer."], + ["Receiver-only downscale", "Saves sender encode, not downlink bandwidth."], + ] + t3 = Table(tiers, colWidths=[6 * cm, 10.5 * cm]) + t3.setStyle( + TableStyle( + [ + ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#1565C0")), + ("TEXTCOLOR", (0, 0), (-1, 0), colors.white), + ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"), + ("FONTSIZE", (0, 0), (-1, -1), 9), + ("GRID", (0, 0), (-1, -1), 0.5, colors.lightgrey), + ("VALIGN", (0, 0), (-1, -1), "TOP"), + ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, colors.HexColor("#F5F5F5")]), + ("LEFTPADDING", (0, 0), (-1, -1), 6), + ("RIGHTPADDING", (0, 0), (-1, -1), 6), + ("TOPPADDING", (0, 0), (-1, -1), 4), + ("BOTTOMPADDING", (0, 0), (-1, -1), 4), + ] + ) + ) + story.append(t3) + story.append(PageBreak()) + + # --- Rollout --- + story.append(p("4. Recommended rollout", h1)) + rollout = [ + ["Phase", "Deliverable", "Benefit"], + [ + "A — Tier selection (unicast)", + "Handshake tier; 720p + 480p encoders; send chosen tier per peer", + "Per-device quality without multicast; no AP surprises", + ], + [ + "B — Multicast one tier", + "UDP multicast publish after unicast handshake", + "~(N−1) egress for same-quality 1:N", + ], + [ + "C — Multicast per tier", + "Separate multicast group per tier; lazy encoder start", + "Combines (1) and (2) on good LANs", + ], + ] + t4 = Table(rollout, colWidths=[3.5 * cm, 7.5 * cm, 5.5 * cm]) + t4.setStyle( + TableStyle( + [ + ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#1565C0")), + ("TEXTCOLOR", (0, 0), (-1, 0), colors.white), + ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"), + ("FONTSIZE", (0, 0), (-1, -1), 9), + ("GRID", (0, 0), (-1, -1), 0.5, colors.lightgrey), + ("VALIGN", (0, 0), (-1, -1), "TOP"), + ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, colors.HexColor("#F5F5F5")]), + ("LEFTPADDING", (0, 0), (-1, -1), 6), + ("RIGHTPADDING", (0, 0), (-1, -1), 6), + ("TOPPADDING", (0, 0), (-1, -1), 4), + ("BOTTOMPADDING", (0, 0), (-1, -1), 4), + ] + ) + ) + story.append(t4) + story.append(Spacer(1, 0.4 * cm)) + + story.append(p("4.1 Summary judgment", h2)) + summary = [ + ["Idea", "Feasible?", "Main win", "Main cost"], + [ + "(1) Multicast + handshake gate", + "Yes (UDP)", + "~(N−1) uplink on good LAN", + "Transport refactor; FEC/NACK; AP testing", + ], + ["(1) Unicast only", "Trivial", "Auth only", "No bandwidth win"], + ["(2) Multi-tier encode", "Yes", "Per-receiver quality", "2–3× encode resources"], + ["(1) + (2) combined", "Yes", "Multicast per tier", "Highest complexity"], + ] + t5 = Table(summary, colWidths=[4.2 * cm, 2.2 * cm, 4.5 * cm, 4.6 * cm]) + t5.setStyle( + TableStyle( + [ + ("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#1565C0")), + ("TEXTCOLOR", (0, 0), (-1, 0), colors.white), + ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"), + ("FONTSIZE", (0, 0), (-1, -1), 8), + ("GRID", (0, 0), (-1, -1), 0.5, colors.lightgrey), + ("VALIGN", (0, 0), (-1, -1), "TOP"), + ("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, colors.HexColor("#F5F5F5")]), + ("LEFTPADDING", (0, 0), (-1, -1), 4), + ("RIGHTPADDING", (0, 0), (-1, -1), 4), + ("TOPPADDING", (0, 0), (-1, -1), 4), + ("BOTTOMPADDING", (0, 0), (-1, -1), 4), + ] + ) + ) + story.append(t5) + story.append(Spacer(1, 0.5 * cm)) + story.append( + p( + "Key code paths today: CastConfig.MAX_RECEIVERS, MultiCastCoordinator, " + "CastFanoutPump, ScreenCastService (primary peer), UdpCastTransport, CastFramingContext, " + "CastSessionGate.", + small, + ) + ) + + doc = SimpleDocTemplate( + str(OUT_PDF), + pagesize=A4, + leftMargin=1.8 * cm, + rightMargin=1.8 * cm, + topMargin=1.5 * cm, + bottomMargin=1.5 * cm, + title="Android Cast — Next-gen egress review", + author="Android Cast project", + ) + doc.build(story) + print(f"Wrote {OUT_PDF}") + + +def main() -> int: + render_mermaid() + build_pdf() + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/docs/_pdf_build/diagram_current_arch.mmd b/docs/_pdf_build/diagram_current_arch.mmd new file mode 100644 index 0000000..d4d629e --- /dev/null +++ b/docs/_pdf_build/diagram_current_arch.mmd @@ -0,0 +1,15 @@ +flowchart LR + subgraph once [Once per cast] + Cap[MediaProjection capture] + Enc[Video and audio encoders] + Q[CastFanoutPump queues] + end + subgraph perPeer [Per receiver today] + S1[CastSession 1 UDP or TCP] + S2[CastSession 2] + SN[CastSession N] + end + Cap --> Enc --> Q + Q -->|same encoded payload| S1 + Q --> S2 + Q --> SN diff --git a/docs/_pdf_build/diagram_current_arch.png b/docs/_pdf_build/diagram_current_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..d88984e75ba4a0dbdaf4c9e99a6e0563f0519544 GIT binary patch literal 24263 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: Unicast handshake PIN codec tier + S->>R2: Unicast handshake + Note over S: One encoder one sessionId + S-->>R1: Multicast media packets + S-->>R2: Same packets diff --git a/docs/_pdf_build/diagram_multicast_proposal.png b/docs/_pdf_build/diagram_multicast_proposal.png new file mode 100644 index 0000000000000000000000000000000000000000..4f7529618a7760e87eb1a6959357630933b98562 GIT binary patch literal 20569 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