From 1711e3e3f434b1cf0b0c9c262d9383b22d36c30a Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Wed, 15 Nov 2023 20:16:18 +0100 Subject: [PATCH 01/66] macOS: Do not switch to the dark theme If the program/graphics library does not support it properly. It is better to ignore the dark theme, which create an unreadable/unusable program, and always show the light theme, which is workable. Maybe the dark macOS theme will be fixed in the future LCL version. See issue #49 [skip ci] --- enduser/macos/app/trackereditor.app/Contents/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/enduser/macos/app/trackereditor.app/Contents/Info.plist b/enduser/macos/app/trackereditor.app/Contents/Info.plist index 36c8919..818cb7d 100644 --- a/enduser/macos/app/trackereditor.app/Contents/Info.plist +++ b/enduser/macos/app/trackereditor.app/Contents/Info.plist @@ -43,5 +43,7 @@ iconfile NSHighResolutionCapable + NSRequiresAquaSystemAppearance + YES From c9843ebe42eaa54c6f61472d96dc9d8695cb77f8 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Wed, 15 Nov 2023 20:21:29 +0100 Subject: [PATCH 02/66] Add: GitHub commits since latest release badge [skip ci] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bff5176..ec5ca45 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This software works on Windows 7+, macOS and Linux. ## Software latest release: ## [![GitHub Latest release](https://img.shields.io/github/release/GerryFerdinandus/bittorrent-tracker-editor/all.svg)](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases) +[![GitHub commits since latest release (by SemVer including pre-releases)](https://img.shields.io/github/commits-since/gerryferdinandus/bittorrent-tracker-editor/latest)](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/commits/main) --- ## Build Status: ## From 24b67148e447192bdf4c99b4d6442e53604fdc88 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Thu, 16 Nov 2023 20:12:59 +0100 Subject: [PATCH 03/66] undo: macOS Do not switch to the dark theme This issue is fixed in newer LCL version. [skip ci] --- enduser/macos/app/trackereditor.app/Contents/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/enduser/macos/app/trackereditor.app/Contents/Info.plist b/enduser/macos/app/trackereditor.app/Contents/Info.plist index 818cb7d..36c8919 100644 --- a/enduser/macos/app/trackereditor.app/Contents/Info.plist +++ b/enduser/macos/app/trackereditor.app/Contents/Info.plist @@ -43,7 +43,5 @@ iconfile NSHighResolutionCapable - NSRequiresAquaSystemAppearance - YES From 82a30f8a193ac91e7ae122a6b04d0fc59f2988e9 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Thu, 16 Nov 2023 20:18:40 +0100 Subject: [PATCH 04/66] fix: TStringGrid dark theme The dark theme for Linux and macOS cannot use AlternateColor. Even rows are visible, uneven rows are invisible. [skip ci] --- source/code/controler_trackerlist_online.pas | 23 ++++++++++++++++---- source/code/main.lfm | 1 - 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/source/code/controler_trackerlist_online.pas b/source/code/controler_trackerlist_online.pas index 431fb4e..fb4705b 100644 --- a/source/code/controler_trackerlist_online.pas +++ b/source/code/controler_trackerlist_online.pas @@ -13,7 +13,7 @@ interface type - TDefaultChecked = function(const TrackerURL: UTF8String): boolean of object; + TDefaultChecked = function(const TrackerURL: utf8string): boolean of object; { TControlerTrackerListOnline } @@ -35,7 +35,7 @@ TControlerTrackerListOnline = class procedure SetChecked(index: integer; AValue: boolean); procedure ShowTrackerStatus(Visible: boolean); procedure AppendRow(Checked: boolean; Status: TTrackerListOnlineStatus; - const TrackerURL: UTF8String); + const TrackerURL: utf8string); public property Checked[index: integer]: boolean read GetChecked write SetChecked; function TrackerURL(index: integer): string; @@ -65,6 +65,17 @@ implementation { TControlerTrackerListOnline } +function IsDarkTheme: boolean; + // by "Hansaplast" & "Alextp" from Lazarus forum + function _Level(C: TColor): double; + begin + Result := Red(C) * 0.3 + Green(C) * 0.59 + Blue(C) * 0.11; + end; + +begin + Result := _Level(ColorToRGB(clWindow)) < _Level(ColorToRGB(clWindowText)); +end; + function TControlerTrackerListOnline.DownloadTrackers_All_Live_Stable: boolean; begin Result := FNewTrackon.Download_All_Live_Stable; @@ -88,7 +99,11 @@ constructor TControlerTrackerListOnline.Create(StringGridTorrentURL: TStringGrid FStringGridTorrentURL := StringGridTorrentURL; FStringGridTorrentURL.RowCount := 1; FStringGridTorrentURL.FixedRows := 1; - FStringGridTorrentURL.AlternateColor := clCream; + + if not IsDarkTheme then + begin // The dark theme for Linux and macOS cannot use AlternateColor. Text will be invisible. + FStringGridTorrentURL.AlternateColor := clCream; + end; FSelect := FStringGridTorrentURL.Columns.Add; FSelect.Title.Caption := 'Keep'; @@ -144,7 +159,7 @@ procedure TControlerTrackerListOnline.SetChecked(index: integer; AValue: boolean procedure TControlerTrackerListOnline.AppendRow(Checked: boolean; - Status: TTrackerListOnlineStatus; const TrackerURL: UTF8String); + Status: TTrackerListOnlineStatus; const TrackerURL: utf8string); var CheckedStr, StatusStr: string; begin diff --git a/source/code/main.lfm b/source/code/main.lfm index 5fa3346..6ece419 100644 --- a/source/code/main.lfm +++ b/source/code/main.lfm @@ -78,7 +78,6 @@ object FormTrackerModify: TFormTrackerModify Top = 0 Width = 1165 Align = alClient - AlternateColor = clWhite ColCount = 0 FixedCols = 0 FixedRows = 0 From b332440276970cf27fd377966e61583ac9bd1a85 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Thu, 16 Nov 2023 20:24:50 +0100 Subject: [PATCH 05/66] Move pictures to release download No need to put binary in Git [skip ci] --- README.md | 4 ++-- pictures/filestrackersinfo.png | Bin 30383 -> 0 bytes pictures/trackereditor.png | Bin 23860 -> 0 bytes 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 pictures/filestrackersinfo.png delete mode 100644 pictures/trackereditor.png diff --git a/README.md b/README.md index ec5ca45..7af7569 100644 --- a/README.md +++ b/README.md @@ -113,13 +113,13 @@ There is no backup function in this software. Use it at your own risk. Bittorren --- -![](pictures/trackereditor.png?raw=true "Trackers List") +![](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases/download/V1.32.0/trackereditor_list_windows.png "Trackers List") This screen shot show the program, after a folder is selected with torrent files inside. The normal procedure is to deselect the trackers that are no longer working. Optionally add your own trackers. And select the 'Update torrent' menu. --- -![](pictures/filestrackersinfo.png?raw=true "Files/Trackers/Info") +![](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases/download/V1.32.0/trackereditor_info_windows.png "Files/Trackers/Info") --- diff --git a/pictures/filestrackersinfo.png b/pictures/filestrackersinfo.png deleted file mode 100644 index e86897c584a5a0e7309662d84ad64df66a8788f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30383 zcmcG#WmsI@(kL%7oo+(*yZ3j` z+2`ILmnV5vcdylR%~dr=jZrnLLlor15nyp(0RRAkq=bkP0Pvy}^dIf@3(zNyhV_M@ z1B9cJxDcRp6mJLg=9Q_StRMhT@dfVA021^b#!f=h5dc8!0{@5Tv&}aG09-^QMFdsc z^bT6Qi%Y+&tvcJL*C?X?kk7u#3c-0~inY+*U(UqKdf!cogTOp3A~!h%+o1>7@(~Gw zPU2cI)J>gQw7s1lS_`M)AXaBvYKCIm5RMF5;kz`W4YIIcIJqy{LV)M!+d1YfEXQ!> zUwC6@qnEmSnnz_vl)N4h+*?=7zs_3sus@8{%vPZ+Whs zVtQ|P2|R|ioz8}RX}ucx@-RGhe+vEB`Ng~Aw)On+ep6qS6nt+T9_5m*%TLE;pAI-Z zS0B&M+D^mTe!Fh3uHN+Mqx(L1{xp5O@M!ySPUyZtY5{hRPne18-f`W-QQLh`+i8>6 zY1bpty~q979pL^^*Zbm7|B>_Ifbe!84Rcfe(^dRK%;nO9ciV&O40w|DHY*jOIB#LU z9!7Akj0^gFg)TD!jdt61j4SXvp8r(f;dsnzo6++s?Jn;j@o~S!`*&>erBdtI_0kw6 z`Tgw*q1%QB|L++6WBog7XS4dI^`h*hCG_R0@03Sw4!6bqrtsF*VY<`hNcOQ@fqG8v z)K>4yCC_%rlHPf~H8$QLH)CmRsOllt7MWC*YD?Gv{?cq_xrBiQ)JtrOWlXjYPGdBm z^y0Q{9$j1iZi|E~aQKE_(#3c;$>=?y{^`=yd-YN7vGr%$jmzROrRV99+p4gshxDv)O**R1@-_27IVh&;kOEgP5K4c_B@ zW=4`?N(PW;V?P}R7U>&}NB?#dy-ZARn);#id{s0Ee(FP#HHe>U;3&4c1woTpIWu0p zU|)Uc(!Wz(y${g8vDUvY5%}Gg_Rvr0eUr6%y!d6H4P-}K?_a#D*GS$!1Wx)|H_BR% za34C;ZX%HilTi<+y=>9R@AcOigJ})V!rSC9b`cU=Y;3NEel>|j_8MycSheT}@^4Mr z`B#SQINGe{P;0tb_NWb4#$NG6tPHaoFJsg;N$J8m%2h?Bb~E=E>xvnr;IYYyBs(7@ zOst{bOh?j-aN~qo!_1rtp1poc7@coR`k%|eWHJFDzG`= z(fZ)=xWV|)%XpV`M7-(oFn{U&eF`Z*dBgSCPJirhqeZ9W+RLWbWMY5;BgAxOl@yYd zl4ilFoav>$xM;41J|{+IKy0<1hz*4xSITITW;s$EoO&;jv2HwzMFMcbk0nctsKxZ; zJ;mk;92x+8{T`i8|rKLM^_#K>x6f| z$L>jza=g>dTJr?XIh%Ot-`KRvrfz>$Gm&nCo6|lGwfB)#9?ECKFhpTf3a!*t@;ylF z_A=~~qRGNGUmDaAGuRr$a-PIyhe+D@gHQ5G#2KEZJuxqAJX{en#d|+B%|a8QI>hWS z5w3_rC1z+g2MQ8$rOs{}%xwlIcSjFfrk^@E?>mtAZ~eU=7EB+b^Eg-UQ6Eo#dD%D2 zsjXa(djFDcJr}rleC*4+7uP?T_~NCqoZ@!tr54s}M`-G26$qI$ud2ILAEhOhQ^86h zDVk_X-Qr*1TAa<2G(!gIh#jyJPccX|WEeA=Z$5v3+-oq9s~aM(e5S3z#*iJSXkM&E z5sj@T9aae|ifzS$4_MR6__IiGPsF}6ICZ_8pWs1GdkkuQSiMCRxN{dchC4lq;oqF9 z|3KAzw!!~Ec$<23lXCQMGIkewUXOy5ZkY`F1`&;3VY1Kt#w^7mzr6`$gV-I0$@p*_|H#?4SM_ivfBn+?^zzf@^3g-((Jdzb5w5`I>W#4ebStD@o+x9T`*jskL zShn*DbP=G`|6U6k{6dG@3?Fk=bBF_sILA!t}^n{aPbege!&Oqrqb^ zQh7LcqsW;%p>;qXQS;{}4$U(Ewg5!`dvpZHWAxTBY1W%kktTT(0Dz0zr55pv9cQzA zzIYS0Ysl7FsfHZX!pAQ`y_5p3OABxKx*4Rt+d1Zu;`J}Ish;lnp)z|x@67k+v9&2Nc>`GgMJ47DsE|XP^Fk=>EbAsolR-VoDCGyp+43DK-u1 z+%;_6i!wr!!b566>nl?iwX$09Py}AglQd4}QtOdK4nY8XSl3tb5I;e~?|UQJR8?b} zXKR!)KzwhbUGa}O|D0gVL6(rGn}CG-7J-Y{*xbqaT_(#_sc!G+@Gmx9w)r=#HQ|Hi zi?L`{-}f{pn^pB15GBP7803D8_KqZ*A{i3nw4Xj6eDGM_ZOUQL8GyB%h-94Bw3nHZ`u@?1Fq_$Kaw+oc*~ zz^#(gMQ4qq)_fE6=&!#JYk{>yp2!hFTO zxbGrV3T2C;;X{=x=l+Y9zGGE#Th{2UFv=nO{&6cZteiWU9a6&}I=J-h+S6Lp+0zuu zP;RUZqI^rP>$}cLr}pE@xh&uQcbbWlmSn2z^$-X}roH#t&4oF$%=>yNxGN-6a@R;@6zFpa~YJ0nD%_!1Guon zAp_#tn;-#pFvT^9r!|TqlmxF4aK=NXgy%SY4DC|4hte`IxZUai00xK@o+VVYmrO`2 z^Z*}eK*>um>@VJF2em!DV)Cs;Yy<0R02723v>nPFTRrDTY6!sl592&OF+MbDUPuUd zuRuYgJ!_&GaZ?%-5a~br&JNiLVzUYh0I1Ei#TTh3D?N_;7^xju(na~HlXC5`<$)5M zQV<|iBVzVz)*-6Fb?Bu#0|0zDX7~(IRW|tTdTY}Vfa9xl=lXY}jm}td_=k7$RxKO& z@-}Jc5qCROD4~W)6c|<~fjHQP8;(^7lo;v^~Ho2P-4Gwr5y)nK02vV6XmA5wE=+C7Rc9!~2iL@a68 z4u(yEk!^7?D}v=OnBFggTJ5V$*eB<4UBou?gQdIMG>qFDjMC$$6U1 zKJ=$hNxw=~vi-!gAnN+omL#_7m#v|DERK(wOJ+pEaP^f?EU3mI?nTU@$_QM!!FxFG zK*8CK%|s6Wf=bJ`t67XTN zNqb?!%W@WHek12=zVn<^y_zy`5G~duxiD58CRG^KfUf^=Xo^6rnJ%C(uo+`~L&XY# zqvt}9tw1uvU##ShZTDw*%8v(W(?H7O0!_%C$p3|U%(n3+IZprh3$5-_G)=sYppMqS zk=FLq{46r*sQfn#ul46j8r&4H|3Z0eH#EXe(4``>xOT|JdP&cMaWH0O8Mi?g#E!*APbkwqeQmRB7O zr=&W6wImH=78+LK?8%hmC}Q9*m|n!O63Q$rtm0E0Ue+QOB@~AewN$S(D0MDR5&KqT zSS7NQ3PX!oh|gxxqZQ;^p%+QcQC3jl#F;9*yZu8+1IOVAStS)>!V&{C9i%CqXJdKp zuGM|Qp zwM8Tqju^dJ+N4khwqeH`p)e05-?&(&7fkE@%qO!*5i9uf>`PhB<-iQ7Qqc^eeEZ`a z_+X}juds_|Jjpg@7aypM8=cFwv?!csbIL!Sv1csfM6e+h(6y{}~&nm6d92uKBX6wL`00ct0uk- zpSU{>m4d#HwbEFroGMjNF)#IUnNJOuP*^1rCs!0^m+H}iF302o2OECYk}mhN?PS=# zYjMLNdfOUaOMDJ4=X%(GViUK`!atWk$EIwIACK3MkpCWPUUI=dy#=|b@d#k2Qw`{4BxFtrouN3?jIB~)oP-q^caaWryO)v?#Hp{ zOxo~n&6*h3m_sGg%^`D-jJ`VJFA?O3v3)t{FvdBI7F3J)=}qswZKGkB07Yn$XMFVH z5$;dH1j(B#StsghipBJJ zhAomL6IE&>I~y-tjJRsN+l%ehzu}D#Q(dvmo0()|-ib-Z-GRxXQ-+KfsIs;Q%O!wQ zA4qp+rps`G_>2_vdKm}aC1j{{V!D-%?WdNmOHMD{NA}a^Ep$in(5Xgja4Y^k7>xcJBAp$g>kDvsmAzQL#z$2 zX>EydoC~a=N9#utq|I1&RYqzoT}$*xRg5#fJL5!A+_ra4zH(n(x+X)o^;C>MPt1Y2A3i z!^mor(~}*T9M%vrX|=3I;m(_UCJ!*=ZFs9;xP=f5kpb;?_;VNDbF8Sn^?kxB=l;~Uiu3exK<<5&?{XOhlLNZb1Tml zb(Tz|?k_V4rgt+qWf;m34^8%yah>2WerM!9-EBe+nBW{tooi%<8SS>n`Xs+f{xYw7 zX{XgGmgd1voUt=-1KpA0!Z~3Q%T)Q+dGl=@@@77pix&UaNvx5~wXe&fmlLfqklxx< zVMnNj;gWvJv*RtV#4za*`^r72q0K5w(-#rG%aDY3a7R@%Hp#8N$`edYM4EqNsPajA zz^Dp9q2mJtmcMoJ)1WJ+?xrSdc#Gy)Tt&>Yt|!}^=^|T$W36Jc*lwTHP2(yS(aBL{ zPN(hkLqn`4l2NCs7y6f=7If#u;sO0~d4DA{w+b#Bgb3T~IB&qFr%k@7fQI=%$WAQpVY^vS=$cI;;qw z%4_ANCzLV|Hz~+MW-nOS{$UGeeBvn-&Mb~g(fmrx6g$Yg+I8TFVE}6pF5A@liQ1uGB!QeMkiZcGFrWj347<)nCSgF zTSS)TjD$B$%A##5+I758d{vHOm^MtlQE{OPjSp@f^`MI=M$0`s5hQ_-FTZ~(6+w{X z;5Mp!9dpaVJ@5G94Y+jFtI0V;CWm>Ewbqt;#_(t4-t*(HI zksMvu>CJ53@Up+F804hu?#g6VQ+2h<87nuHqzYk|X%X6fEP4dYSre)Zp>R*n0qlGt zZy2f!i#eR#;*tpytYPEVQt4TQ05X$cxmS#1s*HXHYP1}>YgpVe&SDWHR&m`5*jcE! zHE&*Nk43EuHt6rQhm~#1Z8-31zD}m*xjb7mP+@#{P;ljzvFmO$+pvoA?9eTo_Uehw z?d%`;glqg8mIGtewXsqQL1lkZB&L-EHZ;da#NiE!bchBNN$l?L; zO*k{7D)|+m2)ab8%=cAUM3u-XGIQCeBYN6Iy;rHe?NZknJucS`9){+D2jqi>uzZ## zB}|75GNOqhHKCFtIZZ5RP7>J(6f)$Nud@Pe3K2hGOpUY!NZ>fS;|qbB^tPKw*?l(amtPswHixFp1mp|g?hpA|NQ#?^v zrMYBI(7+0dDk3ptK^Qs_rD!$COhGQ%=#Yap!t5AxmCz(fm%V*u3TaL~fTDA>1IWqqO&~Oe5~& z#^pd(RryHO&sVUQIW2ErHF)4(@GsmU1cF2g=+6TzR{s6S^quF^+L*V%!#d&fKiz8q zOZZ$ZXlyX~uki>zk-rY3($z0wOpsOp0NT$<0=x+v{*Ncz^Jmu?_}r7{f552iR2?KW z8!r-A#4Uo8vi9gs0i*`L{erICnU4j|8iT=4)0y{0dvNbJZkqM|X@`-XbQ*M}@y0lj zW*fC%I_2iqL|BOEnO%S(HhO7@@=Oc=x()#x|HA?cczT6VovSBP>+`Mf32%iEpp+E|6=8!8R(zqP`1sK|r5@>faR6f{qDDJ?srVY9w6*mzmPd@vHTz z@cpHPFW)iX)*$j`t8J0kJe3-I^YIS)uKYY7!S<_H%07nEEgMIGbXX{Krm6(RnPN%+ zBsWw)J-MMB=^|ISd8Z1BKse}9A4^f#HYN_(FJKV|dbE@%u&uz!C1@^~)OTl5a8DJk zwU19m{J))uCtQX8J_?nbqrrL--;nj9QB3|Q_z*_TL+Uy_trok^^`=*qM9eV zJie7JH5A9uJ~Ik^71o5DInZPl>sS`Rz1&lWPOoEsOk}3a)CWotY}@W@rD7E~j&C<0 zR^z+&tG;V{<}G}MxmYn;$Cv;1*>%@USrbNru&K_ulJ^WHkch-0U4?q6M#dg(9~-yw z-E@JNeysKMSED1@*Lkm`Gozgq7R_wLBW5bYq8Sg?x!Cv_YaOl1;65bn&~4(d8Q{ob zv)P`8niAng%k=1#yp+u`@5NUg!6JRLj9oyK|Ug=bauP>y;D@ydb5>myLwIFAUvAW@h-&t= z?;Jm6=(xKoGel6i)uKBQgJd5t2ofnI)qaqTR*zNeUZx&-w4VJ&;lK@O@lEMKLOZ`> zzN7CG~o0V&Oh>0N<@t4@MK4e=%aHxVh`por| zi)h0q?@PM0ZCgZjJEa+0jF$a>BV=Z1GVevX8oHewHw~`1^K@iNK8zL|QF-vPS0Om( zy8lvr^h1iXe(^1ooMfb_nYSab)HEKsLA`RCzF&pcZz^cExQb9XO#GbH&?gzUg?d`T z;w=|UDTnzNeAWA;u!*ai^ynXj%Slk=Xgz57V-`*rvMgWj*J>_~LYXS7Wh6_`l4sQv zbQ5sc10YRh`}RmG##Y7CCCgkyE0GnM0>dN4)d$e%e%sPF*l>`2l-WJamcM!2l0Y#Njd1H^;i=Wv935+yvs;k z7_u36yVbYzi2?9hlj?#eBGf$i#b$4KkYuA&p6pyS~9k$o0}2$?}|qI2b6X z$Zpl7cyULvjG|`a)v37vKgpNJ;9pFyeMDyw)1L|#5)Mv#zo$noz5ZkJh1ooQmkU&P zJ~nZ3V>eN$4xOEMHFd&5pPw~OefKfa2EaH=yrD1o@kR%Q zt``tsendyh8>%RI(NP$-os51B(vaL@s7gcmeDHEAvr-v@;>ujYaTdu;a_33tzoG`? z1(oXh%zpnIh>%HgK%11sHky@d=p_9NcBv&4W0IB>|0@ELn2v3{X1}+;8emp?Px`H< zbKgiX?iyf^av9^Gy7W+X*`PMh=2)U&I|i7M{e)B4SYs_^0!dg3E}wp9<@dPYXI|Ha z_Tveh)Azpb3B%;k^IJtl_e`5_qG@jNlR?RN=~`D;bzMmjNSTD3frvgWx?`>OVp8Sx zupvV1exyVV!RPmI5v(*tI`(iTu6Eiv5`m0S=X@-jh+3`PDpP)9)mR;A6Ij^xl(7N$ z^d(W6E{ekTrOFtCR+2G;%+;RR2u8-Zo;_U-6e**=#CIgaJ3^jE$c03=DN7LY(yh2wmCp90Nj(q-wHSE@W zHi+v}Si)TQ`!+@5?7i!`2-Id7worV|z^n~Y1$NdcGA)@vkBb21)?EH#dm{Z$#0YYb zps)U^%;@lfBBbw=qN;ZRne{`_?E3PNSDh4CLU39C`Q%Cd{qh5W$!g}QL`Ip!G~8V9pAm+SFTUFrsbI6m#y+e?%?jQ| zp2*Mbfw$!BM8Tx2R?;=99F!-Y=HmTR=;5lzvaBU{Bd|h%Nj8O~L1Czkue7Ic(5>-( z(p7vS=u19D??BI5Yk@!OzE@J$C=gBV>2GGHHvFQ7lIp7%kvYBujdBK3{}?iqC+f=< zkfik46Z-Q7mv21(5ei>?5apCbOIZ|#r$iKS-5&2IKq3R*01j+S&<#w=V*=y#z1(YT zi72##vUe#Dgw2rLY7<4kdUtJiJokNMiB{0SYI*Q#p2i_=aN?}*cc0?@FUx?2Y2}ay z8ImJ`r{To@47ZgLxqc2>z$ZTfA{|Y%pv?(7FKOLq!ttyrmYNkZqoi#SK$q)qfIL*8 zx@Y%8K1Rn1d7K;cSv~)=tEMGeRRy=rpKPc4Y`c)OCo$OmXF5+CoGEaB#wedF=yK@= z4FH%A`Qr=l>ouL{OTjw@0Ki{I|NE(+jZ_|Z@0&_~OsTZ%>Wv8mwx-kD#D8hPyMq7M z8nFIl)aoSaa-X@Y*UfZl*i4&;>2C} zu<&!KCDdlQr1OK?7e!Q5N1|1&3?!A9hD2k|EU)tpj}(=DihYX+mq!5Kt7qGZY*!5m zuwKV_l#NxKkF6M7EF6?v;H)L$CQhFC&n}Kg+vB-;Oce-qCfIcrh!eWGn8P+Rd23pWzqOA+Z#|6iK~C z4dZx|9G%_Kr|~`YeOG>+LV<%uv}wr2XM`|2Q?C;K3Uw>K{j5?04QbzMPS>AH)~O*{ zF+o({%CwbqCV*iby_}p{0Q2!S`CV<=`jX;LnAa~rnvEt5F*Ax1e=eq!$(e(^!H(fx zA=tq;{93C4hy=a!BE-*BTM$zzJDNdN<2Y&_J5Q%-e=8^^)( zI>W#dyJpz-`@c_xB2e`6ti}m(KkHteLDW(_XwTx(*Q7RMG@*dzZN(qum2=GQ z*>!sO3b*l_uFy}t0i`-3<%8F9gj!XjUhwn;Gh@LJHa5SZv`7oi*U0J@v){U?oLe$L zU1OMj+i7;A3Es`4oka3bJ{6hcK$g8#8+`HAFoqm|j@1G-k(C%O^!pU#u}E{V^QZu0 zm=U5PQ)M`8qPtw2Ooz~8;DqrkF|*mO91gAD@7nO;+}-YAG5$?UG&8I1S00!ZJirmG z_Dq*IxE}zAV1WUOiB_JwOb@H$u0J==)Ko91F$FH;zRFz}M^yQy>$Q4by+6lLHai{n z89;&Sd6$Pf#xzYNQOmp0)$oMmZ+MUfJMWU1-^FmsDgCS1goWHFv zvT!FU%%GLlZ|G1yl;MIP%JEYPy+U1cy-$k$+acQhzHsfB>?tF4GbAi5-7ioiNDt|Q zGQo<_78d$`z4SuouobW$+Q~%sj0|uKBl70nl@fhiMP4{9^uO-eC*z&r@jB&L0MrXS z!^G;_@`_WM+Qqd+TG}$@Zs;TyJApcJ43CvSLsxeu!W8s$w&ZSmJxCB!bRX{xhRPqp zkJc^-IuTPa_Z#KdW@zG8g5)8aS)6C#@K^HBjCQxi$lpxN185ln7m8m~Og+-;mcK2} zQILsXDP~|GGS-oIu|}6SQV^488a53zl(XS<-E2#jd1W{slhH6xA5bi5%CE=(ABvx3 zuZHaD0O=>pIyAmiUt<{iDX$DHlJJC~0Ea<;oPcK+#Wax3>}fbNX4t{6d*H}&FA^c; zVlKd&rFp+(JLN_Ym+9(EjFP9C0gz+)YxgHp$gEme3#_onJi>%W}YDg;%DJF0DBZQp0=bh z`3~2NC5!18lhs5XymItO4CUf%^8XM(Yms{#Mv8?I-)CvpAS5k-oYBI1CAhm;p#W&(A{mkPWX7M7de8NOL%G95V*K#;yK=eVJ~JJOKa1yk7!ebHgF7C`AvMQS8xb3%R*~B7=!eR6^E4cFuSrm zD+irrh{4coXbkciX7J(W4aR%M9~RTPFDHTm1^Z|M!du_G7x&8rt(*^vlKDjFD!V}{5j*N!Z*awX9GhE>% z-CM%r$iRbMcvd)~WCMBb0~!dxn#05&F+eJGd0UfN1p8gn9tQZmq*0!jy;zOS??u2HSzVIwvNVnfw^k%p6q@j&xa8RdVTm1c z0~ZGbGo&qG8;p^LB=Bh2Q}Ym{C$~4p!~@VoUXQ*aq}2Awt*~O28&S)jtvEPg2lc~1 zJ}(XsQ=aqgp zQcWj$DOxGsFWiC5LYjWX1)hc*fSWrxEo5PiLc9SyccFDB*XGK)(rem=r6DqP<4CB) z8fAYHu|lW9iJ;dU1`uR{m+!(^_tlA8@?$_szkM^~4@~-khD53HoX(D3A9!M=wmX`z6ZWY3vnyVf4#}Ys-{0s=s&vaAp(w8t&|5vc;Nwl(~huypf zMCwaWmG>EdcBgnXG)m0g**_f$?KC#twQlqOvvmF|TK&PY_5UkckH_;6UDp)_y7k&v z#9NVm)4H6*pMyHvJC86IUuXvD?}DO(o!qk&hJP;ZO*v?w9=|Vn2}v^|t`b~pc#bhO^=7TLC5=SB)#Fasse7A?zmxH@Rq;5a!?gWHw*;W7k?{QctW z&no>05RA+q=nd8HnyOwoz;qO9L>yB|g9bG9|AU+2vsrCh#rWe%X-3UUqCZIqRDHWP zD$`dJ#x=eJXZ_}+PJLNf?3W)?;^dCH=-52%z=@MP7_-6M?K87c z%QPi1U^2wy`-9e$)WvOA_+nNmWX%l+S3h_4RI3Ku#lrWv2MX0k?X-br9e&h zrcbh?8ez~CDuWVY@I+Cc^B{&(bD&4{%WXW+kSR#daW0Xs$&+OU+36Q5=+kz|XWU}C z?}FX}bjbc(1%B=02rhntva<^w=lM}k7Zw1(`zQGRN9yz62w)Msq#zWULcCuo8+oKp zzx9H2Y-8u6`^sCon)XHY*!V=`biU{?8vTki1LU5=XZM&_$uC5XnISK%2UWxOs7iv)G1X(#y9w(&bqSe%Pt!BsKEmE;6kl`7MR(uk35D~+P}aqOasJJncIMA_72Lq~mE zsNILKXwI#g-`5I(M4oxHaV^b5y6W=?pu6q=y_uAjvzBC!(ueH!at$(+=AYApSjI@* z=aVexd`|5oy_#{i)1qkpN};zB9Z}31YBYu?rrH>xNF%TGds{v?3if%LjauWL1L0sc zpp?nO7R2Z>2KHkb)uS^Eu-T=dKpnHsMS&*)Ojs_3y6JBG{*DQhl>T*u&GQOj0kVP7Q_4=>|OQ{^ukitFo%Sm^L+F zw1YUUmMegWAqh=6`|k*T!k+CKDg!pMm?D;>cS&w2F*@hLQkl4*t&{nPXTkz2!O!;j z;VRmr^SZSB#t}D!uvYQ)8uCb(qKE=^`QfGb}vBNDa+-KG51x)t4WGafm3N(wsg} z+4B_+Wc*zcovn)|b>;h{^zUz!jVkEiPVoaFL64*Hj1SO~VUnj4z~^n#tf1Fgrw!Ux2k^cfM>PuUAGs6Y9bC29NYMtj>Ed`Te?92|K}4qDkXg>{6DTt9y?CC& z;=ZzeL1$vgV8LzI?7n~2+kKXcU!dGO?!lhi>AG`+AdL^E#2>p3LA3b_G!qWtKTrmP zButHRXs+hKKf*RS537pd)4Js*Lw}Zf#1emh!TgEB?)ps>{#OPZ+*8sb_x4%?sr(DP z?##+cu?Q%ZYMn`(YfQ8X)KoKS-zS)8a2p_l}A9aEqS zMOIN=WGYDGnIczL7R# zxy?RQH8Rr>8v%kO;?lE3ERo0WeSE0~pUGDS4==ElJ{hTiI5(@1Hy7l)889L7#yCDc z=!6$y0@Q^!Dk||~I%9zL2}K&p9jdbU9L^pm&M*HRM(qoke?)?~u_=OvI*O z_<|1+n%Gi=85>yi{UAWm!#wx?FYwyS2|#B_N3DUAd|=-l4gfb6yoXjkuzD~ed2jZ zBJ;6(WjF%G9C|LTx@&d4npapNe%HO{J$0g+X;KC^v$KBExHc~9WKU6tVbswfHJtU@UqK?L$RK6 z2-+f5STD2=u_)njKSV==ktVOIAU~-EpLg?`4VK|&^suwQYT+AD(a{{GWaAbh3nol196U0db=>MSXDZkKq4pXe$PaCZO&`vz)ul$+0 z{tMCkms55i4!XUU+dBDnTz+&EndIrTMEe^1Ql3ZZo3DskYOYTn=vRvEiO-(R8{wZ} zN%XmKe%bV;sSv^>Y1Cx$>}*tvJI)}mDDxpP+;`TEd;GLDO6rB2A#fF zGjgnwVpliIpD-Q|WEmdX&mtYTH4Wcggb&V?JTmdJr{NIqtoKnF$b=fpCaRL()e{X2 zG-lHS|1=ZfPb?`vFX+1RZikim`YYD=t`BcZIC||XOI#9mj+DpAUU;ek4W#rO3~gmO zuwuZq#R>;;nL84+mExOFvmQc9HMM7xR!^vWms94-he` zkld=FbO{vOF5PIFbVGi?9FRt%s1O5=qJoF#S{2>}UhCdg9ZUFir2Y9Celol z3fo!y-rMtSq=WJXI0X2cNN&6A597H)Iy~PnLB#eY@VNxQaXYO}V`GB5iB|AgeUazu zh=4naRuJr1^`K%`VS2_J9uQ33=>A#z6`x!jGCaPWSf3pm&eo6*i>Zz_C$JnHN}IgE z9ttn{a&WCU%adzB9HypwN~Eb2p|(|6!n%br4D1^GP%D`;WhmosVtb#EVeG;!F6+^+ zz>xEat^tFizL3l*XITu&J>J7rGw>b)(BAM56p+ABfKq~afujOEYap}VEGoVZNT z9HDy*T16Fm6G=o_*dZu6Uk#-*olb`9V?#CWo(ZH57xRo_J)b&?M{FnXbHHZoD|=Be zhYVT&i$khwz0UtljLzmEZahNJ!YF=IhdL#6lxS}L7G;>PQ=&thN&;%kQ2s$L^8JmG zsJTC>d<8en<`>po}+j{ePNX?STn8Yc&MgSx{W zY}XenahA|2N*42~N?EB{hhoL@G`}#x;%Cdl?&U`$*>G4+$~erB(ma6$GvGgz*cC9& z=IUdgY0k>6ZlY|AT#BSIB>kZKcxb~f6X(U@rBJdkcBsfI)lvU^G@{8g%nKlq)mhO1T=U}dP z+O$MNOQ+*BIx|x|uxC6wKzv2zBv55OVO3*8=${alP<$BNe`(`U$yMt>JTedad!m!c zK*lf!$qL7B*2EnsO+UM%%JQGkxlsqjJO*fRbInjdDhN4yB4FespqKS$FJyIY9{t2X z-(g?}$*R70u#bE{9qjWEtMJs8$I6_K85882?7=`n%RU|xW>EKd(qe!=XnIfh^dY!g z`(NEVPt@YGCkh_O?@x8>Pb&|&SslcedQV@ObJ;ClEt4(fTQ|ToCs794=^RaIOJQ_n|* z)rDflX}D~xw91Xf>9wER+b(D6*w3Z4-$#j#94^B!fb%0qSrWoXffh&pBb9VG}`Pi@GnF)*4Yrhv%v0R;4ako$t=;ntR?RM)!f29JYZf% zHW5l?Owd7EIUcAdqO`zJFH0934Q=3vVQQsv$RHuZs#gc*p5cGE$7l|O1VoW14|+Xe ztLah9T@Sn8d)R<~x{-xFthnhYhinUR=*lwR<$i#KVFDkVB6_VR8f=2Oo2AGmq^kAPMQQs2L48&c6O~( z!=Y~~myR^4B*TS+A}cM42ko~{m07<&oKvbvobD#B3Eo=~;;1qcmSlUcc#$081)74& z5BjT*b4yKO9C{$##)bSB4*m2Rt!lMt!C!f;^L{3?JhtO2k4UK7{H)Lu;RbcBWEYUr zT7!PYkP>J#5Z8!0QyZ296(2HMk6czuYb>70SmsODs~1_muvSES!8KAm zurQSLu_%|2waF?_U7sRZ-CaYw5KWUwcKjfix>6$!^8DYtWsrw>)}8F|49Xy5{)sI5 z9jA4c#sT(iJKHS6;APxwSHOJ+B{&jhl-P zLVfVl6d3lWiPd7{7@WS`wpf2V7-~FL(J$oUpm9LR)Sq^E<@JIM$&6nPChlwISEr;o zpa>Xz{bm#i_`DY$1F_v$BQdkq{W>AY%G)JTDt$yO$-3wA^i1vw(FUiQpHl!X77k$w8XKt zdkI&>ezak+Pf&S2qWZy845X{NGG*OCLpmZ)H5$!M+ZvtXQpeedAyG!Wj)opfB|IL;>s8fll)tAbL+@wzl zO55xip7YoSk{F;q#0ICiY#~-P#Vj3#o^S*>cD@1?wgJ^I`DBe?Q=vYY>N=IDxHCXL z?DcZmIn;<$i)s@~GDRv^%%GIw*W_fcs1fEcEim}7kqstEFHCHvC1{}bR2sgi5aC`< zm3Wk!5pJIMlYNKWUDh>LD;dR0uriql#K?gNn~Y1Jni%`3k|=dHm)FF#QS$=ell5e# zhH_=-hL9n_axg6x@sh93UI$$zSco+$!5a32un@0@`J+QA*GcM1KA7mlk-V{1)tkyJ z%Zae>EN3PFIm?v-fmLuqw=Thu$D!(m#Q^F&sa~~)6h{CIMk*V_mJf^tN=6-Qf_1ky zD$1G)-X)-#uG!xuYVgfX`$*%;q-O_sXl(4S-l^H_0*dKI{~(ZDRqd(e^f}bl{EwQ& zeUkq$CIG^f8Nf7=7o*@44UaerwE!E*M^UXw8wQWe32?mJ$`!6NyUe zs=|H$OlF~65)+FQoy2?;mS5ZbFI7rzpkq*IqF5&}iZ7lA| zioDv)@5J=tX;P}p%nF-cDC+4pG|=29tOH6aC#o5muMGlUjYv$^cY@GM%uEd;Rb5vw zr@s0dUHeDW5$(XW5Q6X2*Dk{X>3u4!ld;-v#b}BYWS{KIaT^Q%S8HD#7F8dui-L4_ zD=iJuLrC|~UDDFsp-4AKNP~2DNlAAo-5t^b0tUw2Gb3NzbG-MQ^PInUm_55@|JGXX zdf&CyUM{Gjea^+E@G`uKsak5XS>25moD;I`B*uQuYXdA#EqvRh0Yl^L)`@%=hM_~*?gv^()WP_qP$zPn36XK`tf#=|kK-Jq!RZ9&}6 z=l%$>E$t%BaX&P3YE71K0EL0*7Ep$J-T?6v>l+Y14}thO%dUw)M$m#d$qo{@`*Si4;r_X%X@*&`r0IxTE^GZP~Go{l8BIA;+?+d77jDG0VM1oB(2}cGAxl2 zc5ErcGFT+!p~xzcRwPA4z(|W($XP6|Q6glfzKfeI^2+a|khtnOkU2K4dH|VYn^6fQ zg^9X#m{c9hO$m{^YfOAvgi(@#>o&GhR_1Z|X7_}GrC7twD)=pJMhXMU$c|mX8Ey+^ zTm7y)j#-LB`I=*#(p*9;awe5caCqr8?kfg-xe;8FNiT+WDh^4jkZ0cD_YDQr2t)ya zmCx2;I$E1Wv##V07tn_Go6o142dd3LP!IS4fJQ&>*9h7{sFuw^at*zUJOJUc(PQOs zKQEu82+#XyfS_Jgl*~`b$@`0gB5Y9~$n%1~r0C-KF;UoF0b_4FxD7n9&ZY_TNLTN;= z@RrvdcD2gKy4>?=_+xWVT`lbHllqTN@GH2y!2dhkKKf_4t@sNeXudh!2WOw=_`q8f zuF2mfpM}&T<6wcIy;LdI-%Y-YlK8t;o$Ax~3?lKy5$X=O5z;WIWak})Bo!sU%U z|8*665zVU*Hq$_mS^KyE0)uHLENIoU(_YfFG+8^HiXc`p*JUh6UPD1i+gxoi$L)d*Sz=o4kG4kCs}^ z@~P(^d~;`&*+Am@6cDA8ip#<%#dyG7O&0-`25k25==7Ss=uxaJ`xnI*&qVaYPhTGH z;$;<*CiN2#F!t~caB^MW$uAN%e^{OF$MV%rtUddBgoP2s(7riKY;CuS><~hW|8{>K zhw*FE`f~j)NGZ#FQBu_1j{A+L+;uXMwRb6d@(BBCOWkK@lB`9q$O}x)rO4qiEopUe z=P*fZQ}_GA%~r$@t2}~sUKJJTl+hM=UT~_z#(ATG?dQy0I+!C;|qEkDKT+E^PPe0PA z;uV6hxOriG$Xm)hydFKOMw?eT!mNMU*ubO2CCHM!fTLo8qK%j(W)jEhb}C3{uv?=v zO3;zU(PZqd9TECE)jkxv8q`qzv!+SopTgbY6B;0JKe`PtsSIl?f`o5%oy99yer9d} zrYEBGNfRC}Kpn;_K$xLS_bcI#bKRY1Z^IFRKrlfHjrz0M&{EvL2v*34X#X`b=%1K) zv@r{G{Mk097mpJ2XXOx*Gws)k92)b^VlvNE+kv^m*>}Ht=Ihe z2ACBv{jqQGSuVf^c>sLZhVku>imjjwkU@ip>%8xfEe*evWsfArL>dI`Yj=^q$Uz*3 zPmfa%q$_+#m$lbOJ1H7Us8WJRWrnd8#m;0Tifo1x?p)?v9aSrw+VkLsUp*{46n-SA z7D}}KFO&X@4|4gc=0$gstgD9GI^{qU)IQqL#sUHuj!!UF4ao8jDm#-kSonOH z9RWJ%^AEjj(nXqnojX`2s%Trpqd931h=X*t{MFYXOMUr9E*J5j zfZCu?!$YxmS{d@DL;WL3>9-OV;XK?);PPRufArXvy^V>Eou62J``=zqaM zK!$Mm3?W)W@4Kp44@XHyK5R=B@-uz%gA3Y#LJingnwqVaR_nJ?Zu)WF#v0t1h#60* zlK4F7IO%&LwZ`MoU{&vZP?q5}v6(tR?=ZAP0xP!+iUR&a(%B)Q;tuqDPyv>#p$iIX zTcS)-dOcU`!Q}b0?mCxK=gbg?si3Aym94~dAT)$DO@k?Yr%Xlz7a}K2AVSxZKo&@` zt5KO5b9L;>VM4y6`Zn=A)Jn=g#W8ms%OjlO|Kf%ynQBKZT?p7+MbcZ|YCIgw59-`% zIVLy-@tnRhwv(w|Zy{27i8gz!R$ZDD*_ye(fb8Ov>;0!LWr}ob71f^Oz+?KM38bH{ zVo>f3cup>ZDb-C7{5r74*n&8ud_9W_Xn78O7x)(9Jw!<5)I|=7tqI@9->^tgFO{{! zNk0KIt1d-nStKvcT(XYiw_WyURxL%%|866 zm^b^cHS(#C^gRGsBNM}-=4WiQub*vYP6I=p;GRO;M|ZcBC@clmFVd)=d{R2y@3{s9 z^9`pzhd&t+D6;LsfkNVcaj^e1yMI}#%Qr}MNv=2wx9~6h2q19%CU9b15C7_exSG2Y z_YkrPQwI8@1w-2({*y|iH{E(+Q*VoR@fw3TI;ZK-mVIXe<<@AQxk@8@1OMZGQdqfqu|6 z9M1iYS&Fes*|9m~Vs@a*k@99n?C-vZ5)@e9h+W|A0mOldA(wSg6+DhbQ1HKw&R>jq z*B!mO^XE5Uq?=o&gkhK6kxJ-YQXp-HGvMLbHn*jZ1HwyF(phW{6Acur0;k%x;{nAI6vz)9hhSorN5^n+hP%T6ChhqS~Uo z2z<4FcaIIQVe(r?*~RBhy)xh2BH+5Z$b9ilK6LSEbF-d<-3Wp$q5OINs*g3PJrnbt z12gUAgw?bZ4g?%k_(FNzDvQW`<97@3A;+`P*Z*l-DH=d0!Q_YCERax3M_c9Y!0E;= zrD2JuTXt)U39GeL*B7t>L0PV<=kpIVh0Ra zau5BV0Ue#wJVZcH$AqreQ6cvSBdlMw!hmK^>D2BrvBS4OC*in?1*DVE29KW5K2_v3 zJy;EC0BEJx$P)T!x8yS_dS=p@uV(6^ckWtqoA4zgS<9#Pc2YsmI)g)Qie zTY=fY85lmd4UNSR?nHB|GR;Cbo?+5q)yDW$epj>WOMF-58sA^UPvr#q9LMB29vwXL ziJ@Zj(I%p<)y1@uWA#Qa^pZ@sy?CQwsAwk06t#aY5uLUnRkdz(aLM~%kx*2eLQPVk z+zTNEA&OJf#O_|t@0#{wz=aIL{B>vQq!^W|)`1QcaOm}z?+b`cmKI0wWH^lF9s=Ly^9sQEwHQ@`J|yWdD@l9@I1<@j1_ z9aS)fAx{`CE)iI+*MC74h2%ts#lZ0k@b|sY`zVS`S#z(0pWKH59pAmZzQ!hvQ>ZkLX$AszFTLWC2W%ZMmChI zMH~C*(eV_nMeD;1W|GwI)Nr3C* zhq_L-qZu*OV9d`RFm$11h0P`GNg}g}8aG(ru|At<50m zLxTjXG&4$?Mj$c|!U7yrQHv#Nlx^qB@T=KC=do&d_g-pA&r@1Q8!_R&>;70PveKf$ zOvGZVKOY&Mx8bhTDyzLWV-Gf~^YHPFt$uiD>77I=+nth%%SjJV6*Evzg?xKMRGnzm z>up$g(IvW^QAzUovq=C)Z+Kw-_`zaYrL`q5sdxE5s)Y!JO7;fkFV_&I1NH6Bv(HRkB7&EjnPf5bn`$_JCa^@a(U#zA zOY153>3SM`j|{O#O2a?Mv)KEpIl}VyeH_oc*wk+{br1Tuc&|-v8N-*IO1k-xelgJ9 z+6|vD5IHfuCl%h}^YB%;yn3Q|_^F~6UC3e2H0@JH@lh4&Y*h`={z(d26Il z_Ih$9OKK5LiB0`;ZhCi$Z$4;c7>IY!m}^wsNYR=68z!9(m@Hla>jD;v*-mCQ^@iW- z0#FI=SR4vUUcjs~6`H&J53KIby8yYGQ;KlF@XO*eMWH({(DOC<3{2M4vhjDy8$TeX zbyo1&d?%6V)S+wyWVFc|jo501|}XSJ+y zW}og4LC~({mU1VTxR*n07rq`+hxYJGPkL11z5CQ$y~&@yprM7Q)6Zc?q7*&i`+_L7 zf(f@ldrNh~uhwsY8-gquKAL6icE>6tWqeI!Fd|-wD~h~4zHZ8)5j!p)FCp0;TPi8T zuv!=qKlz~ zH*Eo?d{Q&-N)b9EGksFONUka8@Bsi_Sw-%r)sl% z(huWM+~CcIgi;!klg*0C&WG4cAD||Dkw(^hu*?sZ3={F9Y#FdpI}p#`3=PVk1c81LtOdgf$4D_?oFa=`ItQ&P4!Fhf+p4p$9TEw5HtzLa z5i1Js85tjg#XD85fwWrdDda56e!ltrfwG#g&blcuqIa7%ARmCh^LC5I zZuk~&6FgL{Bj=i>@Q#p*jLKJ-+Ysera45>XaUWw5pvRO%b)(6dt4Vn+B|Ms?GYn7x zC#Xm*R^`%tsRF8gl~AEE6CyCGeKZ^&AKlrD-3yXtbt?lE#1X#bthsS@BX9SqLqQXz zYLkl__k2bu6Jw&z#Vb}Oi81`+G93xUWcS3%JyURM(2j2Vic?7G(ta~aHCoYl*bJ$& zO&?c#$~!oIB1uF+Ep1%lYaYC+z_CU2%E0@VH?{ClU+)InWQAT}i?=+AwYW%v3z&xa zc|guXzz8|#<TgY*vA>?yn#~Ew=zhyCCugPuMf7d@pubrf!Vmd zUKK0NlkfQ#u(o#(LP)-Cq>B0YC()a?Rb!92YFcn(oG)_7r39mv5m&_IRA)ADc8F&; zjS;u|G``H|Q6J2%B_mwmE1~UCdzjZu;TPpzM*`PneM=QWG7q?8Sn3C;WRU-AkRWS_ z=)W&d{CSs_KJ_rc=N=PcSVd{iUyldw{vb47JGCwQl1ljuUzxa=cYwnd>q2+EE0%|N z)ihjHy@mt4W;l>AJI6xqWDj^;H&`S)oq16X)?3-j#ZJ^@tYz69Cww1k328FeBV0jX zuAw_lWXN5K<$Y-~N2ElWj4QMt?>E;F1+>+hdyWnWH8$|3lb!%a`-duM+N*iEH;~<- z+#C2RTdft<;_bv?{Qfb@^ul&YjL98xBOz~+=H|mgTiuEP9*r97{ICeAj2;d$dtBe% zy}50!Zt>w1?Sr0zfl-CFHeCZQh&lw5-{wjsjBHB?y+f))thpN#qym*=u0_CVHReMj z@~=&qny%4{j>clri*&8bJ_cEk(Wg~*TX>7;n^f}g3vLlf+rKYJ1kcUrXyXu4$G=5` z2&=Fv4Jg6+k(+KJ+#=Fk<|yu{&u;Z?hW#h!+M}}cO6%ELnlV0K>W;9_-E|m=6H|kC za|T)13LTybKQo!x^FSZJWK4-kn=@G@1b8lyzW@TWe5DHq6bSf^5!zg>?(V+{6K!%| zNIK)^Tyjdfdq70P0U|kp2epyrVzVTv_Bv%tW|5IO`-A}vL%(ksq6>ly(%S1*SLF;*@*zcGw{w+9ti<>W9B zGX-1o9C6SS-BpHK07nGmzkgM({4w?Z^P>OPE^OyBn-e)!ZttgqhMrG3HlVkB8f1k) z35HU4-_)5#h6R*f%tqsRW~1;)C@ zno?v4M-<$WF#y2|M^16;DWiW0MpXt`n^{*Athk#tIjoO+d<`seB)RB^T&fI=qtz|O zlw)Pkit1oi)N5QfYdWDgg^pn07l57>Sf4eRDYn(`J)2psciT%hxEaH+X!pm;{Ab=o z;rK18yyKB=Z)tI62WVg5n9{eL7e)0;^+|-2vV{5zA!|)^~9=_*?d{63sKScs^v2DCG%AGrk_&d4J z+8$vv(!4zxiB{akD!X9Nbk7yy_pKH1$FIhwM*tEyCt;Xv9nW-+7R(NZJqYe#w=S9e z^3K80oy=0&P~5STJa6Lt;7=a}1_z<{Lco2@!pc+H)sdKAt1$_JKVP{QlVAiBOA=G$ ztgMx>rIzWY;ayqjN({$K`+M|)LUY|^eNghv{Rp=s=~3x=OpSm$CxYp|rpgpw%B=_u z)uW12bf@}2!lW8P;T$?Hv={_|>16EE{WDYOQ6+2e4w_p88r?>GsyrYtF9hGUVfy6b(>~q5^lP|#Q<0MTbTGWQvYL0{pVc(a9{H?nkM}uC#4}km>UH+ z^KIn-P+BT4;)#uc_mYCE zHf{{hMpq}iM73%HwHyB+U^`qK%xh&TQP2}JyBT%LwYIdNz~2}J?dK6af8L82y(l=j zwyXG$le%Yv@M|YWJ!u?FD;eCn#)DM!5YsbkDTL~5f#U_>!LqIY85aT@5|G>CWdjQG3{**3Wqq`s1x7yQOkDm<-#8tU~Q%| z7vaC(Z`DLOpFN1Bm)GVX_zFMYv0HfSW`yo;jJM-YFOC=PCW*sjG6&hr(y1A&&J72~ zDWFC>gS*WmrYm;lE{o^_MDr~92X1&-F<59#f&7a0-`+@==SAVAE|M;yKNCpu?ynox zJeH*q_@GX!vl4<0UXv=%^kp5}OrbR})Sv7jKw^N|JivrEuRqf-94T@BBK$ev;}vwM z%es;I2!d~Citl71!{+MaB@JNe)8LMJ{}{-ddBoC=;>3!5>14r5;Mt0y8Bc9NW%XF@ zxp!@rnXe)7^q4uP8LDCQCr=IAX;n58!~RH4u={7nbMo=B&=2|k65~nc=v2XdMdIm? zlI>PXcty;dLx*gg14G9?RmK>N>RbdT^WPNg>nt1Y)Zl;CN$p8-zurSpqJ%EB-UdwN z91;JkS?zVdPhg7Y$7ZyNdyVr()6Oy%r*)o2I1Y_3Sed3CUi~oQA?@{(IgANawCO3s z?di({_gT_fpIOH*KHw9?m3?vsr#by?ZAF%9yL=9;9ePz)**{xjfn!d%H!`)PQxF+T zUETLle8I_I4ndb`c7l6vX!7tH7yupeCXvE1!}?nxE`H@?l3&v?uY{vQs?8ggD&1Nt zS#Q@5FSVnsBiWN|KRO&LJVESuT^q$+*WS+g$;#}ERBzcLgI{%bcPPSgh14HeJJuFD zlusppYh&B|Dmh+(6P&3RqnxPu7#NK@wWHUe+ILTqeUu!-Tn9cOm7QG?!P&om0|A;} z3yB_`{m0H|(9SBwTKspVM$dYs8moj(vZJ<{wY+gVi7e~2@!8G|7-JkU^a-(zI!@5E zRyKRipL7^rv#h*ZyI#MloQ1eN(#kcPVPg`k7q#AB@{NZm|NKgfCQT~ITSZ(|aq_%E z`spO?rv)sd@(v9}@IxKFq5`c*ux+_)AH5}2mGkg`_`p!q0PbYD;Y$`Uel%w;j+zIF z_nvgni~(9X^-0eocTohgoGm9Ya+)}2WHl0-i8U$O+*CdXZYz3lF0B9)XUdnStXHQ#u<4P**NAR@w{bA{E+RKfkvOpOaGu zt!HhXSUc+a;;}JiT@XTt$2@y_WBj?Tb65hNUO`cET0_gzWI>9X%fby+KJe8VJKx&f z&>GO<@d8zO>w`{i_45eGydWxgn>{ZvSjgQ?Pqw8~rT$E3rnt2ksI7g9|MkOxcTfKL2ZMIXK zxr$eAzbH1ECa`9Y_cgK5 z(5a5l0UD_BfGX#Dq7FBQI?Y73rnlc?OU^G|u97?-rPM-$5|M$)woqj^pD~k4q0xP% zpej@3w1K2{$aa8NMqN33Whj$ThH5oQ%+g|HoHf5(L*CB(5kheqt){J+P8X*OrHs>& zX_d$E=EtwbW}Lpjcs;8XPNlSgV8ip_nq{>H6X9?5t{tKC9n-h9dQTg#QN%P_aimj+9O}K%bmD9)@!%yb6{5msU`VPu z6-N|j(mS@1A8g368afxOXMCwra->iE3<|z-@NUN9R@B-Ur#$nZdRv)>l9B+Osuyd^ zl*($YCJ_2crKM03-NCib{YG9lAzy^`$|5`2j(HRzPRE$YYQk2=SY;mRK0u! zyj&qrhIs=qbNK~aG#S2-TYWIqDYigdK8sz5k9~~O<PUynA275PMXVyX5eBIu@vF$W>6A7K4kL#H|PhYUo*KPPYYC@$&5U+jtTzp+`8;%QF1>k&G(;>?gd*( z)K1_XC)FjuXuTbmO!eFNSXyz36xM*b zf0kj}iF?w1y<`h=Aija0?qf_qYy3V+W9(NEU5r+w`!(@9uxpnEb;y%=qZj)-$Sp$G zrI5j@vp*tO4#*@W>P-ntgvD~X@5&vCs->a&i#`kG*v}x|ha{N>K+z?}2@z8nM*Jv_ z5`|H_mq|y@rw{MIu^+Hs)aGT-qbi+Hh2kOQ3A$OC#vuW;J6u-?O~~UsLy0*)?465+ zV$8rS?)L8&qvihaoQoh@&BxaF#eKW#$7x~6F%17_Y~kA%4^n6{LCEJf_@ltrra?|* z@yS1G$sVNmFiqyj?fihGnNHo%R0WXVAE*qTeLJe|^g0(G6yT~1;>Oy%ArK;vj^)L3 zFnXvuRM-sBnAymn@q1EAhrzII!!;5Pz%^(`30}R2fu-><`H} zof53Fo`uWXkHe~Q14bp8FXgg8$gM!(E3mn1_;usg&9ZtPc;L0C*sUPghbXT#zlt5z z0Uu7od@$`l}%TpxG%Q z{7TVTd%NDN$6?BG491E>X%0TYzTp-A6^iL2@}6StTNm5p_f?j;6ahLnq!{Jc4*JY7ss|uoG*8_2` z@D$mE*9<5X(0J$tAJMrinY*MBIQ8m2v1~jz?iTPm-}O8#y0k#7k|LtK-XxQ{?-yOP z>l`g2;AxF9Sjfglz0J>P*PnHOb{i3%H8vj(mSc!wfdUArxzj>{LpWmT_~LZ;OepoD z9TDiYApj53Ilq9?88$GUE$UFpJZfA!ZbZ~JY|46edR@+C_y)y=>BV7%F{ba11e;*? zYu5!GS%mOTQl*f`&FIGoek_Na$&dRz6wFmInYUdYQ&1VTe#K^Rk5N;<8*dO|)K&Tk z9=WDA{mDM)=JzOJV346h{&dZ4v z>hI&U(oug1<;nNz%fMH+(K#9pG;CJT9zP3cZ*PB3;Cw2twK4+X^UtSjU8aiRx(SO} z5_B^{-wZDEnzvUjEoBLo1p>~OJu`gvJfGtvbYpWqA#T|8I$P3#ZZ;ewTf?;&e$5y*91IaDjqYt@H6YnbOA{AMS0`eExNSvdG)5`;gz>a*%vI>{0~f6SCvkZ z@|SOM8S?S_hxIekO`%x4%}0>OgbbZm%UAcQjnE%Uy0b_pQSqvWj1&(_c5#1X&v#y| zDR^5Z)r%9$nn&MYAFvu~`o+e61V@fa5 z)T#ZBSFJ?dmCwru*uvzJh#V=g+x${TD$;yf^9s4xo-1RX-71%rUMF!Up&(>I+s~j4_(3O*}%T_th#%GCUYs^*vQQPgc&idcb|c3GRR@j0NeM*Y|69>Fl-aAEg`@Q4?S8k)A8`Hy+hC>^CBo z8~5($(953pd(Jk(SLXITQsLO1`p$PqNG^B!PtUz}@V%<1W1u3W@KJ$tJ$vx|9YEok zu)(n72l{Lq{zw&XVlof`B)Lsc`c)y;pc*4B)?%s)pRF#{C;r#GR9*6}2F4~K?qvgR zM0RDgV3$dwEd5pO9L7q!jRi5&-;K=;b+}y5p54l5doplz12Dgn(R@C3fr%$@QR%sS z(74P2kKA>JNqNrYr5@)s!k|+EC-{vgajj+S2S};1_E_P7(=;A?A?gr&c>)KY`mdzB zL1!gvFnQ^QiH5GQ710I*73YhPLzyLA>5?z@yi&u!RsQ10*QBvDfvS?$<<)i++9Adz ziGH&Rwwz5`wN!~tnGMqkUcRmK9ZX=Jk0TwgR$kiV39E_Zf|w~t0b97gghjAUr`vCJ z|29w@WdR=!E;@JeLL!>?9Kwg&bAQcKTMj*<|I9WO9(Hla(YQW^Xu)@fIb8-J78@n+ z;qIIOv+X?G&ua^k!xq9bSJjKPg#9CC&Cn^5)kZb*U*FFiYGY<=E4U z7qj?JTP0z|%1cRJl49h$^bqu^u0l*$HQkHHNYgM1gMk$FL#kmo2H_ML?dwuN$F`FF zLqM@Wh6r_@!OAF=vlk`K6~IXake)`6!Y2^3DwlOmh#&YKi$z|8PF@=mMQ~yPh>7QN z_Jx$r$&lAz(dC8prB2JK-`trA|L&T{>D=X%7Y~)9?=5Zv8VfF$q3v=0I^x8j7ah5l zr1_Agj$F?+E)V5G0#B{}ILT$$MghTAkFdtjpnuHdOp!!Q;$t$9mlWIg?9Q-?`q6z)<9q>lNY9$|xXe=JeKd~Ei>pSpMB=ASr<$BoVz79+W5yE)U z&wq@6xtamI_F9Vb+_LZ*!bI$0WWOt(4ttUcCv7;-Gp zhzS75#;ZX-UkqTv2U6i>bBO1S@MHI>UFTz21VrF~1F<^yngeMabxDb6u4sVn+JD0a zZh(>I9uNw+qCNnzcOc~NcNG5v5>W#}^?E(-e6UpHxi!*07lH__9Og{UbzMFQBBVD6 zHU4tyQdIFnV_y4*5ay@jv{OBf%`pGMC-$%?eJ*mX_Jv-TwvXdueS=FBbzFV}u zg2=7QOtqn|N@S~&+_{hKaRAro-@V233QO`%;Yv| zeDTd{8!R z*_O08ns{M9x{Oxhf|=5K z*e$XQNMAswgZuWeD4yGvqe8 zeTxXUKpQ+xkUJ}$dk_x|5f@bZ94!X($zoP}wq#7z9IlYVJ_FR1A@z;wQ4`3=HnqCv z3&x-19Y3GzsOAsTo~KAO@p~okn;C5k7VPie0Mr>LF%lm>=t;68I8&=j-t^ZwKe!Rd z8PnRXYeFp;o;P7g8jxqv9oV{5M0HnkkT>F-t+Qz<Ql|U0gmUk{E zW;fnt1AZ#^6N!MvD=lYw6$wne@_XWupOB8i6ibT1$tlU{Uq<=5N7rP)`sCVaO@C?if)dV8m4!nni1CKF3?x~J51FG(^ z%yB1C-(;X9jwJ|y7BpMj{{00?gTn_^6=2)aQkgSsqqXd^7WLkT3<1`+YDXgPF$bjR zOmPz#aq~mv8MNFPYA;&FojMxMd5uu5>)@~U9mQ3>#**}Ty;M9XW<416HnEAn&Jz?G z_6UkW>0CIA_X4Z;hlrn2zAkh#o+ycy=Kdxlt3+p`cs4kMF<~=@^qg$4L(fLZK#F!k+V`ifweTv3!y=B(-)@tbv|POj-vQ{g9Bf z{=_~?G}f(HDZI5H-$=i3A4De$YDw@5G~ysq5hzmQe8Ft1uH2h-?hgXIOSCzx1ZMJe zE9rwcwE5jur`#kSe3{E`VSIRZQBRItn;j~x+MNIrUvpl1!}HiWyFd4|xM(*v`kA<^ zFl%Bw>)^qfwQ%Ju#z)?j%)R+H`lZg;)yhZ95MFz}afY!q^BwBxA;^9GZ*^~^lj}qe zP9*)zAi5-8bol*ID-LlOT^4w`_fNkO@aHgYmemAEjy248J*Iq}T(X+;YkFIiz-m5x zdl1KyxK})!D%elTQzG2gyJMyB=kPIm+&3Te9qZzS)e_2D@+`w`Q+KkW?O60Ya$Bkb zOX=n?D)pTMWj>@Aq~j0Lxi~l*7NSfgwK*4t%-~)OeJUw^0~1+cpl7Uou&M5;^kTLY zqchaIKy45A>|6A-O>OjGzIng>*VM85vD}|N9%CR4701G`HE~OMY;sasSnW=-x0Vd{ zld8mffo8nYukFpC9yvh~Af~f}$t{O9CVDJ{k7FsA{>Q#>4y>v|aesKo5V!p6nkl51 zUB!#TImqE~hs{yXYC=#)Cqz(F&bh|iqAS6#K`el*bz|U+2`bI z-rb(plzunhiiaE;>A^c|eL6+z7!w(Beq3AP$^%*Ds^k~+W9Uu_Me<~6sU2=X&qoi| zsw;hir`6=&_2*`9#;-SJ?!2!)tKA-&u+*u`TVj0Xw15sNE+<I(&u-<4SAU(pfs7SQ`+l+});0(|9VI)%fh_Diz-)x!6+3ssMC|qt zoHqGa45F#&rqW*O^eRVcLdXy4GtC3L>@XRI=@iFo3XiOgL1oX2qjQt|STckf$y^GZ zm5S5|l%CQWk#2C~5z!0<`M3mB<4jYtX~VTq)Mnj8MSA2d>r`SicZpj)@c3E} z9nTAz6;|0iR39&t6dNEFvu%!>H`D8xc))pps5AW*0dlT1mjyoWK~-L+zU@CkZ+w>? zkGSSC_TzCsuRl2r&fJmZ95q7tI!c1`@3@F4I1ND;f9D)cDJ9LGPKKdjBzJXF6GZB3 z>jAwF^^b?ok!-FbydfRPu#lTBA>@hWG8Af?7KQExHc#h{iwd^>mV3&LKZByD>NWc* z+-+Nj3Aarf0B~M>OHS-<=S-WNVa^9uC0`O~-cFW$tHlWRaO#&Aj0<|@n#V4M*$rJ$ z_}1|lE<@?gv1moh#jjYL(DX^_3{YS0tz7b2XR(`p)pqEvF*zJGJF4-pve@-jfjaG4 zGBcyGU!w6>E%FO|bl3rV5hnn!7C(gd>hhIv|7>4P{mu=wi#rke@+u` ztmeOvY>c0+s%4aymVB9}G0rrD^eECFJd4AyN~xT4`L$fR zGEs!xuJ-20$AZ3WOEx~kKZmY-_ImzWu_yD)?oqjqJ=+bzO|wa}mUjAyuBHy38*NP> z1HMwJ9H()znwyS(hDT&#NkXZGiB>^3K*+@q z5YzG_O&p58?Sm#&p$szn!35@->aw$B?jvTf+^|AJ8e-bg)=FUUtu`>A34rvf!huZf zd4~dDY{yj|BJU~w(^#G@cp(pIwsqUTQgX_0uTvra-om(w^L_UmEEEXKxMu!G!H#ej z$~#vSzgVYyv!8kicG2P~>ZPUBmm++4n!qe^Sx~K2 zb{uNh-(tw49OHF9;aBypP9#r;jK1`!wPTb&TARIH=O$o_c>4?^^`wO+a)gXFE(RDA z)8p*8*+kr98u%u3f7XSSqD)__^IE=6sxM^ZjQXwe(Jf;3)YKD~X}1M>AD+kF52ZH=NYZm$-~9cuahSC-VY|X5~wLYBS^0B1x>Ae;sXH-PT^+k*>iM&clGI7 zI%eg9_BrBR%HUU+ws7)sPYU_|jkZUjustdF_e9hU?W2KB$Q%t!l%OXll-m&3eV$S|=m zsdH?af@LdjpOdqf-B*UMGrz`%`2Fz9Y^J|dwN^a|!#(caQ&T3fp{c_wLi*FUuQkYt ziddWHN+tJP)34R2;o8i&y{f(Bjr>Wa87E)lhVgaE1={T~S)84V zG2*u_`kDwYQ(Xi_K)J}agDy4ocSggTfTY0RipF|BSo)~5_v9?_2UoSqd~CPH8pGI% zQflD6VHIR>|K`;w(FGYk0^5W<;EUbe#6}<$|1m^`+gnS72Va7eTgY$EE9n8l^8ce~ z%~&Hx&>uB4t1@uftQXdvk@Cz6O5K&`D90nCl}39Azkyz>rWv~}<(%#8QK|ap!J!Pc zro^AxBFSeXwm!wbZO`4`<wJ7F4%9;7s;-%4ex)e-B`@YdV%HCeJ`e{EY4s z^zDcbTl^qaI?=ak3Ps19WeYCJdwGush39PPhm)l4L=^>-x@}0*nh+WKxw*``+kdZ8 zZ^QCnOOM9wE*Qbn6;)!_Q8~|2bf^h(O{<`!abm#7c*yV&|*3h6j(GZixA z@O0Wb+)vvdBg!u`6l>8V9+`?*jt{&iT1a1Ln4qMo0=nNzg^U!uyV`mrbUrwf;a*<3 zc#UFela*f1DOTB<-MLt*ys*6?=U71%nky<_+--LAwo_T|*FOHs&)Kw9itPckSVPXY z?`=wcDDtpTv9uZM<$rx|e5*M#3qO51Bp)igInlM=ryue<^1kR=mokpqI+6Oq!!Fk` zaN@^}V+_Fj?6uu^OGSJbK7!eGq~Yuu%id?R<*$>2w#)==O`mkSZH=bRPd(mbx#J36 zjCMy0l^P7H$OYTGTdloa5=((*Z0O_;`BwAblI72oVCh(H?Q3zIKWSY&*z(DotS8cx zHaRl=qUX3@KK5RS`9<>+S6e#eBy+k|+lE_gBcmNvpB?9rp&=w@ABcB3g7xscw%F+} z+JoxLN)4Q(P1Et!I0cYNuf()#wWEUogtW_u=}7Bb(ry5DNUmGKGOsdS(`f%u0spdw zE9T&ZDunJF{Ks-9q8{Pt`DWh1*>}(F{*eGixC^$++31pI0olAtXVHtBfI7UNn=H>Q zE>=2j*a-AE1~^@!zPZbaXit>Pq#>`TsY;@$H%F@DPrV)dgWV>q=E#;Bn;T+QzAapg~c7)fYFxqD|*AjU9rYd=YB z50a9kWW^dm`-Fj^re%R7y%BiG{rPxU=S7Q(G=g}I4({vlujkeHDEuNvnAg-W*3d6%=RTvsi-?`l?d{(hm8h|DHwlz`huz2*kCYOmn!5a9 zoc67cdRY7a(l^P`(Lxe{ZvRise@48T9J(_`6!|ThO68sdJ6rRLi`Qk>lvJOfiVYu! z{QbiS!Ky8iCX}bMW=8`P<0Q~pm*~&<<|a#KksB&Zd=rzd4BJTaHo!;ro6Afmg9zvX zGV}ElMuwxiSr8X7m6+Tyr<&G4iaXW3C#c>|K&j^wBv8!97Q3*N)gAHOPrr2vKzR+? z8WJeST#7Of&}$SE?&4s3kcN8#J;SEpY+Cuu^Pl~i|vZYlYR950n z?EhwFpS)pJ>Adi=$DIg23jNcZyCkp7M_H;|xzapg zwcjw3|JI))wwr)=KS2aZ27(2q3GprsT8T?aPsRcVL>c#qj!$!M0KSu7TaMaD;Bo)v zbK)+PT^h1?NE+&Xy;Ngy*QsO1>)pJjp64R}jcNN!v;GU7`RdB$+QPrm&-+(lDc#2Z z>-zr|8`-S*`(0Spj7zChJ zgsLh3%3T6H$hvZm0Pn6HroZ!!M}3%=^O&Cf$L{^B6^{XXhsf~V7BS>_bf2Sq1n@2! z<-bW=A~QAG{QLyS`W?yHf(W&viOHx z=mvw{XObVl0wQKzX60p~CNnbe+jt zMaM5_XsrC6f7a>D9AnQH*iACn_?%kgW#eK(4+F`lewQBQYPQik$g4lG@5CHlT3TYZ zC#ub`cl?aWVmtre{gw7C;u-ZJkGXm*wU4PqYR<%sN z`M~DG(z5K)1vQ#`EZfsXNBid1GVSuER5o$$bW>?_m~>g6C!Md}MNOGkl5ycy>ST={ z{?mBlrz}Q7UG=2E1y3E}r*VaX4B7>fW~<-C8;fT{+q!(ZN5DV2yJGadB4|CjUP}ZV z9y6GO`8=o=mHozewmlqUW?%vgBaUG=_hp5cdP^hyo%{zF1e44PokU4e~OsT*?N}(!?SMkI%0+mSU|1O4@dJbrv$AeeTSHDlUR6iLBd<5IRm~_Et~0* z16S;v?%I)1UUE*0?@R{hJRlaqJmn)LB0~B4W-Q zrOX&`cZnwTaW+~RT2pm0Dx@lu%8Fle+rc|6n2j-$Kkb?OX8QH>FeaKa^Onfx<~<@1 zWv{^E#kT$`c$7a(-%+nvU3xa1HbmCYB6$&6##C~WS?ghVNOc(7diZNtRqaNn$D0xQ zIQlC>0Yaw}Z?np}vjnlT=vQ3NS=Vm*Jg|lJLuOrN;|el_$`ocX+6>Q%`;~HK!qqDdg>25ni#z zG~fuUpskpfReZgAG3V$K(mBzKF9B5s(*w&~oA*-EJea<7##`l!0Tq-nQO+0M+UH5B z=yA467EWYyq4>6Df}^&pU_u7sS7V^%{=+ba)xvhrw_tNgsw zFOsQrH3)qv`8h({eTL33w7q>_M_fv-TY^g!3j3gme3dTN6k*b5 zCug#;bmAx;rwL(bJCX#qRb5Ni3Q}o#67xG2t+~`}k~FgUiqW02b(y7$CxSAkT>S&@ zee9b}()i&nne2Hc1Efek_#XT;4mKL?TxmwvZDD+(cRn;u+)JiRJ#MU%yua(-)#$$68aQntbz4IcX(cFAIH+cMCO=bXB1 z$Nk23{NjYg9%zK0MdBN+i3-}gwUl}@1wR3*Nz<%!t5?BEFI{P3DgF(o;%N3TWc#c= zLVYmvUbFZbk)or@!i!y1L9BdnYTuK^RrK|5&&h{;)!6V&8=8)kEAINEm2ALb*Mf&f z62-9n`?A}pk+!XmJV|=zRI-L&Nf;M z4e&p+gveY#-TC>f0TTiGU7wPvw8(i*$Y*3|08q@aqr!c$sB;k<1(oFt&FRaG%{ZhK zg_$+XtDJo)NlGJO^4g2_oHSSR-pUWpB|@a}6jN+l&Suyy3}V~Sh?Mr0@300s(u$Jp z&O^fP72iV+*(^O6lvZ;StKOS9u3@=o$C>5hNi0W$o9C_26qkfDU}P(lzThd z!0E?qw`F=KO`C5+#cFVcUA}PGy_W280vp+n8RGOhXD78|4dP@4+k6chOH}n~E4I$&)*Q2k<)c0J*Qy=bXPh&G|Kp|4rbnU^l zbYL{UU`Z6n(}to$KI568IZIb_e7TmE;=Z7gWup1V4Z-xQ#eI={v6u?rwD|Pe8`W)tAL%i3vIGlRm67=@~=UFku>5FIiJp^BE@(|6LQ~ zB7#|xzO9IN3|gpo-DRY;zu+zylF=TtOIt@LPT=j6^lBP=Zl)Eu+ z{%eJ^BBG@;eU8Z3gc@@icdhuy=q^UJbqB(0Qa0`@-fKwxRIfkm*x2XWqG(kgYUa3E zJ!0$B?SVg_%#xKMB*Dls%J!U-KdkS?53~@P4TjykLNxF>nVt|AF6~EG>c;DDo~o z3BWvPL09zwtb3j}#*--TuU7ek#PN~&$@^kt-+AkFkOCg)&1FSROhQ7koGK<65Eph< znG%C!-yW>;YZJjLkVTSpk}{nXCzAThxG<{ODW~Snq7IL`=pt?21A)-euV-Sc(_vNL zLfxItHl~SxtwZRPI11m3R!(j1@utVJv)Cie9*2bOMwvcuW9BN(T|q0$D$A>kMi*S} zM?DfK8uC@Rbw(eJj@vgIhE&#eu2mhma+(s{U*+T!IZ*Xe$%t=z(K=ER&qH5^RoxDD zAxfFzFx-o01nVye9&|MuHN3IH)p2!&a=oE)(^KiINbtn0m48p9mdnw7kiT1}gxc~9 zD`vNb#?{>&j}fSh)&!NYsR&!eOG0x!V`^Qr(+6cvJ*LNZDg99En3b=M1xuZcLX42_ z#6LrX+Q(%2#(>=TLH8G}-I+_jVP%F*9xh?u8p;C`W2N+#i2=KBAuCd z_ltC1^kzF&chD;hwQM-_r;T{mdP^rOel7d*2>-FZ&qMp=&~Dh6PiC|?nLvCK;~AU$ zmlZ3e;TT+sBKCN?KHaQHitY(AllYY0cbaW^8zolP>W>tsrCe~+K~3bVw7 zQcVnN^WNX|36;I?Dw}jP&KN6?r4>s@+^5QaZ7q?HTduFqdO*D!WN#Y7c4tl9wd{HC zNz)5c>IttKdV|LSIvfga+s7+HQBuOX>Gpu z$PW5xWz4hC&a)Ky~f5! z(9=|dhd>*w-$<6xto8j3Dih`v<&Z!k+yC+&32;7j0XG1JuX%$2x-3_cs0rCKNWB~u z5#yxbUK=7r(w4ghQSW~(=S%MC)|cE&1P8aS02hg_$oin*_aI%S)obJP3m9)fzU%g2 z{x$t}YE?#WJTcy6ie?E7xZnKv;i-jzBF-IW_hh}naH^3;8y_|=4;ohkf&`z1;6D?jfqHLo6= zqeBKXgNP;cfAHTtyEUVqVm+(XN95D)zE;h^UMNt+tJ$#qwqD7bbS@Y-!x{;Qq+U@1 z6AkLQdncoWB_jp9iNhg7eg$ZKnxiP|nYhF6`14aco^eEcoHJHQ&xyj$D}7i=ru>W% zoJ-|ZY>8QG%;;vC7c3x`fN+i^&!HG>~6z-?rFs{3#Kp)Cla{#CnUNDiT;qV}_D6qio~R znq)Mm$tInDR6TWptmz2FNED|-Su<^GJCdm#5m0YrC&V%iKBS$f;6wK}?ftNE3rd;x z#K<7xQ@r7nMOrhX+sT*XzCF1d-A_h`sNE1NHsaUyyPr{=_Z-_ z?WSH8v)!tmugl^_8x7Z>vj^bT;QFL*71oe_HRZPx3LT7Ml_9g$oNurpjAG0v+UwpL zWwRUI?2beZLn9dIGaL^ZDz7R$RG;l4nv8VXbK?A5gLj;+83fX#7E%)Xf;hQmo*DfMa%?{{zdr}R~`zlqvmtc@Si zS#3Ae*E3IU9Y{8fVQ<2 zXRSWuAVbKtP-S;nhq1UF-@(YTXG&^h^tkuVl*wk(YGtd^?1-LEAblP!0mD%C0>5*C zOxO14Xm{@*j`D;^O?F>X!A;dr=(%;PWsNx>GAv*fRQhg2D;JD1rC~j2!F0`7g`0>} zVt{<@QUQY8PaS-%pWs-aKSU5l;2o%6BpA9a2KbY$)9!9Pc;Gq17+z*)($yG^?_X)e ziaQO8Fc0pbMUuAiq+!I}#9jN597oELH&fK+rH6$umHI88bM6t*kE5fEcB~?^&1Z$K z`xz^P!1m$uImW4?_O0tWkj>iRsmG7vCawOO4}Khw95~wU8c~zYKVjQua27id;zT+m z25vLf^eRSZ0DohFQKk@Td|Ia+l5LshBVl66?9W%oVv>m~h+s>9wiL41To&VK|tu16P zLJ2%qta=w2vBmh!=?ck+!L6tnK0p2f@z6wxfPes$)3pfj!pc%}8GaF1#HqT^b#HIy z4Xl5$BYm&Ruil-$$-L1u;<9J|QJ7PGFC?NGezt8JU7ByR1U0I$G3%o_fxjR7!+tC? zd`RZ?pAbi*Nurpg;^jGZ9vz3SxF!zmZ?pyvpPjRHVCOKP<}NHuu+R|Gb51{7Tu9=3 zNBDbft0F;iX`jDZJ!qK~=N4WPIeTsPu*3}&OilUZ;qEFARaI{Ic~B~Y%2PfQsaR6` zD*yJa5T`_=;Qr_GBqN2xNA=*T2)R8dRE=I>Hq+gS)#2sEd*`A;VsWP#b==?{1!0w% zf+o9#tU&bGIc<$lmPFzYJJ4oF0Y#zgCzoyb6dLDpuIhUB_n!YnESk{CX6NL%tL`e$ zdmXY@2er~GiPLfwZYmKnQ(P6vG?~Xe_jkQn&Ei^%a~}>i4vGc?^VWCo)+Tc&Jbs{I ztI>JqE`3$Smq!OeZ<+K%r){g>M`kXg&_@$htLW1m%Lfs_Zvm5=i18 zPD$O6Tv96XPyutX>iE~;Y)sl0GiUpN#E1fVe+)38R^ll`3GA5XUxqY2yNVG zOwZ417B1meoy$20M2eMGrsW@4DOf@~aVX4D+ZYM*(PNI{(G1o=!bWW_Ho{=iP zn@gcHYP4BhN`?qkTgm*8@fxcBQLyjLa#v=^vEiv++`lsU`@UB1=l^0MA2?M>X+iIk zlOAUCXITqipdbudjqYvlZbXqZV;tSCxcQ6dAeGvNUpzobIiuOqM(5tZrv>@n_#O^) zy79N4_P@RFi}_F7&M=QN1$^R#ko6>4>#b$xMC?F;#=6-*AX0uyA%$kmmw+^}}1g$%d4_P3X)sn65<&;O3Y-tTA#7Rq_a*Ijxzc{h^8zzsxd0r@d-lrVT~f>>5Gd;8_BL&?FwL5 zA=@k*Gm=xo-C#|J9&r?l5vbZQm+SXjw663|<1fy?S5%S7ROcahogo37aEcQd<$~-lH?RLcQGDYBoGv^KM#$}Y~IZX-AC1CsFJ6n)uT#}`|QNP z_hD|f^m#J~VLD^n5c_9;lpwmkEgce#)Q`eCnjYoSWa$S$_I%mW=a)M$+I&IrPBjYx zPw~%nb6zOssYSq~IAZZDjvi-rn_TiB=4pk!qP`f&(dZ-~V@2t#W^1+>oWM@$Z5Mjt zjb2$yrg*2ScqvX;sm)aCsr}zODBd13gz-ZH{L0_mc%w#~YbRjMc=yoBniqMFcKXd?da)}4W_W4F^y60;* zZUnv6w@pmb^C$Jw>Ypny-v&<};nomD#d&@hQt3XLXEWFK!_jQWB&~ZbZJS(=p#e{6 zWbsc__U|p7FGuV>jD3i9#_f|`amN{1EXXhJJibF?7>^Wy#!p2ne*{2@`;Z7>5&6lT zp}Xl>%aB}Xw>VtG_sqif)LFXEFwWbXG20Sxnqlfiml{BG@vv?jHOOi*5`W1hR~nxYo!@2?H5b}yl~eF(#TEE zxBF7YZt~X78K>~kRwY=4e#(MuN7^CuZxOJCJXzHB$j3Kx+rTD9!shOSUgzTy5RWxW zA=CI?_aBb-4}B}2s(Q3_BukUL0aEClpZPE-$pxiseVP zaQ#;cWWd4C8_P)OD6i&E_m73_666bX_I!wCG zF6dKxvUiozA*tGA_$rpn?JLW9y&V?fD8IG(m)4GrRZ%Y>ofsYy+&bkyqZOv35HlM_EIuzHYA zB}eey5IX)4kI$!n9TVsZZ8Ezu&tg{vc6L+{-E}R!ZfoMZ+12In)pe49Z+!zkg4!ox zD~zzD$|X`NY* zYEaZybzjHHtDVwCdm3xx!b7O!e*fU-xdBA+VmVdD6o3C#n!TwX3gf1hly!xvOZ&X| z6(asD#*akC(UiH@PZOc=G=Zu-Y~D6t^RRMHlzXAjxS^Ct-xrV98WD(05x2v$I6RRN zVQV0^j%J?k)Lj=IIY;JNlveyJ0eVQq_+5=5Z+zk@bg)pe;;LL3*1THVEcWzhAg4l~ zWQ|8o!SZ7Wn))O&C)S_WXLw31Oq3snQ}bP>?}GyAkW-GoA3_y+I5E<^gRHOlwMYz9 z#C<4`;;tYNz`69#=3iyei2MKtSCRE=ytoSd|B2lHMw#Z{?$@s)K33?z3EfW#ssV)` zGXcKG1d2Tby!F36M-XC7%n#2A4z&>l^<{G)lLP2&)YnGxH`bv1p=7^1_agqO#r(H`Gnq)v&e&nUUNSx_EKJQQTyTaIihs&-d<}b`~I?&+>t%DWTIt+(% zTi2Zw+s@h{1u0Ym(OoH7Tp31m5T%|$(63YB#6fyRro5hj_qFQ}{Ivz#)_e@~e{dRj z5sV>&biZ<%ni|~eInUdm;3k=)ada6)%=T}ybRozYV$OLUtxgrWp06_tK$I$vS2P^X zy>?H9Tt!dsNpvHN@|W`AdYaaMcE-*Y@>%fJo0%scJp4hX46UJ*%zCLWJo<~{*T%Li zSqx5@1Nu!j!<^<^3U}I%_2UmkvcE1bIqa)c#N3YXRYZM=L)b>d+98=akypAkS21Yls1UgDPEPvBW zMR6T?{G(+ozTs|#AXKqBc6Kw*(}Cj~FDR)zOtkr3C6{tGragPa0|w6wbOy7qlAscF zkSB!th|bUBGma333GI(v3e()S=02 zi#*s=p~4Nc65rKyC2}(_!yk%b(P7x0O1UY`s%I!}5%n$ywUvWS|ZbXvRgFd9ZHNf-TFAq?xc+aLV-TAYE8(~%9Ak~vQov$+3 zyQh;zuSYnm?Nyc4ELjRSnlb@dw@2`o_P3nCBjR(ex<8i^ef*Dn2yvr+MD`pG)ITpu z=nZY=_Wd30I%D3RiuT!LOnlJ5UTnPtn-Eb~OFVRJ)JhBezy#0Mb~N%~u|%fhG3_&J zrMfrqQvG|`@|9N~t5lc}6-u^$ozxGRBc-z%Qrcv8Ti2XU+POoV#X&f-OZfLDQWCo& zW4V4854l43Fnr|`biN}*Gg_V3JVMTxzcqoRi1P)?llC@!-xJ01=v-ztGSv}_)@zM! zd&{9#rFRd2wdVrn)trPD9D^Fz^KC+CsCSIm?WA2?KXH0Wgf_FwtT zpEz|Vvsp}8!mC;T(eFIxAN;Bzcn^~M*D%q9;{R_1Y@*onxPf#3DeumpHh-+HwXFTV z%FTpopy^g znb}Ul`rAd?b>an$I`7`T-|&7)lfq{YZt}KxWxJTwbmt$sbxoeGV)||rkOv>}AruBz z+zA`~zvNEaEh=Z)W-)z0wXm=SpDINO5h+Q#mYS7@2iZN<3*?S-c2b?tG+orb&GJV- z&u0SZI1)N=!p9yFuh2#pZdd9&sUk8tE3Y$yH~Ygt0{8w3gH5n{RbL&G`(>B?ucG;j zaEweLeo-H@*lC!SEfnmc2!m)y>DTF#XFO}|Rs@*pQkDP zFn#Kx1bHg#esE4~sjh zUyCD;Y&Ls!FgT_*XxprZbSQlZ!}(!!jD_>1QQ}SA&{kSm2{AG{WhP)$y>S_ea+`w0}Ts0|{ab^u&TocK4+8{=Z7DJRIt^4Rr$hO!=ojIoWSQmDojHH2he8b-1&6ETQFM1vV)DMZH(3_0Dzu zX685V-0%I|_x(J0*wWou#yqGcrcNY8A$p%?a311FYA!pMG+ru%?Gs|~#6?ti-xDB| zhdzmj#=1OXDIRi5$9L0}8e|WYCBqzq=5|wEA=>4E2BMS#xpO>CSyJr#LPGevLONm( zB#1GmQx?&}x-{kbPT6tk%xFC_RM$=e)*c>5)5;LWp553+p*Q29X(o}mFKXLkPqd{m ztap`NLQ)=x!82@)n67p@g}VhsVxXW9JnZm(=bI1K+Xb`ngB!#Km=q{5Z3pFSw_Hkr zmUJ{gtb;Fu?i5XV&ljY1?xnX7sxkL@CRcM*SQb-@7RDJ=JKe4r!}LIEOsbuD;U%v> z;n+>$MV{^?Y4wd}d`V9f6eVVj$I6-7Hw%fX=!bb(c+|BR549^c93f*R6pYUKe7h330)C?16#DRF# z+N}hvX81PJ*j80KUSmPgr?iUVCTPzV0&(VUZYXwNqFw`4wFfyP6lx=)GFLZpLXXYQ=GM_qXnU8B0=oa8@` zNo6VdZdrE89=YZ=&rAXb{e+I+AVfzuq)!T~^F1>4!pmP{8MZIj>(5GnX)zQlL|)xF zJ;XJC+SL7-WtKz{NODBi{z5U(~EEq78DEv?S<+0@$ioZo08?yt1)?i&1Pu>%(-m^_p4!i(cgxs%D^3D#P9f3?az z=UsPwtFL>rlYL0yuV4cnA*+gKfuS=kSC}Mqgx|nPd3c(yy~-E)xI-e2NR1HrKIX|t zM$fPre!a<)&~3+7kV|%?p&VpFZq7-BG@V8`MG)i+>WVly9B0XDu2GJkM+r6!IB^Sz z*6FQ?s@#3(UEh{O$t=h$tTpcj9wlkTmqOYERd51ns3)!pU}}zZ9e)e(`(yc+O~^9e zdm!Ne=K?Jw;)OeiTtNoM{Y7n{P0_cB@Z2;4PJ?ToXu4U>#Xn2?#xYG&iy5DlnpYzA zXv*4FlnYH$UZEeUY#~yZ%d|)=N)OtMoTW$W3o@o#1`NwrZWb~9b4zCKbz@lXooIbq zvqf(8uwE682686wt^Afeeko zn=YgBRhv$vY$4oKVEZA~a6$e{%?%zMIo+^6s>BuUGLqXm!(S-;dFdUa8a6^H{N6)* zSFFX2D)O?*ADzWyV6{#d;01f&GiIMWayzed_Pp-v;K1BJS2@FhCJKL94v{+Q5)hJj z=UL1PeA#o9TXvt7LGv1A6QfeLiJ{?X%H~}Fdd{jLS(G8)>N;w@hMwp>1RHIU)UuW#A+^a!ZguADLtuDjnFC@f$>C`Dbae9J0 zTzY=mwEM!bgtq>o^7fnd!tm70_>njm?j7hLrH6PfO|`Z^F;`RTKs0{RI+^M?1rHPa=63opM`KW-D$TOglQZ+-j<6MXn@w2M z3MzTDI3Y=_ro%}G7PNt!E|9|V1$(CP9-GGm~^nb|hGuzreX+gV==X1`E3!5FpGU*^Uz2P~JR5NAE`rUt1@tS~GA zx+9LSwLQPD`@Y>5ERvCrpJ2xHiD(E*Pb1zd;ji^ild&v zZc0Idc(#)79()IZ{R%$Nk>P%}WN2MJJV}C+(EI%iJ^rE$L^tY^ix2AMx}%xoQ%&6b z%L@sCz=Z=faKXn-FH_pHVEnd!q>Bn;ZoJef8@JCa*lTx^I|gbme{fu$be?)FwihC^ z{uT-j*?6K)Z29pAc80DNt*6gL=SplVJli58A9Wc6nMzPiN-pXUi+*C7WN%Iu^u1rI z1uDQM%o(j4Rcp)GMEaP_p#=>dBpo(PCcH59yL>}}^zm2&;>75JR_e)Ow}wy_vgs4v zA37~q&{O}X@>sU4`+f50#NAe*Dw6W>I|M7*O%UIO8Tw}i*!gQRr+{W~!p9rhB2l`- z*ZtF3FKL$=d_SDDf-sl20j6eJqRgVpc^|eRb=Or)9YE_I@1MOyfp=mq=veN~CtXpA z?d>XX9HT6j+l8a|e-QWg@Bw2$1&o43KTu6pdU9dRK&bAr%RXBgCCjnl&| zQIAICA`z!oolc!EYV`M-lnu;)RgTO(JVL9keQQ2OSNxV zb>YKDXu^YO(e_O}?InL!5D1jh(!5)$J_rVR`{?Qa0eJ79mVMrBuQKe5vgQwOu(~F) z@hyKf1b(js21DYg1AAPPsV2l)q~FSr+EKk@H;mQ*peS{Qn~yr%uZr0l%m4&W*2jJa wfNCE+jFTb{pg`aCj^{d&)R%X_d}}0@f6&$CbEi)x>rq!URdrNwN>%~?1uoVX=>Px# From c1af9896a0ba22aefc7bba568abc6946e576d020 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Fri, 17 Nov 2023 21:46:06 +0100 Subject: [PATCH 06/66] Add macOS Codesign and notarization. Bittorrent-tracker-editor was also sign and notarize in the previous Travis-CI build server. --- .github/workflows/cicd.yml | 91 +++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index c15d1f5..4fc28ad 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -33,17 +33,12 @@ jobs: LAZ_OPT: - os: macos-latest LAZBUILD_WITH_PATH: /Applications/Lazarus/lazbuild - RELEASE_ZIP_FILE: trackereditor_UNSIGNED_macOS_Intel_64.zip + RELEASE_ZIP_FILE: trackereditor_macOS_amd64.zip LAZ_OPT: --widgetset=cocoa steps: - uses: actions/checkout@v4 - - name: show LAZBUILD_WITH_PATH (deprecated) - if: ${{ matrix.LAZBUILD_WITH_PATH }} - shell: bash - run: echo ${{ matrix.LAZBUILD_WITH_PATH }} - - name: Install Lazarus IDE run: | if [ "$RUNNER_OS" == "Linux" ]; then @@ -51,8 +46,8 @@ jobs: elif [ "$RUNNER_OS" == "Windows" ]; then choco install lazarus zip # https://wiki.overbyte.eu/wiki/index.php/ICS_Download#Download_OpenSSL_Binaries - curl -L -O --output-dir enduser https://github.com/GerryFerdinandus/Renesas-RX-GCC/releases/latest/download/libssl-3-x64.dll - curl -L -O --output-dir enduser https://github.com/GerryFerdinandus/Renesas-RX-GCC/releases/latest/download/libcrypto-3-x64.dll + curl -L -O --output-dir enduser https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases/download/V1.32.0/libssl-3-x64.dll + curl -L -O --output-dir enduser https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases/download/V1.32.0/libcrypto-3-x64.dll elif [ "$RUNNER_OS" == "macOS" ]; then brew install --cask lazarus else @@ -98,19 +93,95 @@ jobs: zip -j ${{ matrix.RELEASE_ZIP_FILE }} enduser/*.txt enduser/trackereditor.exe enduser/*.dll shell: bash - - name: Create a zip file for macOS .app release. (unsigned macOS app) + - name: Move file into macOS .app if: matrix.os == 'macos-latest' run: | # copy everything into enduser/macos/app folder # # Move the executable to the application bundle mv enduser/trackereditor enduser/macos/app/trackereditor.app/Contents/MacOS + # Move the trackers list to application bundle mv enduser/add_trackers.txt enduser/macos/app/trackereditor.app/Contents/MacOS mv enduser/remove_trackers.txt enduser/macos/app/trackereditor.app/Contents/MacOS + # move all the *.txt file mv enduser/*.txt enduser/macos/app + + # zip only the app folder with extra text file. + # /usr/bin/ditto -c -k "enduser/macos/app" "${{ matrix.RELEASE_ZIP_FILE }}" + shell: bash + + - name: Codesign macOS app bundle + # This macOS Codesign step is copied from: + # https://federicoterzi.com/blog/automatic-code-signing-and-notarization-for-macos-apps-using-github-actions/ + # This is a bit different from the previous version for Travis-CI build system to build bittorrent tracker editor + if: matrix.os == 'macos-latest' + env: + MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} + MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} + run: | + # Turn our base64-encoded certificate back to a regular .p12 file + echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + + # We need to create a new keychain, otherwise using the certificate will prompt + # with a UI dialog asking for the certificate password, which we can't + # use in a headless CI environment + + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain + + # We finally codesign our app bundle, specifying the Hardened runtime option. + #/usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime enduser/macos/app/trackereditor.app -v + + # sign the app. -sign is the developer cetificate ID + # entitlements does not work at this moment + #codesign --timestamp --entitlements enduser/macos/entitlements.plist --force --options runtime --deep --sign $CERTIFICATE_ID $FILE_APP + + # Please note: this is the same code version used in Travis-CI + /usr/bin/codesign --timestamp --force --options runtime --deep --sign "$MACOS_CERTIFICATE_NAME" enduser/macos/app/trackereditor.app + shell: bash + + - name: Notarize macOS app bundle + if: matrix.os == 'macos-latest' + env: + PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} + PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} + PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} + run: | + # Store the notarization credentials so that we can prevent a UI password dialog + # from blocking the CI + + echo "Create keychain profile" + xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD" + + # We can't notarize an app bundle directly, but we need to compress it as an archive. + # Therefore, we create a zip file containing our app bundle, so that we can send it to the + # notarization service + + echo "Creating temp notarization archive" + ditto -c -k --keepParent "enduser/macos/app/trackereditor.app" "notarization.zip" + + # Here we send the notarization request to the Apple's Notarization service, waiting for the result. + # This typically takes a few seconds inside a CI environment, but it might take more depending on the App + # characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if + # you're curious + + echo "Notarize app" + xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait + + # Finally, we need to "attach the staple" to our executable, which will allow our app to be + # validated by macOS even when an internet connection is not available. + echo "Attach staple" + xcrun stapler staple "enduser/macos/app/trackereditor.app" + # zip only the app folder with extra text file. + echo "Zip file" /usr/bin/ditto -c -k "enduser/macos/app" "${{ matrix.RELEASE_ZIP_FILE }}" shell: bash @@ -118,7 +189,7 @@ jobs: uses: actions/upload-artifact@v3 with: path: ${{ matrix.RELEASE_ZIP_FILE }} - if-no-files-found: error # 'warn'. error + if-no-files-found: error - name: Zip file release to end user uses: softprops/action-gh-release@v1 From 92f992707b86402e462d4757c452934610f7bee0 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Fri, 17 Nov 2023 22:11:55 +0100 Subject: [PATCH 07/66] Remove Travis-CI build files https://www.travis-ci.com/ no longer needed. This project has already been moved to GitHub Actions. [skip ci] --- .gitmodules | 0 ...all_and_run_unit_test_in_desktop_ubuntu.sh | 40 ----- scripts/travis_add_macos_cert.sh | 36 ----- scripts/travis_deploy.sh | 36 ----- scripts/travis_sign_macos_app.sh | 142 ------------------ scripts/travis_unit_test.sh | 47 ------ 6 files changed, 301 deletions(-) delete mode 100644 .gitmodules delete mode 100644 scripts/install_and_run_unit_test_in_desktop_ubuntu.sh delete mode 100755 scripts/travis_add_macos_cert.sh delete mode 100644 scripts/travis_deploy.sh delete mode 100755 scripts/travis_sign_macos_app.sh delete mode 100644 scripts/travis_unit_test.sh diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29..0000000 diff --git a/scripts/install_and_run_unit_test_in_desktop_ubuntu.sh b/scripts/install_and_run_unit_test_in_desktop_ubuntu.sh deleted file mode 100644 index 5b5202b..0000000 --- a/scripts/install_and_run_unit_test_in_desktop_ubuntu.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# for local testing of the project in Ubuntu 14.04 (via VirtualBox) - -#create download folder 'download_FPC' -cd ~ -mkdir download_FPC -cd download_FPC - -#download the FPC + lazarus IDE (1.6.2) -wget http://mirrors.iwi.me/lazarus/releases/Lazarus%20Linux%20amd64%20DEB/Lazarus%201.6.2/fpc_3.0.0-151205_amd64.deb -wget http://mirrors.iwi.me/lazarus/releases/Lazarus%20Linux%20amd64%20DEB/Lazarus%201.6.2/fpc-src_3.0.0-151205_amd64.deb -wget http://mirrors.iwi.me/lazarus/releases/Lazarus%20Linux%20amd64%20DEB/Lazarus%201.6.2/lazarus-project_1.6.2-1_amd64.deb - -#Install the downloaded FPC + lazarus IDE -sudo dpkg -i ./*.deb -#install all the software dependency it needed -sudo apt install -f -y - -#install git -sudo apt-get install git -y - -#Download the source code in the home folder -cd ~ -git clone --recursive https://github.com/GerryFerdinandus/bittorrent-tracker-editor.git - -#build the source code trackereditor. (optional: --build-mode=Release) -lazbuild --build-mode=Debug bittorrent-tracker-editor/source/project/tracker_editor/trackereditor.lpi - -#build the source code tracker_editor_test -lazbuild --build-mode=Debug bittorrent-tracker-editor/source/project/unit_test/tracker_editor_test.lpi - -#Run the unit test -./bittorrent-tracker-editor/enduser/test_trackereditor -a --format=plain - - - - - - diff --git a/scripts/travis_add_macos_cert.sh b/scripts/travis_add_macos_cert.sh deleted file mode 100755 index 9ad919c..0000000 --- a/scripts/travis_add_macos_cert.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env sh - -#must run on griet server only -if [ -z "${TRAVIS}" ] -then - echo "This is not TRAVIS CI build server " - exit 1 -fi - -# secure/hidden variable from travis -# CERTIFICATE_OSX_P12 -# CERTIFICATE_PASSWORD - - -# constant variable -KEY_CHAIN=build.keychain -CERTIFICATE_P12=certificate.p12 - -# Recreate the certificate from the secure environment variable -echo $CERTIFICATE_OSX_P12 | base64 --decode > $CERTIFICATE_P12 - -# create a keychain -security create-keychain -p travis $KEY_CHAIN - -# Make the keychain the default so identities are found -security default-keychain -s $KEY_CHAIN - -# Unlock the keychain -security unlock-keychain -p travis $KEY_CHAIN - -security import $CERTIFICATE_P12 -k $KEY_CHAIN -P $CERTIFICATE_PASSWORD -T /usr/bin/codesign; - -security set-key-partition-list -S apple-tool:,apple: -s -k travis $KEY_CHAIN - -# remove certs -rm -fr *.p12 diff --git a/scripts/travis_deploy.sh b/scripts/travis_deploy.sh deleted file mode 100644 index dcaf45c..0000000 --- a/scripts/travis_deploy.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -# Create a zip file for Windows, Linux and macOS. - -#----------- check for Windows, Linux and macOS build -if [ "$TRAVIS_OS_NAME" = "linux" ] -then - # Linux - sudo apt-get install zip -y - echo "Building zip file for Linux amd64" - zip -j $RELEASE_ZIP_FILE enduser/*.txt enduser/trackereditor - -elif [ "$TRAVIS_OS_NAME" = "osx" ] -then - # Apple macOS - echo "Building zip file for macOS" - - # Add certificate into the macOS system - source ./scripts/travis_add_macos_cert.sh - - # sign + zip the app - source ./scripts/travis_sign_macos_app.sh - -elif [ "$TRAVIS_OS_NAME" = "windows" ] -then - # Windows - echo "Building zip file for windows" - choco install zip - zip -j $RELEASE_ZIP_FILE enduser/*.txt enduser/trackereditor.exe enduser/*.dll -fi - -echo "Create Amazon s3 folder" -mkdir -p s3 -cp $RELEASE_ZIP_FILE s3/$(date +%F_%R)_$RELEASE_ZIP_FILE - -echo "Created $RELEASE_ZIP_FILE for GitHub" diff --git a/scripts/travis_sign_macos_app.sh b/scripts/travis_sign_macos_app.sh deleted file mode 100755 index b38796a..0000000 --- a/scripts/travis_sign_macos_app.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env sh - -# secure/hidden variable from travis -#CERTIFICATE_ID="..." -#USERNAME="..." -#APP_SPECIFIC_PASSWORD="..." -#RELEASE_ZIP_FILE="..." - -# path to app -FILE_APP='enduser/macos/app/trackereditor.app' -PLISTBUDDY_APP='/usr/libexec/PlistBuddy' - -if [ ! -x "${PLISTBUDDY_APP}" ] -then - echo "Couldn't find PlistBuddy" - exit 1 -fi - -# copy everything into enduser/macos/app folder -# -# Move the executable to the application bundle -mv enduser/trackereditor enduser/macos/app/trackereditor.app/Contents/MacOS - -# Move the trackers list to application bundle -mv enduser/add_trackers.txt enduser/macos/app/trackereditor.app/Contents/MacOS -mv enduser/remove_trackers.txt enduser/macos/app/trackereditor.app/Contents/MacOS - -# move all the *.txt file -mv enduser/*.txt enduser/macos/app - -# sign the app. -sign is the developer cetificate ID -# entitlements does not work at this moment -#codesign --timestamp --entitlements enduser/macos/entitlements.plist --force --options runtime --deep --sign $CERTIFICATE_ID $FILE_APP -codesign --timestamp --force --options runtime --deep --sign $CERTIFICATE_ID $FILE_APP - -# Check exit code -exit_code=$? -if [ "${exit_code}" != "0" ] -then - echo "codesign failed: ${exit_code}" - exit 1 -fi - -#must use ditto to compress the file application folder only for notarize. Zip program will not work! -/usr/bin/ditto -c -k --keepParent "$FILE_APP" "$RELEASE_ZIP_FILE" - -# upload zip to notarize service. for RequestUUID -# -- username is the normal apple ID. example myname@mail.com -# -- password is 'app specific password' generated via apple web site. Security -> app-specific password -echo "Uploading to notarize server" -xcrun altool --notarize-app --output-format xml --primary-bundle-id "trackereditor" --username $USERNAME --password $APP_SPECIFIC_PASSWORD --file $RELEASE_ZIP_FILE > "result.plist" - -# remove the uploaded zip file. need to be created again later. -rm $RELEASE_ZIP_FILE - - -# Check exit code -exit_code=$? -if [ "${exit_code}" != "0" ] -then - echo "notarize-app failed: ${exit_code}" - cat "result.plist" - exit 1 -fi - -# Get the RequestUUID -RequestUUID="$("${PLISTBUDDY_APP}" -c "Print notarization-upload:RequestUUID" "result.plist")" -echo "RequestUUID: ${RequestUUID}" - -# wait till notarize apple server is finish with the processing the zip upload. -for (( ; ; )) -do - - # get status from apple notarize server - xcrun altool --output-format xml --notarization-info "${RequestUUID}" -u $USERNAME -p $APP_SPECIFIC_PASSWORD > "result.plist" - # Check exit code - exit_code=$? - if [ "${exit_code}" != "0" ] - then - echo "notarization-info failed: ${exit_code}" - cat "result.plist" - # print the error in the URL - LogFileURL="$("${PLISTBUDDY_APP}" -c "Print notarization-info:LogFileURL" "result.plist")" - if [ ! -z "${LogFileURL}" ] - then - curl "${LogFileURL}" - fi - exit 1 - fi - - # get the status. - StatusCode="$("${PLISTBUDDY_APP}" -c "Print notarization-info:Status" "result.plist")" - echo "Status: ${StatusCode}" - - # if no status code present in result then it is still busy - if [ "${StatusCode}" == "in progress" ] - then - sleep 15 - else - echo "Finish waiting." - #cat "result.plist" - # Check if everything is correct - StatusCode="$("${PLISTBUDDY_APP}" -c "Print notarization-info:'Status Code'" "result.plist")" - echo "Status code: ${StatusCode}" - if [ "${StatusCode}" == "0" ] - then - # there are no error. - break - else - # print the error in the URL - LogFileURL="$("${PLISTBUDDY_APP}" -c "Print notarization-info:LogFileURL" "result.plist")" - if [ ! -z "${LogFileURL}" ] - then - curl "${LogFileURL}" - fi - exit 1 - fi - fi -done - -# verify sign *.app is succes full -spctl --assess --type execute --verbose $FILE_APP -# Check exit code -exit_code=$? -if [ "${exit_code}" != "0" ] -then - echo "spctl failed: ${exit_code}" - exit 1 -fi - -# staple the *.app -xcrun stapler staple $FILE_APP -# Check exit code -exit_code=$? -if [ "${exit_code}" != "0" ] -then - echo "spctl stapler: ${exit_code}" - exit 1 -fi - -# zip only the app folder with extra text file. -/usr/bin/ditto -c -k "enduser/macos/app" "$RELEASE_ZIP_FILE" diff --git a/scripts/travis_unit_test.sh b/scripts/travis_unit_test.sh deleted file mode 100644 index 33772eb..0000000 --- a/scripts/travis_unit_test.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh - -# Run unit test in Windows, Linux and macOS - -#----------- check for Windows, Linux and macOS build -if [ "$TRAVIS_OS_NAME" = "linux" ] -then - # show Linux OS version - uname -a - - # show openSSL version - openssl version - - # Exit immediately if a command exits with a non-zero status. - set -e - xvfb-run enduser/test_trackereditor -a --format=plain - set +e - -elif [ "$TRAVIS_OS_NAME" = "osx" ] -then - # show macOS version - sw_vers - - # show openSSL version - openssl version - - # Exit immediately if a command exits with a non-zero status. - set -e - enduser/test_trackereditor -a --format=plain - set +e - -elif [ "$TRAVIS_OS_NAME" = "windows" ] -then - # Exit immediately if a command exits with a non-zero status. - set -e - enduser/test_trackereditor.exe -a --format=plain - set +e -fi - - -# Remove all the extra file created by test -# We do not what it in the ZIP release files. -rm -f enduser/console_log.txt -rm -f enduser/export_trackers.txt - -# Undo all changes made by testing. -git reset --hard From 2627a0b3167c69cfedb9a094cafbe0e3a6a70332 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Fri, 17 Nov 2023 23:58:52 +0100 Subject: [PATCH 08/66] Update version (1.32.0.Beta.6) -> (1.33.0) --- README.md | 14 +++----------- enduser/version.txt | 4 +++- source/code/main.pas | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 7af7569..863f3c3 100644 --- a/README.md +++ b/README.md @@ -48,28 +48,20 @@ There is no backup function in this software. Use it at your own risk. Bittorren ## Software history: ## -### 1.33.0.beta.6 ### +### 1.33.0 ### + * ADD: Support for OpenSSL 3 + * FIX: Handle dark theme on MacOS. ([Issue 49](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/49)) * ADD: Direct download support for ngosang via menu. * ADD: Extra tabpage 'private torrent'. For issue 31 and 34 * ADD: Check box 'Skip Announce Check in the URL' ([Issue 31](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/31)) * ADD: Command parameter '-SAC' -> 'Skip Announce Check' in the URL ([Issue 31](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/31)) * ADD: Support 'Info Source' tag for private trackers ([Issue 34](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/34)) * ADD: Command parameter '-SOURCE' -> info Source tag for private trackers. See readme.txt file ([Issue 34](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/34)) - -### 1.33.0.beta.5 ### * FiX: support for '/announce.php'([Issue 27](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/27)) - -### 1.33.0.beta.4 ### * FIX: There was an issue with uploading tracker list to newTrackon. - -### 1.33.0.beta.3 ### * FIX: WebTorrent do not have '/announce' ([Issue 24](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/24)) - -### 1.33.0.beta.2 ### * ADD: Wrong tracker URL format from torrent files should be unselected by default ([Issue 22](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/22)) * ADD: Upload trackers to newTrackon ([Issue 23](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/23)) - -### 1.33.0.beta.1 ### * ADD: Verify the working status of public trackers. (Data from newTrackon) ([Issue 21](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/21)) ### 1.32.0 ### diff --git a/enduser/version.txt b/enduser/version.txt index fd2f63b..512f784 100644 --- a/enduser/version.txt +++ b/enduser/version.txt @@ -10,7 +10,9 @@ ADD: Command parameter '-SAC' -> 'Skip Announce Check' in the URL (Issue 31) ADD: Support 'Info Source' tag for private trackers (issue 34) ADD: Command parameter '-SOURCE' -> info Source tag for private trackers. See readme.txt file (issue 34) ADD: Direct download support for ngosang via menu (Issue 35) -Compiler Lazarus: v2.04 +ADD: Support for OpenSSL 3 +FIX: Handle dark theme on MacOS. (Issue 49) +Compiler Lazarus: v2.26 ------ Version 1.32 ADD: Add more options for updating the torrent tracker list. (Issue 8) diff --git a/source/code/main.pas b/source/code/main.pas index c2e3347..b24b734 100644 --- a/source/code/main.pas +++ b/source/code/main.pas @@ -215,7 +215,7 @@ implementation ); //program name and version (http://semver.org/) - FORM_CAPTION = 'Bittorrent tracker editor (1.33.0.beta.6/LCL ' + + FORM_CAPTION = 'Bittorrent tracker editor (1.33.0/LCL ' + lcl_version + '/FPC ' + {$I %FPCVERSION%} + ')'; GROUPBOX_PRESENT_TRACKERS_CAPTION = From 25d88b58deac36c5acefca06c51e06f508ecd960 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Sat, 18 Nov 2023 09:19:21 +0100 Subject: [PATCH 09/66] Remove notarization.zip during the build process. Otherwise it is also 'released' to the end user. Also remove .travis file. It's no longer used. [skip ci] --- .github/workflows/cicd.yml | 5 ++- .travis.yml | 87 -------------------------------------- 2 files changed, 4 insertions(+), 88 deletions(-) delete mode 100644 .travis.yml diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 4fc28ad..1dda5bd 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -180,8 +180,11 @@ jobs: echo "Attach staple" xcrun stapler staple "enduser/macos/app/trackereditor.app" + # Remove notarization.zip, otherwise it will also be 'released' to the end user + rm -f "notarization.zip" + # zip only the app folder with extra text file. - echo "Zip file" + echo "Zip macOS app file" /usr/bin/ditto -c -k "enduser/macos/app" "${{ matrix.RELEASE_ZIP_FILE }}" shell: bash diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b06d67e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,87 +0,0 @@ -# Part of `travis-lazarus` (https://github.com/nielsAD/travis-lazarus) -# License: MIT - -language: shell - -# Linux compability issue. -# Need to build in xenial with lazarus 1.8.2. -# Do not use bionic or newer Lazarus version - -# For linux headless. -# See travis_unit_test.sh will install and use xvfb-run -#services: (- xvfb) does not work must use xvfb-run - -jobs: - include: - - name: Ubuntu 16.04 AMD64 (1.8.2) - os: linux - dist: xenial - env: LAZ_VER=1.8.2 RELEASE_ZIP_FILE="trackereditor_linux_amd64.zip" - - name: Ubuntu 16.04 AArch64 (1.6) - os: linux - dist: xenial - arch: arm64 - env: LAZ_PKG=true RELEASE_ZIP_FILE="trackereditor_linux_AArch64.zip" - - name: macOS 10.14 (PKG) - os: osx - osx_image: xcode11.3 - env: LAZ_PKG=true LAZ_OPT="--widgetset=cocoa" RELEASE_ZIP_FILE="trackereditor_macOS.zip" - - name: Windows (PKG) Build 32-bit software - os: windows - env: LAZ_PKG=true LAZ_REL=32 RELEASE_ZIP_FILE="trackereditor_win32.zip" - -before_install: -# Install python in windows OS -- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install python3 --params "/InstallDir:C:\python3"; fi -- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then export PATH=/c/Python3:/c/Python3/Scripts:/c/lazarus:$PATH; fi - -install: -# Output something at regular time or Travis will kills the job -- while sleep 60; do echo "===== 1 minute mark ====="; done & -- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then python ./travis-lazarus/.travis.install.py; fi -- if [[ "$TRAVIS_OS_NAME" != "windows" ]]; then ./travis-lazarus/.travis.install.py; fi -# Killing background sleep loop -- kill %1 - -script: -# Output something at regular time or Travis will kill the job - - echo "start script" - - while sleep 60; do echo "===== 1 minute mark ====="; done & - -# Build trackereditor project (Release mode) - - lazbuild --build-mode=Release $LAZ_OPT $PROJECT_LPI_EDITOR_PATH - -# Build unit test project (Debug mode) - - lazbuild --build-mode=Debug $LAZ_OPT $PROJECT_LPI_UNIT_TEST_PATH - -# Start the unit test - - source ./scripts/travis_unit_test.sh - -# Killing background sleep loop - - kill %1 - -before_deploy: -# Create the zip file for deployment - - source ./scripts/travis_deploy.sh - -deploy: - - provider: releases - prerelease: false - cleanup: false - edge: true # opt in to dpl v2 - token: - secure: hmjev+YIClSOec6wMclUv5W4lgyLpdX7DlUpF2LQ1W/EO/x/b8RzmSPjNZ5sa7IDUe1WoVXm89G6HtkGGHcRqJrZjNn18HvpvEOnIYgIEXBVtW9uaURsSJ2LYve9beHHvYzs0doEQp1I24qTENUOqMABStk7MKRTATZ7nBWIinZVkpojEYIizQtCnUWwJXpzgs9mx7BEAVqLJPJ35oXNVjEgE96gsWMaYuX82BsVpL9VjGIaYpbEc1iBFBr2RHTgHG03H+2wBewJ4gh3hFwq9vt6mEqdC6Y9UIqmAEUMzCpokqrIfV2cfnPe24miPqmCLboua7Ddu8OpLj/yQ9DvC8xVEVh8aiGszzPvnytaFuRfLxI5HdAtUkA/9P3dXwjJKLJs568kyCTz4Tk7Icrb7seS1i84BJs3Vp2/lkmqDRDR0OqVGTczZGsxfTK+iaZJaNXb999BmGBw+xnPuG1lgrjHUYyEH2ha9D/9eOXiQfxdKUktPs1cF0II7uv5Cg3LEcFyN/A7jblNpM5B9cnf5kJ13lbpqL+Eyig90b9Q9YsrwGGOqtXJG+jSqXOv0O9/warFJfadA0avJljOFv4Pxl4tYe73EA/gP1GVG5UVC/F9nWZhUzP1kPCjzTzHoYBDCmHf8/GErdpCtibqRHoMIelrbcpe0jr+j5aNPxnTKAc= - file: "${RELEASE_ZIP_FILE}" - on: - tags: true - repo: GerryFerdinandus/bittorrent-tracker-editor - - provider: s3 - access_key_id: $AWS_ACCESS_KEY - secret_access_key: $AWS_SECRET_KEY - bucket: "bittorrent-tracker-editor" - cleanup: false - region: eu-central-1 - local_dir: s3 - edge: true # opt in to dpl v2 - on: - branch: to_be_deleted_unit_test From ff234ebff47d983e6c932994772e9f11089aa5bf Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Sun, 19 Nov 2023 16:04:41 +0100 Subject: [PATCH 10/66] Test OpenSSL works on Linux CI See issue #39 In any case, check if it works on the build server. --- .github/workflows/cicd.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 1dda5bd..cc2d0a2 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -42,7 +42,7 @@ jobs: - name: Install Lazarus IDE run: | if [ "$RUNNER_OS" == "Linux" ]; then - sudo apt install -y lazarus zip + sudo apt install -y lazarus zip xvfb elif [ "$RUNNER_OS" == "Windows" ]; then choco install lazarus zip # https://wiki.overbyte.eu/wiki/index.php/ICS_Download#Download_OpenSSL_Binaries @@ -61,7 +61,8 @@ jobs: run: ${{ matrix.LAZBUILD_WITH_PATH }} --build-mode=Release ${{ matrix.LAZ_OPT }} source/project/tracker_editor/trackereditor.lpi shell: bash - - name: Build Unit Test + - name: Build Unit Test on Windows + if: matrix.os == 'windows-latest' # Build unit test project (Debug mode) run: ${{ matrix.LAZBUILD_WITH_PATH }} --build-mode=Debug ${{ matrix.LAZ_OPT }} source/project/unit_test/tracker_editor_test.lpi shell: bash @@ -82,6 +83,10 @@ jobs: git reset --hard shell: bash + - name: Test OpenSSL works on Linux CI + if: matrix.os == 'ubuntu-latest' + run: xvfb-run --auto-servernum enduser/trackereditor -TEST_SSL + - name: Create a zip file for Linux release. if: matrix.os == 'ubuntu-latest' run: zip -j ${{ matrix.RELEASE_ZIP_FILE }} enduser/*.txt enduser/trackereditor From f8039163f24e68e999bd17fac7dc8b6f09391da3 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Tue, 21 Nov 2023 01:36:07 +0100 Subject: [PATCH 11/66] Snap: Skip dummy widget on startup. At startup there is a dummy widget that blocks the operation of the program. This is reproducible on the Raspberry PI 4. '-disableaccurateframe' is part of the Lazarus startup options [skip ci] --- snap/snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 3632cd7..b531820 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -23,7 +23,7 @@ architectures: apps: bittorrent-tracker-editor: - command: app/trackereditor + command: app/trackereditor -disableaccurateframe environment: # Fallback to XWayland if running in a Wayland session. DISABLE_WAYLAND: 1 From f42631c3170d95f38630578d3ea0fe3d58df4321 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Thu, 7 Dec 2023 19:22:40 +0100 Subject: [PATCH 12/66] Fix: Text doesn't fit Under the private trackers tab. Some texts do not always fit in a certain font. Create more space now. [skip ci] --- source/code/main.lfm | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/source/code/main.lfm b/source/code/main.lfm index 6ece419..b8b9bd1 100644 --- a/source/code/main.lfm +++ b/source/code/main.lfm @@ -16,7 +16,7 @@ object FormTrackerModify: TFormTrackerModify OnDropFiles = FormDropFiles OnShow = FormShow Position = poScreenCenter - LCLVersion = '2.0.4.0' + LCLVersion = '2.2.6.0' object PageControl: TPageControl Left = 0 Height = 587 @@ -243,10 +243,11 @@ object FormTrackerModify: TFormTrackerModify ClientWidth = 284 TabOrder = 0 object CheckBoxSkipAnnounceCheck: TCheckBox - Left = 16 + Left = 0 Height = 19 Top = 0 - Width = 221 + Width = 284 + Align = alTop Caption = 'Skip Announce Check in the URL (-SAC)' OnChange = CheckBoxSkipAnnounceCheckChange ParentShowHint = False @@ -254,13 +255,14 @@ object FormTrackerModify: TFormTrackerModify TabOrder = 0 end object GroupBoxInfoSource: TGroupBox - Left = 16 + Left = 0 Height = 120 - Top = 32 - Width = 264 + Top = 38 + Width = 284 + Align = alBottom Caption = 'Warning: This will change the torrent info HASH' ClientHeight = 102 - ClientWidth = 260 + ClientWidth = 280 TabOrder = 1 object CheckBoxRemoveAllSourceTag: TCheckBox Left = 8 @@ -293,17 +295,17 @@ object FormTrackerModify: TFormTrackerModify end object SelectDirectoryDialog1: TSelectDirectoryDialog Title = 'Select a directory with torrent files inside.' - left = 560 - top = 24 + Left = 560 + Top = 24 end object OpenDialog: TOpenDialog Filter = 'torrent|*.torrent' - left = 560 - top = 88 + Left = 560 + Top = 88 end object MainMenu: TMainMenu - left = 472 - top = 152 + Left = 472 + Top = 152 object MenuFile: TMenuItem Caption = '&File' object MenuOpenTorrentFile: TMenuItem From 637593ede918b0a86cbe7ad21c38f3b3f51e6935 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Thu, 7 Dec 2023 19:26:41 +0100 Subject: [PATCH 13/66] Add: flatpak program uses different data folder [skip CI] --- source/code/main.pas | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/code/main.pas b/source/code/main.pas index b24b734..5869dcf 100644 --- a/source/code/main.pas +++ b/source/code/main.pas @@ -236,16 +236,21 @@ procedure TFormTrackerModify.FormCreate(Sender: TObject); end; {$IFDEF LINUX} - // if a ubuntu snap program then save it to other place + // If it is a Ubuntu snap program, save it a special folder FFolderForTrackerListLoadAndSave := GetEnvironmentVariable('SNAP_USER_COMMON'); + // If it is a flatpak program, save it in a special folder + if GetEnvironmentVariable('container') = 'flatpak' then + begin + FFolderForTrackerListLoadAndSave := GetEnvironmentVariable('XDG_DATA_HOME'); + end; if FFolderForTrackerListLoadAndSave = '' then begin - // NOT a snap program + // No container detected. Save in the same place as the application file FFolderForTrackerListLoadAndSave := ExtractFilePath(Application.ExeName); end else begin - // A snap program + // Program run in a container. Must load file from a dedicated folder. FFolderForTrackerListLoadAndSave := AppendPathDelim(FFolderForTrackerListLoadAndSave); end; {$ELSE} From 2dba1e7d30b5ec63ae90b5336ce9ca302a348073 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Thu, 7 Dec 2023 19:35:04 +0100 Subject: [PATCH 14/66] snap: use kde-neon Snap now uses extensions for Gnome with GTK3 and KDE with QT5. The previous GTK or QT part is no longer recommended/supported. Lazarus does not yet support GTK3. The only choice now is to use KDE with QT5 [skip ci] --- snap/snapcraft.yaml | 72 +++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 52 deletions(-) diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index b531820..7ee68be 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,7 +1,7 @@ name: bittorrent-tracker-editor version: '1.33.0' base: core22 -summary: Software for add or remove tracker from torrent files. +summary: Add or remove tracker from torrent files. description: | Features: - Select one torrent file or a folder with torrent files. @@ -9,8 +9,6 @@ description: | - Remove one or more trackers at the same time. - Remove all the trackers to create trackerless torrent. DHT torrent - Change public/private flag. Warning: This will change the torrent info HASH. - - Preset add/remove tracker via add_trackers.txt and remove_trackers.txt files. - - Optional start as console program. - Show torrent files content. - Download stable trackers from newTrackon or ngosang grade: stable @@ -19,29 +17,20 @@ confinement: strict architectures: - build-on: amd64 - build-on: arm64 - - build-on: armhf apps: bittorrent-tracker-editor: - command: app/trackereditor -disableaccurateframe + extensions: + - kde-neon + command: app/trackereditor environment: # Fallback to XWayland if running in a Wayland session. DISABLE_WAYLAND: 1 plugs: - - desktop - - desktop-legacy - - x11 - - unity7 - home - network - - wayland - removable-media - -build-packages: - - fpc - - fpc-source - - lcl-nogui - - lazarus + - pulseaudio parts: bittorrent-tracker-editor: @@ -49,45 +38,24 @@ parts: plugin: nil override-build: | snapcraftctl build - lazbuild --build-mode=Release --widgetset=gtk2 source/project/tracker_editor/trackereditor.lpi + lazbuild --build-mode=Release --widgetset=qt5 source/project/tracker_editor/trackereditor.lpi mkdir $CRAFT_PART_INSTALL/app mv enduser/trackereditor $CRAFT_PART_INSTALL/app build-packages: - - libgtk2.0-dev - stage-packages: - - libgtk2.0-0 - - openssl + - fpc + - fpc-source + - lcl-nogui + - lazarus + - libqt5pas-dev -# This part removes all the files in this snap which already exist in -# connected content and base snaps. Since these files will be available -# at runtime from the content and base snaps, they do not need to be -# included in this snap itself. -# -# More info: https://forum.snapcraft.io/t/reducing-the-size-of-desktop-snaps/17280#heading--cleanup-part -# - cleanup: - after: # Make this part run last; list all your other parts here - - bittorrent-tracker-editor + libQt5Pas: plugin: nil - build-snaps: # List all content-snaps and base snaps you're using here - - core22 - - gtk-common-themes - override-prime: | - set -eux - for snap in "core22" "gtk-common-themes"; do # List all content-snaps and base snaps you're using here - cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \; - done + stage-packages: + - libqt5pas1 + prime: + - usr/lib/*/libQt5Pas.* -plugs: - gtk-2-engines: - interface: content - target: $SNAP/lib/gtk-2.0 - default-provider: gtk2-common-themes - icon-themes: - interface: content - target: $SNAP/data-dir/icons - default-provider: gtk-common-themes - sound-themes: - interface: content - target: $SNAP/data-dir/sounds - default-provider: gtk-common-themes +# Only 2 files are explicitly added in this snap: trackereditor + libQt5Pas.so +# No need to add a cleanup process. There's nothing to clean up. +# +# Use: 'unsquashfs *.snap' to look what is inside the snap file. From d7f48102334f6515c750b94ecd7d6fd1fbf1a88c Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Tue, 12 Dec 2023 21:05:18 +0100 Subject: [PATCH 15/66] Fix: Text doesn't fit Under the private trackers tab. Some texts do not always fit in a certain font. [skip ci] --- source/code/main.lfm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/code/main.lfm b/source/code/main.lfm index b8b9bd1..a7a2be5 100644 --- a/source/code/main.lfm +++ b/source/code/main.lfm @@ -278,9 +278,9 @@ object FormTrackerModify: TFormTrackerModify Height = 21 Hint = 'Keep empty if you do not want to add or change anything.' Top = 56 - Width = 221 + Width = 240 EditLabel.Height = 13 - EditLabel.Width = 221 + EditLabel.Width = 240 EditLabel.Caption = 'Add/Change source tag value: (-SOURCE)' EditLabel.ParentColor = False ParentShowHint = False From a6ee202f4b3b1c914eeb4a5986a4c86eb38fc828 Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Tue, 12 Dec 2023 21:10:44 +0100 Subject: [PATCH 16/66] Add freedesktop-metainfo Get data from a single source for the Linux app. --- ...dinandus.bittorrent-tracker-editor.desktop | 9 +++ ...dus.bittorrent-tracker-editor.metainfo.xml | 71 ++++++++++++++++++ ...yferdinandus.bittorrent-tracker-editor.png | Bin snap/gui/bittorrent-tracker-editor.desktop | 10 --- snap/snapcraft.yaml | 36 ++++----- 5 files changed, 95 insertions(+), 31 deletions(-) create mode 100644 metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.desktop create mode 100644 metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.metainfo.xml rename snap/gui/bittorrent-tracker-editor.png => metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.png (100%) delete mode 100644 snap/gui/bittorrent-tracker-editor.desktop diff --git a/metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.desktop b/metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.desktop new file mode 100644 index 0000000..798d0ca --- /dev/null +++ b/metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=bittorrent-tracker-editor +Comment=Add or remove tracker from torrent files. +Categories=Utility;Qt; +Icon=io.github.gerryferdinandus.bittorrent-tracker-editor +Exec=trackereditor +Terminal=false diff --git a/metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.metainfo.xml b/metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.metainfo.xml new file mode 100644 index 0000000..6793295 --- /dev/null +++ b/metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.metainfo.xml @@ -0,0 +1,71 @@ + + + io.github.gerryferdinandus.bittorrent-tracker-editor + bittorrent-tracker-editor + Add or remove tracker from torrent files. + Gerry Ferdinandus + io.github.gerryferdinandus.bittorrent-tracker-editor.desktop + + CC0-1.0 + MIT + + https://github.com/GerryFerdinandus/bittorrent-tracker-editor + https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues + + + + +

Features:

+
    +
  • Select one torrent file or a folder with torrent files
  • +
  • Add one or more trackers at the same time
  • +
  • Remove one or more trackers at the same time
  • +
  • Remove all the trackers to create trackerless torrent. DHT torrent
  • +
  • Change public/private flag. Warning: This will change the torrent info HASH
  • +
  • Show torrent files content
  • +
  • Download stable trackers from newTrackon or ngosang
  • +
+

+ Warning: There is no backup function in this software. Use it at your own risk. +

+

+ BitTorrent works fine without this program. You probably don't need this software. +

+
+ + + + The main window + + https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases/download/V1.32.0/trackereditor_list_linux.png + + + Torrent info + + https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases/download/V1.32.0/trackereditor_info_linux.png + + + + + + +

+ This release adds the following features: +

+
    +
  • Verify the working status of public trackers.
  • +
  • Direct download support for ngosang via menu.
  • +
  • Extra tabpage 'private torrent'.
  • +
  • Support 'Info Source' tag for private trackers
  • +
  • Wrong tracker URL format from torrent files should be unselected by default
  • +
  • Upload trackers to newTrackon
  • +
+

This release fixes the following bugs:

+
    +
  • support for '/announce.php'
  • +
  • WebTorrent do not have '/announce'
  • +
+
+
+
+
\ No newline at end of file diff --git a/snap/gui/bittorrent-tracker-editor.png b/metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.png similarity index 100% rename from snap/gui/bittorrent-tracker-editor.png rename to metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.png diff --git a/snap/gui/bittorrent-tracker-editor.desktop b/snap/gui/bittorrent-tracker-editor.desktop deleted file mode 100644 index a6cc131..0000000 --- a/snap/gui/bittorrent-tracker-editor.desktop +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Version=1.0 -Name=Bittorrent tracker editor -Comment=Software for add or remove tracker from torrent files. -Exec=bittorrent-tracker-editor -Icon=${SNAP}/meta/gui/bittorrent-tracker-editor.png -Terminal=false -Type=Application -Categories=Utility; -Keywords=bittorrent;tracker;editor; diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 7ee68be..3aabc9a 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,16 +1,8 @@ name: bittorrent-tracker-editor -version: '1.33.0' +adopt-info: mainprogram +icon: metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.png + base: core22 -summary: Add or remove tracker from torrent files. -description: | - Features: - - Select one torrent file or a folder with torrent files. - - Add one or more trackers at the same time. - - Remove one or more trackers at the same time. - - Remove all the trackers to create trackerless torrent. DHT torrent - - Change public/private flag. Warning: This will change the torrent info HASH. - - Show torrent files content. - - Download stable trackers from newTrackon or ngosang grade: stable confinement: strict @@ -20,9 +12,10 @@ architectures: apps: bittorrent-tracker-editor: + desktop: mainprogram/io.github.gerryferdinandus.bittorrent-tracker-editor.desktop extensions: - kde-neon - command: app/trackereditor + command: mainprogram/trackereditor environment: # Fallback to XWayland if running in a Wayland session. DISABLE_WAYLAND: 1 @@ -33,29 +26,30 @@ apps: - pulseaudio parts: - bittorrent-tracker-editor: + mainprogram: # Build and add to snap the main program: mainprogram/trackereditor source: https://github.com/GerryFerdinandus/bittorrent-tracker-editor.git + parse-info: [metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.metainfo.xml] plugin: nil override-build: | - snapcraftctl build + craftctl default lazbuild --build-mode=Release --widgetset=qt5 source/project/tracker_editor/trackereditor.lpi - mkdir $CRAFT_PART_INSTALL/app - mv enduser/trackereditor $CRAFT_PART_INSTALL/app + mkdir $CRAFT_PART_INSTALL/mainprogram + cp enduser/trackereditor $CRAFT_PART_INSTALL/mainprogram + cp metainfo/io.github.gerryferdinandus.bittorrent-tracker-editor.desktop $CRAFT_PART_INSTALL/mainprogram build-packages: - fpc - - fpc-source - - lcl-nogui - lazarus - libqt5pas-dev - libQt5Pas: + libQt5Pas: # Add to snap the libQt5Pas support library : usr/lib/*/libQt5Pas.* plugin: nil stage-packages: - libqt5pas1 prime: - usr/lib/*/libQt5Pas.* -# Only 2 files are explicitly added in this snap: trackereditor + libQt5Pas.so -# No need to add a cleanup process. There's nothing to clean up. +# Only 3 files are explicitly added in this snap: +# trackereditor + .desktop file via copy command +# libQt5Pas.so via prime # # Use: 'unsquashfs *.snap' to look what is inside the snap file. From af12590ceb7165cc82f3027d217ebbaa5662267d Mon Sep 17 00:00:00 2001 From: Gerry Ferdinandus Date: Wed, 13 Dec 2023 16:19:21 +0100 Subject: [PATCH 17/66] fix: appstream-util validate error style-invalid: Content before