Interim commit

- added data source name, device id, and local account id to display
This commit is contained in:
Raman Arora 2020-05-19 14:52:51 -04:00
parent 66898e8519
commit b6631a1d12
3 changed files with 321 additions and 10 deletions

View File

@ -973,3 +973,10 @@ CallLogArtifactViewer.dateTimeLabel.text=Date/Time.....
CallLogArtifactViewer.directionLabel.text=Direction
CallLogArtifactViewer.toOrFromNameLabel.text=Name, if available
CallLogArtifactViewer.personaButton1.text=Persona
CallLogArtifactViewer.dataSourceNameLabel.text=jLabel2
CallLogArtifactViewer.jLabel2.text=Device Id
CallLogArtifactViewer.deviceIdLabel.text=jLabel3
CallLogArtifactViewer.jLabel3.text=jLabel3
CallLogArtifactViewer.localAccountIdLabel.text=jLabel1
CallLogArtifactViewer.localAccountLabel.text=Local Account
CallLogArtifactViewer.jLabel4.text=Data Source Name

View File

@ -11,7 +11,7 @@
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-99"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,44,0,0,1,-99"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
@ -192,7 +192,7 @@
<Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jButton2" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="46" max="32767" attributes="0"/>
<EmptySpace pref="86" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="jButton3" alignment="3" min="-2" max="-2" attributes="0"/>
@ -245,5 +245,156 @@
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="bottomPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Last"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="otherAttributesPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="First"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel3">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.jLabel3.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="otherAttributesListPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Last"/>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="413" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="100" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="localAccountInfoPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Last"/>
</Constraint>
</Constraints>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jLabel4" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="localAccountLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="localAccountIdLabel" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="dataSourceNameLabel" pref="130" max="32767" attributes="0"/>
<Component id="deviceIdLabel" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace pref="140" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="localAccountLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="localAccountIdLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="dataSourceNameLabel" min="-2" max="-2" attributes="0"/>
<Component id="jLabel4" min="-2" pref="16" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deviceIdLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="22" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel4">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.jLabel4.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="dataSourceNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.dataSourceNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="deviceIdLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.deviceIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="localAccountLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.localAccountLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="localAccountIdLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="CallLogArtifactViewer.localAccountIdLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -29,6 +29,7 @@ import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException;
/**
@ -75,6 +76,17 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
jLabel9 = new javax.swing.JLabel();
jButton3 = new javax.swing.JButton();
otherParticipantsLabel = new javax.swing.JLabel();
bottomPanel = new javax.swing.JPanel();
otherAttributesPanel = new javax.swing.JPanel();
jLabel3 = new javax.swing.JLabel();
otherAttributesListPanel = new javax.swing.JPanel();
localAccountInfoPanel = new javax.swing.JPanel();
jLabel4 = new javax.swing.JLabel();
dataSourceNameLabel = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
deviceIdLabel = new javax.swing.JLabel();
localAccountLabel = new javax.swing.JLabel();
localAccountIdLabel = new javax.swing.JLabel();
setLayout(new java.awt.BorderLayout());
@ -190,7 +202,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
.addGroup(otherParticipantsListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel8)
.addComponent(jButton2))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 46, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 86, Short.MAX_VALUE)
.addGroup(otherParticipantsListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel9)
.addComponent(jButton3))
@ -200,6 +212,80 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
otherParticipantsPanel.add(otherParticipantsListPanel, java.awt.BorderLayout.CENTER);
add(otherParticipantsPanel, java.awt.BorderLayout.CENTER);
bottomPanel.setLayout(new java.awt.BorderLayout());
otherAttributesPanel.setLayout(new java.awt.BorderLayout());
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(CallLogArtifactViewer.class, "CallLogArtifactViewer.jLabel3.text")); // NOI18N
otherAttributesPanel.add(jLabel3, java.awt.BorderLayout.CENTER);
javax.swing.GroupLayout otherAttributesListPanelLayout = new javax.swing.GroupLayout(otherAttributesListPanel);
otherAttributesListPanel.setLayout(otherAttributesListPanelLayout);
otherAttributesListPanelLayout.setHorizontalGroup(
otherAttributesListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 413, Short.MAX_VALUE)
);
otherAttributesListPanelLayout.setVerticalGroup(
otherAttributesListPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 100, Short.MAX_VALUE)
);
otherAttributesPanel.add(otherAttributesListPanel, java.awt.BorderLayout.PAGE_END);
bottomPanel.add(otherAttributesPanel, java.awt.BorderLayout.PAGE_START);
org.openide.awt.Mnemonics.setLocalizedText(jLabel4, org.openide.util.NbBundle.getMessage(CallLogArtifactViewer.class, "CallLogArtifactViewer.jLabel4.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(dataSourceNameLabel, org.openide.util.NbBundle.getMessage(CallLogArtifactViewer.class, "CallLogArtifactViewer.dataSourceNameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(CallLogArtifactViewer.class, "CallLogArtifactViewer.jLabel2.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(deviceIdLabel, org.openide.util.NbBundle.getMessage(CallLogArtifactViewer.class, "CallLogArtifactViewer.deviceIdLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(localAccountLabel, org.openide.util.NbBundle.getMessage(CallLogArtifactViewer.class, "CallLogArtifactViewer.localAccountLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(localAccountIdLabel, org.openide.util.NbBundle.getMessage(CallLogArtifactViewer.class, "CallLogArtifactViewer.localAccountIdLabel.text")); // NOI18N
javax.swing.GroupLayout localAccountInfoPanelLayout = new javax.swing.GroupLayout(localAccountInfoPanel);
localAccountInfoPanel.setLayout(localAccountInfoPanelLayout);
localAccountInfoPanelLayout.setHorizontalGroup(
localAccountInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(localAccountInfoPanelLayout.createSequentialGroup()
.addGap(19, 19, 19)
.addGroup(localAccountInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel4)
.addComponent(jLabel2)
.addComponent(localAccountLabel))
.addGap(18, 18, 18)
.addGroup(localAccountInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(localAccountIdLabel)
.addGroup(localAccountInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(dataSourceNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 130, Short.MAX_VALUE)
.addComponent(deviceIdLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addContainerGap(140, Short.MAX_VALUE))
);
localAccountInfoPanelLayout.setVerticalGroup(
localAccountInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(localAccountInfoPanelLayout.createSequentialGroup()
.addGap(18, 18, 18)
.addGroup(localAccountInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(localAccountLabel)
.addComponent(localAccountIdLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(localAccountInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(dataSourceNameLabel)
.addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(localAccountInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(deviceIdLabel))
.addContainerGap(22, Short.MAX_VALUE))
);
bottomPanel.add(localAccountInfoPanel, java.awt.BorderLayout.PAGE_END);
add(bottomPanel, java.awt.BorderLayout.PAGE_END);
}// </editor-fold>//GEN-END:initComponents
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
@ -216,14 +302,25 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
this.toOrFromNameLabel.setEnabled(false);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel bottomPanel;
private javax.swing.JPanel callDetailsPanel;
private javax.swing.JLabel dataSourceNameLabel;
private javax.swing.JLabel dateTimeLabel;
private javax.swing.JLabel deviceIdLabel;
private javax.swing.JLabel directionLabel;
private javax.swing.JLabel durationLabel;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JLabel localAccountIdLabel;
private javax.swing.JPanel localAccountInfoPanel;
private javax.swing.JLabel localAccountLabel;
private javax.swing.JPanel otherAttributesListPanel;
private javax.swing.JPanel otherAttributesPanel;
private javax.swing.JLabel otherParticipantsLabel;
private javax.swing.JPanel otherParticipantsListPanel;
private javax.swing.JPanel otherParticipantsPanel;
@ -241,6 +338,14 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
String dateTimeStr = null;
String duration = null;
Collection<String> otherParticipants = null;
String dataSourceName = null;
String dataSourceDeviceId = null;
String localAccountId = null;
CallLogViewData(String number) {
this(number, null);
@ -274,13 +379,21 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
this.direction = direction;
}
// String getMediaType() {
// return mediaType;
// }
//
// void setMediaType(String mediaType) {
// this.mediaType = mediaType;
// }
String getDataSourceName() {
return dataSourceName;
}
void setDataSourceName(String dataSourceName) {
this.dataSourceName = dataSourceName;
}
String getDataSourceDeviceId() {
return dataSourceDeviceId;
}
void setDataSourceDeviceId(String dataSourceDeviceId) {
this.dataSourceDeviceId = dataSourceDeviceId;
}
String getDateTimeStr() {
return dateTimeStr;
@ -306,6 +419,14 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
otherParticipants = otherParticipants;
}
public String getLocalAccountId() {
return localAccountId;
}
public void setLocalAccountId(String localAccountId) {
this.localAccountId = localAccountId;
}
}
@Override
@ -357,6 +478,23 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
}
// TBD: Populate other attributs panel
this.remove(this.otherAttributesPanel);
// populate local account and data source
if (callLogViewData.getLocalAccountId() != null) {
this.localAccountIdLabel.setText(callLogViewData.getLocalAccountId());
} else {
this.localAccountLabel.setVisible(false);
this.localAccountIdLabel.setVisible(false);
}
if (callLogViewData.getDataSourceName() != null) {
this.dataSourceNameLabel.setText(callLogViewData.getDataSourceName());
}
if (callLogViewData.getDataSourceDeviceId() != null) {
this.deviceIdLabel.setText(callLogViewData.getDataSourceDeviceId());
}
}
@ -378,6 +516,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
BlackboardAttribute directionAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DIRECTION));
BlackboardAttribute numberAttr = null;
BlackboardAttribute localAccountAttr = null;
CallLogViewData callLogViewData = null;
String direction = null;
@ -387,8 +526,10 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
if (direction.equalsIgnoreCase("Incoming")) {
numberAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM));
localAccountAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO));
} else if (direction.equalsIgnoreCase("Outgoing")) {
numberAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO));
localAccountAttr = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM));
}
}
@ -436,6 +577,18 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
}
}
Content dataSource = artifact.getDataSource();
callLogViewData.setDataSourceName(dataSource.getName());
String deviceId = ((DataSource) dataSource).getDeviceId();
callLogViewData.setDataSourceDeviceId(deviceId);
if (localAccountAttr != null) {
String attrValue = localAccountAttr.getValueString();
if (attrValue.equalsIgnoreCase(deviceId) == false && attrValue.contains(",") == false ) {
callLogViewData.setLocalAccountId(attrValue);
}
}
}