Commit 2466b7d4 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '805-export-of-pdmap' into 'devel_12.2.x'

Resolve "export of pdmap submap to SBML crash"

See merge request !756
parents 7102f2a4 17e9fa58
Pipeline #9963 passed with stage
in 10 minutes and 27 seconds
......@@ -8,6 +8,8 @@ minerva (12.2.3) stable; urgency=medium
* Bug fix: updating terms of use could crash when list of users was removed
in separate tab or by another user (#797)
* Bug fix: name of the checkbox in ADD PROJECT window adjusted (#799)
* Bug fix: export of reaction to SBML didn't work when lines on the map were
too short (#805)
-- Piotr Gawron <piotr.gawron@uni.lu> Wed, 24 Apr 2019 17:00:00 +0200
......
......@@ -37,6 +37,7 @@ import lcsb.mapviewer.converter.annotation.XmlAnnotationParser;
import lcsb.mapviewer.model.graphics.ArrowType;
import lcsb.mapviewer.model.map.BioEntity;
import lcsb.mapviewer.model.map.InconsistentModelException;
import lcsb.mapviewer.modelutils.map.ElementUtils;
public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.sbml.jsbml.AbstractNamedSBase>
extends XmlParser {
......@@ -81,18 +82,28 @@ public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.s
public void exportElements() throws InconsistentModelException {
Collection<T> speciesList = getElementList();
for (T species : speciesList) {
S sbmlElement = getSbmlElement(species);
for (T bioEntity : speciesList) {
try {
S sbmlElement = getSbmlElement(bioEntity);
if (sbmlElementByElementId.get(species.getElementId()) != null) {
throw new InconsistentModelException("More than one species with id: " + species.getElementId());
if (sbmlElementByElementId.get(bioEntity.getElementId()) != null) {
throw new InconsistentModelException("More than one species with id: " + bioEntity.getElementId());
}
sbmlElementByElementId.put(bioEntity.getElementId(), sbmlElement);
} catch (Exception e) {
throw new InconsistentModelException(new ElementUtils().getElementTag(bioEntity) +
"Problem with exporting bioEntity", e);
}
sbmlElementByElementId.put(species.getElementId(), sbmlElement);
}
if (isExtensionEnabled(SbmlExtension.LAYOUT)) {
for (T species : speciesList) {
AbstractReferenceGlyph elementGlyph = createGlyph(species);
sbmlGlyphByElementId.put(species.getElementId(), elementGlyph);
for (T bioEntity : speciesList) {
try {
AbstractReferenceGlyph elementGlyph = createGlyph(bioEntity);
sbmlGlyphByElementId.put(bioEntity.getElementId(), elementGlyph);
} catch (Exception e) {
throw new InconsistentModelException(new ElementUtils().getElementTag(bioEntity) +
"Problem with exporting bioEntity", e);
}
}
}
}
......@@ -294,7 +305,7 @@ public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.s
BoundingBox boundingBox = createBoundingBox(-2, 0, 4, 4);
result.getGroup().setFill(getColorDefinition(Color.WHITE).getId());
result.setBoundingBox(boundingBox);
Ellipse ellipse= new Ellipse();
Ellipse ellipse = new Ellipse();
ellipse.setAbsoluteCx(false);
ellipse.setAbsoluteCy(false);
ellipse.setAbsoluteRx(true);
......@@ -366,7 +377,7 @@ public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.s
polygon.addElement(createRenderPoint(33, 100));
polygon.addElement(createRenderPoint(33, 0));
result.getGroup().addElement(polygon);
Polygon crossBar = new Polygon();
crossBar.addElement(createRenderPoint(0, 0));
crossBar.addElement(createRenderPoint(0, 100));
......@@ -408,12 +419,11 @@ public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.s
}
public void setProvideDefaults(boolean provideDefaults) {
this.provideDefaults= provideDefaults;
this.provideDefaults = provideDefaults;
}
protected boolean isProvideDefaults() {
return provideDefaults;
}
}
......@@ -238,6 +238,7 @@ public class SbmlParser implements IConverter {
}
}
}
return true;
}
......
......@@ -48,6 +48,7 @@ import lcsb.mapviewer.model.map.reaction.Reactant;
import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.model.map.reaction.ReactionNode;
import lcsb.mapviewer.model.map.species.Element;
import lcsb.mapviewer.modelutils.map.ElementUtils;
public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sbml.jsbml.Reaction> {
/**
......@@ -217,8 +218,12 @@ public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sb
assignStyleToGlyph(reactantGlyph, style);
}
Point p = reactantGlyph.getCurve().getCurveSegment(0).getStart();
reactantEndPoint = new Point2D.Double(p.getX(), p.getY());
if (reactantGlyph.getCurve().getCurveSegmentCount() > 0) {
Point p = reactantGlyph.getCurve().getCurveSegment(0).getStart();
reactantEndPoint = new Point2D.Double(p.getX(), p.getY());
} else {
reactantEndPoint = new Point2D.Double(reactant.getElement().getCenterX(), reactant.getElement().getCenterY());
}
}
if (reactionGlyph.getCurve().getCurveSegmentCount() > 0) {
Point p = reactionGlyph.getCurve().getCurveSegment(reactionGlyph.getCurve().getCurveSegmentCount() - 1).getEnd();
......@@ -254,8 +259,12 @@ public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sb
assignStyleToGlyph(productGlyph, style);
}
Point p = productGlyph.getCurve().getCurveSegment(0).getStart();
productStartPoint = new Point2D.Double(p.getX(), p.getY());
if (productGlyph.getCurve().getCurveSegmentCount() > 0) {
Point p = productGlyph.getCurve().getCurveSegment(0).getStart();
productStartPoint = new Point2D.Double(p.getX(), p.getY());
} else {
productStartPoint = new Point2D.Double(product.getElement().getCenterX(), product.getElement().getCenterY());
}
}
if (segmentCount < reactionGlyph.getCurve().getCurveSegmentCount()) {
......@@ -360,6 +369,9 @@ public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sb
curve.addCurveSegment(segment);
}
}
if (curve.getCurveSegmentCount() == 0) {
logger.warn(new ElementUtils().getElementTag(node) + " Problematic line");
}
return curve;
}
......
......@@ -30,7 +30,6 @@ import org.sbml.jsbml.ext.render.LocalStyle;
import org.sbml.jsbml.ext.render.RenderGroup;
import org.w3c.dom.Node;
import lcsb.mapviewer.common.XmlParser;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.exception.InvalidStateException;
import lcsb.mapviewer.common.exception.InvalidXmlSchemaException;
......@@ -154,8 +153,8 @@ public class SbmlReactionParser extends SbmlBioEntityParser {
}
PolylineData line = getLineFromReferenceGlyph(speciesRefernceGlyph);
if (line == null) {
throw new InvalidArgumentException("Line undefined for element " + minervaElement.getElementId()
if (line.length() == 0) {
logger.warn("Line undefined for element " + minervaElement.getElementId()
+ " in reaction " + reactionWithLayout.getElementId());
}
if (minervaNode instanceof Reactant) {
......@@ -217,8 +216,9 @@ public class SbmlReactionParser extends SbmlBioEntityParser {
}
getMinervaModel().addReaction(reactionWithLayout);
} catch (InvalidArgumentException e) {
throw new InvalidInputDataExecption(e);
} catch (Exception e) {
throw new InvalidInputDataExecption(
new ElementUtils().getElementTag(source) + "Problem with parsing reaction layout", e);
}
}
Set<Reaction> elementsToRemove = new HashSet<>();
......@@ -450,6 +450,9 @@ public class SbmlReactionParser extends SbmlBioEntityParser {
line.addPoint(end);
}
}
if (line == null) {
return new PolylineData();
}
return line;
}
......
......@@ -672,6 +672,21 @@ public class SbmlExporterTest extends SbmlTestFunctions {
ListComparator<Line2D> comparator = new ListComparator<>(new LineComparator(Configuration.EPSILON));
assertEquals(0, comparator.compare(lines1, lines2));
}
@Test
public void testExportIronMetabolismReaction() throws Exception {
try {
Model originalModel = new CellDesignerXmlParser()
.createModel(new ConverterParams().filename("testFiles/cell_designer_problems/iron_metabolism_reaction.xml"));
exporter.setProvideDefaults(false);
String xml = exporter.toXml(originalModel);
assertNotNull(xml);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
......@@ -248,4 +248,32 @@ public class SbmlReactionParserTest {
}
}
@Test
public void testParseReactionWithProductWithoutLayout() throws Exception {
try {
Model model = parser
.createModel(new ConverterParams().filename("testFiles/small/reaction/product_without_layout.xml"));
Reaction reaction = model.getReactions().iterator().next();
assertNotNull(reaction);
assertTrue(reaction instanceof Reaction);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testParseReactionWithReactantWithoutLayout() throws Exception {
try {
Model model = parser
.createModel(new ConverterParams().filename("testFiles/small/reaction/reactant_without_layout.xml"));
Reaction reaction = model.getReactions().iterator().next();
assertNotNull(reaction);
assertTrue(reaction instanceof Reaction);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level2/version4" xmlns:celldesigner="http://www.sbml.org/2001/ns/celldesigner" level="2" version="4">
<model metaid="Dopamine_Neurotransmitter_Release_Cycle" id="A_comprehensive_Parkinsons_disease_map">
<annotation>
<celldesigner:extension>
<celldesigner:modelVersion>4.0</celldesigner:modelVersion>
<celldesigner:modelDisplay sizeX="9000" sizeY="5500"/>
<celldesigner:listOfCompartmentAliases/>
<celldesigner:listOfComplexSpeciesAliases>
<celldesigner:complexSpeciesAlias id="csa106" species="irme_458">
<celldesigner:activity>inactive</celldesigner:activity>
<celldesigner:bounds x="2247.5" y="2007.0" w="103.0" h="171.0"/>
<celldesigner:font size="12"/>
<celldesigner:view state="usual"/>
<celldesigner:backupSize w="0.0" h="0.0"/>
<celldesigner:backupView state="none"/>
<celldesigner:usualView>
<celldesigner:boxSize width="103.0" height="171.0"/>
<celldesigner:singleLine width="2.0"/>
<celldesigner:paint color="fff7f7f7" scheme="Color"/>
</celldesigner:usualView>
<celldesigner:briefView>
<celldesigner:innerPosition x="0.0" y="0.0"/>
<celldesigner:boxSize width="80.0" height="60.0"/>
<celldesigner:singleLine width="2.0"/>
<celldesigner:paint color="fff7f7f7" scheme="Color"/>
</celldesigner:briefView>
<celldesigner:info state="empty" angle="-1.5707963267948966"/>
</celldesigner:complexSpeciesAlias>
</celldesigner:listOfComplexSpeciesAliases>
<celldesigner:listOfSpeciesAliases>
<celldesigner:speciesAlias id="sa10326" species="irme_72">
<celldesigner:activity>inactive</celldesigner:activity>
<celldesigner:bounds x="2378.000000000001" y="2072.166666666668" w="40.0" h="40.0"/>
<celldesigner:font size="12"/>
<celldesigner:view state="usual"/>
<celldesigner:usualView>
<celldesigner:boxSize width="40.0" height="40.0"/>
<celldesigner:singleLine width="1.0"/>
<celldesigner:paint color="ff9999ff" scheme="Color"/>
</celldesigner:usualView>
<celldesigner:briefView>
<celldesigner:innerPosition x="7906.815893308081" y="5845.130208333333"/>
<celldesigner:boxSize width="40.0" height="40.0"/>
<celldesigner:singleLine width="1.0"/>
<celldesigner:paint color="ff9999ff" scheme="Color"/>
</celldesigner:briefView>
<celldesigner:info state="empty" angle="-1.5707963267948966"/>
</celldesigner:speciesAlias>
</celldesigner:listOfSpeciesAliases>
<celldesigner:listOfGroups/>
<celldesigner:listOfProteins/>
<celldesigner:listOfGenes/>
<celldesigner:listOfRNAs/>
<celldesigner:listOfAntisenseRNAs/>
<celldesigner:listOfLayers/>
<celldesigner:listOfBlockDiagrams/>
</celldesigner:extension>
</annotation>
<listOfUnitDefinitions>
<unitDefinition metaid="substance" id="substance" name="substance">
<listOfUnits>
<unit metaid="CDMT00539" kind="mole"/>
</listOfUnits>
</unitDefinition>
<unitDefinition metaid="volume" id="volume" name="volume">
<listOfUnits>
<unit metaid="CDMT00540" kind="litre"/>
</listOfUnits>
</unitDefinition>
<unitDefinition metaid="area" id="area" name="area">
<listOfUnits>
<unit metaid="CDMT00541" kind="metre" exponent="2"/>
</listOfUnits>
</unitDefinition>
<unitDefinition metaid="length" id="length" name="length">
<listOfUnits>
<unit metaid="CDMT00542" kind="metre"/>
</listOfUnits>
</unitDefinition>
<unitDefinition metaid="time" id="time" name="time">
<listOfUnits>
<unit metaid="CDMT00543" kind="second"/>
</listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfCompartments>
<compartment metaid="default" id="default" size="1" units="volume"/>
<compartment metaid="5" id="5" name="Mitochondrial_space_ROS_space_Metabolism" size="1" units="volume" outside="default"/>
</listOfCompartments>
<listOfSpecies>
<species metaid="irme_458" id="irme_458" name="labile iron pool" compartment="default" initialAmount="0">
<annotation>
<celldesigner:extension>
<celldesigner:positionToCompartment>inside</celldesigner:positionToCompartment>
<celldesigner:speciesIdentity>
<celldesigner:class>COMPLEX</celldesigner:class>
<celldesigner:hypothetical>true</celldesigner:hypothetical>
<celldesigner:name>labile iron pool</celldesigner:name>
</celldesigner:speciesIdentity>
</celldesigner:extension>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">
<rdf:Description rdf:about="#irme_458">
<bqbiol:isDescribedBy>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:pubmed:27293957"/>
</rdf:Bag>
</bqbiol:isDescribedBy>
</rdf:Description>
</rdf:RDF>
</annotation>
</species>
<species metaid="irme_72" id="irme_72" name="Fe2_plus_" compartment="default" initialAmount="0">
<annotation>
<celldesigner:extension>
<celldesigner:positionToCompartment>inside</celldesigner:positionToCompartment>
<celldesigner:speciesIdentity>
<celldesigner:class>ION</celldesigner:class>
<celldesigner:name>Fe2_plus_</celldesigner:name>
</celldesigner:speciesIdentity>
</celldesigner:extension>
</annotation>
</species>
</listOfSpecies>
<listOfReactions>
<reaction metaid="re4888" id="re4888" reversible="false">
<annotation>
<celldesigner:extension>
<celldesigner:reactionType>POSITIVE_INFLUENCE</celldesigner:reactionType>
<celldesigner:baseReactants>
<celldesigner:baseReactant species="irme_458" alias="csa106">
<celldesigner:linkAnchor position="E"/>
</celldesigner:baseReactant>
</celldesigner:baseReactants>
<celldesigner:baseProducts>
<celldesigner:baseProduct species="irme_72" alias="sa10326">
<celldesigner:linkAnchor position="W"/>
</celldesigner:baseProduct>
</celldesigner:baseProducts>
<celldesigner:connectScheme connectPolicy="square">
<celldesigner:listOfLineDirection>
<celldesigner:lineDirection index="0" value="horizontal"/>
<celldesigner:lineDirection index="1" value="vertical"/>
<celldesigner:lineDirection index="2" value="horizontal"/>
</celldesigner:listOfLineDirection>
</celldesigner:connectScheme>
<celldesigner:editPoints>0.8391667847539281,0.009990080770847953 0.8393084880263331,-0.0019129941901638858</celldesigner:editPoints>
<celldesigner:line width="1.0" color="ff000000"/>
</celldesigner:extension>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">
<rdf:Description rdf:about="#re4888">
<bqbiol:isDescribedBy>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:pubmed:25231526"/>
</rdf:Bag>
</bqbiol:isDescribedBy>
<bqbiol:isDescribedBy>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:pubmed:26106291"/>
</rdf:Bag>
</bqbiol:isDescribedBy>
</rdf:Description>
</rdf:RDF>
</annotation>
<listOfReactants>
<speciesReference metaid="CDMT00414" species="irme_458">
<annotation>
<celldesigner:extension>
<celldesigner:alias>csa106</celldesigner:alias>
</celldesigner:extension>
</annotation>
</speciesReference>
</listOfReactants>
<listOfProducts>
<speciesReference metaid="CDMT00415" species="irme_72">
<annotation>
<celldesigner:extension>
<celldesigner:alias>sa10326</celldesigner:alias>
</celldesigner:extension>
</annotation>
</speciesReference>
</listOfProducts>
</reaction>
</listOfReactions>
</model>
</sbml>
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!-- Created by minerva version Unknown on 2019-04-25 at 08:13:40 CEST with
JSBML version 1.4. -->
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core"
layout:required="false" level="3" multi:required="true"
render:required="false" version="2"
xmlns:layout="http://www.sbml.org/sbml/level3/version1/layout/version1"
xmlns:multi="http://www.sbml.org/sbml/level3/version1/multi/version1"
xmlns:render="http://www.sbml.org/sbml/level3/version1/render/version1">
<model id="A_comprehensive_Parkinsons_disease_map"
name="iron_metabolism_reaction">
<notes>
<body xmlns="http://www.w3.org/1999/xhtml">
<p />
</body>
</notes>
<layout:listOfLayouts
xmlns:layout="http://www.sbml.org/sbml/level3/version1/layout/version1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<layout:layout layout:id="minerva_layout">
<render:listOfRenderInformation
xmlns:render="http://www.sbml.org/sbml/level3/version1/render/version1">
<render:renderInformation
render:id="minerva_definitions">
<render:listOfColorDefinitions>
<render:colorDefinition
render:id="color_FFF7F7F7" render:value="#F7F7F7FF" />
<render:colorDefinition
render:id="color_FF000000" render:value="#000000FF" />
<render:colorDefinition
render:id="color_FF9999FF" render:value="#9999FFFF" />
</render:listOfColorDefinitions>
<render:listOfLineEndings>
<render:lineEnding render:id="line_ending_NONE">
<render:g />
</render:lineEnding>
<render:lineEnding render:id="line_ending_OPEN">
<layout:boundingBox>
<layout:position layout:x="-12" layout:y="-6" />
<layout:dimensions layout:height="12"
layout:width="12" />
</layout:boundingBox>
<render:g>
<render:polygon>
<render:listOfElements>
<render:element render:x="0%" render:y="0%"
xsi:type="RenderPoint" />
<render:element render:x="100%" render:y="50%"
xsi:type="RenderPoint" />
<render:element render:x="0%" render:y="100%"
xsi:type="RenderPoint" />
<render:element render:x="100%" render:y="50%"
xsi:type="RenderPoint" />
</render:listOfElements>
</render:polygon>
</render:g>
</render:lineEnding>
</render:listOfLineEndings>
<render:listOfStyles>
<render:style render:idList="csa106">
<render:g render:fill="color_FFF7F7F7"
render:font-size="12" render:stroke-width="2.0">
<render:rectangle render:height="100%"
render:rx="0%" render:ry="0%" render:stroke="color_FF000000"
render:width="100%" render:x="0%" render:y="0%" />
</render:g>
</render:style>
<render:style render:idList="text_csa106">
<render:g render:text-anchor="middle"
render:vtext-anchor="middle" />
</render:style>
<render:style render:idList="sa10326">
<render:g render:fill="color_FF9999FF"
render:font-size="12" render:stroke-width="1.0">
<render:ellipse render:cx="50%" render:cy="50%"
render:rx="50%" render:ry="50%" render:stroke="color_FF000000" />
</render:g>
</render:style>
<render:style render:idList="text_sa10326">
<render:g render:text-anchor="middle"
render:vtext-anchor="middle" />
</render:style>
<render:style render:idList="node_1">
<render:g render:endHead="line_ending_NONE"
render:fill="color_FF000000" render:stroke="color_FF000000"
render:stroke-width="1.0" />
</render:style>
<render:style render:idList="node_2">
<render:g render:endHead="line_ending_OPEN"
render:fill="color_FF000000" render:stroke="color_FF000000"
render:stroke-width="1.0" />
</render:style>
<render:style render:idList="re4888_0">
<render:g render:fill="color_FF000000"
render:stroke="color_FF000000" render:stroke-width="1.0" />
</render:style>
</render:listOfStyles>
</render:renderInformation>
</render:listOfRenderInformation>
<layout:dimensions layout:height="4185"
layout:width="4665.500000000001" />
<layout:listOfCompartmentGlyphs>
<layout:compartmentGlyph
layout:compartment="default" layout:id="default_compartment">
<layout:boundingBox>
<layout:position layout:x="0" layout:y="0" />
<layout:dimensions layout:height="4185"
layout:width="4665.500000000001" />
</layout:boundingBox>
</layout:compartmentGlyph>
</layout:listOfCompartmentGlyphs>
<layout:listOfSpeciesGlyphs>
<layout:speciesGlyph layout:id="csa106"
layout:species="species_0">
<layout:boundingBox>
<layout:position layout:x="2247.5"
layout:y="2007" />
<layout:dimensions layout:height="171"
layout:width="103" />
</layout:boundingBox>
</layout:speciesGlyph>
<layout:speciesGlyph layout:id="sa10326"
layout:species="species_1">
<layout:boundingBox>
<layout:position layout:x="2378.000000000001"
layout:y="2072.166666666668" />
<layout:dimensions layout:height="40"
layout:width="40" />
</layout:boundingBox>
</layout:speciesGlyph>
</layout:listOfSpeciesGlyphs>
<layout:listOfReactionGlyphs>
<layout:reactionGlyph layout:id="re4888_0"
layout:reaction="re4888">
<layout:curve>
<layout:listOfCurveSegments>
<layout:curveSegment xsi:type="LineSegment">
<layout:start layout:x="2373.5803457559946"
layout:y="2092.167623163763" />
<layout:end layout:x="2398.000000000001"
layout:y="2092.166666666668" />
</layout:curveSegment>
</layout:listOfCurveSegments>
</layout:curve>
<layout:listOfSpeciesReferenceGlyphs>
<layout:speciesReferenceGlyph
layout:id="node_1" layout:role="substrate"
layout:speciesGlyph="csa106">