From 9a5e57618e41dd54b2b76a62187f2ecad84dba77 Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Thu, 23 Aug 2018 19:22:55 +0200 Subject: [PATCH 01/44] Improve test generation from CEG in the following way: Given two nodes in the form myvar=A, myvar=B, no test is generated with myvar=A and myvar=B --- bundles/specmate-integration-test/bnd.bnd | 3 +- .../specmate/test/integration/CrudTest.java | 61 +++++++++++++++++++ .../test/integration/EmfRestTest.java | 14 +++-- .../typescript/GenerateAngular.java | 10 ++- .../specmate-std-env/dev-specmate-all.bndrun | 5 +- .../specmate-std-env/prod-specmate-all.bndrun | 3 +- .../prod-specmate-no-cdo-server.bndrun | 3 +- bundles/specmate-testspecification/bnd.bnd | 3 +- .../services/CEGTestCaseGenerator.java | 60 +++++++++++++----- 9 files changed, 134 insertions(+), 28 deletions(-) diff --git a/bundles/specmate-integration-test/bnd.bnd b/bundles/specmate-integration-test/bnd.bnd index c9e88f2eb..0e58f593b 100644 --- a/bundles/specmate-integration-test/bnd.bnd +++ b/bundles/specmate-integration-test/bnd.bnd @@ -236,7 +236,8 @@ Bundle-Version: 0.0.0.${tstamp} specmate-cdo-server;version=snapshot,\ org.apache.commons.lang3;version='[3.3.2,3.3.3)',\ org.eclipse.emf.cdo.server.db;version='[4.4.0,4.4.1)',\ - specmate-rest;version=snapshot + specmate-rest;version=snapshot,\ + org.apache.commons.collections4;version='[4.0.0,4.0.1)' -runproperties: \ jetty.http.port=8088,\ diff --git a/bundles/specmate-integration-test/src/com/specmate/test/integration/CrudTest.java b/bundles/specmate-integration-test/src/com/specmate/test/integration/CrudTest.java index 7dff5fc90..9c7556f3b 100644 --- a/bundles/specmate-integration-test/src/com/specmate/test/integration/CrudTest.java +++ b/bundles/specmate-integration-test/src/com/specmate/test/integration/CrudTest.java @@ -436,6 +436,67 @@ public void testGenerateTests() { // Expect 4 children: two test cases and two test parameters Assert.assertEquals(4, retrievedTestChilds.length()); } + + @Test + public void testGenerateTestsWithMutExConstraint() { + JSONObject requirement = postRequirementToRoot(); + String requirementId = getId(requirement); + + // Post ceg model + JSONObject cegModel = postCEG(requirementId); + String cegId = getId(cegModel); + + // post node 1 + JSONObject cegNode1 = createTestCegNode("myvar","=A", "OR"); + cegNode1 = postObject(cegNode1, requirementId, cegId); + String cegNode1Id = getId(cegNode1); + JSONObject retrievedCegNode1 = getObject(requirementId, cegId, cegNode1Id); + + // post node 2 + JSONObject cegNode2 = createTestCegNode("myvar","=B","OR"); + cegNode2=postObject(cegNode2,requirementId, cegId); + String cegNode2Id = getId(cegNode2); + JSONObject retrievedCegNode2 = getObject(requirementId, cegId, cegNode2Id); + + // post node 3 + JSONObject cegNode3 = createTestCegNode("result","true","AND"); + cegNode3=postObject(cegNode3,requirementId, cegId); + String cegNode3Id = getId(cegNode3); + JSONObject retrievedCegNode3 = getObject(requirementId, cegId, cegNode3Id); + + // post connection + postCEGConnection(retrievedCegNode1, retrievedCegNode3, false, requirementId, cegId); + postCEGConnection(retrievedCegNode2, retrievedCegNode3, false, requirementId, cegId); + + // Post test specification + JSONObject testSpec = postTestSpecification(requirementId, cegId); + String testSpecId = getId(testSpec); + + // Generate test cases + String generateUrl = buildUrl("generateTests", requirementId, cegId, testSpecId); + logService.log(LogService.LOG_DEBUG, "Request test genreation at url " + generateUrl); + RestResult result = restClient.post(generateUrl, null); + Assert.assertEquals(Status.NO_CONTENT.getStatusCode(), result.getResponse().getStatus()); + + String retrieveUrl = listUrl(requirementId, cegId, testSpecId); + RestResult getResult = restClient.getList(retrieveUrl); + JSONArray retrievedTestChilds = getResult.getPayload(); + logService.log(LogService.LOG_DEBUG, + "Retrieved the object " + retrievedTestChilds.toString() + " from url " + retrieveUrl); + + List testCases = getTestCases(retrievedTestChilds); + + // Expect 3 tests should be generated + Assert.assertEquals(3, testCases.size()); + + int numberOfInconsistentTests = 0; + for (JSONObject testCase : testCases) { + if (!testCase.getBoolean("consistent")) { + numberOfInconsistentTests++; + } + } + Assert.assertEquals(1, numberOfInconsistentTests); + } /** * Generates a model with contradictory constraints and trys to generate diff --git a/bundles/specmate-integration-test/src/com/specmate/test/integration/EmfRestTest.java b/bundles/specmate-integration-test/src/com/specmate/test/integration/EmfRestTest.java index 389b3aad9..b547530e0 100644 --- a/bundles/specmate-integration-test/src/com/specmate/test/integration/EmfRestTest.java +++ b/bundles/specmate-integration-test/src/com/specmate/test/integration/EmfRestTest.java @@ -173,17 +173,23 @@ protected JSONObject createTestProcessModel() { process.put(BasePackage.Literals.INAMED__NAME.getName(), processName); return process; } - + protected JSONObject createTestCegNode() { + String variable = "Variable" + counter++; + String condition ="Condition" + counter++; + return createTestCegNode(variable,condition,NodeType.OR.getLiteral()); + } + + protected JSONObject createTestCegNode(String variable, String condition, String operation) { String cegName = "TestCegNode" + counter++; JSONObject cegNode = new JSONObject(); cegNode.put(NSURI_KEY, RequirementsPackage.eNS_URI); cegNode.put(ECLASS, RequirementsPackage.Literals.CEG_NODE.getName()); cegNode.put(BasePackage.Literals.IID__ID.getName(), cegName); cegNode.put(BasePackage.Literals.INAMED__NAME.getName(), cegName); - cegNode.put(RequirementsPackage.Literals.CEG_NODE__VARIABLE.getName(), cegName); - cegNode.put(RequirementsPackage.Literals.CEG_NODE__CONDITION.getName(), "5"); - cegNode.put(RequirementsPackage.Literals.CEG_NODE__TYPE.getName(), NodeType.OR.getLiteral()); + cegNode.put(RequirementsPackage.Literals.CEG_NODE__VARIABLE.getName(), variable); + cegNode.put(RequirementsPackage.Literals.CEG_NODE__CONDITION.getName(), condition); + cegNode.put(RequirementsPackage.Literals.CEG_NODE__TYPE.getName(), operation); return cegNode; } diff --git a/bundles/specmate-model-generators-typescript/src/com/specmate/model/generators/typescript/GenerateAngular.java b/bundles/specmate-model-generators-typescript/src/com/specmate/model/generators/typescript/GenerateAngular.java index 89ddd1948..189d87109 100644 --- a/bundles/specmate-model-generators-typescript/src/com/specmate/model/generators/typescript/GenerateAngular.java +++ b/bundles/specmate-model-generators-typescript/src/com/specmate/model/generators/typescript/GenerateAngular.java @@ -396,14 +396,20 @@ public void registerResourceFactories(ResourceSet resourceSet) { /* * TODO If you need additional resource factories registrations, you can register them here. the following line - * (in comment) is an example of the resource factory registration for UML. + * (in comment) is an example of the resource factory registration. * * If you want to use the generator in stand alone, the resource factory registration will be required. * * To learn more about the registration of Resource Factories, have a look at the Acceleo documentation (Help -> Help Contents). */ - // resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE); + // resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(XyzResource.FILE_EXTENSION, XyzResource.Factory.INSTANCE); + + /* + * Some metamodels require a very complex setup for standalone usage. For example, if you want to use a generator + * targetting UML models in standalone, you NEED to use the following: + */ + // UMLResourcesUtil.init(resourceSet) } } diff --git a/bundles/specmate-std-env/dev-specmate-all.bndrun b/bundles/specmate-std-env/dev-specmate-all.bndrun index 739c9809b..c679ffbc4 100644 --- a/bundles/specmate-std-env/dev-specmate-all.bndrun +++ b/bundles/specmate-std-env/dev-specmate-all.bndrun @@ -186,10 +186,11 @@ com.sun.jersey.core;version='[1.19.0,1.19.1)',\ com.sun.jersey.jersey-server;version='[1.19.0,1.19.1)',\ javax.ws.rs.jsr311-api;version='[1.1.1,1.1.2)',\ - specmate-rest;version=snapshot + specmate-rest;version=snapshot,\ + org.apache.commons.collections4;version='[4.0.0,4.0.1)' -runproperties: \ - jetty.http.port=8080,\ + jetty.http.port=8081,\ jetty.etc.config.urls='etc/jetty.xml,etc/jetty-http.xml,etc/jetty-deployer.xml,etc/jetty-rewrite.xml',\ osgi.console=,\ jetty.home.bundle=specmate-jettystarter,\ diff --git a/bundles/specmate-std-env/prod-specmate-all.bndrun b/bundles/specmate-std-env/prod-specmate-all.bndrun index 5412a98ca..4fdd94f14 100644 --- a/bundles/specmate-std-env/prod-specmate-all.bndrun +++ b/bundles/specmate-std-env/prod-specmate-all.bndrun @@ -171,7 +171,8 @@ specmate-cdo-server;version=snapshot,\ org.apache.commons.lang3;version='[3.3.2,3.3.3)',\ org.eclipse.emf.cdo.server.db;version='[4.4.0,4.4.1)',\ - specmate-rest;version=snapshot + specmate-rest;version=snapshot,\ + org.apache.commons.collections4;version='[4.0.0,4.0.1)' -runproperties: \ jetty.http.port=8080,\ diff --git a/bundles/specmate-std-env/prod-specmate-no-cdo-server.bndrun b/bundles/specmate-std-env/prod-specmate-no-cdo-server.bndrun index 0a3f1a69c..d313217b2 100644 --- a/bundles/specmate-std-env/prod-specmate-no-cdo-server.bndrun +++ b/bundles/specmate-std-env/prod-specmate-no-cdo-server.bndrun @@ -161,7 +161,8 @@ specmate-metrics;version=snapshot,\ org.apache.commons.lang3;version='[3.3.2,3.3.3)',\ specmate-dbprovider-api;version=snapshot,\ - specmate-rest;version=snapshot + specmate-rest;version=snapshot,\ + org.apache.commons.collections4;version='[4.0.0,4.0.1)' -runproperties: \ jetty.http.port=8080,\ diff --git a/bundles/specmate-testspecification/bnd.bnd b/bundles/specmate-testspecification/bnd.bnd index b897e0901..76c65e7f5 100644 --- a/bundles/specmate-testspecification/bnd.bnd +++ b/bundles/specmate-testspecification/bnd.bnd @@ -16,5 +16,6 @@ org.sat4j.maxsat,\ org.sat4j.pb,\ specmate-emfrest-api;version=latest,\ - specmate-rest;version=latest + specmate-rest;version=latest,\ + org.apache.commons.collections4 Private-Package: com.specmate.testspecification.internal.services \ No newline at end of file diff --git a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/services/CEGTestCaseGenerator.java b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/services/CEGTestCaseGenerator.java index 434fcb85b..40e58f2f6 100644 --- a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/services/CEGTestCaseGenerator.java +++ b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/services/CEGTestCaseGenerator.java @@ -1,14 +1,17 @@ package com.specmate.testspecification.internal.services; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.stream.Collectors; import java.util.Optional; import java.util.Set; +import org.apache.commons.collections4.map.MultiValueMap; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.eclipse.emf.ecore.EObject; @@ -168,9 +171,9 @@ private String negateCondition(String condition) { } /** - * Node evaluations are a precursor to test cases. This method computes the - * node evaluations according to the rules in the Specmate systems - * requirements documentation. + * Node evaluations are a precursor to test cases. This method computes the node + * evaluations according to the rules in the Specmate systems requirements + * documentation. * * @param nodes * @return @@ -211,8 +214,8 @@ private Pair, Set> refineEvaluations(Set getInitialEvaluations() { Set evaluations = new HashSet<>(); @@ -247,8 +250,8 @@ private Optional getAnyIntermediateNode(NodeEvaluation evaluation) { } /** - * Returns evaluations that have intermediate nodes (i.e. nodes that have to - * be evaluated) + * Returns evaluations that have intermediate nodes (i.e. nodes that have to be + * evaluated) */ private Set getIntermediateEvaluations(Set evaluations) { HashSet intermediate = new HashSet<>(); @@ -322,8 +325,8 @@ private void handleAllCase(boolean isAnd, NodeEvaluation evaluation, IModelNode } /** - * Sets the value of a node in an evaluation but checks first if it is - * already set with a different value + * Sets the value of a node in an evaluation but checks first if it is already + * set with a different value * * @return false if an inconsistent value would be set in the node */ @@ -338,8 +341,8 @@ private boolean checkAndSet(NodeEvaluation evaluation, CEGNode node, TaggedBoole } /** - * Runs through the list of evaluations and merges the ones that can be - * merged. Identifiey inconsistent evaluations + * Runs through the list of evaluations and merges the ones that can be merged. + * Identifiey inconsistent evaluations * * @throws SpecmateException */ @@ -441,7 +444,7 @@ private int getAdditionalVar(int i) { return nodes.size() + i; } - private IVecInt getVectorForVariables(int... vars) { + private IVecInt getVectorForVariables(Integer... vars) { IVecInt vector = new VecInt(vars.length + 1); for (int i = 0; i < vars.length; i++) vector.push(vars[i]); @@ -475,8 +478,8 @@ private NodeEvaluation fill(NodeEvaluation evaluation) throws SpecmateException } /** - * Sets the value in an evaluation based on an original evaluation and a - * model value. + * Sets the value in an evaluation based on an original evaluation and a model + * value. */ private void setModelValue(NodeEvaluation originalEvaluation, NodeEvaluation targetEvaluation, int varNameValue) { boolean value = varNameValue > 0; @@ -516,6 +519,7 @@ private void pushEvaluation(NodeEvaluation evaluation, GateTranslator translator } } + /** Feeds constraints representing the CEG structure to the solver */ private void pushCEGStructure(GateTranslator translator) throws ContradictionException { for (IModelNode node : nodes) { int varForNode = getVarForNode(node); @@ -528,6 +532,31 @@ private void pushCEGStructure(GateTranslator translator) throws ContradictionExc } } } + pushMutualExclusiveConstraints(translator); + } + + private void pushMutualExclusiveConstraints(GateTranslator translator) throws ContradictionException { + Collection> mutualExclusiveNodeSets = getMutualExclusiveNodeSets(); + for (Collection mutexSet : mutualExclusiveNodeSets) { + Integer[] variables = (Integer[]) mutexSet.stream().map(node -> getVarForNode(node)) + .collect(Collectors.toList()).toArray(new Integer[0]); + translator.addAtMost(getVectorForVariables(variables), 1); + } + } + + private Collection> getMutualExclusiveNodeSets() { + Collection> result = new ArrayList<>(); + MultiValueMap multiMap = new MultiValueMap(); + for (IModelNode node : nodes) { + CEGNode cegNode = (CEGNode) node; + if (cegNode.getCondition().trim().startsWith("=")) { + multiMap.put(cegNode.getVariable(), cegNode); + } + } + for (String key : multiMap.keySet()) { + result.add(multiMap.getCollection(key)); + } + return result; } /** Returns the CEG node for a given variable (given as int) */ @@ -555,8 +584,7 @@ private IVecInt getPredecessorVector(IModelNode node) { } /** - * Equality checker that ignores differences in the fields id, name and - * position + * Equality checker that ignores differences in the fields id, name and position */ private class IdNamePositionIgnoreEqualityHelper extends EqualityHelper { @Override From 32830785fea581caa142831703e0601868326949 Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Fri, 7 Sep 2018 11:38:09 +0200 Subject: [PATCH 02/44] remove comment in connector and reset bndrun file --- .../connectors/hpconnector/internal/services/HPConnector.java | 2 -- bundles/specmate-std-env/dev-specmate-all.bndrun | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/bundles/specmate-hp-connector/src/com/specmate/connectors/hpconnector/internal/services/HPConnector.java b/bundles/specmate-hp-connector/src/com/specmate/connectors/hpconnector/internal/services/HPConnector.java index 8837c6858..53b5294fd 100644 --- a/bundles/specmate-hp-connector/src/com/specmate/connectors/hpconnector/internal/services/HPConnector.java +++ b/bundles/specmate-hp-connector/src/com/specmate/connectors/hpconnector/internal/services/HPConnector.java @@ -132,8 +132,6 @@ public RestResult get(Object target, MultivaluedMap queryPara } Requirement localRequirement = (Requirement) target; - // TODO: We should check the source of the requirment, there might be - // more sources in future if (localRequirement.getExtId() == null) { return new RestResult<>(Response.Status.OK, localRequirement); } diff --git a/bundles/specmate-std-env/dev-specmate-all.bndrun b/bundles/specmate-std-env/dev-specmate-all.bndrun index c679ffbc4..497c570ac 100644 --- a/bundles/specmate-std-env/dev-specmate-all.bndrun +++ b/bundles/specmate-std-env/dev-specmate-all.bndrun @@ -190,7 +190,7 @@ org.apache.commons.collections4;version='[4.0.0,4.0.1)' -runproperties: \ - jetty.http.port=8081,\ + jetty.http.port=8080,\ jetty.etc.config.urls='etc/jetty.xml,etc/jetty-http.xml,etc/jetty-deployer.xml,etc/jetty-rewrite.xml',\ osgi.console=,\ jetty.home.bundle=specmate-jettystarter,\ From bf5981e70a592dfe41638bf6349a40d774b06832 Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Tue, 9 Oct 2018 14:59:52 +0200 Subject: [PATCH 03/44] change duplicate function to not copy test specifications --- .../specmate/emfrest/crud/CopyService.java | 5 +- .../com/specmate/emfrest/crud/CrudUtil.java | 62 +++++++++++++------ .../specmate/test/integration/CrudTest.java | 29 +++++++++ .../specmate/test/integration/SearchTest.java | 1 + 4 files changed, 78 insertions(+), 19 deletions(-) diff --git a/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CopyService.java b/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CopyService.java index af284cc11..be95ed362 100644 --- a/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CopyService.java +++ b/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CopyService.java @@ -1,11 +1,14 @@ package com.specmate.emfrest.crud; +import java.util.Arrays; + import org.osgi.service.component.annotations.Component; import com.specmate.common.SpecmateException; import com.specmate.common.SpecmateValidationException; import com.specmate.emfrest.api.IRestService; import com.specmate.emfrest.api.RestServiceBase; +import com.specmate.model.base.Folder; import com.specmate.model.processes.Process; import com.specmate.model.requirements.CEGModel; import com.specmate.model.testspecification.TestSpecification; @@ -26,6 +29,6 @@ public boolean canPost(Object target, Object object) { @Override public RestResult post(Object target, Object child, String token) throws SpecmateException, SpecmateValidationException { - return CrudUtil.duplicate(target); + return CrudUtil.duplicate(target, Arrays.asList(TestSpecification.class,Folder.class)); } } diff --git a/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CrudUtil.java b/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CrudUtil.java index a361607cf..9202f8319 100644 --- a/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CrudUtil.java +++ b/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CrudUtil.java @@ -20,6 +20,7 @@ import com.specmate.common.SpecmateValidationException; import com.specmate.model.base.IContainer; import com.specmate.model.base.IContentElement; +import com.specmate.model.base.ISpecmateModelObject; import com.specmate.model.support.util.SpecmateEcoreUtil; import com.specmate.rest.RestResult; @@ -69,35 +70,60 @@ public static RestResult update(Object target, EObject update, String userNam return new RestResult<>(Response.Status.OK, target, userName); } - public static RestResult duplicate(Object target) throws SpecmateException { + /** + * Copies an object recursively with all children and adds the copy to the + * parent of the object. The duplicate gets a name that is guaranteed to be + * unique within the parent. + * + * @param target + * @param avoidRecurse + * @return + * @throws SpecmateException + */ + public static RestResult duplicate(Object target, List> avoidRecurse) + throws SpecmateException { EObject original = (EObject) target; - IContentElement copy = (IContentElement) EcoreUtil.copy(original); + ISpecmateModelObject copy = filteredCopy(avoidRecurse, original); IContainer parent = (IContainer) original.eContainer(); + setUniqueCopyId(copy, parent); + parent.getContents().add(copy); + + return new RestResult<>(Response.Status.OK, target); + } + + private static ISpecmateModelObject filteredCopy(List> avoidRecurse, EObject original) { + ISpecmateModelObject copy = (ISpecmateModelObject) EcoreUtil.copy(original); + List retain = copy.getContents().stream() + .filter(el -> !avoidRecurse.stream().anyMatch(avoid -> avoid.isAssignableFrom(el.getClass()))) + .collect(Collectors.toList()); + copy.getContents().clear(); + copy.getContents().addAll(retain); + return copy; + } + + private static void setUniqueCopyId(ISpecmateModelObject copy, IContainer parent) { EList contents = parent.getContents(); - // Change ID String newID = SpecmateEcoreUtil.getIdForChild(parent, copy.eClass()); copy.setId(newID); - + String name = copy.getName().replaceFirst("^Copy [0-9]+ of ", ""); - + String prefix = "Copy "; - String suffix = " of " + name; + String suffix = " of " + name; int copyNumber = 1; - - Set names = contents.stream().map(e -> e.getName()).filter(e -> e.startsWith(prefix) && e.endsWith(suffix)).collect(Collectors.toSet()); + + Set names = contents.stream().map(e -> e.getName()) + .filter(e -> e.startsWith(prefix) && e.endsWith(suffix)).collect(Collectors.toSet()); String newName = ""; do { newName = prefix + copyNumber + suffix; copyNumber++; - } while(names.contains(newName)); - + } while (names.contains(newName)); + copy.setName(newName); - contents.add(copy); - - return new RestResult<>(Response.Status.OK, target); } - + public static RestResult delete(Object target, String userName) throws SpecmateException { if (target instanceof EObject && !(target instanceof Resource)) { SpecmateEcoreUtil.detach((EObject) target); @@ -157,14 +183,14 @@ public static List getChildren(Object target) throws SpecmateException } /** - * Checks whether the update is either detached from any project or is part of - * the same project than the object represented by this resource. + * Checks whether the update is either detached from any project or is part + * of the same project than the object represented by this resource. * * @param update * The update object for which to check the project * @param recurse - * If true, also checks the projects for objects referenced by the - * update + * If true, also checks the projects for objects referenced by + * the update * @return */ private static boolean isProjectModificationRequestAuthorized(Object resourceObject, EObject update, diff --git a/bundles/specmate-integration-test/src/com/specmate/test/integration/CrudTest.java b/bundles/specmate-integration-test/src/com/specmate/test/integration/CrudTest.java index ed3158259..b1ee25cc9 100644 --- a/bundles/specmate-integration-test/src/com/specmate/test/integration/CrudTest.java +++ b/bundles/specmate-integration-test/src/com/specmate/test/integration/CrudTest.java @@ -20,6 +20,12 @@ public class CrudTest extends EmfRestTest { public CrudTest() throws Exception { super(); } + + private void performDuplicate(String... segments) { + String duplicateUrl = buildUrl("duplicate", segments); + RestResult result = restClient.post(duplicateUrl, null); + Assert.assertEquals(Status.OK.getStatusCode(), result.getResponse().getStatus()); + } /** * Tests posting a folder to the root. Checks, if the return code of the post @@ -699,4 +705,27 @@ public void testInconsistentProject() { postObject(Status.UNAUTHORIZED.getStatusCode(), cegConnection, project2Id, ceg2Id); } + + @Test + public void testDuplicate() { + JSONObject requirement = postRequirementToRoot(); + String requirementId = getId(requirement); + + // Post ceg model + JSONObject cegModel = postCEG(requirementId); + String cegId = getId(cegModel); + + RestResult result = restClient.getList(listUrl(requirementId)); + JSONArray payload = result.getPayload(); + Assert.assertEquals(1, payload.length()); + + performDuplicate(requirementId, cegId); + + result = restClient.getList(listUrl(requirementId)); + payload = result.getPayload(); + Assert.assertEquals(2, payload.length()); + +// They are not equal, as id and name are different +// Assert.assertTrue(EmfRestTestUtil.compare(payload.getJSONObject(0), payload.getJSONObject(1), true)); + } } diff --git a/bundles/specmate-integration-test/src/com/specmate/test/integration/SearchTest.java b/bundles/specmate-integration-test/src/com/specmate/test/integration/SearchTest.java index 99801aede..b2802284f 100644 --- a/bundles/specmate-integration-test/src/com/specmate/test/integration/SearchTest.java +++ b/bundles/specmate-integration-test/src/com/specmate/test/integration/SearchTest.java @@ -63,6 +63,7 @@ private JSONArray performSearch(String project, String query) { JSONArray foundObjects = result.getPayload(); return foundObjects; } + private void performReindex() { String reindexUrl = buildUrl("reindex"); From 75e4e85fb39b1ba0de64b54b2060c68469880eff Mon Sep 17 00:00:00 2001 From: Daedo Date: Fri, 19 Oct 2018 08:45:24 +0200 Subject: [PATCH 04/44] Graphical editor clipboard (#291) * Bugfixes, Started work on clipboard. * Fixed dublicate connection. * Bugfix. Added Clipboard Service. * Fixed typo. * Allowing empty string to be interpreted as false --- .../specmate/emfjson/EMFJsonDeserializer.java | 400 +++++++++--------- .../util/graph-element-factory-selector.ts | 2 +- .../components/common-controls.component.html | 8 +- .../components/common-controls.component.ts | 16 +- .../common/modules/ui/ui-safe-decorator.ts | 33 ++ .../components/graphical-editor.component.ts | 4 +- .../providers/properties/tool-provider.ts | 8 +- .../services/clipboard-service.ts | 24 ++ .../services/editor-tools.service.ts | 6 +- .../tool-pallette/tool-pallette.module.ts | 4 +- .../tool-pallette/tools/common/select-tool.ts | 63 ++- .../tool-pallette/util/graphTransformer.ts | 95 +++-- web/src/app/util/objects.ts | 2 +- 13 files changed, 385 insertions(+), 280 deletions(-) create mode 100644 web/src/app/modules/common/modules/ui/ui-safe-decorator.ts create mode 100644 web/src/app/modules/views/main/editors/modules/tool-pallette/services/clipboard-service.ts diff --git a/bundles/specmate-emfjson/src/com/specmate/emfjson/EMFJsonDeserializer.java b/bundles/specmate-emfjson/src/com/specmate/emfjson/EMFJsonDeserializer.java index 8154fc430..42a6caac8 100644 --- a/bundles/specmate-emfjson/src/com/specmate/emfjson/EMFJsonDeserializer.java +++ b/bundles/specmate-emfjson/src/com/specmate/emfjson/EMFJsonDeserializer.java @@ -1,198 +1,202 @@ -package com.specmate.emfjson; - -import org.apache.commons.lang3.StringUtils; -import org.eclipse.emf.common.util.BasicEList; -import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EClassifier; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.util.EcoreUtil; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import com.specmate.common.SpecmateException; -import com.specmate.urihandler.IObjectResolver; - -/** - * Deserializes JSON objects to EObjects - * - * @author junkerm - * - */ -public class EMFJsonDeserializer { - - /** Resolver to obtain reference EObjects from the resource based on an uri */ - private IObjectResolver resolver; - - /** The underlying resource from where to retrieve referenced objects */ - private Resource resource; - - /** - * - * @param resolver - * The object resolver to be used - * @param resource - * The resource from where to retieve referenced objects - */ - public EMFJsonDeserializer(IObjectResolver resolver, Resource resource) { - this.resolver = resolver; - this.resource = resource; - } - - /** - * Deserializes an Eobject from a JSON object - * - * @param jsonObj - * The JSON object to be deserialized - * @return The EObject that is represented by the json object - * @throws SpecmateException - */ - public EObject deserializeEObject(JSONObject jsonObj) - throws SpecmateException { - if (jsonObj.has(EMFJsonSerializer.KEY_PROXY) && jsonObj.getBoolean(EMFJsonSerializer.KEY_PROXY)) { - String uriFragment = jsonObj.getString(EMFJsonSerializer.KEY_URI); - return retrieveFromResource(uriFragment); - } else { - return buildFromJson(jsonObj); - } - } - - /** - * Retrieves an EObject directly from the resource based on an URI - * - * @param uri - * The URI used to adress the object - * @return An EObject that has the given URI - * @throws SpecmateException - */ - private EObject retrieveFromResource(String uri) throws SpecmateException { - EObject retrieved = resolver.getObject(uri, resource); - if (retrieved == null) { - throw new SpecmateException( - "Json contained " - + EMFJsonSerializer.KEY_URI - + " entry but no object with this fragment url could be found"); - } else - return retrieved; - } - - /** - * Constructs an EObject recursively from the given JSON object - * - * @param jsonObj - * The JSON object from which to construct the EObject - * @return An EObject representing the jsonObject - * @throws SpecmateException - */ - private EObject buildFromJson(JSONObject jsonObj) throws SpecmateException { - String nsUri = jsonObj.optString(EMFJsonSerializer.KEY_NSURI); - String className = jsonObj.optString(EMFJsonSerializer.KEY_ECLASS); - if (StringUtils.isEmpty(nsUri) || StringUtils.isEmpty(className)) { - throw new SpecmateException("No uri or eclass specified"); - } - - EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(nsUri); - if (ePackage == null) { - throw new SpecmateException("No package registered for " + nsUri); - } - EClassifier classifier = ePackage.getEClassifier(className); - if (classifier == null || !(classifier instanceof EClass)) { - throw new SpecmateException("No class with name " + className - + " in package"); - } - - EClass clazz = (EClass) classifier; - - EObject eObj = ePackage.getEFactoryInstance().create(clazz); - deserializeFeatures(eObj, jsonObj); - - return eObj; - } - - /** - * Deserializes the values of all features of an EObject from the given - * JSONObject - * - * @param eObject - * The EObject for which the feature values should be dserialized - * @param jsonObj - * The JSON object from which to serialize the values - * @throws SpecmateException - */ - private void deserializeFeatures(EObject eObject, JSONObject jsonObj) - throws SpecmateException { - String featureName = null; - for (EStructuralFeature feature : eObject.eClass() - .getEAllStructuralFeatures()) { - featureName = feature.getName(); - if (jsonObj.has(featureName)) { - Object value; - try { - value = jsonObj.get(featureName); - } catch (JSONException e) { - throw new SpecmateException(e); - } - eObject.eSet(feature, deserializeFeature(feature, value)); - } - } - } - - /** - * Deserialized the value of a single feature of an EObject from a JSON - * entity. This entity is either a {@link JSONArray} or a {@link JSONObject} - * depending on the type of the feature. - * - * @param feature - * The which for the value should be deserialized - * @param json - * The json entity ({@link JSONArray} or {@link JSONObject}) from - * which to deserialize - * @return The EObject or the EList obtained from the deserialization - * @throws SpecmateException - */ - private Object deserializeFeature(EStructuralFeature feature, Object json) - throws SpecmateException { - EClassifier type = feature.getEType(); - if (!feature.isMany()) { - return deserializeValue(json, type); - } else { - JSONArray array = (JSONArray) json; - BasicEList list = new BasicEList(); - for (int i = 0; i < array.length(); i++) { - try { - list.add(deserializeValue(array.get(i), type)); - } catch (JSONException e) { - throw new SpecmateException(e); - } - } - return list; - } - } - - /** - * Deserializs a JSON value, depending on the expected type. - * - * @param value - * The JSON value to deserialize - * @param type - * The expected type - * @return The deserialized value, either an EObject or a primitive type - * such as String, etc. - * @throws SpecmateException - */ - private Object deserializeValue(Object value, EClassifier type) - throws SpecmateException { - if (type instanceof EDataType) { - return EcoreUtil.createFromString((EDataType) type, value.toString()); - } else if (type instanceof EClass) { - return deserializeEObject((JSONObject) value); - } else - throw new SpecmateException(type - + " not supported for deserialization"); - } - -} +package com.specmate.emfjson; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import com.specmate.common.SpecmateException; +import com.specmate.urihandler.IObjectResolver; + +/** + * Deserializes JSON objects to EObjects + * + * @author junkerm + * + */ +public class EMFJsonDeserializer { + + /** Resolver to obtain reference EObjects from the resource based on an uri */ + private IObjectResolver resolver; + + /** The underlying resource from where to retrieve referenced objects */ + private Resource resource; + + /** + * + * @param resolver + * The object resolver to be used + * @param resource + * The resource from where to retieve referenced objects + */ + public EMFJsonDeserializer(IObjectResolver resolver, Resource resource) { + this.resolver = resolver; + this.resource = resource; + } + + /** + * Deserializes an Eobject from a JSON object + * + * @param jsonObj + * The JSON object to be deserialized + * @return The EObject that is represented by the json object + * @throws SpecmateException + */ + public EObject deserializeEObject(JSONObject jsonObj) + throws SpecmateException { + if (jsonObj.has(EMFJsonSerializer.KEY_PROXY) && jsonObj.getBoolean(EMFJsonSerializer.KEY_PROXY)) { + String uriFragment = jsonObj.getString(EMFJsonSerializer.KEY_URI); + return retrieveFromResource(uriFragment); + } else { + return buildFromJson(jsonObj); + } + } + + /** + * Retrieves an EObject directly from the resource based on an URI + * + * @param uri + * The URI used to adress the object + * @return An EObject that has the given URI + * @throws SpecmateException + */ + private EObject retrieveFromResource(String uri) throws SpecmateException { + EObject retrieved = resolver.getObject(uri, resource); + if (retrieved == null) { + throw new SpecmateException( + "Json contained " + + EMFJsonSerializer.KEY_URI + + " entry but no object with this fragment url could be found"); + } else + return retrieved; + } + + /** + * Constructs an EObject recursively from the given JSON object + * + * @param jsonObj + * The JSON object from which to construct the EObject + * @return An EObject representing the jsonObject + * @throws SpecmateException + */ + private EObject buildFromJson(JSONObject jsonObj) throws SpecmateException { + String nsUri = jsonObj.optString(EMFJsonSerializer.KEY_NSURI); + String className = jsonObj.optString(EMFJsonSerializer.KEY_ECLASS); + if (StringUtils.isEmpty(nsUri) || StringUtils.isEmpty(className)) { + throw new SpecmateException("No uri or eclass specified"); + } + + EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(nsUri); + if (ePackage == null) { + throw new SpecmateException("No package registered for " + nsUri); + } + EClassifier classifier = ePackage.getEClassifier(className); + if (classifier == null || !(classifier instanceof EClass)) { + throw new SpecmateException("No class with name " + className + + " in package"); + } + + EClass clazz = (EClass) classifier; + + EObject eObj = ePackage.getEFactoryInstance().create(clazz); + deserializeFeatures(eObj, jsonObj); + + return eObj; + } + + /** + * Deserializes the values of all features of an EObject from the given + * JSONObject + * + * @param eObject + * The EObject for which the feature values should be dserialized + * @param jsonObj + * The JSON object from which to serialize the values + * @throws SpecmateException + */ + private void deserializeFeatures(EObject eObject, JSONObject jsonObj) + throws SpecmateException { + String featureName = null; + for (EStructuralFeature feature : eObject.eClass() + .getEAllStructuralFeatures()) { + featureName = feature.getName(); + if (jsonObj.has(featureName)) { + Object value; + try { + value = jsonObj.get(featureName); + } catch (JSONException e) { + throw new SpecmateException(e); + } + eObject.eSet(feature, deserializeFeature(feature, value)); + } + } + } + + /** + * Deserialized the value of a single feature of an EObject from a JSON + * entity. This entity is either a {@link JSONArray} or a {@link JSONObject} + * depending on the type of the feature. + * + * @param feature + * The which for the value should be deserialized + * @param json + * The json entity ({@link JSONArray} or {@link JSONObject}) from + * which to deserialize + * @return The EObject or the EList obtained from the deserialization + * @throws SpecmateException + */ + private Object deserializeFeature(EStructuralFeature feature, Object json) + throws SpecmateException { + EClassifier type = feature.getEType(); + if (!feature.isMany()) { + return deserializeValue(json, type); + } else { + JSONArray array = (JSONArray) json; + BasicEList list = new BasicEList(); + for (int i = 0; i < array.length(); i++) { + try { + list.add(deserializeValue(array.get(i), type)); + } catch (JSONException e) { + throw new SpecmateException(e); + } + } + return list; + } + } + + /** + * Deserializs a JSON value, depending on the expected type. + * + * @param value + * The JSON value to deserialize + * @param type + * The expected type + * @return The deserialized value, either an EObject or a primitive type + * such as String, etc. + * @throws SpecmateException + */ + private Object deserializeValue(Object value, EClassifier type) + throws SpecmateException { + if (type instanceof EDataType) { + String strValue = value.toString(); + if(type.getName().equalsIgnoreCase("EBoolean") && value.toString().equals("")) { + strValue = "false"; + } + return EcoreUtil.createFromString((EDataType) type, strValue); + } else if (type instanceof EClass) { + return deserializeEObject((JSONObject) value); + } else + throw new SpecmateException(type + + " not supported for deserialization"); + } + +} diff --git a/web/src/app/factory/util/graph-element-factory-selector.ts b/web/src/app/factory/util/graph-element-factory-selector.ts index 99490d750..b0df1ffb0 100644 --- a/web/src/app/factory/util/graph-element-factory-selector.ts +++ b/web/src/app/factory/util/graph-element-factory-selector.ts @@ -20,7 +20,7 @@ import { ProcessConnection } from '../../model/ProcessConnection'; import { ProcessConnectionFactory } from '../process-connection-factory'; import { IModelNode } from '../../model/IModelNode'; -type Coords = {x: number, y: number}; +export type Coords = {x: number, y: number}; export class GraphElementFactorySelector { public static getNodeFactory(template: IContainer, coords: Coords, dataService: SpecmateDataService): PositionableElementFactoryBase { diff --git a/web/src/app/modules/actions/modules/common-controls/components/common-controls.component.html b/web/src/app/modules/actions/modules/common-controls/components/common-controls.component.html index 7cccacffa..1a674dbae 100644 --- a/web/src/app/modules/actions/modules/common-controls/components/common-controls.component.html +++ b/web/src/app/modules/actions/modules/common-controls/components/common-controls.component.html @@ -1,7 +1,7 @@
-   -   -   -   +   +   +   +  
 {{'connection.lost' | translate}}
\ No newline at end of file diff --git a/web/src/app/modules/actions/modules/common-controls/components/common-controls.component.ts b/web/src/app/modules/actions/modules/common-controls/components/common-controls.component.ts index a6348f17e..09f3c58df 100644 --- a/web/src/app/modules/actions/modules/common-controls/components/common-controls.component.ts +++ b/web/src/app/modules/actions/modules/common-controls/components/common-controls.component.ts @@ -1,9 +1,10 @@ import { Component } from '@angular/core'; -import { SpecmateDataService } from '../../../../data/modules/data-service/services/specmate-data.service'; -import { NavigatorService } from '../../../../navigation/modules/navigator/services/navigator.service'; -import { ValidationService } from '../../../../forms/modules/validation/services/validation.service'; import { TranslateService } from '@ngx-translate/core'; import { ServerConnectionService } from '../../../../common/modules/connection/services/server-connection-service'; +import { UISafe } from '../../../../common/modules/ui/ui-safe-decorator'; +import { SpecmateDataService } from '../../../../data/modules/data-service/services/specmate-data.service'; +import { ValidationService } from '../../../../forms/modules/validation/services/validation.service'; +import { NavigatorService } from '../../../../navigation/modules/navigator/services/navigator.service'; @Component({ moduleId: module.id.toString(), @@ -59,11 +60,16 @@ export class CommonControls { } public get isSaveEnabled(): boolean { - return this.isEnabled && this.dataService.hasCommits && this.validator.currentValid; + return this.isEnabled && this.hasCommits && this.validator.currentValid; } public get isUndoEnabled(): boolean { - return this.isEnabled && this.dataService.hasCommits; + return this.isEnabled && this.hasCommits; + } + + @UISafe() + private get hasCommits(): boolean { + return this.dataService.hasCommits; } public get isBackEnabled(): boolean { diff --git a/web/src/app/modules/common/modules/ui/ui-safe-decorator.ts b/web/src/app/modules/common/modules/ui/ui-safe-decorator.ts new file mode 100644 index 000000000..1f1a9738d --- /dev/null +++ b/web/src/app/modules/common/modules/ui/ui-safe-decorator.ts @@ -0,0 +1,33 @@ +/** + * Adding @UISafe() to a getter delays changes to the underlying value until the next update cycle. + * This prevents ExpressionChangedAfterItHasBeenCheckedErrors + */ +export function UISafe(): MethodDecorator { + return function(target: any, propertyKey: string| symbol, descriptor: PropertyDescriptor) { + let originalMethod = descriptor.get; + if (!originalMethod) { + throw new Error('@UISafe can only decorate getters.'); + } + if (!descriptor.configurable) { + throw new Error('@UISafe target must be configurable.'); + } + let oldValue: any = undefined; + let firstCall = true; + descriptor.get = function() { + let context = this; + let args = arguments; + let newValue = originalMethod.apply(context, args); + if (firstCall) { + oldValue = newValue; + firstCall = false; + } + if (oldValue !== newValue) { + setTimeout(() => { + oldValue = newValue; + }); + } + return oldValue; + }; + return descriptor; + }; +} diff --git a/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.ts b/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.ts index 5bf39deeb..7949c5dfe 100644 --- a/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.ts +++ b/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.ts @@ -22,6 +22,7 @@ import { MultiselectionService } from '../../tool-pallette/services/multiselecti import { IKeyboardTool } from '../../tool-pallette/tools/IKeyboardTool'; import { IDoubleClickTool } from '../../tool-pallette/tools/IDoubleClickTool'; import { SelectionRect } from '../../../../../side/modules/selected-element/util/selection-rect'; +import { ClipboardService } from '../../tool-pallette/services/clipboard-service'; @Component({ moduleId: module.id.toString(), @@ -67,6 +68,7 @@ export class GraphicalEditor { private viewController: ViewControllerService, private translate: TranslateService, public multiselectionService: MultiselectionService, + private clipboardService: ClipboardService, private renderer: Renderer ) { } public get model(): IContainer { @@ -84,7 +86,7 @@ export class GraphicalEditor { @Input() public set model(model: IContainer) { this.toolProvider = new ToolProvider( - model, this.dataService, this.selectedElementService, this.translate, this.multiselectionService); + model, this.dataService, this.selectedElementService, this.translate, this.multiselectionService, this.clipboardService); this.nameProvider = new NameProvider(model, this.translate); this._model = model; } diff --git a/web/src/app/modules/views/main/editors/modules/graphical-editor/providers/properties/tool-provider.ts b/web/src/app/modules/views/main/editors/modules/graphical-editor/providers/properties/tool-provider.ts index e33c7d21f..ba4628c8c 100644 --- a/web/src/app/modules/views/main/editors/modules/graphical-editor/providers/properties/tool-provider.ts +++ b/web/src/app/modules/views/main/editors/modules/graphical-editor/providers/properties/tool-provider.ts @@ -15,6 +15,7 @@ import { ProcessDeleteTool } from '../../../tool-pallette/tools/process/process- import { TranslateService } from '@ngx-translate/core'; import { SelectTool } from '../../../tool-pallette/tools/common/select-tool'; import { MultiselectionService } from '../../../tool-pallette/services/multiselection.service'; +import { ClipboardService } from '../../../tool-pallette/services/clipboard-service'; export class ToolProvider extends ProviderBase { @@ -25,7 +26,8 @@ export class ToolProvider extends ProviderBase { private dataService: SpecmateDataService, private selectedElementService: SelectedElementService, private translate: TranslateService, - private rectService: MultiselectionService) { + private rectService: MultiselectionService, + private clipboardService: ClipboardService) { super(model); } @@ -50,7 +52,7 @@ export class ToolProvider extends ProviderBase { private createToolsForCEGModel(): void { this._tools = [ - new SelectTool(this.selectedElementService, this.dataService, this.rectService, this.model), + new SelectTool(this.selectedElementService, this.dataService, this.rectService, this.clipboardService, this.model), new CEGNodeTool(this.model, this.dataService, this.selectedElementService), new CEGConnectionTool(this.model, this.dataService, this.selectedElementService), new CEGDeleteTool(this.model, this.dataService, this.selectedElementService) @@ -59,7 +61,7 @@ export class ToolProvider extends ProviderBase { private createToolsForProcess(): void { this._tools = [ - new SelectTool(this.selectedElementService, this.dataService, this.rectService, this.model), + new SelectTool(this.selectedElementService, this.dataService, this.rectService, this.clipboardService, this.model), new StepTool(this.model, this.dataService, this.selectedElementService), new DecisionTool(this.model, this.dataService, this.selectedElementService), new StartTool(this.model, this.dataService, this.selectedElementService), diff --git a/web/src/app/modules/views/main/editors/modules/tool-pallette/services/clipboard-service.ts b/web/src/app/modules/views/main/editors/modules/tool-pallette/services/clipboard-service.ts new file mode 100644 index 000000000..38f268878 --- /dev/null +++ b/web/src/app/modules/views/main/editors/modules/tool-pallette/services/clipboard-service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { IContainer } from '../../../../../../../model/IContainer'; + +@Injectable() +export class ClipboardService { + + constructor() {} + + private static _clipboard: IContainer[] = []; + public get clipboard(): IContainer[] { + return ClipboardService._clipboard; + } + + public set clipboard(newClip: IContainer[]) { + if (!newClip) { + newClip = []; + } + ClipboardService._clipboard = newClip; + } + + public hasClipboard(): boolean { + return ClipboardService._clipboard.length > 0; + } +} diff --git a/web/src/app/modules/views/main/editors/modules/tool-pallette/services/editor-tools.service.ts b/web/src/app/modules/views/main/editors/modules/tool-pallette/services/editor-tools.service.ts index 0a6618085..fe86ad8fa 100644 --- a/web/src/app/modules/views/main/editors/modules/tool-pallette/services/editor-tools.service.ts +++ b/web/src/app/modules/views/main/editors/modules/tool-pallette/services/editor-tools.service.ts @@ -7,6 +7,7 @@ import { ToolProvider } from '../../graphical-editor/providers/properties/tool-p import { ToolBase } from '../tools/tool-base'; import { TranslateService } from '@ngx-translate/core'; import { MultiselectionService } from './multiselection.service'; +import { ClipboardService } from './clipboard-service'; @Injectable() @@ -23,7 +24,8 @@ export class EditorToolsService { private navigator: NavigatorService, private selectedElementService: SelectedElementService, private translate: TranslateService, - private rectService: MultiselectionService) { + private rectService: MultiselectionService, + private clipboardService: ClipboardService) { this.init(this.navigator.currentElement); this.navigator.hasNavigated.subscribe((model: IContainer) => this.init(model)); } @@ -45,7 +47,7 @@ export class EditorToolsService { } if (!this.providerMap[this.model.url]) { this.providerMap[this.model.url] = new ToolProvider(this.model, this.dataService, - this.selectedElementService, this.translate, this.rectService); + this.selectedElementService, this.translate, this.rectService, this.clipboardService); } return this.providerMap[this.model.url]; } diff --git a/web/src/app/modules/views/main/editors/modules/tool-pallette/tool-pallette.module.ts b/web/src/app/modules/views/main/editors/modules/tool-pallette/tool-pallette.module.ts index fd4fca422..ce91c5fe8 100644 --- a/web/src/app/modules/views/main/editors/modules/tool-pallette/tool-pallette.module.ts +++ b/web/src/app/modules/views/main/editors/modules/tool-pallette/tool-pallette.module.ts @@ -4,6 +4,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { EditorToolsService } from './services/editor-tools.service'; import { TranslateModule } from '@ngx-translate/core'; import { MultiselectionService } from './services/multiselection.service'; +import { ClipboardService } from './services/clipboard-service'; @NgModule({ imports: [ @@ -22,7 +23,8 @@ import { MultiselectionService } from './services/multiselection.service'; providers: [ // SERVICES EditorToolsService, - MultiselectionService + MultiselectionService, + ClipboardService ], bootstrap: [ // COMPONENTS THAT ARE BOOTSTRAPPED HERE diff --git a/web/src/app/modules/views/main/editors/modules/tool-pallette/tools/common/select-tool.ts b/web/src/app/modules/views/main/editors/modules/tool-pallette/tools/common/select-tool.ts index fab008984..ef37232a0 100644 --- a/web/src/app/modules/views/main/editors/modules/tool-pallette/tools/common/select-tool.ts +++ b/web/src/app/modules/views/main/editors/modules/tool-pallette/tools/common/select-tool.ts @@ -8,6 +8,7 @@ import { GraphTransformer } from '../../util/graphTransformer'; import { IDragAndDropTool } from '../IDragAndDropTool'; import { IKeyboardTool } from '../IKeyboardTool'; import { ToolBase } from '../tool-base'; +import { ClipboardService } from '../../services/clipboard-service'; export class SelectTool extends ToolBase implements IKeyboardTool, IDragAndDropTool { public icon = 'mouse-pointer'; @@ -19,6 +20,8 @@ export class SelectTool extends ToolBase implements IKeyboardTool, IDragAndDropT public sticky = false; + private static originType: string; + public activate() { this.selectedElements = []; } @@ -82,88 +85,70 @@ export class SelectTool extends ToolBase implements IKeyboardTool, IDragAndDropT if (ctrl && evt.key === 'c') { // Copy this.cancelEvent(evt); - this.copySelection(); + return this.copySelection(); } if (ctrl && evt.key === 'v') { // Paste this.cancelEvent(evt); - this.pasteSelection(); + return this.pasteSelection(); } if (ctrl && evt.key === 'x') { // Cut this.cancelEvent(evt); - this.cutSelection(); + return this.cutSelection(); } if (evt.keyCode === Key.BACKSPACE) { // Delete this.cancelEvent(evt); - this.deleteSelection(this.selectedElementService.selectedElements.slice()); + return this.deleteSelection(); } return Promise.resolve(); } - private static origin: IContainer; - private static cutFlag: boolean; - private static selection: IContainer[]; - - private copySelection(): void { - SelectTool.origin = this.model; - SelectTool.selection = this.selectedElementService.selectedElements.slice(); - SelectTool.cutFlag = false; + private async copySelection(): Promise { + // Copy Selection + SelectTool.originType = this.model.className; + let graphTransformer = new GraphTransformer(this.dataService, this.selectedElementService, this.model); + let sel = this.selectedElementService.selectedElements.slice(); + this.clipboardService.clipboard = await graphTransformer.cloneSubgraph(sel, Id.uuid, false); + return Promise.resolve(); } - private cutSelection(): void { - SelectTool.origin = this.model; - SelectTool.selection = this.selectedElementService.selectedElements.slice(); - SelectTool.cutFlag = true; + private cutSelection(): Promise { + return this.copySelection().then(() => this.deleteSelection()); } private async pasteSelection(): Promise { - if (!SelectTool.origin || !SelectTool.selection) { + if (!SelectTool.originType || !this.clipboardService.hasClipboard()) { // Nothing to paste return Promise.resolve(); } - if (SelectTool.origin === this.model && SelectTool.cutFlag) { - // Cut & Paste into the same model leaves the model the same - return Promise.resolve(); - } - let graphTransformer = new GraphTransformer(this.dataService, this.selectedElementService, this.model); let compoundId: string = Id.uuid; // Check Compatible Origin - if (this.model.className !== SelectTool.origin.className) { + if (this.model.className !== SelectTool.originType) { return Promise.resolve(); } - let newSelection = await graphTransformer.createSubgraph(SelectTool.selection, compoundId); - if (SelectTool.cutFlag) { - let oldTransformer = new GraphTransformer(this.dataService, this.selectedElementService, SelectTool.origin); - return oldTransformer.deleteAll(SelectTool.selection, compoundId); - } + let newSelection = await graphTransformer.cloneSubgraph(this.clipboardService.clipboard, compoundId, true); this.selectedElementService.selectedElements = newSelection; return Promise.resolve(); } - private deleteSelection(selection?: IContainer[]): Promise { - let tmpSel: IContainer[] = []; - if (selection) { - // Delete can be pressed after we have selected some other nodes so we have to safe the seleciton. - tmpSel = SelectTool.selection; - SelectTool.selection = selection; - } + private async deleteSelection(): Promise { let compoundId: string = Id.uuid; let graphTransformer = new GraphTransformer(this.dataService, this.selectedElementService, this.model); - let ret = graphTransformer.deleteAll(SelectTool.selection, compoundId); - SelectTool.selection = tmpSel; - return ret; + let selection = this.selectedElementService.selectedElements.slice(); + await graphTransformer.deleteAll(selection, compoundId); + return Promise.resolve(); } constructor(protected selectedElementService: SelectedElementService, private dataService: SpecmateDataService, - private rect: MultiselectionService, private model: IContainer) { + private rect: MultiselectionService, private clipboardService: ClipboardService, private model: IContainer) { super(selectedElementService); } } diff --git a/web/src/app/modules/views/main/editors/modules/tool-pallette/util/graphTransformer.ts b/web/src/app/modules/views/main/editors/modules/tool-pallette/util/graphTransformer.ts index f11b09383..7693bc524 100644 --- a/web/src/app/modules/views/main/editors/modules/tool-pallette/util/graphTransformer.ts +++ b/web/src/app/modules/views/main/editors/modules/tool-pallette/util/graphTransformer.ts @@ -1,16 +1,17 @@ -import { IContainer } from '../../../../../../../model/IContainer'; -import { ElementProvider } from '../../graphical-editor/providers/properties/element-provider'; -import { GraphElementFactorySelector } from '../../../../../../../factory/util/graph-element-factory-selector'; +import { GraphElementFactorySelector, Coords } from '../../../../../../../factory/util/graph-element-factory-selector'; import { IConnection } from '../../../../../../../model/IConnection'; -import { IModelNode } from '../../../../../../../model/IModelNode'; -import { SpecmateDataService } from '../../../../../../data/modules/data-service/services/specmate-data.service'; -import { SelectedElementService } from '../../../../../side/modules/selected-element/services/selected-element.service'; -import { Url } from '../../../../../../../util/url'; +import { IContainer } from '../../../../../../../model/IContainer'; import { IModelConnection } from '../../../../../../../model/IModelConnection'; +import { IModelNode } from '../../../../../../../model/IModelNode'; +import { ISpecmatePositionableModelObject } from '../../../../../../../model/ISpecmatePositionableModelObject'; +import { FieldMetaItem, MetaInfo } from '../../../../../../../model/meta/field-meta'; import { Proxy } from '../../../../../../../model/support/proxy'; import { Arrays } from '../../../../../../../util/arrays'; -import { Id } from '../../../../../../../util/id'; -import { MetaInfo, FieldMetaItem } from '../../../../../../../model/meta/field-meta'; +import { Url } from '../../../../../../../util/url'; +import { SpecmateDataService } from '../../../../../../data/modules/data-service/services/specmate-data.service'; +import { SelectedElementService } from '../../../../../side/modules/selected-element/services/selected-element.service'; +import { ElementProvider } from '../../graphical-editor/providers/properties/element-provider'; +import { Objects } from '../../../../../../../util/objects'; export class GraphTransformer { private elementProvider: ElementProvider; @@ -19,13 +20,20 @@ export class GraphTransformer { } // Delete - public deleteAll(elements: IContainer[], compoundId: string): Promise { - let chain = Promise.resolve(); + public async deleteAll(elements: IContainer[], compoundId: string): Promise { + await this.selectionService.deselectElements(elements); + // We have to delete connections first to avoid updating already deleted nodes. + for (const element of elements) { + if (this.elementProvider.isConnection(element)) { + await this.deleteElement(element, compoundId); + } + } for (const element of elements) { - chain = chain.then(() => this.deleteElement(element, compoundId)); + if (this.elementProvider.isNode(element)) { + await this.deleteElement(element, compoundId); + } } - chain.then(() => this.selectionService.deselectElements(elements)); - return chain; + return this.selectionService.deselectElements(elements); } private deleteElement(element: IContainer, compoundId: string): Promise { @@ -86,8 +94,15 @@ export class GraphTransformer { .then((target: IContainer) => this.dataService.updateElement(target, true, compoundId)); } - // Create a copy from the given templates in the current model. - public async createSubgraph(templates: IContainer[], compundId: string): Promise { + /** + * Clones a given list of elements (Nodes, Vertecies) and returns a promise for the copies + * If changeGraph is true, we use factory methods and commit the changes to the model + * This is used when you want to create new nodes/vertecies. + * + * If changeGraph is false, we only clone the objects without changing the model + * This is used when you only want to clone the data for later work. + */ + public async cloneSubgraph(templates: IContainer[], compoundId: string, changeGraph: boolean): Promise { let urlMap: {[old: string]: IModelNode} = {}; let out: IContainer[] = []; // Old URL -> New Node map @@ -95,11 +110,14 @@ export class GraphTransformer { if (this.elementProvider.isNode(template)) { let temp = template; let newCoord = { x: temp.x, y: temp.y + 100}; - let factory = GraphElementFactorySelector.getNodeFactory(template, newCoord, this.dataService); - let node = await factory.create(this.parent, false, compundId); - urlMap[template.url] = node; - this.transferData(temp, node); - await this.dataService.updateElement(node, true, compundId); + let node = await this.cloneNode(temp, newCoord, compoundId, changeGraph); + urlMap[template.url] = node; + node.incomingConnections = []; + node.outgoingConnections = []; + if (changeGraph) { + this.transferData(temp, node); + await this.updateElement(node, compoundId); + } out.push(node); } } @@ -111,10 +129,15 @@ export class GraphTransformer { if ((temp.target.url in urlMap) && (temp.source.url in urlMap)) { let source = urlMap[temp.source.url]; let target = urlMap[temp.target.url]; - let factory = GraphElementFactorySelector.getConnectionFactory(template, source, target, this.dataService); - let con = await factory.create(this.parent, false, compundId); - this.transferData(temp, con); - await this.dataService.updateElement(con, true, compundId); + let con = await this.cloneEdge(template, source, target, compoundId, changeGraph); + let conProxy = new Proxy(); + conProxy.url = con.url; + if (changeGraph) { + this.transferData(temp, con); + await this.updateElement(source, compoundId); + await this.updateElement(target, compoundId); + await this.updateElement(con, compoundId); + } out.push(con); } } @@ -122,6 +145,28 @@ export class GraphTransformer { return Promise.resolve(out); } + private cloneNode(template: IModelNode, coords: Coords, compoundId: string, createNode: boolean): + Promise { + if (!createNode) { + return Promise.resolve(Objects.clone(template)); + } + let factory = GraphElementFactorySelector.getNodeFactory(template, coords, this.dataService); + return factory.create(this.parent, false, compoundId); + } + + private cloneEdge(template: IContainer, newSource: IModelNode, newTarget: IModelNode, compoundId: string, createEdge: boolean): + Promise { + if (!createEdge) { + return Promise.resolve(Objects.clone(template)); + } + let factory = GraphElementFactorySelector.getConnectionFactory(template, newSource, newTarget, this.dataService); + return factory.create(this.parent, false, compoundId); + } + + private updateElement(element: IContainer, compoundId: string): Promise { + return this.dataService.updateElement(element, true, compoundId); + } + private transferData(from: IContainer, to: IContainer) { let fields: string[] = MetaInfo[from.className].map( (item: FieldMetaItem) => item.name); for (const field of fields) { diff --git a/web/src/app/util/objects.ts b/web/src/app/util/objects.ts index e8cf4565e..acc0e543d 100644 --- a/web/src/app/util/objects.ts +++ b/web/src/app/util/objects.ts @@ -14,7 +14,7 @@ export class Objects { actualTarget = Objects.getFreshInstance(source); } for (let name in source) { - if (!source[name]) { + if (!source.hasOwnProperty(name)) { continue; } actualTarget[name] = Objects.getFreshInstance(source[name]); From eecdcaeac84ab4e3961ae1f595690fe1ea191c31 Mon Sep 17 00:00:00 2001 From: Daedo Date: Mon, 22 Oct 2018 14:39:37 +0200 Subject: [PATCH 05/44] Fixed Typo --- .../graphical-editor/components/graphical-editor.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.html b/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.html index bdce96867..fd64e456b 100644 --- a/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.html +++ b/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.html @@ -46,7 +46,7 @@
{{name}} - --> + From bb56dacd67c0ac84531812eb7f37fe43a238dd9c Mon Sep 17 00:00:00 2001 From: Sebastian Eder Date: Tue, 23 Oct 2018 15:08:09 +0200 Subject: [PATCH 06/44] Retrying on empty requirements sources --- .../connectors/internal/ConnectorService.java | 13 +- .../src/com/specmate/scheduler/Scheduler.java | 179 +++++++++--------- 2 files changed, 105 insertions(+), 87 deletions(-) diff --git a/bundles/specmate-connectors/src/com/specmate/connectors/internal/ConnectorService.java b/bundles/specmate-connectors/src/com/specmate/connectors/internal/ConnectorService.java index 88c876493..eb907ff60 100644 --- a/bundles/specmate-connectors/src/com/specmate/connectors/internal/ConnectorService.java +++ b/bundles/specmate-connectors/src/com/specmate/connectors/internal/ConnectorService.java @@ -42,12 +42,23 @@ public void activate(Map properties) throws SpecmateValidationEx if (schedule == null) { return; } - + this.transaction = this.persistencyService.openTransaction(); new Thread(new Runnable() { @Override public void run() { + + // Ensure that requirements source are loaded. + while(requirementsSources.size() == 0) { + try { + logService.log(LogService.LOG_INFO, "No requirement sources here yet. Waiting."); + Thread.sleep(20 * 1000); + } catch (InterruptedException e) { + logService.log(LogService.LOG_ERROR, e.getMessage()); + } + } + SchedulerTask connectorRunnable = new ConnectorTask(requirementsSources, transaction, logService); connectorRunnable.run(); diff --git a/bundles/specmate-scheduler/src/com/specmate/scheduler/Scheduler.java b/bundles/specmate-scheduler/src/com/specmate/scheduler/Scheduler.java index ba2e5a9f8..4886caaa8 100644 --- a/bundles/specmate-scheduler/src/com/specmate/scheduler/Scheduler.java +++ b/bundles/specmate-scheduler/src/com/specmate/scheduler/Scheduler.java @@ -6,97 +6,104 @@ import com.specmate.scheduler.iterators.ScheduleIterator; - /** - * A facility for threads to schedule recurring tasks for future execution in a background thread. + * A facility for threads to schedule recurring tasks for future execution in a + * background thread. *

- * This class is thread-safe: multiple threads can share a single Scheduler object without the need for external synchronization. + * This class is thread-safe: multiple threads can share a single + * Scheduler object without the need for external synchronization. *

- * Implementation note: internally Scheduler uses a java.util.Timer to schedule tasks. + * Implementation note: internally Scheduler uses a + * java.util.Timer to schedule tasks. */ public class Scheduler { - class SchedulerTimerTask extends TimerTask { - - private SchedulerTask schedulerTask; - private ScheduleIterator iterator; - - public SchedulerTimerTask(SchedulerTask schedulerTask, - ScheduleIterator iterator) { - this.schedulerTask = schedulerTask; - this.iterator = iterator; - } - - public void run() { - try { - schedulerTask.run(); - } finally { - reschedule(schedulerTask, iterator); - } - } - } - - private final Timer timer = new Timer(); - - public Scheduler() { - } - -/** - * Terminates this Scheduler, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a scheduler has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it. - *

- * Note that calling this method from within the run method of a scheduler task that was invoked by this scheduler absolutely guarantees that the ongoing task execution is the last task execution that will ever be performed by this scheduler. - *

- * This method may be called repeatedly; the second and subsequent calls have no effect. - */ - - public void cancel() { - timer.cancel(); - } - -/** - * Schedules the specified task for execution according to the specified schedule. If times specified by the ScheduleIterator are in the past they are scheduled for immediate execution. - *

- * @param schedulerTask task to be scheduled - * @param iterator iterator that describes the schedule - * @throws IllegalStateException if task was already scheduled or cancelled, scheduler was cancelled, or scheduler thread terminated. - */ - - public void schedule(SchedulerTask schedulerTask, - ScheduleIterator iterator) { - - Date time = iterator.next(); - if (time == null) { - schedulerTask.cancel(); - } else { - synchronized(schedulerTask.lock) { - if (schedulerTask.state != SchedulerTask.VIRGIN) { - throw new IllegalStateException("Task already scheduled " + - "or cancelled"); - } - schedulerTask.state = SchedulerTask.SCHEDULED; - schedulerTask.timerTask = - new SchedulerTimerTask(schedulerTask, iterator); - timer.schedule(schedulerTask.timerTask, time); - } - } - } - - private void reschedule(SchedulerTask schedulerTask, - ScheduleIterator iterator) { - - Date time = iterator.next(); - if (time == null) { - schedulerTask.cancel(); - } else { - synchronized(schedulerTask.lock) { - if (schedulerTask.state != SchedulerTask.CANCELLED) { - schedulerTask.timerTask = - new SchedulerTimerTask(schedulerTask, iterator); - timer.schedule(schedulerTask.timerTask, time); - } - } - } - } + class SchedulerTimerTask extends TimerTask { + + private SchedulerTask schedulerTask; + private ScheduleIterator iterator; + + public SchedulerTimerTask(SchedulerTask schedulerTask, ScheduleIterator iterator) { + this.schedulerTask = schedulerTask; + this.iterator = iterator; + } + + public void run() { + try { + schedulerTask.run(); + } finally { + reschedule(schedulerTask, iterator); + } + } + } + + private final Timer timer = new Timer(); + + public Scheduler() { + } + + /** + * Terminates this Scheduler, discarding any currently + * scheduled tasks. Does not interfere with a currently executing task (if + * it exists). Once a scheduler has been terminated, its execution thread + * terminates gracefully, and no more tasks may be scheduled on it. + *

+ * Note that calling this method from within the run method of a scheduler + * task that was invoked by this scheduler absolutely guarantees that the + * ongoing task execution is the last task execution that will ever be + * performed by this scheduler. + *

+ * This method may be called repeatedly; the second and subsequent calls + * have no effect. + */ + public void cancel() { + timer.cancel(); + } + + /** + * Schedules the specified task for execution according to the specified + * schedule. If times specified by the ScheduleIterator are in + * the past they are scheduled for immediate execution. + *

+ * + * @param schedulerTask + * task to be scheduled + * @param iterator + * iterator that describes the schedule + * @throws IllegalStateException + * if task was already scheduled or cancelled, scheduler was + * cancelled, or scheduler thread terminated. + */ + public void schedule(SchedulerTask schedulerTask, ScheduleIterator iterator) { + + Date time = iterator.next(); + if (time == null) { + schedulerTask.cancel(); + } else { + synchronized (schedulerTask.lock) { + if (schedulerTask.state != SchedulerTask.VIRGIN) { + throw new IllegalStateException("Task already scheduled " + "or cancelled"); + } + schedulerTask.state = SchedulerTask.SCHEDULED; + schedulerTask.timerTask = new SchedulerTimerTask(schedulerTask, iterator); + timer.schedule(schedulerTask.timerTask, time); + } + } + } + + private void reschedule(SchedulerTask schedulerTask, ScheduleIterator iterator) { + + Date time = iterator.next(); + if (time == null) { + schedulerTask.cancel(); + } else { + synchronized (schedulerTask.lock) { + if (schedulerTask.state != SchedulerTask.CANCELLED) { + schedulerTask.timerTask = new SchedulerTimerTask(schedulerTask, iterator); + timer.schedule(schedulerTask.timerTask, time); + } + } + } + } } - From 56259358670fa4b2c3c4969862bda04359792e31 Mon Sep 17 00:00:00 2001 From: Amir Roosta <10849094+roostaamir@users.noreply.github.com> Date: Fri, 26 Oct 2018 14:00:26 +0200 Subject: [PATCH 07/44] Fix tool buttons being cut on small displays (#295) - Feature number 11 in the list (group 8) - This patch makes the toolbar buttons play more nicely with small displays and zoomed viewpots --- .../tool-pallette/components/tool-pallette.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/app/modules/views/main/editors/modules/tool-pallette/components/tool-pallette.component.html b/web/src/app/modules/views/main/editors/modules/tool-pallette/components/tool-pallette.component.html index d37624867..fe632caff 100644 --- a/web/src/app/modules/views/main/editors/modules/tool-pallette/components/tool-pallette.component.html +++ b/web/src/app/modules/views/main/editors/modules/tool-pallette/components/tool-pallette.component.html @@ -1,11 +1,11 @@

-   -
\ No newline at end of file From fc6ec8c4a99071b21c8f4fb55678133a71d043ca Mon Sep 17 00:00:00 2001 From: Sebastian Eder <23170307+sebeder@users.noreply.github.com> Date: Mon, 29 Oct 2018 04:27:30 +0100 Subject: [PATCH 08/44] Removing company details --- .../src/com/specmate/dummydata/DummyDataService.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/bundles/specmate-dummy-data/src/com/specmate/dummydata/DummyDataService.java b/bundles/specmate-dummy-data/src/com/specmate/dummydata/DummyDataService.java index 2e7cafc16..18f9f1adf 100644 --- a/bundles/specmate-dummy-data/src/com/specmate/dummydata/DummyDataService.java +++ b/bundles/specmate-dummy-data/src/com/specmate/dummydata/DummyDataService.java @@ -154,20 +154,18 @@ private void loadGenericTestData(Folder testFolder) { Requirement requirement1 = RequirementsFactory.eINSTANCE.createRequirement(); requirement1.setId("Requirement-1"); requirement1.setExtId("123"); - requirement1.setName("Zuschlag und Summenprüfung"); + requirement1.setName("Prüfung der Summe"); requirement1.setDescription( - "Das System ermöglicht die Suche nach Säumnis bzw. Prämienzuschlag wenn eine Einzelrechnung vorhanden ist, " - + "eine Reduktion gebucht wurde, und die Betragsart entweder SZ oder BZ ist. Eine Summenprüfung wird " - + "durchgeführt, falls eine Einzelabrechnung vorhanden ist."); + "Das ist die Beschreibung des Requirements."); requirement1.setImplementingBOTeam("Business Analysts"); requirement1.setImplementingITTeam("The IT Nerds"); - requirement1.setImplementingUnit("Allianz IT and Infrastructure"); + requirement1.setImplementingUnit("IT and Infrastructure"); requirement1.setNumberOfTests(4); requirement1.setPlannedRelease("Release 10 - Mount Everest"); requirement1.setStatus("In Progress"); requirement1.setTac("All tests must pass and the code is reviewed"); requirement1.setIsRegressionRequirement(true); - requirement1.setPlatform("ABS"); + requirement1.setPlatform("My Platform"); Requirement requirement2 = RequirementsFactory.eINSTANCE.createRequirement(); requirement2.setId("Requirement-2"); @@ -254,7 +252,7 @@ private void loadGenericTestData(Folder testFolder) { + "durchgeführt, falls eine Einzelabrechnung vorhanden ist."); requirement3.setImplementingBOTeam("Business Analysts"); requirement3.setImplementingITTeam("The IT Nerds"); - requirement3.setImplementingUnit("Allianz IT and Infrastructure"); + requirement3.setImplementingUnit("IT and Infrastructure"); requirement3.setNumberOfTests(4); requirement3.setPlannedRelease("Release 10 - Mount Everest"); requirement3.setStatus("In Progress"); From 3c90cd22c572188e4650d8de433a5213fbb64998 Mon Sep 17 00:00:00 2001 From: Fabian Stolp Date: Mon, 29 Oct 2018 21:26:07 +0100 Subject: [PATCH 09/44] Refactor changedFields function (#283) * first attempt * fixed the complexity and the length of the function and added some comments * some last changes, in the array type and a typo in boolean * fix typo * Fix indentation * Fix indentation --- web/src/app/util/objects.ts | 50 +++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/web/src/app/util/objects.ts b/web/src/app/util/objects.ts index acc0e543d..5f8954ec7 100644 --- a/web/src/app/util/objects.ts +++ b/web/src/app/util/objects.ts @@ -45,32 +45,17 @@ export class Objects { let changedFields: string[] = []; for (let field in o1) { if (!Objects.isObject(o1[field])) { - if (!Objects.fieldsEqualIgnoreBooleanStrings(o1[field], o2[field])) { + if (o2[field] && !Objects.fieldsEqualIgnoreBooleanStrings(o1[field], o2[field])) { changedFields.push(field); } } else if (Objects.isArray(o1[field])) { - if (o1[field].length !== o2[field].length) { + if (o2[field] && !Objects.areArraysEqual(o1[field], o2[field])) { changedFields.push(field); - continue; } - for (let i = 0; i < o1[field].length; i++) { - if (!Objects.fieldsEqualIgnoreBooleanStrings(o1[field][i], o2[field][i])) { - changedFields.push(field); - break; - } - } - } - } - for (let field in o1) { - if (!o2[field]) { - changedFields.push(field); - } - } - for (let field in o2) { - if (!o1[field]) { - changedFields.push(field); } } + Objects.pushTheNotMatchingFields(o1, o2, changedFields); + Objects.pushTheNotMatchingFields(o2, o1, changedFields); return changedFields; } @@ -83,6 +68,33 @@ export class Objects { } return p1 === p2; } + /** + *Return true if the 2 arrays contain the same elements. + */ + private static areArraysEqual(array1: Array, array2: Array): boolean { + if (array1.length !== array2.length) { + return false; + } + for (let i = 0; i < array1.length; i++) { + if (!Objects.fieldsEqualIgnoreBooleanStrings(array1[i], array2[i])) { + return false; + } + } + return true; + } + + /** + *It will go through all the fields from the first object and see if they + *are existing in the second object. The fields that are not matching will + *be pushed in the changedFields arrays. + */ + private static pushTheNotMatchingFields(object1: any, object2: any, changedFields: string[]) { + for (let field in object1) { + if (!object2[field]) { + changedFields.push(field); + } + } + } private static isBoolean(p: any): boolean { return p === true || p === false; From dcd764e450c0175bfceadbb663b064f0443f165b Mon Sep 17 00:00:00 2001 From: Michael Unterkalmsteiner Date: Tue, 30 Oct 2018 21:17:06 +0100 Subject: [PATCH 10/44] Persistency needs more time to startup on Travis (#326) --- .../src/com/specmate/migration/test/MigrationTestBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/specmate-migration-test/src/com/specmate/migration/test/MigrationTestBase.java b/bundles/specmate-migration-test/src/com/specmate/migration/test/MigrationTestBase.java index aa4df1a56..910e368dc 100644 --- a/bundles/specmate-migration-test/src/com/specmate/migration/test/MigrationTestBase.java +++ b/bundles/specmate-migration-test/src/com/specmate/migration/test/MigrationTestBase.java @@ -217,7 +217,7 @@ protected IPersistencyService getPersistencyService() throws SpecmateException { persistencyTracker.open(); IPersistencyService persistency; try { - persistency = persistencyTracker.waitForService(10000); + persistency = persistencyTracker.waitForService(20000); } catch (InterruptedException e) { throw new SpecmateException(e); } From 4c8a7634900ec921df2c77965925dd9c9b221fb0 Mon Sep 17 00:00:00 2001 From: sebeder <23170307+sebeder@users.noreply.github.com> Date: Tue, 6 Nov 2018 12:51:38 +0100 Subject: [PATCH 11/44] reusing ceg models (#325) * reusing ceg models * Enabling model copy for processes * Clearing clipboard after paste --- .../base/contents-container-base.ts | 54 ++++++++++++++++++- .../ceg-model-container.component.html | 32 ++++++++--- .../ceg-model-container.component.ts | 9 +++- .../components/folder-container.component.ts | 9 +++- .../process-model-container.component.html | 33 +++++++++--- .../process-model-container.component.ts | 9 +++- ...elated-requirements-container.component.ts | 14 ++--- ...est-specification-container.component.html | 2 +- .../test-specification-container.component.ts | 13 ++--- .../services/clipboard-service.ts | 4 ++ .../tool-pallette/util/graphTransformer.ts | 17 ++++-- web/src/app/util/objects.ts | 19 +++++++ web/src/assets/i18n/de.json | 4 ++ web/src/assets/i18n/gb.json | 4 ++ 14 files changed, 180 insertions(+), 43 deletions(-) diff --git a/web/src/app/modules/views/main/editors/modules/contents-container/base/contents-container-base.ts b/web/src/app/modules/views/main/editors/modules/contents-container/base/contents-container-base.ts index e88f249b9..6817d572a 100644 --- a/web/src/app/modules/views/main/editors/modules/contents-container/base/contents-container-base.ts +++ b/web/src/app/modules/views/main/editors/modules/contents-container/base/contents-container-base.ts @@ -4,7 +4,10 @@ import { TranslateService } from '@ngx-translate/core'; import { IContainer } from '../../../../../../../model/IContainer'; import { ConfirmationModal } from '../../../../../../notification/modules/modals/services/confirmation-modal.service'; import { Id } from '../../../../../../../util/id'; -import { OnInit, Input } from '@angular/core'; +import { OnInit, Input, Type } from '@angular/core'; +import { Objects } from '../../../../../../../util/objects'; +import { ClipboardService } from '../../tool-pallette/services/clipboard-service'; +import { GraphTransformer } from '../../tool-pallette/util/graphTransformer'; export abstract class ContentContainerBase implements OnInit { @@ -27,7 +30,8 @@ export abstract class ContentContainerBase implements OnIn protected dataService: SpecmateDataService, protected navigator: NavigatorService, protected translate: TranslateService, - protected modal: ConfirmationModal) { + protected modal: ConfirmationModal, + private clipboardService: ClipboardService) { } public async ngOnInit(): Promise { @@ -64,4 +68,50 @@ export abstract class ContentContainerBase implements OnIn const contents = await this.dataService.readContents(this.parent.url, false); this.contents = contents.filter(this.condition); } + + private get clipboardModel(): IContainer { + if (this.canPaste) { + return this.clipboardService.clipboard[0] as IContainer; + } + return undefined; + } + + public get clipboardModelName(): string { + if (this.canPaste) { + return this.clipboardModel.name; + } + return this.translate.instant('pasteAsName'); + } + + public async copy(model: IContainer): Promise { + const copy = Objects.clone(model) as IContainer; + copy.description = model.description; + copy.id = Id.uuid; + copy.name = this.translate.instant('copyOf') + ' ' + model.name; + this.clipboardService.clipboard = [copy]; + } + + public async paste(name: string): Promise { + if (!this.canPaste) { + return; + } + const model = this.clipboardModel; + const pasteName = name || this.clipboardModelName; + const copy = await this.createElement(pasteName); + copy.description = model.description; + + const contents = await this.dataService.readContents(model.url, true); + const transformer = new GraphTransformer(this.dataService, undefined, copy); + + const compoundId = Id.uuid; + await this.dataService.updateElement(copy, true, compoundId); + await transformer.cloneSubgraph(contents, compoundId, true); + await this.dataService.commit(this.translate.instant('paste')); + await this.readContents(); + this.clipboardService.clear(); + } + + public get canPaste(): boolean { + return this.clipboardService.clipboard.length === 1 && this.condition(this.clipboardService.clipboard[0]); + } } diff --git a/web/src/app/modules/views/main/editors/modules/contents-container/components/ceg-model-container.component.html b/web/src/app/modules/views/main/editors/modules/contents-container/components/ceg-model-container.component.html index f14fc7325..deb9ed970 100644 --- a/web/src/app/modules/views/main/editors/modules/contents-container/components/ceg-model-container.component.html +++ b/web/src/app/modules/views/main/editors/modules/contents-container/components/ceg-model-container.component.html @@ -20,13 +20,18 @@
{{'Cause-EffectModels' | translate}}
{{element.description | truncate: 60}} - - - + @@ -41,13 +46,24 @@
{{'Cause-EffectModels' | translate}}
-
+
+
+ +
+ +
+
+
\ No newline at end of file diff --git a/web/src/app/modules/views/main/editors/modules/contents-container/components/ceg-model-container.component.ts b/web/src/app/modules/views/main/editors/modules/contents-container/components/ceg-model-container.component.ts index f6db7cb04..d884385a6 100644 --- a/web/src/app/modules/views/main/editors/modules/contents-container/components/ceg-model-container.component.ts +++ b/web/src/app/modules/views/main/editors/modules/contents-container/components/ceg-model-container.component.ts @@ -10,6 +10,7 @@ import { NavigatorService } from '../../../../../../navigation/modules/navigator import { TranslateService } from '@ngx-translate/core'; import { ConfirmationModal } from '../../../../../../notification/modules/modals/services/confirmation-modal.service'; import { Id } from '../../../../../../../util/id'; +import { ClipboardService } from '../../tool-pallette/services/clipboard-service'; @Component({ moduleId: module.id.toString(), @@ -20,8 +21,12 @@ import { Id } from '../../../../../../../util/id'; export class CEGModelContainer extends ContentContainerBase { - constructor(dataService: SpecmateDataService, navigator: NavigatorService, translate: TranslateService, modal: ConfirmationModal) { - super(dataService, navigator, translate, modal); + constructor(dataService: SpecmateDataService, + navigator: NavigatorService, + translate: TranslateService, + modal: ConfirmationModal, + clipboardService: ClipboardService) { + super(dataService, navigator, translate, modal, clipboardService); } protected condition = (element: IContainer) => Type.is(element, CEGModel); diff --git a/web/src/app/modules/views/main/editors/modules/contents-container/components/folder-container.component.ts b/web/src/app/modules/views/main/editors/modules/contents-container/components/folder-container.component.ts index 29935adf4..3ae2bba06 100644 --- a/web/src/app/modules/views/main/editors/modules/contents-container/components/folder-container.component.ts +++ b/web/src/app/modules/views/main/editors/modules/contents-container/components/folder-container.component.ts @@ -9,6 +9,7 @@ import { ConfirmationModal } from '../../../../../../notification/modules/modals import { Id } from '../../../../../../../util/id'; import { Folder } from '../../../../../../../model/Folder'; import { FolderFactory } from '../../../../../../../factory/folder-factory'; +import { ClipboardService } from '../../tool-pallette/services/clipboard-service'; @Component({ moduleId: module.id.toString(), @@ -19,8 +20,12 @@ import { FolderFactory } from '../../../../../../../factory/folder-factory'; export class FolderContainer extends ContentContainerBase { - constructor(dataService: SpecmateDataService, navigator: NavigatorService, translate: TranslateService, modal: ConfirmationModal) { - super(dataService, navigator, translate, modal); + constructor(dataService: SpecmateDataService, + navigator: NavigatorService, + translate: TranslateService, + modal: ConfirmationModal, + clipboardService: ClipboardService) { + super(dataService, navigator, translate, modal, clipboardService); } protected condition = (element: IContainer) => Type.is(element, Folder); diff --git a/web/src/app/modules/views/main/editors/modules/contents-container/components/process-model-container.component.html b/web/src/app/modules/views/main/editors/modules/contents-container/components/process-model-container.component.html index b29d693a9..20e3455c9 100644 --- a/web/src/app/modules/views/main/editors/modules/contents-container/components/process-model-container.component.html +++ b/web/src/app/modules/views/main/editors/modules/contents-container/components/process-model-container.component.html @@ -20,13 +20,18 @@
{{'ProcessModels' | translate}}
{{element.description | truncate: 60}} - - - + @@ -41,13 +46,25 @@
{{'ProcessModels' | translate}}
-
+
+
+ +
+ +
+
+
\ No newline at end of file diff --git a/web/src/app/modules/views/main/editors/modules/contents-container/components/process-model-container.component.ts b/web/src/app/modules/views/main/editors/modules/contents-container/components/process-model-container.component.ts index abd631553..c4a573768 100644 --- a/web/src/app/modules/views/main/editors/modules/contents-container/components/process-model-container.component.ts +++ b/web/src/app/modules/views/main/editors/modules/contents-container/components/process-model-container.component.ts @@ -10,6 +10,7 @@ import { NavigatorService } from '../../../../../../navigation/modules/navigator import { TranslateService } from '@ngx-translate/core'; import { ConfirmationModal } from '../../../../../../notification/modules/modals/services/confirmation-modal.service'; import { Id } from '../../../../../../../util/id'; +import { ClipboardService } from '../../tool-pallette/services/clipboard-service'; @Component({ moduleId: module.id.toString(), @@ -20,8 +21,12 @@ import { Id } from '../../../../../../../util/id'; export class ProcessModelContainer extends ContentContainerBase { - constructor(dataService: SpecmateDataService, navigator: NavigatorService, translate: TranslateService, modal: ConfirmationModal) { - super(dataService, navigator, translate, modal); + constructor(dataService: SpecmateDataService, + navigator: NavigatorService, + translate: TranslateService, + modal: ConfirmationModal, + clipboardService: ClipboardService) { + super(dataService, navigator, translate, modal, clipboardService); } protected condition = (element: IContainer) => Type.is(element, Process); diff --git a/web/src/app/modules/views/main/editors/modules/contents-container/components/related-requirements-container.component.ts b/web/src/app/modules/views/main/editors/modules/contents-container/components/related-requirements-container.component.ts index 0e00f9a2b..e7a5f5152 100644 --- a/web/src/app/modules/views/main/editors/modules/contents-container/components/related-requirements-container.component.ts +++ b/web/src/app/modules/views/main/editors/modules/contents-container/components/related-requirements-container.component.ts @@ -1,17 +1,13 @@ import { Component, Input } from '@angular/core'; import { ContentContainerBase } from '../base/contents-container-base'; import { IContainer } from '../../../../../../../model/IContainer'; -import { ModelFactoryBase } from '../../../../../../../factory/model-factory-base'; -import { Type } from '../../../../../../../util/type'; -import { Process } from '../../../../../../../model/Process'; -import { ProcessFactory } from '../../../../../../../factory/process-factory'; import { SpecmateDataService } from '../../../../../../data/modules/data-service/services/specmate-data.service'; import { NavigatorService } from '../../../../../../navigation/modules/navigator/services/navigator.service'; import { TranslateService } from '@ngx-translate/core'; import { ConfirmationModal } from '../../../../../../notification/modules/modals/services/confirmation-modal.service'; -import { Id } from '../../../../../../../util/id'; import { Requirement } from '../../../../../../../model/Requirement'; import { Sort } from '../../../../../../../util/sort'; +import { ClipboardService } from '../../tool-pallette/services/clipboard-service'; @Component({ moduleId: module.id.toString(), @@ -22,8 +18,12 @@ import { Sort } from '../../../../../../../util/sort'; export class RelatedRequirementsContainer extends ContentContainerBase { - constructor(dataService: SpecmateDataService, navigator: NavigatorService, translate: TranslateService, modal: ConfirmationModal) { - super(dataService, navigator, translate, modal); + constructor(dataService: SpecmateDataService, + navigator: NavigatorService, + translate: TranslateService, + modal: ConfirmationModal, + clipboardService: ClipboardService) { + super(dataService, navigator, translate, modal, clipboardService); } protected condition = (element: IContainer) => true; diff --git a/web/src/app/modules/views/main/editors/modules/contents-container/components/test-specification-container.component.html b/web/src/app/modules/views/main/editors/modules/contents-container/components/test-specification-container.component.html index 09a6653cb..2c8d09666 100644 --- a/web/src/app/modules/views/main/editors/modules/contents-container/components/test-specification-container.component.html +++ b/web/src/app/modules/views/main/editors/modules/contents-container/components/test-specification-container.component.html @@ -22,7 +22,7 @@
{{'TestSpecifications' | translate}}
diff --git a/web/src/app/modules/actions/modules/export-testspecification-button/components/export-testspecification-button.component.ts b/web/src/app/modules/actions/modules/export-testspecification-button/components/export-testspecification-button.component.ts new file mode 100644 index 000000000..8a4b6b4d1 --- /dev/null +++ b/web/src/app/modules/actions/modules/export-testspecification-button/components/export-testspecification-button.component.ts @@ -0,0 +1,167 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { TestSpecification } from '../../../../../model/TestSpecification'; +import { TestCase } from '../../../../../model/TestCase'; +import { TestParameter } from '../../../../../model/TestParameter'; +import { ParameterAssignment } from '../../../../../model/ParameterAssignment'; +import { Url } from '../../../../../util/url'; +import { Type } from '../../../../../util/type'; +import { IContainer } from '../../../../../model/IContainer'; +import { SpecmateDataService } from '../../../../data/modules/data-service/services/specmate-data.service'; +import { ValidationService } from '../../../../forms/modules/validation/services/validation.service'; +import { TranslateService } from '@ngx-translate/core'; +import { AuthenticationService } from '../../../../views/main/authentication/modules/auth/services/authentication.service'; +import { AccessRights } from '../../../../../model/AccessRights'; +import { UserToken } from '../../../../views/main/authentication/base/user-token'; +import { saveAs } from 'file-saver'; + +@Component({ + moduleId: module.id.toString(), + selector: 'export-testspecification-button', + templateUrl: 'export-testspecification-button.component.html', + styleUrls: ['export-testspecification-button.component.css'] +}) + +export class ExportTestspecificationButton { + + @Input() + public testSpecification: TestSpecification; + + private contents: IContainer[]; + private testCases: TestCase[]; + private testParameters: TestParameter[]; + private parameterAssignments: ParameterAssignment[]; + private finalCsvString: string; + + constructor( + private dataService: SpecmateDataService, + private validation: ValidationService, + private translate: TranslateService, + private auth: AuthenticationService) { } + + // Export Function + public async exportTestSpecification(): Promise { + if (!this.enabled) { + return; + } + const contents = await this.dataService.readContents(this.testSpecification.url); + this.contents = contents; + await this.loadTestParameters(); + await this.loadTestCases(); + await Promise.all(this.loadParameterAssignments()); + this.prepareExportString(); + this.createDownloadFile(); + } + + private prepareExportString(): void { + this.pushHeaders(); + this.pushRows(); + } + + private pushHeaders(): void { + let header = 'Test Cases,'; + if (this.testParameters) { + for (let i = 0 ; i < this.testParameters.length ; i++) { + if (this.testParameters[i].type == 'INPUT') { + header += this.testParameters[i].type + ' - ' + this.testParameters[i].name + ', '; + } + } + for (let i = 0 ; i < this.testParameters.length ; i++) { + if (this.testParameters[i].type == 'OUTPUT') { + header += this.testParameters[i].type + ' - ' + this.testParameters[i].name + ', '; + } + } + } + header += '\n'; + this.finalCsvString = header; + } + + private pushRows(): void { + let testCasesString = ''; + if (this.testCases) { + for (let i = 0 ; i < this.testCases.length ; i++) { + testCasesString += this.testCases[i].name + ', '; + for (let j = 0 ; j < this.testParameters.length; j++) { + let assignmentsList = this.getAssignments(this.testParameters[j]); + for (let k = 0 ; k < assignmentsList.length; k++) { + if (Url.parent(assignmentsList[k].url) == this.testCases[i].url) { + testCasesString += assignmentsList[k].condition + ', '; + break; + } + } + } + testCasesString += '\n'; + } + } + this.finalCsvString += testCasesString; + } + private getAssignments(testParameter: TestParameter): ParameterAssignment[] { + let assignmentsList: ParameterAssignment[]; + assignmentsList = []; + for (let i = 0 ; i < this.parameterAssignments.length; i++) { + if (this.parameterAssignments[i].parameter.url == testParameter.url) { + assignmentsList.push(this.parameterAssignments[i]); + } + } + return assignmentsList; + } + + private loadTestCases(): void { + this.testCases = this.contents.filter((element: IContainer) => Type.is(element, TestCase)) + .map((element: IContainer) => element as TestCase); + } + + private loadTestParameters(): Promise { + let loadTestParametersTask: Promise = Promise.resolve(); + loadTestParametersTask = loadTestParametersTask.then(() => { + this.testParameters = this.contents.filter((element: IContainer) => Type.is(element, TestParameter)) + .map((element: IContainer) => element as TestParameter); + }); + return loadTestParametersTask; + } + + private loadParameterAssignments(): Promise[] { + let testCases: TestCase[] = this.testCases; + this.parameterAssignments = []; + let promiseArray: Promise[]; + promiseArray = []; + + let loadParameterAssignmentsTask: Promise = Promise.resolve(); + for (let i = 0; i < testCases.length; i++) { + let currentTestCase: TestCase = testCases[i]; + loadParameterAssignmentsTask = loadParameterAssignmentsTask.then(() => { + return this.dataService.readContents(currentTestCase.url) + .then((contents: IContainer[]) => + contents.forEach((element: IContainer) => { + if (element.className == 'ParameterAssignment') { + this.parameterAssignments.push(element as ParameterAssignment); + } + })); + }); + promiseArray.push(loadParameterAssignmentsTask); + } + return promiseArray; + } + + private createDownloadFile(): void { + const blob = new Blob(['\ufeff', this.finalCsvString], { type: 'text/csv;charset=utf-8;' }); + saveAs(blob, this.testSpecification.name + '.csv'); + } + + public get buttonTitle(): string { + if (!this.isValid()) { + return 'specificationNotValid'; + } + return 'exportTestspecification'; + } + + public get enabled(): boolean { + return this.isValid(); + } + + private isValid(): boolean { + if (this.testSpecification === undefined) { + return false; + } + return this.validation.isValid(this.testSpecification, this.contents); + } +} diff --git a/web/src/app/modules/actions/modules/export-testspecification-button/export-testspecification-button.module.ts b/web/src/app/modules/actions/modules/export-testspecification-button/export-testspecification-button.module.ts new file mode 100644 index 000000000..75f2789ae --- /dev/null +++ b/web/src/app/modules/actions/modules/export-testspecification-button/export-testspecification-button.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { ExportTestspecificationButton } from './components/export-testspecification-button.component'; +import { BrowserModule } from '@angular/platform-browser'; +import { TranslateModule } from '@ngx-translate/core'; + +@NgModule({ + imports: [ + // MODULE IMPORTS + BrowserModule, + TranslateModule + ], + declarations: [ + // COMPONENTS IN THIS MODULE + ExportTestspecificationButton + ], + exports: [ + // THE COMPONENTS VISIBLE TO THE OUTSIDE + ExportTestspecificationButton + ], + providers: [ + // SERVICES + ], + bootstrap: [ + // COMPONENTS THAT ARE BOOTSTRAPPED HERE + ] +}) + +export class ExportTestspecificationButtonModule { } diff --git a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html index d07ef66ed..ccd951bdc 100644 --- a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html +++ b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html @@ -22,6 +22,9 @@
+
+ +
diff --git a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.ts b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.ts index 294225207..f434afb35 100644 --- a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.ts +++ b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.ts @@ -60,6 +60,10 @@ export class LinksActions { return this.additionalInformationService.canExportTestprocedure; } + public get canExportTestspecification(): boolean { + return this.additionalInformationService.canExportTestspecification; + } + public toggleDescription() { this.descriptionVisible = !this.descriptionVisible; } diff --git a/web/src/app/modules/views/side/modules/links-actions/links-actions.module.ts b/web/src/app/modules/views/side/modules/links-actions/links-actions.module.ts index 04c60e809..f1fdcc1b9 100644 --- a/web/src/app/modules/views/side/modules/links-actions/links-actions.module.ts +++ b/web/src/app/modules/views/side/modules/links-actions/links-actions.module.ts @@ -6,6 +6,8 @@ import { TestSpecificationGeneratorButtonModule } from '../../../../actions/modules/test-specification-generator-button/test-specification-generator-button.module'; import { ExportTestprocedureButtonModule } from '../../../../actions/modules/export-testprocedure-button/export-testprocedure-button.module'; +import { ExportTestspecificationButtonModule } from + '../../../../actions/modules/export-testspecification-button/export-testspecification-button.module'; import { AdditionalInformationService } from './services/additional-information.service'; import { TranslateModule } from '@ngx-translate/core'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @@ -18,6 +20,7 @@ import { AuthModule } from '../../../main/authentication/modules/auth/auth.modul NavigatorModule, TestSpecificationGeneratorButtonModule, ExportTestprocedureButtonModule, + ExportTestspecificationButtonModule, TranslateModule, AuthModule, NgbModule.forRoot() diff --git a/web/src/app/modules/views/side/modules/links-actions/services/additional-information.service.ts b/web/src/app/modules/views/side/modules/links-actions/services/additional-information.service.ts index 1fde9787a..892682ab1 100644 --- a/web/src/app/modules/views/side/modules/links-actions/services/additional-information.service.ts +++ b/web/src/app/modules/views/side/modules/links-actions/services/additional-information.service.ts @@ -127,6 +127,10 @@ export class AdditionalInformationService { return Type.is(this.element, TestProcedure); } + public get canExportTestspecification(): boolean { + return Type.is(this.element, TestSpecification); + } + private isModel(element: IContainer): boolean { return Type.is(element, CEGModel) || Type.is(element, Process); } diff --git a/web/src/assets/i18n/de.json b/web/src/assets/i18n/de.json index 82f0c8c1f..af9322312 100644 --- a/web/src/assets/i18n/de.json +++ b/web/src/assets/i18n/de.json @@ -91,6 +91,7 @@ "errorLoggedOut": "Sie wurden aufgrund eines unbekannten Fehlers abgemeldet.", "expand": "", "exportTestprocedure": "Testprozedur exportieren", + "exportTestspecification": "Testspezifikation exportieren", "failed": "Fehler", "fieldInvalid": "Feld ungültig", "hideGrid": "Hilfslinien ausblenden", @@ -159,6 +160,7 @@ "showGrid": "Hilfslinien anzeigen", "showLog": "Log anzeigen", "sorrySuggestionsCouldNotBeLoaded": "Vorschläge konnten leider nicht geladen werden", + "specificationNotValid": "Spezifikation nicht gültig", "specmate": { "logo": "Specmate Logo" }, diff --git a/web/src/assets/i18n/gb.json b/web/src/assets/i18n/gb.json index 5653ad044..0ec82192f 100644 --- a/web/src/assets/i18n/gb.json +++ b/web/src/assets/i18n/gb.json @@ -90,6 +90,7 @@ "errorLoggedOut": "You were logged out due to an unknown error.", "expand": "", "exportTestprocedure": "Export test procedure", + "exportTestspecification": "Export test specification", "failed": "Failed", "fieldInvalid": "Field invalid", "hideGrid": "Hide grid", @@ -158,6 +159,7 @@ "showGrid": "Show grid", "showLog": "Show log", "sorrySuggestionsCouldNotBeLoaded": "Sorry, suggestions could not be loaded", + "specificationNotValid": "Specification not valid", "specmate": { "logo": "Specmate Emblem" }, From c4574fd94b9d081bd6b2894900197efa2ccde177 Mon Sep 17 00:00:00 2001 From: Michael Unterkalmsteiner Date: Fri, 9 Nov 2018 16:17:44 +0100 Subject: [PATCH 17/44] Testspec skeleton generation (#332) * MVP * Better naming * Model changes for testspec skeleton * Test skeleton generators for java and javascript * Fix review comments * Minor styling --- .../internal/services/Migrator20180925.java | 50 ++++ .../specmate-model-ecore/model/specmate.ecore | 21 +- .../model/specmate.history | 64 ++++- bundles/specmate-model-ecore/model/user.ecore | 2 +- .../specmate-model-ecore/model/user.history | 7 +- bundles/specmate-model-gen/build.properties | 1 - .../administration/AdministrationPackage.java | 2 +- .../com/specmate/model/base/BasePackage.java | 2 +- .../specmate/model/batch/BatchPackage.java | 2 +- .../model/history/HistoryPackage.java | 2 +- .../model/processes/ProcessesPackage.java | 2 +- .../requirements/RequirementsPackage.java | 2 +- .../TestSpecificationSkeleton.java | 78 +++++++ .../TestspecificationFactory.java | 9 + .../TestspecificationPackage.java | 127 +++++++++- .../impl/TestSpecificationSkeletonImpl.java | 221 ++++++++++++++++++ .../impl/TestspecificationFactoryImpl.java | 11 + .../impl/TestspecificationPackageImpl.java | 44 ++++ .../util/TestspecificationAdapterFactory.java | 18 ++ .../util/TestspecificationSwitch.java | 22 ++ .../specmate/usermodel/UsermodelPackage.java | 2 +- .../src/com/specmate/rest/RestResult.java | 4 + bundles/specmate-testspecification/bnd.bnd | 4 +- .../TestSkeletonGeneratorService.java | 70 ++++++ .../internal/testskeleton/BaseSkeleton.java | 82 +++++++ .../JavaTestSpecificationSkeleton.java | 50 ++++ .../JavascriptTestSpecificationSkeleton.java | 43 ++++ web/src/app/model/BatchOperation.ts | 2 +- web/src/app/model/CEGConnection.ts | 2 +- web/src/app/model/CEGModel.ts | 2 +- web/src/app/model/CEGNode.ts | 2 +- web/src/app/model/Change.ts | 2 +- web/src/app/model/Folder.ts | 2 +- web/src/app/model/History.ts | 2 +- web/src/app/model/HistoryEntry.ts | 4 +- web/src/app/model/IExternal.ts | 2 +- web/src/app/model/IModelConnection.ts | 2 +- web/src/app/model/IModelNode.ts | 2 +- web/src/app/model/ITracingElement.ts | 2 +- web/src/app/model/Operation.ts | 2 +- web/src/app/model/ParameterAssignment.ts | 2 +- web/src/app/model/Process.ts | 2 +- web/src/app/model/ProcessConnection.ts | 2 +- web/src/app/model/ProcessDecision.ts | 2 +- web/src/app/model/ProcessEnd.ts | 2 +- web/src/app/model/ProcessNode.ts | 2 +- web/src/app/model/ProcessStart.ts | 2 +- web/src/app/model/ProcessStep.ts | 2 +- web/src/app/model/Requirement.ts | 2 +- web/src/app/model/Status.ts | 2 +- web/src/app/model/TestCase.ts | 2 +- web/src/app/model/TestParameter.ts | 2 +- web/src/app/model/TestProcedure.ts | 2 +- web/src/app/model/TestSpecification.ts | 2 +- .../app/model/TestSpecificationSkeleton.ts | 23 ++ web/src/app/model/TestStep.ts | 2 +- web/src/app/model/User.ts | 2 +- web/src/app/model/UserSession.ts | 3 +- web/src/app/model/meta/field-meta.ts | 9 + ...pecification-skeleton-button.component.css | 4 + ...ecification-skeleton-button.component.html | 1 + ...specification-skeleton-button.component.ts | 64 +++++ ...st-specification-skeleton-button.module.ts | 28 +++ .../login/components/login.component.html | 2 +- .../components/links-actions.component.html | 29 ++- .../links-actions/links-actions.module.ts | 3 + web/src/assets/i18n/de.json | 3 +- web/src/assets/i18n/gb.json | 3 +- 68 files changed, 1102 insertions(+), 72 deletions(-) create mode 100644 bundles/specmate-migration/src/com/specmate/migration/internal/services/Migrator20180925.java create mode 100644 bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestSpecificationSkeleton.java create mode 100644 bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestSpecificationSkeletonImpl.java create mode 100644 bundles/specmate-testspecification/src/com/specmate/testspecification/internal/services/TestSkeletonGeneratorService.java create mode 100644 bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/BaseSkeleton.java create mode 100644 bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavaTestSpecificationSkeleton.java create mode 100644 bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavascriptTestSpecificationSkeleton.java create mode 100644 web/src/app/model/TestSpecificationSkeleton.ts create mode 100644 web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.css create mode 100644 web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.html create mode 100644 web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.ts create mode 100644 web/src/app/modules/actions/modules/get-test-specification-skeleton-button/get-test-specification-skeleton-button.module.ts diff --git a/bundles/specmate-migration/src/com/specmate/migration/internal/services/Migrator20180925.java b/bundles/specmate-migration/src/com/specmate/migration/internal/services/Migrator20180925.java new file mode 100644 index 000000000..71e614321 --- /dev/null +++ b/bundles/specmate-migration/src/com/specmate/migration/internal/services/Migrator20180925.java @@ -0,0 +1,50 @@ +package com.specmate.migration.internal.services; + +import java.sql.Connection; + +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +import com.specmate.common.SpecmateException; +import com.specmate.dbprovider.api.IDBProvider; +import com.specmate.dbprovider.api.migration.IAttributeToSQLMapper; +import com.specmate.dbprovider.api.migration.IObjectToSQLMapper; +import com.specmate.migration.api.IMigrator; + +@Component(property = "sourceVersion=20180925", service = IMigrator.class) +public class Migrator20180925 implements IMigrator { + + private IDBProvider dbProvider; + + @Override + public String getSourceVersion() { + return "20180925"; + } + + @Override + public String getTargetVersion() { + return "20181108"; + } + + @Override + public void migrate(Connection connection) throws SpecmateException { + String objectName = "TestSpecificationSkeleton"; + String packageName = "model/testspecification"; + IObjectToSQLMapper oMapper = dbProvider.getObjectToSQLMapper(packageName, getSourceVersion(), + getTargetVersion()); + + oMapper.newObject(objectName); + + IAttributeToSQLMapper aMapper = dbProvider.getAttributeToSQLMapper(packageName, getSourceVersion(), + getTargetVersion()); + aMapper.migrateNewStringAttribute(objectName, "name", ""); + // "language" seems to be a reserved term, hence CDO uses "language0" + aMapper.migrateNewStringAttribute(objectName, "language0", ""); + aMapper.migrateNewStringAttribute(objectName, "code", ""); + } + + @Reference + public void setDBProvider(IDBProvider dbProvider) { + this.dbProvider = dbProvider; + } +} diff --git a/bundles/specmate-model-ecore/model/specmate.ecore b/bundles/specmate-model-ecore/model/specmate.ecore index 2e79b1daa..fd57edef7 100644 --- a/bundles/specmate-model-ecore/model/specmate.ecore +++ b/bundles/specmate-model-ecore/model/specmate.ecore @@ -1,7 +1,7 @@ - + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="model" nsURI="http://specmate.com/20181108/model" nsPrefix="com.specmate.model"> + @@ -71,7 +71,7 @@ eType="#//base/ITracingElement" eOpposite="#//base/ITracingElement/tracesTo"/> - @@ -135,9 +135,14 @@ - + + + + - @@ -205,7 +210,7 @@ - - - + diff --git a/bundles/specmate-model-ecore/model/specmate.history b/bundles/specmate-model-ecore/model/specmate.history index 4d9cd39c1..84cdbab14 100644 --- a/bundles/specmate-model-ecore/model/specmate.history +++ b/bundles/specmate-model-ecore/model/specmate.history @@ -2193,8 +2193,6 @@ - - @@ -2282,4 +2280,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/specmate-model-ecore/model/user.ecore b/bundles/specmate-model-ecore/model/user.ecore index 142dfe9ad..1ba01660b 100644 --- a/bundles/specmate-model-ecore/model/user.ecore +++ b/bundles/specmate-model-ecore/model/user.ecore @@ -1,6 +1,6 @@ + xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="usermodel" nsURI="http://specmate.com/20181108/model/user" nsPrefix="com.specmate.model"> diff --git a/bundles/specmate-model-ecore/model/user.history b/bundles/specmate-model-ecore/model/user.history index f71792978..0e1d1df4b 100644 --- a/bundles/specmate-model-ecore/model/user.history +++ b/bundles/specmate-model-ecore/model/user.history @@ -312,5 +312,10 @@ - + + + + + + diff --git a/bundles/specmate-model-gen/build.properties b/bundles/specmate-model-gen/build.properties index fb7b5b415..612d368cd 100644 --- a/bundles/specmate-model-gen/build.properties +++ b/bundles/specmate-model-gen/build.properties @@ -2,7 +2,6 @@ bin.includes = specmate-model-gen.jar,\ model/,\ - icons/,\ plugin.xml,\ plugin.properties jars.compile.order = specmate-model-gen.jar diff --git a/bundles/specmate-model-gen/src/com/specmate/model/administration/AdministrationPackage.java b/bundles/specmate-model-gen/src/com/specmate/model/administration/AdministrationPackage.java index 4154f9450..f9eaa2356 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/administration/AdministrationPackage.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/administration/AdministrationPackage.java @@ -37,7 +37,7 @@ public interface AdministrationPackage extends EPackage { * * @generated */ - String eNS_URI = "http://specmate.com/20180925/model/administration"; + String eNS_URI = "http://specmate.com/20181108/model/administration"; /** * The package namespace name. diff --git a/bundles/specmate-model-gen/src/com/specmate/model/base/BasePackage.java b/bundles/specmate-model-gen/src/com/specmate/model/base/BasePackage.java index 53b22a066..413f679a1 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/base/BasePackage.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/base/BasePackage.java @@ -38,7 +38,7 @@ public interface BasePackage extends EPackage { * * @generated */ - String eNS_URI = "http://specmate.com/20180925/model/base"; + String eNS_URI = "http://specmate.com/20181108/model/base"; /** * The package namespace name. diff --git a/bundles/specmate-model-gen/src/com/specmate/model/batch/BatchPackage.java b/bundles/specmate-model-gen/src/com/specmate/model/batch/BatchPackage.java index 6478527c5..89f089447 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/batch/BatchPackage.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/batch/BatchPackage.java @@ -39,7 +39,7 @@ public interface BatchPackage extends EPackage { * * @generated */ - String eNS_URI = "http://specmate.com/20180925/model/batch"; + String eNS_URI = "http://specmate.com/20181108/model/batch"; /** * The package namespace name. diff --git a/bundles/specmate-model-gen/src/com/specmate/model/history/HistoryPackage.java b/bundles/specmate-model-gen/src/com/specmate/model/history/HistoryPackage.java index 933c80912..b61cf55ae 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/history/HistoryPackage.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/history/HistoryPackage.java @@ -38,7 +38,7 @@ public interface HistoryPackage extends EPackage { * * @generated */ - String eNS_URI = "http://specmate.com/20180925/model/history"; + String eNS_URI = "http://specmate.com/20181108/model/history"; /** * The package namespace name. diff --git a/bundles/specmate-model-gen/src/com/specmate/model/processes/ProcessesPackage.java b/bundles/specmate-model-gen/src/com/specmate/model/processes/ProcessesPackage.java index e381675b2..a9689e3ec 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/processes/ProcessesPackage.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/processes/ProcessesPackage.java @@ -39,7 +39,7 @@ public interface ProcessesPackage extends EPackage { * * @generated */ - String eNS_URI = "http://specmate.com/20180925/model/processes"; + String eNS_URI = "http://specmate.com/20181108/model/processes"; /** * The package namespace name. diff --git a/bundles/specmate-model-gen/src/com/specmate/model/requirements/RequirementsPackage.java b/bundles/specmate-model-gen/src/com/specmate/model/requirements/RequirementsPackage.java index 402548068..35943bbae 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/requirements/RequirementsPackage.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/requirements/RequirementsPackage.java @@ -40,7 +40,7 @@ public interface RequirementsPackage extends EPackage { * * @generated */ - String eNS_URI = "http://specmate.com/20180925/model/requirements"; + String eNS_URI = "http://specmate.com/20181108/model/requirements"; /** * The package namespace name. diff --git a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestSpecificationSkeleton.java b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestSpecificationSkeleton.java new file mode 100644 index 000000000..a9906f988 --- /dev/null +++ b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestSpecificationSkeleton.java @@ -0,0 +1,78 @@ +/** + */ +package com.specmate.model.testspecification; + +import com.specmate.model.base.INamed; + +/** + * + * A representation of the model object 'Test Specification Skeleton'. + * + * + *

+ * The following features are supported: + *

+ *
    + *
  • {@link com.specmate.model.testspecification.TestSpecificationSkeleton#getLanguage Language}
  • + *
  • {@link com.specmate.model.testspecification.TestSpecificationSkeleton#getCode Code}
  • + *
+ * + * @see com.specmate.model.testspecification.TestspecificationPackage#getTestSpecificationSkeleton() + * @model + * @generated + */ +public interface TestSpecificationSkeleton extends INamed { + /** + * Returns the value of the 'Language' attribute. + * The default value is "". + * + *

+ * If the meaning of the 'Language' attribute isn't clear, + * there really should be more of a description here... + *

+ * + * @return the value of the 'Language' attribute. + * @see #setLanguage(String) + * @see com.specmate.model.testspecification.TestspecificationPackage#getTestSpecificationSkeleton_Language() + * @model default="" + * @generated + */ + String getLanguage(); + + /** + * Sets the value of the '{@link com.specmate.model.testspecification.TestSpecificationSkeleton#getLanguage Language}' attribute. + * + * + * @param value the new value of the 'Language' attribute. + * @see #getLanguage() + * @generated + */ + void setLanguage(String value); + + /** + * Returns the value of the 'Code' attribute. + * + *

+ * If the meaning of the 'Code' attribute isn't clear, + * there really should be more of a description here... + *

+ * + * @return the value of the 'Code' attribute. + * @see #setCode(String) + * @see com.specmate.model.testspecification.TestspecificationPackage#getTestSpecificationSkeleton_Code() + * @model + * @generated + */ + String getCode(); + + /** + * Sets the value of the '{@link com.specmate.model.testspecification.TestSpecificationSkeleton#getCode Code}' attribute. + * + * + * @param value the new value of the 'Code' attribute. + * @see #getCode() + * @generated + */ + void setCode(String value); + +} // TestSpecificationSkeleton diff --git a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestspecificationFactory.java b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestspecificationFactory.java index c83e1d005..8c5b3ca59 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestspecificationFactory.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestspecificationFactory.java @@ -30,6 +30,15 @@ public interface TestspecificationFactory extends EFactory { */ TestSpecification createTestSpecification(); + /** + * Returns a new object of class 'Test Specification Skeleton'. + * + * + * @return a new object of class 'Test Specification Skeleton'. + * @generated + */ + TestSpecificationSkeleton createTestSpecificationSkeleton(); + /** * Returns a new object of class 'Test Parameter'. * diff --git a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestspecificationPackage.java b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestspecificationPackage.java index 95dcfc041..b5cc56a57 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestspecificationPackage.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/TestspecificationPackage.java @@ -41,7 +41,7 @@ public interface TestspecificationPackage extends EPackage { * * @generated */ - String eNS_URI = "http://specmate.com/20180925/model/testspecification"; + String eNS_URI = "http://specmate.com/20181108/model/testspecification"; /** * The package namespace name. @@ -123,6 +123,61 @@ public interface TestspecificationPackage extends EPackage { */ int TEST_SPECIFICATION_OPERATION_COUNT = BasePackage.ICONTAINER_OPERATION_COUNT + 0; + /** + * The meta object id for the '{@link com.specmate.model.testspecification.impl.TestSpecificationSkeletonImpl Test Specification Skeleton}' class. + * + * + * @see com.specmate.model.testspecification.impl.TestSpecificationSkeletonImpl + * @see com.specmate.model.testspecification.impl.TestspecificationPackageImpl#getTestSpecificationSkeleton() + * @generated + */ + int TEST_SPECIFICATION_SKELETON = 1; + + /** + * The feature id for the 'Name' attribute. + * + * + * @generated + * @ordered + */ + int TEST_SPECIFICATION_SKELETON__NAME = BasePackage.INAMED__NAME; + + /** + * The feature id for the 'Language' attribute. + * + * + * @generated + * @ordered + */ + int TEST_SPECIFICATION_SKELETON__LANGUAGE = BasePackage.INAMED_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Code' attribute. + * + * + * @generated + * @ordered + */ + int TEST_SPECIFICATION_SKELETON__CODE = BasePackage.INAMED_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'Test Specification Skeleton' class. + * + * + * @generated + * @ordered + */ + int TEST_SPECIFICATION_SKELETON_FEATURE_COUNT = BasePackage.INAMED_FEATURE_COUNT + 2; + + /** + * The number of operations of the 'Test Specification Skeleton' class. + * + * + * @generated + * @ordered + */ + int TEST_SPECIFICATION_SKELETON_OPERATION_COUNT = BasePackage.INAMED_OPERATION_COUNT + 0; + /** * The meta object id for the '{@link com.specmate.model.testspecification.impl.TestParameterImpl Test Parameter}' class. * @@ -131,7 +186,7 @@ public interface TestspecificationPackage extends EPackage { * @see com.specmate.model.testspecification.impl.TestspecificationPackageImpl#getTestParameter() * @generated */ - int TEST_PARAMETER = 1; + int TEST_PARAMETER = 2; /** * The feature id for the 'Id' attribute. @@ -204,7 +259,7 @@ public interface TestspecificationPackage extends EPackage { * @see com.specmate.model.testspecification.impl.TestspecificationPackageImpl#getTestCase() * @generated */ - int TEST_CASE = 2; + int TEST_CASE = 3; /** * The feature id for the 'Id' attribute. @@ -286,7 +341,7 @@ public interface TestspecificationPackage extends EPackage { * @see com.specmate.model.testspecification.impl.TestspecificationPackageImpl#getParameterAssignment() * @generated */ - int PARAMETER_ASSIGNMENT = 3; + int PARAMETER_ASSIGNMENT = 4; /** * The feature id for the 'Id' attribute. @@ -368,7 +423,7 @@ public interface TestspecificationPackage extends EPackage { * @see com.specmate.model.testspecification.impl.TestspecificationPackageImpl#getTestProcedure() * @generated */ - int TEST_PROCEDURE = 4; + int TEST_PROCEDURE = 5; /** * The feature id for the 'Id' attribute. @@ -477,7 +532,7 @@ public interface TestspecificationPackage extends EPackage { * @see com.specmate.model.testspecification.impl.TestspecificationPackageImpl#getTestStep() * @generated */ - int TEST_STEP = 5; + int TEST_STEP = 6; /** * The feature id for the 'Id' attribute. @@ -559,7 +614,7 @@ public interface TestspecificationPackage extends EPackage { * @see com.specmate.model.testspecification.impl.TestspecificationPackageImpl#getParameterType() * @generated */ - int PARAMETER_TYPE = 6; + int PARAMETER_TYPE = 7; /** @@ -572,6 +627,38 @@ public interface TestspecificationPackage extends EPackage { */ EClass getTestSpecification(); + /** + * Returns the meta object for class '{@link com.specmate.model.testspecification.TestSpecificationSkeleton Test Specification Skeleton}'. + * + * + * @return the meta object for class 'Test Specification Skeleton'. + * @see com.specmate.model.testspecification.TestSpecificationSkeleton + * @generated + */ + EClass getTestSpecificationSkeleton(); + + /** + * Returns the meta object for the attribute '{@link com.specmate.model.testspecification.TestSpecificationSkeleton#getLanguage Language}'. + * + * + * @return the meta object for the attribute 'Language'. + * @see com.specmate.model.testspecification.TestSpecificationSkeleton#getLanguage() + * @see #getTestSpecificationSkeleton() + * @generated + */ + EAttribute getTestSpecificationSkeleton_Language(); + + /** + * Returns the meta object for the attribute '{@link com.specmate.model.testspecification.TestSpecificationSkeleton#getCode Code}'. + * + * + * @return the meta object for the attribute 'Code'. + * @see com.specmate.model.testspecification.TestSpecificationSkeleton#getCode() + * @see #getTestSpecificationSkeleton() + * @generated + */ + EAttribute getTestSpecificationSkeleton_Code(); + /** * Returns the meta object for class '{@link com.specmate.model.testspecification.TestParameter Test Parameter}'. * @@ -764,6 +851,32 @@ interface Literals { */ EClass TEST_SPECIFICATION = eINSTANCE.getTestSpecification(); + /** + * The meta object literal for the '{@link com.specmate.model.testspecification.impl.TestSpecificationSkeletonImpl Test Specification Skeleton}' class. + * + * + * @see com.specmate.model.testspecification.impl.TestSpecificationSkeletonImpl + * @see com.specmate.model.testspecification.impl.TestspecificationPackageImpl#getTestSpecificationSkeleton() + * @generated + */ + EClass TEST_SPECIFICATION_SKELETON = eINSTANCE.getTestSpecificationSkeleton(); + + /** + * The meta object literal for the 'Language' attribute feature. + * + * + * @generated + */ + EAttribute TEST_SPECIFICATION_SKELETON__LANGUAGE = eINSTANCE.getTestSpecificationSkeleton_Language(); + + /** + * The meta object literal for the 'Code' attribute feature. + * + * + * @generated + */ + EAttribute TEST_SPECIFICATION_SKELETON__CODE = eINSTANCE.getTestSpecificationSkeleton_Code(); + /** * The meta object literal for the '{@link com.specmate.model.testspecification.impl.TestParameterImpl Test Parameter}' class. * diff --git a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestSpecificationSkeletonImpl.java b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestSpecificationSkeletonImpl.java new file mode 100644 index 000000000..81a17295e --- /dev/null +++ b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestSpecificationSkeletonImpl.java @@ -0,0 +1,221 @@ +/** + */ +package com.specmate.model.testspecification.impl; + +import com.specmate.model.base.BasePackage; + +import com.specmate.model.testspecification.TestSpecificationSkeleton; +import com.specmate.model.testspecification.TestspecificationPackage; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.internal.cdo.CDOObjectImpl; + +/** + * + * An implementation of the model object 'Test Specification Skeleton'. + * + *

+ * The following features are implemented: + *

+ *
    + *
  • {@link com.specmate.model.testspecification.impl.TestSpecificationSkeletonImpl#getName Name}
  • + *
  • {@link com.specmate.model.testspecification.impl.TestSpecificationSkeletonImpl#getLanguage Language}
  • + *
  • {@link com.specmate.model.testspecification.impl.TestSpecificationSkeletonImpl#getCode Code}
  • + *
+ * + * @generated + */ +public class TestSpecificationSkeletonImpl extends CDOObjectImpl implements TestSpecificationSkeleton { + /** + * The default value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The default value of the '{@link #getLanguage() Language}' attribute. + * + * + * @see #getLanguage() + * @generated + * @ordered + */ + protected static final String LANGUAGE_EDEFAULT = ""; + + /** + * The default value of the '{@link #getCode() Code}' attribute. + * + * + * @see #getCode() + * @generated + * @ordered + */ + protected static final String CODE_EDEFAULT = null; + + /** + * + * + * @generated + */ + protected TestSpecificationSkeletonImpl() { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() { + return TestspecificationPackage.Literals.TEST_SPECIFICATION_SKELETON; + } + + /** + * + * + * @generated + */ + @Override + protected int eStaticFeatureCount() { + return 0; + } + + /** + * + * + * @generated + */ + public String getName() { + return (String)eDynamicGet(TestspecificationPackage.TEST_SPECIFICATION_SKELETON__NAME, BasePackage.Literals.INAMED__NAME, true, true); + } + + /** + * + * + * @generated + */ + public void setName(String newName) { + eDynamicSet(TestspecificationPackage.TEST_SPECIFICATION_SKELETON__NAME, BasePackage.Literals.INAMED__NAME, newName); + } + + /** + * + * + * @generated + */ + public String getLanguage() { + return (String)eDynamicGet(TestspecificationPackage.TEST_SPECIFICATION_SKELETON__LANGUAGE, TestspecificationPackage.Literals.TEST_SPECIFICATION_SKELETON__LANGUAGE, true, true); + } + + /** + * + * + * @generated + */ + public void setLanguage(String newLanguage) { + eDynamicSet(TestspecificationPackage.TEST_SPECIFICATION_SKELETON__LANGUAGE, TestspecificationPackage.Literals.TEST_SPECIFICATION_SKELETON__LANGUAGE, newLanguage); + } + + /** + * + * + * @generated + */ + public String getCode() { + return (String)eDynamicGet(TestspecificationPackage.TEST_SPECIFICATION_SKELETON__CODE, TestspecificationPackage.Literals.TEST_SPECIFICATION_SKELETON__CODE, true, true); + } + + /** + * + * + * @generated + */ + public void setCode(String newCode) { + eDynamicSet(TestspecificationPackage.TEST_SPECIFICATION_SKELETON__CODE, TestspecificationPackage.Literals.TEST_SPECIFICATION_SKELETON__CODE, newCode); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__NAME: + return getName(); + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__LANGUAGE: + return getLanguage(); + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__CODE: + return getCode(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__NAME: + setName((String)newValue); + return; + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__LANGUAGE: + setLanguage((String)newValue); + return; + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__CODE: + setCode((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__NAME: + setName(NAME_EDEFAULT); + return; + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__LANGUAGE: + setLanguage(LANGUAGE_EDEFAULT); + return; + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__CODE: + setCode(CODE_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__NAME: + return NAME_EDEFAULT == null ? getName() != null : !NAME_EDEFAULT.equals(getName()); + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__LANGUAGE: + return LANGUAGE_EDEFAULT == null ? getLanguage() != null : !LANGUAGE_EDEFAULT.equals(getLanguage()); + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON__CODE: + return CODE_EDEFAULT == null ? getCode() != null : !CODE_EDEFAULT.equals(getCode()); + } + return super.eIsSet(featureID); + } + +} //TestSpecificationSkeletonImpl diff --git a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestspecificationFactoryImpl.java b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestspecificationFactoryImpl.java index 10e527740..99229012c 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestspecificationFactoryImpl.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestspecificationFactoryImpl.java @@ -58,6 +58,7 @@ public TestspecificationFactoryImpl() { public EObject create(EClass eClass) { switch (eClass.getClassifierID()) { case TestspecificationPackage.TEST_SPECIFICATION: return (EObject)createTestSpecification(); + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON: return (EObject)createTestSpecificationSkeleton(); case TestspecificationPackage.TEST_PARAMETER: return (EObject)createTestParameter(); case TestspecificationPackage.TEST_CASE: return (EObject)createTestCase(); case TestspecificationPackage.PARAMETER_ASSIGNMENT: return (EObject)createParameterAssignment(); @@ -108,6 +109,16 @@ public TestSpecification createTestSpecification() { return testSpecification; } + /** + * + * + * @generated + */ + public TestSpecificationSkeleton createTestSpecificationSkeleton() { + TestSpecificationSkeletonImpl testSpecificationSkeleton = new TestSpecificationSkeletonImpl(); + return testSpecificationSkeleton; + } + /** * * diff --git a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestspecificationPackageImpl.java b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestspecificationPackageImpl.java index 763abcaee..c91dd8e4d 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestspecificationPackageImpl.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/impl/TestspecificationPackageImpl.java @@ -30,6 +30,7 @@ import com.specmate.model.testspecification.TestParameter; import com.specmate.model.testspecification.TestProcedure; import com.specmate.model.testspecification.TestSpecification; +import com.specmate.model.testspecification.TestSpecificationSkeleton; import com.specmate.model.testspecification.TestStep; import com.specmate.model.testspecification.TestspecificationFactory; import com.specmate.model.testspecification.TestspecificationPackage; @@ -56,6 +57,13 @@ public class TestspecificationPackageImpl extends EPackageImpl implements Testsp */ private EClass testSpecificationEClass = null; + /** + * + * + * @generated + */ + private EClass testSpecificationSkeletonEClass = null; + /** * * @@ -188,6 +196,33 @@ public EClass getTestSpecification() { return testSpecificationEClass; } + /** + * + * + * @generated + */ + public EClass getTestSpecificationSkeleton() { + return testSpecificationSkeletonEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getTestSpecificationSkeleton_Language() { + return (EAttribute)testSpecificationSkeletonEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getTestSpecificationSkeleton_Code() { + return (EAttribute)testSpecificationSkeletonEClass.getEStructuralFeatures().get(1); + } + /** * * @@ -353,6 +388,10 @@ public void createPackageContents() { // Create classes and their features testSpecificationEClass = createEClass(TEST_SPECIFICATION); + testSpecificationSkeletonEClass = createEClass(TEST_SPECIFICATION_SKELETON); + createEAttribute(testSpecificationSkeletonEClass, TEST_SPECIFICATION_SKELETON__LANGUAGE); + createEAttribute(testSpecificationSkeletonEClass, TEST_SPECIFICATION_SKELETON__CODE); + testParameterEClass = createEClass(TEST_PARAMETER); createEAttribute(testParameterEClass, TEST_PARAMETER__TYPE); createEReference(testParameterEClass, TEST_PARAMETER__ASSIGNMENTS); @@ -408,6 +447,7 @@ public void initializePackageContents() { // Add supertypes to classes testSpecificationEClass.getESuperTypes().add(theBasePackage.getIContainer()); + testSpecificationSkeletonEClass.getESuperTypes().add(theBasePackage.getINamed()); testParameterEClass.getESuperTypes().add(theBasePackage.getIContentElement()); testCaseEClass.getESuperTypes().add(theBasePackage.getIContainer()); testCaseEClass.getESuperTypes().add(theBasePackage.getIPositionable()); @@ -420,6 +460,10 @@ public void initializePackageContents() { // Initialize classes, features, and operations; add parameters initEClass(testSpecificationEClass, TestSpecification.class, "TestSpecification", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEClass(testSpecificationSkeletonEClass, TestSpecificationSkeleton.class, "TestSpecificationSkeleton", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getTestSpecificationSkeleton_Language(), ecorePackage.getEString(), "language", "", 0, 1, TestSpecificationSkeleton.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getTestSpecificationSkeleton_Code(), ecorePackage.getEString(), "code", null, 0, 1, TestSpecificationSkeleton.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEClass(testParameterEClass, TestParameter.class, "TestParameter", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); initEAttribute(getTestParameter_Type(), this.getParameterType(), "type", null, 0, 1, TestParameter.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); initEReference(getTestParameter_Assignments(), this.getParameterAssignment(), this.getParameterAssignment_Parameter(), "assignments", null, 0, -1, TestParameter.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); diff --git a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/util/TestspecificationAdapterFactory.java b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/util/TestspecificationAdapterFactory.java index 406fe38e6..90def0c53 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/util/TestspecificationAdapterFactory.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/util/TestspecificationAdapterFactory.java @@ -80,6 +80,10 @@ public Adapter caseTestSpecification(TestSpecification object) { return createTestSpecificationAdapter(); } @Override + public Adapter caseTestSpecificationSkeleton(TestSpecificationSkeleton object) { + return createTestSpecificationSkeletonAdapter(); + } + @Override public Adapter caseTestParameter(TestParameter object) { return createTestParameterAdapter(); } @@ -161,6 +165,20 @@ public Adapter createTestSpecificationAdapter() { return null; } + /** + * Creates a new adapter for an object of class '{@link com.specmate.model.testspecification.TestSpecificationSkeleton Test Specification Skeleton}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.specmate.model.testspecification.TestSpecificationSkeleton + * @generated + */ + public Adapter createTestSpecificationSkeletonAdapter() { + return null; + } + /** * Creates a new adapter for an object of class '{@link com.specmate.model.testspecification.TestParameter Test Parameter}'. * diff --git a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/util/TestspecificationSwitch.java b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/util/TestspecificationSwitch.java index 413a993ef..a8dd38e48 100644 --- a/bundles/specmate-model-gen/src/com/specmate/model/testspecification/util/TestspecificationSwitch.java +++ b/bundles/specmate-model-gen/src/com/specmate/model/testspecification/util/TestspecificationSwitch.java @@ -85,6 +85,13 @@ protected T doSwitch(int classifierID, EObject theEObject) { if (result == null) result = defaultCase(theEObject); return result; } + case TestspecificationPackage.TEST_SPECIFICATION_SKELETON: { + TestSpecificationSkeleton testSpecificationSkeleton = (TestSpecificationSkeleton)theEObject; + T result = caseTestSpecificationSkeleton(testSpecificationSkeleton); + if (result == null) result = caseINamed(testSpecificationSkeleton); + if (result == null) result = defaultCase(theEObject); + return result; + } case TestspecificationPackage.TEST_PARAMETER: { TestParameter testParameter = (TestParameter)theEObject; T result = caseTestParameter(testParameter); @@ -159,6 +166,21 @@ public T caseTestSpecification(TestSpecification object) { return null; } + /** + * Returns the result of interpreting the object as an instance of 'Test Specification Skeleton'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpreting the object as an instance of 'Test Specification Skeleton'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public T caseTestSpecificationSkeleton(TestSpecificationSkeleton object) { + return null; + } + /** * Returns the result of interpreting the object as an instance of 'Test Parameter'. * diff --git a/bundles/specmate-model-gen/src/com/specmate/usermodel/UsermodelPackage.java b/bundles/specmate-model-gen/src/com/specmate/usermodel/UsermodelPackage.java index 111d08945..1f82fed2e 100644 --- a/bundles/specmate-model-gen/src/com/specmate/usermodel/UsermodelPackage.java +++ b/bundles/specmate-model-gen/src/com/specmate/usermodel/UsermodelPackage.java @@ -38,7 +38,7 @@ public interface UsermodelPackage extends EPackage { * * @generated */ - String eNS_URI = "http://specmate.com/20180925/model/user"; + String eNS_URI = "http://specmate.com/20181108/model/user"; /** * The package namespace name. diff --git a/bundles/specmate-rest/src/com/specmate/rest/RestResult.java b/bundles/specmate-rest/src/com/specmate/rest/RestResult.java index 148e46900..d302c7fcd 100644 --- a/bundles/specmate-rest/src/com/specmate/rest/RestResult.java +++ b/bundles/specmate-rest/src/com/specmate/rest/RestResult.java @@ -17,6 +17,10 @@ public RestResult(Response response, String url, T payload) { this.payload = payload; } + public RestResult(Response response) { + this(response, null, null); + } + public RestResult(Response.Status status, T payload, String userName) { this.status = status; this.payload = payload; diff --git a/bundles/specmate-testspecification/bnd.bnd b/bundles/specmate-testspecification/bnd.bnd index b897e0901..fc5b2f92e 100644 --- a/bundles/specmate-testspecification/bnd.bnd +++ b/bundles/specmate-testspecification/bnd.bnd @@ -17,4 +17,6 @@ org.sat4j.pb,\ specmate-emfrest-api;version=latest,\ specmate-rest;version=latest -Private-Package: com.specmate.testspecification.internal.services \ No newline at end of file +Private-Package: \ + com.specmate.testspecification.internal.services,\ + com.specmate.testspecification.internal.testskeleton \ No newline at end of file diff --git a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/services/TestSkeletonGeneratorService.java b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/services/TestSkeletonGeneratorService.java new file mode 100644 index 000000000..8518b9d5b --- /dev/null +++ b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/services/TestSkeletonGeneratorService.java @@ -0,0 +1,70 @@ +package com.specmate.testspecification.internal.services; + +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; + +import com.specmate.common.SpecmateException; +import com.specmate.emfrest.api.IRestService; +import com.specmate.emfrest.api.RestServiceBase; +import com.specmate.model.testspecification.TestSpecification; +import com.specmate.model.testspecification.TestSpecificationSkeleton; +import com.specmate.rest.RestResult; +import com.specmate.testspecification.internal.testskeleton.BaseSkeleton; +import com.specmate.testspecification.internal.testskeleton.JavaTestSpecificationSkeleton; +import com.specmate.testspecification.internal.testskeleton.JavascriptTestSpecificationSkeleton; + +@Component(immediate = true, service = IRestService.class) +public class TestSkeletonGeneratorService extends RestServiceBase { + private final String LPARAM = "language"; + private final String JAVA = "java"; + private final String JAVASCRIPT = "javascript"; + private final String TYPESCRIPT = "typescript"; + private Map skeletonGenerators; + + @Activate + public void activate() { + skeletonGenerators = new HashMap<>(); + skeletonGenerators.put(JAVA, new JavaTestSpecificationSkeleton(JAVA)); + skeletonGenerators.put(JAVASCRIPT, new JavascriptTestSpecificationSkeleton(JAVASCRIPT)); + } + + @Override + public String getServiceName() { + return "generateTestSkeleton"; + } + + @Override + public boolean canGet(Object object) { + return object instanceof TestSpecification; + } + + @Override + public RestResult get(Object object, MultivaluedMap queryParams, String token) + throws SpecmateException { + + String language = queryParams.getFirst(LPARAM); + if (language == null) { + return new RestResult<>(Response.Status.BAD_REQUEST); + } + + BaseSkeleton generator = skeletonGenerators.get(language); + if (generator == null) { + return new RestResult<>(Response.Status.BAD_REQUEST); + } + + if (!(object instanceof TestSpecification)) { + return new RestResult<>(Response.Status.BAD_REQUEST); + } + + TestSpecification ts = (TestSpecification) object; + + return new RestResult(Response.Status.OK, generator.generate(ts)); + } + +} diff --git a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/BaseSkeleton.java b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/BaseSkeleton.java new file mode 100644 index 000000000..a43dd40f2 --- /dev/null +++ b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/BaseSkeleton.java @@ -0,0 +1,82 @@ +package com.specmate.testspecification.internal.testskeleton; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.regex.Pattern; + +import com.specmate.model.support.util.SpecmateEcoreUtil; +import com.specmate.model.testspecification.ParameterAssignment; +import com.specmate.model.testspecification.ParameterType; +import com.specmate.model.testspecification.TestCase; +import com.specmate.model.testspecification.TestSpecification; +import com.specmate.model.testspecification.TestSpecificationSkeleton; +import com.specmate.model.testspecification.TestspecificationFactory; + +public abstract class BaseSkeleton { + private static Pattern startsNumerical = Pattern.compile("^[0-9]"); + private static Pattern invalidChars = Pattern.compile("[^a-zA-Z_0-9\\_]"); + protected String language; + protected String testArea; + protected Date generationDate; + protected TestSpecification testSpecification; + protected StringBuilder sb; + + public BaseSkeleton(String language) { + this.language = language; + this.generationDate = new Date(); + this.sb = new StringBuilder(); + } + + public TestSpecificationSkeleton generate(TestSpecification testSpecification) { + this.testSpecification = testSpecification; + this.testArea = testSpecification.getName(); + TestSpecificationSkeleton tss = TestspecificationFactory.eINSTANCE.createTestSpecificationSkeleton(); + tss.setLanguage(language); + tss.setName(generateFileName()); + tss.setCode(generateCode()); + return tss; + } + + protected void generateTestCaseMethodName(TestCase tc) { + List pAssignments = SpecmateEcoreUtil.pickInstancesOf(tc.getContents(), + ParameterAssignment.class); + + ParameterAssignment output = null; + for (ParameterAssignment pAssignment : pAssignments) { + if (pAssignment.getParameter().getType().equals(ParameterType.OUTPUT)) { + output = pAssignment; + } else { + generateParameterValue(pAssignment); + } + } + + if (output != null) { + generateParameterValue(output); + } + } + + protected void generateDateComment() { + sb.append("/*\n"); + sb.append(" * Datum: "); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + sb.append(sdf.format(generationDate)); + sb.append("\n */\n\n"); + } + + protected String replaceInvalidChars(String r) { + r = startsNumerical.matcher(r).replaceAll(""); + return invalidChars.matcher(r).replaceAll("_"); + } + + private void generateParameterValue(ParameterAssignment pa) { + sb.append("___"); + sb.append(replaceInvalidChars(pa.getParameter().getName())); + sb.append("__"); + sb.append(replaceInvalidChars(pa.getValue())); + } + + protected abstract String generateCode(); + + protected abstract String generateFileName(); +} diff --git a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavaTestSpecificationSkeleton.java b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavaTestSpecificationSkeleton.java new file mode 100644 index 000000000..67d143ec9 --- /dev/null +++ b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavaTestSpecificationSkeleton.java @@ -0,0 +1,50 @@ +package com.specmate.testspecification.internal.testskeleton; + +import java.util.List; + +import com.specmate.model.support.util.SpecmateEcoreUtil; +import com.specmate.model.testspecification.TestCase; + +public class JavaTestSpecificationSkeleton extends BaseSkeleton { + + public JavaTestSpecificationSkeleton(String language) { + super(language); + } + + @Override + protected String generateCode() { + sb.append("import org.junit.Test;\n"); + sb.append("import org.junit.Assert;\n\n"); + generateDateComment(); + sb.append("public class "); + sb.append(generateClassname()); + sb.append(" {\n\n"); + List testCases = SpecmateEcoreUtil.pickInstancesOf(testSpecification.getContents(), TestCase.class); + for (TestCase tc : testCases) { + sb.append("\t/*\n"); + sb.append("\t * Testfall: "); + sb.append(tc.getName()); + sb.append("\n\t */\n"); + sb.append("\t@Test\n"); + sb.append("\tpublic void "); + sb.append(generateClassname()); + generateTestCaseMethodName(tc); + sb.append("() {\n"); + sb.append("\t\tAssert.throw();\n"); + sb.append("\t}\n\n"); + } + + sb.append("}"); + + return sb.toString(); + } + + @Override + protected String generateFileName() { + return generateClassname() + ".java"; + } + + private String generateClassname() { + return replaceInvalidChars(testArea) + "Test"; + } +} diff --git a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavascriptTestSpecificationSkeleton.java b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavascriptTestSpecificationSkeleton.java new file mode 100644 index 000000000..843ac6a31 --- /dev/null +++ b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavascriptTestSpecificationSkeleton.java @@ -0,0 +1,43 @@ +package com.specmate.testspecification.internal.testskeleton; + +import java.util.List; + +import com.specmate.model.support.util.SpecmateEcoreUtil; +import com.specmate.model.testspecification.TestCase; + +public class JavascriptTestSpecificationSkeleton extends BaseSkeleton { + + public JavascriptTestSpecificationSkeleton(String language) { + super(language); + } + + @Override + protected String generateCode() { + generateDateComment(); + sb.append("describe('"); + sb.append(replaceInvalidChars(testArea)); + sb.append("', () => {\n\n"); + List testCases = SpecmateEcoreUtil.pickInstancesOf(testSpecification.getContents(), TestCase.class); + for (TestCase tc : testCases) { + sb.append("\t/*\n"); + sb.append("\t * Testfall: "); + sb.append(tc.getName()); + sb.append("\n\t */\n"); + sb.append("\tit('"); + sb.append(replaceInvalidChars(testArea)); + generateTestCaseMethodName(tc); + sb.append("', () => {\n"); + sb.append("\t\tthrow new Error('not implemented yet');\n"); + sb.append("\t});\n\n"); + } + + sb.append("});"); + + return sb.toString(); + } + + @Override + protected String generateFileName() { + return replaceInvalidChars(testArea) + ".js"; + } +} diff --git a/web/src/app/model/BatchOperation.ts b/web/src/app/model/BatchOperation.ts index 1320748bd..da93a9c01 100644 --- a/web/src/app/model/BatchOperation.ts +++ b/web/src/app/model/BatchOperation.ts @@ -5,7 +5,7 @@ export class BatchOperation { - ___nsuri: string = "http://specmate.com/20180925/model/batch"; + ___nsuri: string = "http://specmate.com/20181108/model/batch"; public url: string; public className: string = "BatchOperation"; public static className: string = "BatchOperation"; diff --git a/web/src/app/model/CEGConnection.ts b/web/src/app/model/CEGConnection.ts index 4d3a88f5b..9856243dc 100644 --- a/web/src/app/model/CEGConnection.ts +++ b/web/src/app/model/CEGConnection.ts @@ -4,7 +4,7 @@ export class CEGConnection { - ___nsuri: string = "http://specmate.com/20180925/model/requirements"; + ___nsuri: string = "http://specmate.com/20181108/model/requirements"; public url: string; public className: string = "CEGConnection"; public static className: string = "CEGConnection"; diff --git a/web/src/app/model/CEGModel.ts b/web/src/app/model/CEGModel.ts index d8155ca3e..83b1b51d7 100644 --- a/web/src/app/model/CEGModel.ts +++ b/web/src/app/model/CEGModel.ts @@ -4,7 +4,7 @@ export class CEGModel { - ___nsuri: string = "http://specmate.com/20180925/model/requirements"; + ___nsuri: string = "http://specmate.com/20181108/model/requirements"; public url: string; public className: string = "CEGModel"; public static className: string = "CEGModel"; diff --git a/web/src/app/model/CEGNode.ts b/web/src/app/model/CEGNode.ts index 09ba8be39..f87623257 100644 --- a/web/src/app/model/CEGNode.ts +++ b/web/src/app/model/CEGNode.ts @@ -4,7 +4,7 @@ export class CEGNode { - ___nsuri: string = "http://specmate.com/20180925/model/requirements"; + ___nsuri: string = "http://specmate.com/20181108/model/requirements"; public url: string; public className: string = "CEGNode"; public static className: string = "CEGNode"; diff --git a/web/src/app/model/Change.ts b/web/src/app/model/Change.ts index b5d211533..271ed0342 100644 --- a/web/src/app/model/Change.ts +++ b/web/src/app/model/Change.ts @@ -4,7 +4,7 @@ export class Change { - ___nsuri: string = "http://specmate.com/20180925/model/history"; + ___nsuri: string = "http://specmate.com/20181108/model/history"; public url: string; public className: string = "Change"; public static className: string = "Change"; diff --git a/web/src/app/model/Folder.ts b/web/src/app/model/Folder.ts index 8a4c1f3e5..6e8431d47 100644 --- a/web/src/app/model/Folder.ts +++ b/web/src/app/model/Folder.ts @@ -4,7 +4,7 @@ export class Folder { - ___nsuri: string = "http://specmate.com/20180925/model/base"; + ___nsuri: string = "http://specmate.com/20181108/model/base"; public url: string; public className: string = "Folder"; public static className: string = "Folder"; diff --git a/web/src/app/model/History.ts b/web/src/app/model/History.ts index 3966decd2..f399c65a4 100644 --- a/web/src/app/model/History.ts +++ b/web/src/app/model/History.ts @@ -5,7 +5,7 @@ export class History { - ___nsuri: string = "http://specmate.com/20180925/model/history"; + ___nsuri: string = "http://specmate.com/20181108/model/history"; public url: string; public className: string = "History"; public static className: string = "History"; diff --git a/web/src/app/model/HistoryEntry.ts b/web/src/app/model/HistoryEntry.ts index 5a2850add..cbe17494c 100644 --- a/web/src/app/model/HistoryEntry.ts +++ b/web/src/app/model/HistoryEntry.ts @@ -5,7 +5,7 @@ export class HistoryEntry { - ___nsuri: string = "http://specmate.com/20180925/model/history"; + ___nsuri: string = "http://specmate.com/20181108/model/history"; public url: string; public className: string = "HistoryEntry"; public static className: string = "HistoryEntry"; @@ -17,7 +17,7 @@ public comment: EString; // References - + // Containment public changes: Change[]; diff --git a/web/src/app/model/IExternal.ts b/web/src/app/model/IExternal.ts index 7a37f455e..91862ce9d 100644 --- a/web/src/app/model/IExternal.ts +++ b/web/src/app/model/IExternal.ts @@ -4,7 +4,7 @@ export class IExternal { - ___nsuri: string = "http://specmate.com/20180925/model/base"; + ___nsuri: string = "http://specmate.com/20181108/model/base"; public url: string; public className: string = "IExternal"; public static className: string = "IExternal"; diff --git a/web/src/app/model/IModelConnection.ts b/web/src/app/model/IModelConnection.ts index 1bf42ca42..2846eff66 100644 --- a/web/src/app/model/IModelConnection.ts +++ b/web/src/app/model/IModelConnection.ts @@ -4,7 +4,7 @@ export class IModelConnection { - ___nsuri: string = "http://specmate.com/20180925/model/base"; + ___nsuri: string = "http://specmate.com/20181108/model/base"; public url: string; public className: string = "IModelConnection"; public static className: string = "IModelConnection"; diff --git a/web/src/app/model/IModelNode.ts b/web/src/app/model/IModelNode.ts index 19dafab59..84cbc2f54 100644 --- a/web/src/app/model/IModelNode.ts +++ b/web/src/app/model/IModelNode.ts @@ -4,7 +4,7 @@ export class IModelNode { - ___nsuri: string = "http://specmate.com/20180925/model/base"; + ___nsuri: string = "http://specmate.com/20181108/model/base"; public url: string; public className: string = "IModelNode"; public static className: string = "IModelNode"; diff --git a/web/src/app/model/ITracingElement.ts b/web/src/app/model/ITracingElement.ts index 2bc407f5b..337329d01 100644 --- a/web/src/app/model/ITracingElement.ts +++ b/web/src/app/model/ITracingElement.ts @@ -4,7 +4,7 @@ export class ITracingElement { - ___nsuri: string = "http://specmate.com/20180925/model/base"; + ___nsuri: string = "http://specmate.com/20181108/model/base"; public url: string; public className: string = "ITracingElement"; public static className: string = "ITracingElement"; diff --git a/web/src/app/model/Operation.ts b/web/src/app/model/Operation.ts index 6d62826c8..12cd9712b 100644 --- a/web/src/app/model/Operation.ts +++ b/web/src/app/model/Operation.ts @@ -5,7 +5,7 @@ export class Operation { - ___nsuri: string = "http://specmate.com/20180925/model/batch"; + ___nsuri: string = "http://specmate.com/20181108/model/batch"; public url: string; public className: string = "Operation"; public static className: string = "Operation"; diff --git a/web/src/app/model/ParameterAssignment.ts b/web/src/app/model/ParameterAssignment.ts index f26df2d42..638cbcc70 100644 --- a/web/src/app/model/ParameterAssignment.ts +++ b/web/src/app/model/ParameterAssignment.ts @@ -4,7 +4,7 @@ export class ParameterAssignment { - ___nsuri: string = "http://specmate.com/20180925/model/testspecification"; + ___nsuri: string = "http://specmate.com/20181108/model/testspecification"; public url: string; public className: string = "ParameterAssignment"; public static className: string = "ParameterAssignment"; diff --git a/web/src/app/model/Process.ts b/web/src/app/model/Process.ts index 6f168160f..eb5bf4b09 100644 --- a/web/src/app/model/Process.ts +++ b/web/src/app/model/Process.ts @@ -4,7 +4,7 @@ export class Process { - ___nsuri: string = "http://specmate.com/20180925/model/processes"; + ___nsuri: string = "http://specmate.com/20181108/model/processes"; public url: string; public className: string = "Process"; public static className: string = "Process"; diff --git a/web/src/app/model/ProcessConnection.ts b/web/src/app/model/ProcessConnection.ts index 9761711f5..e5a968c50 100644 --- a/web/src/app/model/ProcessConnection.ts +++ b/web/src/app/model/ProcessConnection.ts @@ -4,7 +4,7 @@ export class ProcessConnection { - ___nsuri: string = "http://specmate.com/20180925/model/processes"; + ___nsuri: string = "http://specmate.com/20181108/model/processes"; public url: string; public className: string = "ProcessConnection"; public static className: string = "ProcessConnection"; diff --git a/web/src/app/model/ProcessDecision.ts b/web/src/app/model/ProcessDecision.ts index 4fe298ca8..03ab16a14 100644 --- a/web/src/app/model/ProcessDecision.ts +++ b/web/src/app/model/ProcessDecision.ts @@ -4,7 +4,7 @@ export class ProcessDecision { - ___nsuri: string = "http://specmate.com/20180925/model/processes"; + ___nsuri: string = "http://specmate.com/20181108/model/processes"; public url: string; public className: string = "ProcessDecision"; public static className: string = "ProcessDecision"; diff --git a/web/src/app/model/ProcessEnd.ts b/web/src/app/model/ProcessEnd.ts index fc78a3aa6..75ef43941 100644 --- a/web/src/app/model/ProcessEnd.ts +++ b/web/src/app/model/ProcessEnd.ts @@ -4,7 +4,7 @@ export class ProcessEnd { - ___nsuri: string = "http://specmate.com/20180925/model/processes"; + ___nsuri: string = "http://specmate.com/20181108/model/processes"; public url: string; public className: string = "ProcessEnd"; public static className: string = "ProcessEnd"; diff --git a/web/src/app/model/ProcessNode.ts b/web/src/app/model/ProcessNode.ts index 6c3b4135e..c7895d551 100644 --- a/web/src/app/model/ProcessNode.ts +++ b/web/src/app/model/ProcessNode.ts @@ -4,7 +4,7 @@ export class ProcessNode { - ___nsuri: string = "http://specmate.com/20180925/model/processes"; + ___nsuri: string = "http://specmate.com/20181108/model/processes"; public url: string; public className: string = "ProcessNode"; public static className: string = "ProcessNode"; diff --git a/web/src/app/model/ProcessStart.ts b/web/src/app/model/ProcessStart.ts index 247071fc3..e3b355a57 100644 --- a/web/src/app/model/ProcessStart.ts +++ b/web/src/app/model/ProcessStart.ts @@ -4,7 +4,7 @@ export class ProcessStart { - ___nsuri: string = "http://specmate.com/20180925/model/processes"; + ___nsuri: string = "http://specmate.com/20181108/model/processes"; public url: string; public className: string = "ProcessStart"; public static className: string = "ProcessStart"; diff --git a/web/src/app/model/ProcessStep.ts b/web/src/app/model/ProcessStep.ts index 1ce2d8e14..608043e06 100644 --- a/web/src/app/model/ProcessStep.ts +++ b/web/src/app/model/ProcessStep.ts @@ -4,7 +4,7 @@ export class ProcessStep { - ___nsuri: string = "http://specmate.com/20180925/model/processes"; + ___nsuri: string = "http://specmate.com/20181108/model/processes"; public url: string; public className: string = "ProcessStep"; public static className: string = "ProcessStep"; diff --git a/web/src/app/model/Requirement.ts b/web/src/app/model/Requirement.ts index 30dec9053..099573a34 100644 --- a/web/src/app/model/Requirement.ts +++ b/web/src/app/model/Requirement.ts @@ -4,7 +4,7 @@ export class Requirement { - ___nsuri: string = "http://specmate.com/20180925/model/requirements"; + ___nsuri: string = "http://specmate.com/20181108/model/requirements"; public url: string; public className: string = "Requirement"; public static className: string = "Requirement"; diff --git a/web/src/app/model/Status.ts b/web/src/app/model/Status.ts index 476a4db31..3cf4cf847 100644 --- a/web/src/app/model/Status.ts +++ b/web/src/app/model/Status.ts @@ -4,7 +4,7 @@ export class Status { - ___nsuri: string = "http://specmate.com/20180925/model/administration"; + ___nsuri: string = "http://specmate.com/20181108/model/administration"; public url: string; public className: string = "Status"; public static className: string = "Status"; diff --git a/web/src/app/model/TestCase.ts b/web/src/app/model/TestCase.ts index 315ae6fa0..d1bbace93 100644 --- a/web/src/app/model/TestCase.ts +++ b/web/src/app/model/TestCase.ts @@ -4,7 +4,7 @@ export class TestCase { - ___nsuri: string = "http://specmate.com/20180925/model/testspecification"; + ___nsuri: string = "http://specmate.com/20181108/model/testspecification"; public url: string; public className: string = "TestCase"; public static className: string = "TestCase"; diff --git a/web/src/app/model/TestParameter.ts b/web/src/app/model/TestParameter.ts index 4e1c0bad2..591b89442 100644 --- a/web/src/app/model/TestParameter.ts +++ b/web/src/app/model/TestParameter.ts @@ -4,7 +4,7 @@ export class TestParameter { - ___nsuri: string = "http://specmate.com/20180925/model/testspecification"; + ___nsuri: string = "http://specmate.com/20181108/model/testspecification"; public url: string; public className: string = "TestParameter"; public static className: string = "TestParameter"; diff --git a/web/src/app/model/TestProcedure.ts b/web/src/app/model/TestProcedure.ts index 475069258..eb6b945d7 100644 --- a/web/src/app/model/TestProcedure.ts +++ b/web/src/app/model/TestProcedure.ts @@ -4,7 +4,7 @@ export class TestProcedure { - ___nsuri: string = "http://specmate.com/20180925/model/testspecification"; + ___nsuri: string = "http://specmate.com/20181108/model/testspecification"; public url: string; public className: string = "TestProcedure"; public static className: string = "TestProcedure"; diff --git a/web/src/app/model/TestSpecification.ts b/web/src/app/model/TestSpecification.ts index 5f8a78003..eae83491d 100644 --- a/web/src/app/model/TestSpecification.ts +++ b/web/src/app/model/TestSpecification.ts @@ -4,7 +4,7 @@ export class TestSpecification { - ___nsuri: string = "http://specmate.com/20180925/model/testspecification"; + ___nsuri: string = "http://specmate.com/20181108/model/testspecification"; public url: string; public className: string = "TestSpecification"; public static className: string = "TestSpecification"; diff --git a/web/src/app/model/TestSpecificationSkeleton.ts b/web/src/app/model/TestSpecificationSkeleton.ts new file mode 100644 index 000000000..2a4f493e1 --- /dev/null +++ b/web/src/app/model/TestSpecificationSkeleton.ts @@ -0,0 +1,23 @@ + import './support/gentypes'; + import { Proxy } from './support/proxy'; + + + export class TestSpecificationSkeleton { + + ___nsuri: string = "http://specmate.com/20181108/model/testspecification"; + public url: string; + public className: string = "TestSpecificationSkeleton"; + public static className: string = "TestSpecificationSkeleton"; + + // Attributes + public name: EString; + public language: EString; + public code: EString; + + // References + + // Containment + + + } + diff --git a/web/src/app/model/TestStep.ts b/web/src/app/model/TestStep.ts index 2e7bcfb0c..3045cf902 100644 --- a/web/src/app/model/TestStep.ts +++ b/web/src/app/model/TestStep.ts @@ -4,7 +4,7 @@ export class TestStep { - ___nsuri: string = "http://specmate.com/20180925/model/testspecification"; + ___nsuri: string = "http://specmate.com/20181108/model/testspecification"; public url: string; public className: string = "TestStep"; public static className: string = "TestStep"; diff --git a/web/src/app/model/User.ts b/web/src/app/model/User.ts index a860cedaa..165f2016b 100644 --- a/web/src/app/model/User.ts +++ b/web/src/app/model/User.ts @@ -4,7 +4,7 @@ export class User { - ___nsuri: string = "http://specmate.com/20180925/model/user"; + ___nsuri: string = "http://specmate.com/20181108/model/user"; public url: string; public className: string = "User"; public static className: string = "User"; diff --git a/web/src/app/model/UserSession.ts b/web/src/app/model/UserSession.ts index c36aa51dc..99b20fb42 100644 --- a/web/src/app/model/UserSession.ts +++ b/web/src/app/model/UserSession.ts @@ -4,7 +4,7 @@ export class UserSession { - ___nsuri: string = "http://specmate.com/20180925/model/user"; + ___nsuri: string = "http://specmate.com/20181108/model/user"; public url: string; public className: string = "UserSession"; public static className: string = "UserSession"; @@ -18,7 +18,6 @@ public TargetSystem: AccessRights; public libraryFolders: EString[]; - // References // Containment diff --git a/web/src/app/model/meta/field-meta.ts b/web/src/app/model/meta/field-meta.ts index e378686dd..04f135fa7 100644 --- a/web/src/app/model/meta/field-meta.ts +++ b/web/src/app/model/meta/field-meta.ts @@ -255,6 +255,15 @@ export class MetaInfo { rows: '8', position: '100' } ]; + public static TestSpecificationSkeleton: FieldMetaItem[] = [ + { + name: "name", + shortDesc: 'Name', + longDesc: '', + required: true, + type: 'text', + position: '0' + } ]; public static TestParameter: FieldMetaItem[] = [ { name: "name", diff --git a/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.css b/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.css new file mode 100644 index 000000000..4311c5e7a --- /dev/null +++ b/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.css @@ -0,0 +1,4 @@ +.btn.btn-link { + padding: 0px; + margin: 0px; +} diff --git a/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.html b/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.html new file mode 100644 index 000000000..d36315e8f --- /dev/null +++ b/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.html @@ -0,0 +1 @@ + diff --git a/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.ts b/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.ts new file mode 100644 index 000000000..1c6ac5838 --- /dev/null +++ b/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/components/get-test-specification-skeleton-button.component.ts @@ -0,0 +1,64 @@ +import { Component, Input } from '@angular/core'; +import { SpecmateDataService } from '../../../../data/modules/data-service/services/specmate-data.service'; +import { TestSpecification } from '../../../../../model/TestSpecification'; +import { TranslateService } from '@ngx-translate/core'; +import { saveAs } from 'file-saver'; +import { LowerCasePipe } from '@angular/common'; +import { TestSpecificationSkeleton } from '../../../../../model/TestSpecificationSkeleton'; + +@Component({ + moduleId: module.id.toString(), + selector: 'get-test-specification-skeleton-button', + templateUrl: 'get-test-specification-skeleton-button.component.html', + styleUrls: ['get-test-specification-skeleton-button.component.css'] +}) + +export class GetTestSpecificationSkeletonButton { + + private _testspecification: TestSpecification; + + private _lang: string; + + @Input() + public set testspecification(testspecification: TestSpecification) { + if (!testspecification) { + return; + } + this._testspecification = testspecification; + } + + @Input() + public set language(lang: string) { + this._lang = lang; + } + + constructor(private dataService: SpecmateDataService, + private translate: TranslateService) { } + + public async getskeleton(): Promise { + if (!this.enabled) { + return; + } + + const data: TestSpecificationSkeleton = await this.dataService.performQuery(this._testspecification.url, 'generateTestSkeleton', + { language: new LowerCasePipe().transform(this._lang)}); + + if (data === undefined) { + throw new Error('Could not load test specification skeleton for ' + this._lang); + } + + saveAs(new Blob([data.code], {type: 'text/plain;charset=utf-8'}), data.name); + } + + public get language(): string { + return this._lang; + } + + public get enabled(): boolean { + if (this._testspecification === undefined) { + return false; + } + + return true; + } +} diff --git a/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/get-test-specification-skeleton-button.module.ts b/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/get-test-specification-skeleton-button.module.ts new file mode 100644 index 000000000..00bdb6cc0 --- /dev/null +++ b/web/src/app/modules/actions/modules/get-test-specification-skeleton-button/get-test-specification-skeleton-button.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { GetTestSpecificationSkeletonButton } from './components/get-test-specification-skeleton-button.component'; +import { BrowserModule } from '@angular/platform-browser'; +import { TranslateModule } from '@ngx-translate/core'; + +@NgModule({ + imports: [ + // MODULE IMPORTS + BrowserModule, + TranslateModule + ], + declarations: [ + // COMPONENTS IN THIS MODULE + GetTestSpecificationSkeletonButton + ], + exports: [ + // THE COMPONENTS VISIBLE TO THE OUTSIDE + GetTestSpecificationSkeletonButton + ], + providers: [ + // SERVICES + ], + bootstrap: [ + // COMPONENTS THAT ARE BOOTSTRAPPED HERE + ] +}) + +export class GetTestSpecificationSkeletonButtonModule { } diff --git a/web/src/app/modules/views/main/authentication/modules/login/components/login.component.html b/web/src/app/modules/views/main/authentication/modules/login/components/login.component.html index 44e9fec42..b6296fa15 100644 --- a/web/src/app/modules/views/main/authentication/modules/login/components/login.component.html +++ b/web/src/app/modules/views/main/authentication/modules/login/components/login.component.html @@ -62,4 +62,4 @@

{{'login' | translate}}

- \ No newline at end of file + diff --git a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html index ccd951bdc..caa2eb7b3 100644 --- a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html +++ b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html @@ -18,14 +18,25 @@
+
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + {{'testspec.skeleton' | translate}}:
    +
      +
    • + +
    • +
    • + +
    • +
    +
  • -
    - -
    -
    - -
    -
    - -
    diff --git a/web/src/app/modules/views/side/modules/links-actions/links-actions.module.ts b/web/src/app/modules/views/side/modules/links-actions/links-actions.module.ts index f1fdcc1b9..f1b7f48de 100644 --- a/web/src/app/modules/views/side/modules/links-actions/links-actions.module.ts +++ b/web/src/app/modules/views/side/modules/links-actions/links-actions.module.ts @@ -12,6 +12,8 @@ import { AdditionalInformationService } from './services/additional-information. import { TranslateModule } from '@ngx-translate/core'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { AuthModule } from '../../../main/authentication/modules/auth/auth.module'; +import { GetTestSpecificationSkeletonButtonModule } from + '../../../../actions/modules/get-test-specification-skeleton-button/get-test-specification-skeleton-button.module'; @NgModule({ imports: [ @@ -20,6 +22,7 @@ import { AuthModule } from '../../../main/authentication/modules/auth/auth.modul NavigatorModule, TestSpecificationGeneratorButtonModule, ExportTestprocedureButtonModule, + GetTestSpecificationSkeletonButtonModule, ExportTestspecificationButtonModule, TranslateModule, AuthModule, diff --git a/web/src/assets/i18n/de.json b/web/src/assets/i18n/de.json index af9322312..aadd5fbc3 100644 --- a/web/src/assets/i18n/de.json +++ b/web/src/assets/i18n/de.json @@ -166,7 +166,8 @@ }, "successful": "Erfolgreich", "testspec": { - "generate": "Testspezifikation generieren" + "generate": "Testspezifikation generieren", + "skeleton": "Testspezifikationshüllen herunterladen" }, "toggleLog": "Log ein/ausblenden", "tools": { diff --git a/web/src/assets/i18n/gb.json b/web/src/assets/i18n/gb.json index 0ec82192f..0d6202454 100644 --- a/web/src/assets/i18n/gb.json +++ b/web/src/assets/i18n/gb.json @@ -165,7 +165,8 @@ }, "successful": "Successful", "testspec": { - "generate": "Generate test specification" + "generate": "Generate test specification", + "skeleton": "Download test specification skeletons" }, "toggleLog": "Toggle log", "tools": { From 5f188950f91b83970a351b6fd795cc071e7fb826 Mon Sep 17 00:00:00 2001 From: Daedo Date: Mon, 12 Nov 2018 11:01:07 +0100 Subject: [PATCH 18/44] Added missing fileds names to validation error message. (#329) * Added missing fileds names to validation error message. --- web/src/app/util/objects.ts | 2 +- web/src/app/validation/required-fields-validator.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/web/src/app/util/objects.ts b/web/src/app/util/objects.ts index de82a3217..e8576eaae 100644 --- a/web/src/app/util/objects.ts +++ b/web/src/app/util/objects.ts @@ -3,7 +3,6 @@ import { Type } from './type'; export class Objects { public static clone(source: any, target?: any): any { - if (source === target) { return; } @@ -87,6 +86,7 @@ export class Objects { } return p1 === p2; } + /** *Return true if the 2 arrays contain the same elements. */ diff --git a/web/src/app/validation/required-fields-validator.ts b/web/src/app/validation/required-fields-validator.ts index 493318b7e..6cbdebe71 100644 --- a/web/src/app/validation/required-fields-validator.ts +++ b/web/src/app/validation/required-fields-validator.ts @@ -13,7 +13,9 @@ export class RequiredFieldsValidator extends ElementValidatorBase { public validate(element: IContainer, contents: IContainer[] = []): ValidationResult { const missingFields: string[] = this.fields.filter((field: string) => !element[field] || element[field].length === 0); if (missingFields.length > 0) { - return new ValidationResult(Config.ERROR_MISSING_FIELDS, false, [element]); + let fieldText = '[' + missingFields.join(', ') + ']'; + let message = Config.ERROR_MISSING_FIELDS.replace('{{fields}}', fieldText); + return new ValidationResult(message, false, [element]); } return ValidationResult.VALID; } From 3311c699dcded1053981858a51a2ca108e4b2f0e Mon Sep 17 00:00:00 2001 From: Sebastian Eder Date: Tue, 13 Nov 2018 09:53:01 +0100 Subject: [PATCH 19/44] Version increase --- web/webpack/webpack.common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/webpack/webpack.common.js b/web/webpack/webpack.common.js index f8b8e2c12..9bef71e42 100644 --- a/web/webpack/webpack.common.js +++ b/web/webpack/webpack.common.js @@ -1,4 +1,4 @@ -const SPECMATE_VERSION = '0.2.7' +const SPECMATE_VERSION = '0.2.8' const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); From 5d1f335f431cd2682800bed19f30ce358f0a9be9 Mon Sep 17 00:00:00 2001 From: Michael Unterkalmsteiner Date: Sat, 17 Nov 2018 09:52:23 +0100 Subject: [PATCH 20/44] Bugfix were stringbuilder content was reused --- .../internal/testskeleton/BaseSkeleton.java | 18 +++++++++--------- .../JavaTestSpecificationSkeleton.java | 6 +++--- .../JavascriptTestSpecificationSkeleton.java | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/BaseSkeleton.java b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/BaseSkeleton.java index a43dd40f2..84fb31509 100644 --- a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/BaseSkeleton.java +++ b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/BaseSkeleton.java @@ -20,25 +20,25 @@ public abstract class BaseSkeleton { protected String testArea; protected Date generationDate; protected TestSpecification testSpecification; - protected StringBuilder sb; public BaseSkeleton(String language) { this.language = language; this.generationDate = new Date(); - this.sb = new StringBuilder(); } public TestSpecificationSkeleton generate(TestSpecification testSpecification) { + StringBuilder sb = new StringBuilder(); this.testSpecification = testSpecification; this.testArea = testSpecification.getName(); TestSpecificationSkeleton tss = TestspecificationFactory.eINSTANCE.createTestSpecificationSkeleton(); tss.setLanguage(language); tss.setName(generateFileName()); - tss.setCode(generateCode()); + tss.setCode(generateCode(sb)); + return tss; } - protected void generateTestCaseMethodName(TestCase tc) { + protected void appendTestCaseMethodName(StringBuilder sb, TestCase tc) { List pAssignments = SpecmateEcoreUtil.pickInstancesOf(tc.getContents(), ParameterAssignment.class); @@ -47,16 +47,16 @@ protected void generateTestCaseMethodName(TestCase tc) { if (pAssignment.getParameter().getType().equals(ParameterType.OUTPUT)) { output = pAssignment; } else { - generateParameterValue(pAssignment); + appendParameterValue(sb, pAssignment); } } if (output != null) { - generateParameterValue(output); + appendParameterValue(sb, output); } } - protected void generateDateComment() { + protected void appendDateComment(StringBuilder sb) { sb.append("/*\n"); sb.append(" * Datum: "); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); @@ -69,14 +69,14 @@ protected String replaceInvalidChars(String r) { return invalidChars.matcher(r).replaceAll("_"); } - private void generateParameterValue(ParameterAssignment pa) { + private void appendParameterValue(StringBuilder sb, ParameterAssignment pa) { sb.append("___"); sb.append(replaceInvalidChars(pa.getParameter().getName())); sb.append("__"); sb.append(replaceInvalidChars(pa.getValue())); } - protected abstract String generateCode(); + protected abstract String generateCode(StringBuilder sb); protected abstract String generateFileName(); } diff --git a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavaTestSpecificationSkeleton.java b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavaTestSpecificationSkeleton.java index 67d143ec9..4aeb5d440 100644 --- a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavaTestSpecificationSkeleton.java +++ b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavaTestSpecificationSkeleton.java @@ -12,10 +12,10 @@ public JavaTestSpecificationSkeleton(String language) { } @Override - protected String generateCode() { + protected String generateCode(StringBuilder sb) { sb.append("import org.junit.Test;\n"); sb.append("import org.junit.Assert;\n\n"); - generateDateComment(); + appendDateComment(sb); sb.append("public class "); sb.append(generateClassname()); sb.append(" {\n\n"); @@ -28,7 +28,7 @@ protected String generateCode() { sb.append("\t@Test\n"); sb.append("\tpublic void "); sb.append(generateClassname()); - generateTestCaseMethodName(tc); + appendTestCaseMethodName(sb, tc); sb.append("() {\n"); sb.append("\t\tAssert.throw();\n"); sb.append("\t}\n\n"); diff --git a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavascriptTestSpecificationSkeleton.java b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavascriptTestSpecificationSkeleton.java index 843ac6a31..660256d6e 100644 --- a/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavascriptTestSpecificationSkeleton.java +++ b/bundles/specmate-testspecification/src/com/specmate/testspecification/internal/testskeleton/JavascriptTestSpecificationSkeleton.java @@ -12,8 +12,8 @@ public JavascriptTestSpecificationSkeleton(String language) { } @Override - protected String generateCode() { - generateDateComment(); + protected String generateCode(StringBuilder sb) { + appendDateComment(sb); sb.append("describe('"); sb.append(replaceInvalidChars(testArea)); sb.append("', () => {\n\n"); @@ -25,7 +25,7 @@ protected String generateCode() { sb.append("\n\t */\n"); sb.append("\tit('"); sb.append(replaceInvalidChars(testArea)); - generateTestCaseMethodName(tc); + appendTestCaseMethodName(sb, tc); sb.append("', () => {\n"); sb.append("\t\tthrow new Error('not implemented yet');\n"); sb.append("\t});\n\n"); From ad29daf80c38d089ce19e1d07f90739e0a65aa78 Mon Sep 17 00:00:00 2001 From: Michael Unterkalmsteiner Date: Sat, 17 Nov 2018 13:20:20 +0100 Subject: [PATCH 21/44] Fixed that generator did not consider Array attributes. --- .../specmate/model/generators/typescript/generateAngular.mtl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/specmate-model-generators-typescript/src/com/specmate/model/generators/typescript/generateAngular.mtl b/bundles/specmate-model-generators-typescript/src/com/specmate/model/generators/typescript/generateAngular.mtl index a904a50eb..60c185737 100644 --- a/bundles/specmate-model-generators-typescript/src/com/specmate/model/generators/typescript/generateAngular.mtl +++ b/bundles/specmate-model-generators-typescript/src/com/specmate/model/generators/typescript/generateAngular.mtl @@ -28,7 +28,7 @@ // Attributes [for (a: EAttribute | aClass.eAllAttributes)] - [if not (aClass.interface)]public[/if] [a.name/]: [a.eType.name/]; + [if not (aClass.interface)]public[/if] [a.name/]: [a.eType.name/][if (a.many)]['['/][']'/][/if]; [/for] // References From 7943359fee6a3c63ba63e3a8f14fd40af13a53ab Mon Sep 17 00:00:00 2001 From: anushamogili <37270878+anushamogili@users.noreply.github.com> Date: Wed, 21 Nov 2018 15:43:58 +0100 Subject: [PATCH 22/44] Fix unused private an public properties (#333) Bug name on sonar quebe: Refactor this getter so that it actually refers to the property --- .../components/links-actions.component.ts | 5 ----- .../services/additional-information.service.ts | 10 ---------- 2 files changed, 15 deletions(-) diff --git a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.ts b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.ts index f434afb35..02663ca6d 100644 --- a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.ts +++ b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.ts @@ -15,11 +15,6 @@ import { Config } from '../../../../../../config/config'; export class LinksActions { public isCollapsed = false; - - public _requirement: Requirement; - public _model: IContainer; - public _contents: IContainer[]; - public _testSpecifications: TestSpecification[]; public descriptionVisible: boolean; constructor(private additionalInformationService: AdditionalInformationService) { } diff --git a/web/src/app/modules/views/side/modules/links-actions/services/additional-information.service.ts b/web/src/app/modules/views/side/modules/links-actions/services/additional-information.service.ts index 892682ab1..0e0cc0424 100644 --- a/web/src/app/modules/views/side/modules/links-actions/services/additional-information.service.ts +++ b/web/src/app/modules/views/side/modules/links-actions/services/additional-information.service.ts @@ -17,9 +17,6 @@ import { UserToken } from '../../../../main/authentication/base/user-token'; @Injectable() export class AdditionalInformationService { - private _requirement: Requirement; - private _model: IContainer; - private _contents: IContainer[]; public element: IContainer; private parents: IContainer[]; private _testSpecifications: TestSpecification[]; @@ -29,7 +26,6 @@ export class AdditionalInformationService { constructor(private dataService: SpecmateDataService, private navigator: NavigatorService, private auth: AuthenticationService) { this.informationLoaded = new EventEmitter(); navigator.hasNavigated.subscribe((element: IContainer) => { - this.clear(); this.element = element; this.loadParents() .then(() => this.loadTestSpecifications()) @@ -76,12 +72,6 @@ export class AdditionalInformationService { return readParentsTask.then(() => Promise.resolve()); } - private clear(): void { - this._model = undefined; - this._requirement = undefined; - this._contents = undefined; - } - public get hasAdditionalInformation(): boolean { return this.requirement !== undefined || this.model !== undefined || this.testSpecification !== undefined; } From c0a702d990059d0143530ce629dc1fa9bb9e1e89 Mon Sep 17 00:00:00 2001 From: sebeder <23170307+sebeder@users.noreply.github.com> Date: Fri, 23 Nov 2018 08:25:16 +0100 Subject: [PATCH 23/44] Rotate colors in project explorer tabs (#337) --- web/src/assets/scss/specmate.extensions.scss | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/src/assets/scss/specmate.extensions.scss b/web/src/assets/scss/specmate.extensions.scss index da640c27d..d987a5f61 100644 --- a/web/src/assets/scss/specmate.extensions.scss +++ b/web/src/assets/scss/specmate.extensions.scss @@ -164,4 +164,12 @@ textarea:focus, .login-top-space { height: 100vh; padding-top: 64px; -} \ No newline at end of file +} + +.nav-tabs .nav-link { + color: #495057; +} + +.nav-tabs .nav-link.active { + color: #007ea8; +} From c98ddd83df31cb36f997591f292cf8470ddcc5c2 Mon Sep 17 00:00:00 2001 From: sebeder <23170307+sebeder@users.noreply.github.com> Date: Fri, 23 Nov 2018 08:25:52 +0100 Subject: [PATCH 24/44] Refreshing history on save (#338) --- web/src/app/model/User.ts | 2 +- .../services/specmate-data.service.ts | 3 ++ .../components/history-view.component.ts | 32 +++++++++---------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/web/src/app/model/User.ts b/web/src/app/model/User.ts index 165f2016b..0dd561fe9 100644 --- a/web/src/app/model/User.ts +++ b/web/src/app/model/User.ts @@ -10,7 +10,7 @@ public static className: string = "User"; // Attributes - public allowedUrls: EString; + public allowedUrls: EString[]; public userName: EString; public passWord: EString; public projectName: EString; diff --git a/web/src/app/modules/data/modules/data-service/services/specmate-data.service.ts b/web/src/app/modules/data/modules/data-service/services/specmate-data.service.ts index ad679f9c5..96558ee36 100644 --- a/web/src/app/modules/data/modules/data-service/services/specmate-data.service.ts +++ b/web/src/app/modules/data/modules/data-service/services/specmate-data.service.ts @@ -43,6 +43,7 @@ export class SpecmateDataService { } public stateChanged: EventEmitter; + public committed: EventEmitter; private cache: DataCache = new DataCache(); private serviceInterface: ServiceInterface; @@ -57,6 +58,7 @@ export class SpecmateDataService { this.serviceInterface = new ServiceInterface(http); this.scheduler = new Scheduler(this, this.logger, this.translate); this.stateChanged = new EventEmitter(); + this.committed = new EventEmitter(); this.auth.authChanged.subscribe(() => { if (!this.auth.isAuthenticated) { @@ -190,6 +192,7 @@ export class SpecmateDataService { this.scheduler.resolveBatchOperation(batchOperation); this.scheduler.clearCommits(); this.busy = false; + this.committed.emit(); } public undo(): void { diff --git a/web/src/app/modules/views/side/modules/history-view/components/history-view.component.ts b/web/src/app/modules/views/side/modules/history-view/components/history-view.component.ts index 864e80b3f..61be8b02f 100644 --- a/web/src/app/modules/views/side/modules/history-view/components/history-view.component.ts +++ b/web/src/app/modules/views/side/modules/history-view/components/history-view.component.ts @@ -1,10 +1,7 @@ import { Component } from '@angular/core'; -import { Requirement } from '../../../../../../model/Requirement'; import { IContainer } from '../../../../../../model/IContainer'; -import { TestSpecification } from '../../../../../../model/TestSpecification'; import { NavigatorService } from '../../../../../navigation/modules/navigator/services/navigator.service'; import { SpecmateDataService } from '../../../../../data/modules/data-service/services/specmate-data.service'; -import { History } from '../../../../../../model/History'; import { HistoryEntry } from '../../../../../../model/HistoryEntry'; @Component({ @@ -13,8 +10,8 @@ import { HistoryEntry } from '../../../../../../model/HistoryEntry'; selector: 'history-view' }) export class HistoryView { - public modelHistoryEntries: HistoryEntry[]; + public modelHistoryEntries: HistoryEntry[]; public isCollapsed = true; constructor( @@ -22,19 +19,20 @@ export class HistoryView { private dataService: SpecmateDataService) { } ngOnInit() { - this.navigator.hasNavigated.subscribe((elem: IContainer) => { - if (elem === undefined) { - return; - } - this.dataService.performQuery(elem.url, 'history', { type: 'container' }) - .then((history: History) => { - if (history !== undefined) { - this.modelHistoryEntries = history.entries; - } else { - this.modelHistoryEntries = []; - } - }); - }); + this.navigator.hasNavigated.subscribe(() => this.loadHistory()); + this.dataService.committed.subscribe(() => this.loadHistory()); + } + + private async loadHistory(): Promise { + if (this.navigator.currentElement === undefined) { + return; + } + const history = await this.dataService.performQuery(this.navigator.currentElement.url, 'history', { type: 'container' }); + if (history !== undefined) { + this.modelHistoryEntries = history.entries; + } else { + this.modelHistoryEntries = []; + } } public getDeletedObjectName(s: string): string { From c16e509ec53b9451293449f732dcb9ad9a69432a Mon Sep 17 00:00:00 2001 From: sebeder <23170307+sebeder@users.noreply.github.com> Date: Mon, 26 Nov 2018 16:17:58 +0100 Subject: [PATCH 25/44] Selecting model as fallback (#336) --- .../components/graphical-editor.component.html | 2 +- .../graphical-editor/components/graphical-editor.component.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.html b/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.html index fd64e456b..27c4d1b83 100644 --- a/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.html +++ b/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.html @@ -16,7 +16,7 @@
    {{name}}
    - + diff --git a/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.ts b/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.ts index 7949c5dfe..7f433895e 100644 --- a/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.ts +++ b/web/src/app/modules/views/main/editors/modules/graphical-editor/components/graphical-editor.component.ts @@ -289,6 +289,9 @@ export class GraphicalEditor { this.editorToolsService.activateDefaultTool(); } } + if (!this.selectedElementService.hasSelection) { + this.selectedElementService.select(this.model); + } } private select(element: IContainer, event: MouseEvent): void { From 32aad36cd0900b881038c3e4dc53a0070351a85c Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Tue, 27 Nov 2018 08:18:41 +0100 Subject: [PATCH 26/44] fixed review comments --- .../src/com/specmate/emfrest/crud/CopyService.java | 4 ++-- .../src/com/specmate/emfrest/crud/CrudUtil.java | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CopyService.java b/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CopyService.java index be95ed362..63e50ee67 100644 --- a/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CopyService.java +++ b/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CopyService.java @@ -20,7 +20,7 @@ public class CopyService extends RestServiceBase { public String getServiceName() { return "duplicate"; } - + @Override public boolean canPost(Object target, Object object) { return target instanceof CEGModel || target instanceof Process || target instanceof TestSpecification; @@ -29,6 +29,6 @@ public boolean canPost(Object target, Object object) { @Override public RestResult post(Object target, Object child, String token) throws SpecmateException, SpecmateValidationException { - return CrudUtil.duplicate(target, Arrays.asList(TestSpecification.class,Folder.class)); + return CrudUtil.duplicate(target, Arrays.asList(TestSpecification.class, Folder.class)); } } diff --git a/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CrudUtil.java b/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CrudUtil.java index 9202f8319..c8125548e 100644 --- a/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CrudUtil.java +++ b/bundles/specmate-emfrest/src/com/specmate/emfrest/crud/CrudUtil.java @@ -74,16 +74,19 @@ public static RestResult update(Object target, EObject update, String userNam * Copies an object recursively with all children and adds the copy to the * parent of the object. The duplicate gets a name that is guaranteed to be * unique within the parent. - * + * * @param target - * @param avoidRecurse + * The target object that shall be duplicated + * @param childrenCopyBlackList + * A list of element types. Child-Elements of target are only + * copied if the are of a type that is not on the blacklist * @return * @throws SpecmateException */ - public static RestResult duplicate(Object target, List> avoidRecurse) + public static RestResult duplicate(Object target, List> childrenCopyBlackList) throws SpecmateException { EObject original = (EObject) target; - ISpecmateModelObject copy = filteredCopy(avoidRecurse, original); + ISpecmateModelObject copy = filteredCopy(childrenCopyBlackList, original); IContainer parent = (IContainer) original.eContainer(); setUniqueCopyId(copy, parent); parent.getContents().add(copy); From b32824ad763aa36061478b1912ce885c488fa801 Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Tue, 27 Nov 2018 08:33:55 +0100 Subject: [PATCH 27/44] fix bundle index --- bundles/cnf/localrepo/index.xml | 36184 ------------------------ bundles/cnf/localrepo/index.xml.sha | 1 - bundles/cnf/releaserepo/index.xml | 2 +- bundles/cnf/releaserepo/index.xml.sha | 2 +- 4 files changed, 2 insertions(+), 36187 deletions(-) delete mode 100644 bundles/cnf/localrepo/index.xml delete mode 100644 bundles/cnf/localrepo/index.xml.sha diff --git a/bundles/cnf/localrepo/index.xml b/bundles/cnf/localrepo/index.xml deleted file mode 100644 index 8e08e8238..000000000 --- a/bundles/cnf/localrepo/index.xml +++ /dev/null @@ -1,36184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bundles/cnf/localrepo/index.xml.sha b/bundles/cnf/localrepo/index.xml.sha deleted file mode 100644 index 870ea5775..000000000 --- a/bundles/cnf/localrepo/index.xml.sha +++ /dev/null @@ -1 +0,0 @@ -79659d8793c884ee6d323bd0455d746ac2ff61d150aa6fc4395cbf5f24e7ab75 \ No newline at end of file diff --git a/bundles/cnf/releaserepo/index.xml b/bundles/cnf/releaserepo/index.xml index 7b708d89e..d7cc25a7f 100644 --- a/bundles/cnf/releaserepo/index.xml +++ b/bundles/cnf/releaserepo/index.xml @@ -1,2 +1,2 @@ - + diff --git a/bundles/cnf/releaserepo/index.xml.sha b/bundles/cnf/releaserepo/index.xml.sha index d25c4d07e..3b8ae786c 100644 --- a/bundles/cnf/releaserepo/index.xml.sha +++ b/bundles/cnf/releaserepo/index.xml.sha @@ -1 +1 @@ -588e9daeffa76506497afdf3ef329dcd7523eb8a8431ee9963eab24645a30b73 \ No newline at end of file +f3cdc0cdf7ee64d9e83fce2f4444215c1db183ce1e543b7c40e99d6f80c165d5 \ No newline at end of file From d782ea1e48da25bad0ccf8f6f6b9971a935cc106 Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Tue, 27 Nov 2018 08:37:37 +0100 Subject: [PATCH 28/44] fix bundle index --- bundles/cnf/localrepo/index.xml | 36184 ------------------------ bundles/cnf/localrepo/index.xml.sha | 1 - bundles/cnf/releaserepo/index.xml | 2 +- bundles/cnf/releaserepo/index.xml.sha | 2 +- 4 files changed, 2 insertions(+), 36187 deletions(-) delete mode 100644 bundles/cnf/localrepo/index.xml delete mode 100644 bundles/cnf/localrepo/index.xml.sha diff --git a/bundles/cnf/localrepo/index.xml b/bundles/cnf/localrepo/index.xml deleted file mode 100644 index 8e08e8238..000000000 --- a/bundles/cnf/localrepo/index.xml +++ /dev/null @@ -1,36184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bundles/cnf/localrepo/index.xml.sha b/bundles/cnf/localrepo/index.xml.sha deleted file mode 100644 index 870ea5775..000000000 --- a/bundles/cnf/localrepo/index.xml.sha +++ /dev/null @@ -1 +0,0 @@ -79659d8793c884ee6d323bd0455d746ac2ff61d150aa6fc4395cbf5f24e7ab75 \ No newline at end of file diff --git a/bundles/cnf/releaserepo/index.xml b/bundles/cnf/releaserepo/index.xml index 7b708d89e..cb098b4e8 100644 --- a/bundles/cnf/releaserepo/index.xml +++ b/bundles/cnf/releaserepo/index.xml @@ -1,2 +1,2 @@ - + diff --git a/bundles/cnf/releaserepo/index.xml.sha b/bundles/cnf/releaserepo/index.xml.sha index d25c4d07e..3687b487a 100644 --- a/bundles/cnf/releaserepo/index.xml.sha +++ b/bundles/cnf/releaserepo/index.xml.sha @@ -1 +1 @@ -588e9daeffa76506497afdf3ef329dcd7523eb8a8431ee9963eab24645a30b73 \ No newline at end of file +d115cf226addc47b313f6eca5f9889aff870c6ce55d2e37e2a17d5278e8ecf48 \ No newline at end of file From f288e8a044eebaebca506bd0f977de474a6a3d9a Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Tue, 27 Nov 2018 08:48:51 +0100 Subject: [PATCH 29/44] fix bnd file --- bundles/specmate-integration-test/bnd.bnd | 1 - 1 file changed, 1 deletion(-) diff --git a/bundles/specmate-integration-test/bnd.bnd b/bundles/specmate-integration-test/bnd.bnd index 8efa78aad..2bc93dc47 100644 --- a/bundles/specmate-integration-test/bnd.bnd +++ b/bundles/specmate-integration-test/bnd.bnd @@ -238,7 +238,6 @@ Bundle-Version: 0.0.0.${tstamp} specmate-scheduler;version=snapshot,\ specmate-config;version=snapshot,\ org.apache.commons.collections4;version='[4.0.0,4.0.1)',\ - org.dkpro.token-pos-tagging;version='[1.0.0,1.0.1)' -runproperties: \ jetty.http.port=8088,\ From 3ac3cc48d3a24efab43b5318f408913f192ce0d7 Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Tue, 27 Nov 2018 09:01:08 +0100 Subject: [PATCH 30/44] fix bnd file again --- bundles/specmate-integration-test/bnd.bnd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/specmate-integration-test/bnd.bnd b/bundles/specmate-integration-test/bnd.bnd index 2bc93dc47..e19638828 100644 --- a/bundles/specmate-integration-test/bnd.bnd +++ b/bundles/specmate-integration-test/bnd.bnd @@ -238,7 +238,7 @@ Bundle-Version: 0.0.0.${tstamp} specmate-scheduler;version=snapshot,\ specmate-config;version=snapshot,\ org.apache.commons.collections4;version='[4.0.0,4.0.1)',\ - + org.apache.commons.lang3;version='[3.3.2,3.3.3)' -runproperties: \ jetty.http.port=8088,\ osgi.console=,\ From 6b2c9c8032a539c127dcf49b4d393dc5dc58d7ad Mon Sep 17 00:00:00 2001 From: sebeder <23170307+sebeder@users.noreply.github.com> Date: Tue, 27 Nov 2018 09:12:00 +0100 Subject: [PATCH 31/44] Show errors in library models (#335) * First version * generated code --- .../components/links-actions.component.html | 10 ++-- .../additional-information.service.ts | 48 ++++++++----------- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html index caa2eb7b3..47db26cda 100644 --- a/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html +++ b/web/src/app/modules/views/side/modules/links-actions/components/links-actions.component.html @@ -1,4 +1,4 @@ -
    +
    {{'LinksandActions' | translate}} @@ -18,16 +18,16 @@
    -
  • +
  • -
  • +
  • -
  • +
  • -
  • +
  • {{'testspec.skeleton' | translate}}: