[Feature #12255] Pop-up Text improvement for the locked records
updated at 1-3-3 git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/widgets/grsf-manage-widget@171457 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
450b37906e
commit
784882b390
|
@ -1,4 +1,8 @@
|
||||||
<ReleaseNotes>
|
<ReleaseNotes>
|
||||||
|
<Changeset component="org.gcube.portlets-widgets.grsf-manage-widget.1-3-3"
|
||||||
|
date="2018-09-14">
|
||||||
|
<Change>[Feature #12255] Pop-up Text improvement for the locked records</Change>
|
||||||
|
</Changeset>
|
||||||
<Changeset component="org.gcube.portlets-widgets.grsf-manage-widget.1-3-2"
|
<Changeset component="org.gcube.portlets-widgets.grsf-manage-widget.1-3-2"
|
||||||
date="2018-03-20">
|
date="2018-03-20">
|
||||||
<Change>[Task #11124] Testing the GRSF management panel</Change>
|
<Change>[Task #11124] Testing the GRSF management panel</Change>
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<groupId>org.gcube.portlets.widgets</groupId>
|
<groupId>org.gcube.portlets.widgets</groupId>
|
||||||
<artifactId>grsf-manage-widget</artifactId>
|
<artifactId>grsf-manage-widget</artifactId>
|
||||||
<version>1.3.2-SNAPSHOT</version>
|
<version>1.3.3-SNAPSHOT</version>
|
||||||
<name>gCube GRSF Manage widget</name>
|
<name>gCube GRSF Manage widget</name>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
|
|
|
@ -57,13 +57,13 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
* Since it needs the scope, we need to check if it is null or not
|
* Since it needs the scope, we need to check if it is null or not
|
||||||
* @param discoverScope if you want to the discover the utils library in this specified scope
|
* @param discoverScope if you want to the discover the utils library in this specified scope
|
||||||
* @return DataCatalogue object
|
* @return DataCatalogue object
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public DataCatalogue getCatalogue(String discoverScope) throws Exception{
|
public DataCatalogue getCatalogue(String discoverScope) throws Exception{
|
||||||
String currentScope = Utils.getCurrentContext(getThreadLocalRequest(), true);
|
String currentScope = Utils.getCurrentContext(getThreadLocalRequest(), true);
|
||||||
DataCatalogue instance = null;
|
DataCatalogue instance = null;
|
||||||
try{
|
try{
|
||||||
String scopeInWhichDiscover = (discoverScope != null && !discoverScope.isEmpty()) ? discoverScope : currentScope;
|
String scopeInWhichDiscover = discoverScope != null && !discoverScope.isEmpty() ? discoverScope : currentScope;
|
||||||
logger.debug("Discovering ckan utils library into scope " + scopeInWhichDiscover);
|
logger.debug("Discovering ckan utils library into scope " + scopeInWhichDiscover);
|
||||||
instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
|
instance = DataCatalogueFactory.getFactory().getUtilsPerScope(scopeInWhichDiscover);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
|
@ -98,7 +98,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-of-a-connected-bean",
|
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-of-a-connected-bean",
|
||||||
"semantic identifier of the record",
|
"semantic identifier of the record",
|
||||||
"Fishery"
|
"Fishery"
|
||||||
));
|
));
|
||||||
toReturn.setCurrentConnections(connectTo);
|
toReturn.setCurrentConnections(connectTo);
|
||||||
|
|
||||||
// these are the "suggested connections"
|
// these are the "suggested connections"
|
||||||
|
@ -129,55 +129,55 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
toReturn.setSources(sources);
|
toReturn.setSources(sources);
|
||||||
List<SimilarGRSFRecord> similarGrsfRecords = new ArrayList<SimilarGRSFRecord>();
|
List<SimilarGRSFRecord> similarGrsfRecords = new ArrayList<SimilarGRSFRecord>();
|
||||||
similarGrsfRecords.add(new SimilarGRSFRecord(
|
similarGrsfRecords.add(new SimilarGRSFRecord(
|
||||||
"uuid-similar-record-1",
|
"uuid-similar-record-1",
|
||||||
"description similar record",
|
"description similar record",
|
||||||
"short name similar record 1",
|
"short name similar record 1",
|
||||||
"title similar record 1",
|
"title similar record 1",
|
||||||
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-1",
|
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-1",
|
||||||
"semantic identifier record 1",
|
"semantic identifier record 1",
|
||||||
"Stock 1"
|
"Stock 1"
|
||||||
));
|
));
|
||||||
similarGrsfRecords.add(new SimilarGRSFRecord(
|
similarGrsfRecords.add(new SimilarGRSFRecord(
|
||||||
"uuid-similar-record-2",
|
"uuid-similar-record-2",
|
||||||
"description similar record",
|
"description similar record",
|
||||||
"short name similar record 2",
|
"short name similar record 2",
|
||||||
"title similar record 2",
|
"title similar record 2",
|
||||||
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-2",
|
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-2",
|
||||||
"semantic identifier record 2",
|
"semantic identifier record 2",
|
||||||
"Stock 2"
|
"Stock 2"
|
||||||
));
|
));
|
||||||
similarGrsfRecords.add(new SimilarGRSFRecord(
|
similarGrsfRecords.add(new SimilarGRSFRecord(
|
||||||
"uuid-similar-record-3",
|
"uuid-similar-record-3",
|
||||||
"description similar record",
|
"description similar record",
|
||||||
"short name similar record 3",
|
"short name similar record 3",
|
||||||
"title similar record 3",
|
"title similar record 3",
|
||||||
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-3",
|
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-3",
|
||||||
"semantic identifier record 3",
|
"semantic identifier record 3",
|
||||||
"Stock 3"
|
"Stock 3"
|
||||||
));
|
));
|
||||||
similarGrsfRecords.add(new SimilarGRSFRecord(
|
similarGrsfRecords.add(new SimilarGRSFRecord(
|
||||||
"uuid-similar-record-4",
|
"uuid-similar-record-4",
|
||||||
"description similar record",
|
"description similar record",
|
||||||
"short name similar record 4",
|
"short name similar record 4",
|
||||||
"title similar record 4",
|
"title similar record 4",
|
||||||
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-4",
|
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-4",
|
||||||
"semantic identifier record 4",
|
"semantic identifier record 4",
|
||||||
"Stock 4"
|
"Stock 4"
|
||||||
));
|
));
|
||||||
similarGrsfRecords.add(new SimilarGRSFRecord(
|
similarGrsfRecords.add(new SimilarGRSFRecord(
|
||||||
"uuid-similar-record-5",
|
"uuid-similar-record-5",
|
||||||
"description similar record",
|
"description similar record",
|
||||||
"short name similar record 5",
|
"short name similar record 5",
|
||||||
"title similar record 5",
|
"title similar record 5",
|
||||||
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-5",
|
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-5",
|
||||||
"semantic identifier record 5",
|
"semantic identifier record 5",
|
||||||
"Stock 5"
|
"Stock 5"
|
||||||
));
|
));
|
||||||
similarGrsfRecords.add(new SimilarGRSFRecord(
|
similarGrsfRecords.add(new SimilarGRSFRecord(
|
||||||
"uuid-similar-record-6",
|
"uuid-similar-record-6",
|
||||||
"description similar record",
|
"description similar record",
|
||||||
"short name similar record 6",
|
"short name similar record 6",
|
||||||
"title similar record 6",
|
"title similar record 6",
|
||||||
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-6",
|
"http://data.d4science.org/ctlg/GRSF_Admin/uuid-similar-record-6",
|
||||||
"semantic identifier record 6",
|
"semantic identifier record 6",
|
||||||
"Stock 6"
|
"Stock 6"
|
||||||
|
@ -204,13 +204,13 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
|
|
||||||
String systemType = extrasAsMap.get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
|
String systemType = extrasAsMap.get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
|
||||||
if(systemType == null || systemType.isEmpty() || systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
|
if(systemType == null || systemType.isEmpty() || systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
|
||||||
throw new NoGRSFRecordException("This is not a GRSF Record");
|
throw new NoGRSFRecordException("This is not a GRSF Record");
|
||||||
|
|
||||||
boolean isStock = record.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY).contains(Product_Type.STOCK.getOrigName());
|
boolean isStock = record.getExtrasAsHashMap().get(Constants.DOMAIN_CUSTOM_KEY).contains(Product_Type.STOCK.getOrigName());
|
||||||
|
|
||||||
// fetch map for namespaces
|
// fetch map for namespaces
|
||||||
Map<String, String> fieldsNamespacesMap =
|
Map<String, String> fieldsNamespacesMap =
|
||||||
Utils.getFieldToFieldNameSpaceMapping(httpSession, isStock ?
|
Utils.getFieldToFieldNameSpaceMapping(httpSession, isStock ?
|
||||||
Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK : Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_FISHERY);
|
Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_STOCK : Constants.GENERIC_RESOURCE_NAME_MAP_KEY_NAMESPACES_FISHERY);
|
||||||
|
|
||||||
// get extras as pairs
|
// get extras as pairs
|
||||||
|
@ -219,10 +219,10 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
String catalogueIdentifier = record.getId();
|
String catalogueIdentifier = record.getId();
|
||||||
String description = record.getNotes();
|
String description = record.getNotes();
|
||||||
Status status = Status.fromString(extrasWithoutNamespaces.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY).get(0));
|
Status status = Status.fromString(extrasWithoutNamespaces.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY).get(0));
|
||||||
|
|
||||||
if(status.equals(Status.To_be_Merged) && !requestForRevertingMerge)
|
if(status.equals(Status.To_be_Merged) && !requestForRevertingMerge)
|
||||||
throw new Exception("Records under merging activities cannot be managed without explicit authorisation!");
|
throw new Exception("The record is locked due to a merge request in progress!");
|
||||||
|
|
||||||
String uuidKB = extrasWithoutNamespaces.get(Constants.UUID_KB_CUSTOM_KEY).get(0);
|
String uuidKB = extrasWithoutNamespaces.get(Constants.UUID_KB_CUSTOM_KEY).get(0);
|
||||||
String grsfDomain = extrasWithoutNamespaces.get(Constants.DOMAIN_CUSTOM_KEY).get(0);
|
String grsfDomain = extrasWithoutNamespaces.get(Constants.DOMAIN_CUSTOM_KEY).get(0);
|
||||||
String semanticId = extrasWithoutNamespaces.get(Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY).get(0);
|
String semanticId = extrasWithoutNamespaces.get(Constants.GRSF_SEMANTIC_IDENTIFIER_CUSTOM_KEY).get(0);
|
||||||
|
@ -259,7 +259,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
logger.debug("SimilarGRSFRecords are " + similarRecords);
|
logger.debug("SimilarGRSFRecords are " + similarRecords);
|
||||||
|
|
||||||
// get connected records (and the proposed ones)
|
// get connected records (and the proposed ones)
|
||||||
List<String> connectedBeanUrls =
|
List<String> connectedBeanUrls =
|
||||||
extrasWithoutNamespaces.containsKey(Constants.CONNECTED_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.CONNECTED_CUSTOM_KEY): null;
|
extrasWithoutNamespaces.containsKey(Constants.CONNECTED_CUSTOM_KEY) ? extrasWithoutNamespaces.get(Constants.CONNECTED_CUSTOM_KEY): null;
|
||||||
|
|
||||||
List<ConnectedBean> connectedBeans = new ArrayList<ConnectedBean>(0);
|
List<ConnectedBean> connectedBeans = new ArrayList<ConnectedBean>(0);
|
||||||
|
@ -277,11 +277,11 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
|
|
||||||
// get the connections the knowledge base suggests
|
// get the connections the knowledge base suggests
|
||||||
List<ConnectedBean> suggestedConnectionsByKnowledgeBase = new ArrayList<ConnectedBean>(0);
|
List<ConnectedBean> suggestedConnectionsByKnowledgeBase = new ArrayList<ConnectedBean>(0);
|
||||||
List<String> exploitedResourcesUrls = isStock ?
|
List<String> exploitedResourcesUrls = isStock ?
|
||||||
(extrasWithoutNamespaces.containsKey(Constants.EXPLOITING_FISHERY_CUSTOM_KEY) ?
|
extrasWithoutNamespaces.containsKey(Constants.EXPLOITING_FISHERY_CUSTOM_KEY) ?
|
||||||
extrasWithoutNamespaces.get(Constants.EXPLOITING_FISHERY_CUSTOM_KEY) : null):
|
extrasWithoutNamespaces.get(Constants.EXPLOITING_FISHERY_CUSTOM_KEY) : null:
|
||||||
(extrasWithoutNamespaces.containsKey(Constants.RESOURCES_EXPLOITED_CUSTOM_KEY) ?
|
extrasWithoutNamespaces.containsKey(Constants.RESOURCES_EXPLOITED_CUSTOM_KEY) ?
|
||||||
extrasWithoutNamespaces.get(Constants.RESOURCES_EXPLOITED_CUSTOM_KEY) : null);
|
extrasWithoutNamespaces.get(Constants.RESOURCES_EXPLOITED_CUSTOM_KEY) : null;
|
||||||
|
|
||||||
if(exploitedResourcesUrls != null && !exploitedResourcesUrls.isEmpty()){
|
if(exploitedResourcesUrls != null && !exploitedResourcesUrls.isEmpty()){
|
||||||
for (String exploited : exploitedResourcesUrls) {
|
for (String exploited : exploitedResourcesUrls) {
|
||||||
|
@ -303,9 +303,9 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
|
|
||||||
// set the values
|
// set the values
|
||||||
toReturn = new ManageProductBean(
|
toReturn = new ManageProductBean(
|
||||||
semanticId, catalogueIdentifier, uuidKB, grsfType,
|
semanticId, catalogueIdentifier, uuidKB, grsfType,
|
||||||
grsfDomain, shortName, description, grsfName,traceabilityFlag, sdgFlag,
|
grsfDomain, shortName, description, grsfName,traceabilityFlag, sdgFlag,
|
||||||
status, recordUrl, sources, similarRecords,
|
status, recordUrl, sources, similarRecords,
|
||||||
connectedBeans, suggestedConnectionsByKnowledgeBase);
|
connectedBeans, suggestedConnectionsByKnowledgeBase);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
String sessionProductKey = ScopeProvider.instance.get() + bean.getCatalogueIdentifier();
|
String sessionProductKey = ScopeProvider.instance.get() + bean.getCatalogueIdentifier();
|
||||||
threadRequest.getSession().removeAttribute(sessionProductKey);
|
threadRequest.getSession().removeAttribute(sessionProductKey);
|
||||||
|
|
||||||
Utils.updateRecord(baseUrl, bean, catalogue, username, administratorFullName, threadRequest,
|
Utils.updateRecord(baseUrl, bean, catalogue, username, administratorFullName, threadRequest,
|
||||||
PortalContext.getConfiguration().getCurrentGroupId(threadRequest), context, token);
|
PortalContext.getConfiguration().getCurrentGroupId(threadRequest), context, token);
|
||||||
|
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
|
@ -400,7 +400,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
String uuid = UUID.randomUUID().toString();
|
String uuid = UUID.randomUUID().toString();
|
||||||
String adminInUrl = "costantino.perciante";
|
String adminInUrl = "costantino.perciante";
|
||||||
String adminInUrlFullName = "Costantino Perciante";
|
String adminInUrlFullName = "Costantino Perciante";
|
||||||
long timestamp = System.currentTimeMillis() - 1000 * ((long)(Math.random() * 10 * 60 * 60));
|
long timestamp = System.currentTimeMillis() - 1000 * (long)(Math.random() * 10 * 60 * 60);
|
||||||
return new RevertableOperationInfo(
|
return new RevertableOperationInfo(
|
||||||
baseUrl, fullName, usernameCurrent, uuid, adminInUrlFullName, adminInUrl, timestamp, RevertableOperations.MERGE);
|
baseUrl, fullName, usernameCurrent, uuid, adminInUrlFullName, adminInUrl, timestamp, RevertableOperations.MERGE);
|
||||||
}
|
}
|
||||||
|
@ -440,21 +440,21 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
Map<String, String> extras = dataset.getExtrasAsHashMap();
|
Map<String, String> extras = dataset.getExtrasAsHashMap();
|
||||||
String recordUrl = extras.get(Constants.ITEM_URL_FIELD);
|
String recordUrl = extras.get(Constants.ITEM_URL_FIELD);
|
||||||
String currentStatus = extras.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY);
|
String currentStatus = extras.get(Constants.STATUS_OF_THE_GRSF_RECORD_CUSTOM_KEY);
|
||||||
|
|
||||||
// check current record status
|
// check current record status
|
||||||
if(!currentStatus.equals(Status.To_be_Merged.getOrigName()))
|
if(!currentStatus.equals(Status.To_be_Merged.getOrigName()))
|
||||||
throw new Exception("Record '" + dataset.getTitle() + "' (" + recordUrl + ") is no longer involved in a merge operation!");
|
throw new Exception("Record '" + dataset.getTitle() + "' (" + recordUrl + ") is no longer involved in a merge operation!");
|
||||||
|
|
||||||
// check if it is a reviewer, than he can do what he wants (no matter the admin)
|
// check if it is a reviewer, than he can do what he wants (no matter the admin)
|
||||||
if(isReviewer){
|
if(isReviewer){
|
||||||
return new RevertableOperationInfo(recordUrl,
|
return new RevertableOperationInfo(recordUrl,
|
||||||
fullName, username, uuid, fullNameadminInUrl, userNameadminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation());
|
fullName, username, uuid, fullNameadminInUrl, userNameadminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation());
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
if(!username.equals(userNameadminInUrl))
|
if(!username.equals(userNameadminInUrl))
|
||||||
throw new Exception("You are not the editor allowed to perform this operation!");
|
throw new Exception("You are not the editor allowed to perform this operation!");
|
||||||
else
|
else
|
||||||
return new RevertableOperationInfo(recordUrl,
|
return new RevertableOperationInfo(recordUrl,
|
||||||
fullName, username, uuid, fullNameadminInUrl, userNameadminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation());
|
fullName, username, uuid, fullNameadminInUrl, userNameadminInUrl, decryptedUrl.getTimestamp(), decryptedUrl.getOperation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
if(baseUrl == null || baseUrl.isEmpty())
|
if(baseUrl == null || baseUrl.isEmpty())
|
||||||
throw new Exception("Unable to discover grsf-updater service!");
|
throw new Exception("Unable to discover grsf-updater service!");
|
||||||
|
|
||||||
Utils.revertOperation(httpClient, baseUrl, threadRequest, rInfo, token, context,
|
Utils.revertOperation(httpClient, baseUrl, threadRequest, rInfo, token, context,
|
||||||
PortalContext.getConfiguration().getCurrentGroupId(threadRequest));
|
PortalContext.getConfiguration().getCurrentGroupId(threadRequest));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -578,18 +578,18 @@ public class GRSFNotificationService extends RemoteServiceServlet implements GRS
|
||||||
|
|
||||||
if(dataset == null)
|
if(dataset == null)
|
||||||
throw new Exception("A record with id " + id + " doesn't exist");
|
throw new Exception("A record with id " + id + " doesn't exist");
|
||||||
|
|
||||||
Map<String, String> extras = dataset.getExtrasAsHashMap();
|
Map<String, String> extras = dataset.getExtrasAsHashMap();
|
||||||
String systemType = extras.get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
|
String systemType = extras.get(Constants.SYSTEM_TYPE_CUSTOM_KEY);
|
||||||
String domain = extras.get(Constants.DOMAIN_CUSTOM_KEY);
|
String domain = extras.get(Constants.DOMAIN_CUSTOM_KEY);
|
||||||
String url = extras.get(Constants.ITEM_URL_FIELD);
|
String url = extras.get(Constants.ITEM_URL_FIELD);
|
||||||
|
|
||||||
if(systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
|
if(systemType.equals(Constants.SYSTEM_TYPE_FOR_SOURCES_VALUE))
|
||||||
throw new Exception("This record is not a GRSF record!");
|
throw new Exception("This record is not a GRSF record!");
|
||||||
|
|
||||||
if(!acceptedDomain.equalsIgnoreCase(domain))
|
if(!acceptedDomain.equalsIgnoreCase(domain))
|
||||||
throw new Exception("You are suggesting a " + domain + " record instead of a " + acceptedDomain + " record!");
|
throw new Exception("You are suggesting a " + domain + " record instead of a " + acceptedDomain + " record!");
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue