You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by an...@apache.org on 2015/12/24 17:32:01 UTC
syncope git commit: [SYNCOPE-719] improved error and exception
managament: sent correct error-messages to enduser
Repository: syncope
Updated Branches:
refs/heads/master f65636e05 -> 33fd83021
[SYNCOPE-719] improved error and exception managament: sent correct error-messages to enduser
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/33fd8302
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/33fd8302
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/33fd8302
Branch: refs/heads/master
Commit: 33fd83021e7aa0ba835c03c39d41c66b812b7c55
Parents: f65636e
Author: Andrea Patricelli <an...@tirasa.net>
Authored: Thu Dec 24 17:29:36 2015 +0100
Committer: Andrea Patricelli <an...@tirasa.net>
Committed: Thu Dec 24 17:29:36 2015 +0100
----------------------------------------------------------------------
.../client/enduser/resources/InfoResource.java | 10 ++--
.../client/enduser/resources/LoginResource.java | 44 +++++++++--------
.../enduser/resources/SchemaResource.java | 26 +++-------
.../resources/SecurityQuestionResource.java | 11 +++--
.../resources/UserSelfCreateResource.java | 50 ++++++++++----------
.../enduser/resources/UserSelfReadResource.java | 31 ++++++++----
.../resources/UserSelfUpdateResource.java | 26 +++++-----
.../app/js/controllers/LoginController.js | 8 +++-
.../app/js/controllers/UserController.js | 40 ++++++++++++----
9 files changed, 140 insertions(+), 106 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
index 46c3aeb..530112b 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/InfoResource.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.enduser.resources;
import java.io.IOException;
+import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.client.enduser.adapters.SyncopeTOAdapter;
import org.apache.syncope.core.misc.serialization.POJOHelper;
@@ -42,7 +43,6 @@ public class InfoResource extends AbstractBaseResource {
protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
ResourceResponse response = new ResourceResponse();
- int responseStatus = 200;
try {
response.setWriteCallback(new WriteCallback() {
@@ -53,12 +53,16 @@ public class InfoResource extends AbstractBaseResource {
SyncopeEnduserSession.get().getSyncopeTO())));
}
});
+ response.setStatusCode(Response.Status.OK.getStatusCode());
} catch (Exception e) {
LOG.error("Error retrieving syncope info", e);
- responseStatus = 500;
+ response.setError(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), new StringBuilder()
+ .append("ErrorMessage{{ ")
+ .append(e.getMessage())
+ .append(" }}")
+ .toString());
}
- response.setStatusCode(responseStatus);
return response;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
index 8c03e50..e481d2c 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.enduser.resources;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.enduser.model.Credentials;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
@@ -40,8 +41,6 @@ public class LoginResource extends AbstractBaseResource {
@Override
protected ResourceResponse newResourceResponse(final Attributes attributes) {
- int responseStatus;
- final String responseMessage;
ResourceResponse response = new ResourceResponse();
try {
@@ -54,30 +53,33 @@ public class LoginResource extends AbstractBaseResource {
LOG.debug("Enduser login, user: {}", username);
if (StringUtils.isBlank(username)) {
- responseMessage = "Could not read credentials from request: username is blank!";
- LOG.error(responseMessage);
- responseStatus = 400;
- } else {
- // authenticate user
- final boolean authenticated = SyncopeEnduserSession.get().authenticate(username, password);
- responseStatus = authenticated ? 200 : 401;
- responseMessage = username;
- }
+ LOG.error("Could not read credentials from request: username is blank!");
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(),
+ "ErrorMessage{{ Could not read credentials from request: username is blank! }}");
+ } else // authenticate user
+ if (SyncopeEnduserSession.get().authenticate(username, password)) {
+ // user has been authenticated successfully
+ response.setWriteCallback(new WriteCallback() {
- response.setWriteCallback(new WriteCallback() {
-
- @Override
- public void writeData(final Attributes attributes) throws IOException {
- attributes.getResponse().write(responseMessage);
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(username);
+ }
+ });
+ response.setStatusCode(Response.Status.OK.getStatusCode());
+ } else {
+ // not authenticated
+ response.setError(Response.Status.UNAUTHORIZED.getStatusCode(),
+ "ErrorMessage{{ Username or password are incorrect }}");
}
- });
-
} catch (Exception e) {
- responseStatus = 400;
LOG.error("Could not read credentials from request", e);
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
+ .append("ErrorMessage{{ ")
+ .append(e.getMessage())
+ .append(" }}")
+ .toString());
}
-
- response.setStatusCode(responseStatus);
return response;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
index db6a7e4..b909767 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
@@ -19,11 +19,10 @@
package org.apache.syncope.client.enduser.resources;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.List;
+import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.client.enduser.model.SchemaResponse;
-import org.apache.syncope.common.lib.to.AbstractSchemaTO;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.lib.to.DerSchemaTO;
import org.apache.syncope.common.lib.to.PlainSchemaTO;
@@ -61,8 +60,6 @@ public class SchemaResource extends AbstractBaseResource {
AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
- int responseStatus = 200;
-
try {
final AnyTypeTO anyTypeUserTO = anyTypeService.read(AnyTypeKind.USER.name());
@@ -86,25 +83,16 @@ public class SchemaResource extends AbstractBaseResource {
virSchemas(virSchemas)));
}
});
+ response.setStatusCode(Response.Status.OK.getStatusCode());
} catch (Exception e) {
LOG.error("Error retrieving {} any type kind related schemas", AnyTypeKind.USER.name(), e);
- responseStatus = 400;
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
+ .append("ErrorMessage{{ ")
+ .append(e.getMessage())
+ .append(" }}")
+ .toString());
}
-
- response.setStatusCode(responseStatus);
return response;
}
- private <T extends AbstractSchemaTO> List<T> getSchemaTOs(final List<String> schemaNames,
- final SchemaType schemaType, final Class<T> type) {
-
- List<T> schemaTOs = new ArrayList<>();
-
- for (String schemaName : schemaNames) {
- schemaTOs.add(type.cast(schemaService.read(schemaType, schemaName)));
- }
-
- return schemaTOs;
- }
-
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
index 60ab318..4a03601 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.enduser.resources;
import java.io.IOException;
import java.util.List;
+import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.common.lib.to.SecurityQuestionTO;
import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
@@ -48,8 +49,6 @@ public class SecurityQuestionResource extends AbstractBaseResource {
AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
- int responseStatus = 200;
-
try {
final List<SecurityQuestionTO> securityQuestionTOs = securityQuestionService.list();
@@ -62,12 +61,16 @@ public class SecurityQuestionResource extends AbstractBaseResource {
}
});
+ response.setStatusCode(Response.Status.OK.getStatusCode());
} catch (Exception e) {
LOG.error("Error retrieving security questions", e);
- responseStatus = 400;
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
+ .append("ErrorMessage{{ ")
+ .append(e.getMessage())
+ .append(" }}")
+ .toString());
}
- response.setStatusCode(responseStatus);
return response;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
index 02297fb..b065a86 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.enduser.resources;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.client.enduser.adapters.UserTOAdapter;
import org.apache.syncope.client.enduser.model.UserTORequest;
@@ -47,7 +48,6 @@ public class UserSelfCreateResource extends AbstractBaseResource {
@Override
protected ResourceResponse newResourceResponse(final Attributes attributes) {
- int responseStatus = 200;
final StringBuilder responseMessage = new StringBuilder();
ResourceResponse response = new ResourceResponse();
@@ -61,35 +61,33 @@ public class UserSelfCreateResource extends AbstractBaseResource {
LOG.debug("Received user self registration request for user: [{}]", userTORequest.getUsername());
LOG.trace("Received user self registration request is: [{}]", userTORequest);
// adapt request and create user
- userSelfService.create(userTOAdapter.fromUserTORequest(userTORequest, null), true);
- responseMessage.append("User").append(userTORequest.getUsername()).append("created successfully");
+ final Response res = userSelfService.create(userTOAdapter.fromUserTORequest(userTORequest, null), true);
+
+ response.setWriteCallback(new WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(res.getStatusInfo().getFamily().equals(
+ Response.Status.Family.SUCCESSFUL)
+ ? responseMessage.append("User: ").append(userTORequest.getUsername()).append(
+ " successfully created")
+ : new StringBuilder().append("ErrorMessage{{ ").
+ append(res.getStatusInfo().getReasonPhrase()).append(" }}"));
+ }
+ });
+ response.setStatusCode(res.getStatus());
} else {
- responseMessage.append(userTORequest == null
+ response.setError(Response.Status.FORBIDDEN.getStatusCode(), new StringBuilder().
+ append("ErrorMessage{{").append(userTORequest == null
? "Request received is not valid"
- : "Self registration not allowed");
- responseStatus = 403;
+ : "Self registration not allowed").append("}}").toString());
}
- response.setWriteCallback(new WriteCallback() {
-
- @Override
- public void writeData(final Attributes attributes) throws IOException {
- attributes.getResponse().write(responseMessage);
- }
- });
-
- } catch (final Exception e) {
- LOG.error("Could not read userTO from request", e);
- responseStatus = 400;
- response.setWriteCallback(new WriteCallback() {
-
- @Override
- public void writeData(final Attributes attributes) throws IOException {
- attributes.getResponse().write(e.getMessage());
- }
- });
- }
- response.setStatusCode(responseStatus);
+ } catch (Exception e) {
+ LOG.error("Could not create userTO", e);
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder().append("ErrorMessage{{ ")
+ .append(e.getMessage()).append(" }}").toString());
+ }
return response;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
index 824aa76..c1d465f 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.enduser.resources;
import java.io.IOException;
+import javax.ws.rs.core.Response;
import org.apache.syncope.client.enduser.SyncopeEnduserSession;
import org.apache.syncope.client.enduser.adapters.UserTOAdapter;
import org.apache.syncope.core.misc.serialization.POJOHelper;
@@ -45,19 +46,29 @@ public class UserSelfReadResource extends AbstractResource {
protected ResourceResponse newResourceResponse(final Attributes attributes) {
LOG.debug("Requested user self information");
-
- ResourceResponse response = new ResourceResponse();
- final String selfTOJson = POJOHelper.serialize(userTOAdapter.toUserTORequest(SyncopeEnduserSession.get().
- getSelfTO()));
- response.setWriteCallback(new WriteCallback() {
+ AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse();
+ try {
- @Override
- public void writeData(final Attributes attributes) throws IOException {
- attributes.getResponse().write(selfTOJson);
- }
- });
+ final String selfTOJson = POJOHelper.serialize(userTOAdapter.toUserTORequest(SyncopeEnduserSession.get().
+ getSelfTO()));
+ response.setWriteCallback(new WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(selfTOJson);
+ }
+ });
+ response.setStatusCode(Response.Status.OK.getStatusCode());
+ } catch (Exception e) {
+ LOG.error("Error retrieving selfTO user", e);
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
+ .append("ErrorMessage{{ ")
+ .append(e.getMessage())
+ .append(" }}")
+ .toString());
+ }
return response;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
index 4e2d90a..2737bdb 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java
@@ -49,8 +49,6 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
@Override
protected ResourceResponse newResourceResponse(final Attributes attributes) {
- int responseStatus;
- final String responseMessage;
ResourceResponse response = new ResourceResponse();
try {
@@ -68,9 +66,12 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
// update user
Response res = userSelfService.update(userTO);
- responseStatus = res.getStatus();
- responseMessage = "User updated successfully";
+ final String responseMessage = res.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)
+ ? new StringBuilder().append("User").append(userTO.getUsername()).append(
+ " successfully updated").toString()
+ : new StringBuilder().append("ErrorMessage{{ ").
+ append(res.getStatusInfo().getReasonPhrase()).append(" }}").toString();
response.setWriteCallback(new WriteCallback() {
@@ -80,19 +81,16 @@ public class UserSelfUpdateResource extends AbstractBaseResource {
}
});
+ response.setStatusCode(res.getStatus());
+
} catch (final Exception e) {
LOG.error("Error while updating user", e);
- responseStatus = 400;
- response.setWriteCallback(new WriteCallback() {
-
- @Override
- public void writeData(final Attributes attributes) throws IOException {
- attributes.getResponse().write(e.getMessage());
- }
- });
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
+ .append("ErrorMessage{{ ")
+ .append(e.getMessage())
+ .append(" }}")
+ .toString());
}
-
- response.setStatusCode(responseStatus);
return response;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
index 9256668..8c00fc8 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/LoginController.js
@@ -44,7 +44,13 @@ angular.module("login").controller("LoginController", ['$scope', '$rootScope', '
$location.path("/self/update");
}, function (response) {
console.log("LOGIN FAILED: ", response);
- $scope.credentials.errorMessage = "Login failed: " + response;
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ }
+ $scope.credentials.errorMessage = "Login failed: " + errorMessage;
growl.error($scope.credentials.errorMessage, {referenceId: 1});
});
};
http://git-wip-us.apache.org/repos/asf/syncope/blob/33fd8302/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
index 2cd3f77..5f8953b 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
@@ -19,9 +19,9 @@
'use strict';
-angular.module("self").controller("UserController", ['$scope', '$rootScope', '$location', 'AuthService',
+angular.module("self").controller("UserController", ['$scope', '$rootScope', '$location', '$compile', 'AuthService',
'UserSelfService', 'SchemaService', 'RealmService', 'SecurityQuestionService', 'growl', function ($scope, $rootScope,
- $location, AuthService, UserSelfService, SchemaService, RealmService, SecurityQuestionService, growl) {
+ $location, $compile, AuthService, UserSelfService, SchemaService, RealmService, SecurityQuestionService, growl) {
$scope.user = {};
$scope.confirmPassword = {
@@ -108,8 +108,14 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
}
}
- }, function () {
- console.log("Error retrieving user schemas");
+ }, function (response) {
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ }
+ console.log("Error retrieving user schemas: ", errorMessage);
});
console.log("USER WITH ATTRTO: ", $scope.user);
@@ -118,8 +124,14 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
var initSecurityQuestions = function () {
SecurityQuestionService.getAvailableSecurityQuestions().then(function (response) {
$scope.availableSecurityQuestions = response;
- }, function () {
- console.log("Error");
+ }, function (response) {
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ }
+ console.log("Error retrieving avaliable security questions: ", errorMessage);
});
};
@@ -185,7 +197,13 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
$location.path('/self');
}, function (response) {
console.log("Error during user creation: ", response);
- growl.error("Error: " + response, {referenceId: 2});
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ }
+ growl.error("Error: " + (errorMessage || response), {referenceId: 2});
});
} else {
@@ -201,7 +219,13 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
});
}, function (response) {
console.log("Error during user update: ", response);
- growl.error("Error: " + response, {referenceId: 2});
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ }
+ growl.error("Error: " + (errorMessage || response), {referenceId: 2});
});
}
};