From 0f3aeb0b3fac503c4c570a1f3e56760f42063ff5 Mon Sep 17 00:00:00 2001 From: Alexis Delhaie Date: Wed, 2 Dec 2020 19:17:30 +0100 Subject: [PATCH] v1 --- .gitignore | 1 + Cam2Ascii.pro | 38 +++++ icon.ico | Bin 0 -> 114684 bytes main.cpp | 11 ++ mainwindow.cpp | 162 +++++++++++++++++++++ mainwindow.h | 66 +++++++++ mainwindow.ui | 379 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 657 insertions(+) create mode 100644 .gitignore create mode 100644 Cam2Ascii.pro create mode 100644 icon.ico create mode 100644 main.cpp create mode 100644 mainwindow.cpp create mode 100644 mainwindow.h create mode 100644 mainwindow.ui diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86a9657 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pro.user \ No newline at end of file diff --git a/Cam2Ascii.pro b/Cam2Ascii.pro new file mode 100644 index 0000000..16f137c --- /dev/null +++ b/Cam2Ascii.pro @@ -0,0 +1,38 @@ +QT += core gui multimedia multimediawidgets + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++17 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# remove possible other optimization flags +QMAKE_CXXFLAGS_RELEASE -= -O +QMAKE_CXXFLAGS_RELEASE -= -O1 +QMAKE_CXXFLAGS_RELEASE *= -O2 + +RC_ICONS = icon.ico + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + main.cpp \ + mainwindow.cpp + +HEADERS += \ + mainwindow.h + +FORMS += \ + mainwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..d4fd4ed127c64f8a4afdcdba728fd21eddbefccb GIT binary patch literal 114684 zcmeF42Rzm7|NqZ%4u=qukr7eRFj|PRXJs@+R>{uF&N>GnyAUEfBzvzoBt+R;cCz=L z=YJigue-bMyZiq3?K}QIkH_orIp=iN=Xzf6d0n3q1OkQNL9l;N2qVOc7Xr})w~@$C z_gV3wkU8*}py22G!Vn0Z2o%D}`RRV#0SH9&K6oYL=li4($XGlSLJE%9_tS<$Ab$B! z$OAbU3E~|zJHT5LOG%1e!u~5(_}GtDx*G>RllQ8WsL&P5_VK4yA@pLo8%1Y>f^Hv# zm+W#qx^K*#mCVnbdRG>yoS&$WpwLB*Cn#&>hfcNx1Vnt)jSP`#%7PEi=P*@73KCTu zc6T}u?j*?QB-pC;C`hhIpgP1PZ}rMm`T4tfGBsBG3>8<*%&xvPi|@J@7R&8@kY;b! zvq=Mp2h{Ln%HF-BIHSaC+3c2juve&R6o&U4<{mR%yd}vJ>CmC|QCoZ)NCKp*RQ+@c zT>r5eLf>j{{!8oco3sjcYa=UtM zIImX(iNg*x(sz(unH7_ADhPgbBIkZm1V^1{40wBw+L?52F8EHo!W~^&(+=uveG@~u zJPvPlgbt`Kx!_MA>`1y8hIH-y4_=aJfJVDM4r3!^UqLTbo+_B57a|(;$>Jy7LoC{I zz##}$jb1%#bXIx1N}GuSoUd@k+SvTHb2b|tJ@k+ayz@>jttU)z+)VTyCDr0w#q>2^ zK6_A?WX{ooaBmTwfx6vq-U z_>qVFjC@&e?`|CVkoP2*u!BT1t6&*m#T-mJ5;3`Hqbvh9jeII@5 zf}W}rx#CHBBp!H0-oB}`;e^yzD?O{Kh^b8W&7)502+aq|J-xi5wP%X3=Tb~&kr4SM z@N76+z)>AUAz=uPM_T)9n0;Amag`OZ5aF%Hh_~mI8K(FgP9Rl}CE8L*!)r|;{25AX zZU`G<9`b_Jx?aQ54~8SKkIQW%FbD?@3r@?4MCDrS(4yA;=#f>?U zXuHpm+OZj$p;TbG+lb~sQukqooxYtp!}w`Uh`t7g`c_si|BYe927}S@hIYgNbERW7 zc=FsOKBJ?YFmJMH%3F#V=nrS4RYZ6k5_E)2mGM^4JI)FB)*yoAc;e{LKJJv``+MZk zGMW1#25|5Q*jz8l&Zb2u*saf@*kdvUN*Ig7jUXcI_l%{_Rc;&;B=lnu;W_EO=P~y@ zG>TvBG54D)6^14JKv)PmV}XQ~XU8POS!u2h>Sw-QcRanp1gv z3V%*=vP?sygCB49)C$@fogLJ?f!N_x!UH~@Ux4V0Y6Zs$jx*Es;ka(*8RKPfvCl~Y z2en?1yoGwHD_ZYUQBlOlzT;pygd37y@h;wlnfmq$^6Kqda#<5Af=r52q(+<#?Nkjt z+LqvX4)<64jfqpd)^F*`DXKLUMkWc5z;x;zMvmdKSrU44oJd?(p`j)o1;aBHf_Mv` zbaJClHUG#|kK?;AU~A+{SsEu2JzPCTdF|bi#kEE|)hcjn3`B=_bywdd-^GjLKBZJq`5}oUT7vK# z*T)2s{V}*%>kR|)-coeMQ9bmM@~gXO@QDYoU*&Bz`dyEHG&ghg#C1|zwb}+8_q>K! z-1F#;fTV?39nzB?FzUM-4Zg*zs%LncI=vOC#UgPJE|lr3cDa<@h3D2eSRh4)Xxd2) zSq$Ff!wzDfjKN(a5M?P5c<<0NrB`2)W^{`0SqYo)DP!*~vG1&(gZF)mt>o?lwC$ zk8)kBOzjtIsZBS=mpP4Wo(<*MQBW1FJV$KzF(Z6Nt6p2sUgk1`+=qca{5v`*eTE~; z${=XnGFijpkD_C4RXR(c^^u7Skd~z2^#R znuI1sryYc1NUn<=#M9`kMXaEnN9wh*eeie>h9lQ|{QlrN0d>s8V^3zuV9L0T6G>4Q zIcN{+7p1HS9?l4-T5=eoS&+XgnzS=~{(ZSQWC9`XcP}a!u1T0~JcnYc-9DK$OslQY z2H@Q+0ZqexE?f)&&k9%Q_Yp2d!3W7IZ`+8|q^>N``r4X-8HPbz34sD`JVoOgo9^Ga}** z9Me##!e-U%XtBmUW}e_1TUpXfxrfI}pD@jez?JGaZdfz2);N#KxoLHF9xD6fsiA1k zp`9AighRWO>CN&l#uOz+f>~kI)qVGsE^Go>4(UVf|AKd|u?sqK&?; zlohKzG1y68vC8dzX@9MRbDRtQ5_!+%vgBvS?aTrMo|Er*=ftNMA=kkzrFiH`?wn$p z9B+Edqo5rokq0|uSczE3-K^aB6<*q1@K^09BJgXLiK#e=qdjidAY0tEfjI@aOClBh>2Icg=UyxUg8#%!)?;q6(7A0>J)yi z|6S!xlkZJ+9~!Z7@OzjC1FuV_FK|K9UwxO; zk3Z9hsF$m0XhuBAK;N|OG45&T8>()KcAYzf?17W=jR;F|tj+Gf)6ZO!B{;~R?u|Uld zWioA{Ca;rB4jJ00H&#yyoL%t~bczr62$a@6_4eI$$ppL(BTc_TYxMS3y~9}h3I3wx zQ&Bq}DRW(@r^3#MmOkUDOHnvFmyoF1ZW0p;)pLZ0d+*UHh972dp%l$N5R2Ow<5^-V zrFfq3QEjO1)8ZF<3EKU#Xk#byHfS34MG1*kp3xzKH{Pu7Rw(4Mr*mzL6Ff{N*wHpC z4&^{*$K>heEAt*>i(BjGWOF^ToAME*Xyb{Y`z3;1`RHqXL%k2eC?t>I1QH|!#aL3= zVj!COZLWruSwu_^D@CIFP@i9RN)j9b`7YB7lcB!!DkUr98G!VFA`>-v3 z;&PmqEEIub@&I*xXSn`?stYpk89ls6NZgC@%$~}9`uc4T)NSNx388J4_y-M+pPBS} z=4^HT+OC&SHBNcgBnieK?!3JHUKLah0nAXcTx|_6K~`;)4(5aH4u65ytIMm|u2C&R z*{fG?U4|IL9o|K~VyC_Mjw_mNXJbZq94Ez&x`4X-L+w`T=Lj!23B#T|d?~kdsK@A4 zF$uaIn(=Oaz8< zRTqEQlv-$3_`UWqHw$py!@a?k015U6x>Y#OtE0ux*cpZ;M)4HNAgG zh~bg0mi)QSaZV>OFd(rr`BxDyKYDR8D~7Ke+n=E($Aj~foQ)>FD5A5|$!ZjqIiJv7 zSMtim<3l)`%Q^Rtrfsz_JGB)(>eI*tg=|B(jdFQMqBg3&;{{&ykUP^IlZ*6E-*<@@ zBwDuA>7TJKZ67-spP7|Z`}_erZJG7h68>bpMa!{e3L<8RF(-c5GuOCHt#f-ABWT zLz!e!^z$e~>wrRXE2&yW98z*2oA);8k!X_LWMbZTY1T3a=x=|{4V^wom zeaun!o|{3&wYu`yU6VyQWKML2Ch^Oi+}&B2=2=)o+&A9e78s7sJOTwp7y zTA+EOkndShp(!2eL>V1Ua$$Q0YAAFaftSRO3a%R-N%D{i z!dpB3{xSt_E64Slx$IA=&WkWiWkxk2l*CeMhV9--UR9x&$|b;5)6u0*Q6C;ZKddJn za6yUh)oYH?{Dh*s0y*9`jaTcpUnUxZQ#Ld}q`H_pytWHaB~lD;1aD$wEN=hdBpXXR zzB==;9$hE?u3;E+`xyh!lksZ1IFIAKd)&7zn1rnrbd;`nqW8H&7I2#5$K~iGNGEul z1uUb+b$3|X+OuptdFW4WMj^#SFV=pEVW~7P@r+HY_CdpTp@mwp+!!vs8R0fEFHlaU z_wGGMhit9Ub$GUtWdC%KD7&9&ZlQ5a5E@Lx;?PuTOtI&*gKO$)i6;G8|0r!*lVn53 zz5aGhH9hHiKgzhs(ZeURDOzfglv26tIR58p15A@tR*+S`?~QP@Rx{P*Z_>={GEsp% z>9F>0Glp~9>)0xe%v77XzozAUeQS{<_T3!nP_G9PMt!eLI!fpc`JIMaH_Pw6&X(35 zUAdjz_U2L}g67tpqvMA$L4lO$)A`BoURx)OA`|fzbm>t-o%bYCJh=zop$E`%a7J_D z_bPk1_oqkVmTFgtm3kVbt+l6$kVcaZw>}jppfEV22D2+@P&CWBO8)>pyL(tP16iBn z-(v#LUpeo52)&na*~#qv>mXh>Bh$OVt+z!9uXv%&Q+bG(=lMgjEZ`l94P|R0TzzP^ zUGJNN-`2V=8>*eZq=<}rvp{OS)X+ZaA^bHQ~Qmul+fbh z413a%TERTHjST!z1XZafO)#fdb0|BB>e$-AYdZ<9a6`wrvwUfHQcFwd?VT0RB3Lo( zyVw?!BA}N1+Nv`3nkYo1CdZiCm0n}-AyP8<$H3P+!$vejASnY>ft;Q-ADOO38e|2?1O5 z0Kr}jU$>}d&q;C~%#`iBV5d%Ks}`Kuk)w;L8!JG)Bjg)}!t6rB_&Jl5Dlw_v`i>Ok zMsWWJO8o3pI(?@d#7S{%*NKi+}Cq3A%|MX@tG$@USJlXl^Bb~z*h};Lomy0 z<=3sR(|AwE=xFiKr*gt}%3c${>OH0-;yc@#6`~8JzPCcmhQ4+R58p$?-)4frh|DhH zFf`kfXdn`tS#SFJm4gflip4?RE2WYK>oa9uY<5J0FH0tfiZpjuc0>$lRVju?LR}LN z*~&;>G;S1SACQ`d`g+|Mg|Q2(Uv?&uX?lNcY;37wJl-lf?C`h={Dc6vo9bA)P*<7u zyOTFuADQ_Tw|MLyaE9FwxeBM#x|Z6uQ`4eNF0Mnjf&*5bDMd~!%8Rql7@j121w%Ga zsQv-JU9o3mU7&0_|AX<31X!+;WSW>^cSt~$wXyu&zYSP z);=QU$9(GO5qg37+!>Z)C8Q?5l#Wo!+BLoG>40Rf-W2_o$_~;4N!Amv3EO8a50dvZ zQ6}$cFqWf);;O&Hg%?dRo)nfp#P(7V;+*WX<48=>tI`;hX}pDGr5zttL@L2ybKF6X z@-B5}lYtG|WA`jy7@wanGo&o2v6xico05F5=~cESlPY1%br*+<%$UU3M+qU^H1VqI zZCnfa?ITugDepslNh5^3Xnb?z1x206&CG0s)eq1zJYZgG-pQPMr<-_oB84)5f0|t& zXHfcfk%dw7i=-5tGEuHY=5F`6=dpcG)Pz@w)$TAhCitDimp)>z89@>^a+kuq;4B}Q zmlb2-TxaFR<~o}#?54vOhxlObsv5Ey!#8Rj@`hmQP(_ze^G?ab$q-r|U7NE4evj{Q zn~9QoQ=Y68CF#&GmKBX$MbJR=SY0+Ld>2u1i zWZlvbC4ES_VQ!{>zJWGVDJ>(@zj9(y;8=CZ+_Mucz@6{v3Vj5OtCCE{$)w{>V#M0L zBF{G4{$8ua>+a-}*1i)i-8&Zq&<#!QsftYUw&4^7o;QR%GP`erGE%8?prrR&L5HpH zD9p-Rq>=Nve!IHwsik?lU{1|X<>PZ*nK3ZNa3n&eGQtRMq9^%xVYir_?nQJq1(8_{ymjp&*Pr&+Y zC+bS6{#(inMtTV~X~MEBPNUO;Z2O(+%Sx14mC4SQln)5sjM|}mHC4h;y_UU+dgVSX zs&gHd6nU+dS0lTQICZJWY;{y=p~k}IG+v2CeKLJ;Qk7BrokULqG1rF&^G)J2AbrCy zb_7%dF}Ru#gweVxu28muBxW-r8z7+eP-O2mB}y@9>S}}D`=zy2SZCIU zk+Oiv{VRgcw25pP?-ka7N>K*1k+xkRT7lh?01YSJarJ@=T+#SbDjxHWBUd*S6W#f06mh;;X5 zBY0(h@$|6wT+bjojqB`2`jC)%ct@%xAK0oY-55U(R-B zvH5UJSAi2kWmG7e6{Zt4B>hNcTCe<|nNz!RGDRs8CTVA(x;_V$zo|w=JpwB{1_ySa zurzo-Sf=NJ#!I?|*aJtEQg_U2oRLu9QT2P-mef&*S%Me1rLWYMmZ3?Id}7 z1-RXb`ROdG?tXNxyFyn(@~~FpM1n%}gE>^(jBzCDTvy69C+d%byiFa~*NDZ3VUM$q z2%oVlumPQ$en5ifo98 zhSFKfH}BLelHB=gStV(P{d};mo0yw^65IW;R-o_<=Z9xPM2E+@ObTUIkTaH?viI6j zxR|J$FPYqBEj2#RV8mgQk^au;sHZkchQWx`pMZ7Le%*N4*Kj(qLq+@)LXSNcmuQ+r z8uUtd-{9ShBazg{uYMT8#(1qcgszWw0?c=2U1ORVas0K`Q*<0kSs~`Off?Og2_$w4 z-UFtc%ja^`o9u zhv)b@h=z^yiHWk)gkJf)$f9G_(sbwf!?wp20?RTOk6-ZC=3r-&OA1g6EhU@FLJnQ! zmNRe?WX@bc78GBqH<$aM&$Tm>QtN_*oCqO^cvSnApIoG$et+Xg?nWDhf8o-qMjGe1 zw$Nj;l*E35kINwn$s9Pf)X}X$o;pHSa+jXrdhJWMSa+#^xPn}*7-c@#k#NE<_cC|? ziKr@uVmEHYyGSU}D^sac}7n%!kw)}N%F=djOd@+5rTYCdmc(f z=HWH7N(@8#LQ98`VvbfrFi+0%;##t} zJMO*sc#I^n%A$p~N=51Z;Ip-6TFIVtAKJ+#xhqCXl+e!$QMtQkymgW#xh-fERJRJP zM#a1Br<^V6S`)kPidqwz#2S?OB{rW!6&}E}r|Mf@8+<`u)4_(W*DVyX?1ck=6n|fO z2l)jv1J?1C@%nm#5C+8?XAF3ZPVDS37{5Ko_5pv)LW^_bY5!Y7xwh;K+|ob_Fufu3v^Aq9Dz1SWVbn`~MszEbtRH7IM1=J+c0&u;*b)j}w)jv|^Envh zlO~enc(AVCx{%V^8|IEb8Dh|r_9ob9F1C5r>@xS_JIa{ZYzo3I1L(AQV#LO6QGA9b zAyt*U6{LI0^;YA9fm~~PPN~MLiv^aGp385v#Fz8p+TqN19@RRG861)MfL}=_*mw(` zJqHblpfzn^Jrc>Tfj_>|n$umL&SFq171jw^pS&$h_`wT(%c41hLRuucT(9B$4W!mQ zMX=N0!3;((=Gx3r8r|pK^`RGZP*rkbJO;guHMSlK`G&5Ylee=t=^GG~naJz6Ki<4x z&Q2}?5t2|_Z9TS=`KBb7Ha{8rY6lzLA_J{aaVTxo>K+!|7rReH;ARCozAM0wrpkmQ zL)NcFh^sLYS-B-R7H0VK_ps^~&AI~H$QR7ze%87cOIP%xpk4vKJyvw{&3tZFVMYj-?Ma6uT0+F;M5)yhg_nt zv#TnL`#D~w9~aVS>z^8L>0ROQe3tn-EEvc32RFNi7_5cVJ36+DvNtELs;=Sb{J!d=GT1X;jw^uC5Q3p2|X-zYw&;3M&A(*i? z$}w)u=pG-i?)L;A4>xkz&OPj@5a6#;SmdbA_f;G_tqJFrX>&NHm$f?P(>b|v>f(hr*1tQ&){$!AGR}m@$IB7yzhSd4m0{oC+XZN zshb;ExpA&O((K~#uW}w(P;$O+lHdQD;zHhn)ZTmZFAJ;_ORwpX^p_pFklWeIK7*b$zTmQc&^Ir4^X4yBtHxx7q|R$nOtt=!wadQrSMp7hU0VV-Bi zZ{}Z7XB}D{VlFhFJ)tz!b0mhik$%)H<8Hqn8;{y-Cg%)C!{ z^@^ZIy5Y3H6{(PS(?s%^Ph@W+@aQ*lMam;^L1I-^tIv2Z*luHJSD{TmPS*~b*DdrJ zSNOYh_Vz|g6Y4TmwCCMJAr9NJW9s-`yg*o9D#BN;M=0ID&zusCyRd@fa|LaLAm*Hb z<$*EV@%}T@E2~z)yP^5`<)GAf7hBIjqd3(w5_U(`irlhiLX%`#Fh#{(Ecs+tt+qm^ zxGKFl{x!me=3c3S{JX_D4?d{!u|K0Kn1<%7u2W+c*JcW&A2HfFF~`1+&ts-TJ)u0) zlbm{>vE=M2?sist{8wiVv87Bo`=gBP9m@Mhxs+1;nnz(?B`v3-yhFstLSL>k7}t6d z2F_OOdM~nu&$5@z)u4)7HDhNFl+`}(jbAVrgTOGVHiUfm5?OTr?H;gJDkNPxz?h+W z!mVBKgZfl|zKYt4D#kxsTsy#w?w*iNL=*H9RhnZR8ZGJrG8c)}O z!Lh-}np-w>ryIc`uDQK*huA7^Fc?u@B)@)2#?4eCVSb<~0IB3)FYM;SO#0DF@a|a5 zV3%57llSb~84~)Gi_H=rbdKZ=$tsGHG^Ga9P9&B>r?eCX_3Rn#%U=aKTZv}~Qhm(9 zvo@eqD13CX-$6#;*df~33XpemJYflVS#BWDUpbDkJEArF$i&=g+0vvWV8bNm#c{-x zMGw6d?tCqR#%eKOUNzfS!7q6~o5hY;wU0fK^U(Ro<#5AOs%z`MYa^-hCaEcXNb;ik zceh-)8xUR436jO^Qz3OHMg#rnS*mjp1u#bn_~PR<^0=|n0}Lh1SFTCcSIjyMG8D_5 z4q)NB&}zEd!p6jKboS%RIXtbd{BX?>nI}1C$+_sC3ACN4HpP$c&OGA{w+!WwSn8vB zoqLOM{A&4BUdrhc5R zq(N{Z1sr+gx-Cx+U{IB|ZX-DdlW!HohXi}6m9!GyddfZdjN9fQp8iu#^D7CwouXFq zZr9&ho+8iHOs_kQ(@kxTu|0-StgG@@ZTHH0yuw@7PF!#3`=+Fm}~|S{l;} zqLJ=cMus3VN4ojObJ$SOyy|(fx0fw0ga&x?*ACTAqa%e_=|XZLG!hJ!cZRLU?!IPz zzh3XQ(mpb(jwWlIJzw`M>*G8F--MY0$5k>2V^ToT)%}X$=_c@l^Hf$BqR$KeV=buB= zo>(mk5Dvm4GL;*_FB#??g57_mmU2-uSX%o$XW}#5iW+*>* zYAP66fdj-CAqJ?R^bn&793*mLrD|!Xb+l>42qWiF-E5XmJCkgj0=nPzy%06eHwAv{ z_?n9(f^h>9DXXjYj`y7i11p4PW_=^o^Yv|GMLq{mvBi*_nHjORS>Yxz?mnVp=g-RC z^hT6ni8M#3DzM*uKd|XK3$#ix1)EpH^-iC@(U!O@Nfq?hyB-0entVxKN-n*U`gx zj!!SrW$#@g(+4}$n%$^k@$i$?Zhu%OS`EN!Z9f@apEC)r4tTBX=kKFZqL=S z@>;}O4q8fF#{-oYTZ5O(TA$>pkHAO@SJ?a6t$id^thqz2_K5LNW`rY3n+|rKx(hj* zZl6MzbI!o$aPl3c=8SNBPIn&~TFnq;{=M@ph{ua_sT~yFQ>(G+ZjM1>JmLYw$s+;= zREbOS&N^_2k+JsvH)Uk-eP(c6;dyEP_+y85y`_rHvxzJ8m`A-bR6&oeQohbUmX0qW zMF=;F&@uF+7pxg$I0Nh3nOjWe*i+-(i1;wbyRI-*ieL05wj%5Cc*D^#p0KJ)IR+m6 zuA=2?wwluHW3TWf?%tTDUoT%TH=!;$hyy7WYbI2=%0+A&F6X1Pa)@p&B9Wg4(l6$V z;y0QXP*wMS!7wo16_>nAC*+1RnU~>&((N@9wNXfqIlLw=*V1+lb!*?5ow(-k$d4pa zyts;T%PgSY-H`A4NFHz&-Jcw6llHzW_ZgUEgZm7!m!%Tu1ZxxocB65d%ty!Z-8?wY z9)9wYK-jFpsE)OrM({d=<+`K)*i5iX&UBjw4d2z_xAUm<)foF`-M&_F2r>sJ&MxLE zFFL;1l~qra(2a=V>|wl1%k9P=GXxV!mZ})c8w7?6?Jp)iBrtP@ub_*L70eB~WWt6{ zk4mgFYQ8CF!?i`T(y-F(exGdQx|-R~lY!Q*V+>Q(%;@=Gjd^W>nY%EaYaDXpuC1D8 z_grT}k;g7(97qohDM#Zyt&t0aZcdRMR2e6_TD&gTA}+sv)vN=Qyk139ay`8IS3{Xp+Y(|DsIFd9(ee!W7!>-VB7MR|YL#-{ zvN%KTaX_Yio4i=?$E+uwCZ5DW83B>{5$5o{3^&wSv+0g|F?8qpSW^`#TN~^c*RGTq z4?bqcevFhG2eL#z6=+W#O(sN>fxgZVceXn>nf^%Bei1vG9YOQlWN*v^0wYY`E1#IL zMHuUVocC_Qou&5Gmt$+Ah^9eJ3Bpj<{H1-U&Edf*CCHSRiNVdZ@|?|77qN?fd58L@ ze1duZ(F@k)QL(u3vtR|wUw@ijDTwlY{!-$QIa5bks?=LX=q^=*37!oH0Y~n(oO>Gh z36(8=o(OexT)=yE>v!7BgI3!mCFx%a|&c;%e~m*94Od)8lQehAC1VG&!*6lCajG;Lgrdn z;78f&T&uB4XEVlQ{^6p&)~PA=UAH9bcdQI{7bfU0zM;hlOZrGNF?CuT)*h<>9)gEPvThw?Z7g~JXI;}HBXbw6+m+pP0dW_GG zWVoDP|KT;@2X?xa>!q`qFJ;U_^%a(L+w9-Pfi)nd;0k#LPEWx(+Y472v+Y=ZOxf-$0?0nd=Bt&t#gFC z&91lU$r9?8a<%9b3*OkoAeuS(TFU)d8qW$X72WiGJfD>3hxL-Va;_e0y<=8 zCG}6Nops{TZ6fe}{Al0tI>_2kn0P#hOqu?PjkA@H$vy#AVa5DW8DSm4hcMY z$RGYe`J!3toUCf>a*G!m6P($WQCF$H4l%OA6?p-ai6_;PNh+9XOIOg`BbiGPJ86&% z>$8(KN&0KinJ8sui=G&MH5L0?wv0ln*H#2+#`B^{_CMf{&QdKHiC*W3@QS0wor+Q~ z%e6@%y1yV+$YwREM zMj7m8bb=vc&)JJR&DI-nL)loh4p7imEkDcg>L<4jU~ z7Mw9OGUMQgmlE(LUV8=&B!?@}&YGRmyImSccg#lMYMf-?tG>vZq0K=`M(u5Q`{dN& zsi3PYw!K&H3L5N$go7{22U&zMzs=KlL6UP0Ozd~r6r=5@#w46q1Z&Bng$cW0<~Pjh zp|TIj@0vj%^e3u233KSRPfe;^W~jKvz?oa1aZy(LA-;x{l*)waiAQ0+4*a!*HaDBz zsIDD3&18Xq)E?^(fuZvWjd&c#UGfrIO0G4n^{cNz=##z_8JQ=(?uWN`LH5}>&+|BtQgVit7sQ01 zF|Q}H8MZ0zc;}w;);S28)6=2K6Rxtzo`zvJ8AFDG?FW_h`&q2^j**>tbc#)GfLjNZ zs%#d88*wIk9@QZK^!WU4IwxOnW`-M27c;<_wL89y6nPb=E>?%ol_+^nc3X<@wypLR zTXb4?ox1H>{N+NMgI*;HVC=au)mGrWUlNQ>Hmzms9EM%`hbjVOh-OIC<77*Iy*{CRJXR3#`(19Ziw&A>7;DkQ#rK@|>b3hlAtww}o z8yK}&!D*b1vS#kloHF0ZaQ*^ev>07I;*uxcZ4Fvk1|wI>Gdt*VW*Qv>Y6Z1*OhF94PY`n;p^fdpbJcYpJjVuk=#`=T$)v)p8tIj@oN(_> zf_KjCVf=bvJyMbM?d;*_w?<$GR(HKvYE!3KAz_(R|M%0yMycqmu4y(cIF1)iNE55AghNv)seJQtzsIF z^TGZh9aKz6Qx1<9;a;4bDpu_g?m9-hOQ3#rr(doHpck*)l1{5~hLt~AL0YZ9ZbaCn z&SbpuieY5+!wy}SE$I}knkbi7cp!G1l}zDa1JhmJVvSde#eBC0bX?v&6J*6sEAS;L zjF_h$#QTfYB5v`xP_GE)1rQ@Gi!*;QA z{#wV9l)PM?UP?5f{MRSMIEhSQ&gL_DSn17J|c@*xx2$vSR7(!Dl-{+ zZdhXNdTrks9n|3>DMF7`|FdkCdw4VlhFvfZaiV<4kPO&&z60Jl0QMBE71#DYUMgK% z&?13#MQ~g)Py(({kE6iwh|l4Xt^aWbs0lhaZD#Hjm7LLTew?W&lY5J?C{;+ia(ZjIo6=P}mXX2-7!G%7zxpuMD&dDpw-op+)jSNE|;f2Yw{T26#ZV}x>$cYcm zO`Ju}BJ0)5z!~X01f9Y8NZhnE&?xkFu(&h1N1{uFTpH0MF*s*H!m~RN_YNLU64txL zmAw{IL^Dmv;3SQo?Z1&`_>$xt_TnaRMjfaqwmLo>QUoDRPK&vbCD)&Xzg0iQd9qN(i1=U4{BJ-^^=^Ne;n20t&d7MEE_P|+y8&dW3qqD9=!nHXSr*=&dr9dq4 z3&0aGEwpCTWe17CI1*#ywK?Pltb=$he~+a)@)-JYalKhl;u5afF-vz8)uHhza3!R* zrhU<#YCf+R7%PNVGb9^&K#TK9{RzTRhwQzZS7lyNX?rT4$WAYNV$RHza5r3crULZrlGM3aQo z99Y3^B=!Mt5i0g7)lYv=2st5SQ=cFBpF6l)65s$a0ZDjR5@-V52MYJJB*^r%B6tJT z;blcI1T+n_=KV?2;5g(1{tc)CDC6Nhf-s=_K$?&45l8?r0pa}54cLGA3AtJB*z0CV zpbU6F0jdRB1iUfZ1(;*D1ejyC1ejyC1ejy60=&Nn@WyP(7u*I~1giD3CU^p*>~Br5 z_rHAj{_DOz;EfL?3G@hX?*zOt+w~jn;NO0fyU#Z6*g5bOcPx91A6C|%1lVJ+dTdS5 z0rUt+D!>{a@n1Kf{{>(8fyEBI2bMde0rM!J86XT`|L^9GWxpxF9fMV%4gM5RB#?BF z&F1eu{1=Swf9_WV+z$hJ0`?=HnEyC;tlj^SpZ@`0|HS{9?KsCxNqu- z4gLs_C(z;l+!6lI`(}VQ4v-8`5#SE&d`sWAcdXCf^7GrdWBG5zckJ;8WBfO{fA;mC z?VVuL-oM2i%O5b`R4_OO+inUSVv8>e^ndx|cc$ED?$^Pw$;y&&u!Im*yHCq{*UUpzZ>Jf zYx7&&zhaL8>@kt{_^UwPQT7Pp{~w$HV15ax|7-65q4nI~iSfU)_iu9l#2yo6j}L^v zMB5|!fn@$y=Kx?%02BInKy|;h`R~X0AF1cIYPtV{7{AH=v#-bc`|URW z5AJ|H;J&F?B%&7R;QzuL0Nk$v?w@;hpKO17zxHRv_`le*{hiH!UCVu^j{mOB|6z>( zj?Hh{`)|2p0C!B>C(S%ZA};^8&H=z32Dp3vqkr=geLcwIzO_#Cqq!ZnZ@aB$`%lIA zP{4MJ{kFXRM}7Tvo8QhJ1K4ApqYxYMD1;jj?7wLq0PcifAa$| zesi7X@Aqu~(YyOjjQ^8*?wi~{=Xc-p_21%-0n9h`0vv(T6Ho}Sa{r(I2bfa>z5B%e z``mvd#{WBewqNIVKf?Vl#`quMjse^^mFR$Y2SoLsJOco82B3B<`~Qpa+j9Ev$M`Kj z|Ha<1cK_MtKe2Z}U;y_`B{?A4fc_)*902A_K;8d~b^O0L#(!b|8}48pY~zjr+%d_U z!s||P#M}3u-f*>bN_+9e#_psbH}7O;9&rJ zOsXSZC(xe%ggF4XlLKGhxaIG+bKi{d+xqo?mfw9Vr~h5g_N(0PM|<^ux1QU|>9I#_ zeE%26_-}AWZ0C+;k4gKa#&kzK@_*+X0L%%2-hPYyU&`zMgX+1hTJ8sXwttw@Z>#08 zwcMt@%Im)s;I>Ewm%`pZ{>I2@%7*0j%AO@y^l8o z^eA>{}u27ci}Dee`AznKI|eJX3$EYK;19ST1zN-M{}%gS-Lw7g=+*xdF&@-&*nIwTPXAqd|C&3n z`AzPh*<*@baMys2{IhcaaL@S`_w9B3&x-MX*Vq5dp6&PS{ZH0qe^HFb+aBY$eEn~@ z1G~qv$CS8kD*K<|54ekOvHz0S{|EKz|1B~8yLtV;HpZj9D87#I-{iiHJ?0gd1EsFG z;(uoj0Pawrw_mvbKpnq*?^RaxHB9A8r%hFX2uLiUuX1f}}{q1T3_qVGV+}~8OBPQq3!7ujy zua5C(PYTRfXD;To|A9^Z*!*rQ#&7fW+iiZ6`)Br8{uQrXalx;^{Ix&8UG59}Z8rbi zp6yrbvaQuom|yXi6DIy;U3RFu_*Z-+=2fKF=3b1ylG}Y<&wU-^w|Y3+>$%sD4`SxW z+BVOr4DkOt#((AOzvhks+%c~o;9|-i;L80K`hYtGsQRCY@xO|HF5thF*Z(U1rGWp} zwH$U${%6*6RS{<~EAt~?=5zVu1Dke_WxmDz8@?WE@7uX!*<;Ed;8p|u@Du>t1^+Cs z|FfR$ui~Ev_-|c9^(*;f`}E)I)o-oMeq)X1hw}Q?Y#q$T`sx?<*c%mq|M$3W^YvTy zzQrBO9#gR?xZsaY0Kh(FdrrT7J$`$P$L_t^(pD`W03O5ct^c+BKkc>rRs3HA`~SQL z=g)2a$9lG3^7`Hi&);z0y7LC`|JvSv!~Gw={tNrh+%a$5;8-R92!Ftx8Sq};it|6Z zKDWhvtAEq>i{gKNnAn&8&G0XZ|7C#xKjZ7S$M~%}zSxr-GuocMh5L8MHvtDWYdS3R zKjZ$%=HbBZH@Raf0e_(NDmVC_?i&T%U4LiqApiTu?_T|G56;##RM_LMJX*uM=wjai-> z-j4d4x2phuY;L!e-(mB*&$-?97{BG~zvhm43;4fvhY!4ShkrK_1l-SkVgFS<_gDAX z{wn@2!^JlD-(dGz{wn?zfd6l7{x8OOEPHGn-;$+?SzlZFChxBwd<*z*tLMJ3|0>3R zk2?l%-&D0b{M`3^0AL^Xqc*?g>$iUU=3?&HpaOZ~6Hxd*99-1K49~+~Hy0;t%3G9?&E<&VQZL zZ(pC=;=bM2W7p+2*XBN7Pl4TM+g|f)`agxA`D3q_{Z;(m0RDe9#(!Ry#gurGVTM~? z{2}Xa{Ueq?Hm}=O&;6mV-)8Sy+_CI2wI1+Epx^Bg0^G&_i2Ju<{1*3bt;_yQ{&SN( znD40w@W<}0$F9!|w5DO^!E=A3DR3WXWpV0T!}_-#tBe-=)7)+=uivtHY_GQ5pBXbZ z+W5CVvl{UK8@_&%IhOlp_E`RyIuH2o_J;uWUVk;lZ@2laby@5YyB6Q^6YYO{jNkJ0 zpRbSq;eGYJwUK{o+`siAEdQ;3Eq34CpZR($`>N1WnC01z-+H?rdaNdJ{~y{r$nC!6 z>%ZoXWsj-%fO~!&1Avcj{YMYy%kSC#?cYZD+5ErezGd@2x-R=O`Bwq{zvceN>#{BB zH!p5&r|5vzU*<%_!;H}&F1MW0`C&q8tJl5W~@4vyW z%l=IM+hhE9x&P6+EZBq7SNHSm|1IFZ-R8GyxlLaWY<+8e4%@HoDRulF(!cb0-Dmz^ zxPPkWe#8D7etyf|x42^(JmHweO~JlgKMLyjYn!z^$ltc|yRE$bH!=Qme)l!^?d-Sq zV*E`0+hhFi?EO!;Z>`h(RQ}IIH~Y0;$N25*bFVx|F+&YMF9*i*$Fl!i$Nz@==e+)R zz8-7qpY0uM^PjoHF-@K@tS)W&0Fc}He9isqdhYY@82|9^AHDyH@xLfSY%|V(Z=daN z_uPGZ@72%b{|@lqviYsNe!I<=`!QnvUwhvIomF+^pAdxv#8- zNgxS%lNU)K2|54YKHuH$gXe@1QU5 z1pX=NdRyi#+(ilS2jw#Uz#K(Xf5x5ivXyHe4T3Y$=l#dq z#s0-Vkl2%bPtnFF3WH~Ra?)s7zbj+|0CpE*~X{3 zmnKg9iy{Av{rcy}in`+2k+2Q=a$ir2*!RkJCFWkZd+B=3#!LJOcLVmKY*NM#&>P`b zLB3s(t~d2G9SZ!d{ztO*iv4=88XU^cs5zRN814TK;Lo)f9krW+;EeQnUst^-nRkt+ zynErkJK@tyeQ)`95_1pSMOjXU*q@U@*gvEDcBb{5uIstxj^$nNaaa+f{3q%y2e+4| zW@mi%Xvf0u*|ivvzzz6vZ%2*TGv_KhW=pYJD_-ljj`y?is;(z_XWR*UQJ#}Q*uT#4 zn=rVmHlDF}^slz|Nms-eZ%w)0QpwBK#)$t;;Lo)f0g#6N_;_2T*faBTBlf(Gx7YHP zU$5)>y=EJqz#Z5V<`(XRy*QAQu?UzKnsC?Gb0!;a!kua{C>I|${;cOyt+S02|6RbJ z>o7tC?DNHANA`=|)4%MB-^8rzb?gcMLagI=%C$WFH}>y>bUouv?_7JuH8_NQ-1u|7 zC9mgFslAFDf2*$E2i0&N^`P!+_lp-xJwL>{o@JhJ7ZtgZih+H-7w%47A8o&EWsLgY ztKKq7?bYEJ_5bcyzh~FqghSc|vn83=?B}(OWqOVKroBvJe(+`7&-Ot7|_NH2lsu=Y@ z*V_fv+&Oddr`y<5uBI+V{a^CxEp{zND)`emy`43p6l*=*r%!PmZ}RQ@a3}1=p~)i% z`x6wuF~x8Ko=@W26C+OisoqXvudL^&{w7KdPMrAfU380Gi;*h+bRNZe%I5!to|lc= z#@p4W4#t~bd$<>%BKP2Bi<)my4{7_94M9R_4x&Bw=y z|32W)br^%epU&+^thZv}_0G7R$2y*3_J$aa)4xmj^(I{}6x>BM<^TxTk80!f9LqbN zLFVn>0cXz|93?LsC;nmTE&cNG6sxa~QU5dkl#h?&bppAbgG+7=iq-r3^?tY~bUn$t zBnx{{GkFAIUze(l*JWPqcNTZOT_{}-oK1OIiq*%7e<|djYcb-$pMGNiK4Hy@+hx2~ z$gy>t z7w3y=J?d8dhs@0e>UrlnUa|4guQ%y>#$40_|Jo^%ilOTZQ?>D?oIKay#942}^_FDc z{cJqxdCtpP{g3RP7!5Jw&w1H~P0{x81kaZN(fGmrsq1=6$CIvC^n4Qg1n%N6-a&-@ z5{}vWt>YgpV>ndcl0#p>h4e?R13-A_@o`qyG0xXbstDI*pE``l2thpe;ZJWZVV>-CmiHeQ!`b-!$5 zjPhUp+AXe_ZTZ5#k?Xmz_=fpj%f{?P+|E=h6t~l3ccrr~6UUDv`Za~YH_Uh1wmc)_ zI7-YmDf7{Ey~NzYovn0P=6n)1a<0?>y02@lF_MLw~1z`(%l^6|;5d`VcnWjr-IQq9H*)1m>5xaQD;o zz&A|oRowWizMYqiSLK~?=R8f*u7c3_JLroQz~7mlllv*`7|z~Fr-_y=&jDomgOd{;*g?0R$TvzYa&o*l9Rh;!!YQ3eb zyVLZ%uIp9YIZqQe{$X%e>n$tu&llZ?*66T?J|_GLdmVR*<2bNa^gQ`^n#>dKqIsI6 zI}_+j{J-dhyYAPsuIJh-ue@xW_^b7nx?dl*Cr0z``24?vkpFKE&QzmB~FcUsRW*z35H&bM$EEx^BJTKX3me|m>cU*@--W8Bp}6|Cz`^;dD?zZ?2r z$K7P(9eokB{qZd^;(uuI&4bF*v=sig3T>#r>*rq@#kX_n`h>hQ?u5Og{{!I<>~nZ6 zA63_zYBA!hw^HjZb=*z5p7zM={g2|t-`YQya(=Gi&0EC@Y1|tG=BhN8=f*H|J$*XMSEBKfFG0Y)!ylVsDUn zmUn}VS7lzbVh(^>L9YI9qyvEayj1FJO?lZk>#h85&SBusx_-FvC)^#_d&oT1T3Yp% zdi_npr=L1f9Nn4k$EG0st(dLt(>rv%W#h@m({w%KE?V=_MO$9FvHv6C5A1))eti^O zZ>qf-PW&ksPc&Tk*FyeN!96Hu+rI7r&pFUskicK}>y`DK3wP4@mdq3GOrHH;f&J;A zdaqhb-Nx%Vc{MK^XT6o@O~D6skbk!E!->D#L*=RKQ_st`F8`4jKs})TBK#fl9$@1c zcT46O``Y%rbkF|JqyvEcpJI6ST&(qW`n^z(8GqV4H(dB1hWuOm=fc+6+VwZ47>>iI zhmY6%@>Qb0qf%v4v;cp$^V&MzWaC-aGwuSo6Z!UkC;Wl^SFoNN;CjnseRXm#jj6s` z&CgM+HqLrG$Bobq>OX$M-a|E9_}4AD*^IkVXFJ$fee;|zh`xr+Hn&HBzn`wRG`L}dkZ?f^E?^WE@yzFq|&vh8R!{q-H{*;S1<>P~Fyj6D> zE@qpTDSArg$~n+V_#1pX4;!!IE`U4HGQu{@3o?Hb@166q@r=D!UN+8pJ6i}0e~|q1 z9;)HOzh2^>x{X)Y@nK@NT^k=3tqZ>F^6zY!Px^LJ_AOn{xbyo>VX&v~tbXeBG~m81 zjLduGWrqv@2H?-N7{i5s1MoNOrHN$Y!{DBf_r!Yc$gFeh_)QetJ25vpUrgT$3Jbsd z9319QTjDAMyEX#xQIbnKto%6i@lcL(-LUiNU&6mblF_ici0J_aHmEmb0X zb*lUDf9zU}o`z!A=j!+SaDH^E#5oD-$2(CY@Ynr2JvZmd%VJJ&{3akTYwLM6X3H|~ z;oGr}*Krp|UrgT!iYEM)rU3Te4~0AYeLX)HHZRMuJC5P-T3+pa<*2p9I?uEA%A*D+ zFjnumjyK0_346N^!;q8L*K<*Iy$N@19dFCL<=Z82Pw09n^T3?2CvwI5EqFt{LC>%B zvhm*amdP3%?fGMNtUe6x?ANn@$Nf;edSaxMllP0+0$cLuO+I~?b-W38hpu<$Wd~#9 zb=*bQi|Ox%0@>$F!2W7bzeCR(iz zC+Y`%-3Qvx9|8M3buW!tV;dHCue_|P=T8Riw67wumJhL>vwS;~e-}qymTkPM>v=6l z?+#s`@as%6&-hOX4RF90f&CfK^%cWul=e?o-3~^@H*4P6qBK|L)Jk#K%@(}|Cxne3$$KtK6EX{5Ul4oCmXW%$}2DH^zF>+c-_V)WIlmAVc!e7E&`M(e-+sO zityKcdhUs#%exouCqvh>jd#RwJYu%&(+95OeQbP${9G#XPPjAuDrG=ZI1$*-RPFp{ z>v%_fwT$Dif0shcR$t2}?K}B+Nz5ho$MVx>rU2ofP676(L*C!^l6i-X_lw!a)5lop ze>C(q{uI#ljJp8#Z-abmx&{Tb&&iPaF`zA~Z|9}!!`k>E=y7Pr>Qi0MokBKV#htL< z0vh83(U5-x>^~3M=Y{*pu~2M*n5~9;q`Yj1m~9-jS25*f!`gTi z`xU+UX(!ds_kr8^5wJfUYq=a=&w0xGr@Qvb*7Fg3I~Df<;Qk!wq^$3az()K}JZJO{ zVBbOblYI|u<73=Q6LmeuaXVGsW5~<;`t*v8CtWXqc?amWh`0Nc{5mkd5>!lkCY5K; z1@58xG}(AV%vSU3(-?Qcen;>0v@1_ZFjE{9aL)qGrhSv#%QkKsZ_3kf?CvDzW$ic) zui=yOF8%r>_S4g*1N$M(;id>-ET;kUpMa_z`{#V(H=n|ot!3X`xK{)Be~RTMpW;6P z?8l-H&Q$co=#R3V3sYC`SjV4?n5`DSp|zb`<`rE(J*^M8=Yqzb;;_X&JYat{=xxr) zldPNM-L;nnxJF&iam`(ne7qW~_ln)w@f(WWYS_DRPslv%y8zxqZ-c%T`;GlG`$1s- zJIi#*K;&^?g#GMBs~M`QBs9J>D0joGTc zT^Vq{3p8R#Z|0xzj|2M=u=D=}D)j1i=D_`A*m(cEtR?df8~-6N|M6$IN1K?C`LDyy zPXaY^3@7S(E{@u(6k~Udu=6hf^Q)q9{n@wmI{@rQfqn$+7l7IZ(f=rpI$J**--g&- z0q94--q>SN=k2rOXm=#TNki@-nu|l z^82Ic`-RD4dBN=DvAkgNP+rjHhW`I?Jm6jZ{6_b&G8{P|WjJy`RqFW|kbYdKevScV ztH&6ieyn~>1J;fm!v_P7;iskDs2@9q4+esc9qfTY{kY0Go>4)^h0gD1L_N-So}V7| z*m?SAN5g#wqT;20ztB10$n&SldH$%NV|~8s$3gO=f3C};eyq#0F7K}6Y?UE{{wP#G zhrX#&j}7|C!61x`gMsmGedu5S`qIGw^r>UOI8+s!)W^yIrM^}MDD}BAAZhcI0gb2M zQwDG&9V-`*wqrw0_S1LEA!GKftG3 zx4=H#I>G)ru0j}D7n5%oqV@4t@ySh~Y*2dICHNPwo6^!ghiWsT;d)JcFl+pC4`$sB zdiwbXvlfFkz3@<0<)nwQ+CY6dpj`Z&J0Yub@`S8SQzm3Bo;o4x>1h+P?w@3nK6>z_$S3lEAkB-;%()0N*0dq8A^|+MoY$ zX72PyGH;miNaiW)r-JYEo_%oi1n_+TB#3Y3{RRB3^3A*x-^{z@Tj3pi3-B$#wB7gLfz2Viu0Ux1>3b zW_HhgEOX+#$1=|u?D$hXA3SG(?gQV=#5d-;jkg!ykZ}jzI^Qbh7T%I?V9tDtx%eA= zi}|2}$1hM zd}n}X=ya!UOLea2lYTSExX!yW*Dby?32&8e0lo#E_b#mGedpl0zp=^#c+LbZiz?$Z z-(!$*u>klhb6sGrGv*22@mzC$);T@z8qd64iszoj60-%*qd+Ue+B1iYd)Tue8FynY zW!#Oqn{UC-d&P4fSK_&UgUVHa=M2!2sCHb(ob0%3u4}qY)9X&WlQOQ)bz$M1Yf(cY4;9^~{@lqTB=UeL3t| zr^>f#$0PczM!r?v9lA}Q>z;h$8SWl@)3d(#Sx@qLFHeo^MBo3*!rTM!oB`U%^W2MX zw~U+Znc}nRzFSy(79`{9TzB$~XB+bKF3|UWBl=zk>H_fnTjpKP_4s|(lx18#%NdyS z^E~-^juP+WTo?R|7kS<3woZO>va#n_tV6?zCJ@NLaxb6w#*Z?6(3o&7VilN)0$xsS(GGRY}^t=3%iE`aQIaW3GQN@k~*_=QZ)sr1N#Y z1^0PIuh*wc{KJ-=4Zb^7-KNWU)8QRzuqo8vZ{}PnHZ1)`sPC#@I#|5G%bp2EuiJBd z-IQ^nt@ac76YFx$7yKLxn{V{CrvAq0b=iqthiB{e0DM2d{;JM5&-LaM_+OfHh4?rH z{txX~kdSlCZ+_QI^t2zcZ{G&+PrcoVck1PC@hzywr`6-}_bUJ3I~`Q6 z@@n=BF{{ zLhbE`{$AJf96-D=C&{ev#t?6c=k-tYa96Y;afge%Iarx5%9iK#axZQ zAkOOWS;O+b82tOKOWQ->e|Tp>!iTY*#kceIAB+Cuok6UNp60z`+oUt(vy&y}z?(4V zXKipFAFG$k9l-oaInM*uXB2}u5<>o~fd3M0T}nQT>a&L7zYhGf?{?sW{|BAXAIN)G zU6I%^?Lzs?VD44Q{mT-4=QCsvBko^=UIxVb5*2ej4xz3~!}6bq!Fc+gJD&R{w@2Sf3TC^W1M;8is%J+k$-7ju7*o_$U7* z%&VjFJyD!9)_z{7X|D4#WYoSD*t@<3yw~WMC)VT17>pHP7Of%XzwNhS&YS!fT91d} zzhPH_^xcB^Z!cdVcI1q4@UF_Z2jASUp&EF1*=sY%ILDr3{7H+mhT-4kw;9%FVfb$Z z|Kzv%y;}D!5<4bkX>;8rFsiK>u-ZX!)JGPG{X_!khW#-hzF=yGzL-`No&S@K1i5 z`iy1Uhp}QXq|?Lj-wgh#4|mXu?Bd~7_X-E*=DD8W-P)6H^~vr+e7VLn*WEtMND<0! z1OH0QO(?M^drf{c1pdvt3#1)CuB>Z4@5R7?Xk7b%Ku;Q9%(?G~vKP4;zWO#*#@&1; zV=!U(xBWJE?8%P7gyFvh{FC2SGJTxrs@>?xy81!O$B)^4ShxoV_Tsyqb4I;0t-Y9A zkT+ba<<7ivDI$#DqWW#F7!33|txLo3e+2xq9p96ChG^TjNM+UY@3zfP%XyAI1T5q7 znU0J(??JWpAT9ykPfE-+pVgF03Clk{Tan{0G7jO0!JH<#Ld<{SU-el@zMD2Y4!#FG zdFKzRr=M$MuJcX37I@Ds_Fg@Sb;_NbL*n?d&O67K!`N-|+Z?K~_KPW=UF&!M&7@OJp>7l)0rhT)(5HdE}0pRGdc z((VxWw}F3$PPd+cMSZqv7G5X%I;)Mm(|;ZY|B8&u{q@W@^KR|6yO?4Cz`IOcpRxa< z+wrjc2gRO3@xQ0QY{$Vr>9*?Gbx{g#fozF&_wGT$7B2;;Xo27-hA z;J+qC{<)_X^;BXzuKO^o+uGi}TMYE~$jdi_f6{L%-`pR?+BaQ>eN=Y*n`8h!>jU~a zg?%@+<6-Q!&VTu9w}{#l`0p$!u%G?FeZcwIF1l{xx!$_?yW&JwooE67EgI$)-|`u3 z*f-|Le-QuhSx{XbKZ70bs9rDnkF`dkiba1b>ek#RPT;&K)VXuI z?YHSZ4C!^YXOQUYT@~s&L-oG{Ztn9z2d>e8K4xd%`-F)qtb6x84 zUtDut%C}Rm>vNr-vj(1dAMpKzv)>E6XCQC5QTJIT-|*e&*+{YSt*p<~dG06UD&{oT zb-ro76XwJ>^N#(mAA=+E&GF`vPHHsqR zwtmxeI`?tqdG5hC^=0nH-rpyT?ZpKuanT=ijCw=wUEjPqQV{iw0W znfe?2Qs*zsG3I(+taIH*#m2-DJnrb!niC z!=EwCb?U2KgnnGZvj2(iA$ZRK=J&&gY4*}>G5M^zJp9m@ZQZaWWi{b8)lDtMmjF&MvfX-FAA zfVn;ae4jG=U-f$m-baA%8{os_!j?Juc(E<>@>$`ho8~(8;mQSl7rZ-SR{FJ1#bfBV zOMv^of%m7t_hQ)bO`uBn>utci4|AQU4ZK%ku5W^VTa3B>6zJa|=a&pMPl(r9Ed;oC zKw(;6Ca8PPPgUZ06u;~DgYOgHH@=Vj&i6Ud zTmtvKkbV#?CFBpG`Gfoc;KaDe6M!RqQFfkSoD;Z{(flUpXCS*z1a=C=-6sP3N7F&$ zu&3_dL3!9?wHkY@O0n1G2#EVY96=p^DQeMIqb55KHOc>u`qXi#Pd#aJkA2=3V%)z6 zZNa$vX-^#Qi&OUrsrx3le}h$1+>iRwEvPem0Ck2J;x-S<3*){BGy~)AQupnud)j!f z3-5cN8u(-#xTEg^?_ujgt=tUMj9oNTOkm8TL62hG*khjTDM0(n`F_hiY1+Ol$30hS zxVdiv*Em|WZbwn~^eAe7VtpP5#(g#RiSNMJ?Oq7_zIfL?$6hMaJ=e$0b(vI$%k^5Q z+bKr<%GGgTfid3(>cAXNj$PaD>NCgH9vyP7@crg-Q;i+h7IM9nRd>^l`iq~Y$^*ts zdgXr1m3|t#pKRLm+++WmS_iC-o9aRJx<{pnfR1HS1?cPdyac;*Zx|)L|8WIo@;a5sta@OwdPt8 zHFu6Y>Q>|uJ^L?U+>fba_tYzxAMwrcL>-@6=feA|lJ%OWt9vdUGtDE|o{KH@Lo=?lc`pv9mi z&s-qh04;s?0P>-PrF~w@pE}dt!>P@2StCnzqT62mp=ham-`?xNxmRo7;xrWljQf00 zr>e)8$#)TgL+fSbbI!5=oKB@x%6{gEsU1*7eH1kmFw#Vf?Ewe!YHvUCxD~rQ$t%?DPkXpYA#D`BU?D$l+{8 z4kI1o{u1tYzdmlZ`K3PNFWrCm(C;!{UYC7kxcP^smWd8b950H8;*VGb?X&H^x1M#;%W> z{Vc!n@5K1ocB=Yt^<*Ie^^qW7pMU-FNR zJzvPxq4va8H~T(pemVJve81U0WWToDXZ(9Gezhi;_2Gw8{O|vU=f`^9lm26EsExbX zxNm7M#?Q}~w(?BnxaS=-b{@B~29o~a0iW@gVEmSU=+K8BP4yrDMvw9L_q2$zS8lLt z0o2?mkDKzrO8sIx?K5)twdnJr`n46?yywr}4<5G1t?I+|KI5l4t<5i-VZ8r!>mEte z);s68qu$n;-x?wJ3GrN^wS?MpjAXOYXZ)oYKl_KgH-z>AeLU?FGMt-pee3G|Y_=fsrpgAUqfSe=y9uO70KoypYb2S`01W=O(Od$ zTVM3Q|GThng!Ey>!s|tEhj+bv>&D0BJ?DBPJ#URX-uoE$6y7JH>v7VDe&ese_%**) z?upnQF#bKcW8@wPsyjF^>&v32-dyiab?`KH!??M|U^48_J+!~Wq{m4%t9|Z&W#I(r zA1Z#WtP9(b?|=XIO&(+Gangqsd1s5GhI(}xKaJhaA1bw9Ru1hR#8$>(?bdJ7<0P9k z#oqJ(AjWU-YsIeV-s7iQ)v_sL1lO>!KCGI2x@g<{ltZq2F@9Ow;2t;Co%e&jgt4b% z4YZl&3a{O0-O2i}ws?*$R{9_0cO66D1ESq?zaiSO-}!iZmG7LU@t0%#q*s!4DX1g2 zYH^Od_cMDR4UONcrWCoW%^(@q!nl8@>v5`=CfPjfGk%qyeFfhZJx#mS|1$nf6_xpUz73ziN(uZ|Byzjp{z_JD5 z$6qyVjH`xQpW`hBmx^O0bL?6W$`LDhQmWOq*N?;l?sp#5<+C0qy+Zo1KIHhzG5%vA z?|=2Q(XP5JwVs3X+eh+8CF;#lpTuLA^-3?MJJ#%<;V z325I-*NIY48E8MK{N?M!ftSA{_D&uvDhjRW+{*|a- z_-#=$&L>T;9dw+{sOGEV} z`W^?CPtzQ?$Bp~1)DaltS2TXqH)ld0Zm0D!)%OOh-K3x8;nzy}G}(L~edsk;)LP|j z$cKBz4~Yk?m#@XRkJ27#wMNyjc9S-U^|(_XCiljwdc`!yb-iNWb7ze;)h8VVQA#!N zh4u0sh)?ue>wIgjIM;6KxXA`-ey!2wN0{TXR#?_uB z22$s^wgxi!wVpPg_V4JmVN$1PHIOuRstLomPk3xgQicf5cEgK5xTZ>EJbx$>ytboaB>r3hVI*bKD*~#@r6NjmI&V zcgW_|xaT|UIc~7|Qm;Ud)7a&>4L08-n^aS#){}M^F4=brfegyik6#8&A?spzYKFbhePg$?Ij&CluEcc< zP_NO0>)OvpQS+%>=Rmm{E8o$B*mVJ(194@lqmXq)501{kwR^#{Q0s}*d?@9&I7g(` zCs?uPUc{YqP?In^$~bV%%R#&7y3DhzVM5-XbD5l1qkOl_lUVf}YRsGBuU71J7wRA` z4>Jbb=WB7@CcZA^-T7W~E>h+p`MP+g`T)vt$XX1m_Jw1<9K%CAsR=QeYyHN6>t2ED zHk$6W0b|E?6SWkH=Um8I1jG)h_Jd+@9LGW|s1f;1xb7sznC6#yuT2;S+-uoWk7^ev zk4`yVnFm1r+={n4&7_6CtUm1eQF5B z@%MZ4{@!t{9&CR7c02!0y+|lt_Th8qh{m$z;?Ty4GN#JwaI9tL&^^F?J`2>X%G0{H zexv@Zr)u83q++~&x%>K+ z#V-rW%f6j^x!8sG+P%vhmHT)UfTOkxnAm3gmu&`=*%sw zKUkhVS>fh?<7>Ce{^k^qCVATRzwYbre&aTAa06nkTF;{+C9jHNtM4Dh_h~<-wRWR^ zj!k@BuG`yexc(+!%k!Er-m}tu{SsVXe>Lx%D~ewjDf4HXXQkMPwbpHtc|J{N7QOA} zpXQb=$C%f94c9My(|P^QgKNaj7fzSG1t>2quZwHTm_{Nt&APi!k0}xIWD-s&S&c1l4|2z30Au z^;;uu#-_Q&7pq)x7ys#c zufz2zjzO_e&Tlo$zf|=s?PKF2L6PK3B~H%R)a$f?ZbxkVW7H_R=**ul5Guiv=h zpY2{l6p!VYN%M@eMaS}gu-B1Ryg}L@vO$oiD_|GJLmtEs9rlk)PQP1hd-Ji z>Ol1$JtWHKe_b@Ldq^~an%6%hT0loYt)RMsuevbi_%Fu{tXM%G_7mCmm&O3QILTq3 zpr>tJ?bMkLj5*F_$&=kXjP5nBojJzOJtna3bod{1ea!38u#0;sCQk8LvQHG7HRwzi z#vCuPV?0(YkgrQTQ=Hq1>Fh;Z$LNnEzIsLRbEh>Wu8UrZy3Vxb7U#rNjA>p|j(}s3 zYD`I9HxYMi#2VXi--&ni1^aX@>{AoR7AZcb=}bG;ugjB$vE*5acQzp|;p>0%IAA9( z$8~q{b*aw`%M;yej_(*TR_?VGXQepKE>NiT2af^Q9*x*o4zAnFaY&XYRgS5r2j6Q2 zV{31FS}$TSIfx$_@#bs!z2n+fg69I{^m`a%n%DZhRxqY(_kiC5TsP(Qr#>d|d=}={ z-I!nVFt3Zia|7h57d-a@;|AR8B3ySKFun`d4!!;sh1leUkO74c5PP8gc4t)~GEs=| z0#P=?2SjNRUwmGn^*dGgP5N!Rh8?QFwJA=4u!M|N*l~)}g5wm}H}fs57pG&*R)+P< zF{~es!Iv(BFFPGR-M8?Q#uwJrS)f^1?+wsekJdc2wxl&Y)f&<|7IjwxSijDKPvTgo z;d)s(Z!Mii_4BkwBj26Y{ZuPQYfxHqQ{4^u6tJypVbAT~z!bTs)vw)~Jg8X=T zc0kFZTV<{f`ZymvmJ*LErYFx|mG>8NompS@j{MDrlGg;)-cSuwUsr?JJ@YcD!=Xn@ z!Q*k_k?Lak^^N;L(P4sm)%a0q^KP>%R@&({$9!DIYjMfh8=OoWBn)!9PCTq3MZ`=2pD4%n= zINnksf1}~`zmfSS*p*WFDfxuQ=6U~zFE3ikmWhL_@3ZSFI`=IS70}n!`R9mZRqu+{ zrGL*hAs;@*wXpF6TW4M++N<6d9iYyG?~BF_*`f>Y-JrIQACdVv(yvWuW4O ziF7*IPO@L}Je*7V3_4{kbc#KH>349=EZ{KmP- literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..fd3e533 --- /dev/null +++ b/main.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/mainwindow.cpp b/mainwindow.cpp new file mode 100644 index 0000000..3019fab --- /dev/null +++ b/mainwindow.cpp @@ -0,0 +1,162 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + cameras_availables = QCameraInfo::availableCameras(); + for (const QCameraInfo &cameraInfo : cameras_availables) + { + ui->devicesBox->addItem(cameraInfo.description()); + } + ui->devicesBox->setEditText(QCameraInfo::defaultCamera().description()); + revert(); + init(QCameraInfo::defaultCamera()); + QObject::connect(ui->startAndStopButton, &QPushButton::clicked, this, &MainWindow::start_or_stop); + QObject::connect(ui->devicesBox, qOverload(&QComboBox::currentIndexChanged), this, &MainWindow::config_changed); + QObject::connect(ui->sourceWidth, static_cast(&QSpinBox::valueChanged), this, &MainWindow::config_changed); + QObject::connect(ui->sourceHeight, static_cast(&QSpinBox::valueChanged), this, &MainWindow::config_changed); + QObject::connect(ui->asciiWidth, static_cast(&QSpinBox::valueChanged), this, &MainWindow::config_changed); + QObject::connect(ui->asciiHeight, static_cast(&QSpinBox::valueChanged), this, &MainWindow::config_changed); + QObject::connect(ui->charEdit, &QLineEdit::textEdited, this, &MainWindow::config_changed); + QObject::connect(ui->disableProcess, &QCheckBox::clicked, this, &MainWindow::config_changed); + QObject::connect(ui->applyButton, &QPushButton::clicked, this, &MainWindow::apply); + QObject::connect(ui->revertButton, &QPushButton::clicked, this, &MainWindow::revert); + QObject::connect(this, &MainWindow::image_processed, [&, this] (QPixmap img) { + img = img.scaled(ascii_width, ascii_height); + ui->screen->setPixmap(img); + fps += 1; + }); + QObject::connect(this, &MainWindow::tick_framerate, [&, this] () { + ui->framerate->display(fps); + fps = 0; + }); +} + +void MainWindow::init(QCameraInfo cam) +{ + camera = new QCamera(cam); + image_capture = new QCameraImageCapture(camera); + image_capture->setCaptureDestination(QCameraImageCapture::CaptureDestination::CaptureToBuffer); + camera->setCaptureMode(QCamera::CaptureStillImage); + camera->start(); + QObject::connect(image_capture, &QCameraImageCapture::imageCaptured, [&, this] (int id, QImage img) { + img = img.scaled(source_width, source_height); + if (!disable_process) { + convert(img); + } else { + ui->screen->setPixmap(QPixmap::fromImage(img)); + fps += 1; + } + }); +} + +MainWindow::~MainWindow() +{ + delete_all(); + delete ui; +} + +void MainWindow::delete_all() { + if (thread_running) { + start_or_stop(); + } + camera->unlock(); + camera->stop(); + delete camera; + delete image_capture; +} + +void MainWindow::convert(QImage in) { + int length = chars.length(); + QString res = ""; + for (int y = 0; y < in.height(); y+=4) { + for (int x = 1; x < in.width(); x+=2) { + QColor pix1(in.pixel(x, y)); + int avg1 = (pix1.red() + pix1.green() + pix1.blue()) / 3; + QColor pix2(in.pixel(x-1, y)); + int avg2 = (pix2.red() + pix2.green() + pix2.blue()) / 3; + double avg = floor(avg1 + avg2 / 2); + int char_index = floor(((256.0 - avg) / 256.0) * (length - 1)); + if (char_index >= length) char_index = length - 1; + if (char_index < 0) char_index = 0; + res += chars[char_index]; + } + res += '\n'; + } + QBitmap bitmap(1920,1080); + bitmap.fill(Qt::white); + QPainter painter(&bitmap); + QFont serifFont("Consolas", 12); + painter.setFont(serifFont); + painter.setPen(Qt::black); + const QRect rectangle = QRect(0, 0, 1920, 1080); + QRect boundingRect; + painter.drawText(rectangle, 0, res, &boundingRect); + painter.save(); + QPixmap pix(bitmap); + emit image_processed(pix); +} + +void MainWindow::start_or_stop() { + if (thread_running) { + thread_running = false; + capture_thread->wait(); + framerate_count->wait(); + delete capture_thread; + delete framerate_count; + ui->startAndStopButton->setText("Start"); + } else { + ui->startAndStopButton->setText("Stop"); + thread_running = true; + capture_thread = QThread::create([&, this]() { + while(thread_running) { + image_capture->capture(); + QThread::msleep(refresh_timer); + } + }); + framerate_count = QThread::create([&, this]() { + while(thread_running) { + QThread::sleep(1); + emit tick_framerate(); + } + }); + capture_thread->start(); + framerate_count->start(); + } + +} + +void MainWindow::apply() { + ui->applyButton->setEnabled(false); + ui->revertButton->setEnabled(false); + delete_all(); + QCameraInfo cam = cameras_availables[ui->devicesBox->currentIndex()]; + init(cam); + source_width = ui->sourceWidth->value(); + source_height = ui->sourceHeight->value(); + ascii_width = ui->asciiWidth->value(); + ascii_height = ui->asciiHeight->value(); + chars = ui->charEdit->text(); + disable_process = ui->disableProcess->checkState(); + refresh_timer = ui->refreshTimer->value(); +} + +void MainWindow::revert() { + ui->sourceWidth->setValue(source_width); + ui->sourceHeight->setValue(source_height); + ui->asciiWidth->setValue(ascii_width); + ui->asciiHeight->setValue(ascii_height); + ui->charEdit->setText(chars); + ui->refreshTimer->setValue(refresh_timer); + ui->applyButton->setEnabled(false); + ui->revertButton->setEnabled(false); +} + +void MainWindow::config_changed() { + ui->applyButton->setEnabled(true); + ui->revertButton->setEnabled(true); +} diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..33d0349 --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,66 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +public slots: + void start_or_stop(); + void apply(); + void revert(); + void config_changed(); + +signals: + void image_processed(QPixmap img); + void tick_framerate(); + +private: + Ui::MainWindow *ui; + QCamera *camera; + QCameraImageCapture *image_capture; + + QThread *capture_thread; + QThread *framerate_count; + QCameraInfo selected_camera; + + bool thread_running = false; + QString chars = " .~#☻░▒"; + int source_width = 480; + int source_height = 360; + int ascii_width = 771; + int ascii_height = 531; + int refresh_timer = 25; + bool disable_process = false; + + int fps = 0; + + QList cameras_availables; + + void init(QCameraInfo cam); + void convert(QImage in); + void delete_all(); +}; +#endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..af8a5af --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,379 @@ + + + MainWindow + + + + 0 + 0 + 1007 + 561 + + + + + 800 + 561 + + + + + 1007 + 561 + + + + Cam2Ascii (Demo) + + + + + + 10 + 10 + 771 + 531 + + + + Currently stopped + + + Qt::AlignCenter + + + + + + 800 + 10 + 20 + 541 + + + + Qt::Vertical + + + + + + 820 + 30 + 181 + 22 + + + + + + + 820 + 10 + 47 + 14 + + + + Device + + + + + + 820 + 70 + 111 + 16 + + + + Source scale + + + + + + 879 + 94 + 47 + 14 + + + + Width + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 880 + 120 + 47 + 14 + + + + Height + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 931 + 90 + 61 + 22 + + + + 3840 + + + + + + 931 + 116 + 61 + 22 + + + + 2160 + + + + + + 820 + 180 + 111 + 16 + + + + ASCII Video output + + + + + + 932 + 232 + 61 + 22 + + + + 2160 + + + + + + 932 + 206 + 61 + 22 + + + + 3840 + + + + + + 881 + 236 + 47 + 14 + + + + Height + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 880 + 210 + 47 + 14 + + + + Width + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 827 + 300 + 161 + 21 + + + + + + + 830 + 280 + 111 + 16 + + + + Characters + + + + + false + + + + 915 + 520 + 80 + 22 + + + + Apply + + + + + false + + + + 827 + 520 + 80 + 22 + + + + Revert + + + + + + 830 + 488 + 161 + 22 + + + + Start + + + + + + 820 + 58 + 181 + 16 + + + + Qt::Horizontal + + + + + + 830 + 330 + 161 + 20 + + + + Disable process + + + + + + 815 + 151 + 111 + 20 + + + + Refresh timer (ms) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 930 + 150 + 61 + 22 + + + + 25 + + + 5000 + + + + + + 923 + 440 + 71 + 31 + + + + + + + 880 + 420 + 111 + 16 + + + + Framerate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + +