From c92666a53799ea0bbdf052979ebf32f8b7ecf26d Mon Sep 17 00:00:00 2001 From: Stephen Cooper Date: Tue, 9 Jul 2019 09:09:44 +0100 Subject: [PATCH 1/2] Added tray icon --- app/Components/runner/Runner.js | 25 +++++++++++++++++++++++++ app/DotnetRunnerApp.js | 15 ++++++++++++++- app/assets/icon.ico | Bin 0 -> 116944 bytes app/browserWindows/main/main.js | 10 ++++++++++ app/ipcMessages.js | 3 ++- app/tray.js | 26 ++++++++++++++++++++++++++ package.json | 2 +- startup.js | 16 +++++++++++++++- 8 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 app/assets/icon.ico create mode 100644 app/tray.js diff --git a/app/Components/runner/Runner.js b/app/Components/runner/Runner.js index 4fd2c0c..13e4dd3 100644 --- a/app/Components/runner/Runner.js +++ b/app/Components/runner/Runner.js @@ -163,6 +163,8 @@ module.exports = class RunnerElement extends WebComponentBase { this._runningProccess.on('data', (d) => { this._terminalProcess.write(d); }); + + this._emitEvent('starting'); } clean() { @@ -196,6 +198,8 @@ module.exports = class RunnerElement extends WebComponentBase { this.setState(RunnerElement.states.stopping); this._runningProccess.kill(); + + this._emitEvent('stopped'); } exportLog() { @@ -234,17 +238,26 @@ module.exports = class RunnerElement extends WebComponentBase { stateEl.textContent = 'Starting'; stateEl.className = 'state badge badge-info'; actionBtn.textContent = 'Stop'; + this._emitEvent('state-change', { + state: RunnerElement.states.starting + }); break; case RunnerElement.states.running: stateEl.textContent = 'Running'; stateEl.className = 'state badge badge-success'; actionBtn.textContent = 'Stop'; this._enableAction(); + this._emitEvent('state-change', { + state: RunnerElement.states.running + }); break; case RunnerElement.states.stopping: stateEl.textContent = 'Stopping'; stateEl.className = 'state badge badge-info'; actionBtn.textContent = 'Start'; + this._emitEvent('state-change', { + state: RunnerElement.states.stopping + }); break; case RunnerElement.states.stopped: stateEl.textContent = 'Stopped'; @@ -252,10 +265,22 @@ module.exports = class RunnerElement extends WebComponentBase { this._enableAction(); this._enableClean(); actionBtn.textContent = 'Start'; + this._emitEvent('state-change', { + state: RunnerElement.states.stopped + }); break; } } + _emitEvent(key, data) { + const e = new CustomEvent(key, { + detail: data, + bubbles: true + }); + + this.dispatchEvent(e); + } + static register() { customElements.define('runner-element', RunnerElement); } diff --git a/app/DotnetRunnerApp.js b/app/DotnetRunnerApp.js index a4e09f3..62d4f75 100644 --- a/app/DotnetRunnerApp.js +++ b/app/DotnetRunnerApp.js @@ -213,6 +213,13 @@ module.exports = class DotnetRunnerApp { this._enableTasks(); } + _handleMinimizeToTray() { + this._mainWindow.on('minimize', (e) => { + e.preventDefault(); + this._mainWindow.hide(); + }); + } + /** * @returns {Menu} */ @@ -246,6 +253,8 @@ module.exports = class DotnetRunnerApp { this._menu.setApplicationMenu(this.getMenu()); + this._handleMinimizeToTray(); + const eixstingApps = getApplications(); if (!eixstingApps || eixstingApps.length === 0) { @@ -254,7 +263,7 @@ module.exports = class DotnetRunnerApp { if (displayReleaseNotes) this._mainWindow.once('ready-to-show', () => this._displayReleaseNotes()); - + return this; } @@ -267,4 +276,8 @@ module.exports = class DotnetRunnerApp { once(...args) { this._mainWindow.once(...args); } + + on(...args) { + ipcMain.on(...args); + } } \ No newline at end of file diff --git a/app/assets/icon.ico b/app/assets/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..009e4c5a07f106d959fdaa78acda88e3e364fbb8 GIT binary patch literal 116944 zcmeEP2V4|K7e9)M1+mu%_TFMm>@^yVu|$nsjM3ONu`9}9jj>?w1#A=r5fwWime@OX z1dJU)>?p{7|Nq?Wxtw=!G?UMS-|w;Ic6Z*JSLV%|H!~`gnJS|yM-CN^MO6bVRjU3f zm8xh_&9yu3pT)hZRkhcpRH`v~RjNjfG}mRDs8qIfRVuYwdu?T=`eqV7fIoikr=}{^ zu<2&1vbe^la7S|=2bBunEl^nl;#&LfZG^8%z!TpLanE*q^Y*dthOk3!VY|jIiSZh^ zAm+-p4PmeD`K*8cd}s5x=p7l}J<&Wbe*^ba@h^7fkB!>l9C^j-$;p*#C6AxxOY1w$ zkv9A|SK8ELo)k1^rS#yGXT;klzVoD*UHSM8{zY8&Qc2S8{LezXy@S2hOWTGllw5w8 zBYFNjU-F-^LOO)^yaz9oTsz`k-}%y+b?c;vOIy99_}%$;jaj0K2;QFY{3aLYJq}Cb zS>9%pwRh4|>BP!467EYE++3y8Yu8E#r!5Cg&f+`1zb=Xon!9rTwqZ*$M&I)O#&6t` z$aU>zi*k-FSuLI0;38f0aFsx}baT%p>6-6G@g071=cvV!O9z2VB0zb=+`jawoenZHUpyWT}QvS76o_{T~qaP~@R&!lCNE9%L6&_e0yb?>*YA8e0F z@cu}=ul>djoF4=a#JlqQ4k%yuzSmonAGTku!C#awzmIQ_R-^9&|H!LeVW_|LiM>x5 zFjzj`e{^ok`ez~An(iLIld zH+7pQc(8rMB2fp#U&tWdBTt|Yl3QM zPrh!%cPI2%c5@b`z?v{S@rBkcd#)I#kkl(z}EujO{AL-T3ywIONo?PDg=*03h zk_Tjcb1!GmG+%PJca{#J{_mgkd;~q6CB5^@6Z2T3Km34JcU90S%lFTAHpXvjAagf- ze_Qklc)WsM-9$aFhK@D{SSs~5ER#wVXaRd-CQvcyAD`tre3y2nD4-F5_DB4|@EEc) znjb&@ud_c9zGgTt3F!YWa>phdFWfoe{={$mk~gS>H)mbfMLZAPb}{zpj*YM*eYMZ> z9Z?4#e>w3x@_RV)8`S~M`0n+0k-qPuu6vPJf^V+SSHgxab0z9Zc#yjk^Jx29Ja--M z%m;i4NERM=Uc>nE`pRa8HjZVo{PmsZN*lY*6?Gu+z&+Z) zt*|$=mC!*6xW}XJ4&ZxLjUr0c!zo{!5&MSy3Z4KP%eWFVL_ShaZ|>eC!4?q@ezOjA$zVO8eN*ALs(cPQE9@%EAU%T5tZUHc)@vSYCEAe{ zYb3~>fYWGuXhWd4qHU9(=exw~;PmCvy%Qc1+Rw{qE2{yY1XUo#`>Uk4e)(U7`y9Ns zW258?JHv0tbnwV}CY@|Y&Y)b{eI*bV%H@G6XwUj++OrRM%oetSIHOMer8m0@Kwfn? zNYYVrv}aTHJ1vW6yDVtd@mSL)u$^WbE0@joEM*2xg-mN>y5S|GjOYk~4hLgsFsQkD@Pul4(37<#n_t3|p&m??6)&>1I)<4Rn45FQv{#>%=gI|KOX%}dR zKFD8!@-L$NNKrocOxcv5`>1^4poP7Ym%;w56*|E3Df_HH`oyd!onIuE54$0Mm-45e zKN97?NpAV97vTfKhan#HKlRI%aS-(DmA{Ske_Pc5+Z2_rsEY$rmnWcCE>}J#QT`j0 zACYYOwdIRCn5OVUQQva8@-d0>pP>8;EdTTx)A=vUL5jR)Qhr~bjmxE}X>XK|Eo4!?Ca+lfz7 zKHFfF|M=q8*^+d?9ObLxU+$_5-{5Y7^5IJ+uzw1jOD_Fw`mf5lK1o}X`|?CqAvzqHEn=grt+Am{KM|DkH%*hXQ1!F@1oxm2YWni^>=?D z>Y@3Q;saGutY03q3A@?1W_ux?$2;`x8DEgwq9n^#^a?&0_T z<<8u4A5X>s{WBHhpaNv^9Qxm)-KYN}cmh1=|FIt}_d$tA0{T%dZLsK5!f$2FgYVLx zV?P@GCH76u#lPHH;pr`Jxmewia-fBp(8selmmZw<#5Y%<-%6fn+9tNkTL%CSMH@g{ zM_+~hug-r2&TRYX&!UehLD$Zry{%=;|0W^|94g>^2k?0R=D~L1+aMMr;tN7H7|%g{ zGXBH31^Fd#6g*~sf4=bB5W}J0{~mt7FTPh^{=SZA11It`IOYOO0EFWk((|xwqTMHr z#DVgm>;HhqtRMEj4$oV~_>IK=3+N5Q`{T9W67(4;@}paLUcWA;;aisgZ=M8im5#$N zrEbW51YQ60keh`5+H2rTyFMMjdenXEqk@vSp?nwTwtz0+-?ErTzJJ2ky8}P=8TjxL zw)+lr=TFG*a^Tnn&wZhMH?d+QwV4#JQaQ${R1ITPD!XWv$|g*u$`q(lS*Q^@AgEIK zC%+$vZ-wET{5H#AS&|CjnLrDPaf+${dw?!ZQ8IaP3cPCYPgw^z&kSH6m_F}P$aWx( zxBoio5rr7jOW3HF=(|5b?CTclI1u%?9KW-DstB+Gq?nHekxS&JvMihz1M~+_hwehI z;kWxTMkst1_K`*3g8Bfxq)ocMORMvdJKo`)JAiF~UjY18y3wKhHqOfeW&myg;sLY; zB96kogVM&!Z4-~wZQ8H{QtrN=WeGYG5r-sylD~mt4Ztoy96(p5 zE{?-?Slf>1<7@C**z-A}U16+&Hkdr*x3y*X;mG)0ifPckOFyV1KvUXC)7MeP;TZEdx)3oR#Lw6!8mD8n zh%KE$pX=!j`Uv2|6W^!6gSI(I8t{yY@j@Is!cIQ{aO_FcA>)I_WSscu;&`ZU5i`@q zwZyqLzQw)}>zHE&lpAAm$NP*W(Pw@67ksS99Z{g8ixlUVs6HSDslu~003qy$UqD=o zK3!5W&aolJ7}!^m_-ILd;kb7L|Ndr6%_`1NVr}mj3f&LGNhz*9m+t%67~xHUnl$y1NA2C9cVzzGc@#| zTbcN`yLCJO{$?0co5lDjeHDFK*K%}TRYf|x0v z*Z&6TpxvVVqCM5egFJvA6%X4qLz4Ci9$W z&Hh6rz}=+qr){9Urhm-XDs8>7*uRWBkNWZ>z{p~et=Z~#zBnY&$?%xfHKA;)4{O^wk<-3VIPyiUyMnh?rBSzcVlR5fN>iy zwCRTQm$4fy{`B)!01l-XfAT{+mcnsz;v>fI6m-b-FUyLY+Y*F$im|Z;f&W00@DBj) zw`Kf8jOee?`j_QNONX5Qan@BUQ=miO&+#YNeYVNE+!_O80`k~E()e!^aU|d!0-%2? zZJszz^oFuzoq7O8+4kegwxnmG~uf?q#h0(f+>(*WpjxU#2PkG95TF zcjqwj9)jj3E-Qv;F@`_=7X|(tCrUT`spI>d5+BDhggft)^l1`1=F*B|7{M z{@>xh47m3J2>;=BI^fT|o5bYY*l$MV|3m$AjJ!8Mq~|LKT7 zV{m1_U{NexmXmMx%>u2B}cl)5*{{{Ytm&PHsMZa0ZgK#W@{@2w| z|Fp+{e_G2w+F#@-T}6)47sQ``II{mf8TgAlwX~G~6yrb0u>XnvQ#@jVlO^epE`~xn z;$!@Z!+*QR*pGg{fn(m@^#9QZ{-_V2r?2|Irxbq?_tT37u|I%5U>N#LC8hWKbnz3O zNRp&N{AwWLlkcd*?CU7`z_E7PG}+(R$J5w#vhYXWi+xicf)pmL0K8ee}gO@+Fz8S`oJBD#y4PPck${!S*1j9159^MDYjSa-O@0<Wh5|_Dhi4dKK~6@?k;l265+2>H+*B9$Uh`KBSMtF>{Wci(C!8F(UHVSPn*__!DpD zM4*4bc%g`y$+C_kap!ox7+YdKVC0Smz^4`Fp+L?P%Dp}@f(A`)cXynN95Q)~j&VI@ zuC&Z&>b!mqM`HN1uk3}mynd{e;|uPXZ@{=T^8tV}f&P6@fEjT!<&Vz+I0n-V@Bkpj zk3_CH;)IM9vyPOyL0XhKAPMkCeRD1eb(48J`ZkWbDe|F_(|h;N1Y@f#y9XepV_>AY zCEyZ3_^ce$!8{ldYhXN1e@uq5AaY1xzexjeX3UP~AL*u6W;n-({ruPW5{%z5*MemW zxi+QV^`DX7#jzZ~13;foGk%IA=66T|Gm(d5V7x%&Nikjre^FmIsiUlO#>5!^5;=b# z#!p#>8=wpz#kk9~$lt&*8-VdH4KGLsc)=We#!VTw)VH^?e#kaO{Lb-fjPWt%6>(7~ z{%7#n>?@?blhN;Q9($J6h z83#NE7z-!@5P0*L)_=-x<2*m0D}cF{*I_4K(q2Sd#&{*>5(t^m(m+`f`5VaH7CBpy zI~X^(4p;~11SkMVH@x-hL0J~gEdj*6X?cE%!RuBB-rZ= z+D0GH$o!{vfZ_l#ri){WWd&{z+5~`{Jj7%oUI!w%h(|T@hj2tL6SA39Dm;cPBb5sI zM#wn&aKvkP5p$$?Qs(B5MQUA!>f9Ic?g&V*tkoP&~OL+ucGM)PL%k?7a z3H2q{o30+^dX?*$&j6UG)d-*l=<>91BRTWQ@M^ODWO-2>t#QtNINQsq0B_hf+K2GF z$2=m@?mxpA@iVmBkME!I48w0H0bclhCV+Wy><4EB=yZtZ|Fl0n{D|*Y07t+<0LNou z=(EwTGk=1)%k)2$_M3hc?WD-_*R(l|q5cKf4HyUDH+A+K=YM-O5C;Vm#yQ9S_5-2- za@(Wvk&th}u@&ZDh;~-L9nfAgKY?QcnmK46zJc#CCeCjU0I;pmmHnwJLRq#JmkBst z1iS|*=w^=2b}9UjyTmyt>|cmBko^H8z~AY&(6_pGB0&EV3i^lo{-iPb<@>^Chabvu|EQ~8LU;I0MOpDUr!DCV(AkLe zlm(O{*L7u_>-Ka_6!eX50utasyyydQ9MVvXz!Z9oJwu(Kuf=|180OZp-$+}khrOuY% zj+FOFfM)<**~Ei6uYVm)IuB1tA9+if*f&hj&o*Kg_%3yV{e9-FFh^9hDG7CgxX~5~ zeMk#Az_(bJIRT3Su>e6kbzJEeGyY?ej%)2a;}e{#%5@^>`-{AiL}=I59p0xru>E8l zM>A&uIDM!G_R~1_LYz}o1$QK+sNE7yVM?Q;B{lVgjb( z%9s>m1xJnKamx8ioR8038WAhi%8DWS<$II`ew*z4PsnqFR2et zgub$0Cv2iAm4IheTt@@P?s)$hd5$?2q8+A=CP&9PC!Bmy&PPv>6USUjBS4*C-V6OE z+7?slK=vz{cYDcWy%>*$u0BUybVnX3=Zhs-1&kGg<}dMH2=f`3E6Vnla&D@u)89!f z57ijW2JfRD7t>eapNJ&?=#M&vHzeVIO^NAd%8#Brg-@?e#8 zG0#!t#3E+QJWJ+RaZWn>f6C|dp4=M`%(F^|p^+W`E?Kg4unkfZj?v88Ja(oemQ zf3@oijKQ5}{L>VkQ{Na5W6nBr*NLA#&dO^;Ikg;9l5^O^dJyO%QZAJ5>7R@C5;?C) z&A(9cjPe3I9Q@ZYk0Myl= z$$!$%u^>?oI5HPntVf}rL#(uw+PYTG-_YS_NIxOVm{0Q_>w}HKI!n4SR#pUg4=4h= zcLnpD6T~<_`X*?nUFX=7;7cMrm)AVuIz0OMm-4lee%67q9yoSD`(P+PTb2pR0^3!8 z%*mmB{0LudU9jEa8Y`Ih5ez=-#>f@)4+H)0lcJw;M7}45lXA@!nN~wbL-Z@_f#=i_ z=CSH>v6XV5wWYKRVoVeG8L9))PrT7bi$i-jh&-47aL&F>0NZ+w9T>{-)_oJ-=h)y; z12&$#pbaC>4AE-nUSjm?*8}^OY%3Dj8Ok5{&-p*}oppHX>41WM`b7bxS;70dxQ-U| zU)ri!56DP8%HJ1lJjO}oxhA45GceD=5Y5VarqG|D9?(`O=dIA6<`_g`vQL~7&<|Qc z@7DlX_Z@LA`VX9!CDubqf_}OEWqT~I)yMdrk~UM$lS4o2L2fIk6YMk5x0d}rnKy=x zdi1jo%YHKHXCG%DAX)U&{4SSo2}eEu%LWcpc_{`wAF-(V-c&%AlACuC^tBSZ3F3jNC5 ze6Ep1e=b3eJFeMJNK6Mb^eECezP33`TQ~P!IG=I6stpN=hdZqhFSF zk=sxIH<8?a=9?tuw-}(GH1`7hLE4i;KVvtPIin!YT~KTKexm(1q7#Pbm+5Bv&-TQW zxdDQH^iPfT6AjQ$nx_Fc-jtAj_&2hBll4b=Op<=NZcq<9MlBJ2d9E#Hiu?;%=h|3k zLz6SNz-0O{4kOcx<5s{K`I<2Uj&qB3R1&fOCeyE|2d<;ac}#4-m9|0VzfQ*!S)0pP zPB8DALO;irIPX`c7srzTjj6iuzruD)_(;$Rc^(YgGtQ5pU!B0V zB{3gHu9FnfPa7DSfc{|65B*LP`B%`bvlY|{_$!PHan301<3+?#nYSX-l9FT6^v@A% z4h#N&h!u03QWwvs{4+l+UFnzW1ognVcK(R-ebk3It2e*yX*eNy?C`LCltW%D5P>nVlwKL+h#`t;Mjr9$M88m!dwC|W`cEQMSSC5KtE}w|JxDp`d>jmY>z_znK$tx zpaMYnfNcLiYyKyspLV}2fH43~{Nvw6KlAD`0~iBhEa>ys|AhP>uce*z*8)Td`NvrA z7Q}ZyOZ)eMe&!O^CjHtNFm+(h=T1NSU|Rb}+0UYg|5FC+L4PdA`af6xGcOJE*ti~J zZ<+UsF@Suye_GIw+@jA_{*kwI7IQ@NE9sZ(0OMlAK>z#1#*r8YOLqJRa;NM6>z(gI zj8MNXlagyw`ag)($6{=g7QjUVr=j&_%_m`?}7wl-!knyO45F=Yi)%w64xZ>Ug5j) z{zThH7?LNAta}5H{ITYg_2I94(TdWm``oVfk>#yx}%ZmC^lKjy*azHp&wj|~Y zU6ki;CAQWfb6+?Xnvyxptea%h51z|&f{l%N3EPeO5Nkamo(!9R4tqV7z`kQ2(W`%h zc0dd5&>ot+RweVKk~;@FS@dgloOzeb^AqC{`aH)qc~1Mx*s5l&&K*(6W&4h6SW41G zeR2(6Yw73Q(!l_+-v!qi<@`M6`WTwWE{~5SXAZSV^n-5BN#>eGq{~>YG{<*1{?AzI z!!yW@*7);`Z;k+101VP<>?WTFSOFLx(2fska@;xo&OEoo#+`+Y1inexNTc!(I+V6e ze@?Sp-$KWc563Y_=IkkQquIHQ)V2sQ}@AExC7Qk$Pr~}51m?!b{re+=!b3urM zv37^H$=Dq3#Q2}2ZKJFMn48J56y|C&FB^CgNc&s>^I8(6F{vN6Re@|H1R5Y#YBzS!WIwbM822oBUA3^cc%wT!(#{ zq{uVrcYX&zU7$T+%vi2xQ8s1Hq&8rRPlE?!Pvi?D2Z(!0QZ|kCA(+2P8&26}-hxdh21!yf^_|nrm@1m8@hvhi|hE2%J~E9Pk_dqCvv)<^>bMFdy%?gE%vnu;l5 zzs8if;GB9<9`Fl*_+A1;!Rgzdp0LMTs(11Udf`euO0!h*=Ou%V0_{$_76A!9+ZKin~ zFNk#tH2c%=hlb*H&0aOU=6*H&vyqQs;!>3Uqw_zw@w7k(sP{%7Wb+C^mRvjZH^;-`r?3Q0IsFv2v`sB z2AqJcx(v91Irz6R7w;bWIS=8_+(drXt;ZL(9ETnU;rE?*mcGYWKoI0MHm<3rJTxp8mD^&n^M=tFLQ0ajya3H^6QH`NDV* z`DG9oKj1uS=A<%L#F)P-VlL>rFn8^aW)BukAN=F*QZ88LEdX;(1_G)8L|g(#9nSyk z+WqHZr>sMqQ_sHyOavSUaGcj5ua)=dmx?tUj(Lc@RL1U%_Sf|KXpCoYE|h^a*Nm0> z7-b&-&<=eKAkP2EK{7>5QD^2jF9GNepq@Vh7_0jP_sMqxbKd{NIuz`aBo?ob`=|+y zXcs6e3D*oXt$g6g+-tT&KLJVs%m6|bl35-9n#bk(!IAzIZRr9)C_t=Hfnx$58@r~h z=lB+L&pC%o=(}E@JOQ5-dT;2y=)c1^5bIZQ%}c~RL|oQ1eByv7+lYApwpkeg|H*+u zs^$97)=f(sR|D<>Oyalv9C?7P9O*-@0el6ZZTnZtflNP+^q=bj=vT9jl2fM%VzS28hD|Q76MJ67ZxR3I`en>1 z61E_Da=>GdP&w7B|0I?nj z)@TrZeHz&El=A$e_q6>*=Gbz*2=1AkLf?RP(FX8;-zLa3;8+R3`1^-=tSK_UemrzO z>bjR$YfjAHX5K+6`g0%gEsbSJ?sIVcMvMiDbt!}#m_o1S8OEDE0rZXjZ)HG>JNr58 z)13z-(CMVE*~W8D1J_;Qx{^!2;*hc(ONw^w?`Lpq1Ngsd z4}de}))GK_&$y_`yccae^3K8n-K4#fxPOdkG267_TUvjIz5(Npj6=%#KFN@SC#bu= z01-F(r~3rJQ*P_?;QS8&$KXujy{Hq|d$Ipf3fC4-7Vp@GAV$ReO|JPQ-c7G|g}woR z@kp`968bL5=r6JkX9BDN|Je3G#tp~3fDHhX_%8S3#oFpvOGnI6qEDZWydbZ+78=*5 z<~r3}YmIs69P^Re?_|l6i9Q6sE%H6FUST5no`&j;{e!iDLV$mq86ZwtD2k&Gfa9Zv z=tyvnIw01Tho8i}Y1Vmq*FXDdTrZMq^@#NbvCg2p?x1qby>!I`@-6Ri_u#a_eCGu9 zq^L_joU@MqQ8GY$0A&Ci|1^fX?mpXi&O6bqt#9JEY)W;KyreJ2xgAFgtZyl=Im-23 zx#lSI)@iGa%}Gfq9{TUmN93ABr?JMTW=;?4F6mgZ7wR}a;2$9a!~;+q5CqWi*w8uK zc!Ip=7UxwZdtBB;TPy0CZ3x_JC`fb1f^eW+ux_r}jwL8GPFpvdQ^J zudt3;621Y)L$?450{&JRVEKRo01rUoyw{G)G8b6vt-$(Br#h8+&v^=L<4sw^T4w{m zf89CcAi4WD=Jxo>Q`hj;@mk4uL#yi+kpG9Bes#FF8Ma-C7G*(=*j)Um#P zvCcOF=x={g8DMz;&O=)SFc{Ml{W;*wy{sf-z7b?leCwLz2gkYfGc<)`i7rE2v8Pz&$wPcz#Bk9 zoY=-g=QZQ9YeoB+?rl8U=Pmu`i}hH!$BOLFrv=~jzrk;F{}QfEkl4BmDUo6QcZ6>M zd&&8e+(W@g?h*TjqXC~JPKa{I|8{_n^6}`mq-1XueY#D)hK`U2o_yDr1NIdd zJ78WI`*MO;$?;8-@hp7<+E3=U7}-1U0r=61yh+bLejiXCa0Q^#dl9q6xa{qNn?)QY zy~kx)*Q|5aJ>#lL?bGoQ?~K^^WIxCDMXcYwQsjaNx`CU?@|z49;5TVU*&m^-8^}E( zPbve_MFjX=Kn?)M@dWSXHvZumPtj*iYOZ{0>xF#hc!1B)g_?azQ1^cu?-epcyCe4R z!Coa?%RrePRvFSC(e)mB(Y?)3DgC#cP7TlwCjT~-`ELYnU(^8?~(tF z0FNnaoFBz`QtS_rH??Onk@3KvRyl^fwW7=ZQ zNjlaK+XUU-q36Zkp;2*9cQlH5lJuT;ctn4Fk~>j_)eLk z&%^mz+=nJj?Yx%nTwjLk)N^01YraYE)0UX-fAky5(8ZFuh8g^L*^Z@oouRJiBeD;~ z{i`s}>?28gvt#WRQ&^nnGnfy{eG_}5oq0q3H>_UFiV`cYh~F9>_in6kI#M|Gcw zz1H8)iFS6)=>qpT5ptVOxXZf1@sO16Et(h~&T(%>?As&uaoYA_KPw&o~*(>?h#c$T_)#daM!u#?KU1fAoytJ$yds{(R&z#?#-V zjY)IcrNx(ag=?M3`>rLcZWGaWu{R~w7}Dpvyl0P+{~VJi$on){JqBPmB=5I zd2Q$@^Izt@%ztsj9=kl=@WVchSpUoDK8=aUpCKC9CZuF9XhU^q>>hO$v1;bteTDwo zNBW)A4ZO$rzB~Q>dnY`E%`#S2vhUOOK|YhSx2~ajG<1(VVvbd?muY)dUfsS?)BbC9 zUnvK&EYKeCocX*LVN24gufXqM?b77!g>9^#q<7z?{cN!>7kKCb{#zx*Z{_cJhyA_p z058*=|KPnCm&G_|ipOOQ=o{;jVYn!GG*I1|CKN>I0N4PV^kla!w}aV~W@kW6tzhlC9@@GD%y{v5Y^L zrd@xId>1}_GWMo5#DAI3Ngd@q3^^Xdwu3Tf$POj@9_SGLMf7>L%HxZA^_QIb*YJO( z9HZwrai&C>uKf|uQTJ;B9s)G{KbbcCXIxCw3usMt{TR@BuDgfzuM=(GmAp1|ek}?6 zZ%iI!dm#2UhrJ;#X+aa^nPdNqd8NhNvDk2zPycx=jjSq^S;Z+G|{Y1LPd=e#6G=atV2{==4N z`A=Rh1ehl#0QjA{&-uuA03Y~|d3WreDZiiGbH*q+UYeRVlXXk~D>w_I zKl8=7HdSK$&w}6g%Dm^1WBXi_TkxO#wp92eoM*#zu}#g@U|rD9HnlI89KOrX>hoXb zpUn4^9>sUiSKuDsv{^~Yy|!Is9E5v+q^6#Y=s)$@ACT3M0N_4#pFTnqKIpyg!&q(ke^OzL=pUnTm;B$7R0l+nFKi8vTtVn)N9MhBk zlmmIMEye~o*FwkubR;FbOvyWGq5s0ho6vWV`Oo+vbIG|U%(kJ6L>;8Y*OT>0d6fCj z^-uM9%D7GyfKCK>4&WL@I=>(1>B@h`ITP$3g#B}v>%sLBPOn*~>EnF@IY>bc-Q_RurHf41*q0ZRTe-phHr z`m&<&|I*O@GX~6jLB==ay^<0fAqP80FA?>_@%NPIbaLKF3ICI&@8CPz{YxI}Mf^+V zd4ePCG_Tn=qE0Zc&s07edyf3)Hx2NgJl+n-C<_42Z2??|EM57}{@=DCM)`EM#ul{%i-JIp8Ivy{aXE7pqqXr<04;6L~zt|1596OVRK zn z?(1J`eFOSS>_3ZKo-~q!wBWzYbLu>EhS-Na0=t!@zU%Q_DI1KDq$>WKxc*bmxt2b4 zpKZS<;3M7Vy)@%L+Wn;V%uL`1=*s}F=^J4Dm~l;xyQW2(V2uBX*>-*VAm@&oV z1oRi_H?wb@oW38Q)#txbzm+`axy*OwhqL_=ZG0kaxXjCx96tg7$@2z)-T=-aH>&^K z3pusocRE{TrUI9eBeLUSx8NcI^FeO!GHD>7(+QYZF!RYMJ4}b8!sQ}-!YGa z`6q|5CTUu?@#)TgtQWy`_6+e=dyi{3CAwxG+kc_||4;mvWr4l{`-_OHoo9d1Kwh|# z|H96*od@69#Ma0TT;E&%_r4=ng8+;a=_dQ z=GBThfQr~r0{(;VqK(JcEXN`P8JAa#)1()#4ShE)_|G_E68e7*yuY3#|IdT}^4!%F z_DBC#{!Gj?x;y?4fjK+Q`7xe$RC&T}J`!DOg z-f_7hhv-*H((f%jFf98I1%@582>IdN75g+*gZ2$k$|4%O)>CAuT zehvkQDZn_^1H1zK$Nzsw959{v{}Q}zESRsE16&l>q5tv!)9bmh7+^Z{|1@}=OTm9j zT#NO7^=06*xBs7U{4bIApL>St)&j*jeSlH=yyvyx|0VkW^FPb}-@nlRXWP%Ueq{9* zM_ktg7+n8}`w;)f|4-XCq@(@ko)A?NFdrAV$GyDw0}}Xv+~YCgGWd`6NI%E;&*vQf zGh+Y!!Q(6j_)i)5Xe@~Qe**qb_S0$^ZO-i-3Oz|3BmYzu^A^UH-=zEpLtTUn>J< zc+L^Pexmfb>;LCG{;S|W$95(G66L+Z29(CL;X3{Yf4=_zXU%`CgYrhB|J=`~lqvkz z$^gd&xfg&&|H*%>+51`c|2|{?pX=ag`M(6bGZ% zTl#&T_W!fxKXNs(humH0Zl$`5dP5U4HIw z?8_LAxCrA|UOpMf_W!2jei*Mz6F{Lg^nJb-3w2y+9t zzT}-F?$UmYHPUBEjc-6bppWP^5I*83l7mml|9xt$Z-=$;Q)4r!Yuq1*>yR@yN2`yV z&p8c{5nuvGlm7_63n&6O1`sm9Bin>mfBA^@Gr4a$^*J@Z0r$QleV?MQkna2!zTI+Z z`*8Sn*#9hbd>4MbbP)5p|2pO&)^=xpu9g=8IC2lyDy`jEBc8yu!rQUdp<(v6!m`_=XC(d;AF}k zWf@v%hU0y}2N|F(fE@51*9=GhL$vFu^$i$15_?8Mhtk?FNOS(nz8%IDD7&fg?Px35 zo-!81^=Y4lcx(8stz&K7N8`wx9l@8BaW#2wY0F}szz~4ZeFK?$a{Hj0vyl|;5gC= z?90OVUuxR~;Ul8onOYw)Rs4s}bBz`5Yn5u>jVWS!!d+v;`ubjJ1hU8c$9U{}sL+ZL}f# zZSp;B8&Ch{4EBqCdV_5|>M&s&udGw**=hjSZb&08rtUMu1CRr-24LI{Xk~-+AxEl%qw9&`HyvHHZ_jRT6Z_>d_9tRTsqmS|4^2E7aYPg2$tLli zz8%Kw(j;yN97!kb7VGT!ir^RzHj`sjcI*guE{uxUSKkP0sZ#mVmWZGsE;>kw&51r@wnZmb2eUj-jC(BrT%#+k*_5u| zBfeVTxbZfCm`{RZ0)893*2a?Q3!h%QPBZry^_VIh1RvMaN7Rca>-Z1;q}7-#dCwRJ z<&OK#h5Dn7M;^WjZM_@o)DgZ=1rYp13>Ekl)IOYLxY$^&M)0pH@){_TkJca(S zk1c$}RO+NIo{W4%&j08BKOcO%RF2Kj)&sU7hl_jDzX%iKvPsgas29$^<{WMIr~Yqw zFN>5+1CF#|tpH~M$*B*aH`E{Q(YJfT5}{YAjUiG;*;nBBx!0i7$L)m9!$xtPZU1xv30o$KZ_&j(LzZa=Kwet-B2AEy~q9{^@)3UGVVtiNDDbg zZM#C7L|I}k7h_v*5#y3=mx(k!!E?(2#R32KI&Vy1W!iA$+!FeRT!Ykfzku>W-vGcl zDQOi;mVLG49);|ojb}dOt-YHh=0_%@ji;Qmk9-u+3?Te_9F0}qXLFx4YM~&GzX2`* zjOx9i--LcKmVDep8f215H)7FQA zMh8G4fUXWqsk6`V8D$;dyeNQc)6qv{tlN<8e0+~QfE+MCf_V~KkS`%@K^n>dzegLx z@xH%~ew2IlF-{3_CoLBMl<~5Fe?8yzWm#D#IR66B8?YVl0+3Ywir5=(} zC1Y$QwXtN`zocyuxmR~hj@c5Yr+|Y1+IiCSAK&#EuXnAiBb;-bt2uyU-NAsjfFxys zwt)K{g$25aF&2)sB-=O8w($vbuTVDRD+wH4<9FIGj)T<&h_N~x1@HC9{qHi78j$M@ zNA`yc133R+4S=%1dQOxV^vO8Ja%I~FG0(`Nc@5~*CF4k}-`0Rh053oofMaAI%Y)W8h`R12om#b4jKLVQ1)`1D=3d>wI23J& zk^UUZx&a6T%m6S({~ym&&SI0_L_H_aD_pbRTolk4Fc#nf2mo9ML;#`zak7ujF&K{J z(>D-(1g($AHev_zNw4qN$lR-V*bdI8pk6aJ!(8_RfVBXY!Po`u5%V7t;A1i&|2>!{ zHK1SrxMo|C6<`PW3cz^kAi#LQGR$Xo1Al!nuCx>5v6qpH7>l_k50Rtn2iaI3`*g?e zkQLgMegL*NbpVvFYyc6L#qqP@xg`F=RH{sxGx0y3ta1EsBbwJXAFkEBHq%|l@lvH~ zDBlo|D_#f`KdUU{-!+#imG)Yc#(R#M8!__lcA9JL=X59r%D-zrsFtra80kKz{h$^* zKGcvO)O}v1vg5Vx^ID9<STKPK=OmK}VSN;ry6QB!(^{*444+8YB6QB=*^sf_;1A>ye4oiq% zCjINcguh!P_gbCseY50VCw%?CtAAPzB$uE1&j%(XC`tJWOZa@Iq^^^af4$#7(kFfW z($`1*Ykhszzt*=0AK44Fl0ev#K;<>;Pnhx=_DTOb0YPX(5)c3boB-j5A73Xx*b(+x zSspHx2n%~0_~8LzuN4T1Hco+%Xwno2+3|ad0vqyLQJ}c|P@pJIQ6r)_MT4SkF?9vl zY2Mcr;HbHlKdAkjt_lUVd_?;JJMH5#hK};J<^$T&c~g*Rr~6q$g5r`7Xpx)M?)w(j zSqgDK0PAmCHtT?P9j9h0E3O>U<2U#IDpk{R-!^O9aoml_gJZ{)d^9Qa?f5NqYS%F< z@SW{z1f-zf(dms)x1%&Cxj8KWxKK4bse+Qvg%MtZ)9AGf7Y@bqIYW~1DPU4ApZziO2G zge{NXPYMlH}5p}?lc^*Z#b=3LuybtX@BpS9br3@N(q zMy@BXhCV-E{KzqzaMzGM^X6M@RF@r5#>L|6u>N5g!*aB$YL;EqAdi{l`Dv9~cUtj2 zs#M?bqd)iuc?|4%W#f!K6^nGedVY%kpqIynE;+Ix)2uHFbq{pwd31iR=BnWqrR>dq zx2U4pQMSXltYys$zNp?Ne8JTHVL8=VeWnD?bXwKU+#&af{cqnD39M|Nr___Yi$~O& znWJc_qa#OdT(_cR?AhjXnq=6S*Y=?0#%9hlTh`m-e56FCXU<0-Z>#-wRKZO-PcN6g zHyf@R8Te&Un*%e8&&oLWP>HFx50_9^?wg^{RrSzD<}p^S_5|cF^`!mcLECnX$(Xyz z`ybbw+8*uoLq&&(8o_%H6ra|4?Y_n8qCO=WKi}T;NYstFwl+@1y2n&=Y3VxUV!O4~ z9UEjm@JI3Kd;9l(-qLk{w3SQi5mx?orJnRHdq~<6_{Oz!Y-HgED@s>=-mlv5)n(qt zWp0)KQY)9Eb!>Mpb{Ra)W=OHoFRNbY?pGr2UANx@=M}G-p@-S+8oei4$CP++@Ll8j z#UEy`XZ|q9%B?SpT|OC~GptOzL2o$BsGoQ)hEPXQ8xPJAiYFJZ` zn1;W1cv^R2+v%#qE+Zz)csty-%$xYUb2{X`Fl@A=_52yloHPC&vUknbHtY%)K+qCw`J1KzbvZ$`1<5`OJ9yG)5RgO z;;vDy?}1p*oZQiKn|)hv=ei?JGez69m>;>rrpDol(b=Q(w5smDKVSXg1FS2rs2?@G zX|%JsU5kP*qMGiFtdrd}v*+yQ)wZoG@&3-YCzs`S8olpT9qUUW1q#`fe)bTR7S&{S z#=6@p4fv`;`Iv{R0&BOcHMLH?YF!FeUfnoK-6ndH`}_B0oC3^-MBXS`!>Quc<97Q` z#$Ece+;`s>+cINf=l2nZ=351Pe|Lu0#s(8C!l(AN3b-<`xN2APm>#-uE>0hR@!XoCFRo-5wD-5RZ{9}CD0X4Sl#>lc z+_iU$v>3D6qSrTj^GIK`oZ7J3KZdOS#6mr@dbO+G+nAm+9|AuH{o_ zsTp6p?9i~T5l7E_Z)s6u|CNk?{^3|9`s<}V#)nMJ(XRUOb<2N>_vm}qxp&j0H}m*M zbS{u9=lNN;eWzZ|oqL+iFtdXdUYoVsYZajWt=L-MUbnV3s~WgtNWW{-q|#vzoLW45 z{m1bB5uLm%Rg-RIuC{H>hNb1Q`-Ro*)AD7r->>zY*wXgvmi80ZcYp0veuP=f?m#=$ zk9|fi3@p8JsP&X}mXou`RP@<)^RFB$T~?MWxBK>sGG%*rZB$S-VbaVAs_Ned2GsoK z`GuxO?5=IOIInKuhW4&=E}F+%##F0nvud_gt)q)aPJ41YTU_q2Kle4r(WYqYPQTgp zDE9tz$?1zO9q+bGQyG`6A`2IL6;o{e?x-i5C#k|3s-!PA73|n&WR63D=jyGB9-d)x z#$D$EHf))i!#vx!&u&$Gaqhc?u~DT4O>gB$L2FukN`o20LK;7R*e59Vn;T2U9C*B< zeUM}w*88U$nKG`i%s3|F4NJ!YOI%)j-LdMq8|5R0SoZhp)vx^FpxJI+#=V-8C3N(v z?rraQKT{RR)w}$6Pi`M9X;<^q!qI;Yweq|Y9-vyADa+LF%!f^UGSsO}OjGxRA-}Y5 zUU7e>HugWa{`vO4mhY~A+iKZG?@Y41MqE56O*wmIa{ zl}ncXu0`Lq%TeF9N!GXSr|-I-{`t#4f_pi8=bX_jrsIuYpKs5+zV^_jmXkt!Y<^Zt z+2U$N7b#FL*NE#|Zx#5?+{(hSNKB}DYR|fR_xdiYe0ss;_>wDXpX+<~q<0>N`gdE{ zWm%tLQqe}UEu%{{DSGJmvT|+vxu3q@>9*7C8C9%j*}kqmD)##hEru7}<2Ja@(M4sq zU8t>oUUY$aw(Zk*eY(H3F$*wvm@+2#dUtET$NOh*TiY*u)1r?3NA9`c<(6SmOs?>K zVOM)QTSgyk+WKnWmV>V6y7#DJ@Y{O6U`tbh{Z>y#{S;WXBz~rqG!fK!_9xO zue#H0cfBj450{Q}-jJ>Ko3W91R|b~tc-(*Ff|oD@YuAmv*PwUShl7qfTdtg7TgWPK z%D0wF-kRUrGW+sxrTUc_dur2)H(&2TQ}?hBY|S^$8Ta+E8)v&DZ=KBV+nNs>zdB+{ zxwsN#vr3^&b{&3PZ>wiLxBkl=-+i_Bjd#&govwPs7I*n;|Gcp716rwGO;v9#(DA{G z#ctIu|8}oe@6IK*?)O{>Hz__|mQW z)pD!%MdiI2UhVwrLa{qGQDvS5HgG7>zRmzUcU9XB=BFz+krt@C+xBejlUX_(SY<=2 z;bZfyY_xRC&!Kyd1Z6D~QqaFbqpa_q9i39%VT{+ZJ>Qr&+EvVDX}R|Md>akj{`=Ow zC)y3Tk!g%u%lcm)I=^Or-GZHmsGgb!SUFg~n{9dP`SH%v%f*$u+)MhU{hHBrGHvm= zf4wV>aO{-~_w2?l+E>N0+xeNcS=Y~Wh$y|OX6{Ds5!I?HXQw3aVX^9tU&!cp+2>Ihnf3?RPXww`{{e-dUx-bbNa9>Rce)-P_fw)|6dn6 z+m`gHKP>yc$Y$-#dtm)o1 zX7tMes`|Ma#oSnQ#ix(C&!MtEdYrvquI(>*bMCo!rR!^_N?+om9S8n7YeboyPT4$H zU69OwzV$ssuU?xzSsZiZ{p0Olqt+kHS9X{Gp!p3a&wcCWyr|(AuSsoc-n4Yh{BoST z*OcA?akX-(3so#IJmyR>bcYNX|GmW9`6s`t6mV<=!Y|N8|8l3r~AWUWxl_FiYQuY z*N_#@N6mQL<95#(O_~;O(*MS@zG#7*i@)^ST%>T>Re_S(>WpJ=fO%g%hD`M7cvu0FD0s-@qqkOtAYqAvyh>a6Of{#Mo3z3i5!Lt``7a9U8M%HCIJPnUglu6e9O zrLd-U9b)5#4Jc8hlq##=??D%Xn~&XOyK3N{@fXU@YGIQrz_Chv$Bk?H9F;8k9X_ev zU&HL`=?OPa24pA|*J9vAd8@zr>OtkEuEj0{Odvk4u2=t(Z~N_P+Ew;6rfH#GnJ$Gu_} z_IcUm_ZvSgcplt5Z~JS5o4WQZ+pA(V>GGGpPkWRce>cao*fYNOB0}>yWa+f?{tNeS zHrH?7cGICA@0+??1=#i7P$3|%|HR4jUhXJ!+<#Ke5>MBA)-&HZzxSqx!-|gD9rAER z#;|F5+kdrcL%k)xu5)d7_4hAst$$)sdzgF0t{L)HimCo`Pf)va{awn%U_w6Mj2M_$uX>?D(kM*p6wrc{@!Fu#jfR>+&T3Ah}~^x$De;6y|GB!4THMY z%W!aercv+5tPHB6F4Hb@<<(`uWh{NWZK(S7rq^%(bnB7Vzd{YCe6Rm%J?*CLzMI4L ztWYg>%`s?iu6u(EdOn&m@sB0l2L4%hQAyhdjpF=&-RTY6n&i8@`uCeOx6p+brdCji1 zb1u93RG-B?E}lN(YcmIZ00;Gvrm@d9755rdcWIzw6@oQRQorRR(5-~{|nUJ%L-;)+*{;1doSdN4eeT;w>;Fd+`<;w zbMD`A&-Y${b(}@ftJb+5#(4R9#5)%5bZG48*#TZ2{ohSrRMCIJH`AZ)JL2`DO~~BW zwWe(A`Eabcd+q8cmXzz+b)#Rq5pA2fcJhncJapqc+tLmLhV0t;*B2*i#z#zTrV5>1 ze%*mzf~#~19vk}AIkaNsdUgw}8NR=XOACvbp9XK)7cu5#eHe&Ad9IYm(%QRPp2yE} zpubuCZA`H#`xicbb-!M8=|QU;_FXD@{zCV@5y5XBl-(VA(kEza!#zRlimYBe!!tbl z=+G=7qq|!6-e0w1yaAb_r!I)fqejXVcINW9B z&3tvgH7~O2#OCN&r`}B>2d+F<)pgK!%g&ywEA!01IXE`^tH6F;{b~TTqT-G3sLti^xJNQ>gJM3P?lk^(z@3$z^_t{~@|T^tRqT zkF9?cA8nCyc`q~R%AQtr{fB?iyWX@KKW8r0I>7w9-K#9?G*|UjO&=I4rs-z;>uqXVob=k=&i>h}krnGXUL4~2D7&M7zL(*xXVmrzyZZES|B|Z0 zk9#`*(lZbBX})H2dXbY>5 zL7ponkGWVse1A}R|LXy+`y-F_FQdx(&GshaPd=H@ zsQlwB?St~Q@8aM8O3@Kbo4F3Ovx@qzb5N$;4qyLzHLA+}bLaBM-*Dbmf5nwqeh>Zq zf~6KYf_k@ku;Sg}+Q%oq$u;OiWMq*%4R*xbS5J$Y@G!^eLenQyZ246#mpX+uIn-=g z>C#_6ZQ6XL$G*j{f4nrkO2_-pgJa%L42YSrc*(?C?(KIEei6}h$@9q_I}bWN>Ai(- z=)qePNB7R{nQd8_7~3o6vsTtUQFTI%mZM!8y?y-CQ|swX+MQbRetPa78V+7uzRILW zFC5>!nrr*p;rPlUUpeN9nKQ z)!p+2Tthr=7oO9p?~=s}w#D6X^MCFUKG$|wQ%n0Sj=AziF5B3DK6`)lhh?oas)%Fx z^+6Ttj~igotWg=C65o$#@nGMj-PtlPc^g;c`Wx?C&t6&As&L&sV^OuUYF(p7UhQ1R z4fB3bYtcJZom}-E^?A|6{oTBSw{K*be{WEi&V%i;4jbXov$ol_&QkA;erh_sJuAMx zJ?QbF!|JA;t;1($XxOXlsUm(W3lBc_O-;33qg~HBSDiDaMu(SShYpuV7{)Sg;+*x* zu6;9aM^5uS1%r=QzY(!2{LtaeQx{tWx45rf2Rk0FpS%9J z5e<9PI+|f&=CBK|hFM(sPUZL5|IN#HkL!<%R@=l_=ICmZd20)c9PVc~+x2`sZ}Hkf z=V#{F_sg!xx>kMKc5nE{An*PCx6V=xsTuEYckW8Vs`G0)@9aK(aOs09%Klt@O8Nb} z2YYo3>{e4{=8$dAj;mLn0-G6KJDi)*wCw&{E5GvWXI^zhzXCBC?A;&DymIS{;HjBx zhEADRT)kkI!$7Y>fm7YPIaUa&S$<(AneS2luwl!N-JdN9 zx3IO(d%foZ)pz%;T&H9`P_SCy{9ZYiEe$W!xJyq9pOddb#?-GAHlfA&b~C13=+%2m zCL7x;)4R8eip_g3Zi1!DhRcrI?wnH}9_(D}{5Z=}r`r5l-~6jNC#ycM`Y_s0RcV9G z)615xPxj1Sqm*jox#*l%a{Q2OY5Vmy!!Puo>88q7ZH(Evt|zklEX+9Ha`LoY{j*-_ z7rLtbqzvb>Rz04>z2$BD9krKb-g6?)hQKykTP&=f!6l&R!Ipu$T-tg(Z*1STdL@_Z zS+<$2Yn(U!Wz~l{dQ}cA9XMw3mm>)OH#Q8fzq|3w><%kSFFCL> zXW-;3gWoUf)y8M?w3p?--aV&*{|~h-ZmzCUD~Eb-ivoR`K6bPVUEd~4mF)IE*k`+T z$Kis9nN?V^1J|T88QNN0%VxEHj+6C>T!B{6xwrlzJ#`%(e!?;0Vc(wLx_#?WwT#)5 z%_kZhI&6RVh53*|x19PG4lAjiIKa1Ubk%FocT}~kqcY69u}fXYYMnI} zu`cWHc6+kk%oply*6eic`a^1s>#jaCEpz9h>aQv^%R0Wm5L~yJe)!t0xH0C}=KZ32 z85X{;fU4)fY~8oFt7~>^-bwS9J}1J)o7KvDC-BVDV(q5xGxO;)JgiUdLpRNL&N18b zL!Ibfi)L(Hs8OChbDhqQsJAt*MOBabJF`1od|9eu&cGa1Z$~T`A06ge;abLNeP*ee zjEi-&v3-}R$=1&K;wBV0v^B@iMZzcF$YEC2x=N8fcHx~Y2N&_)+i6Sfj9u^DoZDU9 zr?Y!OztVf|M~&-}n<8bEBf@c5i9oNm-!D6VqmcO%ulPxsw^eT!F(PNS%+$rz2Mc*-3TqQt zFsDWH1*I1+j>Jfx3uo^@KsrS?R@TRg9Fd@ zat@k0bMhhec(c+q!g_3L5sojdEgEvao65Fcwptl4WUXr7Z7#H{TeBt>r6<kw%U^G6@#Zwd7S@YCF@gF?RVdu)5;tbKY7LwCoS}F=4N6SFLrqf6F|cdfIkY3I34mz-*UnJsLkO-znXdH1xrp|0I@LiTbw&FtbY6q`~v_keKq z+jp-5HrOvz?`?SAyup;ZKg2A|+1zsNq`>;uVyfq85LQ02m6dOgR=4jyv@YqA)nOLM z`PO09h=`?=`b;{TXY#2A_O@LR;cFiE@Wsgn_IFPm^uN(2`}PI5)%ix*`8baWwkY6Z z-65c{GlmLUh83Pw+~LNn;P?IK|2D92*w4R~%h@E%Ztk7gGZ7GUKimJyR*{3tU9c(O zvdb&Wfd>}7GL+vr)$)ML!l|0Lj z%^#}d++1yuYn^3po>&|VJXUDmW%ajqJ}p;W8P@jYeyhwu+rsUN6!$6NWNUq;ckj?= zLwfJD44rR1o4*e2YW|P#Hr=RBci7&Ibm)D01|eUymQ1S~svi7PtG?ai!H~U2Odem+-0Yl<)b~-orz`K0P(~ zpxM$gf&DGq*PXv#ty$&B=GL>KA6fd9x$I|OzUffcuXo zuU@@-$SiY{9~X?LICg0{edy>ZKUX@myZW9X&kJ@LR&?j&EQ@k%Y&1KgRb;`$-NvwaOk@*&}l8nLV;^R`!-ewkxBQk&KY6$lhDHNOmN9 zUWBr@i;Lgs`}+g#eVlVY>-~AZp3iIZ+#8-6h zi7y)|Z(Kjh5MlIFY$Pv2F>YsowPuwT!i%hq?sorCHZgk&C@+Tw zGfbACX461$_RvOIxZ7VjNd47f4c^UkqAT7)+?)knFk@+8cZ_>wI%FitDMut)K|yDR z0GF>EdFsVhB~al`7ed@Pa-ml=5e+n(OvYsxCTAO5eLphzQkkCNUKKEMj zgH?2(QI5k&V=L4Fz8CJu0Y;Ryl_WbWvY@gwj_o4{>QzhLSeZRdNQ5ndN9F485_-cX z*oTxGZHYgGiEIA;?h$$BrN}~j>?uR`EZA8_NTHnQNp;92GtvJjq!HcpV6K8miTsE}*TqQQplF|R87`PvOaDIfgQ zRzio>PLGdIq8O)s#cv!MIex8M6=aVi#;<@YknNYq`%+q1v7XnD z*NN&FNL7zkC*=2D-4kAjzOJSZWY>1!Q+_TNQ`R))@n_7ooMr>X$Ug!30Q>aK4L)i9 zPyvqZeWK#IsOud3LIZ0Fp7}OL9v3YiQ{ya2KWVNl&a8L;HCvU}J?%>cZ`0V(YXNLD zN5cy!ITM=NaX-5NY-A9sNX`_=OhPqnt9DRsl=8*YS^sbO6o2=k=BjVI?af@XM-`=V z?P~g+2xhW8RS3||ykj7+!CUAN4UH|_(Q^Tgf|z2*bA=<8IW!x3SdpTZqX&;?5j?Ori)`lK_?X6~%` z1~+Az2wjYp%H#Kb{H1CgPBK<_y2!9;BAYu+U91!e>Lswo*m7A!M)YElMx5~xcu$JBcfLPHqb&dPj%;0mUy&njtdvRSk%5BQ_j(p z1*$>cfS9*W2qlSK9=>%YlO4T!B_?o3e(>leku7; z@>!{k2}4bozj<=5Z({V$^HTnq$tE9$ zcojsp5L=FD+7}a^v!hLU{9yQ8mQRLh$Lm-EY;dJ|i|xZAL0ZLdS|a}Dg;`&BDAv#x zSh(^0J4cts*r#RdKRgs_Q`*z3^=3QlLcf1fw^6JmX%9gtu8L$KqhZVNKg!_aKH-U; zyiLbs-iEW=A2d8CqS%38CIlA@enI}B_HlUCM^H)83hPzdpa`2AETvh-qCG+gh_x>6 zhZ-C19O2Eal+38LmL47xKkv@oIdi~QG&uzBHl4itKkV}YPjhw(Bf1xDm`6fyU5W@q zi1co2MgGiJEcq*wQmj4K73=m!b>LBnbzWJ^5U8mkFNf*{o%&ZjJaDk9Rw4kEaO+c| zt}<)?h8vXW3!45^4mDm1l~rL?gaRqh(+M4a3TQ`Y$SI-1^nPwdY{m( z<;ok6j^JkeNwe&pY~Yer8Z=U(U53d{03cq<<9|C%@y_6@BLM#fz2d%cLzs z+PN|b0byJM&n3EEmBwV={n$2}QSQZ714BDql?@640F$0C+GRqsv`E;Yp;H`L4nUBra4HNb4Q-1Sr9VEa**@MuT)AWnM zRLp(z_{<*0GW!?qce4Iq+mi{iOBz0BdJOaZy3HrH=_K*UB9`B`4KwHEGzdSsv%ewU ze`;BHnV}ZJ@7TUy7@qu4`T026?rkn9xv!kKOjxS7bYvYHYo8#KE}Pf-FUf?d966$1 z|DE1ixg~!2@Vh4+w)E=<8EuXHsi3+XmYY8mKt`3Xe?O{2FD|&;4YYxZ_yr=o*9gs4 zR3#A3TtPLXhO-?$efw3yjMS~{JGO9%lqW)E&LNb5Rqo?efj*2$24Us zXH+TxM((3w#x!}{vX4|U3Hw!iI@jM-orJ8Ec(k;$1aGi=5@tQS0<~WakWl|q6~JgN zR^$+C5;P$3wkN_qZu-7Au6G#<~1JNHTk$KOM5`FF_fU@#K2d%jZHvcodEcJ)n);JfE@(f(3pZUEq13--uUV zBhAXk2ZD-z=PX-U_q5plfXmWy)_Fx@;-Otnu=O=xlj#fiYDyaLGpt!i*`248-q8I1 z!OXSYm~g`f4;p=i(Ua6W=X!V+1}? zyUHt|&Nv`fM~oRgnk2RFR4^f{3$F}Nv6V*)hGp38c}l_r#cCd$?ww4TU!NC7%P};Y zAz#9TQ0G>%&qn1O4W{~B3mrOkjB|j}2#cY`*@+yoJT4IZC0YOM?mk1*nmE**F#HS2>k3u+%E);LYc3?kmKPO(x%{8CD@TJifTR zg;!nsLFsKnhId_r&(2fs)N8*6c5w?jXvZzy;jf7={C_k)4Q7yPpN+9#3zvxnU2uu& zW1r)Y(SKe~6zW19*8F$Vh->`hTZXF~+xu%$EW|mY*MpAND!Lr2LH9ZGj-rVZqiu;p zQ#YUFN~B@hjUPDN z33tX-B*$^ulK-jRxE4ZW4;Q2fJ<1w3wCua*^@fDiZEPn5OqzTm-#UBEV(|;4Ae$wr zZ>d^p-A4DIvLxgGuZcT@di5 z2e9WXU!6~*yK1nZ&Et~#)AAe)8eM;Bef{v100^k$FJz)w5P3QU0Ru&pk>gQC`lBc3 zQljX_NuRf=MCfsdAjsPKKslPE0mNnBtaja9O075Yk7AJ#=bnG>&dK!rQYD`iK^Ah# z%F^AuG8gYMMSDl|Y&_OtkUB-ntH3_Xs{5@tzoqv3n|+IsxJ0ehuD@|bkQ+*=#gYs1 zQgw(l8%kbzf`rlhv=Cw65&H72VaoiaDUUUhv(7&fZALmf!;)j^ty=SrgSc{;c_uDs z-H8eHKr7~{Gtub>5Ro&)yxf+$)J<#h@BN`=(_aCxPL90RmcBtx^og)`M^1xgaPS9* zZfgQ70=dbpd!95Y|KK19iit=mC}sgUGxf>+_tZ~_rS|&L zJsQZ`9;NqF&8M)7e^MeLcwE@P)0dHZZS1xvffrJWqK5sjSa3D7^&Qn^hS~^{A zgY+L1cdYsF)}=kd)!0Xs7I^g5U#&HAAB!(6AxqmmPW*#Md_wLNlpx}Q^z}3mXToOXoQc{jkyU9F>a2qkEv>)mBNAH1XP>-YIe!2E znW^Jfp%kGK-{I(+Tl{4k6k9(*{8TS!u&^qYMk; zmYJk^T+U{l-pGxMvhKlE({jd6YFOr`b=X|HfU`IZ_z{gl8o5=7Q2fR`mfDYGB)iTI-S~g%O@@8Wz7JtXc~XKnsq2F?&aE=PcL1X{<1hFw_=>-^D@tjeDhN@+W-+z_v`dt6`8n(rV&a@#cb)H!)-jg7N^04z>LP z_T70}1=%f%+Jw%QP3l?sj=al})7IvYq^KIc#+@XUtdvT<+hK1uHh3%_+EEW^{T&G* zzIo{TJ&o{cY7FMI7JdI6*U@9hwH~WLgxt#6o-vBwlRDLe&FE0~?-&H23IKK}&Z6P# z!Kxosw9#|oa>kbu&bDMT@5$!Ct=0)GX!;)FiSv)KGyb*v$hp?qXZBX|>dW8i21NeY zbrOs!g%+#hS?kWXpUkn$Ve0D!V~?r#X-IkV8+Td#&X_MU!P*~wMn=JZ*)K||9}JaI z3DW81IP|NPQz**1FMZl{yFp&LB=Z^l!smOot36rVP5Pih+oA7k01DVAiUdCx@62ER zv3QxR=54yUHZ9wFlOt+6TUA{y(74+FmkLdWo}yT>c`ny`92W3q$X`%uOzx7NYLvCg z;o%7lJ(G`=jDZ25`_ z?DD+rSg`WP10nW~p)nNq=ZjZpz!wUJP?zr$PnlN2b6dnZIW1-KJ$)^g9oLb$|`BxRB(^WyTApd{X&# zvE}9X&u*Yh%Ld5NY(=|kc<$+A8>H8J4M;X#d&Gp1(IW%f=CexCn_)X@-Qgl7CcNBK z)Wmb1U>g#Y$3cTQ^Irh5rxlikWt7b4t3w=XbWGjhG4P+4N=d*b;>p>Lj zDNsueALqBf;cykt=~(8&5lvqC;wVUE@QwauMKv6n2nr>_Ds^XOsc_8ltdGMfN?8C|=o=aj;MZ#~rdI)< zcY|!){;^@-_Lczj&mwocg8-+K(?Z$N0r%)|<06_T!Vy(f9=P-6d=B<_7e%LAjh!`j zeba-Qr3JumZ>OYDtZ<;r_!cD@Ews-tWvn2oV1Gdo#rAWR4FEp50(>LT4bTSC!DnbE zvx4ENz){M6F%3**p5`mnv~1%jyLCP7ccG3+xav|qBD?Tc3JI_U7L$1)ijq5CK+Epn zm>-CX4Y^lCW7vQ`JfJm{hFrH(rfk=XTMwY+RVFU-vk6(DIKlnyvT;*=IKb#Np9zZH z96yb9a$<5QzMwA*K?5OytIFJ})=r;n9jugZLk-(oDMc3vAHi9U6auFlWDz=TR12pHXncLF&(MeALFe(+ypg~g#go3L@7vp zpR84?Y+9!(X75w>UQCHhd8hBzxjG<@{D+|z>mRKj&{RUQ@pb)`u(?N2&^~CNvuf>v z!@$s>CDCy?>b?D#R4Zw zHfz(pfVSiFU+4t9rQPIxi?kK3;RzXYcWoYXGIDTPL_zW)>bMl{X)4Ct^HrCw3TqF6H*-ZtR95 zucbD}y^4zVIq9LY0n86*e=ql|g*F1&JI;4MUQFpjt13jT-4sndYc(KtJX4r%w>w!B zMo!N@Tg&vX+;b}Wu?Bqg^cTu$N0WQHYSglxwCof%)TPNn#rq2ui)**j%Dc*PKKCjE z(^UPikF6GYQX+eg41o$%pH zY7M?5C;QuYsYoxm$}ay(!4Jdt zVVH9bq71bcON9O0T=Xp-UtA5A0#EI4IUHZ!VI_zM<)EOUFf5(;U%_!IfVvcT7jPs4 zAag~`;ds<0?mgs@OTL8z&C`)POcK0{& zepo*7R&vW-+~`YnnAw;>hsqC2e~ty!j~uzzDu#TqKtBXuBe} zf`t-GO?oWHEK-3Kh_StBd7HM3aC`tCwxlt6EF~)@W!uAbY?hdqZq165^Y?j(uD@N0M+!v)%T|QT{mpLiz`c{vO)a!siaYE9NrcCQyj-Z37i~6P38RQpnUyYUpAcs+{eRl(r+QXRw*(6khwUO;Z&C` zIoFW2m_;92?S4#i~;}>^8*#t-cvCw@X-ArYh6iDXAXh^bQ{lb$Z` zC7Qq#2CSI~+5`A(7JCz-VEm`2C&{*Pz>gurPXh`!;uBxxfPN=IW8%dhG8IoViQq=# zuWxFCm|_-*<(qyR%sj-@qHpjx=K}x1*R5$rvj@%1D3W`pJwVQr?$QfL24*@Ez?s`# z<7~3__hi@^ZzzCrnwA^DN~?p;c*sg+Clak;q2L#^fkHS;p1NaFcytLru9OGQHmGu3 z6A{{@jrhd$xz0`j4*fnp5z|uiEIoJ3q5{$c@MH3AIHDXY}2HQ?Tkto zDI^NMlS28tiGzDAd6_S4JEO!T*e4LPjTb1c;O(D;`D9x+Dm_=9eu>*uQanHU0xRcB zPye1AOMDrQN^{4yKw zj9C7-KVRat4MY`EPDgDnBwi0$Pq4JxEhgvv$e81)rZ0qKo=#`2x*JV<%0c!LxRe~G zM0J+7zxih;ZXN)3;^NEu)Z57zykHuv6Z&%|{*scljBO^DFc^2sTi#@=`j(P&glkLA zSiH52>iHq2fQcmA#G1&VpfDr+R@Vu5ED^iHwl*2`oAtW|cqa zz1Y;qRH zGF~B4sOG18n~66S)&&#rhdgEJb$eF*eGiPFkq(MwcecO0YQ+~7m6kkLC7NYx(-nJ3 z6s__G@cn9I#_ixxKdyy_}P2v5psRAY6hF45}5;nv-iQj6%Zwdb+J_Y;F6w&xzU>lFWVf) zLLK;Y#Ae0eFZ5!?t*$bY$N!AhF<#pC=N1k>0!~pU-9B3jKy?g{A=+W_P&fW$B0`3f zDM{<07L5CAEd=w?oPC8+M`c6XE4Th{igkUQ*}-<%MA7);Io?tR8i$4ndK7H|mll~G z?$qzmbo%`=67(Nambw&vs4;-UMTxJeVxiJ$#!Xa!^+R4EdUGs7%w0%Ok!dhzTe1D` zbmWM6wIm6E4W0$Xj;+FEI8)3L#H$lS)EAEPXyON8y;In1UgQu78{?JP}r?j0Z^U3K|BXAK3hI_l5sb^R{@*I=6*N>Q zhtFqi79z=w%y;D_ZY-mRxv{jcXVLY9>VC_fm_4w3bPbI!ok`uK~vf7`>-R$%Vkl*c;!^7kx@W1Pqi|1AGnn*Ck5FAO;V+cG?dvz4h7#J>)X}d0{O~$mQ0?9nO<)fZqJhv*qLv zT?q<{cKr^15wS$-nXM-Kk|RT3IfdoYz(}dj!}n;>+@;r)&bV=PYNWZ5KmG3{$qv(h z&h=c2VG2RA?g2ZX*hud$p@?5ZgvmB}!9ME@LLUEeQ)Av{xBj_{X<8Iq@JfAco2m5hc%%iuyhFqeTF`@3Kq#k+1K!ZKy! z&OY@%+kQ6c*CfLybR{`6*q!2*C}Cb8oy@B-QaRW+gfytOR`0J;#_ISU;t*nFK z(`X}{8SD$v>9Zjaz7t=YeU|lhPI@?cnFu?2s4@IQ3 zTI_d!?t@bC8A~2%pb(yz!uM-7z5O}z1duc-!Rw9l+y!D@ z@lM_^<+%3!fLxW~Z1wH-(%uN*wxk7k3J|+$lZ8NsOYz_ZF)nG2V3bzhY2gh0bZ2(ru8ue}o|U;)Ls|eKs@u zWckVOXb;kbYORFDud>Cx5qkX@@05HxWv-1e?3!8fDB{{IrFTk?CeU!-v(+1dnphPV VOD)_L@ZT9A4OLy03MHF}{{dv!uNVLT literal 0 HcmV?d00001 diff --git a/app/browserWindows/main/main.js b/app/browserWindows/main/main.js index ac9f260..44e68d8 100644 --- a/app/browserWindows/main/main.js +++ b/app/browserWindows/main/main.js @@ -22,6 +22,16 @@ let apps = []; document.addEventListener('DOMContentLoaded', onDomContentLoaded); + +document.addEventListener('state-change', () => { + const running = apps.reduce((accu, cur) => cur.component.state !== Runner.states.stopped ? accu + 1 : accu, 0); + + if (running === 0) + ipcRenderer.send(ipcMessages.trayTooltipText, ''); + else + ipcRenderer.send(ipcMessages.trayTooltipText, `(${running}) ${running ? 'app' : 'apps'} running`); +}); + ipcRenderer.on(ipcMessages.reloadApplications, onReloadDataIPC); ipcRenderer.on(ipcMessages.displayReleaseNotes, onDisplayReleaseNotes); diff --git a/app/ipcMessages.js b/app/ipcMessages.js index 298b317..9e2bf41 100644 --- a/app/ipcMessages.js +++ b/app/ipcMessages.js @@ -6,5 +6,6 @@ module.exports = Object.freeze({ reloadApplications: 'reload-apps', displayReleaseNotes: 'display-release-notes', displayPreferences: 'display-preferences', - taskComplete: 'task-complete' + taskComplete: 'task-complete', + trayTooltipText: 'tray-tooltip-text' }); \ No newline at end of file diff --git a/app/tray.js b/app/tray.js new file mode 100644 index 0000000..f3af8cc --- /dev/null +++ b/app/tray.js @@ -0,0 +1,26 @@ +const { Tray, Menu } = require('electron'); +const path = require('path'); + +let trayInstance; + +module.exports.create = function({ + onQuit, + onClick +}) { + trayInstance = new Tray(path.join(__dirname, 'assets/icon.ico')); + + const contextMenu = Menu.buildFromTemplate([ + { + label: 'Quit', click: onQuit + } + ]); + + trayInstance.setContextMenu(contextMenu); + + if (onClick) + trayInstance.on('click', onClick); +} + +module.exports.setTooltip = function(tooltipText) { + trayInstance.setToolTip(tooltipText); +} \ No newline at end of file diff --git a/package.json b/package.json index ea81431..37e9150 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dotnet-runner", - "version": "0.2.0", + "version": "0.2.1", "description": "Electron application to launch dotnet applications", "main": "startup.js", "scripts": { diff --git a/startup.js b/startup.js index 8975a57..2c208a1 100644 --- a/startup.js +++ b/startup.js @@ -5,6 +5,10 @@ const SplashScreenApp = require('./app/SplashScreenApp'); const preferenceStore = require('./app/data/preferencesStore'); +const ipcMessages = require('./app/ipcMessages'); + +const tray = require('./app/tray'); + const splashApp = new SplashScreenApp(); const dotnetApp = new DotnetRunnerApp(BrowserWindow, Menu); @@ -15,9 +19,19 @@ splashApp.onReady = function(settings) { .once('ready-to-show', () => { splashApp.close(); dotnetApp.show(); + + tray.create({ + onQuit() { + app.quit(); + }, + onClick() { + dotnetApp.show() + } + }); + + dotnetApp.on(ipcMessages.trayTooltipText, (e, t) => tray.setTooltip(t)); }); } - app.on('ready', () => { splashApp.run(); }); From 92d360709cec5b0ca3843e82c7ba74605202c660 Mon Sep 17 00:00:00 2001 From: Stephen Cooper Date: Tue, 9 Jul 2019 09:12:35 +0100 Subject: [PATCH 2/2] added release notes --- ReleaseNotes.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index a6b8d80..3a38636 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,16 +1,12 @@ -## Version 0.2.0 +## Version 0.2.1 --- Release highlights: -* Added copying of logs to the clipboard +* Added tray icon --- -# Copying logs to the clipboard +# Tray Icon -It is now possible to copy the entire log of a terminal to the systems clipboard. This also includes the selected text. - -To copy only the selected text, first highlight the desired text then right click on the terminal. - -To copy the entire log, select `Copy Log` from the drop down menu of each terminal. +It is now possible to minimize Dotnet Runner to the system tray. A tray icon has been created, when minimized clicking the icon will maximize the application.