From 4b8c4bd5219dce68c116f0963ee47afac07b9ab2 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Sun, 14 Oct 2018 12:06:51 -0700 Subject: [PATCH] Remove menu code duplication --- .../ApplicationView/WidescreenPanel.cs | 2 - .../Library/Widgets/LibraryWidget.cs | 113 ++--- .../Library/Widgets/PrintLibraryWidget.cs | 477 +----------------- StaticData/Icons/x64.png | Bin 1315 -> 1021 bytes 4 files changed, 56 insertions(+), 536 deletions(-) diff --git a/MatterControlLib/ApplicationView/WidescreenPanel.cs b/MatterControlLib/ApplicationView/WidescreenPanel.cs index d1058b842..c0489a5d0 100644 --- a/MatterControlLib/ApplicationView/WidescreenPanel.cs +++ b/MatterControlLib/ApplicationView/WidescreenPanel.cs @@ -153,7 +153,6 @@ namespace MatterHackers.MatterControl popupMenu.CreateHorizontalLine(); - //// x64 indicator icon //if (IntPtr.Size == 8) //{ @@ -176,7 +175,6 @@ namespace MatterHackers.MatterControl // indicatorIcon = blueBox.BackBuffer; //} - menuItem = popupMenu.CreateMenuItem("Forums".Localize(), linkIcon); menuItem.Click += (s, e) => ApplicationController.Instance.LaunchBrowser("https://forums.matterhackers.com/category/20/mattercontrol"); diff --git a/MatterControlLib/Library/Widgets/LibraryWidget.cs b/MatterControlLib/Library/Widgets/LibraryWidget.cs index 316a016a8..bc8b91b5c 100644 --- a/MatterControlLib/Library/Widgets/LibraryWidget.cs +++ b/MatterControlLib/Library/Widgets/LibraryWidget.cs @@ -569,7 +569,7 @@ namespace MatterHackers.MatterControl.PrintLibrary providerMessageContainer.AddChild(providerMessageWidget); } - private void CreateMenuActions() + public static void CreateMenuActions(ListView libraryView, List menuActions, PartPreviewContent partPreviewContent, ThemeConfig theme) { menuActions.Add(new PrintItemAction() { @@ -586,7 +586,7 @@ namespace MatterHackers.MatterControl.PrintLibrary { if (openParams.FileNames != null) { - var writableContainer = this.libraryView.ActiveContainer as ILibraryWritableContainer; + var writableContainer = libraryView.ActiveContainer as ILibraryWritableContainer; if (writableContainer != null && openParams.FileNames.Length > 0) { @@ -596,7 +596,7 @@ namespace MatterHackers.MatterControl.PrintLibrary }); }); }, - IsEnabled = (s, l) => this.libraryView.ActiveContainer is ILibraryWritableContainer + IsEnabled = (s, l) => libraryView.ActiveContainer is ILibraryWritableContainer }); menuActions.Add(new PrintItemAction() @@ -615,7 +615,7 @@ namespace MatterHackers.MatterControl.PrintLibrary (newName) => { if (!string.IsNullOrEmpty(newName) - && this.libraryView.ActiveContainer is ILibraryWritableContainer writableContainer) + && libraryView.ActiveContainer is ILibraryWritableContainer writableContainer) { writableContainer.Add(new[] { @@ -626,7 +626,7 @@ namespace MatterHackers.MatterControl.PrintLibrary }, IsEnabled = (s, l) => { - return this.libraryView.ActiveContainer is ILibraryWritableContainer writableContainer + return libraryView.ActiveContainer is ILibraryWritableContainer writableContainer && writableContainer?.AllowAction(ContainerActions.AddContainers) == true; } }); @@ -846,7 +846,40 @@ namespace MatterHackers.MatterControl.PrintLibrary menuActions.Add(new PrintItemAction() { Title = "Remove".Localize(), - Action = (selectedLibraryItems, listView) => deleteFromLibraryButton_Click(selectedLibraryItems, null), + Action = (selectedLibraryItems, listView) => + { + // Perviously - deleteFromLibraryButton_Click + + // ask before remove + var libraryItems = libraryView.SelectedItems.Select(p => p.Model); + if (libraryItems.Any()) + { + if (libraryView.ActiveContainer is ILibraryWritableContainer container) + { + if (container is FileSystemContainer) + { + container.Remove(libraryItems); + libraryView.SelectedItems.Clear(); + } + else + { + StyledMessageBox.ShowMessageBox( + (doDelete) => + { + if (doDelete) + { + container.Remove(libraryItems); + libraryView.SelectedItems.Clear(); + } + }, + "Are you sure you want to remove the currently selected items?".Localize(), + "Remove Items?".Localize(), + StyledMessageBox.MessageType.YES_NO, + "Remove".Localize()); + } + } + } + }, IsEnabled = (selectedListItems, listView) => { // Multiselect, WritableContainer - disallow protected @@ -862,7 +895,14 @@ namespace MatterHackers.MatterControl.PrintLibrary menuActions.Add(new PrintItemAction() { Title = "Export".Localize(), - Action = (selectedLibraryItems, listView) => exportButton_Click(selectedLibraryItems, null), + Action = (selectedLibraryItems, listView) => + { + // Previously - exportButton_Click(object sender, EventArgs e) + // Open export options + var exportPage = new ExportPrintItemPage(libraryView.SelectedItems.Select(item => item.Model), true); + + DialogWindow.Show(exportPage); + }, IsEnabled = (selectedListItems, listView) => { // Multiselect - disallow containers @@ -875,7 +915,12 @@ namespace MatterHackers.MatterControl.PrintLibrary menuActions.Add(new PrintItemAction() { Title = "Share".Localize(), - Action = (selectedLibraryItems, listView) => shareFromLibraryButton_Click(selectedLibraryItems, null), + Action = (selectedLibraryItems, listView) => + { + // Previously - shareFromLibraryButton_Click + // TODO: Should be rewritten to Register from cloudlibrary, include logic to add to library as needed + ApplicationController.Instance.ShareLibraryItem(libraryView.SelectedItems.Select(i => i.Model).FirstOrDefault()); + }, IsEnabled = (selectedListItems, listView) => { // Singleselect - disallow containers and protected items @@ -927,7 +972,7 @@ namespace MatterHackers.MatterControl.PrintLibrary feedbackWindow.ShowAsSystemWindow(); - currentPartsInQueue.SaveSheets(); + currentPartsInQueue.SaveSheets().ConfigureAwait(false); } }); } @@ -982,54 +1027,6 @@ namespace MatterHackers.MatterControl.PrintLibrary base.OnClosed(e); } - private void deleteFromLibraryButton_Click(object sender, EventArgs e) - { - // ask before remove - var libraryItems = libraryView.SelectedItems.Select(p => p.Model); - if (libraryItems.Any()) - { - if (libraryView.ActiveContainer is ILibraryWritableContainer container) - { - if (container is FileSystemContainer) - { - container.Remove(libraryItems); - libraryView.SelectedItems.Clear(); - } - else - { - StyledMessageBox.ShowMessageBox( - (doDelete) => - { - if (doDelete) - { - container.Remove(libraryItems); - libraryView.SelectedItems.Clear(); - } - }, - "Are you sure you want to remove the currently selected items?".Localize(), - "Remove Items?".Localize(), - StyledMessageBox.MessageType.YES_NO, - "Remove".Localize()); - } - } - } - } - - private void shareFromLibraryButton_Click(object sender, EventArgs e) - { - // TODO: Should be rewritten to Register from cloudlibrary, include logic to add to library as needed - - ApplicationController.Instance.ShareLibraryItem(libraryView.SelectedItems.Select(i => i.Model).FirstOrDefault()); - } - - private void exportButton_Click(object sender, EventArgs e) - { - //Open export options - var exportPage = new ExportPrintItemPage(libraryView.SelectedItems.Select(item => item.Model), true); - - DialogWindow.Show(exportPage); - } - public override void OnMouseMove(MouseEventArgs mouseEvent) { if (PositionWithinLocalBounds(mouseEvent.X, mouseEvent.Y) @@ -1064,7 +1061,7 @@ namespace MatterHackers.MatterControl.PrintLibrary public override void OnLoad(EventArgs args) { // Defer creating menu items until plugins have loaded - CreateMenuActions(); + LibraryWidget.CreateMenuActions(libraryView, menuActions, partPreviewContent, theme); navBar.OverflowButton.Name = "Print Library Overflow Menu"; navBar.ExtendOverflowMenu = (popupMenu) => diff --git a/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs b/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs index 87cff082f..415bc44b2 100644 --- a/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs +++ b/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs @@ -465,424 +465,6 @@ namespace MatterHackers.MatterControl.PrintLibrary providerMessageContainer.AddChild(providerMessageWidget); } - private void CreateMenuActions() - { - menuActions.Add(new PrintItemAction() - { - Icon = AggContext.StaticData.LoadIcon("cube.png", 16, 16, ApplicationController.Instance.MenuTheme.InvertIcons), - Title = "Add".Localize(), - ToolTipText = "Add an.stl, .obj, .amf, .gcode or.zip file to the Library".Localize(), - Action = (selectedLibraryItems, listView) => - { - UiThread.RunOnIdle(() => - { - AggContext.FileDialogs.OpenFileDialog( - new OpenFileDialogParams(ApplicationSettings.OpenPrintableFileParams, multiSelect: true), - (openParams) => - { - if (openParams.FileNames != null) - { - var writableContainer = this.libraryView.ActiveContainer as ILibraryWritableContainer; - if (writableContainer != null - && openParams.FileNames.Length > 0) - { - writableContainer.Add(openParams.FileNames.Select(f => new FileSystemFileItem(f))); - } - } - }); - }); - }, - IsEnabled = (s, l) => this.libraryView.ActiveContainer is ILibraryWritableContainer - }); - - menuActions.Add(new PrintItemAction() - { - Title = "Create Folder".Localize(), - Icon = AggContext.StaticData.LoadIcon("fa-folder-new_16.png", 16, 16, ApplicationController.Instance.MenuTheme.InvertIcons), - Action = (selectedLibraryItems, listView) => - { - DialogWindow.Show( - new InputBoxPage( - "Create Folder".Localize(), - "Folder Name".Localize(), - "", - "Enter New Name Here".Localize(), - "Create".Localize(), - (newName) => - { - if (!string.IsNullOrEmpty(newName) - && this.libraryView.ActiveContainer is ILibraryWritableContainer writableContainer) - { - writableContainer.Add(new[] - { - new CreateFolderItem() { Name = newName } - }); - } - })); - }, - IsEnabled = (s, l) => - { - return this.libraryView.ActiveContainer is ILibraryWritableContainer writableContainer - && writableContainer?.AllowAction(ContainerActions.AddContainers) == true; - } - }); - - menuActions.Add(new PrintItemAction() - { - Title = "Print".Localize(), - Action = (selectedLibraryItems, listView) => - { - // TODO: Sort out the right way to have an ActivePrinter context that looks and behaves correctly - var activeContext = ApplicationController.Instance.DragDropData; - var printer = activeContext.Printer; - - switch (selectedLibraryItems.FirstOrDefault()) - { - case SDCardFileItem sdcardItem: - // TODO: Confirm SD printing? - // TODO: Need to rewrite library menu item validation can write one off validations like below so we don't end up here - // - ActiveSliceSettings.Instance.GetValue(SettingsKey.has_sd_card_reader) - printer.Connection.StartSdCardPrint(sdcardItem.Name.ToLower()); - break; - case FileSystemFileItem fileItem when Path.GetExtension(fileItem.FileName).IndexOf(".gco", StringComparison.OrdinalIgnoreCase) == 0: - if (printer != null) - { - UiThread.RunOnIdle(async () => - { - await printer.Bed.StashAndPrintGCode(fileItem); - }); - } - - break; - default: - //TODO: Otherwise add the selected items to the plate and print the plate? - if (printer != null) - { - UiThread.RunOnIdle(async () => - { - await printer.Bed.StashAndPrint(selectedLibraryItems); - }); - } - break; - } - }, - IsEnabled = (selectedListItems, listView) => - { - var communicationState = ApplicationController.Instance.DragDropData?.Printer?.Connection.CommunicationState; - - // Singleselect - disallow containers - return listView.SelectedItems.Count == 1 - && selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem - && !(firstItem is ILibraryContainer) - && (communicationState == CommunicationStates.Connected - || communicationState == CommunicationStates.FinishedPrint); - } - }); - - // edit menu item - menuActions.Add(new PrintItemAction() - { - Title = "Add to Bed".Localize(), - Action = (selectedLibraryItems, listView) => - { - var activeContext = ApplicationController.Instance.DragDropData; - var printer = activeContext.Printer; - - if (listView.SelectedItems.Count == 1 && - selectedLibraryItems.FirstOrDefault() is ILibraryAssetStream assetStream - && assetStream.ContentType == "gcode") - { - // Change loaded scene to new context - printer.Bed.LoadContent( - new EditContext() - { - SourceItem = assetStream, - // No content store for GCode - ContentStore = null - }).ConfigureAwait(false); - } - else - { - activeContext.SceneContext.AddToPlate(selectedLibraryItems); - } - }, - IsEnabled = (selectedListItems, listView) => - { - // Multiselect - disallow containers, require View3DWidget context - return ApplicationController.Instance.DragDropData.View3DWidget != null - && listView.SelectedItems.Any() - && listView.SelectedItems.All(i => !(i.Model is ILibraryContainer)); - } - }); - -#if !__ANDROID__ && DEBUG - // edit menu item - menuActions.Add(new PrintItemAction() - { - Title = "Markdown Tests"/* Don't localize debug tool */, - Action = (selectedLibraryItems, listView) => - { - UiThread.RunOnIdle(() => - { - DialogWindow.Show(); - }); - }, - IsEnabled = (selectedListItems, listView) => true - }); -#endif - - // edit menu item - menuActions.Add(new PrintItemAction() - { - Title = "Edit".Localize(), - Action = async (selectedLibraryItems, listView) => - { - if (selectedLibraryItems.FirstOrDefault() is ILibraryItem firstItem - && ApplicationController.Instance.Library.ActiveContainer is ILibraryWritableContainer writableContainer) - { - BedConfig bed; - - var newTab = partPreviewContent.CreatePartTab( - firstItem.Name, - bed = new BedConfig(ApplicationController.Instance.Library.PartHistory), - theme); - - // Load content after UI widgets to support progress notification during acquire/load - await bed.LoadContent( - new EditContext() - { - ContentStore = writableContainer, - SourceItem = firstItem - }); - - if (newTab.TabContent is PartTabPage partTab) - { - // TODO: Restore ability to render progress loading - } - } - }, - IsEnabled = (selectedListItems, listView) => - { - // Singleselect, WritableContainer, mcx only - disallow containers and protected items - return listView.SelectedItems.Count == 1 - && selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem - && !(firstItem is ILibraryContainer) - && !firstItem.IsProtected - && firstItem is ILibraryAsset asset && asset.ContentType == "mcx" - && ApplicationController.Instance.Library.ActiveContainer is ILibraryWritableContainer; - } - }); - - // rename menu item - menuActions.Add(new PrintItemAction() - { - Title = "Rename".Localize(), - Action = (selectedLibraryItems, listView) => - { - if (libraryView.SelectedItems.Count == 1) - { - var selectedItem = libraryView.SelectedItems.FirstOrDefault(); - if (selectedItem == null) - { - return; - } - - DialogWindow.Show( - new InputBoxPage( - "Rename Item".Localize(), - "Name".Localize(), - selectedItem.Model.Name, - "Enter New Name Here".Localize(), - "Rename".Localize(), - (newName) => - { - var model = libraryView.SelectedItems.FirstOrDefault()?.Model; - if (model != null) - { - var container = libraryView.ActiveContainer as ILibraryWritableContainer; - if (container != null) - { - container.Rename(model, newName); - libraryView.SelectedItems.Clear(); - } - } - })); - } - }, - IsEnabled = (selectedListItems, listView) => - { - // Singleselect, WritableContainer - disallow protected items - return listView.SelectedItems.Count == 1 - && selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem - && !firstItem.IsProtected - && ApplicationController.Instance.Library.ActiveContainer is ILibraryWritableContainer; - } - }); - - // move menu item - menuActions.Add(new PrintItemAction() - { - Title = "Move".Localize(), - Action = (selectedLibraryItems, listView) => - { - var partItems = selectedLibraryItems.Where(item => item is ILibraryAssetStream || item is ILibraryContainerLink); - if (partItems.Any() - && libraryView.ActiveContainer is ILibraryWritableContainer sourceContainer) - { - DialogWindow.Show(new MoveItemPage((newName, destinationContainer) => - { - destinationContainer.Move(partItems, sourceContainer); - - // Discover if item was moved to an already loaded and now stale view on an ancestor and force reload - var openParent = ApplicationController.Instance.Library.ActiveContainer.Ancestors().FirstOrDefault(c => c.ID == destinationContainer.ID); - if (openParent != null) - { - // TODO: Consider changing this brute force approach to instead mark as dirty and allow Activate base method to reload if dirty - Task.Run(() => openParent.Load()); - } - - libraryView.SelectedItems.Clear(); - })); - } - }, - IsEnabled = (selectedListItems, listView) => - { - // Multiselect, WritableContainer - disallow protected - return listView.SelectedItems.Any() - && listView.SelectedItems.All(i => !i.Model.IsProtected - && ApplicationController.Instance.Library.ActiveContainer is ILibraryWritableContainer); - } - }); - - // remove menu item - menuActions.Add(new PrintItemAction() - { - Title = "Remove".Localize(), - Action = (selectedLibraryItems, listView) => deleteFromLibraryButton_Click(selectedLibraryItems, null), - IsEnabled = (selectedListItems, listView) => - { - // Multiselect, WritableContainer - disallow protected - return listView.SelectedItems.Any() - && listView.SelectedItems.All(i => !i.Model.IsProtected - && ApplicationController.Instance.Library.ActiveContainer is ILibraryWritableContainer); - } - }); - - menuActions.Add(new MenuSeparator("Export")); - - // export menu item - menuActions.Add(new PrintItemAction() - { - Title = "Export".Localize(), - Action = (selectedLibraryItems, listView) => exportButton_Click(selectedLibraryItems, null), - IsEnabled = (selectedListItems, listView) => - { - // Multiselect - disallow containers - return listView.SelectedItems.Any() - && listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink)); - }, - }); - - // share menu item - menuActions.Add(new PrintItemAction() - { - Title = "Share".Localize(), - Action = (selectedLibraryItems, listView) => shareFromLibraryButton_Click(selectedLibraryItems, null), - IsEnabled = (selectedListItems, listView) => - { - // Singleselect - disallow containers and protected items - return listView.SelectedItems.Count == 1 - && selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem - && listView.ActiveContainer.GetType().Name.IndexOf("Cloud", StringComparison.OrdinalIgnoreCase) >= 0 - && !(firstItem is ILibraryContainer) - && !firstItem.IsProtected; - } - }); - - // Extension point - RegisteredLibraryActions not defined in this file/assembly can insert here via this named token - menuActions.AddRange(ApplicationController.Instance.RegisteredLibraryActions("StandardLibraryOperations")); - -#if !__ANDROID__ - menuActions.Add(new MenuSeparator("Other")); - - // PDF export is limited to Windows - if (AggContext.OperatingSystem == OSType.Windows) - { - menuActions.Add(new PrintItemAction() - { - Title = "Create Part Sheet".Localize(), - Action = (selectedLibraryItems, listView) => - { - UiThread.RunOnIdle(() => - { - var printItems = selectedLibraryItems.OfType(); - if (printItems.Any()) - { - AggContext.FileDialogs.SaveFileDialog( - new SaveFileDialogParams("Save Parts Sheet|*.pdf") - { - ActionButtonLabel = "Save Parts Sheet".Localize(), - Title = ApplicationController.Instance.ProductName + " - " + "Save".Localize() - }, - (saveParams) => - { - if (!string.IsNullOrEmpty(saveParams.FileName)) - { - var feedbackWindow = new SavePartsSheetFeedbackWindow( - printItems.Count(), - printItems.FirstOrDefault()?.Name, - theme.ActiveTabColor); - - var currentPartsInQueue = new PartsSheet(printItems, saveParams.FileName); - currentPartsInQueue.UpdateRemainingItems += feedbackWindow.StartingNextPart; - currentPartsInQueue.DoneSaving += feedbackWindow.DoneSaving; - - feedbackWindow.ShowAsSystemWindow(); - - currentPartsInQueue.SaveSheets(); - } - }); - } - }); - }, - IsEnabled = (selectedListItems, listView) => - { - // Multiselect - disallow containers - return listView.SelectedItems.Any() - && listView.SelectedItems.All(i => !(i.Model is ILibraryContainer)); - } - }); - } -#endif - - menuActions.Add(new PrintItemAction() - { - Title = "Open Package".Localize(), - Action = (selectedItems, listView) => - { - var firstItem = selectedItems.First(); - - if (firstItem is ILibraryAsset libraryAsset) - { - var container = new McxContainer(libraryAsset); - container.Load(); - - container.Parent = ApplicationController.Instance.Library.ActiveContainer; - - ApplicationController.Instance.Library.ActiveContainer = container; - } - }, - IsEnabled = (selectedListItems, listView) => - { - return listView.SelectedItems.Count == 1 - && selectedListItems.FirstOrDefault()?.Model is ILibraryAsset libraryAsset - && libraryAsset.ContentType == "mcx"; - } - }); - - libraryView.MenuActions = menuActions; - } - public override void OnClosed(EventArgs e) { if (libraryView?.ActiveContainer != null) @@ -894,63 +476,6 @@ namespace MatterHackers.MatterControl.PrintLibrary base.OnClosed(e); } - private async void addToQueueButton_Click(object sender, EventArgs e) - { - var selectedItems = libraryView.SelectedItems.Select(o => o.Model); - if (selectedItems.Any()) - { - await PrintQueueContainer.AddAllItems(selectedItems); - } - } - - private void deleteFromLibraryButton_Click(object sender, EventArgs e) - { - // ask before remove - var libraryItems = libraryView.SelectedItems.Select(p => p.Model); - if (libraryItems.Any()) - { - if (libraryView.ActiveContainer is ILibraryWritableContainer container) - { - if (container is FileSystemContainer) - { - container.Remove(libraryItems); - libraryView.SelectedItems.Clear(); - } - else - { - StyledMessageBox.ShowMessageBox( - (doDelete) => - { - if (doDelete) - { - container.Remove(libraryItems); - libraryView.SelectedItems.Clear(); - } - }, - "Are you sure you want to remove the currently selected items?".Localize(), - "Remove Items?".Localize(), - StyledMessageBox.MessageType.YES_NO, - "Remove".Localize()); - } - } - } - } - - private void shareFromLibraryButton_Click(object sender, EventArgs e) - { - // TODO: Should be rewritten to Register from cloudlibrary, include logic to add to library as needed - - ApplicationController.Instance.ShareLibraryItem(libraryView.SelectedItems.Select(i => i.Model).FirstOrDefault()); - } - - private void exportButton_Click(object sender, EventArgs e) - { - //Open export options - var exportPage = new ExportPrintItemPage(libraryView.SelectedItems.Select(item => item.Model), true); - - DialogWindow.Show(exportPage); - } - public override void OnMouseMove(MouseEventArgs mouseEvent) { if (PositionWithinLocalBounds(mouseEvent.X, mouseEvent.Y) @@ -985,7 +510,7 @@ namespace MatterHackers.MatterControl.PrintLibrary public override void OnLoad(EventArgs args) { // Defer creating menu items until plugins have loaded - CreateMenuActions(); + LibraryWidget.CreateMenuActions(libraryView, menuActions, partPreviewContent, theme); navBar.OverflowButton.Name = "Print Library Overflow Menu"; navBar.ExtendOverflowMenu = (popupMenu) => diff --git a/StaticData/Icons/x64.png b/StaticData/Icons/x64.png index 0beb1d0db61297327cbd9017bf82cac710f19aed..16704809463eb1304826fdf907bf893549133fea 100644 GIT binary patch delta 318 zcmZ3?^_N|-Gr-TCmrII^fq{Y7)59f*fq_8)ggMw47#QR~|4-bgc$%r6;kT!YV~9oX z)ysSJTo?sdALP5LwzxSi5BSJZvUvG~UKhncg)CDq{|C!2db)^Qi9W+Up<_+cESFvl zmp>xwp6r^I6uNA-rKS3FpR_E&k4@2UuQqh-$egUBlxKBIwf@?CR;$y#EGg4;jR5Z2#A> z9V_a) zC(JxASlIcr!@^DW^UR%Lw~mVW8GYU`mDx_rG%h9X?3pyy{71h|Klwku= Y`F-B?>S)z6FfcH9y85}Sb4q9e02ki_@% delta 614 zcmey%zL-m~Gr-TCmrII^fq{Y7)59f*fq_8?ggMw47#PCN^@VR#Jk3%0T&fkOul9N19){+@ytPhnYE+;JD)>jnk}1{cmPNIxH6G|lYm%qONk7k2)A zVrsnW&qVL<5wop+=X{hZd4JD#-;S0g>$KDRf7}k3)maJS?^ZC?I<4rs~JUsvZ8yhSM`Ib>+ zTw|*IVypD_yp^9iPR;Spia+;yroHDGC4<^+lNTRWW@BS(>&)gW`d443=z9KCrJh-H z#01Oud;0@_fBU^w;Qs&qV{_u|y3f6~{1OqFCAnYQ=W+28&=#=jqTwMQ-WKGz=|NqLx?)_CK?Qh@u`Tl;rTBPn*?sI;A z{4-|Ec<}S%_xJbDT=#$XGd(Tsn@pts;>nXQ*FV|w?d@&zY0m9@nk!bV+7}iU_OC;3 zMf|>+#JyEtSFPB&)B30Jj2W9Zf3^}UX^n}AskgDQdAFeZFatmT`TP{;goF>NQEpkH bISgWF?p@9~Z~Ksefq}u()z4*}Q$iB}&Obf`