From c099f1f4e8ae48b5e8b356acd6a47aba54f24f01 Mon Sep 17 00:00:00 2001 From: Massimiliano Assante Date: Wed, 11 Sep 2013 16:40:39 +0000 Subject: [PATCH] in the way to the FWS, 50 percent ported so far git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/admin/resource-management@81277 82a268e6-3cf1-43bd-a215-b396298e98cf --- .classpath | 1 + .settings/org.eclipse.wst.common.component | 3 + .settings/org.eclipse.wst.validation.prefs | 2 + pom.xml | 66 +++---- .../client/ResourceManagementPortlet.java | 172 +++++++++--------- .../client/utils/Commands.java | 2 +- .../client/utils/FWSTranslate.java | 23 +++ .../resourcedetails/ResourceDetailsPanel.java | 43 ++--- .../resourcetree/ResourcesTreePanel.java | 3 +- .../client/widgets/panels/MainPanel.java | 2 + .../client/widgets/taskbar/TaskbarButton.java | 4 +- .../client/widgets/taskbar/TaskbarItem.java | 5 +- .../server/ResourceCommands.java | 42 ++--- .../server/ServiceProxyImpl.java | 44 ++--- .../ResourceManagementPortlet.gwt.xml | 10 +- src/main/webapp/ResourceManagementPortlet.css | 18 +- src/main/webapp/WEB-INF/web.xml | 70 +++---- .../webapp/conf/resourcemanagement.properties | 4 +- src/main/webapp/d4scienceOrg.css | 58 +++++- src/main/webapp/images/D4infraFWS.png | Bin 0 -> 38740 bytes src/main/webapp/images/bg-pattern.png | Bin 0 -> 945 bytes .../webapp/images/icons/GenericResource.png | Bin 0 -> 622 bytes src/main/webapp/images/icons/collection2.png | Bin 0 -> 854 bytes .../webapp/images/icons/gcoreEndpoint.png | Bin 0 -> 1762 bytes src/main/webapp/images/icons/hostingNode.png | Bin 0 -> 636 bytes src/main/webapp/images/icons/server.png | Bin 530 -> 0 bytes .../webapp/images/icons/serviceEndpoint.png | Bin 0 -> 1785 bytes src/main/webapp/images/icons/software.png | Bin 0 -> 1876 bytes .../GwtTestResourceManagementPortlet.java | 3 +- 29 files changed, 328 insertions(+), 247 deletions(-) create mode 100644 .settings/org.eclipse.wst.validation.prefs create mode 100644 src/main/java/org/gcube/portlets/admin/resourcemanagement/client/utils/FWSTranslate.java create mode 100644 src/main/webapp/images/D4infraFWS.png create mode 100644 src/main/webapp/images/bg-pattern.png create mode 100644 src/main/webapp/images/icons/GenericResource.png create mode 100644 src/main/webapp/images/icons/collection2.png create mode 100644 src/main/webapp/images/icons/gcoreEndpoint.png create mode 100644 src/main/webapp/images/icons/hostingNode.png delete mode 100644 src/main/webapp/images/icons/server.png create mode 100644 src/main/webapp/images/icons/serviceEndpoint.png create mode 100644 src/main/webapp/images/icons/software.png diff --git a/.classpath b/.classpath index 930f7bc..4035493 100644 --- a/.classpath +++ b/.classpath @@ -34,5 +34,6 @@ + diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 2852ff5..a807789 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -4,6 +4,9 @@ + + uses + diff --git a/.settings/org.eclipse.wst.validation.prefs b/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..04cad8c --- /dev/null +++ b/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,2 @@ +disabled=06target +eclipse.preferences.version=1 diff --git a/pom.xml b/pom.xml index a9a434f..d803826 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ - 2.4.0 + 2.5.1 3.0 distro @@ -43,19 +43,18 @@ - - xerces - xercesImpl - 2.9.1 - provided - + without old Xerces and Xalan version of gCore complaining --> com.google.gwt gwt-user ${gwtVersion} provided + + xalan + xalan + 2.7.1 + com.google.gwt gwt-servlet @@ -131,29 +130,29 @@ org.gcube.portlets.admin rmp-common-library - [1.1.0-SNAPSHOT, 2.0.0-SNAPSHOT) + [2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT) - - org.gcube.portlets.admin - ishealth-monitor-widget - [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) - - - org.gcube.portlets.admin - resource-sweeper-widget - [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) - - - org.gcube.portlets.admin - software-upload-wizard - [1.1.0-SNAPSHOT, 2.0.0-SNAPSHOT) - - - org.gcube.portlets.admin - activation-record-widgets - [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) - + + + + + + + + + + + + + + + + + + + + com.google.inject @@ -242,7 +241,7 @@ gwt-log 3.1.7 provided - + @@ -255,7 +254,7 @@ org.codehaus.mojo gwt-maven-plugin - 2.4.0 + ${gwtVersion} @@ -267,10 +266,11 @@ - -Xmx512M -DGLOBUS_LOCATION=${GLOBUS_LOCATION} + -Xmx512M -DGLOBUS_LOCATION=${GLOBUS_LOCATION} + -classpath $CLASSPATH:${GLOBUS_LOCATION} ResourceManagementPortlet.html ${webappDirectory} - + diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/ResourceManagementPortlet.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/ResourceManagementPortlet.java index 30dcb79..92250e2 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/ResourceManagementPortlet.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/ResourceManagementPortlet.java @@ -17,10 +17,10 @@ package org.gcube.portlets.admin.resourcemanagement.client; -import org.gcube.portlets.admin.client.forms.ActivationRecordVMForm; -import org.gcube.portlets.admin.client.forms.GenericResourceCMForm; -import org.gcube.portlets.admin.client.forms.GenericResourceTreeManagerForm; -import org.gcube.portlets.admin.ishealthmonitor.client.dialog.ISMonitor; +//import org.gcube.portlets.admin.client.forms.ActivationRecordVMForm; +//import org.gcube.portlets.admin.client.forms.GenericResourceCMForm; +//import org.gcube.portlets.admin.client.forms.GenericResourceTreeManagerForm; +//import org.gcube.portlets.admin.ishealthmonitor.client.dialog.ISMonitor; import org.gcube.portlets.admin.resourcemanagement.client.forms.genericresources.DeployVirtualCollection; import org.gcube.portlets.admin.resourcemanagement.client.remote.ProxyRegistry; import org.gcube.portlets.admin.resourcemanagement.client.utils.Commands; @@ -35,7 +35,7 @@ import org.gcube.portlets.admin.resourcemanagement.client.widgets.panels.MainPan import org.gcube.portlets.admin.resourcemanagement.client.widgets.registry.UIIdentifiers; import org.gcube.portlets.admin.resourcemanagement.client.widgets.registry.WidgetsRegistry; import org.gcube.portlets.admin.resourcemanagement.client.widgets.viewport.MainContainer; -import org.gcube.portlets.admin.resourcesweeper.client.dialog.SweeperDialog; +//import org.gcube.portlets.admin.resourcesweeper.client.dialog.SweeperDialog; import org.gcube.resourcemanagement.support.client.Resource_support; import org.gcube.resourcemanagement.support.client.events.SetScopeEvent; import org.gcube.resourcemanagement.support.client.events.SetScopeEventHandler; @@ -139,7 +139,7 @@ public class ResourceManagementPortlet implements EntryPoint { // the menu and statusbar can be built. buildMenu(); buildStatusBar(); - Commands.mask("Loading scopes", UIIdentifiers.MAIN_CONTAINER_VIEWPORT_ID); + Commands.mask("Loading infrastructure scopes", UIIdentifiers.MAIN_CONTAINER_VIEWPORT_ID); Commands.doGetAvailableScopes(this); if (StatusHandler.getStatus().getCurrentScope() != null) { @@ -165,7 +165,7 @@ public class ResourceManagementPortlet implements EntryPoint { viewport.setLayout(bl); WidgetsRegistry.registerWidget(UIIdentifiers.MAIN_CONTAINER_VIEWPORT_ID, viewport); - MainPanel northPanel = new MainPanel(53, "Main App", LayoutRegion.NORTH) { + MainPanel northPanel = new MainPanel(60, "Main App", LayoutRegion.NORTH) { @Override public void init() { ConsoleMessageBroker.log(this, "Initializing north panel"); @@ -189,11 +189,11 @@ public class ResourceManagementPortlet implements EntryPoint { } }; - MainPanel westPanel = new MainPanel(200, "ResourceNavigation", LayoutRegion.WEST) { + MainPanel westPanel = new MainPanel(200, "Resources", LayoutRegion.WEST) { @Override public void init() { ConsoleMessageBroker.log(this, "Initializing west panel"); - this.setCollapsible(true); + this.setCollapsible(false); this.setMargins(new Margins(5, 0, 5, 5)); Text widget = new Text(); widget.setId("res-details-widget-fake"); @@ -439,16 +439,16 @@ public class ResourceManagementPortlet implements EntryPoint { MenuItem testIS = new MenuItem("Check IS Health") { protected void onClick(final ComponentEvent be) { - super.onClick(be); - GWT.runAsync(ISMonitor.class, new RunAsyncCallback() { - @Override - public void onSuccess() { - ISMonitor.pingIS(); - } - public void onFailure(Throwable reason) { - Window.alert("There are networks problem, please check your connection."); - } - }); +// super.onClick(be); +// GWT.runAsync(ISMonitor.class, new RunAsyncCallback() { +// @Override +// public void onSuccess() { +// ISMonitor.pingIS(); +// } +// public void onFailure(Throwable reason) { +// Window.alert("There are networks problem, please check your connection."); +// } +// }); }; }; testIS.setIconStyle("is-icon"); @@ -460,22 +460,22 @@ public class ResourceManagementPortlet implements EntryPoint { MenuItem cleanGHN = new MenuItem("Resource Sweeper") { protected void onClick(final ComponentEvent be) { - super.onClick(be); - if (SupportedOperations.SWEEP_GHN.isAllowed(StatusHandler.getStatus().getCredentials())) { - GWT.runAsync(SweeperDialog.class, new RunAsyncCallback() { - @Override - public void onSuccess() { - String currentScope = StatusHandler.getStatus().getCurrentScope(); - new SweeperDialog(currentScope); - } - - public void onFailure(Throwable reason) { - Window.alert("There are networks problem, please check your connection."); - } - }); - } - else - MessageBox.alert("Resource Sweeper", "You are not allowed to execute this operation", null); +// super.onClick(be); +// if (SupportedOperations.SWEEP_GHN.isAllowed(StatusHandler.getStatus().getCredentials())) { +// GWT.runAsync(SweeperDialog.class, new RunAsyncCallback() { +// @Override +// public void onSuccess() { +// String currentScope = StatusHandler.getStatus().getCurrentScope(); +// new SweeperDialog(currentScope); +// } +// +// public void onFailure(Throwable reason) { +// Window.alert("There are networks problem, please check your connection."); +// } +// }); +// } +// else +// MessageBox.alert("Resource Sweeper", "You are not allowed to execute this operation", null); }; }; @@ -499,22 +499,22 @@ public class ResourceManagementPortlet implements EntryPoint { // Create activation record from plugins MenuItem createARTM = new MenuItem("Activation Record for Tree Manager") { protected void onClick(final ComponentEvent be) { - super.onClick(be); - if (SupportedOperations.GENERIC_RESOURCE_CREATE.isAllowed(StatusHandler.getStatus().getCredentials())) { - GWT.runAsync(GenericResourceTreeManagerForm.class, new RunAsyncCallback() { - @Override - public void onSuccess() { - String currentScope = StatusHandler.getStatus().getCurrentScope(); - new GenericResourceTreeManagerForm(currentScope).show(); - } - - public void onFailure(Throwable reason) { - Window.alert("There are networks problem, please check your connection."); - } - }); - } else { - MessageBox.alert("Activation Record for TM", "You are not allowed to execute this operation", null); - } +// super.onClick(be); +// if (SupportedOperations.GENERIC_RESOURCE_CREATE.isAllowed(StatusHandler.getStatus().getCredentials())) { +// GWT.runAsync(GenericResourceTreeManagerForm.class, new RunAsyncCallback() { +// @Override +// public void onSuccess() { +// String currentScope = StatusHandler.getStatus().getCurrentScope(); +// new GenericResourceTreeManagerForm(currentScope).show(); +// } +// +// public void onFailure(Throwable reason) { +// Window.alert("There are networks problem, please check your connection."); +// } +// }); +// } else { +// MessageBox.alert("Activation Record for TM", "You are not allowed to execute this operation", null); +// } }; }; createARTM.setIconStyle("pluginTM-icon"); @@ -523,23 +523,23 @@ public class ResourceManagementPortlet implements EntryPoint { // Create activation record from plugins MenuItem createACM = new MenuItem("Activation Record for Content Manager") { protected void onClick(final ComponentEvent be) { - super.onClick(be); - if (SupportedOperations.GENERIC_RESOURCE_CREATE.isAllowed(StatusHandler.getStatus().getCredentials())) { - GWT.runAsync(GenericResourceCMForm.class, new RunAsyncCallback() { - @Override - public void onSuccess() { - String currentScope = StatusHandler.getStatus().getCurrentScope(); - new GenericResourceCMForm(currentScope).show(); - } - - public void onFailure(Throwable reason) { - Window.alert("There are networks problem, please check your connection."); - } - }); - - } else { - MessageBox.alert("Activation Record for CM", "You are not allowed to execute this operation", null); - } +// super.onClick(be); +// if (SupportedOperations.GENERIC_RESOURCE_CREATE.isAllowed(StatusHandler.getStatus().getCredentials())) { +// GWT.runAsync(GenericResourceCMForm.class, new RunAsyncCallback() { +// @Override +// public void onSuccess() { +// String currentScope = StatusHandler.getStatus().getCurrentScope(); +// new GenericResourceCMForm(currentScope).show(); +// } +// +// public void onFailure(Throwable reason) { +// Window.alert("There are networks problem, please check your connection."); +// } +// }); +// +// } else { +// MessageBox.alert("Activation Record for CM", "You are not allowed to execute this operation", null); +// } }; }; createACM.setIconStyle("pluginCM-icon"); @@ -548,24 +548,24 @@ public class ResourceManagementPortlet implements EntryPoint { // Create activation record from VM MenuItem createVM = new MenuItem("Activation Record for View Manager") { protected void onClick(final ComponentEvent be) { - super.onClick(be); - if (SupportedOperations.GENERIC_RESOURCE_CREATE.isAllowed(StatusHandler.getStatus().getCredentials())) { - //MessageBox.alert("Activation Record for VM", "Operation not implemented yet.", null); - - GWT.runAsync(ActivationRecordVMForm.class, new RunAsyncCallback() { - @Override - public void onSuccess() { - String currentScope = StatusHandler.getStatus().getCurrentScope(); - new ActivationRecordVMForm(currentScope).show(); - } - - public void onFailure(Throwable reason) { - Window.alert("There are networks problem, please check your connection."); - } - }); - } else { - MessageBox.alert("Activation Record for VM", "You are not allowed to execute this operation", null); - } +// super.onClick(be); +// if (SupportedOperations.GENERIC_RESOURCE_CREATE.isAllowed(StatusHandler.getStatus().getCredentials())) { +// //MessageBox.alert("Activation Record for VM", "Operation not implemented yet.", null); +// +// GWT.runAsync(ActivationRecordVMForm.class, new RunAsyncCallback() { +// @Override +// public void onSuccess() { +// String currentScope = StatusHandler.getStatus().getCurrentScope(); +// new ActivationRecordVMForm(currentScope).show(); +// } +// +// public void onFailure(Throwable reason) { +// Window.alert("There are networks problem, please check your connection."); +// } +// }); +// } else { +// MessageBox.alert("Activation Record for VM", "You are not allowed to execute this operation", null); +// } }; }; createVM.setIconStyle("pluginVM-icon"); diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/utils/Commands.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/utils/Commands.java index d2b263c..b94c684 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/utils/Commands.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/utils/Commands.java @@ -207,7 +207,7 @@ public class Commands { StatusHandler.getStatus().setCurrentScope(scope); StatusHandler.getStatus().setCurrentResourceType(resourceType); Commands.mask( - "Getting Profile Details for " + resourceType + ": " + resourceID, + "Getting Profile Details for " + FWSTranslate.getFWSNameFromLabel(resourceType) + ": " + resourceID, WidgetsRegistry.getPanel(UIIdentifiers.RESOURCE_DETAIL_GRID_PANEL).getContainer() ); ProxyRegistry.getProxyInstance().getResourceByID( diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/utils/FWSTranslate.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/utils/FWSTranslate.java new file mode 100644 index 0000000..7ae6bb6 --- /dev/null +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/utils/FWSTranslate.java @@ -0,0 +1,23 @@ +package org.gcube.portlets.admin.resourcemanagement.client.utils; + +import org.gcube.resourcemanagement.support.client.views.ResourceTypeDecorator; +/** + * Simply return the correspondant Feather Weight Stack label to the gCore Label + * @author Massimiliano Assante (ISTI-CNR) + * + */ +public class FWSTranslate { + /** + * + * @param gCoreLabel + * @return the Feather Weight Stack label if present, the same label otherwise + */ + public static String getFWSNameFromLabel(String gCoreLabel) { + ResourceTypeDecorator[] toCheck = ResourceTypeDecorator.values(); + for (int i = 0; i < toCheck.length; i++) { + if (gCoreLabel.compareTo(toCheck[i].name()) == 0) + return toCheck[i].getFWSName(); + } + return gCoreLabel; + } +} diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/views/resourcedetails/ResourceDetailsPanel.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/views/resourcedetails/ResourceDetailsPanel.java index b15d258..f75bc39 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/views/resourcedetails/ResourceDetailsPanel.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/views/resourcedetails/ResourceDetailsPanel.java @@ -25,7 +25,7 @@ import org.gcube.portlets.admin.resourcemanagement.client.utils.OpCommands; import org.gcube.portlets.admin.resourcemanagement.client.widgets.console.ConsoleMessageBroker; import org.gcube.portlets.admin.resourcemanagement.client.widgets.registry.UIIdentifiers; import org.gcube.portlets.admin.resourcemanagement.client.widgets.registry.WidgetsRegistry; -import org.gcube.portlets.admin.software_upload_wizard.client.AppController; +//import org.gcube.portlets.admin.software_upload_wizard.client.AppController; import org.gcube.resourcemanagement.support.client.utils.StatusHandler; import org.gcube.resourcemanagement.support.client.views.ResourceTypeDecorator; import org.gcube.resourcemanagement.support.shared.operations.SupportedOperations; @@ -108,7 +108,8 @@ public class ResourceDetailsPanel { */ public final void init() { this.rootPanel = new ContentPanel(new FitLayout()); - this.rootPanel.setHeading("Resource Details"); + // this.rootPanel.setHeading("Resource Details"); + this.rootPanel.setHeaderVisible(false); this.widget.setId("res-details-widget-fake"); this.widget.setStyleName("x-panel-cube-background"); @@ -322,24 +323,24 @@ public class ResourceDetailsPanel { this.getToolBar().add(new SeparatorToolItem()); ToolButton doAddSoftware = new ToolButton("add-software-icon") { protected void onClick(final ComponentEvent be) { - super.onClick(be); - - - GWT.runAsync(AppController.class, new RunAsyncCallback() { - @Override - public void onSuccess() { - String currentScope = StatusHandler.getStatus().getCurrentScope(); - HandlerManager eventBus = new HandlerManager(null); - AppController appViewer = new AppController(eventBus, currentScope); - //AppController appViewer = new AppController(eventBus); - appViewer.go(); - } - - public void onFailure(Throwable reason) { - Window.alert("There are networks problem, please check your connection."); - } - - }); +// super.onClick(be); +// +// +// GWT.runAsync(AppController.class, new RunAsyncCallback() { +// @Override +// public void onSuccess() { +// String currentScope = StatusHandler.getStatus().getCurrentScope(); +// HandlerManager eventBus = new HandlerManager(null); +// AppController appViewer = new AppController(eventBus, currentScope); +// //AppController appViewer = new AppController(eventBus); +// appViewer.go(); +// } +// +// public void onFailure(Throwable reason) { +// Window.alert("There are networks problem, please check your connection."); +// } +// +// }); }; }; @@ -352,7 +353,7 @@ public class ResourceDetailsPanel { public final void setGrid(final Grid grid, final boolean groupingEnabled) { // Sets the grid container title - this.rootPanel.setHeading("Resource Details (" + StatusHandler.getStatus().getCurrentResourceType() + ")"); + //this.rootPanel.setHeading("Resource Details (" + StatusHandler.getStatus().getCurrentResourceType() + ")"); this.initToolbar(); diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/views/resourcetree/ResourcesTreePanel.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/views/resourcetree/ResourcesTreePanel.java index bcf9bc5..c7a4741 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/views/resourcetree/ResourcesTreePanel.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/views/resourcetree/ResourcesTreePanel.java @@ -115,7 +115,8 @@ public class ResourcesTreePanel { try { icon = ResourceTypeDecorator.valueOf(type).getIcon(); - label = ResourceTypeDecorator.valueOf(type).getLabel(); + label = ResourceTypeDecorator.valueOf(type).getFWSName(); + //label = ResourceTypeDecorator.valueOf(type).getLabel(); } catch (java.lang.IllegalArgumentException e) { label = type; icon = null; diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/panels/MainPanel.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/panels/MainPanel.java index 42ee844..b391099 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/panels/MainPanel.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/panels/MainPanel.java @@ -37,6 +37,7 @@ public abstract class MainPanel { }; }; this.setSplit(true); + container.setHeaderVisible(false); } public MainPanel(final int size, final LayoutRegion position) { @@ -78,6 +79,7 @@ public abstract class MainPanel { public final void setSplit(final boolean split) { this.layout.setSplit(split); } + public final void add(final Widget w, final boolean removeOthers) { if (removeOthers) { diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/taskbar/TaskbarButton.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/taskbar/TaskbarButton.java index 9c4206c..5dcbc78 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/taskbar/TaskbarButton.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/taskbar/TaskbarButton.java @@ -16,6 +16,8 @@ package org.gcube.portlets.admin.resourcemanagement.client.widgets.taskbar; +import org.gcube.portlets.admin.resourcemanagement.client.utils.FWSTranslate; + import com.extjs.gxt.ui.client.core.El; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Events; @@ -150,7 +152,7 @@ public class TaskbarButton extends Component implements IconSupport { String fontStyle = "font-family:'Reenie Beanie',arial,sans-serif; font-size:20px; padding: 5px; overflow-x: hidden; overflow-y: hidden;"; setElement(DOM.createElement("dt"), target, index); El a = el().createChild("
"); - iconEl = a.createChild("

"+type+"

"); + iconEl = a.createChild("

"+FWSTranslate.getFWSNameFromLabel(type)+"

"); El txt = a.createChild("
"); String toShow = ""; if (text.length() / splitTextTo > 0) { diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/taskbar/TaskbarItem.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/taskbar/TaskbarItem.java index e76701a..b4b6f2e 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/taskbar/TaskbarItem.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/client/widgets/taskbar/TaskbarItem.java @@ -62,9 +62,8 @@ public class TaskbarItem { return this.scope; } - private void initUI(final String title, - final String id, - final String buttonIcon) { + private void initUI(final String title, final String id,final String buttonIcon) { + this.detachButton = new TaskbarButton("btn" + id, ""+type, title) { protected void onClick(final com.extjs.gxt.ui.client.event.ComponentEvent ce) { relatedWidget.doMinimize(); diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/server/ResourceCommands.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/server/ResourceCommands.java index 5504115..9e1f32c 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/server/ResourceCommands.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/server/ResourceCommands.java @@ -19,15 +19,13 @@ package org.gcube.portlets.admin.resourcemanagement.server; import java.util.List; import org.gcube.common.core.scope.GCUBEScope; - - +import org.gcube.common.scope.impl.ScopeBean; import org.gcube.resourcemanagement.support.client.utils.CurrentStatus; import org.gcube.resourcemanagement.support.shared.util.Assertion; import org.gcube.resourcemanagement.support.server.managers.resources.CollectionManager; import org.gcube.resourcemanagement.support.server.managers.resources.GHNManager; import org.gcube.resourcemanagement.support.server.managers.resources.GenericResourceManager; import org.gcube.resourcemanagement.support.server.managers.resources.RuntimeResourceManager; -import org.gcube.resourcemanagement.support.server.managers.resources.ViewManager; import org.gcube.resourcemanagement.support.server.managers.scope.ScopeManager; import org.gcube.resourcemanagement.support.server.types.AllowedResourceTypes; import org.gcube.resourcemanagement.support.server.utils.ServerConsole; @@ -61,7 +59,7 @@ public class ResourceCommands { checker.validate(opCode.isAllowed(status.getCredentials()), new InvalidParameterException("The current user is not allowed to execute the operation.")); - GCUBEScope gscope = ScopeManager.getScope(scope); + ScopeBean gscope = new ScopeBean(scope); /********************************************************** * GHN @@ -182,24 +180,24 @@ public class ResourceCommands { /********************************************************** * VIEW *********************************************************/ - // DELETE - if (opCode.equals(SupportedOperations.VIEW_DELETE)) { - for (ResourceDescriptor resource : resources) { - checker.validate( - resource.getType().equals(AllowedResourceTypes.VIEW.name()), - new InvalidParameterException("Invalid type. " + AllowedResourceTypes.VIEW.name() + " required")); - new ViewManager(resource.getID()).delete(gscope); - } - } - // DELETE - if (opCode.equals(SupportedOperations.VIEW_FORCE_DELETE)) { - for (ResourceDescriptor resource : resources) { - checker.validate( - resource.getType().equals(AllowedResourceTypes.VIEW.name()), - new InvalidParameterException("Invalid type. " + AllowedResourceTypes.VIEW.name() + " required")); - new ViewManager(resource.getID()).forceDelete(gscope); - } - } +// // DELETE +// if (opCode.equals(SupportedOperations.VIEW_DELETE)) { +// for (ResourceDescriptor resource : resources) { +// checker.validate( +// resource.getType().equals(AllowedResourceTypes.VIEW.name()), +// new InvalidParameterException("Invalid type. " + AllowedResourceTypes.VIEW.name() + " required")); +// new ViewManager(resource.getID()).delete(gscope); +// } +// } +// // DELETE +// if (opCode.equals(SupportedOperations.VIEW_FORCE_DELETE)) { +// for (ResourceDescriptor resource : resources) { +// checker.validate( +// resource.getType().equals(AllowedResourceTypes.VIEW.name()), +// new InvalidParameterException("Invalid type. " + AllowedResourceTypes.VIEW.name() + " required")); +// new ViewManager(resource.getID()).forceDelete(gscope); +// } +// } /********************************************************** * RUNNING INSTANCE diff --git a/src/main/java/org/gcube/portlets/admin/resourcemanagement/server/ServiceProxyImpl.java b/src/main/java/org/gcube/portlets/admin/resourcemanagement/server/ServiceProxyImpl.java index 3b1e1ad..aa82529 100644 --- a/src/main/java/org/gcube/portlets/admin/resourcemanagement/server/ServiceProxyImpl.java +++ b/src/main/java/org/gcube/portlets/admin/resourcemanagement/server/ServiceProxyImpl.java @@ -32,6 +32,7 @@ import org.gcube.common.core.informationsystem.client.QueryParameter; import org.gcube.common.core.informationsystem.client.XMLResult; import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericQuery; import org.gcube.common.core.scope.GCUBEScope; +import org.gcube.common.scope.impl.ScopeBean; import org.gcube.portlets.admin.resourcemanagement.client.remote.ServiceProxy; import org.gcube.portlets.admin.resourcemanagement.server.gcube.services.StatusHandler; import org.gcube.portlets.admin.resourcemanagement.server.gcube.services.configuration.ConfigurationLoader; @@ -55,6 +56,7 @@ import org.gcube.resourcemanagement.support.shared.types.UserGroup; import org.gcube.resourcemanagement.support.shared.types.datamodel.CompleteResourceProfile; import org.gcube.resourcemanagement.support.shared.types.datamodel.ResourceDescriptor; import org.gcube.resourcemanagement.support.shared.util.Assertion; +import org.gcube.vremanagement.resourcemanager.client.RMReportingLibrary; import org.gcube.vremanagement.resourcemanager.stubs.reporting.ReportingPortType; import com.google.gwt.core.client.GWT; @@ -158,16 +160,16 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro checker.validate(scope != null && scope.trim().length() > 0, new Exception("Invalid parameter type")); AllowedResourceTypes type = AllowedResourceTypes.valueOf(resType); - GCUBEScope targetScope = ScopeManager.getScope(scope); - GCUBEScope sourceScope = ScopeManager.getScope(status.getCurrentScope()); + ScopeBean targetScope = new ScopeBean(scope); + ScopeBean sourceScope = new ScopeBean(status.getCurrentScope()); String reportID = ManagementUtils.addToExistingScope(type, resourceIDs.toArray(new String[]{}), sourceScope, targetScope); - ReportingPortType manager = - ResourceFactory.createResourceManager(type).getReportResourceManager(targetScope); + RMReportingLibrary manager = + ResourceFactory.createResourceManager(type).getReportResourceManager(targetScope.toString()); String xmlReport = manager.getReport(reportID); String mappingPath = this.getXML2HTMLMapping(); @@ -197,8 +199,8 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro checker.validate(scope != null && scope.trim().length() > 0, new Exception("Invalid parameter type")); AllowedResourceTypes type = AllowedResourceTypes.valueOf(resType); - GCUBEScope targetScope = ScopeManager.getScope(scope); - GCUBEScope sourceScope = ScopeManager.getScope(status.getCurrentScope()); + ScopeBean targetScope = new ScopeBean(scope); + ScopeBean sourceScope = new ScopeBean(status.getCurrentScope()); return new Tuple(ManagementUtils.removeFromExistingScope(type, resourceIDs.toArray(new String[]{}), @@ -208,7 +210,7 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro public final String deploy(final List ghnsID, final List servicesID) throws Exception { try { - GCUBEScope sourceScope = ScopeManager.getScope(this.getCurrentStatus().getCurrentScope()); + ScopeBean sourceScope = new ScopeBean(this.getCurrentStatus().getCurrentScope()); String[] param1 = ghnsID.toArray(new String[0]); String[] param2 = servicesID.toArray(new String[0]); return ManagementUtils.deploy(sourceScope, param1, param2); @@ -221,8 +223,8 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro public final Tuple checkDeployStatus(final String scope, final String deployID) throws Exception { if (SupportedOperations.SERVICE_GET_REPORT.isAllowed(this.getCurrentStatus().getCredentials())) { GCUBEScope sourceScope = ScopeManager.getScope(scope); - ReportingPortType manager = - ResourceFactory.createResourceManager(AllowedResourceTypes.Service).getReportResourceManager(sourceScope); + RMReportingLibrary manager = + ResourceFactory.createResourceManager(AllowedResourceTypes.Service).getReportResourceManager(sourceScope.toString()); String xmlReport = manager.getReport(deployID); String mappingPath = this.getXML2HTMLMapping(); String htmlReport = ISClientRequester.XML2HTML(xmlReport, mappingPath); @@ -273,7 +275,7 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro public final HashMap> getResourceTypeTree(final String scope) throws Exception { try { - GCUBEScope gscope = ScopeManager.getScope(scope); + ScopeBean gscope = new ScopeBean(scope); HashMap> results = ISClientRequester.getResourcesTree(getCacheManager(this.getCurrentStatus()), gscope); return results; } catch (Exception e) { @@ -289,7 +291,7 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro getCacheManager(this.getCurrentStatus()), type, id, - ScopeManager.getScope(scope) + new ScopeBean(scope) ); } catch (Exception e) { ServerConsole.error(LOG_PREFIX, e); @@ -302,7 +304,7 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro try { return ISClientRequester.getResourcesByType( getCacheManager(this.getCurrentStatus()), - ScopeManager.getScope(scope), type, null); + new ScopeBean(scope), type, null); } catch (Exception e) { ServerConsole.error(LOG_PREFIX, e); return null; @@ -380,13 +382,13 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro if (scope == null || type == null) { return null; } - return ISClientRequester.getResourceModels(ScopeManager.getScope(scope), type, subType, additionalMaps); + return ISClientRequester.getResourceModels(new ScopeBean(scope), type, subType, additionalMaps); } public final List getWSResources(final String scope) { try { - return ISClientRequester.getWSResources(ScopeManager.getScope(scope)); + return ISClientRequester.getWSResources(new ScopeBean(scope)); } catch (Exception e) { ServerConsole.error(LOG_PREFIX, e); return null; @@ -397,7 +399,7 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro try { return ISClientRequester.getResourcesByType( getCacheManager(this.getCurrentStatus()), - ScopeManager.getScope(scope), type, subtype); + new ScopeBean(scope), type, subtype); } catch (Exception e) { ServerConsole.error(LOG_PREFIX, e); return null; @@ -406,16 +408,14 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro public final CompleteResourceProfile getResourceByID(final String scope, final String type, final String resID) { try { - CompleteResourceProfile profile = ISClientRequester.getResourceByID( - this.getXML2HTMLMapping(), - ScopeManager.getScope(scope), - type, - resID); + CompleteResourceProfile profile = ISClientRequester.getResourceByID(this.getXML2HTMLMapping(), new ScopeBean(scope), type, resID); + System.out.println("CompleteResourceProfile getResourceByID(final String scope, final String type, final String resID)"); return profile; } catch (Exception e) { ServerConsole.error(LOG_PREFIX, e); return null; } + } public final String createGenericResource( @@ -433,7 +433,7 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro return GenericResourceManager.create( ID, - ScopeManager.getScope(this.getCurrentStatus().getCurrentScope()), + new ScopeBean(this.getCurrentStatus().getCurrentScope()), name, description, body, @@ -453,7 +453,7 @@ public class ServiceProxyImpl extends RemoteServiceServlet implements ServicePro SupportedOperations.GENERIC_RESOURCE_EDIT.isAllowed(this.getCurrentStatus().getCredentials()), new InvalidPermissionsException("The user is not allowed to execute the following operation")); - GCUBEScope sourceScope = ScopeManager.getScope(this.getCurrentStatus().getCurrentScope()); + ScopeBean sourceScope = new ScopeBean(this.getCurrentStatus().getCurrentScope()); GenericResourceManager resource = new GenericResourceManager(ID); resource.update(name, description, body, subType, sourceScope); } diff --git a/src/main/resources/org/gcube/portlets/admin/resourcemanagement/ResourceManagementPortlet.gwt.xml b/src/main/resources/org/gcube/portlets/admin/resourcemanagement/ResourceManagementPortlet.gwt.xml index d6d4126..5bff73d 100644 --- a/src/main/resources/org/gcube/portlets/admin/resourcemanagement/ResourceManagementPortlet.gwt.xml +++ b/src/main/resources/org/gcube/portlets/admin/resourcemanagement/ResourceManagementPortlet.gwt.xml @@ -8,15 +8,13 @@ - + - + - + - + - - sweeperServlet - org.gcube.portlets.admin.resourcesweeper.server.SweeperServiceImpl - + + + + - - sweeperServlet - /resourcemanagementportlet/sweeper - + + + + - - guiceFilter - com.google.inject.servlet.GuiceFilter - - - guiceFilter - /* - - - org.gcube.portlets.admin.software_upload_wizard.server.BootstrapListener - + + + + + + + + + + + - - isHealthServlet - org.gcube.portlets.admin.ishealthmonitor.server.ISMonitorServiceImpl - + + + + - - isHealthServlet - /resourcemanagementportlet/ishealth - + + + + - - arServlet - org.gcube.portlets.admin.server.ARServiceImpl - + + + + - - arServlet - /resourcemanagementportlet/activeservice - + + + + diff --git a/src/main/webapp/conf/resourcemanagement.properties b/src/main/webapp/conf/resourcemanagement.properties index 9fb8d3d..6e268cd 100644 --- a/src/main/webapp/conf/resourcemanagement.properties +++ b/src/main/webapp/conf/resourcemanagement.properties @@ -6,12 +6,12 @@ USER_CREDENTIALS = DEBUG # Defines the modality in which the portlet is running # possible values [STANDALONE,PORTAL,NOTDEFINED] -RUNNING_MODE = PORTAL +RUNNING_MODE = STANDALONE DEFAULT_USER = massimiliano.assante # The scope that will be used as default -DEFAULT_SCOPE =/d4science.research-infrastructures.eu +DEFAULT_SCOPE =/d4science.research-infrastructures.eu/gCubeApps # the target of update notification (if in singleton mode) # mails MUST be separated by ; USERMAIL_TO = m.assante@gmail.com diff --git a/src/main/webapp/d4scienceOrg.css b/src/main/webapp/d4scienceOrg.css index d58ab98..1157c3d 100644 --- a/src/main/webapp/d4scienceOrg.css +++ b/src/main/webapp/d4scienceOrg.css @@ -1,10 +1,58 @@ #wrapper { - font: 11px/1.5 "Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, sans-serif; + font: 11px/1.5 "Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, + sans-serif; margin: 0 auto; - width: 90% !important; + width: 92% !important; } -#bottombar { - margin: 0 auto; - width: 100% !important; +.x-menubar { + background: #FFF url(images/bg-pattern.png) repeat; } + +.x-panel-body-noheader { + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +.x-border-layout-ct { + background-color: transparent; + border-color: transparent; +} + +.x-toolbar { + border-color: #226599; + background: #FFF url(images/bg-pattern.png) repeat; +} + +.x-panel-header { + background: #FFF url(images/bg-pattern.png) repeat; +} + +.x-toolbar .xtb-sep { + background-image: none !important; + background-color: transparent; +} + +.x-accordion-hd { + background-position: 0 0px; +} + +.x-status-text { + color: #226599; + font-weight: bold !important; +} + +.x-status-text-panel { + border-color: transparent; +} + +.x-component { + color: #226599; +} + +.x-btn button { + color: #226599; + font-weight: bold !important; + +} \ No newline at end of file diff --git a/src/main/webapp/images/D4infraFWS.png b/src/main/webapp/images/D4infraFWS.png new file mode 100644 index 0000000000000000000000000000000000000000..7162c8ba0fabd09117f49d190a1cd54242351f7f GIT binary patch literal 38740 zcmaI7b8v4#w=EjmPIjE^7{A!IZQHh;?AW$YN+fLs8&b{Z}_s2W0t5&U^tHu~} zcK57RwR+7CmzNcThrxjX0s?}U5EoYbcQ5~U9YcWt0ReY~w<-TKu$@KJot5lNo!tx^ zO@IW9?F>x_C2S1LOcYHFj6EF2Ot^u7K#47s)t%L4q&bc3Z0HRBgQ0V`vH!;g0^;U# zw>L1dGI1s}G%>TV4~wY5yT;ojh!v4cuvMok;#$LDy z*}~42@IQ(MhITH_JjDMZ{a-_{vHw4^wod^X%TO$?mv9F^_ttp9r!<<0G! z?VQZ*>t|IIc2zg&U;k^7%iu(AK=S=hwU z!qvoB)X~m{@V|!4Y4JbD!uCJv{co=E{~QbZ|H!5P7YzM>7WV(O(Et7DU-tZ``+w5* zpYeYZ-^BJ`wmbeyYmV1*2_T@vQ3+uIW%u<-WgF>VE?75PPo8Ymw0KF)ic~soXse91 zbG?g0uL8)E%$$7Ib2OHMQABqp2^@N?;Y{7LqmV|QyVO$Z#J-LbWD|x_p=}%{14Ptt zF{W4Q78W;>UR~Q-UT)t~=n`rG(~sT6iLHmt2kxGq8;>!9d1e_mCy)zU%||PaKsk6* z@ADwCmu-t`JwI!*FHxkU;?(42lP-fs)V5Td$Yyz z_9bok(?y}DU`jSsFkvT8o?YeT?4fO2PndKuez)ITCS(Q1q;ZI75-3&|n}mEA(RJz4 z0C$$u3FttI3C7eTQ_6_VOK7l?aehLwO7qUOuB|v;u?1#&D6&LkT-{x0bnWtT;Jm3E znS}+lZxecJ)=WaEH*el-Qv)p4%xG#l|NDnFy?Gj~`smx}Dd0l^M)@n(UlWc)J385T zyE=a(F+aZpo>U_wM8MmX-k?BH%fB$>)|Ak@Sz1YEWPTu&}U0-h|bhX0p@iQKEo#s|RFzu#q}` z`Vc7EY@Is9o~=^L42lR5r*BU%5e2$Ta8CJND#?09Q{wCBmugesh(3qTl3`7hbNfYo zEXhT;?w6q&lja6t6zKPgJ`ykk=jCPH*4K}FZ|2Qy1Ot^i^~pVZ?paqatqB_wLNbgn ztt&58qv)6%WZ}E~7|4L{>yr~?ERgK%oGkP0<#$mxFAoeM)L6~%61sW4{)@p$saR%T zup~RbyhkW*4l(L-&(pS!6&hoj`=g^*HmE4d@ zt(L9c>8j7x*32myMYbem1Wu4x=P(bLz^*BCFYfQxs@CHuic*P%1Bz-$>K{bdTG`0k zGKlJ%rY}gafYR3*4u)xKb{TV9h7mnkJc$MEjtcTj2JIC*F(qCkekRy+M^qS^RVIN0 zgqh(mjgvI$gd)oY(fjG`wbe=%yVNHb5X$5Y)Y}Rrrfg_T4SGk6$f@o|^EtS6g6J^# zohz!wM2W$QN|r_3Bb!^8daQ1oeg`aV)hQWTk(fKIh#9c0IL1Wb~a(_ zPeWn{*JwbY5&^;H(uSY)Zm&^`|4=RnK+lvxMpyyMv?SXCIZjbCuRvLbhAM-95S+A6 zhd58TAnnyZd{5vYv%6Iu9TRW|jERB_U6w)7iZtgBMVChSXHb&^7L zimzWJq(v}D2ZxyosT-Eq{_3GaM{Q!15fC8h(z!OS_X{z>`-qsgoznfid* zr_E#w5Sy}F)20iL1F8`f6Z1Yd0Jpz4I3mfo&*4`5`2=S@hV8szODEh0!7P$l(aKuC zJ7MxDRToNYspcm;&iCEz@lzhh3g=OJEbu=~c=<)1x%=QCU_aY_SOlm`GuSQE#~POF zbmw9ckajhr>XQBVIZ7R|KH zd~6xQ_;nH+^(Lz3itnHKejIz$gyYZhc;<3@=&F=F?s+UgX-dlV42^jthhJsK+W1!{ zj#c)s@=fkuugoz>wlpX+G<0Rg#ly6rX-po>uD!|yP_%MkrGnYH@D5cdm~06^LiM~g zwlF_7I|mQWFqR#>zty=)sZU0RgmyCl*j*DFMEE`ePs7{8MO(x7K+q&Zw>+`m1i*04 z>pk8}8G!Q12Ifc|LVP%Bb!$GWfftSURzIX8B*JXsIAyi%8ub}*d)4XP03MR!a<=9& z^-OxU&wotm1?QL-FNV9f(eI!wn=-|of6b2`3f0~0-Z=QdL~Wo=T;(G4J|J+1NAZ;Q z4gixFUJe>Eb|+79qoi;`PD}?rz9nZbT*aBG#-t)(gLJx`&dv2O5nN#guQE{5(sXK_ z-CrsJ-m(m+b~QX{?gi#c$2S9qbdY!{#gT?s8CE24umFC`j-;FtBXieT>-zy6wG)M21% z2hObCuHArR7f?mu0@xpLS!jL8TNrjB;=N0G3UsREd3`|2jfbBg27nGGKH6{@A=Pf@ zPW0kxK_mTaHYLlobmRox8CJ*9VY}a{XBnl{*+ZZ&eY`w=68#kyEAT)uTGOY-Z+D8V zneUT1MgdWXD3Oe+gNbQgI*2TD>iXFp6K(g&MoSL^?EL%}aX)YoAn+ZNwGy$26$}cf zd|EUp}Og5F4k_ul#|lD?D#``2^BU+t^*$YK-V-$zGIzJBz0E>go<-+?Eeq9pUfK*RYS>-X-v% zHOy~?>jOF7mIrU}P|32!b!*@!ZC3g3;NWzkd?HaJl2&PVCgg@mQzwXu z{`_Nf`VzI6lg5;k<(nA1FfgQW^EPb=4dTPfTl|Ei@O})3%pBCUHAvjKi-(2KiBv~N z0@N&}dP=tf5Bu6WAmsdt#FvV(*RkgfV6_XApdzzg@Dg~fJn=np;Tf(~x>WyhT=v04cZ9S_Bo+=J9cPy(U1zoFD2pa7d zoUijPg>XMe?L2cNsKE)D%>2%UCmwTk((zIAfOsGZC86ZpvX{X3C?-_D)sKgUilPBJ zSS)Z*TbrXt9Q_kQ@px5}%!9%ONNh6m`_<@vJe%C{8t|E9;=uzib4;s}11cxJ{1se2 zy8Ds>Ry>?RSz)w|tgkQQP@KNiVRz_z*wPwaNUcpRYXX0LMq6_?FLb}}v6o?=QLF=> z9Ry9``-t(asA?`Q-g8%?v}4S*G?}9jQe8uKzWjSe{C&r`pu50#Z}Sg?(NB3XC8(*@ zc;%oF-|~lr>p}+jSJ14*>G*@qFW81BbhQTOy|b|foG2T&cWe1u3O+6pY1{f%eFBjX zkKL6-K0VjguGuLzjN>!v=?C+SNH%X{EXY9df5hdQNq(fqUBu9RGt8f_1x$jpoNF!O zI%ZB$sgE%EsKdTL$zsBr3Bu*dR?HI$(!_pTr=kpP zD+fc+ojo<6_L9z*)`Y{nHRM#B!?teh)-UqmxBz7&O4TwmX+N}YG=CrJSljZ+eGiYd z3}%~*;*W$Pt#-jRG|0H2c6|dhOnyjU8{Y$z zuj%Uh1O@>_Zwc<;ZH}hW+HcFnaO(_z%>0z%?gv785k{A#g|iP8i*PoNz*B}6x_AGf zAqD9mB19o2wCR&~O0+Bz*2DqRc;io}NL1erb1Lh;Pm`IL$b+e)sV8i$U-iv8k{jHg z8hBSvGHD36aY7x_D-|t`JdIp5mPF#J+;wH=?Y~^Y=~;|zZZ^JUT8Dt%PsT@)#oYJz zoPLx#RC$}=^ORCMiiQCQamMqH*g29RC9TMWO0~QEFBQ(-yuH{ zP!1r+%Gqdc_P43b$#~(HjoM8LOMUe)Zme7_@u(Ao@GW zyUT|lG4<2H;fhzOTDfsrBXsE22odCbe#5Z2K($hh z#S>6kFv*ucb>;*E@m>AKZ^mf%NA8s*D zf?TpqbGb&+oIZsi7Qx^1{{CKluzCOBC@MzF)}4@9Y9Oi}m%FmDQYtMaq`Wd zPeLeR=kE!v$Gs}WezBgSnl8x8X<1N4*aVhc5J(-!?onR;_wTLX)=(X`VZ3-_<>B_f z>;W$yodob2$7}4-f1j&R_xT1qXNXOy$6x!>2kiuSvt6{f@lRymaP7{4A{W z>jfAyqkyFmu!Z&_;WxWCX%5*>*x#DYs zbW#=Y+7-;M&KchhqBR;+R?7vw^Y$HFeH&=g)va%Q-)t*ySgJ*FY+E#}gU}HbBM&AC z-~?tqWr^i;ZCLv-H{A5nV(q~N=wVIw{o4ys|7)+HARm{Sl!kW z+y7EN9Y4mKFZOQukOjj}@DBI+)f5;m1(RX-Z)ysL&0T_s=)vvL1Z{1TJ<_lit)74E z3HUZT7#c#NF-=e1`^|e-4Z)}P=7wF*n+rpF9$j~SMzw|U`?CYOzA{?`czdPHD(085Y} z3k~~z9k!IVGFWgQ5aBLH*nlfX7GwIPP+q-qoAT>pM4-fKG=0X(+E@U2r0nJ<9vnP; zfI(PtszfmdN5<%={?o15k<2@hnr-{!MKPq9j%^F#zNtEjojzELu*b^=oyvJLh^GeA z)hwF+gNl?kHSTkeLATWP8znN-P^QTI&=?e!wBj2 z%@C|SJ^TW1n~49#Ps=kx-0Z#f%L(%`nSB`8n!v& zZ`HKny6`k;Gd}A}qv%1`G%6ZXwD!ft99~@oXw0inB}2O$tOb5~t)&MD6UkaFv5xhp z(kCvUNC)jY!Ioh=*>WcD&Qf5Xy*=X>j9IFZmIt+;!zXzNEt1FH=3;F<>Cr>gQ>&`7 zv-DjTYuAaG>>9s^sTL%M)vRUjKFJ^h{a&BYGJBQM(g%{ZbLqox3yh=YIEWyDGR3~0 z2}Ry8Wc#%Oc{^FhH1b}F9#l_pX~}0jR7k$83zQ+(@*nGu55t>A>!(djU3YvO#1x;g zqx%c(4hHRAHZL?qJ*t*h>4)5}R>&6P;=3EuhFjiCtYK7T%L$eF5N!mvtHuKrT7p0> z|Lt93m0Bdz8>hOkyM^IrBiMT1zYEYFV`W8A{lxSmK6q2zCT9d=vQ7dUWEU${pUy*h zlY0&AS1qX#R?F_WWux5B)-QI?f499Bw>a6;VkL$eN07(r+ISdRUxO{&b&Iq^!@b@;PiWFS68dwr(4}h6JWDe_zU+G$2@4#`;l~s~>DJ3hj&K|E@w>vtHgM z-mNQ$m%=Lng{r?@zqAejI;j1!^R98f=#`xc`g|#jWU(e+cW2F|O(mTTCWze? zd-AyIv15i;S3g8#A3-Kw{ znb&cl7#`Z@j>sr6IYw&MFdv!2G<#)Z*~UbE3T1Np6J|A!e1OytP34DJN)$$5Zb)f83Q{axQ)|A*6wqk_*-{ zt}0i5K%-!{zK$1Ep$HvR_NHEKlfPMXIubV`L1y4xyqR>r_ zp7w^ry#UeJ&i&|C3^GQ|dqoNvAvFw;0ilY9`F&k=BZcVpQ~W6I>bO|#cOK!$r12Mj zq`jxJ?Y-dcE};$UYSFb(Jh=NPvUG|0xu@a7T>dE(?!6VPIKPLw7jloX%yNLgXGMyX zd}x1jv>P99_+B822t`D)2pXuSQWZ9LBqBWiN$(0-YQJDm;mZdPEkp#$BVtuKaxJg{ z+JTu0J=hfvlWbUu2oRd=$`N|yDn{7#7YzP;=;Ol=x_3L#UreERO=WB8CB4XLhcr7l zm}CzsED(Szh>Kvx53XPj7JH}u<~oOs&2Ng0jR)p7x1@o7D6cFJ9VRNz&rgITCCkJAJy(pB;F81)KNn7?5_mTWyyGo<1;Sih5F*40*H)n zU^ewGgOT=sA2-3zI$YC@ygi7CgiMH#xSs@up90!6gHVEO)M^R1zklJ<&Qtxyj&IHC z_1vr{iVNZ<)z}yU6Q4O#T|cx()AL6Z62M4>(x5NSFc|Q?7)9;w0?Vs_alu+5)N=|-mdbG7Urs0--;eB<{YhpA`{ZM#K;4tyF zb5>to`u#Y)8}DRYG67p!I@RMf?k4LNS4HKW{zT}cGAcJxm4^TDY6F7%D=%?8R5NFz zG$*AvJHch*?T4+D`rBozTA)p7J+o)4+n@|9k>IoF)4E~l0wFE1k_&0pD!Fa#js#*P z76<3ok51SnA}3rREo~KiboA5H6GB)dDd?#EU{#ee)q*)oTaXi6I<{xmcUU4Dzs8X5 zeEZLzPp93W!e5aS`wOr*^xnncQxhzM=1W_;F+h^8=zoTYiP+F_N7^sDJr>|Xggil= zDpfZ+Hkvc1bOed`gXam2Q6!9o!C(~mHHf<;5TpU(knwDNh7Ac6yg4uqu3AE>$6XJ8 z)Tt9c(DyrUiz;dAr0YMYJvQvP&bk=msE6ZFfwp)It|&6`1|R8b=fD}Is^d+Tlr#{t zV9N?u^@|h6^{3`tl4YSbr4|`dEBe^md{Z6AUOwo5VhHufUdCxL0AP*$w=;4OI2kyg z#`<&pAwprt@L-?cI8IZOEB6;Gx2Ii3c1P$9dK4&}S2|&mlJ)ncZn|YS8gYe@Q6?IP zoJi1h2n~_X9q0i}noX?K6F>_gJa7=$5v15DDrIQCd}oerb=R{R+hRLcE{BGKuTelz zPG<#rvk@W0+N8w7g89PIqen36@fquyu_FzhOOo5M&QiN}zLs*2^$z!)tv6}gQ#n;$ z748?nm(yhjzbh#MhJukL9bf-2Fy_~kdEeab4d_>Q^ZN_NL!H7nh={3gPsG;iYZMD2 zSFPw(*O0K=;nITvwRVyt<+BcqqdC&vlN#{mrk0o!ou~zX#%CejIJX%ywvAj=S5l7r?}H z4`SS(jbW-3rn-Cc{u~Y+0Y)KAmJq{0V`gPFH8Tr1RdYPOZQ@!(y`$azY@wJA=y8NJ zYiVpAE9zw^nmxZ&)tb_ z&Ms;-=0|Xk>CG>Lt<`q}Q@8(I?I%R#*3pDG!46$ASC%b>EkQ_QykT>C@mBO!arE5@ z*;NC^CxmivR4iCCjF*^0tQ0pfIcoRQ`&h8wBR~H^D7E@}PlXGW&XeFxLc-j=?ZR~T z9oWO1_R#dyw6gM2QbHAYWaMr=Sre$C4kb?prNH*G8EuO zM+gwi2jE0wL>|>#{4m|3!CEM-twGeK)vjA7W0oJnw9T1E#Ks=rRc!?eQQl-yuDyUL zQ*FE1_xU`ivpP?qIM;w=z0vo)Q<0HjO#j;a=-QTtV$zVtt!jI^z1i>s@(0@tI=X@Q zWdke8gqM^9;jXFVlzvPl9~^7z_0K5Oj^ zaj1=j&D6vMEq%>y3o7O=cf$Q;-p)eD+Y?)q=)-9Io7qebs$;z`Vv~?E>UN+z33B8f zKX3&or=pfti|NxtP1kqHnsxQx&R%G7EQ0>6S$|xJPjY?`V&Vb_!ynlD2ZI{_#{lDF zXHL0nPMtWutX$3vtmlJMQ2Bv`zM?SrsRKto1x7SK0rFlYTsk)!AESS7xq)!1@6Wrp zrSQ8u_HwX52Oy(bYeI|x=Erw)x;1o445boj9H`gG2vd+LNG$(X*jD@Yh2mlonEUv@ z6K9NpH;BiTzcsV z38UZ-d%bo6Z*5z2sSD5%s1x&f{+?aieH0PJ{|YqbX>4ypn$--r~M4N0(V?_h3ONqgu$!5{M9qPSg=+_FKkFbK;$P>m9oN{>U-5&zEjwa|lDex1u`E>lEv@XiIYW_q>m0#G|dM}qpW z&Echjc@0_E3#8|_I#;7>743%y?h==jlpj698-Sn5xI zmXVMJWl3<`b9{Wfyv!;e9Pb@+7fLv72hn55BGk6%01lUbvUD%g6-Z+I$$;xTsb%R{H__Geg`e>lg4&i4< z!Gq22q>J2+T(53VlpYCYIw^<4=QwJ~7LzD6;2C3@6}l)&gd=k6Sz*_V9Um2sqdRG9_A(Ai{M703C%-?5y}%FXs5A6Tn)A*pA!wm^Up1oG`Udr$kQIL@xO)nsfQRW+9fpNnUV~7FwuRt^6Ha#X4j4R z*7f-g5!VfD!K%|TA4&pG^(umpV^eg?Y#SG(#ee^nMzHe?TwXnThJ4ou#OnHVYY5wv zeyw3udp+;5*|2_AIY`4g;XWXudji3HjJwPEq+vxn#5Q&#qD6xbFztiEA|j*tqmzZs zl87{JYwjFj`fDSb3sHH8m%GpSr3q_m#ZjzFw)v4w$PWGU$BT}0lwJE9RL`wZ!&=Sc z==TsMCi>AgUs%shMgA0aadJ6&LdEnD{hc4*%|+^K3qj{LU2bJ6A_i>Sq!{!jhMtS> z4S^piG4cKdHN8eBi>3sXR6&o-E@38gzPIT6Fl@?81r33S zR7WA^Yc&Rz+|dm+8e@`q;U{9|3!tvpl~f+aZaMT>l1X={F(I!NJ?4 zl9A4MEW1-KwpQuyaiY1G-pyu}&EmvjO5wRZ-}+*ygha;o=(08(-)1{b7)WDd^VQlS zaF~!l%;}w~wCYFnqGBvn?w0$rQha;`KooIMZnC$)9CKq-g4xO%ZwrK_!iPWqpKzrm zH~)<5d@gA16lx!0%HIL0&ssH&3Cb;l*Y@m9p1;NAr>YCHCWUAvIfzw|#4{UU=MR-E z?98Pm8pYEMFw{DxkI%*b2-O`qtiE35{piO9o$O-g*

8s? z-6dL4;Kk^Kc^eKwt*mfxpWnNyEKjRZRK*_&8n3CZQiXlgO#2R*h{Ry{4># z0ihOL3*vYCnq`Ecy65lM#J|Gv}{lOzp`S$V4rZmpxKpgQQ;`7~~5Z-}q15;zsUXV?+I^PO`Kk?EP>%{gnx-=u7mQ>m7L-?{SGmnpXg3y5W2d zR5(#uED0C(w|wC8b1qiwXWsSB>NG00kdwSjK5ZtBQj0gpwAe13pCDPiygA%P_fMIW zVa&*@U$Vzp>eH>C-<+shX9d-(c?^t;J^m3VYGjpBT1(lR7TeyPwlDFEUSujmRY}P_ ze^fXs?pIE-yh1CP6Q3}&MfD98{=n3;LA99 z8cZHlx7OC0x3wex)sB;S{+9H+d`rT0bz_?sg;=n@#dPRA4#y03H4881aZ=#%?D?3S zFX<*X6)kc8yJhAtr&8(=%20YQC`(DnGsJO(P#%iKu(8ljE$1*M;z3BAa~Gb8GWgnL zy_vA0#*GAmLKLi%k+b->yuo+`amB(q?}3m6Z$zNsSEHMSX&`HS0Y#hi@H>TIM{T^Ay9b*U>@BK3x<;t)A>Wp z)=(64jCG5#jIF}kZIlYo@68T&;$ed$RtGX5z#e)GHzUTIz-Oz%oDwjJ2vc8wk;x?V zm7_)6EU=lwj6j)?BS}#L<17}d?;Rg%c37Nd^6-WPT#N^?<0rcy1Yb9tsLG6WTDwS~IT`NC>JVk5vDa{-Nn!QdYB6lQn>{Z0sMH%z$G zUKoJ_oZNJ3=3uDaE&RY3?;fzdr=LcAMz0}O%awaK$Gmk`_x6*d!;pUtY44$I|a%G5v=N z&Goq1KgRa;jt;Ocvff7n;yGULm{?Be-FRQd>q6Y%HQOC;<=Sjl*_M0GTwTc<$a; zCkOW|T)baok^%Kqhnf%gZbaMIUQ2dcO>_daE3W9`-ZESZ%nx^yX&kBQYnY)li6b&LY|iOD$uv zY$6n0rnJ6Qe9O7WSl_trb4TQ;S;~+-!xyZ0RaI9^Er97-t#kHr%v`HH+3{vAo^SZJ zyM4feRQrNH+4P^)oXH9|L(UCaI+mWrxC3Q zHKSvmn2AT|WqOT(cDPmLex6s~!*fORGkz-De=!+>qEV+x#OAo@oLTqVSGI4fFo)kk z0C^M>2i`*XLr56zFK}-!)H$5N{HDrU-8`n^z2;UvFAj_%ig!2eO9N8*9e>f@ng2zQ z+hOHBX-7U1ozr9TQUYDmbMjh3rSGI*ePTx*W zpLW-Nn?*llUuPWIBYHU*xBJeI>dZrR3HX2n(cR{$H^POe29k*a$H(d((p0({&+Vs71RS zmI7^_0_o-Lj}Tgg-cqqTH2ujiZ^^OExy)Y%VPAy<&ZL2HNgu8P>MI0?8Ni^jO4jYH z+Py|T!Rh)~UlfC{AZQ}PsI@UNl|L<&t8w4sSMv&#Y_^|jH9M+ti7F}zfcf#Fxw+@d z((QvQ5C(imuCbF4O3wb#az^1b&8saH-`Mw!BR2DI`meo66A_OYZikzrn%iTq?Ux+JdlB|no>eo7 zjBw$_hjEve*m%_<7_@zAbD2T(+g!j?CFkX~Z%Wu5HgDoj-wO(v+0LJ*pRJ$wjE}fDc8wVRZe>yszTcdnU zN1wADJ*Ai75!$}Ej~wi9M4B>uU+=7dcS=9g)j_k`b%v}_y^qm6@ii;ow-`58)gPuS zwj~KEay`B8pDl8~i{W}>XwPxok7t5ZN;J^ng}0;h6ms7FB6cA~;d;iKgD?Y+9e^mF z`MHhHXJLVjoDuQfQvpFWD!CT^S0D8d>W#}&bJy+aYWPkB=cIFYYm?g$a1;^%EwRg@ zte*YtM?~A}xh3KOm7YoV3FgS}58RILPb_IDC2{ky@;Q(4=9g)8Os3Ku zf$lL@l|NIT&r0DTOTcb58zvLul+#o5h7^||c==!wFqkk<`L%Lo2NJ@akeDeK`<@0T z(=~3_>q{q~Q*v<=#VB>sWRP#M2f;w^fw0;I770&UPx+7Vz_BYcA?=dF1tO6cs>)IC zKlwY4_pGxs$RQ~0zhqz^(iJ2-s5r9%&dI*~xUN$0H_)7x=Dz>G)r01c<#9>q;f zV!R*T4f22L?arMolNG`FhDE{_xJ!Nx!)Lw?8Upj2sI@7C6{7LgVwWP0z0y4Q@5CA! z>TM~$a(GT=_-cvWjt2PFx8~R8OqtlwRDC)ss$7?&D4lbcpj4_5YWTz@p|lH=#7T+M zhKPYJEMGyQ8?(n!%@)((*r#@nzY+Ub+n)}eS)(L-iTOU^F91LBY(&8ZB}uU$E> zG^=danB?}^eMwGBgOqKC>0$W16nS}_PV$#qR&WV)GMas_AlnL$+bWME>fwqtf5A$b z5b?O@y@vHC5$ZoaFHRgm|Ep&*hhTz(>zFta+-A`BX2vVzgZK#$&5gwTW9VnE&j3Oc zLvjh54kxmfV`cID@i~#>v92%PcKt{&^D1(D;bxI4jQWfBu_1cs%`;xT-ROc-Isx8@ z)DZW8T=sa^4Ef0T@X|vnr#uMe`S|2`;^>~AkiR~iP!LUISFlWZePK)L;S}rPU8Yql3fp6|t-=K-}F_C?=A zXEwZi1L3TgoU4tO!xZUj2K){iTb7JPZB^U}TYMSSC@Ms-0Kc$;U3yXp5^HKAj50;6RBI-wGfixHc%6oov*N%eJ90fljSDX&1o#5g`{#;PLBEKC z--(hJmzQNSm<^_F8ftjH;16`^tKQ~jW&YS^{yQb~RL9Pi&TVk8j+p#jpEtwAIzrz! z_OGO*W+VtmUjCUV0roiNINLA{ix?uh*8i|JbSBH>{evI3Y|+=mE_**ZTImgW8+^hgYzSPm|C@X4M%=hQJB z-F+#2t`Hh*IBXS|k3hweeY%OTVVyEDhqBT`rrytef<%KTzu&`Gg(F|PI!a~g4$tJE zNksgg;Ny2cxhw$wF%_&IYGC@L$i3K+HUX0KPUo3l(#F->M6TX%p?tpYGx(Yn%-C%d zq3-Y-kZOJb-<;x(UsWLC!4dLLPw+LLGm$HyzMM#+qfzsbXWQ94-O0b?hO+cPOR^~? zEVETlUOoaY;)yVTAddnBxe+Bqc!$Hs+~@PfeRXq0tAh85kqsKwG&iDzvXu@>fh)n5 zrNrYb#RJlbK_-N0ASj)h@2o8}&I&?cYx=%hZq!eP!o#R(B~+7&kIm=Cky_OvcteUa z4|na<(;A>q?wLVM&_7otTE=8T%~vhhY@a{Xg|=`dLS#fp$i9(9z5 zC=xFn%Sy??Fm+J-4B+?G{qF99q=;yTc$BJ`rz`E(X@E7UT+x0Ar-v)^R9y_=0E!e( zizsJPAeu1?`av?7^-imE+o~J2Y`WfT%6xc$36Wo>j4Uo~XmFBNIU;1wYW3Z9ST(?% zj7UR*3<5qq1zb2(DpRR;_T1yl(#PpmTfTh_p+ma^y*fD-&;=iIi-@Rs6TrwS4;Zvw z3ihIzN#~}dWVG83kkK7ykCXtx)TPVi!CE7fj#-~e?KA&*SH~14*qmQ4P%ay=jvbg> zxJdlBxk?X)ZLc%!*ZckAf+qrvt06wZ8!FZ?>&vjO0f7uva{3gBF|||Yw9@u)VkC_K z)9d_a1903&W8a}20{%8Y8~m*Sl)7X&F*5<}#28w@zXCB_>oYR_ON_5`^~|w1QsW9E zpJVnhFaE@VpT%fcSvCz|yI__HE~H(OZ|iN1;?3)J&HWdM@Gw*hR3Q{e1X~~hJzvHl z0c-NG>AY5`0NG* z?!)t?`@GEw@E!86peha1g?;&YdrkGC0W6Ip}ofaSbysr2kzks25~w2*dkw zfHsl*daZ@P_vHgLob$@RvMi5xyhz^aG%>$4rAEEY`OFBnemst{*NDN-UPVHAAo3aLs zJsqE4To|;tR0!%Ay((fBLJITZ!DM?THe#kf-(PHjzV6f@ZI2|C8EJVJ8+bW8`hHmwv6-nIN;6G>X&U^l@dTk-r%nR%=&Ig*3G`m@Qe?w%TpHQinix^y}@JVAq|&HGBV@vAMZ8fNpPX z6)IDzUqTdZ7vsQ@HM|M-lG*=!z8&xHgMfWgV(7>UwV~zo`$ir9Rac=v1JQ<}B7DKk ztwEFtjonSL8+<=;y_A;+3#=2<2JrB}Pen!ssyZRLTa-Z{oW9JbVCVMO{RFHvyq5xn z`GJvTZX5xB@7uHQrQ=?LcQ_4p1l|$cY2YkCPW*ue$aAY$vY7AU;o(6IN4wnbng{ju z^%@`eN7bEnV^GjM9B)BTP5<)qNu2tWtYcr910T$%7;=mLgT%s|6+dB2p+zW?oRWkU zji+zfFy!9V)g`ShNP@pGgI7cHrJ0S9{k(AM*D~_)`M~FMa&?5$lwvCM)rY%_CV;U( zFWfK&zRIH*1$qjq0feefmnZ}&QA}~uBu#asuN^?yufKlDTCs$n2)}5V#MQpV?)5x5 zmDvJBzuNMnpVUxK`tj)tg87WSf;FL0w36*RdlIk!wTjAaJ{5sZ-M8$*j#ml8{rBUI zfhlL>HVpBC%^P9rUjxpZ*)$2Cu_oBkCbbV2&nl3Ec+jOvZq>fdx|}SQ<9?sMN6$O7 ze<$FY0K|?A^hbzN_d~X6yKbGy$;$3G;-9)<^`8i6N9pocP=DRbdRkHrk~^&}nUb-R_wFNv6Q}uP4)Nr8tWG(?j(jh>Ugf z3yRd#Vt(I4skbV*S!lN(JQR@}IDWGp(8zR&zk7SIBJpC91mOn65CXUjzh_LVMheHI z3hK9VQ#0YIwvPT4b%q4~Z5;++`QK$nLvSlt z%8$t(E1k*u1Y_QYqL)CKNWQX?E5JybaSM*O4jWeh0wDlbd?~2IKN1jF=e39C()oOt ztLry(S=+dlyXRoi(^R?P36SC^)y*a#bwvy}Z&w8(xR2(`wAXG+~-HRWeF| zi31G;Eq|y8u&{W3o|2x1XfSoZ^vQ#iq-3U+=4&Sf85@nX``0y(my=^d^c5baCh+Vf zKadS}9}GP;_0*_1mrseqM@)?oaFaX(3rlfnDP&Z;0AhfH>uRj*y8VGab?S7X(~`6$ju4ch86sphG$JK zPU*|N=3T)=*h%$T%SB7{Q8Z)Qktwh`@xyz-+$0jsF$1&y`Tql_Kv=)@nb%2eL_f1uJ{eDh;y73d3*h=94kVkDx7c#>UW?3n=rXXgg+h$s(L$Wh zEjBS&3bF(s9zM62+(#QMS4)3c((U^@{yL)izxnkqk%hnI;*{8t@s@*a6m`}6KS|Q!K-h8l^~GZGQ%^3X zB1|li6ZZ*b>A{0FF3o57ro}ln5xQw=d&YtGRa~ zyL)=Nd!dUBCDkEnu$s~92pk#VDi~&oJ~(Rq%G&uOdI}J^XwgChY0Dch0|i3ivDy=( zMwQ2au!lMEtOVpM5k7N}L z@Bent_@+B#o|FI5hoh4T zDIiTP-Q69=PAWpN7`YMFOPV`VjA-+2Gg<6)C+g-cSU~kbn#5n3`h*7-lw1}4aILCa zkSHsgm-otux&Z9CmtJ~Vh!X?mIiL0X%E@bOYXd^Tm_uqj>-?qEa03JFfrnh7lCJ7#w{5AENxaM2x{58|Nf{_5f^gW{^_kI>}G z6AKKA%DH)e7%5ZPy6vl)ni|$ul`lZL9>)6f3G?!D=U319_>+Gl2T8vlG#rP+!5OyD zU(sz+jL%}*M~}ML@#ixFxx_HOI6Luli(M$dI0GOYp}*d-W!9YeyrJ8^eBKL>UN!!+ zFKk_V`a3dV;*!!;S8z=9-ino-rcR76;Pz*by2j(_v}*Y5aM;mK1|J*5XqjkE(Y~|_ z3kGhul;!D?0NBK2&Xkwl^W(v%D5`}k=5-y zw7vDW(AIlPKNgQ1`Pu9B{`=qS8k?F}+m4;m$j33FR;xW84~Vq^t0XRE1hrqSwmccZ=1lR!H2w5Xv1xGa^E?bNiMFQ*IrkRRf=0cHd~_r6Nl&9sg+yG;eBr z3Wjh>#t#Z~^R7(IZfS1Wy?1X*OB;+QPT(<`+RT9iPJrpfIU+X2@12cH7C196(u&d*wqS=(}U7b5+c#jn*AABxnO{iCmzez=?g%z|lwzgX=2yyuR!2xkU{n~CVxhIy;`jN}(lcWe z!M_hJEJ@cVTrK@*r!8#zr2amHCrMLT>S@z5e>@^==c~MeA?lq^Pug9f@uT!zHlNKA zFeJ)5EMAFNKq99*E}1kx81#GGE?uHNUbOz~@rl@llf_={{)ZITK0JC0!IuFq=x`ob zUOW4!={<&bgRo<8f*CvY;A3}{3kCcXjm+%}CuyVsGHggn2!$eQxroa_BNjMz06LfIX z*{3~Z7oRU=qd1UGTbc4uwrYw(lzL6bb_P3|?K@8Ptf3ilTISF5Gy@VlwRU+LdOhK8 z@A*zwl3MEY24Qd{B7w_?GLH^@nocQuVoBLGqrb0-#xKtOfQkh8n2;9*SEb=|vZORk zH6d4hD=RNAKboHjQtnpA-gEY?z;4;Fd9qZuWL)ZF{0q2)*`0w`R~)%@e8%DWu8P8> z+B3c5%k)Q2TZXQ75VYT4JUVf>2;!^7Kd}1GA27aQ4KxZd5$C1H<>f&qIT61YS4nWS zR$OdQR)_=%?vP0(&ZL=$JJg{RXTriUyN}z0=L4iY6mbhM3ACI-=G#AVWS`Lp*olG-v zfDha`C3i+7VDGS}{!Dax1FRjLG-rC&^GflEPcph4f!YT1IitHcM|1FGmtdGFz&vtC zxnW3z`ZdP?0@l!I-C}eda0FWelmq9BB0LJ?ampXV^#X$$gU+y6e+hwHl$fiYm7|)j z6sKL~+fTRHELNY@;Xh||4TJx$l03fn8-V}sa0iTL_r^W#LX2SsE}`chtdffH|8V+a zCXme)*nX&^$L@Eyf;f&kWAW^Q!YuVSg8l)9Y%pwd2K8Dn9R>gS^Z#o1|8CNMlm46Z z-=zN=ab0W=!yPi)11+(y8cB{qWEfg(-@g4-W2&SQ$wjIRx=&y-g8~KDx7c^?Vp+GG2N9;LSDs=4E=G+%wK1E(35+;NwPnWkY{(kITBc{LG+ih-GP%76L@6Q4!$6&Q+YhzU;XBHQmIs}RuvT$2?T=G4R_}%Zwph%4<8pwwz+tImDct3VoZr>@VuoT8*9N!* z5xF!a2ih=V`dI@jlOw8X7)Yz4rO%pZU}4ZwCWz zE~F8P6-VwBDo_j;d@UxvZ|rDOsVfA0B9**7L6|8ZFbN@dkjr|l-MPuEzX0v!9Onpu zyil-ICX0~6&h-0#y9`qdeu()6i z8)!I8@)zD^=6~V!MK42XXRsX%_+zy-M~@vR2;##v>*2mgEZ(r`^POMs{^1XvU7WL_ zqpgD*Pq{qdYu_UsU5y2KW$}-K=WJ|yU{?0;23hHHB01gjq*y}GHjLKOg8nVc@SOBF zYkFS$?A+7&nz`&AL;ry?7jhvbr?oC$muafyvc$@4F>?f52mq zAZUB#v*6Z#g(q*#qfHCn!X!8kEO552Kq(FTd{~?h3%t7b!$U%aH2Fs}xNPcNtJ;>W z4b}H~wcvt`mlw4@w+2avzDJ45^noKCg$I`j_~^9Lv97M?lbZb1j{-SyM<{~AEl-`D z+n3>Q2)g1j((-A{zx0{{jP^(@2+AMDYT0dwL?-vJ& z%H-g~`4}!#F(S*%Rrq5SNt&dFv42oKJF)S$f8=gnD#CI5%eynokGY*l#1VD9t=kT2 zHZ1W4LZSOM;max_<5O^1f^Yo030v9UcF0gDRyd;H^F7O)4;|}Im3*}f z-K3DOqJPyXB2%TAP$*eYXd;foXh=7TMFL6KjoRe)yZK+XNvCC#4;KdiaoBmXIeAPG zrj&Gz`*)N<02g>|mP(bZ)d?F}5Fx!bRiRXZ2E%{9L8(Ib5w2j8lvTAV2#-(!*lpd5_9I~}QmVKNLhOCKNuNpTer#};d) z8=vU;>kh~3`?;Ipbg{0ySR^GRQZaNhpTL>Y)U^61JIns5du)RJ+$qIFm7WK)#V9C8 z=$*ON`R<|4A8wFTM9;!{JVDulLeOdxc=CuR7~6lP{bVpprkgVwdec(*6Zl)v6vKcO;5KqzaU>MW(!b3b3+r6mgsjn1Q;5b z2p#eG0u^PI(BEF4ui;cZ_p}~+kFmL9bk%5vrn|b#HfK*}UY@PZ9O98&#UL3H5lA!4H#z^6kjLYFqw}AAlL!Ci z{$HQ|yZvBYhsBMM3>cnHC9=7KoFC%Dcc7iNch>HHe95$94NWH-yTu}YAjD)EGH77e!PyohzaAC#Pedp#+8?$-$vFd4KLZqvu z!&-CF#Ic>RWvNYVy?4$YbF#7d*y$b)8~=NEPTqaw^!QOZVv#IF2KF31+uG?C5$FJq z4AW2CJr&qiW9#|-wPq-tlcwzI^#?;?0>^?ReP4BjR3iFx+ljkwn*hHas;fWU?BMg5 zG`)QGq^h-B4lS8Gp{ebBQ=5Ci^s4^x|N5|bQZYVvoOV{FdilEMJ8qFzPtZ&)SCM3R zqYl@e{o{KLJYL{0tIq5@eB|eU*{dL2dyjNiPf*Spqm>J&4LgjWdcW}J zqccWH7EIEPFO{7>buM{s!{IthcQ4YuUifqE^m6H(Z|VN_;TbR;Ki%5){GUGC zeXyx4Q#oM%L&v}VugdFN9Th?um@GLVVM z`s~!SOt+tYbJfoO{nrjICSM@nZ{FX1xV|^9pcJ&Qx7Kyv`+UuzQ%n>+sYaa)9s0s*%j=z4S2j^(Rs z;j`Y5E0ZNeXe=kMT%|%Aey{#;^m`jSR&Hwh{o8H2M14wX4n;-aSGh`*mMoe#RsYB@ z_p-s#Op-pwkY4iJXDTsF86=s8^WH_XinFqF2h4weDDvduoZyQ%-*4lSNZYi*tH!9W9l~wKjLS$rNcanY&!PKoIqSTqb<+ z-5Q36`Ga&Q;DebwZ-TzEqRQ>HFZ=yhNb^JJYWgr+xj~KOD9brUDcK_F6Zb{N-`8+*B0%0ASJ6jBCIjHZvR=z+^Qy!<& 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 literal 0 HcmV?d00001 diff --git a/src/main/webapp/images/bg-pattern.png b/src/main/webapp/images/bg-pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..d9ca94b4c39905ae9d7bace9c2ee0dfec54ac0ed GIT binary patch literal 945 zcmaJ=&yLbS9G+z3MmO2S=t(b5W-ppZ+bOiWZK#_r1($>p0wl|k(hktD?bLR#g_H5N zFX1EX!IKFGz4`kx zm<88iqGtwL>*{=;n?(fI5H>N;T~Ix{1uHZrP!Wm+SHc*os(?$1s^ZsBmar^J{8kIN zq${c}pTfTRpG@x@OD8Z#E@qL`+skQN0Rk3_6#TCO3>1&$~rvyeGiAxuuT z3KmJ+*pHY`LzpW%13F~};*s8^5JWrKFxixe7fj5YNW_Aar?dsy_Wz+lutO)TP446U zr*P7pMMP|qgid3ZH*R>6yNdKmOdLkzE~VGoDz?Uy(PT^`Sm~(n<&__LG)-Qu@wTnk z!-P4ZOX`+^xPsvOo?gP$qNLR{<;=nuS7r0UlqyQGQj=5(n?-rcwWvD{NXWKa@1AS! z<>sRhMBKAQV*fqyYB3GqI%VD8AIs@py$#pfAIsTZuE>KC^Tz(w=&gxQPrluaEkEoA zpM-qcV?NfOrA34P5{Ioux4K%bmdoX>{p%68Jgr-1H~Ts0dwqaPAMD5Q8vvicgPYOf P3;zu2)uwfO(f{}dAORta literal 0 HcmV?d00001 diff --git a/src/main/webapp/images/icons/GenericResource.png b/src/main/webapp/images/icons/GenericResource.png new file mode 100644 index 0000000000000000000000000000000000000000..c9348a21a92077805483a6e962a52d96f2c2593c GIT binary patch literal 622 zcmV-!0+IcRP)=3_2NMgdhXeCFM9Bz7pb0VPlcWe2{~y65zIwQn%WwS z4Z6GCZT2VYn=!R1siz(s_;~Z)&b;@{``!v+7{Ym0ADnZM`T0jcDFs3Z$g+GKSBHl$ zEvRa2hB?iqQP|!6zRtGocAFpYeV>DLXA6P=L{U_yrf#idvlF_eCF$Xz3$R4T|EW3GdU=*s=Z=4b7rkqM8 zW`>4RH&r!GkBcsxcI7c*Jb^S!-Beq*DQ-rCw;BKQtj(EO%Yi>~ zhagE2jJ5DvAB{#Y+#&t_k!jnuX{Ay-C68ekJ(A%$Zdo$ZG+R46Uq6twwaq7n@hf?j z#*S0J%&a77)$Vv0wp;uAKUgDQ2$FOi19H!0f58C%_2*?S)!nO)$$G5k45dFo_~(eN z4m^XhH^%oj=r-gV56+xKL<(^QaT_s;xQ4h0s}|&*>pa1m`>&XJ$7T&t>FnPkJ~0Mt zU?fDe1NI&f9?JJ%K$zxb8etKh+Aoh=!<6m77XJI+_*;Mh099|+L3mS9a{vGU07*qo IM6N<$g3Q?y@Bjb+ literal 0 HcmV?d00001 diff --git a/src/main/webapp/images/icons/collection2.png b/src/main/webapp/images/icons/collection2.png new file mode 100644 index 0000000000000000000000000000000000000000..9866da1d41341470382c692aa2a76b9ad82f7a63 GIT binary patch literal 854 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 literal 0 HcmV?d00001 diff --git a/src/main/webapp/images/icons/hostingNode.png b/src/main/webapp/images/icons/hostingNode.png new file mode 100644 index 0000000000000000000000000000000000000000..71059ba5232c48551d57b4ea79a2c7a44021a014 GIT binary patch literal 636 zcmV-?0)zdDP)o!O{p z5K>v_T9!x*poR#lBx;=>j(umFOC(na2j!7Y{)W@@y?ze?D=ROsyu5t9P-1*)Q8 zdOC^rX&XeL5Y8f(j*sixgpgk$!4S{$ctQ!s4lJvWZm$RGdgyk#@CGh8j*GB6obUVL z1d&Jtq9_tk5IjmKKXY*g^K7kr23d6yjooKKld2Dx1B8^`e-Q4-PX z_lCcOR;vYTFhHLrN~hDc;`3sAad9y$kYyS1c-&ExsHbTfrt~SKl1ZdeDM+#i8uy^8 zic{Jsd24HHVL^c7IIwL8XQqi}yERHMux$8U50ttH_^*KV08xk_rmC1q=+Jc?q9njm z{83Kb)fRBHW7Z&baTUvVZa%*eL*xlVV_CM^u*?Yfdl*?sfb92*JUw{2L8kP0G7ykiz W$pe4r^j7i!00008!PM!jse+otDvXRhleu>w{(hr=P& zTV2;rBMofZo=3rrs;YWAJqHeofOC+HNSe*6&}=qN@aeaKWm$(L&gF8enM?+{FRwu9 zoD1NBqmclHW{%@Tw}6Wqg+f989t^&~Me(EkfChX#56VZfjYtFPF_lU|uh;XF8H4TO zj!YM$blUKV1mw(6M2qNP2;H{su`-!X|7n%u=>+~>3AvaIiltqd9#DvgJ&1=10t0D6 z$;|KlP3c1Y-2fh17umvCJQ4=!_2+B&{P5)SL<2$#ZY7EM2$|!%^Ti9`3q;4qtws{i zDI^jJKbdhUAOoMo-`t-B@esjXtJQ*jzYmI{z|3qKZ(vLsG2zn?;Y5OJwYqN@My1o~ zTxy!Ox4y9nOZhb^2wGcN&dWOz93XwP&!N7PVQ7Y$>`>)rKL8*jG z-pCX}LIod5k_MzJk;wFrC~=9tEC^)5RG8u6>FG%U=@1OjAUX}EyThIw2Au;z;M7CL zvneGBoCtycR4zQ?l9Mn@!J*OAYBg2OprXn|8q8+1%^GyNJC1NyrO7do#$B#jHmx8) zRAQx6fk{z0XjT-(qp28|j5~c_f=uy2R<4?A6W%bIMx>y@RLES?G*Bq~f2d6M0jvSuUMS=Q%2k+1E=B?cTr#del}aTX$dBpi!-u_KI@1$|{TN3Ous_QA)QV5`QHs1K*X*k#FH>ClC%H7-49$G7|2gRCEqr>+%MW9V2OkC>k>k^@#K-z!P}Vd2w#WhnK2e(X z_&8wJrL2w+8#uCQWqjkGCW~2n>rPf(c67TbyMO@wJ`m7pdT2UhY_`!(*xKJrvo@+X zuQHmtTMwH$ORQ3b`r0@r1qZett$qFN#UV|D z+s}1(sU`J_zG4qutD_5{Qh$SJT3OgUsWB!xw^@n!y_qiF^?7$LH<2=4{}E>x8X7f0 znYU7R%<2fIfYxY>tM%e01yN9`jehN_SrlNjumj6ye{=e3yYHgsK^c`3_Xau#vwyX1 zF4&UG{%#YOSyfun*OMO0$k^woe;u#`3BUE1`pQou>HV!t&^p-nTFsiPj|{}`Nijr% z1DSY~c#OEE{{bQUSncraq_!V^3?+U3q_DPJ)VJJbXAoDLN#=Em>IYvwSfUN$eM#JM zRgM@Y!uI+2OwO~^uUV?CDBm@oRsPkD#yY2Fw;PSMC5HUYE@J_K{Jdj4rZmUlOhu`) zBz=2lbVt6c>tywl%r~!e#)44N(PKLc&+Rz@FrBl{0rUE4g&l-bES*lzg9c0{liDX` z7hsv2U2hWRr5w0^)}@1#%W-?Ya40Jzo)!L#LiPhB$<2A}RZ(92EV_WSuZ7x() z8^&C1+-ggoEh$;9>7VS{dqpTe$hl2fTDg^AGw~TA*d>-IIUG!Sy5sHLfuXKdLwQx2M+qkIB(ZS$+O9-{X@sZK7x6NTOAY9I!}Co5NIU);|vW3Nj9pd|qoF-kkY*DYwGJ^7Nx{4)yl3lW_6 Hjm!EMo>tu< literal 0 HcmV?d00001 diff --git a/src/main/webapp/images/icons/software.png b/src/main/webapp/images/icons/software.png new file mode 100644 index 0000000000000000000000000000000000000000..16fd0822187d44e77e969bbe6fe1e4d25c28e690 GIT binary patch literal 1876 zcmaJ?Yfuwc6kdresfLQNg<$Ql4NA3`WRnP(K#0ggDTydxi7i5wWPu3DhRq`J8K46U z+776-Xq}3!O0_D`X?@hzCM6)sXv1iA5TY1g*y;!lPt9Yyv10q9bZ2(>M1q=#7K>LL{*3qP%fIU(Mi|?KbhH( zMlE4yM#y2gJ{~R5EZ>Nu=^IyMs5Ta=L~6D)7K$;7DFH1?Adpd8q%(+(67~ySF}3z? z^VrY}2vI0u|7}VkUkSxyI0{8@VU7xpgrP`2moHot6&1A*62N?z2Mc(70f!$Y77D~L z4845VR5o0lCr(R9dYOxgBWzB=Twq1RM&%F>KHgh>@c+ zgia_VpavDL(Gwa>2YD5dT&#qUuqmg1m!Q?ZlGPbrwux#O&xq)Gd@k%QX#yyh|36f# zeT6mdCz%tZ*rKM#yL>gaRPbu>Q5`kyI5pO#8T3`uZMl$~5SL->$@P$= z)Y`KP=g908aV34yn@2%9lvGEjw`_iPagelZ0l_jL7pN&RKMi5n-{X4xrXT6K?v~;t zX^L>3C4nhZ1M99GOI7#3b`5wmruoHb#_y73{eF^cF8J{Dw(`{9N6d{Wz2vM~4;fT9 z?6S?z&l*)^BxXJs8?!M|nE5@J2vab$i z`HZAnVxPJ0#9I5LW>f3A#wW4b@>7KcG1H^pweE9f{*o2lk~7f$W2cj+}+;J6?Rn(Nj-BSmi_oiNwtv+1tuv$7VSuD18OV^y4TJrwQEAg^zVI?Uh_xQrM z)vcDUH`^?hwpNSsfW>lKVc#5}j+iCvXgK0rc3trBeHdm{|Avf@?kh)ze8H+{XC|zF z>US8{zt-(BkN!!LS5rM?=BeXAbx(f?Np4?|=;{w-6d?htx4FZbm_uZrnIvmt$4Rnd zfFw_6lVna>s7KnMZhY@*PMD@->jD&%G$b=jBp>cR->jV9xh_w6pSi*F^u`apG7LK{ z^^Di7jZ@rsICPJb!%}~e#bR|Q21#OiLw)hNOUizwO`EC^(RMRjUw^UCXDRI@8hqx= z4d@P3owKQR(A{=^Iqh@bhS;NPU-}Z*`X4oE|^tiXU*CyqyH=*+U{%|{+Imc`^srGaQ z+my%Xe0OIG2-eZ!;^;mdA$<7WZl3Si&$c^yd-KgrkL@QqF3by9*%97(^FrsZ))o`V z05!2-)uZNM7V}D&z~%Ay76?OW)1!l|_PxFga3_PYEJOg$tqkJ3oX%a2n+NN)GTHH; zXKdZ#yfk?CZaA3!Hdgg}yNSgpi~O+tfzb7AKME~ z60cmh2^ePfuWht72Xb;9pJlf#n0wh0{*^`f?fKT0p-7tbn_6@5>$*a8@tKpm9pQEU zOrc*`W_GbJ$bBan4Ak9tvmu+a->=qp)rr}{DKnd{xprQ`?d&UztO_PWc6`o~5Lnintegration tests must extend GWTTestCase. @@ -12,7 +11,7 @@ import com.google.gwt.junit.client.GWTTestCase; * See http://mojo.codehaus.org/gwt-maven-plugin/user-guide/testing.html * for details. */ -public class GwtTestResourceManagementPortlet extends GWTTestCase { +public class GwtTestResourceManagementPortlet { /** * Must refer to a valid module that sources this class.