From 25082890ad727705e3f9b3c04a3efea07a59cc00 Mon Sep 17 00:00:00 2001 From: walterlv Date: Mon, 15 Apr 2024 09:21:42 +0800 Subject: [PATCH 01/23] Dont find the path twice --- src/Native/Windows.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs index 04fe5e8b..2d22ac42 100644 --- a/src/Native/Windows.cs +++ b/src/Native/Windows.cs @@ -160,7 +160,7 @@ namespace SourceGit.Native return; } - startInfo.FileName = FindWindowsTerminalApp(); + startInfo.FileName = wt; startInfo.Arguments = $"-d \"{workdir}\""; break; default: From 003ad66ccb7946ff94e7023efb67a1d7fdf2d0d9 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 15 Apr 2024 15:07:07 +0800 Subject: [PATCH 02/23] ux: add menu icon for git-flow --- src/Resources/Icons.axaml | 4 ++++ src/ViewModels/Repository.cs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index 5f036c97..2df7fe64 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -90,4 +90,8 @@ M765 555C747 661 661 747 555 765L555 683 469 683 469 765C363 747 277 661 259 555L341 555 341 469 259 469C277 363 363 277 469 259L469 341 555 341 555 259C661 277 747 363 765 469L683 469 683 555 765 555M851 469C832 315 709 192 555 173L555 85 469 85 469 173C315 192 192 315 173 469L85 469 85 555 173 555C192 709 315 832 469 851L469 939 555 939 555 851C709 832 832 709 851 555L939 555 939 469 851 469M512 427C559 427 597 465 597 512 597 559 559 597 512 597 465 597 427 559 427 512 427 465 465 427 512 427L512 427Z M973 358a51 51 0 0151 51v563a51 51 0 01-51 51H51a51 51 0 01-51-51V410a51 51 0 0151-51h256a51 51 0 110 102H102v461h819V461h-205a51 51 0 110-102h256zM51 102a51 51 0 110-102h256c141 0 256 115 256 256v388l66-66a51 51 0 1172 72l-154 154a51 51 0 01-72 0l-154-154a51 51 0 1172-72L461 644V256c0-85-69-154-154-154H51z M976 0h-928A48 48 0 000 48v652a48 48 0 0048 48h416V928H200a48 48 0 000 96h624a48 48 0 000-96H560v-180h416a48 48 0 0048-48V48A48 48 0 00976 0zM928 652H96V96h832v556z + M412 66C326 132 271 233 271 347c0 17 1 34 4 50-41-48-98-79-162-83a444 444 0 00-46 196c0 207 142 382 337 439h2c19 0 34 15 34 33 0 11-6 21-14 26l1 14C183 973 0 763 0 511 0 272 166 70 393 7A35 35 0 01414 0c19 0 34 15 34 33a33 33 0 01-36 33zm200 893c86-66 141-168 141-282 0-17-1-34-4-50 41 48 98 79 162 83a444 444 0 0046-196c0-207-142-382-337-439h-2a33 33 0 01-34-33c0-11 6-21 14-26L596 0C841 51 1024 261 1024 513c0 239-166 441-393 504A35 35 0 01610 1024a33 33 0 01-34-33 33 33 0 0136-33zM512 704a192 192 0 110-384 192 192 0 010 384z + M939 94v710L512 998 85 805V94h-64A21 21 0 010 73v-0C0 61 10 51 21 51h981c12 0 21 10 21 21v0c0 12-10 21-21 21h-64zm-536 588L512 624l109 58c6 3 13 4 20 3a32 32 0 0026-37l-21-122 88-87c5-5 8-11 9-18a32 32 0 00-27-37l-122-18-54-111a32 32 0 00-57 0l-54 111-122 18c-7 1-13 4-18 9a33 33 0 001 46l88 87-21 122c-1 7-0 14 3 20a32 32 0 0043 14z + M236 542a32 32 0 109 63l86-12a180 180 0 0022 78l-71 47a32 32 0 1035 53l75-50a176 176 0 00166 40L326 529zM512 16C238 16 16 238 16 512s222 496 496 496 496-222 496-496S786 16 512 16zm0 896c-221 0-400-179-400-400a398 398 0 0186-247l561 561A398 398 0 01512 912zm314-154L690 622a179 179 0 004-29l85 12a32 32 0 109-63l-94-13v-49l94-13a32 32 0 10-9-63l-87 12a180 180 0 00-20-62l71-47A32 32 0 10708 252l-75 50a181 181 0 00-252 10l-115-115A398 398 0 01512 112c221 0 400 179 400 400a398 398 0 01-86 247z + M884 159l-18-18a43 43 0 00-38-12l-235 43a166 166 0 00-101 60L400 349a128 128 0 00-148 47l-120 171a21 21 0 005 29l17 12a128 128 0 00178-32l27-38 124 124-38 27a128 128 0 00-32 178l12 17a21 21 0 0029 5l171-120a128 128 0 0047-148l117-92A166 166 0 00853 431l43-235a43 43 0 00-12-38zm-177 249a64 64 0 110-90 64 64 0 010 90zm-373 312a21 21 0 010 30l-139 139a21 21 0 01-30 0l-30-30a21 21 0 010-30l139-139a21 21 0 0130 0z diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 43665925..61afbb6b 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -715,6 +715,7 @@ namespace SourceGit.ViewModels { var startFeature = new MenuItem(); startFeature.Header = App.Text("GitFlow.StartFeature"); + startFeature.Icon = App.CreateMenuIcon("Icons.GitFlow.Feature"); startFeature.Click += (o, e) => { if (PopupHost.CanCreatePopup()) @@ -724,6 +725,7 @@ namespace SourceGit.ViewModels var startRelease = new MenuItem(); startRelease.Header = App.Text("GitFlow.StartRelease"); + startRelease.Icon = App.CreateMenuIcon("Icons.GitFlow.Release"); startRelease.Click += (o, e) => { if (PopupHost.CanCreatePopup()) @@ -733,6 +735,7 @@ namespace SourceGit.ViewModels var startHotfix = new MenuItem(); startHotfix.Header = App.Text("GitFlow.StartHotfix"); + startHotfix.Icon = App.CreateMenuIcon("Icons.GitFlow.Hotfix"); startHotfix.Click += (o, e) => { if (PopupHost.CanCreatePopup()) @@ -748,6 +751,7 @@ namespace SourceGit.ViewModels { var init = new MenuItem(); init.Header = App.Text("GitFlow.Init"); + init.Icon = App.CreateMenuIcon("Icons.GitFlow.Init"); init.Click += (o, e) => { if (PopupHost.CanCreatePopup()) From cc6996444e1751ef14866132e7e7a3510e08bb49 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 15 Apr 2024 15:22:32 +0800 Subject: [PATCH 03/23] ux: update icon for navigate to current HEAD button --- src/Resources/Icons.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index 2df7fe64..a8a31ad3 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -87,7 +87,7 @@ M875 117H149C109 117 75 151 75 192v640c0 41 34 75 75 75h725c41 0 75-34 75-75V192c0-41-34-75-75-75zm-725 64h725c6 0 11 4 11 11v288h-747V192c0-6 4-11 11-11zm725 661H149c-6 0-11-4-11-11V544h747V832c0 6-4 11-11 11z M875 128h-725A107 107 0 0043 235v555A107 107 0 00149 896h725a107 107 0 00107-107v-555A107 107 0 00875 128zm-115 640h-183v-58l25-3c15 0 19-8 14-24l-22-61H419l-28 82 39 2V768h-166v-58l18-3c18-2 22-11 26-24l125-363-40-4V256h168l160 448 39 3zM506 340l-72 218h145l-71-218h-2z M900 287c40 69 60 144 60 225s-20 156-60 225c-40 69-94 123-163 163-69 40-144 60-225 60s-156-20-225-60c-69-40-123-94-163-163C84 668 64 593 64 512s20-156 60-225 94-123 163-163c69-40 144-60 225-60s156 20 225 60 123 94 163 163zM762 512c0-9-3-16-9-22L578 315l-44-44c-6-6-13-9-22-9s-16 3-22 9l-44 44-176 176c-6 6-9 13-9 22s3 16 9 22l44 44c6 6 13 9 22 9s16-3 22-9l92-92v269c0 9 3 16 9 22 6 6 13 9 22 9h62c8 0 16-3 22-9 6-6 9-13 9-22V486l92 92c6 6 13 9 22 9 8 0 16-3 22-9l44-44c6-6 9-13 9-22z - M765 555C747 661 661 747 555 765L555 683 469 683 469 765C363 747 277 661 259 555L341 555 341 469 259 469C277 363 363 277 469 259L469 341 555 341 555 259C661 277 747 363 765 469L683 469 683 555 765 555M851 469C832 315 709 192 555 173L555 85 469 85 469 173C315 192 192 315 173 469L85 469 85 555 173 555C192 709 315 832 469 851L469 939 555 939 555 851C709 832 832 709 851 555L939 555 939 469 851 469M512 427C559 427 597 465 597 512 597 559 559 597 512 597 465 597 427 559 427 512 427 465 465 427 512 427L512 427Z + M765 118 629 239l-16 137-186 160 54 59 183-168 144 4 136-129 47-43-175-12L827 67zM489 404c-66 0-124 55-124 125s54 121 124 121c66 0 120-55 120-121H489l23-121c-8-4-16-4-23-4zM695 525c0 114-93 207-206 207s-206-94-206-207 93-207 206-207c16 0 27 0 43 4l43-207c-27-4-54-8-85-8-229 0-416 188-416 419s187 419 416 419c225 0 408-180 416-403v-12l-210-4z M973 358a51 51 0 0151 51v563a51 51 0 01-51 51H51a51 51 0 01-51-51V410a51 51 0 0151-51h256a51 51 0 110 102H102v461h819V461h-205a51 51 0 110-102h256zM51 102a51 51 0 110-102h256c141 0 256 115 256 256v388l66-66a51 51 0 1172 72l-154 154a51 51 0 01-72 0l-154-154a51 51 0 1172-72L461 644V256c0-85-69-154-154-154H51z M976 0h-928A48 48 0 000 48v652a48 48 0 0048 48h416V928H200a48 48 0 000 96h624a48 48 0 000-96H560v-180h416a48 48 0 0048-48V48A48 48 0 00976 0zM928 652H96V96h832v556z M412 66C326 132 271 233 271 347c0 17 1 34 4 50-41-48-98-79-162-83a444 444 0 00-46 196c0 207 142 382 337 439h2c19 0 34 15 34 33 0 11-6 21-14 26l1 14C183 973 0 763 0 511 0 272 166 70 393 7A35 35 0 01414 0c19 0 34 15 34 33a33 33 0 01-36 33zm200 893c86-66 141-168 141-282 0-17-1-34-4-50 41 48 98 79 162 83a444 444 0 0046-196c0-207-142-382-337-439h-2a33 33 0 01-34-33c0-11 6-21 14-26L596 0C841 51 1024 261 1024 513c0 239-166 441-393 504A35 35 0 01610 1024a33 33 0 01-34-33 33 33 0 0136-33zM512 704a192 192 0 110-384 192 192 0 010 384z From c617331657aadfe527d63ddf889a76a9c2d17a23 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 15 Apr 2024 17:48:52 +0800 Subject: [PATCH 04/23] fix: wrong path for sublime text command-line interface --- src/Native/MacOS.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Native/MacOS.cs b/src/Native/MacOS.cs index 28519e40..f4ddc2ea 100644 --- a/src/Native/MacOS.cs +++ b/src/Native/MacOS.cs @@ -23,9 +23,8 @@ namespace SourceGit.Native public string FindGitExecutable() { - if (File.Exists("/usr/bin/git")) - return "/usr/bin/git"; - return string.Empty; + // XCode built-in git + return File.Exists("/usr/bin/git") ? "/usr/bin/git" : string.Empty; } public List FindExternalTools() @@ -34,7 +33,7 @@ namespace SourceGit.Native finder.VSCode(() => "/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"); finder.VSCodeInsiders(() => "/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code"); finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/Applications/Fleet.app/Contents/MacOS/Fleet"); - finder.SublimeText(() => "/Applications/Sublime Text.app/Contents/SharedSupport/bin"); + finder.SublimeText(() => "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl"); return finder.Founded; } @@ -69,7 +68,7 @@ namespace SourceGit.Native var tmp = Path.GetTempFileName(); File.WriteAllText(tmp, builder.ToString()); - var proc = Process.Start("/usr/bin/osascript", $"\"{tmp}\""); + var proc = Process.Start("osascript", $"\"{tmp}\""); proc.Exited += (o, e) => File.Delete(tmp); } From fd8f257d6dc435e158ff6798f9bdae0074aed639 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 15 Apr 2024 18:01:15 +0800 Subject: [PATCH 05/23] feature: supports lxterminal on Linux --- src/Native/Linux.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Native/Linux.cs b/src/Native/Linux.cs index 172d598b..176941cc 100644 --- a/src/Native/Linux.cs +++ b/src/Native/Linux.cs @@ -96,7 +96,7 @@ namespace SourceGit.Native { var dir = string.IsNullOrEmpty(workdir) ? "~" : workdir; if (_terminal == null) - App.RaiseException(dir, $"Only supports gnome-terminal/konsole/xfce4-terminal/deepin-terminal!"); + App.RaiseException(dir, $"Only supports gnome-terminal/konsole/xfce4-terminal/lxterminal/deepin-terminal!"); else _terminal.Open(dir); } @@ -158,6 +158,12 @@ namespace SourceGit.Native return new Terminal(test, "--working-directory=\"{0}\""); } + test = Path.Combine(path, "lxterminal"); + if (File.Exists(test)) + { + return new Terminal(test, "--working-directory=\"{0}\""); + } + test = Path.Combine(path, "deepin-terminal"); if (File.Exists(test)) { From 92b80cbcda65ecd8964fb7d82b8d3e2d11f0e3f0 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 15 Apr 2024 18:07:17 +0800 Subject: [PATCH 06/23] code_style: remove unnecessary parentheses --- src/Native/OS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Native/OS.cs b/src/Native/OS.cs index 259b6a22..c3a94037 100644 --- a/src/Native/OS.cs +++ b/src/Native/OS.cs @@ -61,7 +61,7 @@ namespace SourceGit.Native { if (OperatingSystem.IsWindows()) { - var windows = (_backend as Windows); + var windows = _backend as Windows; if (windows.Shell != shell) { windows.Shell = shell; From 69d9edf9639f112cc122999fbcb6a148912102f9 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 15 Apr 2024 20:34:58 +0800 Subject: [PATCH 07/23] ux: add Icons.Submodule.Add --- src/Resources/Icons.axaml | 1 + src/Views/Repository.axaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index a8a31ad3..f645c00e 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -61,6 +61,7 @@ M177 156c-22 5-33 17-36 37c-10 57-33 258-13 278l445 445c23 23 61 23 84 0l246-246c23-23 23-61 0-84l-445-445C437 120 231 145 177 156zM331 344c-26 26-69 26-95 0c-26-26-26-69 0-95s69-26 95 0C357 276 357 318 331 344z M683 537h-144v-142h-142V283H239a44 44 0 00-41 41v171a56 56 0 0014 34l321 321a41 41 0 0058 0l174-174a41 41 0 000-58zm-341-109a41 41 0 110-58a41 41 0 010 58zM649 284V142h-69v142h-142v68h142v142h69v-142h142v-68h-142z M557.7 545.3 789.9 402.7c24-15 31.3-46.5 16.4-70.5c-14.8-23.8-46-31.2-70-16.7L506.5 456.6 277.1 315.4c-24.1-14.8-55.6-7.3-70.5 16.8c-14.8 24.1-7.3 55.6 16.8 70.5l231.8 142.6V819.1c0 28.3 22.9 51.2 51.2 51.2c28.3 0 51.2-22.9 51.2-51.2V545.3h.1zM506.5 0l443.4 256v511.9L506.5 1023.9 63.1 767.9v-511.9L506.5 0z + M770 320a41 41 0 00-56-14l-252 153L207 306a41 41 0 10-43 70l255 153 2 296a41 41 0 0082 0l-2-295 255-155a41 41 0 0014-56zM481 935a42 42 0 01-42 0L105 741a42 42 0 01-21-36v-386a42 42 0 0121-36L439 89a42 42 0 0142 0l335 193a42 42 0 0121 36v87h84v-87a126 126 0 00-63-109L523 17a126 126 0 00-126 0L63 210a126 126 0 00-63 109v386a126 126 0 0063 109l335 193a126 126 0 00126 0l94-54-42-72zM1029 700h-126v-125a42 42 0 00-84 0v126h-126a42 42 0 000 84h126v126a42 42 0 1084 0v-126h126a42 42 0 000-84z M170 470l0 84 86 0 0-84-86 0zM86 598l0-172 852 0 0 172-852 0zM256 298l0-84-86 0 0 84 86 0zM86 170l852 0 0 172-852 0 0-172zM170 726l0 84 86 0 0-84-86 0zM86 854l0-172 852 0 0 172-852 0z M812 864h-29V654c0-21-11-40-28-52l-133-88 134-89c18-12 28-31 28-52V164h28c18 0 32-14 32-32s-14-32-32-32H212c-18 0-32 14-32 32s14 32 32 32h30v210c0 21 11 40 28 52l133 88-134 89c-18 12-28 31-28 52V864H212c-18 0-32 14-32 32s14 32 32 32h600c18 0 32-14 32-32s-14-32-32-32zM441 566c18-12 28-31 28-52s-11-40-28-52L306 373V164h414v209l-136 90c-18 12-28 31-28 52 0 21 11 40 28 52l135 89V695c-9-7-20-13-32-19-30-15-93-41-176-41-63 0-125 14-175 38-12 6-22 12-31 18v-36l136-90z M512 0C233 0 7 223 0 500C6 258 190 64 416 64c230 0 416 200 416 448c0 53 43 96 96 96s96-43 96-96c0-283-229-512-512-512zm0 1023c279 0 505-223 512-500c-6 242-190 436-416 436c-230 0-416-200-416-448c0-53-43-96-96-96s-96 43-96 96c0 283 229 512 512 512z diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index d618ea4c..b38e2242 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -318,7 +318,7 @@ From 37ca14997076af9cd8377ff4c690d0a98b9b10ca Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 16 Apr 2024 09:23:54 +0800 Subject: [PATCH 08/23] fix: get latest version info from sourcegit-scm.github.io instead of api.github.com (#75) --- src/App.axaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 8ef9e336..eeacb56d 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -165,7 +165,7 @@ namespace SourceGit { // Fetch lastest release information. var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(2) }; - var data = await client.GetStringAsync("https://api.github.com/repos/sourcegit-scm/sourcegit/releases/latest"); + var data = await client.GetStringAsync("https://sourcegit-scm.github.io/data/version.json"); // Parse json into Models.Version. var ver = JsonSerializer.Deserialize(data, JsonCodeGen.Default.Version); From 66215cfa9edcc24868342c06550bea73b11cc00e Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 16 Apr 2024 09:34:37 +0800 Subject: [PATCH 09/23] readme: force update contributors' image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e84afc3b..7d62a6b8 100644 --- a/README.md +++ b/README.md @@ -82,5 +82,5 @@ You can set the given environment variable for special tool if it can NOT be fou Thanks to all the people who contribute. - + From ebf139de68a583058bb2f5754f1f4c4bccb3f0db Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 16 Apr 2024 12:37:15 +0800 Subject: [PATCH 10/23] feature: add a deb build script for Linux --- README.md | 1 - build/build.deb.sh | 14 ++++++++++++++ build/build.linux.sh | 4 +--- build/resources/SourceGit.desktop.template | 7 ------- build/resources/deb/DEBIAN/control | 7 +++++++ .../usr/share/applications/sourcegit.desktop | 8 ++++++++ .../resources/deb/usr/share/icons/sourcegit.png | Bin 0 -> 37445 bytes 7 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 build/build.deb.sh delete mode 100644 build/resources/SourceGit.desktop.template create mode 100644 build/resources/deb/DEBIAN/control create mode 100644 build/resources/deb/usr/share/applications/sourcegit.desktop create mode 100644 build/resources/deb/usr/share/icons/sourcegit.png diff --git a/README.md b/README.md index 7d62a6b8..1f54eaaf 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,6 @@ For **Linux** users: * `xdg-open` must be installed to support open native file manager. * Make sure [git-credential-manager](https://github.com/git-ecosystem/git-credential-manager/releases) is installed on your linux, and it requires `ttf-mscorefonts-installer` installed. * Maybe you need to set environment variable `AVALONIA_SCREEN_SCALE_FACTORS`. See https://github.com/AvaloniaUI/Avalonia/wiki/Configuring-X11-per-monitor-DPI. -* Modify `SourceGit.desktop.template` (replace SOURCEGIT_LOCAL_FOLDER with real path) and move it into `~/.local/share/applications`. ## External Tools diff --git a/build/build.deb.sh b/build/build.deb.sh new file mode 100644 index 00000000..0edd46da --- /dev/null +++ b/build/build.deb.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +rm -rf SourceGit resources/deb/opt +dotnet publish ../src/SourceGit.csproj -c Release -r linux-x64 -o SourceGit -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained + +mkdir -p resources/deb/opt/sourcegit +mv SourceGit/SourceGit resources/deb/opt/sourcegit/sourcegit +mv SourceGit/*.so resources/deb/opt/sourcegit/ + +chmod -R 755 resources/deb + +rm -rf SourceGit + +sudo dpkg-deb --build resources/deb \ No newline at end of file diff --git a/build/build.linux.sh b/build/build.linux.sh index 60db33e8..d2c2b6d4 100644 --- a/build/build.linux.sh +++ b/build/build.linux.sh @@ -1,8 +1,6 @@ #!/bin/sh -rm -rf SourceGit +rm -rf SourceGit SourceGit.linux-x64.tar.gz dotnet publish ../src/SourceGit.csproj -c Release -r linux-x64 -o SourceGit -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained -cp resources/SourceGit.desktop.template SourceGit/SourceGit.desktop.template -cp resources/App.icns SourceGit/SourceGit.icns tar -zcvf SourceGit.linux-x64.tar.gz --exclude="*/*.dbg" SourceGit rm -rf SourceGit diff --git a/build/resources/SourceGit.desktop.template b/build/resources/SourceGit.desktop.template deleted file mode 100644 index ec4b7c41..00000000 --- a/build/resources/SourceGit.desktop.template +++ /dev/null @@ -1,7 +0,0 @@ -[Desktop Entry] -Name=SourceGit -Comment=Free & OpenSource Git Client -Exec=SOURCEGIT_LOCAL_FOLDER/SourceGit -Icon=SOURCEGIT_LOCAL_FOLDER/SourceGit.icns -Type=Application -Terminal=false \ No newline at end of file diff --git a/build/resources/deb/DEBIAN/control b/build/resources/deb/DEBIAN/control new file mode 100644 index 00000000..33f0ab98 --- /dev/null +++ b/build/resources/deb/DEBIAN/control @@ -0,0 +1,7 @@ +Package: sourcegit +Version: 8.8 +Priority: optional +Depends: libx11-6, libice6, libsm6 +Architecture: amd64 +Maintainer: longshuang@msn.cn +Description: Open-source & Free Git GUI Client diff --git a/build/resources/deb/usr/share/applications/sourcegit.desktop b/build/resources/deb/usr/share/applications/sourcegit.desktop new file mode 100644 index 00000000..5b5f5bba --- /dev/null +++ b/build/resources/deb/usr/share/applications/sourcegit.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Source Git +Comment=Open-source & Free Git GUI Client +Exec=/opt/sourcegit/sourcegit +Icon=/usr/share/icons/sourcegit.png +Terminal=false +Type=Application +Categories=Development \ No newline at end of file diff --git a/build/resources/deb/usr/share/icons/sourcegit.png b/build/resources/deb/usr/share/icons/sourcegit.png new file mode 100644 index 0000000000000000000000000000000000000000..8cdcd3a8789bad8188578e9518b5b9e209679d22 GIT binary patch literal 37445 zcmc$``6E>CA2)oRGiSyzCdQiGNU}r?NkSZywU|&8YE(ojDoeJUv8IHIHe{r-WGj>; zCKOtjqO!%5L`r0r?Viu~x$nQ>`3XO{<~r}?wVg?1*jue4%aQ>At8A>dI|2ale}w=_ z;{R|zo$n0*4cKfqb3U8-`?)}%d`r;SrLpife+5Z-lb$A%$JyF%KG;6Elw^%yYXo2# z4E@M#xFV+-Dyh}-=m^oSn^s)$;LG3-j>nZZnP-w|&>FQhL&gN&x!JzLk&-_@Wx!i$ z`|LAqZ>M&?+v)Og>ElXY;U8f#`8Z3vjQE%%)d{;Xh5mp4PGWcz11AmPbh7mxmuGSG+bU zkY;n1M7y)uOI_Il#K<4nrYrMpSGG+(ZHr9)&5D})JrpGL*K?+gbo~1a*EBKAWfVJM zenO>ZIORyjPkVp=gLx)ABpy&L-~aeN6=v~k)y~qD-(5$umwI+(=tutS%&{2Qc(CRM zWABY@HxI{0j|%Sm&Uh#3Wm>rKbIa}0gJLVT4YxW%_J6wXf81@;X#3-)ywMTY?1!a( z99^&sPXk|Xt8EfF^!!i5=VxJ`jz)G@njAjdRP8%f zQTpcWz3IP6LvBjhGr9LS`}P+d*c{~5_2_%=n@Mr8 zx`_8ggaS$TzRcK?=W?kz_pG&b^N?xe?3aZ}``bH99;mzZ_w`OWIvgDeb~!i}ckaov zu(GmQPwM%%B_Xym6Ej2S0h#x&ZbG&tY^w(49*-w1} zPtJZ_f7Chw((PM+WY20ot6VAgeGF+P#=e@Fsg&9HvDnrl`w3lnzCDS%V6psF$)t2v zp?D*a8L;|9^}w(1d-YZtTcoh5e!LFuPp2-bh}M%23EN z5EjlXdnQf_ugL}yl!6lc2Kl^6P5`T>+L(N7++@7-M z9+>{jEUOeGJu?LV!rpg%Ja5XBEdVY`l&~01wJ*0^SQ)1=r~!VT9B5~C-K4h~*9Pkm zVXN}3KhK}YpQx?<{GugZ_sx*y(NF@ljl7w)K%)Lp&62jKQfk%AN%zn{LS&rx_++j8 z%1XqRIlq;e_Z_^W!AGoa7tH*A-(1je&!W`S zXs=HU_BF_YbBQ{rCqs(p6*UYjo? zQ~rK52I2jRFd5_BKRL5I`}^vbhoj2Azu36^5YHiKdTwfg@pA} z$oZ^{M_pD+3wM`(vU>AU&)cwyDV`zsrOZPUkZFr>r|Kiwa8% zQ$%2Gl-2rcH@rSh>})TIHQh=rYv63vY7UNNnVdGd^vyE*z0l5x^er>ttjpU%e@^w> zsnPRad3W%&X#qy_j`9iH5@q&HZzN;C>8gB|TxX``(!x3F1jlr!&0%iO;G^$-w+1yB z(LmjmDsuftQ~g$FkmtRl;r-34Uzzq2zuzU}qcWal+tz=(X2CwAYDQBCLlGYYA`7}x zVkilSvdOnemKwL~HnlBopE5HR?fClL@4fQ$QY(--5IP1v^ec7L{nA(pPgov>MxQJd z*PP9IN#zVZfA^sM+;n@(;pMH?fMc@?dF*+-deX^#$AjwSfU&9kPQN!-9S*BnXd6bo z{IFJi2awRV#TSXE0(=i>W$r*TGdIUsun5xR->tWip8Ihx^rJZ`foQ~9<$$?YH130X zC>nc2gzw8X2as5+RcL2-Nt1q;Y);LAqF1JVZq<2c27@SxBldOzG*f09l)-l4kADjC(j(_>6tO( z-wGUAkH*&L-MmVL+YDm~hDc$F65M~r5r)uSKg;$6Y1yh@d+#rYbX;HlvoRW`jz8_n z%D&g0v~gvifA5A}VNcKOGOWn??Z1Dsq^v05KSHSFGTHSOWzbG6=g4JiQXzw991rIm z-O=z+CQao0c62+Z`P_#&Fv_p^=6r{dg3Z*!iv>t6Qa2~E@U%zLRo^7osZgL4^mWU;*U zJq@hz)9vL;zZbI?+_^)qrBoO1uC{935SSS(KQ9UPQ-K7D4!HCCh*~QAbEMl{aV4f{ zi3ysKiQ7$R-8gPdw&a|Q#w?|eTcXEX(1dR*)$P<9!3i{KS&tV2-P%y(ac$yi+gGV0 z=Dgck3XH!gw?=Zw^H*!0K70_S=n!)C$RF1MLEQVM0F8)&d=E=anqVOnNZK)oG;m?{ z%Z5GCoJH4IjFQ>J;OWJ~O-HH78dan|^b+Ss1+&w5Epp)`gnS@StC}bVTT*}4R;!;& z9~m?IA@OzFbrD9ZgOIBFhJRPHx8QbS$5Lo%#2;s8%fmj(G9v9`Lr?{GtNnTfo*_udupNGKQ7|u#S;%4+k_9P zI?iN5cyd4MQ>|?wfH}4hxJ;4IWRtR1x*ZE(DJOIK3zVp?6hO3KT|9#z_BN>etz;_y zp?i~ja=7=MV>x<`a2xJ7P#l9bofbgLl)+sYkV+pun74J=@SOxQynE|dSb}hYso~bA zPN55D4&rE<((X`Oa&T!@@XUg;$T=NrErr^=E78?cdD6peCUO!}^MzhE8{xgeTZx5W zxc+jsB@*!)sCA!=T)0_H;=Q&N1|Yk)^p_z0u7fCI_$mJe<9>E$?&f zYmrJ*MxR^gSxuplYxiobBTcQ{uk0KoESg9#a!p$llVg$xw|gBP8p}y;1Fq`P!|hv>T7`8dp(yJ2Ax-T1 za)tW0Ht*#g)8&I{vueCVilX42D@8pJFemQxlH@j0semT~2|_Sd=?o2CM34&-$PZCu zyW@Bgi4{Xa>WPS>DE!m&2?Qr9+Ok7XR6XzW!S>t{*9I0#HH8^IwWn`+K4(VY^}@1z z0XV)Q{+(cEPF&obnwv>>?Ib6aq3KiT`hbD0yvw zI^$6)jb;wL7GOAzFCHhd)D5nP3kv9|mhI7i;yJ~F0{^@WI8;|{8n;*jA`2v?VrR}? zCs5xGwYDDbKN=F4ooJ~v7&$7Erc}L1Gvl>rjbt1Y5gVc``lbf$<&^5Dyk7|yubZF- zFFO{ZBXbmdbG@@7hXFm%lPq)0$A3uLYhoA<7>SzfLzg$AJI&CY@#18-OSDXFedcG> zRXJdNIv$N_2A1kKK&?VWm4(o44MrjF)H`E|=$qeJc7t-c_xfxwDdNw>)FNh!?I&~26VJ*0Co&n(! zBy8YxG^X330*>iW7&+L-L(y0?N|ag`V8RYC(~@|rf;MtgDa7B@P6ul9c66r`^#)Uu zHJdf9DStfHxIN z-A7MJoJ$sq>hPQvZdJ(^1{TB{z~{OquFTBGj|d@+-S~D0RFDx&#*7J>(WJ;jO{X2l zb>m@#b*5ac!8ev87|oeNV>xSg3C6lBAz}XV@bk~BSW`xQ4+;9lax~QVW+K69@r>Dh zGB=NCwRFE}IXmlbdfkfoLSfn@0{%4m1)+CC^YIeTLJ-f<^;4(oA&1r?_fhmM4c*>N zqZ*z@D|(I5sUn+I7^m$Lz?T*llcMGqHX?%P@Kb#EbB%fbBg-P*R;|CIjK6&GZ>)H9 zxK#AM<+gax^wN=7B=(BxT2KHK;5P`eU7e;}w)Q@Hm_K<-u{P>)~k5y%>=FEd3|d)h~uK&^<8lc&Tq@ z>+{D6GBa($(>JluH{txfYLZkddL&C!dfF4evQp7|xp~Ir^R>0lTXO408ap3)kidtX z{3kn(1H)Pf3Oq+9-nuT1T#O8btRlX)j7hf1~K^ArUs^w z8A#`-IY}bNZF%F`u^df7)@ENzh3T#l2aNU(VR<7e3#I&0kJa zlVm*8`nhXD^ym7K;3K)R;MhkcReh7$xrT!gRHGmn+H|jF)2>Z#hkGfwvmoRo+1Oeg+@JTPJ0)Ny)VYG z6a|=%Q0l`BHl}L+vgt@a5Ve5-d}S$(XWCzkD(HWC6W-T1TNzcAEtK|TEM{8fZrGb< zt7ezzx8iY@C#2bLqHK>xob>nZ{JmWHbBU0WX9v#S8tHv526y~aP^LlLWWb;@fKLTR zdryE7oQwbqW^D+Xxd#1CMb-(TT(4K{s)*yO1~p%MTV~$0{t=Zp>^g}xMiGE-2My00 zYWP(FJrmb&&M^yH>3eHa&fmfvX}tVZgur@AVEi@p(pyZj0u;Jq;L8s8{lj{&?wQNmgnqi$JtRV)spsXXSU>k0gvl(r-IgMq(8hQCwA8kBF zJ@1Wve`krlorvYIcJfisD!4`5RZwDS+}naJL|O=A*L^2f*r9>6?-FSB--ijucZf~d z{%RN)YpBi%6AvnoH{KJzv$ErP&!hf6eFX9P*?qWrv~uZ;{TT6e_gAGSX}AT8vF>A69Wo|F*mIpI^9}L8ZXhlUU&&hwB>r zmNw1kvL;#wTlme@d^Fnflp?-dw13HJ?ZU4MaewPv1Th7;)-Y26)Y7=B{~cM2R_1Qb zycvz%A+ZpC4I)%n=r{HJV~huz^Lmri4bsI0n@$QK|Nd6KA#&9|f^)At_5+2LrL}=| z;|c+zi`0LU_6^t`4T|2!7fe6#jXUlS5zWxY>pSzBHvU~pQ zx$!J9I>)g3%T{=BTfZ8=43x7k*XHgeCToJ>$(1M;x?q*`a#mUp`%)8#J&(~ur%FCp zK!U9FFm*bDTrn<^YzxdQBJKEvdiTI0@4d5Vl*;27yTic#yWs%ZWOC zO_MEdfeZUep<3l;paBoNDN=_0w=(x)0AlRqPj(3^;@y*uA@Kx0P5zpXtVKS^)5>-y zaO~G3bMbd~JuXKDj4#Q1yucEoH|82g^OtP&omx_Fb`9yd!w*a(p1RG|U-KZ(vwC2G z?w`2BPEF}GJUD+j0$KRu#qV$(1p`fS)<2kCxA>!RH7(~P`=vjw?l;%yQX6~ z$Hw?b)cP_QhgpMU*oK6lfP_fdp)`<5W9T}>a56Pgw+JcI+haL8L>46)Lw|D^7{;uL zytNrQVt;r6#qa-BEPomBD`eVYC0OQJ{=5D{C92&DP$p+x4UcL z-B0!>u;zQa*EwywoiY0JCKd?SPEKN>6QchcNDzoL!MI1hwoze|IuRH{N%#-@S)8lMEZ|J#*R*hUOaL|NN?j-Y&KOQTU!r~!_! z4$6{N*Gt0%`S{h|7L|Ww!5rDX3f7hHT-2W${U_~i70g=b-5uC?QN7KM$<85>dfY%* zb!>;)kZNAt?RNy(rPG(7Xtu*TNl|zz<9Xe(VxTxucDsmXJ)J*kk}~t~@zwCk%5Be| zR37aS@y}kluBP-N?4(-ue>3cO>Q-_3G5t4W&Ls`;)9!xvs|6xptN{3Dz5OIJ3S3q1 zHyA6Y9*^Vb3bO9O{N)wqTZsY)x`!MhB0q#siExamYfgKO<79!EF6Go%>J3?V2ZgnT z?f=Gz*S#cImHdY^J1@>X7$`$3e8Vg&P$U_31NB-LO`hczkF8~E7}R00r>q~O;mAQN zZl#{$F9$Q)%lw|N7MzN&A&Yp|u7Bq*MyzW-vxAr4IVA(C|I8m8ZAA|n;sT#dGi_ZX z4^w#o%(z$%c|E@_?5RF!Am54Vx>mW2D}c}?s*7$)nkXXrxr)H@=?R5ED|fdPnm~C z@2M}cWg?Far~keAXY>Cm;*>XUD8{mDCmu;2UolFT`%B?QCwvr6AAC6_?4|Q=eibN^ zxNlejL646NH@>es{Ime>zGj1J?K%YXv~|+4FNZc#Z#YoT>nPK$%$e6ntX^wp_`hCD zrp|TZoN}I}B=^ar$|-GDxis1RC4+5Sh_?n`7OJ`l$}I5HumqW#WPX&716G@Tej;U| zrU^xZ7*OoO;#f=F3hE!~Ffl|jk4v8zYhSD}o<|3v=A+Fa(UxDG*)Yf^;4_~M9G6qY zaf`jFl>=wvIGTQHzc{~$#OV*J%4`W15q^+KOVy1)DY>IoCzqXWM+}Pn+nM@Q3iD74 z=l~p7{(-l=oIDgo{Pkhbtb6^j!gocIhen+>t|hNCWM1$*Rv|{U_67_A{d7#MKRwT* zkYBA3{^OpYJeiJ2i6h@sk#AJ^6oo|&JO^VpqdD#h@KsTGw-_vXOAL)!LRlUZR$^J4 zGF?iUE_&hIKkb0S(ma#Lt9w^Fm`B;v8u;cH?^{do)g1FCaB%!SY}n0YS0+wEU+R`k zDh6~Wwcknu8(G9ro<(>8qrhHdccc0rrPj^=7i#IWE{FI z#4a!+6ZU6#f~e1tUy+L9cd@~S#GAA-;}(dIHOD$kj(qO_l zpZ$ZuV&u!{&JbfzcI-&{xA#x?3Jbt3eadA!`B(A4`u+Gfs43O>d{?cw-USF-e?$G^yokZ+ zbCi_4M8fq%RYMO=C`gTja1Q_v*yH(`#3V7VUosEZz~pbPDnME+<;lV?ov=8E#j5@xCa)KwY_PleYBZZ^Lz4y^JFyOiB7) zmgYUnC+Lib9RS>$(-r_HGARzR_m>HGGl&d@Ae(Y^hzPlTkvnmx z@^at(4bMFi+Gq5it$uyA)Oq8Dg&Pr8|G4@4SLGih-dJ8V%^5fzQ|a5czA>SzKcsjf zFv5u6DN{vd=IkCE7X%LITG#)2keRcZzxr%5X?PB2-aQtxM>3n&p|Q${xsE*Qi3T{* zJt@E4t`Q@TCUZckK-DF{rsEU95R4SQh@2LyFy1D#U+U!=Wc#)tS!!xIVSSASyRFYe z#iyUM0E6$Fz8jgX1D5ZOVUaTQU56Jp8FCe2{EdN+j8eB|{ovrXC)ef%+D6)VHvXmwk3TQOy|L@*U;lr*>aNJ8!a?=TP4M z=w_>lX0L_Jo&%P_B_@A(b-zatF+H?V1^KoaZB*uSSE`>m9|oPS zc=XhX3OliV^v#&M?l%>Pq5Rp~$l%HI^?V%(gWC$i2|5y;DLI@!&J^O6S7!6;R|qjK ztrn(nfCLO153zgL0GGrzQS>?{#;%fmqeh1qrcq?Qfm0b&YY9yb3{@VW-SVn9{r|E6 z`v~|)X;`+iG;e9_-o*Fy(-*~suZ$s=PJ_ki$XQ}!j_;{@Q6ipk>@yK;t@Mh)@(`Q| z+pR^U+>{v?sni_43`McPo%yzct2rB|(ci>!y5uj57+B8ZN%YPPManZOvPy0Xhm(FL zACzEq6ey{j5Co*#N(tnVUhup|7~CS}m$H@%b!%&}AvJ$YL2*umYlN=L!4;F^ZS6OUhieY#X0j23Z^-{F2|Jf^^xiiWAYpM29um8e5ex6F;e_(G!@&$s~3v{@rT zlf*&ibp^o_M*8Na3BYA86Ne%Bjc+6}S z%vMZ!7@Ft^334Cm?fy=5frKML6V;f7pt1o?8T z<>`ZcA^ofWGVMQ@%@-BP>B=E`zbbD+5dW6ra0>C-vH!+JS!XOrfQ3{MDQooYXBtk% z%5RRo$20v2-QoR?5Nd3=tS`v2-zG5*;|JV~s`jqyub-LScoi7f)QTU0dA02KWFT+m z5DL?}`1X*|^TDU90bdsIcw`~6iggxZ?Jy_ur57*MSrqvph*E(q*FeKS$bxm#oamnV z6c`M3Z9cE?t{~tgKAND+;HzHIO-&K~eMaNoJ^z%~ z4K40_|Ne@eoxWmt<%1t&bgi!@F#4+tMcex-yb+@SZu95r*h62>#$zfLH2WA#%YrSN zb?;d1O%W>f24zRN+8OnLQ182{s{>*IeVf?+C$%C=tL>u~$c6X^xV2H_F=GwGRKo}B zX3ykjJc%S6xNQXSZUHP*w8B43{PlR9iwbvSymR>M&$*uA!p3+qmCs~H%0r&+Yx?xq zdgA@LhEb7OOTL;hA+rjMjBs)#!6|*vYd9H;^T|)Ma8G%!{7dJA$L6#b45(NP!0;(9 zMs>BOo=?}Lkt|r!!bHuEB4D^%N4Aa3hO1%$+Z`l8H**5$DiS08p)#b_Y%u%MNuESu z%A0gDE^4wR_h3()Az6e((o2}}Bpfh#Fth505NkO4&Ryd0i;$%;_TDI5ye=oKDJAeqQ3Mg zZjg$YXvgBW9>xv1)+VfJyCyr)nRBQBzP2?V_qwwod^0*6plr$o}! z4*pdFi!w0tG70ZF64q3nAr5NHnFS=4sw^VqOHI{eOJ&{lKBx5nFAOy&rV>Pfvov42 zGUmv8PY~rY(Z*jkLm0_?J@a>f%Udg)9L? z#z&~B1Kdr7bwCZ(+N{h~HVR)56J)(KM80h|!D(d}hPgnJjzkF+pe}P(1_}^`0`|f@ zX7_dj{f#o!!BOx@!}a4+o|mawwOSjfA6(aq@q4`h`IklGoj6!`eMl2wXQVU>#c(5u zx8&GDD-HLy>ZF>gM2p{CLpjeP6~NNKt_TcIz`zLkQ*q`JY4R{wYtt@b(Bl1X`A9;f z%6k8xh|ufu7bn#oO_#;)>Y%04lv6n&yq`zV^K;kNmPO+*D8R!kh>Q)i{rULQyYP1D zfb>rY4Q#LhnQzGn4ejPk|6_Fbg)eRFm0`sIr5=?M>7DJ-fstUp^!D~>3QJgLbMtkf zGcki?&S$@ffy)ODP`0loDZhLlIWPacw1rjkn?YK=6s1Dp96tVHU{J%101LW1I3I=K zJ0^RUMyAKQzGii|E%)}REj}|Yvj1xZ?i$Gd9@Tj;neoZ5{I=JBfR;|$ zZ46fA4C(x)BYZr11HLCu+HSV|*1FjOWWEsv2IfP=yGb$SzlJ70vfKrpuWTzk1Y<`w6?iW{w|VUpBZwy z=40}D==qzwTg~u8ZpCLpKAdk-QG%HdouP|s5eAfcrehOw$d%}RSdvx`ZaL<@ufSlQ zG0by*3^*nfLh!u=^Dn>Z;MsGroaJJkp=LVppjWsSQRTm9V&a(9GglS%1iZBL+5hB| z0$6=DSAz!fN!1%OV?P9KVjFCcH`9+xDKIMp(FZeNj+he>Mc3|EE_=Iw=s-_UT(QS! z_TTB-O6jY?`Dr!KcndHd@~CZ*UDMZGT1!Kk54;PjXu5r`9tB@y0rEdgql35-wfHvd zZD&rze|};*8I;p07;v`)?i?yl59X=E_%&qAT9(k{VxQ1=LJ7b4N3Ja7VpRwjM5N*C zTaDVNY@v9rt(ha7%nv)IG|+>3bYAPwk!~VlxIbs;n@0ZGLsDt)ZZu*K)FjKWSiW~z z7$YpmD&cqewOi9&&)y0{ZTfQ6qnV~dDSWWDCFx{P69bAA2d!?mkC2E^21l3P@Ww)b5j#b0AKR&maht%u(z1LTFyS^ zjl>k2wGp-UYSM21vNU76!5zX-?w`nt>?gq$bwj0tOS0gHnOazZf%e|O{JR;Bw~aib z4>$e(y5ueYz=Hh-h8!fhS`fF49&hz}zYK|rX#O~FjD0OqZ!I~P1`ICCkQ465asG59 zj%&cY_9=RP*>b2Ia zXh&b(*sp6}fk%$CCpUba(qX(=uH@YXx-+&Z4pyX|zYeVF&S}DX_sm8fQ5?PHKH-G6#&FLdaLgeJ|h5D@Ve zhGim#U{La1J@J5(VFsDo!TFnbVwtv=@$sZ^iN{0inCCM>!~GNb{X6pgKU+G(J)v3P zoiHU$ibK<0eX?YW1>`}j3d$Q3w=t3Z((*9;+2&uO3#-)g8El8%V%G%BMPTZy|7T_7 zn77p(@_E*}3Mu1H`o_V90t7%|oz3lY-bQYE@@c`kr!C0hgsCB)8qvYxA!TYY;(i{u z-aM}O{ZV61cFzd|FU$S64F??G&0h~=aU2!kJ24^M5T=RSXQcz0fT$)-wq&;=ki@nQ zL3j9#Pvw6uPC*gfM2#8My}k3YE~Kw^DQ5PNVtnz_Ifc3fnW`;y#K`R0^(R&D_dAq5 zLiS*n7|@q)bLBVrC0k7*j+_d~t^YKdRtedRPdFKlaS)KzC=)@^1J40Mn}#z*dX?Beu!#Ud(i7QFtPq z2u6k#F7lD2jbs_45GOt)fnx?DbfP8$N^4DyuD^LXU`ITZCkmRVK%hOwbGAb;B92yV z&+BngjK0*qhP}9Yg+)Cp=bk3c_N^CR*s9U2$$tFdEir!@>Mni}s`O4OHTS9`yHWAo z8iq{ul)HZ~J*)t(`eD)b%FS5-wh1h>LknpmvW|#nWeKnBQWU?5LJc$MhMM1hIfO%pt zujnm7{^px%sd#Hw-Tr*iB4|OBrb5gg;EFm&->E+@1n8*$S(!N6mN)cRkyY zsn<9pl=jG}d~#+OFeW??Y_xP!e>Z{j{8 zfs|w>+&}umoM48*_?Q|V^xl_+)uS{jU}eL!mSDEvt)B~GCl*Fio|M#di4NRTl}_0f zxNuwu$v@*{mC_EV>-PY!<{kHI6fJN=Nz&WPo*XS1()UCB(;Hk>Sm#anU_;!Ak7^9K z5+kHnq-zu=(Hi}E&$(T5F1)z1QqITzMG4ZzOniA!D587A5Y*gaQ!i(~-YUwGq&^*b zH_z@;x`*U-#XNa)6IruZDVg-uf(G2T(ZbL+v;5P7!RU7(RBsIuOFsXeMr{h}&`!rv z_NMfWbdgy|Lhz#}Pn?WW{_q*p$+uc2{BU)DF{RNyTGn&hSHSEjJd=fose-Fa89YR*6di zj>n-|z%0ZK93*Mthu)oj$fw2UZc_++RDuFW=%qBt{oM{p+>;Y`{2pxn6)nV<^5Nin z%?uhpA$Y@zNr;DbY+R8b`R)sV2ElQ_5DHhn>X2;LQg_St+HB2*@$XP)&7pORdUNLt zR$}u0=a%ILk$U=v&WH@_5AylsSxso^yULg0kYT+;PhFd1Ir2W1svJ!m;Gbl041iCB zOHZ~Xcbs$x9iyI?69blfI>MtfFHi_~*svssgLX)hZfMdd_PJyO6K!eX9CGJHO{PF0 zuAL8?TnJD5OiEjv8KPUO33wW}*`ja`*M(7ohcsmy>n@p=jPHHot?Dca@ORV zS=D$}(~G4S>$wZ>$3kB!XN6;*RmwD3vJbs+7y01C@p^zSYR6;Gh;VT-pNCSpX4DV` z>iOA;h`T4ELarr9CN87+_Rz8q*Badp+6}yVTyvc__q505Kv2CwLsh%1!oHVP{54tj zTT&-Ls5I^3*YMwobSAlj3VxseBVs~(!Ncr$FMrh;TRmPbR%^Q$pfS3HrY_^f`l2!1FnLXvaA@Mq-j`CFLz=a5O zqV~CzyZ?&pzrGdisS{xrUF08$ap*CeQ<2o+034%y+C>QzMYz?K|2EOeTst1@`~0bT z_Ditfp*pJ`qY8dkDqdSq0Y1}LgL(0}+B(^@8y@}{J2Uq-Ykf*qz(Ya&WY@lDHrBo+Z5KCd=<~GJ&tS;qsc=G@rHbOCYRiq zsL6ABO>8uwc-5__QXGxjTtqf})i4*qWSvQEmsxs>ngRRIx}jG?x1MZguEFq)ETZ5|H{Yn_C8eh4y(KRfha>5 z6JTvYjW5|UgAoFM_4BDN&WXi$NOodu(M#dESmx5nZ;bj{J%-MYk--%9Q%qZevWXr|=mD*iChUEDC?cf54F30k*9x`rS2U6C^9jjqm_ZE$(9Lyb1N z&=Jc&w5C_{`!yS_&H1mZl#|25GnE5&V0aq;6@c~>Dze&(cRR0@IjN_O_s zH6>Y)CI9PIDA-2v$vnD>Q0S#wCegqjFfO}^?k$2=lGKy=c&;Py_bWQnZ}BjSuV#*q z>^QXnOBV;fm9ec4h$d0IVa3k6;0=rVzt7D@cEpU|@-DSB2BlV}WMcn5p^}g&er$GI z)o>URxD4$Q<+~vyyawYa3TvHzW#|;jGO*grlY_T(e+tQ)*8pN1jfc5SpZczt-fkOn z4=opWTw^C2#EW~VOF93(9``{oy$68AS=4YO?)*XL#|^g{iM?JWNlz?&nSEV*4}h_J zT(E4TmwY^wV)jvP;~KCb@fR`zhJVvt{)mF^p#RuhX6*7n_*Y)_{P@CnDJQ-~WM7h$ z?DO~wOpCWFjPWl`FQ)tab3z9EP}Zy}GSkw(hqeXx(B`&53_1#1hu zcf;!I$n2+>UokH1v4Jg|%69_Dtw=L0^O8ZQXAGykoQRa!cMl1njOUjN!hS#cxG|$J zoQUtxFDH2BpQC3!p8ceB(vvR+I$vBya32VS$0eDUhZw7YKuy5C;`+O{c#??R;?B#x zACcrMKkEE6H87(^85ZDlXDBB?77EacTqB=ps2Hr8%sK{RIjg}`^Ii8RF!mf^Hnmk{ z!v!$`Q!R1hdmCN8J|DI^d+M_8twRx8{&^no8@KHE%qzap#2cB-2A>m3Z&5q>W@`1Z z0|9I8)fCquJ{PFUT;uR7f~E`$U(Db@c8%$6xw^-l$mmJmRJ1i;yRU(f=D?hB%&B7+wChAvCl063dT*8?OiZr>N{EW6@@SK~o1! z8vK@1Oe>}P5+i^~QY2zx-Xp!BF1Kw3j6V0tq3F|)zT`*>xo%}`l}}EpFm!9pcgdL0 zh+_{0km0B)pB!MpZjS}arXj3Yjur%wpijFNYFfBDTgZk(mbMq8H}rmv8w)x7ybnb! zg(P55_2z^D7u*X<;!s738GZrp;JED;sefj{Pp*irN4_g0b^aZ! z6bM2Y_PAKuT(?I6wBP4KfTemoa<$RxyW_8Zr1f0%t`O#f|&f=QITy-B%*N#^3_P6<9E zG89atOpTe>9Rj|ixYU<~8@@dy~ zas${)*ZZUYT&f$oNv{6(7i2YVPi2&`-L8u_PuR!!O=fT>uO4Old10W6F=Ny7v z5(bf{S{Z=-F=n_ZFWZA8_r9QI{)uW5>qO#V<}_yg z({LXRx5YO&ee#aMPkvd4CPn@`v}RzFN09{S=VLGQ;)_}n>A>kziY#yau>LT`>QCNg zL-OzoiQTgoD`s4em=r#K6pj69f1A6}U|R4?LDs*vRoB!G`eqt+WdnK_8Q*Wkh}M819UvpgAtD?ZgrkFSSl=JQ;F#2Zv_TM86aZ-+ zgY5~vkt;X-wGwtYDSqEfG~)gYQN6VJxLS8|BOkrONE}g45J{tLM{823>PJv()v}Lv z28;)BgscNJew?Anuc!8alNm*m##JHY2#{=ra%Q)zXxO({vK_OWmaYbEoYD*L+1i!$ z=O6@n2fdZH{?6JNgc*VT@8{jtf--ydZNPNmkH{;%HVo@ffN)-FA($my-XQ}BIK46- zB`JVzXZM7fN2N)XE%Q5p#D(^Rjai4l@#J%mJn}y0N^}6Zh|z5ZrS7 zz61{6P!P;={d}a4Mwh1|AYds&0LVrF_R;gNtK9lOXZ2eUJE1ZRW-d!?qR=GiO%y_j z2H(e1PY2D}ilpn0j;x`d_(lajr8d|7vb7EB9E?KZ5XrY$v)J5pkmuy zRIKTdIrSKC_gt(u8HM?(hX_Blp{_G07)MYVU$yItn(%lS;h%rZg!lbdPYK6@IfCHz z3k8M#7vF!^v#V)>gXHm`mGm>*`FBK=#Se_d!z>4BiXXjdeysm67~j>CvwplaZ3{#l z-9sGa<37S#aBMShZj}J)tvSXx;A}-WHV8+V#JRW^bo>OvdK-zYAio^qQ8E{PkUM3U zsJ|@*`rovgO1;n(t_wGozh$T>Z2vOSQS!IF*fD0tPO+0$lwT~MERo%U5>AIwX=T2I zs^AE8L-ix>&jvatWMlQ~O;pT9`=p=#*f!?%8O7YFws9uA1AC%hj(;U-hmFk5#&MIW z!|X~T84=1fjy>%6S(t4z?Z~mVEbuBzUh_?822Gs3P{xee6Njt8U*Sx;?`A0 z0(_(3Iw)W{W4)&w%oKr{N?T10mplWPRh;4!ELEhruNxwD^*X&`k(4!v;@4CjK>=2( z6OIg=6sx|*dH=<@hcgcrLJ1yO-kGILZjV>1*wo0w6)GdZa12kDu~6Ou=SM~gSG-Ha zz)n_jXnmS2HH<3o$7%b$79V>MmFwW(GhD1_A%fb$)AX^`{o-kt^(e^ z2fRy+2cLy76$n_Z7z*Nk!;66eeG@V;a1jO9MS-z+>IT3V zg79POfphQ|fQRnjvECfz)z_8Aj_QcKIFL5KcHXzc^opTk@}1px{tkBtF5bcd=sVP7 zBT?2Deow2GNhy0@6{}zM20j^bs#2>TDkDF3Oy0S(q4@cfmH&?i*_{F+*~bn^ z^QCavMO(-RNZY*Z{lQom1K|JrUV!N_Bfw7xC;^{qz=sJ?$$(w_H>xlVn9YEBYvBKh z_7D~a8X$~sV}4IVa0MNahT65tODSaoDG39^i%m{y^@$aN6u8^!0^R^S5^UCN!G=_h zf4mZ-wDTHu?)~Q%&sRa5>ylSLOWpm2I$wwK7gi0gyl<$E$65M*YzyoK%SCn#p!Z5Q z{*(6c#Y_5^r1yKrAAauOjjB_npF(nIjTxp<)AR9(G+4d|?!+S;pUru~0|+iGi0cc0 zj<(0~kfbb_@Lh*NVBpLcnfLjan_T3AmAYO&5Pn&~RwOmwtM}-m@dylE&v@@#*&3;w?Jd~b8gq@6O+|3A59SL~e835~e4&!pgoknhbZb#qq^>92` zj&HklWeQ+JrR|dd1+NJbHo*N(CEsp1d;ntj+dsM7&ZsZ0-1khQd5;C84!F1A3ri^) zLrr6*UJnIPLWF}00Zk&L(RPZ3LPVBBAiCHV;)(w;!nP>3)Pb16V{z=@6|-84hu+7O zj3N^B?sR|G2MnJ2>{SvU7~Gva&}UBP%3HCcvtiAJ$yau3dkb_0Ahs0c%GD}5(93=SSz#SL8+@)PHu&nxm ztAL5@ykpGuC_$^*h>z89E<`{<8BGL3cv>{n?3Ln3tR$Euc(z!Xnz!siXU-dsX2~ zS0rlUDRw?x0%YtD>@oMzTSpV&cmtO%8fLjGJP1KhnU7PZfm88Qf300vUp870VP!v| z2lr3q0CD?2;`jPriROx$VIZQ#1ZxdLSpiJ`P7Dl_41q;OaK|0E{4vRZ83+IFf-PLD zr#$GmmSU)!R$!TmU)WmeE`O#aA^*B%*6bBUB;S#pAHtmv(J$0d3F+CL&{Gej>RbWF zgzaEpA025!FG$pC@S}(x%f@o3L9Ur*UrIoYZ}{P^J0s*l2A2juq$bu4)o^q$)zpKst^d4$|=}4tuHs z1^B3+M1yI^46UqL%ZhX+hrHM>#6-K+Vr(xUdO;ny8@vFbc{7n}4RI*E5eevs;1}@x z0vlB8_l$*!#y=H7k*~gLe-`_stUurcIV5fv6M_hXmFpwKjMg<|wIl6NX##dJ}cNoxYXQs_WMQraPqE{ z*Qp}ci+|-i6htldw>9mXT-38(k9P;D5jJsE;pfzq-4wB8F;~>E?ex&iIGRWRzIycn zETc>1pS_+uZjX>_?I&#Med%dCWMElO*5}?zhIxal^NJ8N&Yc6?e+=cqe=ifka5G^3 zfgcPo1KT}X3@r^1^#|7XfHiT8CPd^qGwBQzsyUbcD$qK;vAh<<#&g!yarzCPtVh4B zhhdB+y5mk=Q_*W0-abyWpNuXpNYR~&f{Ytc>xQ8vpun zQ%{TwxS&VEOekP1FCk$1gW6agXU?k*eiU3$hmD0(gHY)o%L2b%gtc1{wgbh--G~z} zfed%ee(KdO5d(a@>jrWeFTs#PKq46+BMS!EfcaMls{>(sVIb8O=8a?qmzazyR!f?_ z_r4G8ba``gG+!wEobeVV0pmeEPS951mbl>02YTP;k!(oC(}1mrsy9qa@LE}#x&AlA z>1nhgp45!|XX@7td(1|n&JvnwaXZz79q)V1?7rc`Nm(eGaX5f#_!(+mZ`(N$SRV;I4mOW--N$z*~VSHfnqi9UW`nLIvTg(RXYl?b^=Wr)MP)k!ey z=i<&}yIw+kix0=hVu@B~1j63Z3|8U7L;o7{F5mj=(GT9H1Jq1Pw&z_#0aBaS8LwfB z4%mP1Wj9Z61)`<6{mAZl$P@~;vuKnJ5))R2_&^Um7?Jquz>Ilhuy2IK9=Oz_iNF^* z+*1auo>Kw(3&3y2o-{RXXKGi#$_yh%iUux2z*xy0ShEuuJ$^u`Ns9qnlfv>bKt6F> zsXOAtHfg{6^Gd*u%+2cVaF1 zL*KKWTD+8(_xU1Sao%JratS^2`Y&N|Rr@i1k9+x(TT}f7J*mrR=Hb`IF#6||30G0r z*BDxI;5UVW#|;L+0q+^{4+)am2Zr2SzjuS0L@Flcj$H(+6?H4#fBp+Gm4V7#nV&>E zbPWtUK!%~Z0IXSIphp>a%g@oL&A7rVHZR5BHhkd~je(KSKslG-@=Q81zOd7I?zmmI z`#XVFs(y9mlR{~((dl5{)Yjy`!M1F=BYF#?g>R!1iV#y5-kf}1G>!q4 zT{O{dpUWxj5z7>6uEPHrSu3I$`X`zvhE?-VQf_kl3U3nUZy}gO-&5Tu%=V9}x}P4> zxhZ(ZxZ2{!Yi1t(2T7tUBx@ZSX3!eD0B8etsc!BYC}s>MIO>SK#PQOz3Tt zF#S!^z-V-G&eB1j%jU?_9;dXVVC+}rpiCbFpYgoD8Ia-&G<#K0M1o?1p*T08HywG3!!W=+ z4CiQXTVTzn-i70Ck$`!N)|(ESR~3E3$rK_atlMWCzf-?cmc!zZ$ZoZ$&Y(Njb^c># zjR#nXT5(z~tC?tgmL6&TAA(}#5alAY{0&=o`RB9hK?MK8ncoZ8o8Z!ysy$~n|InpB z*-S_wD%cw-DF1e}+&Y_q{}!&AVAmkk|Ko3u@K!;Y*4^ZkBpz2gk1MJBkK{!_kMIK#!*ar5xrdY<{bqyb&E zY%1*cm|vvoE_xZ5SUy?8QXR)b{AC!U;u5TkV1J8(Kx@OEq7^QuUdi2-`Ly2l55EBH zEx!_zu#X@$BD#T%k4R?UuYWa@Q4I$YtD?km_mBnBW59Tx3J9@-+I9K4?lv=_9S%f3cLv2C( zd_MBq5$E!&7WkX{q%byy+K;(tmn=iiAP?VgVK4azp$JtwJf~y0PxxWx)T~Maxo~*R z#on@%yWY%>I+t285|uxn+yyWk4B}#dU?9bv3Sitfwt&4kAljCJwBD2Z6Y9VYV3WP- zLP*dmL>-dAA_8>M17{hK;n=@y*nBId*|lChxK?ESY0nya zO8eay*#*>q@Dn%fL;V+#8py~(*QOy&=;1_Ai{eIsi}sl}Y_XGhl- z&Z7Me`C{_(%DKCb=~XtOCyJaqwY?vzUCqC~ulbouG3_cJHDYP8h0g>A1JsQ)+`zZY zrao(`eeq>hWtvnc(U;BcaUbqnOxz64RkuJcv1p&mf$Ry;FU;~y5M5I==KFH~PoCQx){b#6!S z+y5d|1V4h~u26tvqJT2jkp!17=r%$3J3W8;(6p)02T1)7`aaKIT;Nag>`5%H)ea-v zi|luxs5!V6M#7_h< z8Kj)7$-eS&#|yyPsjJKd+Lt*mxfc!m7}>kXrh&OnB}konfjYT7uhhdLuy{(IZNp6a169fJ0lqMq&4(4z@bM2W z9q~)qQ%ODgy;#LdwxXx4JYq!ATyl2q=j3p5ZDb?8h~-w-=XO_bX?o^#IA}>;eWG6F zrZ8t5zyIbw2?83D^&onfZT$*i50rkTwKj|vhwjl;jA-n0?Mj_foza3hTQJ*vS&QPs zpkEhl83|VRe$h36c^5%?$Mq?M(*%L5KjV0oIv>gHwjHW5{FxwLOY-BC2^$T+39lq{`?T|UfW z(qMVVvZ&!vRH$ zsdg=qKfK9s4KuuqBS0fg1;@$ebg zH3WhmVQ8mrt44t8gM%=;i#>;-LdnS=VjPKiTNLp2XTsD-VGMC5#$*Z2&w3BAjwS=_ z&1gBTFy@0FDe-9mwqzsaaz&e2a${=8mw6Xz$Pw@mY@rxm_y&R+Nxh}IlX_jyJR{wI zu`1BuHD&jT>m7PkqebiZ{_R80KbwxY*~2d?V_<6YoHk7~mr|*i``&dQPC^dAX$taiS3AXwOZe4b99!7kNxgKb&KcoOdZbXo_n0o1LfDubi|L^lw2=Sdg=66 z2Ot&B!lm+6WIC&15^Qu5162tMJ-h{leIM8J+#LN*rj79*TrZDx}?_tVYs-yEPC@M`Q zeoE)U--2ZXM6@lQP6uZ;S8tD~MqT^BIA>$VSvc#pkq`zyxO)}>|CdrOC@ujsn=}M5 zNU}EpAfe6y{9stG7=M3bjAoy4Q>#f`#Wx+ositTr&;zWP+z&J04@yHwFm1ZB9=5=n zXcDAi{lEcczp=tlquytFKaWK`kb;f~xQ3(wx5IHLA2n;I8?zv_Jf^pvstsc#Nkrkd z48M_Voo0x)Ogwa)`y*$LK6GmahgRa~8II;C+pA{ejmtk8y?B_Wc}`{aihl7$M@@(9 zlAh%sDL*OMxmHbJcpK^_6Phaxo7U_KjTs;e=Efh@uc&frTvzXj0oV0jN%-<+^8jHF z;9?AN9|izyFE359l}ZzVT7y9enD-dKIkE#W1TcFNM2=pU z02o7)Dv;r%*nD@;V2}r0XfBLJ--J1rr^PaMJIG?hR2r_unc+0H)c#{l6RKNZ7um(- zXf#oCI~znsZB|A1&YZ)oz0M%(>T|k1JbtPFbhWR&WXkrOO?6<2_z#8#+hZZ7Ft2Ow z&n{9`$4$|3^iONA7?luY%`Qqas_DhxiD6pea}nQjI$r_rpDf^hFoboil8hMz=+iE^>)DuCm1 z7;|`f@5w(3yOWWE~5EF*y8mW;S@g!rjwV%rAW0Xww|OY$@O5 zPaB$X5!Ou6$Zh-L$ZJcBr~%|U^K9ThzHs)Y;3!Y}Jb>w6GCsK{!1@tD(~zK2Ca{^r zwgg~q;eP1me=z~e8NJmSIC#?`ejX0{PE6;lSB(RH#vN*U|LPhqFeB$a_azgH@LiTm z?~IC6loF%m_Y_^_0YNadL}U zTuyGj#lsa1vww%2SI_{e=4n9iyL1~Uf;!r+pG`|G`w1XHd>JJ+FVjH)r>cwzn9b zp8h_Hh|NKwnl)s$6~kGCs7zV2y+-4jKaxjeRS+!j=}u0?X&?DDFllKkck0Z50t5`C zTH)Zn4)6|%^_|FME5b-?kXl@fpNY`_@HC)rUmNsKe$u`^Ch}_}ydtUT%lClyp-h(n zQVfRDVqf*9kw3`=IC|Fx2rUsX{Ce zHm3M$8Jj8TJ$+254Jmd{CC)Gqsr_eaIb-6U;1-YKs?u@|1Ra(zmarqVkh41Y8}OFC z&Tv?`>|eXtih=OU>k%DcFfQ&}8e2K6oYnSYBLZQh1q4_ichQby8opFo=V8Xq>@U@4 zT7-8Qo!bOB8MA=WJI~keqc4G0e$a~SpagRaV2&M_Sta>j;s}~~c=FYmhzY5Z;Tj!p zgM?o(icbVUD^^Tk2*T{>(}01OhF8IhdKh+y5_6jZG@x8OE{PY&z`T24fN?88ADHQC z%W=+lj_F-WAXq$A$o$T7-&mdpFY*%ep%OAIrj(CD8W-VY{fybmRKHoA+xSh&Npc2q zEuOwcM9vi7B#^0XF^nfOHs6!5;fx#ggy;C{>v`*`1pXCU_;3GQb-0B0@tZMeZ(Nl=re z2+f*og4twu>1Qn6vp1bQz$ZcAtp`JSKoQM+K)RxWpjmEft_!>c|061e)n8)1nr%lI z%_Bnd)nR6^Q)AM81KoN(L}*Of4TZ>hdWfU{nVoh;`Mrw@N1N&hM5_)@ze?0Mw<9)) zEONe}tGe~{h>P3NLao=RyW`sO8M(p%ciWOdejCA?g7BT0nectSN)wnla*d3_>`lOJ z;3p5WAAYljR)|bp{>rUMDYGS;_SdV}*9*a7D7F?J9;%^uZnbbEz3RwDc}Z}-I=`?r zg``qC&HHZzb+zv7ufq3)qe9AxM1qAUKz)NSTBI0jXCN;O%Ai`==C^o9k<9?28~6gK zF(0}T-?Ljc^Rjqzb!Sv}sH+H|$}W+h%pr6K_R%0Ic(4X^0szLGbe0M@8-QdkD=9Lp&m;`j$S;M=vbpGW-N(G zXFvrSwa#+2H3`$qWWB@3E3c|10D4K)ZsKH3DMfo@#mL-{m-KNw=rUpvj$epiyAuls zodgCjM3$<+4ty?w`v|v@@pl?^BF{)c+lrE5SbGss`EKJ`SqQ_FD>BKHMKAX{s2J{e z^Z(oZWzsYV(4PQ~8bY%|s1zlO51bEK!4N$g;90Z2WvK`{tYBMlX5d&6ywV4?T{oO0 zf$-7e$vEiKJ!rNVhS|OVGNj)=rMNnG#xroNLCv_Si@2BQU6vxX#%Mu`tlim;$RZga zsPOT4XaA><*f7wk7o1_+MZS&{y(xGF>GQ%KJ=YTNPPg^mHuzjJ_2{U{`;7eI5X)d# z$U;|NZ(m}wWR)@zroa$N658^KnD?^k2vO`Xr37ILRP}*<+ym{q1@2j#C&|?#S?+%u zBP4;(1_iLLo;qJ_7rg8L+<&Zym?Zhvbcsp^7(2pnn*Ki^GMu~-=+{Gkfv`86=;6;F zkzz?^rJ2r8DR08CSqLJ?R+-)VP}J&-ZgC5K*@==!^ARH(J2=|2Ju3R4bxQo^jhpQe zs>zbaFBdv3D2xqffjXuf5pV;Uq2YDC6Q6zWoJq1(WP(9d>-5bpI^9l|n_;K-ene;n zgr5~qbu5b$Y2HM%4EW5UiSI8dhtMZ_gkDK4mN9CuEr`#@|d*WawFE{KHFVnT4C z5K3Q|STH>7;Ifai=rEBgb@{{Rz;0}VEFF>qXd~#AFN_+bTn7m4OCXz$5nP6=UqMz% zV=ob@7Lfv%b=vLEmg%o(u{@c%m3l!3ZMvAvP{RJIKNE{j9A;>J5gDzT0 zd`Yl}I{Fpnih`&P61VAuC`}~v>7lMKz!8wZ;}~}N#|bDMB&~r2R+DGU_UH0`xZfE` z!@K|@BfnOjU=c?nMCXt9^VsXFy;w*TJQMt6PU3@8@Wcd0YGB{>69#x7ASGaFz#*F2 z`K*reU4&c^!5A~`JZUs)JMaFq1< z(w|}bQdS9Sd+?11n0BzIIm7`*E*P5dMr`5%CAEwt12M7W-h*QxjzkGua=wZlnHIyz z0k(od-oi1phE9~g@Vss1W8>zJz3FD+);L3eF$89emS~U5-d3EPlQKNr!0%9l4e7fO z_)IK$ICzdAmaJs?TgUhkTD`PVAkm@$8*1Kndl+=(YJJ$y|uzL*_ zw5|VKK`_{p8JbmtVa!M|iB~e&K#%VG(k$l?#b#O<87a{)=tfC;^|~M$i6Xy;Fup2g zu)w)v+Sz*D?{*m(E8MSFMR6}tlM&H+@yX?bLbJ5=!VxY4gHp5d3+e5U>+GZQyM=7- zoOz0u%{LpO{=XIghCzCgzrS#GOv{6)UAh~$Yeig(@1(3A5q#&JSB!{5!#r`m>8Bm| z^5~AR75%gH@nG_N>{X`IZ1Tiy^+Tf4Sw_oBH5JkOAYYq!~MG=)e z@bXE)p#J(7v|)M&AKuJFg}b=|t%(#rcEL ziRlSnyYrrv&vp<_6gK;_A3sIeY>U{u8+vp zt+-ORNV>y};HTaxwK09_pz_z%Fhb!LPQ)(xkV2xjx0;LbqEUg<9^FIMa}Am$ukSKk z&0%rT3|j-L`L=YwiDS%>IH-juIhEF?JRes%{`&ooSxKq#Bc?DWo~1te9XlZ~b^L_n zR#r?eQt~qb#t#H9yx6(rax^Q$v+lNF^QfzvgBg^{eCK!|t;38SjD)B3mmZC;}6!SI3HaKL{tc0^V}r%~ue3=YJRya|!jn0wCV zEwp`?)1>n~-xC9lzGe|1L0@pcn5Yx{*|IE8jCRDTh~P|0xQw1Cms1M;yg`FZaXwns zlBgM%pAUNH6YQAe^;L2;>sFwA^S=D*BEfm3&jaZoACWwFc0a^qf}-Sr`pM-Nc6Kul zS5;s9XW69$qX>3zHe=>&!lm;_n21yP@k}1G->ay~Dp{9V{kkBy!1>bg$f1Cy`BaFy z|AA`54>=OF9$rgfhXbHqKPg|ALK%Ngx@-KF%{zw){gV(HpXGAhr3?~ zPZ=-$O@=wJe*I{4?e+op&XeaMWZ<)$#oYkQpvJ6aV9ZtJ)IbAzj-`HWSCV9%X)lQv z&{M4E&0H`)C`t}teb=PY<5oh9c>L*yWR)AMVh*73L`t}fZ$*8&A|J=TxNNqdxu^PI zH1b=7RDl31`#R{7<^Juw`Ur9FIkF}iOLX}?qd^$neyY;)XOEfT>Dm!n`Mg#B44yzB z95j(Aru|b62rXv+{wnj9L8gQFax5;YR8aOEMpN9(U0_?m(2!x}=(tQFZRWeuLm&6f zr<`LC>iG4Tge+4_HBA}vg!HaBkmil5A!myZTOkO$aoTKkf8$5*l?(1Tb>F_@-i_Yg zg3rF2gfIeOMoH-(KcUrlM~M`t8=eQONlzIe?ZVRS;ekrS6&PGa*BnTf&Gk%^I$eQUd*pjfS?=Cubn#^{IEn()2xorCXx zMtp)^Uda{L)JeoJV1iT8Nty=j7yRfe0}?Q=kxX#?>M+F_Uf=8D#;tdQLy>lT%?~~d z?#eX;gw(-a*FOz$=R=q;FD4b=R!mb6XsvL zV0s7lcB)5Tt}$hjEl|NQf<<92&KjA2)sh?UYC+d|8;I=FlZ9FewMb-?-m??}%ZL?I zrU3&JW8;}yCa+4frukI_B5?c>(V8XhjN|3wu9*>!3(lwn#=2%USa0s*2i7h#$P)K>=VR^QcG@5b?yvx%_z(#Wkz z`#;~ozY^H79N8AvH@!1$$Ix8X!rR>RL%{jiGVEhALjE?TAN{NeCYK5`>-W^%v4XH8 zd0WlnW%j!I>1rSo(woOj@VUMPFUIXnPJb+#C7RvPoeS3K9QnM}Pickfx8xh&+0fMX zS8v!%D>Y9g$Sxee*`{9@DN29+-*XG(i^f9MFlVwb(~qlV%59mAdk1|rsH z&Uyx`@_92+Wsn|t@Upo!sw#)F0jFC-t=buMX{u$&s zA1vywrv<){#e&J;`BXmLj{$*{xcQ3{lXY}8CtT?vfrMDdbGliVUM*NkWm`Mu_3>Q2 zrO}wA|2svO$C(Pd1n-4T(Uw&*p75-UoAAA3Pyx(#eQm20em2lPshK@ox~Zsc0us?5 znJ|iCAQI{DQP82={LlrRVC$H930_Pmt!7**Mokir!5SjAlQp^HYcu;-`6J%(H%IXj z)LC}K^ZDB%=q9#WV|Qjk)iP?{Pig?pfWwD7<`lUL)k9cKtgso}%&dj9EKVDs zR8<4^U5Ae*2=)~h_}>o(F_A800Thj(PEHIX-0gNhqP*nu=y-*$MhQv&*H|cNXwH6P zQ$8)6_P1EbMAbVmo@4_@w|ZDdx;cd)fj8NtWU&Qkx|`6EUfE+bK@D5>UV&e{9lOF= zze%osPAde~7xpK+yeKf&6E1sx)hvb7gg>qYoP3cQi+%j&ERLJ@Y&3pm$?m)R;elJg z{<8&Io+idy{`4+GnxL~o53KuUCPYYDbP!yZC(F~12urt&Cs4*RM8OAALa7^)eH=@v zhD!;}cgc=&VTqy6nrsL#&y3F6dv(o_xbiOhsOE%$t3O`zCQ&(#RzkNvxCCU17{hty!pn|yYgm3{ zV|$*n4tX*B@umH9;qKWtRwK4mm0%1hp$Svaqxbhl*6*R=JJ2}Irdtva2*B|_W5C=V zNkG{bck_Foqp!ONynN%)drtDzPC@;fjzD-Eg^Jka6)Am-R+?7l(OBFg75n$eqC)D2 zo=S780gUE2Ht)_F_$(Qp9;v;>_33ZK->G+0EZDTGZd$^AHSb%W#LPdk-{tgbY+)t& z`XtX@Jsh!_*1W9+^&hqNB?OkK!?%uMh;*Sv&j%G3{ZyWV-uwK>~kovjUnoOD$anuc#I+(-!EI+ z02~KA8EgfbLyq3IecJ4NL& z>7)k6BXnafJJ6-8yX~u}fw*eBo^F0mCRqkzs7nyIqNAfzGBf&aP`gKAsWjdxjlHRC zvk7!x5*_#&{?0Kan5T)2VlQ*n9GaSW5oPtkJW5F`n+hjKp<%dC+LW67KGy8+Wvk%p z5hL-DOcTG#BRMV>l?k@-NAO*KmvLiBWV5itaIv%|>zHkA?d0%yz9D#PQbl<+uL34a zS-BB=7KTw#s7y;Nq%i-!Rroc6?uEQ{aKgu?-K$EOPt-m17c(h~G2@{KOakv3YNT+iKis?CHhk|#`fT_iQLTsYj@W01MH z`Li#L8T#tbq;^fdc2DA8%Y0ip*S&R-r#15myy`Epb+;E2yGWs7OgF9-BLs<>!g+ZK zx8ej=Zc!p(t&a)pfOx#)xcHJtXD?_-<0GS~9@`<9G1N4@>zP4w_*df8m+V^&@tD*z zJ-}XiXg;T^{%@e_o*WwRNtq$HF&`r-8tq7F~0*~uV#-gOyX(o)H0e~8jSCKnSzi)RoHk}^Ac7LBA zc_Li+>EvzS98S*{&h1QlSjmSZSE+o0dNIV3uV*#63`RJLe+4jZ%v=-S&SCMMPf7I) zi_EGyx3UvxMgj`YTu3zkY$c!n_7NR}!9BH|$_k&GqYoJ{B|5O-H}==a1GWhp8vGbR z(6{NBONFBI2;R6;u$F@e>&0pX62yNywk@h6>`MJ-S)$@u_;+QWn($*1%ARXtpN^;N zl)sa(p+q-a2L83ohpPFGi?L~czQ0Qsq4IVTct|#x$=Pt-NB9+d_Fo(m#^`?gdFgJS zz&j~V7VEWbmB~7M)#e`ldC|WGIZ{l>4N5`~ZK`oFubrK$?lD1D?Ise^Tm^8;QMpD!N1kL^--7f1V;U(uyuL}pX&Qs72X z1(`9be3SJL#*YNN?>Z-aOxtN~MI5XwovinaCP}x6zDIzo;AgBUC_Sv^f$nNGavIGQ zO`Zs5{sWm+D<7RLjJjoqKRAp0Q>ckHjcg3%-T1yUe?~t`{XOb_Lc}u&_3>BI7@ZYW+tsWI;C8fO7Dso97c3-#vp6 zIHKOmE{*YmDU;ZDt+%}LMu=JJPkahYx1cQ<4e0|TiU9fztE;YS0j^sOeYRo>@|eTh>!SnO`g zrp(8hVf8hkTt+|)(0TV-M7`Tqw0>gsR)V9NMa_amQh$Uv%ZrU`d6tK12AocWlM(kB zN6Dd%d+*rM9<-+a+t0QXXthnqd#tokeOd70r*Gy!Td;VA%$b@81n7#{h<}!urD6{% z;9(CFm}@E&pv^OayQ;=pD;B4Hnv85{*q;zuprHq;XQBfl!m!zT{NF@Q_ImuEpoq>y zv-rOP?;6wF-#Z#Hz1tA|XK`4!ui0dz$?xsWQb>37ehuN6O9$>A=cC)pNWN7oUP_B4 zFe?iYWb@$_&V3h#8^icM-X-}r`6(%Eo5go@dhFqv#K-L;h%JFAG1Xa`Q*W7;YsW4 zfWo-GV4IO#_l$L})&kHS(8Q;I^qV|1Dw2LmNOQWB1^C}TR@koMPfsJ@IjTZ-@9@AU zROf_RuIqQ1c;Xjz8DKAH^O<;!EvL12a*~79pufyp^$ulBHuftfnFL>6!qbnOKfS(o z5#qfzCj+ND=9x&bKbeR8tw~rgXNhOy>{J8N^g2sn0I`#dca@v_-E2<6c5##McIk_uj@i2d=?en%#IBctNwrU^=Nl7@32<#O<%@4`7L#~F*p#O06zE7)L7?V~mgSW}NeH z4U=Q<5Tp!~v%zs0uSQ+#e;eUHQD6AaS3``+C2JNkMx``=Ml*sRPaW5-DbbfQxsA@+ zPY5Qw%w4zC`A_rV*o7~?7E9WjH5)YCHDZ)4Uv#O_KQ8us7k4nk?D**qZ@XZqS}1tn z!ZNdSVV{}*l3d<4N>H@0{YKd~$Kd~vK+8*TR$kcT9SAtzCK)zZw%Asjc%gc|Hjx+9 z(tBLbJC=e_0IouxD-M6Fn}}J9zI_Q|c-1^Ubu#3p%sZvhwHiSGe-}jvxBmD>#6WuJ zhOe6A_HO$G^+S4%^eZ}d#%W;QJkLi$j2sRe!wQaUiHa$nZo6tY%A68pR%U-C{5sYH zf5r|v|BRNiF_9|oM_3%599oV%KeQN$JG4B!oJ3al*7=%}suRm$c<;zk^S1@mMUJ=x z>{=zt|CmC}XSOyt!a6iQ47m|~^ywGEm&)%7XI2Hr!v2>9g^=Ou*$A$K?%M6I20BKx zy*Cy-VgYvjQ``d~u)o93<2MIKvqVmxOuQlRaeZkq=H`SEkI5N;D6_%jDj;p!mSzK zzOmJU8Cb(F@2D7`7oBMD=O8iPuV+sf<(|xv$wO~hd7=JISb{JysDV@^uuoJ@AA9yt zz=%ZO%RaLw^ilLkz_~H;)gm!M;Mf%Gi0;Vg(OJfOv;8B6I!&5r^Fz_2y{b!Q}@@`mNes;coPyx8LU_aH<%=ZmZm zsWOVZ5d`XMXPv?8c9jH_;J2kmGj^@%?diIm8^wp(_{}W$cE0)1`1BN~h*DXss8Si= z^r1x8F=4EQKmxQ=3XuKeq6}|Hp;yiN^xpqYz0bM3M`@z|-`lB!VowTVX6f5@6gZ!b z{xDw#+m!)Q6y>jSw%V)SPFv+b$8?kwV~SZ@K*C0~`6sSJHBPs$Oz13}9{qag-o9Ys zu8@eMNP;&^hdr|i{1?Dk;ML3zhr!7*>De$t%JC67kE-dHp$x^U@Z|WT$w6_((#_D* z!z#wkk`b!Suit3#%U+`)>9hGI$De=2z4_n}n0Fuo>(aj`PzGixI?BPq9jHH-B@!@| z?w=mf+{193E?xfWo*)35@)|V<#in3rFmm$}b&%W6a`UyDtjjCQukX;Jtdqb{ES0yL_jr@ecy$LO-##M{j>V_*$Z|B?Qy%Yy8gNxq}&bGwIK3{5fnu-X_d?Xf@ z_NYlMa5rdJw~#c^?x{&DFYobdhUC)t2;H^l2CuKE)d5NGsJJuad!%(6$amnpzPz@4e#sbrEV7An)O6l@bX9W824gLWSo*f>zoko#- zF~*7MX|pbGji3{&m9p!Vi6ir|s+}Cw`%4$D{cNy{hcXvb0`; zJtfmRpL*81w?S(i7#Xvg0d>mOAKK2?m7I9o8};be&8u!en|%XyPn`)_PY5Hb@79gN<3+ze{}Em&o5Vf;JCSdc zW2GeUd8BWs&YWuRu@D`>QSdC?>2wK2NUxB+ycHjP2g=}wV~m{{F=pZG%Op1e|G4z0 zG;Oc>!HED9TW)J0fTPiv1Wdn=n}uC!caJd|gBuNx9Bvt|&Kdq734GKK;)sV@BLe+4 z5Agdk6tp((^MlS$fWL-BQ#NLDA~7^CF-Dlu;<^cLhe$!@HZk#L$VQ#3ILU{|Zu1=E z#l(;9y4HH!fkNWD8eh3wwz82#$QH`*23t7xL1e*ok;Bc=rLvU*Z1SwV$IfOxSTD@HvbLaLZz-ek;6;Cq6v_v#WqH z5h7O9DJ)}xTEJ-chP7WOF>~j&D0oB*lYc`2x*pxLh3G!g`|#~e3zvX}dG4D`HIJ3| zt};Z{C)C^+(0)IXuqV!#7?Goxf2~kC<@{;FxvJ)tU1wPGHPOgJLY72K#9`=8+ggBT z=#bh}nO{o%kNybi(_FZH^bVd0zd6uG2=a%aCqzDo!YcPkXOk#^{M`gqh|NKB`=t59 zvMc7q2G*g~Qz zPx@ESae3k$*zeXz5{QZ-Bn%lSNgqT{f8xXd3*2X+5YG+FC7D2<<+yOKeX+_fYvl=R{Q3f?ywkG05tB80?cUAjgpsk0XhyQ$mU2nfY}i z5{Z(;P7az&DdUQKf8~^EYS`K}XL^HmZE(W1_UZI0Y!iczn2A)0aV+;cRQw)!vfG zC@jXK+NWAIYV-8+;+dCHSGwaoXQ2VhXVpV|?z#3+Ut0B{Bp6{iLp@n%Oy9c<7{L;A+5yGD+_iWHX*aSfN;zRQ?qy zAZ001(L0_uwT0dqF(S2@>gA^6rR z>gb;2E+DF<_X5qulbBtawO;60b&)hqptJ5t4dG=jkW zd#+jd#6a!ARb+r->h#v~kzIa?;c~y?05vn;*lqW%dJ}*sa^VXb7W>UIe@@Z9yuKbr+(=}qwsDh%mPzjP|fqpDB z8}Mt}63A(e&eF6(hb%>X@%u?tcrb ztKjH^OjZX%>!l8t)*?(UKx!+)Etn?mN8<)a+o6Y~=?`4UX#%YfNxZc8svBhglZ1aua8^G2p>}EX(ls=MkqBkU^f~>( zYG{mPZvHic<~hBiM?TwPZd8 zQ`F!Jsn1no2AYe9%hpwmjtpYGOt3)bg{8v2T-42|?Q*1hpcyh`%4}}xQB_uHe5d(0 z?I}@<4ZgMhu4b<~d4b+k*?bgCUZ^c%x;MT^Zn^ zN5A^+X4fIE_^)mF?ru$3o6;e-8H6d;hCR4G%hS4Sc{nMXn)1(B!1MpqcAZa6ufh74 z5Fo)Ip?HkaLNC%{p$j1dDUqTmMUWy&kzN!y3W0$14kA)a5XA-(0VziWq$I#Ghbja? zy3%_IJvVpe{tNg0v>%_{cXnrI_Stxs8_Z_wKF zc*4R00m=_z_k99W>jtTXLgoOD1eEhs{}KS6HKvotZ_`xs7X;N7`5fZu!jeov2c`Rv zPkXf@NsROD0eCH0ZuC&?&%4<8Mq_G!kj>x22%>iFHm7Z!UW&azBBlyworZBs6N>V| z1NSEkWS$dGyn;^13V-Lcf&_pkHJB~L4DR)8$9QN|gN_MAk0b#tZ*$qa$lK33sWlHH zdAE%#1Ro1%&C@m`4>=H%$Oe6ouR%fAk0lnk*S%VFh@CNz2fyBn-)NePcwq0Q1`Wu? z5*V63qUx%?ET`66O!4Y5=TkD^g^JeQRxCV|JN3Y2V~*w7jbEOxb8KpB>lB>;dy`XRfsKwjWhxgmYV_^C( zHfbB|5^nql+KcWaDRk=VXV&ujmR|>xjR0P)hoFG0@zcNwiWfuON2Er@*Xi<>A#1V1 z03VrCai;iR;_k3i3mHAYv7WQ2f)(mP16<{*;E5FQSsCV=}t*DIoMsIe5tNjjI8n`Zb;Toh~N-1B=hG1~0cYQ7!ow)hN@z7D?P zNqpp{^q%NgQ{UEcq9d^2*h+8)8UW!q<zH-^RkUA+&ny zCdccvrY8#PZaPA~hoIUy#m0Y^YBzqV+;-@ka0t%61Ty*KY17eL5+$twM)B#&>v~Db z-S`1k02c2b%}bY)R;c`N+Z$#&%vFR^hc3; z^KzY*6fB_{-78HfZ{TvobKJHqu?B+LwjE|HYrcJDeP-5wO~L2gQ{-2NFwPJT{D=?K-v+s_n=16?NbDN6EpE zTOyvho?U-=LhPlz7AheK&VeYqEEfZWMIxqD28=4bC8{ZF3r+j)({+xpb;GKgA&4Zy zAfn~(J;fp08P%e5ovNG1)`f?#24&ejn5TES&!dQ3Aprc*{PvrF{Hj!|^{&rZv*JhO zcow8){}-$AiH&rPG8z4+%*Co>X9W=E+PkQHzUK2#LTsJHO3GP6H~Wiyi}a3v?2P8T z2)5v#GuGrCxd{X*fz*sJrvY|c?SDU(0ppslhVnNDusaWA{{{l<36#&N}s zxmBh8$5Hu0IPP_aC$KQxppDAr4pLU&=a4^qaQ*}wkZ%s67=yOOu0=hA7GnKWTDPv7 zI(|Vy4FaD0Sx%2f=wml@8VH6pD!|wb>pc(PBUHmv@MPIc*rs-W?4DhAq%->#>4&gH zU_d}ZP+M(fHqh`m4%^>a#AyPXdDZt?U{{d`Q+JUqjJ72Ueu14p#Ee-f`mcOS5bsX6 z_4{*}naK)jAS^yzH~`%eSBH(nrncC)R`oqJM&`~kJ6EsYI4((!GUF!a=Up^_p3*s5 zaqw6z)SBeWiE)nVtHGbY6*Ikc-l98O$yF|Re9`Su7K-pNO94!;ri*b#Nt@^vPD9xZoTgdhLgKgqtP)>!R(u0 z!KE3wo)3s9T-A~GUSPz+tsmR99gPO!?~c8G?EhEJq9 z|5&l@;K~qC7NBRr|2%@NpsN7M3<&flw-Q2nS`r1blj-a*LRn*=(Xpm?4ct|Df@Oq; zXBQ5jWU&R?o^xsO(_9xi7d?_TZ{i0s5P?(pfq!>i{+iOxq1X>Grot+imLD8gvp)|8 zgHswBg@J8Xf(Mk+emX1uxCbFYD05Zb{w3$jkRw3a%^_;mN#dq1bRi9ki4}#zC`t95 znu5{@-SF@Im+VcyZAybZHnE1m6(Be>!g)c*h&;?;UJBSrl1*NllqLhG!7||Ie_43& zOxfJMbytOS`ixTFxhZd_@hg$NxwldedC!J`0=^99LLtqmcPID9%2@|hdOp1B#+ldF zraRq8amr_jyXd|v;#umC;;UUrhY|Ao3qYI; zZs(?kJllpk$30tq9V~i2n9s&9GugyRmX-zkM!Q1{{o4*a(8IZ`x-X@?cjwP@6 zyYBA21FI1J=2U??2ea3ZLw_pV`zesEoQO>MY<)%FkQx!o^?^HlczDzbUH38o{ZN&E zqGKZsvT%uC?Mbr)SW&U39W|#2FCM?CsF}DrwO!=eZJH>talP%?aDG%y+EX1V&|!2PqbmI6EY>1G191a zRR7AAWp_Tf#q9iC*I?nRWF+P-^NjBunsCGghE<8>)>V!rNtbl662FOB=bRAu4Kj~N zj%m0|I}8hUcp9@++-6Bhuv}ek8|qk{KN6&S`*)f(KtL2(UR86ok5?lY)aQ-%U|z)G3O)=8|+8Ek=a=!2Qct~#tNAgDb3 z%#*9~_XnI{vr&}E=Vqb;1VzFX;g%mqpXDuVd!A;CC`{nX8@avHn;tVgXxjVkLbtiE zJvoyQ9p>Bjv%)!B0kBsI*eSxZh7(2{#+~m+*uP1w`P_eyCSn@W5^nL(Ote$W>d_+? zse5ea*rj7wwMc)PyBho4*-ib`m&~E}X?UJ^7E?^kxC8Hh`GS%a^jc zlM!<8V94Blx2GuFlE%09t*f(y@YQ>NmzhRSJSuFN7JRTNxFB35sM7)bZVHa@?toF$t-+do3CHTSO? zxfFhzr8TT?E9mFe_k2-ALt+a#l3Vu5Z=vL5iWc>lvBc;Or6XBlK2!4y3H_+lW*e6a zaYlbXolehDFBN3jcqMBf8;6?Sx1Zsi^8)!%nq5%v*1i)P=&K!Tvv8zM5<)dv?Id13 zI&Z`;|JvHbZ7qG|gVj*hqm~RgXH&7A>3h+cO?C$zjM-XU?T71WX9UL#pkXe9v7h7J z+kLdPb=()%>p$t3%~DtNv^4zuhezuo#YA~e&#S8?y+1cOHduhNzn9LA!W z=XK%`AHMBr3GKMG<dmWXa=9EXl($e{<3!6}!0Fh8+GcX7ow+olnM-OquDKI%$_`kVLz zw$E4E@z5LhqjcdKPMG3#xn!hftaqK%iDKbFPk!n=KQRrGh=U=yv6#{RRJl6$9+=#( zyU1++fBwrm=_$UVz@+Fl8F_eAH}m44G!=0b+vmne(rnwH>I z1K#SbOc4#%9-V}{N^4K?hOV#m>i5ua@wW;{C|XFN$TT|WJ9>u#Vt{?XH6Y>W@@97z z9g4*7WmgBq0cN5;hMidZcZ*fHtbAwgTLr)s2Shkh3N9fAU3)Tzz5#3FOIDG{HY-CU zt@UgiK4lF}CR2^XKez_L#k1V@m9?mR9cUV(mCNM>1;*g=fz*HtdQB@VSN7V($?bSJ z5bJ}y8tZQ+L|!sOlD9gRb1dQ8}G?nr@KC$h!NnPSQMy5=Gui#+K3+!1KeIx%~MOx+FtrE zX|C%FhhlYT98+(e+aQpKC?+HCYE?HDEvy?*k`4k@tOur*=ux$Mi^SLpR<@MK^tHcW v;=O#cyZh~`k?YCMhf}AUcK@GDc*X_`L^HaO?Fkr_1MFvNWP$sLbs_!_r&b+j literal 0 HcmV?d00001 From de5a60c6dda7e05c978f9c29765a737c6b0a8275 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 16 Apr 2024 14:38:26 +0800 Subject: [PATCH 11/23] update: specify the file name of generated deb package --- build/build.deb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/build.deb.sh b/build/build.deb.sh index 0edd46da..727950af 100644 --- a/build/build.deb.sh +++ b/build/build.deb.sh @@ -1,6 +1,6 @@ #!/bin/sh -rm -rf SourceGit resources/deb/opt +rm -rf SourceGit resources/deb/opt *.deb dotnet publish ../src/SourceGit.csproj -c Release -r linux-x64 -o SourceGit -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained mkdir -p resources/deb/opt/sourcegit @@ -11,4 +11,4 @@ chmod -R 755 resources/deb rm -rf SourceGit -sudo dpkg-deb --build resources/deb \ No newline at end of file +sudo dpkg-deb --build resources/deb ./sourcegit_8.8_amd64.deb From 7f7e5ef5f83cf3f247943c341e4aabd5a6f7756f Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 16 Apr 2024 17:29:36 +0800 Subject: [PATCH 12/23] refactor: rewrite all build scripts * supports generate rpm package on Linux * use a global VERSION file --- README.md | 4 +- build/VERSION | 1 + build/build.deb.sh | 14 ----- build/build.linux.sh | 31 ++++++++++- build/build.osx.command | 15 +++-- build/build.windows.ps1 | 8 +-- .../usr/share/applications/sourcegit.desktop | 0 .../usr/share/icons/sourcegit.png | Bin build/resources/{ => app}/App.icns | Bin build/resources/{ => app}/App.plist | 52 +++++++++--------- build/resources/rpm/SPECS/build.spec | 31 +++++++++++ 11 files changed, 102 insertions(+), 54 deletions(-) create mode 100644 build/VERSION delete mode 100644 build/build.deb.sh rename build/resources/{deb => _common}/usr/share/applications/sourcegit.desktop (100%) rename build/resources/{deb => _common}/usr/share/icons/sourcegit.png (100%) rename build/resources/{ => app}/App.icns (100%) rename build/resources/{ => app}/App.plist (90%) create mode 100644 build/resources/rpm/SPECS/build.spec diff --git a/README.md b/README.md index 1f54eaaf..0954b6d0 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,11 @@ You can download the latest stable from [Releases](https://github.com/sourcegit- For **Windows** users: * **MSYS Git is NOT supported**. Please use official [Git for Windows](https://git-scm.com/download/win) instead. -* `Source.win-x64.zip` may be reported as virus by Windows Defender. I don't know why. I have manually tested the zip to be uploaded using Windows Defender before uploading and no virus was found. If you have installed .NET 8 SDK locally, I suggest you to compile it yourself. And if you have any idea about how to fix this, please open an issue. +* `sourcegit_x.y.win-x64.zip` may be reported as virus by Windows Defender. I don't know why. I have manually tested the zip to be uploaded using Windows Defender before uploading and no virus was found. If you have installed .NET 8 SDK locally, I suggest you to compile it yourself. And if you have any idea about how to fix this, please open an issue. For **macOS** users: -* Download `SourceGit.osx-x64.zip` or `SourceGit.osx-arm64.zip` from Releases. `x64` for Intel and `arm64` for Apple Silicon. +* Download `sourcegit_x.y.osx-x64.zip` or `sourcegit_x.y.osx-arm64.zip` from Releases. `x64` for Intel and `arm64` for Apple Silicon. * Move `SourceGit.app` to `Applications` folder. * Make sure your mac trusts all software from anywhere. For more information, search `spctl --master-disable`. * Make sure [git-credential-manager](https://github.com/git-ecosystem/git-credential-manager/releases) is installed on your mac. diff --git a/build/VERSION b/build/VERSION new file mode 100644 index 00000000..83ea3179 --- /dev/null +++ b/build/VERSION @@ -0,0 +1 @@ +8.8 \ No newline at end of file diff --git a/build/build.deb.sh b/build/build.deb.sh deleted file mode 100644 index 727950af..00000000 --- a/build/build.deb.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -rm -rf SourceGit resources/deb/opt *.deb -dotnet publish ../src/SourceGit.csproj -c Release -r linux-x64 -o SourceGit -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained - -mkdir -p resources/deb/opt/sourcegit -mv SourceGit/SourceGit resources/deb/opt/sourcegit/sourcegit -mv SourceGit/*.so resources/deb/opt/sourcegit/ - -chmod -R 755 resources/deb - -rm -rf SourceGit - -sudo dpkg-deb --build resources/deb ./sourcegit_8.8_amd64.deb diff --git a/build/build.linux.sh b/build/build.linux.sh index d2c2b6d4..b5dd854b 100644 --- a/build/build.linux.sh +++ b/build/build.linux.sh @@ -1,6 +1,31 @@ #!/bin/sh -rm -rf SourceGit SourceGit.linux-x64.tar.gz +version=`cat ./VERSION` + +# Cleanup +rm -rf SourceGit *.tar.gz resources/deb/opt *.deb *.rpm + +# Compile dotnet publish ../src/SourceGit.csproj -c Release -r linux-x64 -o SourceGit -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained -tar -zcvf SourceGit.linux-x64.tar.gz --exclude="*/*.dbg" SourceGit -rm -rf SourceGit +mv SourceGit/SourceGit SourceGit/sourcegit +rm -f SourceGit/*.dbg + +# General Linux archive +tar -zcvf sourcegit_${version}.linux-x64.tar.gz SourceGit + +# Debain/Ubuntu package +mkdir -p resources/deb/opt/sourcegit/ +mkdir -p resources/deb/usr/bin +mkdir -p resources/deb/usr/share/applications +mkdir -p resources/deb/usr/share/icons +cp -f SourceGit/* resources/deb/opt/sourcegit/ +cp -r resources/_common/usr resources/deb/ +chmod -R 755 resources/deb +sed -i "2s/.*/Version: ${version}/g" resources/deb/DEBIAN/control +dpkg-deb --build resources/deb ./sourcegit_${version}-1_amd64.deb + +# Redhat/CentOS/Fedora package +rpmbuild -bb --target=x86_64 resources/rpm/SPECS/build.spec --define "_topdir `pwd`/resources/rpm" --define "_version ${version}" +mv resources/rpm/RPMS/x86_64/sourcegit-${version}-1.x86_64.rpm . + +rm -rf SourceGit \ No newline at end of file diff --git a/build/build.osx.command b/build/build.osx.command index 2d4127c1..5e5beb70 100644 --- a/build/build.osx.command +++ b/build/build.osx.command @@ -1,17 +1,22 @@ #!/bin/sh -rm -rf SourceGit.app +version=`cat ./VERSION` + +rm -rf SourceGit.app *.zip mkdir -p SourceGit.app/Contents/Resources -cp resources/App.plist SourceGit.app/Contents/Info.plist -cp resources/App.icns SourceGit.app/Contents/Resources/App.icns +cp resources/app/App.plist SourceGit.app/Contents/Info.plist +cp resources/app/App.icns SourceGit.app/Contents/Resources/App.icns +sed -i "s/SOURCE_GIT_VERSION/${version}/g" SourceGit.app/Contents/Info.plist mkdir -p SourceGit.app/Contents/MacOS dotnet publish ../src/SourceGit.csproj -c Release -r osx-arm64 -o SourceGit.app/Contents/MacOS -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained -zip SourceGit.osx-arm64.zip -r SourceGit.app -x "*/*\.dsym/*" +zip sourcegit_${version}.osx-arm64.zip -r SourceGit.app -x "*/*\.dsym/*" rm -rf SourceGit.app/Contents/MacOS mkdir -p SourceGit.app/Contents/MacOS dotnet publish ../src/SourceGit.csproj -c Release -r osx-x64 -o SourceGit.app/Contents/MacOS -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained -zip SourceGit.osx-x64.zip -r SourceGit.app -x "*/*\.dsym/*" +zip sourcegit_${version}.osx-x64.zip -r SourceGit.app -x "*/*\.dsym/*" + +rm -rf SourceGit.app \ No newline at end of file diff --git a/build/build.windows.ps1 b/build/build.windows.ps1 index e18e58e8..ddca1e1e 100644 --- a/build/build.windows.ps1 +++ b/build/build.windows.ps1 @@ -1,13 +1,13 @@ +$version = Get-Content .\VERSION + if (Test-Path SourceGit) { Remove-Item SourceGit -Recurse -Force } -if (Test-Path SourceGit.win-x64.zip) { - Remove-Item SourceGit.win-x64.zip -Force -} +Remove-Item *.zip -Force dotnet publish ..\src\SourceGit.csproj -c Release -r win-x64 -o SourceGit -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained Remove-Item SourceGit\*.pdb -Force -Compress-Archive -Path SourceGit -DestinationPath SourceGit.win-x64.zip +Compress-Archive -Path SourceGit -DestinationPath "sourcegit_$version.win-x64.zip" diff --git a/build/resources/deb/usr/share/applications/sourcegit.desktop b/build/resources/_common/usr/share/applications/sourcegit.desktop similarity index 100% rename from build/resources/deb/usr/share/applications/sourcegit.desktop rename to build/resources/_common/usr/share/applications/sourcegit.desktop diff --git a/build/resources/deb/usr/share/icons/sourcegit.png b/build/resources/_common/usr/share/icons/sourcegit.png similarity index 100% rename from build/resources/deb/usr/share/icons/sourcegit.png rename to build/resources/_common/usr/share/icons/sourcegit.png diff --git a/build/resources/App.icns b/build/resources/app/App.icns similarity index 100% rename from build/resources/App.icns rename to build/resources/app/App.icns diff --git a/build/resources/App.plist b/build/resources/app/App.plist similarity index 90% rename from build/resources/App.plist rename to build/resources/app/App.plist index 3327c5d8..01d93ad7 100644 --- a/build/resources/App.plist +++ b/build/resources/app/App.plist @@ -1,26 +1,26 @@ - - - - - CFBundleIconFile - App.icns - CFBundleIdentifier - com.sourcegit-scm.sourcegit - CFBundleName - SourceGit - CFBundleVersion - 8.8.0 - LSMinimumSystemVersion - 10.12 - CFBundleExecutable - SourceGit - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - 8.8 - NSHighResolutionCapable - - - + + + + + CFBundleIconFile + App.icns + CFBundleIdentifier + com.sourcegit-scm.sourcegit + CFBundleName + SourceGit + CFBundleVersion + SOURCE_GIT_VERSION.0 + LSMinimumSystemVersion + 10.12 + CFBundleExecutable + SourceGit + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleShortVersionString + SOURCE_GIT_VERSION + NSHighResolutionCapable + + + diff --git a/build/resources/rpm/SPECS/build.spec b/build/resources/rpm/SPECS/build.spec new file mode 100644 index 00000000..2e6875a6 --- /dev/null +++ b/build/resources/rpm/SPECS/build.spec @@ -0,0 +1,31 @@ +Name: sourcegit +Version: %_version +Release: 1 +Summary: Open-source & Free Git Gui Client +License: MIT +URL: https://sourcegit-scm.github.io/ +Source: https://github.com/sourcegit-scm/sourcegit/archive/refs/tags/v%_version.tar.gz +Requires: libX11.so.6 +Requires: libSM.so.6 + +%define _build_id_links none + +%description +Open-source & Free Git Gui Client + +%install +mkdir -p $RPM_BUILD_ROOT/opt/sourcegit +mkdir -p $RPM_BUILD_ROOT/usr/bin +mkdir -p $RPM_BUILD_ROOT/usr/share/applications +mkdir -p $RPM_BUILD_ROOT/usr/share/icons +cp -r ../../_common/usr $RPM_BUILD_ROOT/ +cp -f ../../../SourceGit/* $RPM_BUILD_ROOT/opt/sourcegit/ +chmod 755 -R $RPM_BUILD_ROOT + +%files +/opt +/usr/bin +/usr/share + +%changelog +# skip \ No newline at end of file From b926dc055dc96f220439e440ba999f4456e6fe6f Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 16 Apr 2024 19:50:40 +0800 Subject: [PATCH 13/23] update: git ignore files & folders --- .gitignore | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 05b24d8a..ed1d7c43 100644 --- a/.gitignore +++ b/.gitignore @@ -596,14 +596,11 @@ package-lock.json *.db-shm *.db-wal -## SourceGit ### - -# Output folders. -[Bb]uild/[Ss]ource[Gg]it/ -[Bb]uild/[Ss]ource[Gg]it.app/ - -# Files -SourceGit.win-x64.zip -SourceGit.linux-x64.tar.gz -SourceGit.osx-x64.zip -SourceGit.osx-arm64.zip \ No newline at end of file +# SourceGit output files +build/resources/ +build/SourceGit/ +build/SourceGit.app/ +build/*.zip +build/*.tar.gz +build/*.deb +build/*.rpm From 27265dc465b0ef8c38160520fe64cee6d2792efe Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 16 Apr 2024 20:32:18 +0800 Subject: [PATCH 14/23] fix: use sed to replace version in plist failed on macOS --- build/build.osx.command | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/build.osx.command b/build/build.osx.command index 5e5beb70..df3222b0 100644 --- a/build/build.osx.command +++ b/build/build.osx.command @@ -5,9 +5,8 @@ version=`cat ./VERSION` rm -rf SourceGit.app *.zip mkdir -p SourceGit.app/Contents/Resources -cp resources/app/App.plist SourceGit.app/Contents/Info.plist cp resources/app/App.icns SourceGit.app/Contents/Resources/App.icns -sed -i "s/SOURCE_GIT_VERSION/${version}/g" SourceGit.app/Contents/Info.plist +sed "s/SOURCE_GIT_VERSION/${version}/g" resources/app/App.plist > SourceGit.app/Contents/Info.plist mkdir -p SourceGit.app/Contents/MacOS dotnet publish ../src/SourceGit.csproj -c Release -r osx-arm64 -o SourceGit.app/Contents/MacOS -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained From 3a3c0e717f65b3fd3fbefba3cfd902faf508dd90 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 17 Apr 2024 11:00:48 +0800 Subject: [PATCH 15/23] build: read version from VERSION file --- SourceGit.sln | 58 ++++++++++++++++++++++++++++++++++++---- build/VERSION => VERSION | 0 build/build.linux.sh | 4 +-- build/build.osx.command | 4 +-- build/build.windows.ps1 | 2 +- src/SourceGit.csproj | 2 +- 6 files changed, 59 insertions(+), 11 deletions(-) rename build/VERSION => VERSION (100%) diff --git a/SourceGit.sln b/SourceGit.sln index 1efe00f1..80921840 100644 --- a/SourceGit.sln +++ b/SourceGit.sln @@ -13,11 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{773082AC EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "resources", "resources", "{FD384607-ED99-47B7-AF31-FB245841BC92}" - ProjectSection(SolutionItems) = preProject - build\resources\App.icns = build\resources\App.icns - build\resources\App.plist = build\resources\App.plist - build\resources\SourceGit.desktop.template = build\resources\SourceGit.desktop.template - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{F45A9D95-AF25-42D8-BBAC-8259C9EEE820}" EndProject @@ -36,6 +31,48 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "files", "files", "{3AB707DB global.json = global.json LICENSE = LICENSE README.md = README.md + VERSION = VERSION + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "app", "app", "{ABC98884-F023-4EF4-A9C9-5DE9452BE955}" + ProjectSection(SolutionItems) = preProject + build\resources\app\App.icns = build\resources\app\App.icns + build\resources\app\App.plist = build\resources\app\App.plist + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_common", "_common", "{04FD74B1-FBDB-496E-A48F-3D59D71FF952}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "usr", "usr", "{76639799-54BC-45E8-BD90-F45F63ACD11D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bin", "bin", "{2E27E952-846B-4D75-A426-D22151277864}" + ProjectSection(SolutionItems) = preProject + build\resources\_common\usr\bin\sourcegit = build\resources\_common\usr\bin\sourcegit + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "share", "share", "{A3ABAA7C-EE14-4448-B466-6E69C1347E7D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "applications", "applications", "{2AF28D3B-14A8-46A8-B828-157FAAB1B06F}" + ProjectSection(SolutionItems) = preProject + build\resources\_common\usr\share\applications\sourcegit.desktop = build\resources\_common\usr\share\applications\sourcegit.desktop + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "icons", "icons", "{7166EC6C-17F5-4B5E-B38E-1E53C81EACF6}" + ProjectSection(SolutionItems) = preProject + build\resources\_common\usr\share\icons\sourcegit.png = build\resources\_common\usr\share\icons\sourcegit.png + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "deb", "deb", "{9C2F0CDA-B56E-44A5-94B6-F3EA7AC20CDC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DEBIAN", "DEBIAN", "{F101849D-BDB7-40D4-A516-751150C3CCFC}" + ProjectSection(SolutionItems) = preProject + build\resources\deb\DEBIAN\control = build\resources\deb\DEBIAN\control + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "rpm", "rpm", "{9BA0B044-0CC9-46F8-B551-204F149BF45D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SPECS", "SPECS", "{7802CD7A-591B-4EDD-96F8-9BF3F61692E4}" + ProjectSection(SolutionItems) = preProject + build\resources\rpm\SPECS\build.spec = build\resources\rpm\SPECS\build.spec EndProjectSection EndProject Global @@ -56,6 +93,17 @@ Global {2091C34D-4A17-4375-BEF3-4D60BE8113E4} = {49A7C2D6-558C-4FAA-8F5D-EEE81497AED7} {FD384607-ED99-47B7-AF31-FB245841BC92} = {773082AC-D9C8-4186-8521-4B6A7BEE6158} {67B6D05F-A000-40BA-ADB4-C9065F880D7B} = {F45A9D95-AF25-42D8-BBAC-8259C9EEE820} + {ABC98884-F023-4EF4-A9C9-5DE9452BE955} = {FD384607-ED99-47B7-AF31-FB245841BC92} + {04FD74B1-FBDB-496E-A48F-3D59D71FF952} = {FD384607-ED99-47B7-AF31-FB245841BC92} + {76639799-54BC-45E8-BD90-F45F63ACD11D} = {04FD74B1-FBDB-496E-A48F-3D59D71FF952} + {2E27E952-846B-4D75-A426-D22151277864} = {76639799-54BC-45E8-BD90-F45F63ACD11D} + {A3ABAA7C-EE14-4448-B466-6E69C1347E7D} = {76639799-54BC-45E8-BD90-F45F63ACD11D} + {2AF28D3B-14A8-46A8-B828-157FAAB1B06F} = {A3ABAA7C-EE14-4448-B466-6E69C1347E7D} + {7166EC6C-17F5-4B5E-B38E-1E53C81EACF6} = {A3ABAA7C-EE14-4448-B466-6E69C1347E7D} + {9C2F0CDA-B56E-44A5-94B6-F3EA7AC20CDC} = {FD384607-ED99-47B7-AF31-FB245841BC92} + {F101849D-BDB7-40D4-A516-751150C3CCFC} = {9C2F0CDA-B56E-44A5-94B6-F3EA7AC20CDC} + {9BA0B044-0CC9-46F8-B551-204F149BF45D} = {FD384607-ED99-47B7-AF31-FB245841BC92} + {7802CD7A-591B-4EDD-96F8-9BF3F61692E4} = {9BA0B044-0CC9-46F8-B551-204F149BF45D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7FF1B9C6-B5BF-4A50-949F-4B407A0E31C9} diff --git a/build/VERSION b/VERSION similarity index 100% rename from build/VERSION rename to VERSION diff --git a/build/build.linux.sh b/build/build.linux.sh index b5dd854b..080341bf 100644 --- a/build/build.linux.sh +++ b/build/build.linux.sh @@ -1,6 +1,6 @@ #!/bin/sh -version=`cat ./VERSION` +version=`cat ../VERSION` # Cleanup rm -rf SourceGit *.tar.gz resources/deb/opt *.deb *.rpm @@ -28,4 +28,4 @@ dpkg-deb --build resources/deb ./sourcegit_${version}-1_amd64.deb rpmbuild -bb --target=x86_64 resources/rpm/SPECS/build.spec --define "_topdir `pwd`/resources/rpm" --define "_version ${version}" mv resources/rpm/RPMS/x86_64/sourcegit-${version}-1.x86_64.rpm . -rm -rf SourceGit \ No newline at end of file +rm -rf SourceGit diff --git a/build/build.osx.command b/build/build.osx.command index df3222b0..985dbebc 100644 --- a/build/build.osx.command +++ b/build/build.osx.command @@ -1,6 +1,6 @@ #!/bin/sh -version=`cat ./VERSION` +version=`cat ../VERSION` rm -rf SourceGit.app *.zip @@ -18,4 +18,4 @@ mkdir -p SourceGit.app/Contents/MacOS dotnet publish ../src/SourceGit.csproj -c Release -r osx-x64 -o SourceGit.app/Contents/MacOS -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained zip sourcegit_${version}.osx-x64.zip -r SourceGit.app -x "*/*\.dsym/*" -rm -rf SourceGit.app \ No newline at end of file +rm -rf SourceGit.app diff --git a/build/build.windows.ps1 b/build/build.windows.ps1 index ddca1e1e..392a1ec3 100644 --- a/build/build.windows.ps1 +++ b/build/build.windows.ps1 @@ -1,4 +1,4 @@ -$version = Get-Content .\VERSION +$version = Get-Content ..\VERSION if (Test-Path SourceGit) { Remove-Item SourceGit -Recurse -Force diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index ecad8b6c..4a078c8b 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -5,7 +5,7 @@ true App.manifest App.ico - 8.8 + $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)\\..\\VERSION")) false true true From 1e3711e569ab7ba8885fb502bfc1024f37f72642 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 17 Apr 2024 16:16:11 +0800 Subject: [PATCH 16/23] refactor: using a new DotBrushProperty instead of calling Application.TryGetResource --- src/Views/Histories.axaml | 1 + src/Views/Histories.axaml.cs | 23 +++++++++-------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 0dfedc9a..9077d500 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -131,6 +131,7 @@ diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs index 4a214784..13f05aff 100644 --- a/src/Views/Histories.axaml.cs +++ b/src/Views/Histories.axaml.cs @@ -99,19 +99,18 @@ namespace SourceGit.Views set => SetValue(BindingDataGridProperty, value); } - static CommitGraph() + public static readonly StyledProperty DotBrushProperty = + AvaloniaProperty.Register(nameof(DotBrush), Brushes.Transparent); + + public IBrush DotBrush { - AffectsRender(BindingDataGridProperty, GraphProperty); + get => GetValue(DotBrushProperty); + set => SetValue(DotBrushProperty, value); } - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + static CommitGraph() { - base.OnPropertyChanged(change); - - if (change.Property.Name == "ActualThemeVariant") - { - InvalidateVisual(); - } + AffectsRender(BindingDataGridProperty, GraphProperty, DotBrushProperty); } public override void Render(DrawingContext context) @@ -153,11 +152,7 @@ namespace SourceGit.Views DrawCurves(context, top, bottom); // Draw connect dots - Brush dotFill = null; - if (App.Current.TryGetResource("Brush.Contents", App.Current.ActualThemeVariant, out object res) && res is SolidColorBrush) - { - dotFill = res as SolidColorBrush; - } + IBrush dotFill = DotBrush; foreach (var dot in graph.Dots) { if (dot.Center.Y < top) From 60a4d21ce7ab2c8c05e07e05de0ca57457e29ee5 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 17 Apr 2024 17:13:28 +0800 Subject: [PATCH 17/23] enhance: AutoFocusBehaviour will move cursor to the end of contents --- src/Views/AutoFocusBehaviour.cs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Views/AutoFocusBehaviour.cs b/src/Views/AutoFocusBehaviour.cs index d7423a49..9437abc9 100644 --- a/src/Views/AutoFocusBehaviour.cs +++ b/src/Views/AutoFocusBehaviour.cs @@ -1,4 +1,5 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Input; namespace SourceGit.Views @@ -6,17 +7,11 @@ namespace SourceGit.Views public class AutoFocusBehaviour : AvaloniaObject { public static readonly AttachedProperty IsEnabledProperty = - AvaloniaProperty.RegisterAttached("IsEnabled", false, false); + AvaloniaProperty.RegisterAttached("IsEnabled", false, false); static AutoFocusBehaviour() { - IsEnabledProperty.Changed.AddClassHandler((input, e) => - { - if (input.GetValue(IsEnabledProperty)) - { - input.AttachedToVisualTree += (o, _) => (o as InputElement).Focus(NavigationMethod.Directional); - } - }); + IsEnabledProperty.Changed.AddClassHandler(OnIsEnabledChanged); } public static bool GetIsEnabled(AvaloniaObject elem) @@ -28,5 +23,18 @@ namespace SourceGit.Views { elem.SetValue(IsEnabledProperty, value); } + + private static void OnIsEnabledChanged(TextBox elem, AvaloniaPropertyChangedEventArgs e) + { + if (GetIsEnabled(elem)) + { + elem.AttachedToVisualTree += (o, _) => + { + var text = o as TextBox; + text.Focus(NavigationMethod.Directional); + text.CaretIndex = text.Text == null ? 0 : text.Text.Length; + }; + } + } } } From 8378f018b1f3b94824ba45620056cd67f45f3ad5 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 17 Apr 2024 20:05:40 +0800 Subject: [PATCH 18/23] enhance: use `restore` instead of `reset` to discard changes (#76) --- src/Commands/Discard.cs | 6 +++--- src/Commands/Restore.cs | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Commands/Discard.cs b/src/Commands/Discard.cs index 072dc59a..22b579a3 100644 --- a/src/Commands/Discard.cs +++ b/src/Commands/Discard.cs @@ -7,7 +7,7 @@ namespace SourceGit.Commands { public static void All(string repo) { - new Reset(repo, "HEAD", "--hard").Exec(); + new Restore(repo).Exec(); new Clean(repo).Exec(); } @@ -37,7 +37,7 @@ namespace SourceGit.Commands for (int i = 0; i < needCheckout.Count; i += 10) { var count = Math.Min(10, needCheckout.Count - i); - new Checkout(repo).Files(needCheckout.GetRange(i, count)); + new Restore(repo, needCheckout.GetRange(i, count), "--worktree --recurse-submodules").Exec(); } } @@ -49,7 +49,7 @@ namespace SourceGit.Commands var files = new List(); for (int j = 0; j < count; j++) files.Add(changes[i + j].Path); - new Restore(repo, files, "--staged --worktree").Exec(); + new Restore(repo, files, "--staged --worktree --recurse-submodules").Exec(); } } } diff --git a/src/Commands/Restore.cs b/src/Commands/Restore.cs index 12a2eaa1..7a363543 100644 --- a/src/Commands/Restore.cs +++ b/src/Commands/Restore.cs @@ -5,6 +5,13 @@ namespace SourceGit.Commands { public class Restore : Command { + public Restore(string repo) + { + WorkingDirectory = repo; + Context = repo; + Args = "restore . --source=HEAD --staged --worktree --recurse-submodules"; + } + public Restore(string repo, List files, string extra) { WorkingDirectory = repo; From 8d7df75241456e1668a3b58fb9bfad929c5f2728 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 18 Apr 2024 09:38:28 +0800 Subject: [PATCH 19/23] readme: minimum version of git required by this app (#76) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0954b6d0..4ccde98f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Opensource Git GUI client. ## How to use -**To use this tool, you need to install Git first.** +**To use this tool, you need to install Git(>=2.23.0) first.** You can download the latest stable from [Releases](https://github.com/sourcegit-scm/sourcegit/releases/latest) or download workflow artifacts from [Github Actions](https://github.com/sourcegit-scm/sourcegit/actions) to try this app based on latest commits. @@ -50,7 +50,7 @@ For **macOS** users: For **Linux** users: * `xdg-open` must be installed to support open native file manager. -* Make sure [git-credential-manager](https://github.com/git-ecosystem/git-credential-manager/releases) is installed on your linux, and it requires `ttf-mscorefonts-installer` installed. +* Make sure [git-credential-manager](https://github.com/git-ecosystem/git-credential-manager/releases) is installed on your linux. * Maybe you need to set environment variable `AVALONIA_SCREEN_SCALE_FACTORS`. See https://github.com/AvaloniaUI/Avalonia/wiki/Configuring-X11-per-monitor-DPI. ## External Tools From 599ba01f207cbd79926c383667e7725b78b1bd05 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 18 Apr 2024 10:50:14 +0800 Subject: [PATCH 20/23] ux: re-design Views.Repository * It's better to move the `Navigate to HEAD` button to the top-right of this page. * Icons and alignments --- src/Converters/BoolConverters.cs | 4 +-- src/Resources/Icons.axaml | 4 +-- src/Views/CommitBaseInfo.axaml | 2 +- src/Views/Histories.axaml | 18 ++++++------ src/Views/Repository.axaml | 49 ++++++++++++++++---------------- 5 files changed, 39 insertions(+), 38 deletions(-) diff --git a/src/Converters/BoolConverters.cs b/src/Converters/BoolConverters.cs index bfe3bf41..0a7d2aa1 100644 --- a/src/Converters/BoolConverters.cs +++ b/src/Converters/BoolConverters.cs @@ -5,10 +5,10 @@ namespace SourceGit.Converters { public static class BoolConverters { - public static readonly FuncValueConverter ToCommitOpacity = + public static readonly FuncValueConverter HalfIfFalse = new FuncValueConverter(x => x ? 1 : 0.5); - public static readonly FuncValueConverter ToCommitFontWeight = + public static readonly FuncValueConverter BoldIfTrue = new FuncValueConverter(x => x ? FontWeight.Bold : FontWeight.Regular); } } diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index f645c00e..f33f0073 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -54,9 +54,9 @@ M128 256h192a64 64 0 110 128H128a64 64 0 110-128zm576 192h192a64 64 0 010 128h-192a64 64 0 010-128zm-576 192h192a64 64 0 010 128H128a64 64 0 010-128zm576 0h192a64 64 0 010 128h-192a64 64 0 010-128zm0-384h192a64 64 0 010 128h-192a64 64 0 010-128zM128 448h192a64 64 0 110 128H128a64 64 0 110-128zm384-320a64 64 0 0164 64v640a64 64 0 01-128 0V192a64 64 0 0164-64z M24 512A488 488 0 01512 24A488 488 0 011000 512A488 488 0 01512 1000A488 488 0 0124 512zm447-325v327L243 619l51 111 300-138V187H471z M715 254h-405l-58 57h520zm-492 86v201h578V340zm405 143h-29v-29H425v29h-29v-57h231v57zm-405 295h578V559H223zm174-133h231v57h-29v-29H425v29h-29v-57z - M869 145a145 145 0 10-289 0c0 56 33 107 83 131c-5 96-77 128-201 175c-52 20-110 42-160 74V276A144 144 0 00242 0a145 145 0 00-145 145c0 58 35 108 84 131v461a144 144 0 00-84 131a145 145 0 10289 0a144 144 0 00-84-131c5-95 77-128 201-175c122-46 274-103 280-287a145 145 0 0085-132zM242 61a83 83 0 110 167a83 83 0 010-167zm0 891a84 84 0 110-167a84 84 0 010 167zM724 228a84 84 0 110-167a84 84 0 010 167z + M757 226a143 143 0 00-55 276 96 96 0 01-88 59h-191a187 187 0 00-96 27V312a143 143 0 10-96 0v399a143 143 0 10103 2 96 96 0 0188-59h191a191 191 0 00187-151 143 143 0 00-43-279zM280 130a48 48 0 110 96 48 48 0 010-96zm0 764a48 48 0 110-96 48 48 0 010 96zM757 417a48 48 0 110-96 48 48 0 010 96z M896 128h-64V64c0-35-29-64-64-64s-64 29-64 64v64h-64c-35 0-64 29-64 64s29 64 64 64h64v64c0 35 29 64 64 64s64-29 64-64V256h64c35 0 64-29 64-64s-29-64-64-64zm-204 307C673 481 628 512 576 512H448c-47 0-90 13-128 35V372C394 346 448 275 448 192c0-106-86-192-192-192S64 86 64 192c0 83 54 154 128 180v280c-74 26-128 97-128 180c0 106 86 192 192 192s192-86 192-192c0-67-34-125-84-159c22-20 52-33 84-33h128c122 0 223-85 249-199c-19 4-37 7-57 7c-26 0-51-5-76-13zM256 128c35 0 64 29 64 64s-29 64-64 64s-64-29-64-64s29-64 64-64zm0 768c-35 0-64-29-64-64s29-64 64-64s64 29 64 64s-29 64-64 64z - M902 479v-1c0-133-112-242-250-242c-106 0-196 64-232 154c-28-20-62-32-100-32c-76 0-140 49-160 116c-52 37-86 97-86 165c0 112 90 202 202 202h503c112 0 202-90 202-202c0-65-31-123-79-160z + M706 302a289 289 0 00-173 44 27 27 0 1029 46 234 234 0 01125-36c23 0 45 3 66 9 93 28 161 114 161 215C914 704 813 805 687 805H337C211 805 110 704 110 580c0-96 61-178 147-210C282 263 379 183 495 183a245 245 0 01210 119z M364 512h67v108h108v67h-108v108h-67v-108h-108v-67h108v-108zm298-64A107 107 0 01768 555C768 614 720 660 660 660h-108v-54h-108v-108h-94v108h-94c4-21 22-47 44-51l-1-12a75 75 0 0171-75a128 128 0 01239-7a106 106 0 0153-14z M177 156c-22 5-33 17-36 37c-10 57-33 258-13 278l445 445c23 23 61 23 84 0l246-246c23-23 23-61 0-84l-445-445C437 120 231 145 177 156zM331 344c-26 26-69 26-95 0c-26-26-26-69 0-95s69-26 95 0C357 276 357 318 331 344z M683 537h-144v-142h-142V283H239a44 44 0 00-41 41v171a56 56 0 0014 34l321 321a41 41 0 0058 0l174-174a41 41 0 000-58zm-341-109a41 41 0 110-58a41 41 0 010 58zM649 284V142h-69v142h-142v68h142v142h69v-142h142v-68h-142z diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml index 40b1e036..b09bb6d6 100644 --- a/src/Views/CommitBaseInfo.axaml +++ b/src/Views/CommitBaseInfo.axaml @@ -86,7 +86,7 @@ - + diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 9077d500..b14dc0b5 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -69,8 +69,8 @@ + Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}" + FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/> @@ -85,7 +85,7 @@ VerticalAlignment="Center" IsHitTestVisible="False" User="{Binding Author}" - Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.ToCommitOpacity}}"/> + Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}"/> @@ -96,8 +96,8 @@ + Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}" + FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/> @@ -108,8 +108,8 @@ + Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}" + FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/> @@ -120,8 +120,8 @@ + Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}" + FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/> diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index b38e2242..9f450c77 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -69,13 +69,17 @@ - + + + @@ -111,19 +115,16 @@ - - - - + + + - - - + + + - - - + + + - - - - + + + + @@ -181,8 +182,8 @@ - - + + @@ -223,12 +224,12 @@ - - - - + + + + - + Date: Fri, 19 Apr 2024 14:28:18 +0800 Subject: [PATCH 21/23] localization: update translations --- src/Resources/Locales/en_US.axaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 9752f0d6..55c997c4 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -252,9 +252,9 @@ Paste Preference APPEARANCE - Default FontFamily + Default Font Default Font Size - Monospace FontFamily + Monospace Font Theme GENERAL Avatar Server From 905db5ca5956af4e3018f5f374fa4b3b55cfc61a Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 19 Apr 2024 17:35:42 +0800 Subject: [PATCH 22/23] ux: show count of stashes and changes in selected stash --- src/Views/StashesPage.axaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Views/StashesPage.axaml b/src/Views/StashesPage.axaml index c2877f5e..5828ef86 100644 --- a/src/Views/StashesPage.axaml +++ b/src/Views/StashesPage.axaml @@ -20,11 +20,11 @@ - + - -