From bd5f846d246aa015919dc435c6292ea75c928c4f Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Mon, 2 Mar 2020 11:08:29 -0500 Subject: [PATCH 001/106] Update viber.py Added the coalesce sqlite function to the sql statement, this function will return the first column included in it that does not contain a null value. --- InternalPythonModules/android/viber.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py index a5edef4ce9..ded45e186f 100644 --- a/InternalPythonModules/android/viber.py +++ b/InternalPythonModules/android/viber.py @@ -268,8 +268,8 @@ class ViberContactsParser(TskContactsParser): def __init__(self, contact_db): super(ViberContactsParser, self).__init__(contact_db.runQuery( """ - SELECT C.display_name AS name, - D.data2 AS number + SELECT C.display_name AS name, + coalesce(D.data2, D.data1, D.data3) AS number FROM phonebookcontact AS C JOIN phonebookdata AS D ON C._id = D.contact_id From 64d73e04348572539f174820c5888450b8015787 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Thu, 5 Mar 2020 16:44:23 -0500 Subject: [PATCH 002/106] Update viber.py If contact does not have an email or phone number then create a TSK_Contact artifact outside of comms helper so we do not loose the contact. --- InternalPythonModules/android/viber.py | 29 +++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py index ded45e186f..aadd1a2104 100644 --- a/InternalPythonModules/android/viber.py +++ b/InternalPythonModules/android/viber.py @@ -117,13 +117,28 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer): try: contacts_parser = ViberContactsParser(contacts_db) while contacts_parser.next(): - helper.addContact( - contacts_parser.get_contact_name(), - contacts_parser.get_phone(), - contacts_parser.get_home_phone(), - contacts_parser.get_mobile_phone(), - contacts_parser.get_email() - ) + if contacts_parser.get_phone() is not None: + helper.addContact( + contacts_parser.get_contact_name(), + contacts_parser.get_phone(), + contacts_parser.get_home_phone(), + contacts_parser.get_mobile_phone(), + contacts_parser.get_email() + ) + else: + current_case = Case.getCurrentCase().getSleuthkitCase() + attributes = ArrayList() + artifact = contacts_db.getDBFile().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), self._PARSER_NAME, contacts_parser.get_contact_name())) + artifact.addAttributes(attributes) + + try: + # Post the artifact to blackboard + current_case.getBlackboard().postArtifact(artifact, self._PARSER_NAME) + except Blackboard.BlackboardException as e: + self.log(Level.WARNING, "Error adding viber contacts artifact to case database.", ex ) + self._logger.log(Level.WARNING, traceback.format_exc()) + contacts_parser.close() except SQLException as ex: self._logger.log(Level.WARNING, "Error querying the viber database for contacts.", ex) From 76600c12197ff6d76410a3362a2b6a0cfe17042d Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 6 Mar 2020 10:20:41 -0500 Subject: [PATCH 003/106] 6077 display a summary image when extracted from documents --- .../filequery/Bundle.properties-MERGED | 3 ++ .../autopsy/filequery/DocumentPanel.form | 51 ++++++++++++++++--- .../autopsy/filequery/DocumentPanel.java | 48 ++++++++++++++--- .../autopsy/filequery/DocumentWrapper.java | 34 +++++++------ .../autopsy/filequery/FileSearch.java | 25 ++++++++- .../autopsy/filequery/ResultsPanel.java | 6 +-- 6 files changed, 131 insertions(+), 36 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED index ea9e846568..c5dd80db41 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED @@ -16,6 +16,9 @@ DiscoveryUiUtility.sizeLabel.text=Size: {0} {1} DiscoveryUiUtility.terraBytes.text=TB # {0} - otherInstanceCount DocumentPanel.nameLabel.more.text=\ and {0} more +DocumentPanel.numberOfImages.noImages=No images +# {0} - numberOfImages +DocumentPanel.numberOfImages.text=1 of {0} images DocumentWrapper.previewInitialValue=Preview not generated yet. FileGroup.groupSortingAlgorithm.groupName.text=Group Name FileGroup.groupSortingAlgorithm.groupSize.text=Group Size diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index 05ed6fc0c8..8064993a0c 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -24,19 +24,28 @@ - + - - + + - - + + + + + + + + + + + - + @@ -44,9 +53,15 @@ - + + + + - + + + + @@ -135,5 +150,25 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 849d3843ec..2df3a78f38 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -23,6 +23,7 @@ import java.awt.Component; import java.awt.Dimension; import java.awt.Point; import java.awt.event.MouseEvent; +import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.ListCellRenderer; @@ -58,6 +59,8 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere nameLabel = new javax.swing.JLabel(); javax.swing.JScrollPane previewScrollPane = new javax.swing.JScrollPane(); previewTextArea = new javax.swing.JTextArea(); + sampleImageLabel = new javax.swing.JLabel(); + numberOfImagesLabel = new javax.swing.JLabel(); setBorder(javax.swing.BorderFactory.createEtchedBorder()); @@ -88,6 +91,11 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere previewTextArea.setMaximumSize(new java.awt.Dimension(164, 94)); previewScrollPane.setViewportView(previewTextArea); + sampleImageLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + sampleImageLabel.setMaximumSize(new java.awt.Dimension(120, 120)); + sampleImageLabel.setMinimumSize(new java.awt.Dimension(120, 120)); + sampleImageLabel.setPreferredSize(new java.awt.Dimension(120, 120)); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -96,22 +104,32 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 648, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(isDeletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(previewScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 649, Short.MAX_VALUE) - .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(previewScrollPane) + .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() - .addComponent(nameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 17, Short.MAX_VALUE) + .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(previewScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(previewScrollPane)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -126,12 +144,19 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere private javax.swing.JLabel fileSizeLabel; private javax.swing.JLabel isDeletedLabel; private javax.swing.JLabel nameLabel; + private javax.swing.JLabel numberOfImagesLabel; private javax.swing.JTextArea previewTextArea; + private javax.swing.JLabel sampleImageLabel; private javax.swing.JLabel scoreLabel; // End of variables declaration//GEN-END:variables - @Messages({"# {0} - otherInstanceCount", - "DocumentPanel.nameLabel.more.text= and {0} more"}) + @Messages({ + "# {0} - otherInstanceCount", + "DocumentPanel.nameLabel.more.text= and {0} more", + "# {0} - numberOfImages", + "DocumentPanel.numberOfImages.text=1 of {0} images", + "DocumentPanel.numberOfImages.noImages=No images"}) + @Override public Component getListCellRendererComponent(JList list, DocumentWrapper value, int index, boolean isSelected, boolean cellHasFocus) { fileSizeLabel.setText(DiscoveryUiUtils.getFileSizeString(value.getResultFile().getFirstInstance().getSize())); @@ -139,8 +164,15 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere if (value.getResultFile().getAllInstances().size() > 1) { nameText += Bundle.DocumentPanel_nameLabel_more_text(value.getResultFile().getAllInstances().size() - 1); } + if (value.getSummary().getNumberOfImages() > 0) { + numberOfImagesLabel.setText(Bundle.DocumentPanel_numberOfImages_text(value.getSummary().getNumberOfImages())); + sampleImageLabel.setIcon(new ImageIcon(value.getSummary().getSampleImage())); + } else { + numberOfImagesLabel.setText(Bundle.DocumentPanel_numberOfImages_noImages()); + sampleImageLabel.setIcon(null); + } nameLabel.setText(nameText); - previewTextArea.setText(value.getPreview()); + previewTextArea.setText(value.getSummary().getSummaryText()); previewTextArea.setCaretPosition(0); DiscoveryUiUtils.setDeletedIcon(value.getResultFile().isDeleted(), isDeletedLabel); DiscoveryUiUtils.setScoreIcon(value.getResultFile(), scoreLabel); diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentWrapper.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentWrapper.java index a15e151673..9bf3b173ff 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentWrapper.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentWrapper.java @@ -19,55 +19,57 @@ package org.sleuthkit.autopsy.filequery; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.textsummarizer.TextSummary; /** - * Class to wrap all the information necessary for a document preview to be + * Class to wrap all the information necessary for a document summary to be * displayed. */ public class DocumentWrapper { - private String preview; + private TextSummary summary; private final ResultFile resultFile; /** * Construct a new DocumentWrapper. * * @param file The ResultFile which represents the document which the - * preview summary is created for. + * summary is created for. */ @Messages({"DocumentWrapper.previewInitialValue=Preview not generated yet."}) DocumentWrapper(ResultFile file) { - this.preview = Bundle.DocumentWrapper_previewInitialValue(); + this.summary = new TextSummary(Bundle.DocumentWrapper_previewInitialValue(), null, 0); this.resultFile = file; } /** - * Set the preview summary which exists. + * Set the summary which exists. * - * @param preview The String which should be displayed as a preview for this - * document. + * @param textSummary The TextSummary object which contains the text and + * image which should be displayed as a summary for this + * document. */ - void setPreview(String preview) { - this.preview = preview; + void setSummary(TextSummary textSummary) { + this.summary = textSummary; } /** - * Get the ResultFile which represents the document the preview summary was - * created for. + * Get the ResultFile which represents the document the summary was created + * for. * * @return The ResultFile which represents the document file which the - * preview was created for. + * summary was created for. */ ResultFile getResultFile() { return resultFile; } /** - * Get the preview summary of the document. + * Get the summary of the document. * - * @return The String which is the preview of the document. + * @return The TextSummary which is the summary of the document. */ - String getPreview() { - return preview; + TextSummary getSummary() { + return summary; } } diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index 56a6754e3f..11f1d79e1d 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -50,6 +50,7 @@ import org.imgscalr.Scalr; import org.netbeans.api.progress.ProgressHandle; import org.opencv.core.Mat; import org.opencv.highgui.VideoCapture; +import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; @@ -280,11 +281,33 @@ class FileSearch { } if (summary == null || StringUtils.isBlank(summary.getSummaryText())) { //summary text was empty grab the beginning of the file - summary = new TextSummary(getFirstLines(file), null, 0); + summary = getDefaultSummary(file); } return summary; } + private static TextSummary getDefaultSummary(AbstractFile file) { + Image image = null; + int countOfImages = 0; + try { + Content largestChild = null; + for (Content child : file.getChildren()) { + if (child instanceof AbstractFile && ImageUtils.isImageThumbnailSupported((AbstractFile) child)) { + countOfImages++; + if (largestChild == null || child.getSize() > largestChild.getSize()) { + largestChild = child; + } + } + } + if (largestChild != null) { + image = ImageUtils.getThumbnail(largestChild, ImageUtils.ICON_SIZE_LARGE); + } + } catch (TskCoreException ex) { + logger.log(Level.WARNING, "Error getting children for file: " + file.getId(), ex); + } + return new TextSummary(getFirstLines(file), image, countOfImages); + } + /** * Get the beginning of text from the specified AbstractFile. * diff --git a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java index 7ba0e452ca..7a750f50eb 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/ResultsPanel.java @@ -782,7 +782,7 @@ public class ResultsPanel extends javax.swing.JPanel { if (preview == null) { preview = new TextSummary(Bundle.ResultsPanel_unableToCreate_text(), null, 0); } - documentWrapper.setPreview(preview.getSummaryText()); + documentWrapper.setSummary(preview); return null; } @@ -792,10 +792,10 @@ public class ResultsPanel extends javax.swing.JPanel { try { get(); } catch (InterruptedException | ExecutionException ex) { - documentWrapper.setPreview(ex.getMessage()); + documentWrapper.setSummary(new TextSummary(ex.getMessage(), null, 0)); logger.log(Level.WARNING, "Document Worker Exception", ex); } catch (CancellationException ignored) { - documentWrapper.setPreview(Bundle.ResultsPanel_documentPreview_text()); + documentWrapper.setSummary(new TextSummary(Bundle.ResultsPanel_documentPreview_text(), null, 0)); //we want to do nothing in response to this since we allow it to be cancelled } documentPreviewViewer.repaint(); From bd3a79a5980acdd34885f52ca478351e00048522 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 10 Mar 2020 17:39:51 -0400 Subject: [PATCH 004/106] 6082: Create Email & Phone correlation attribute instances only for actual accounts created in CaseDB --- .../datamodel/CorrelationAttributeUtil.java | 65 +------------------ 1 file changed, 1 insertion(+), 64 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 04aa6fc16e..3d2abc5dd0 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -84,23 +84,12 @@ public class CorrelationAttributeUtil { BlackboardArtifact sourceArtifact = getCorrAttrSourceArtifact(artifact); if (sourceArtifact != null) { int artifactTypeID = sourceArtifact.getArtifactTypeID(); - if (artifactTypeID == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) { - BlackboardAttribute setNameAttr = sourceArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME)); - if (setNameAttr != null && CorrelationAttributeUtil.getEmailAddressAttrDisplayName().equals(setNameAttr.getValueString())) { - makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD, CorrelationAttributeInstance.EMAIL_TYPE_ID); - } - - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() + if (artifactTypeID == ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) { makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN, CorrelationAttributeInstance.DOMAIN_TYPE_ID); - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_CONTACT.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() - || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID()) { - makeCorrAttrFromArtifactPhoneAttr(sourceArtifact); - } else if (artifactTypeID == ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) { makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID, CorrelationAttributeInstance.USBID_TYPE_ID); makeCorrAttrFromArtifactAttr(correlationAttrs, sourceArtifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS, CorrelationAttributeInstance.MAC_TYPE_ID); @@ -169,58 +158,6 @@ public class CorrelationAttributeUtil { return sourceArtifact; } - /** - * Makes a correlation attribute instance from a phone number attribute of an - * artifact. - * - * @param artifact An artifact with a phone number attribute. - * - * @return The correlation instance artifact or null, if the phone number is - * not a valid correlation attribute. - * - * @throws TskCoreException If there is an error querying the case - * database. - * @throws CentralRepoException If there is an error querying the central - * repository. - */ - private static CorrelationAttributeInstance makeCorrAttrFromArtifactPhoneAttr(BlackboardArtifact artifact) throws TskCoreException, CentralRepoException { - CorrelationAttributeInstance corrAttr = null; - - /* - * Extract the phone number from the artifact attribute. - */ - String value = null; - if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString(); - } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString(); - } else if (null != artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) { - value = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString(); - } - - /* - * Normalize the phone number. - */ - if (value != null) { - String newValue = value.replaceAll("\\D", ""); - if (value.startsWith("+")) { - newValue = "+" + newValue; - } - value = newValue; - - /* - * Validate the phone number. Three to five digit phone numbers may - * be valid, but they are too short to use as correlation - * attributes. - */ - if (value.length() > 5) { - corrAttr = makeCorrAttr(artifact, CentralRepository.getInstance().getCorrelationTypeById(CorrelationAttributeInstance.PHONE_TYPE_ID), value); - } - } - - return corrAttr; - } - /** * Makes a correlation attribute instance for an account artifact. * From 276242d3192a029064869020b91a35fcb1c42e33 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Wed, 11 Mar 2020 11:10:02 -0400 Subject: [PATCH 005/106] Update viber.py Added check for only spaces, blanks and special characters. --- InternalPythonModules/android/viber.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py index aadd1a2104..4bc2d0c5d2 100644 --- a/InternalPythonModules/android/viber.py +++ b/InternalPythonModules/android/viber.py @@ -117,7 +117,7 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer): try: contacts_parser = ViberContactsParser(contacts_db) while contacts_parser.next(): - if contacts_parser.get_phone() is not None: + if (not(not contacts_parser.get_phone() or contacts_parser.get_phone().isspace())): helper.addContact( contacts_parser.get_contact_name(), contacts_parser.get_phone(), @@ -125,7 +125,8 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer): contacts_parser.get_mobile_phone(), contacts_parser.get_email() ) - else: + # Check if contact_name is blank and if it is not create a TSK_CONTACT otherwise ignore as not Contact Info + elif (not(not contacts_parser.get_contact_name() or contacts_parser.get_contact_name().isspace())): current_case = Case.getCurrentCase().getSleuthkitCase() attributes = ArrayList() artifact = contacts_db.getDBFile().newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT) From 219bb5b2e06da3d2a09bb1c4409ea381ce61be6a Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 11:21:47 -0400 Subject: [PATCH 006/106] Upgrade version of JNA. --- Core/nbproject/project.properties | 2 -- Core/nbproject/project.xml | 4 ---- CoreLibs/ivy.xml | 6 +----- CoreLibs/nbproject/project.properties | 4 ++-- CoreLibs/nbproject/project.xml | 16 ++++++++-------- 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index 94dffdeb9b..80e8cfd4d4 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -45,7 +45,6 @@ file.reference.jericho-html-3.3.jar=release/modules/ext/jericho-html-3.3.jar file.reference.jgraphx-v3.8.0.jar=release/modules/ext/jgraphx-v3.8.0.jar file.reference.jhighlight-1.0.3.jar=release\\modules\\ext\\jhighlight-1.0.3.jar file.reference.jmatio-1.5.jar=release\\modules\\ext\\jmatio-1.5.jar -file.reference.jna-5.1.0.jar=release\\modules\\ext\\jna-5.1.0.jar file.reference.json-simple-1.1.1.jar=release\\modules\\ext\\json-simple-1.1.1.jar file.reference.jsoup-1.11.3.jar=release\\modules\\ext\\jsoup-1.11.3.jar file.reference.jul-to-slf4j-1.7.25.jar=release\\modules\\ext\\jul-to-slf4j-1.7.25.jar @@ -97,7 +96,6 @@ file.reference.xz-1.8.jar=release\\modules\\ext\\xz-1.8.jar file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar file.reference.commons-validator-1.6.jar=release/modules/ext/commons-validator-1.6.jar -file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar file.reference.api-common-1.7.0.jar=release/modules/ext/api-common-1.7.0.jar file.reference.gax-1.44.0.jar=release/modules/ext/gax-1.44.0.jar file.reference.gax-grpc-1.44.0.jar=release/modules/ext/gax-grpc-1.44.0.jar diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 182b92a661..02d37221a7 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -615,10 +615,6 @@ ext/commons-validator-1.6.jar release/modules/ext/commons-validator-1.6.jar - - ext/jna-5.1.0.jar - release\modules\ext\jna-5.1.0.jar - ext/jbig2-imageio-3.0.2.jar release\modules\ext\jbig2-imageio-3.0.2.jar diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index 6819dac82d..4853d1f90e 100644 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -14,8 +14,7 @@ - - + @@ -73,8 +72,5 @@ - - - diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index 677f823e67..42f8292d5b 100644 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -21,7 +21,6 @@ file.reference.dom4j-1.6.1.jar=release/modules/ext/dom4j-1.6.1.jar file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar file.reference.gson-2.8.5.jar=release/modules/ext/gson-2.8.5.jar file.reference.gst1-java-core-1.0.0.jar=release\\modules\\ext\\gst1-java-core-1.0.0.jar -file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar file.reference.guava-19.0.jar=release/modules/ext/guava-19.0.jar file.reference.imageio-bmp-3.2.jar=release/modules/ext/imageio-bmp-3.2.jar file.reference.imageio-core-3.2.jar=release/modules/ext/imageio-core-3.2.jar @@ -44,6 +43,8 @@ file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0- file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar +file.reference.jna-5.5.0.jar=release\\modules\\ext\\jna-5.5.0.jar +file.reference.jna-platform-5.5.0.jar=release\\modules\\ext\\jna-platform-5.5.0.jar file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar @@ -52,7 +53,6 @@ file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar file.reference.opencv-248.jar=release/modules/ext/opencv-248.jar file.reference.openjfx-dialogs-1.0.2.jar=release/modules/ext/openjfx-dialogs-1.0.3.jar -file.reference.platform-3.4.0.jar=release/modules/ext/platform-3.4.0.jar file.reference.poi-4.0.1.jar=release\\modules\\ext\\poi-4.0.1.jar file.reference.poi-excelant-4.0.1.jar=release\\modules\\ext\\poi-excelant-4.0.1.jar file.reference.poi-ooxml-4.0.1.jar=release\\modules\\ext\\poi-ooxml-4.0.1.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index 0498669b04..d5169a8965 100644 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -806,10 +806,6 @@ ext/sigar-1.6.4.jar release/modules/ext/sigar-1.6.4.jar - - ext/jna-3.4.0.jar - release/modules/ext/jna-3.4.0.jar - ext/gson-2.8.5.jar release/modules/ext/gson-2.8.5.jar @@ -902,6 +898,10 @@ ext/commons-csv-1.4.jar release/modules/ext/commons-csv-1.4.jar + + ext/jna-5.5.0.jar + release/modules/ext/jna-5.5.0.jar + ext/imageio-sgi-3.2.jar release/modules/ext/imageio-sgi-3.2.jar @@ -946,10 +946,6 @@ ext/imageio-bmp-3.2.jar release/modules/ext/imageio-bmp-3.2.jar - - ext/platform-3.4.0.jar - release/modules/ext/platform-3.4.0.jar - ext/commons-lang-2.6.jar release/modules/ext/commons-lang-2.6.jar @@ -1018,6 +1014,10 @@ ext/dom4j-1.6.1.jar release/modules/ext/dom4j-1.6.1.jar + + ext/jna-platform-5.5.0.jar + release/modules/ext/jna-platform-5.5.0.jar + ext/imageio-metadata-3.2.jar release/modules/ext/imageio-metadata-3.2.jar From c64cbb351f023c844ebd779720a790a51bddc53e Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Wed, 11 Mar 2020 12:07:29 -0400 Subject: [PATCH 007/106] 6111: CVT displays incorrect To phone number for Outgoing calls. --- .../relationships/CallLogNode.java | 60 ++++++++++++++++--- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java index 288b3efa3f..055cddcc09 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.communications.relationships; import java.util.logging.Level; +import org.apache.commons.lang.StringUtils; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.communications.Utils; import static org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities.getAttributeDisplayString; @@ -67,14 +68,6 @@ final class CallLogNode extends BlackboardArtifactNode { return sheet; } - String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); - if(phoneNumber == null || phoneNumber.isEmpty()) { - phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); - } - if(phoneNumber == null || phoneNumber.isEmpty()) { - phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); - } - long duration = -1; try{ duration = getCallDuration(artifact); @@ -84,7 +77,7 @@ final class CallLogNode extends BlackboardArtifactNode { sheetSet.put(createNode(TSK_DATETIME_START, artifact)); sheetSet.put(createNode(TSK_DIRECTION, artifact)); - sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", phoneNumber)); + sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", getPhoneNumber(artifact))); if(duration != -1) { sheetSet.put(new NodeProperty<>("duration", "Duration", "", Long.toString(duration))); } @@ -107,6 +100,55 @@ final class CallLogNode extends BlackboardArtifactNode { return endAttribute.getValueLong() - startAttribute.getValueLong(); } + /** + * Returns the phone number to display in the To/From column. The number is + * picked from one the the 3 possible phone number attributes, based on the + * direction of the call. + * + * @param artifact Call log artifact. + * + * @return Phone number. + */ + private String getPhoneNumber(BlackboardArtifact artifact) { + String direction = getAttributeDisplayString(artifact, TSK_DIRECTION); + + String phoneNumberToReturn = ""; + String fromPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); + String toPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); + String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); + + switch (direction.toLowerCase()) { + case "incoming": // NON-NLS + + if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } else if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } + break; + case "outgoing": // NON-NLS + if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } else if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } + break; + default: + if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } else if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } + } + + return phoneNumberToReturn; + } /** * Circumvent DataResultFilterNode's slightly odd delegation to * BlackboardArtifactNode.getSourceName(). From 92a3667a1419c68d73a5cd6d8bdadb67cf5cb674 Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 12:08:56 -0400 Subject: [PATCH 008/106] Revert Gst initialization on Windows since it didn't have any impact on crashes. --- .../contentviewers/MediaPlayerPanel.java | 86 +++++++++---------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index c518abdd45..6df0cf8161 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -74,7 +74,6 @@ import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstException; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.event.SeekType; -import org.sleuthkit.autopsy.coreutils.PlatformUtil; /** * This is a video player that is part of the Media View layered pane. It uses @@ -222,14 +221,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //True for fairness. In other words, //acquire() calls are processed in order of invocation. sliderLock = new Semaphore(1, true); - - /** - * See JIRA-5888 for details. Initializing gstreamer here is more stable - * on Windows. - */ - if (PlatformUtil.isWindowsOS()) { - Gst.init(); - } } private void customizeComponents() { @@ -264,7 +255,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Manage the video while the user is performing actions on the track. progressSlider.addMouseListener(new MouseListener() { private State previousState = State.NULL; - + @Override public void mousePressed(MouseEvent e) { previousState = gstPlayBin.getState(); @@ -273,11 +264,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void mouseReleased(MouseEvent e) { - if(previousState.equals(State.PLAYING)) { + if (previousState.equals(State.PLAYING)) { gstPlayBin.play(); } previousState = State.NULL; } + @Override public void mouseClicked(MouseEvent e) { } @@ -289,7 +281,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void mouseExited(MouseEvent e) { } - + }); //Manage the audio level when the user is adjusting the volume slider audioSlider.addChangeListener((ChangeEvent event) -> { @@ -389,6 +381,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie gstPlayBin.getBus().disconnect(endOfStreamListener); gstPlayBin.getBus().disconnect(stateChangeListener); gstPlayBin.getBus().disconnect(errorListener); + gstPlayBin.getBus().dispose(); gstPlayBin.dispose(); fxAppSink.clear(); gstPlayBin = null; @@ -548,10 +541,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie // Initialize Gstreamer. It is safe to call this for every file. // It was moved here from the constructor because having it happen - // earlier resulted in conflicts on Linux. See JIRA-5888. - if (!PlatformUtil.isWindowsOS()) { - Gst.init(); - } + // earlier resulted in crashes on Linux. See JIRA-5888. + Gst.init(); //Video is ready for playback. Create new components gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); @@ -599,23 +590,27 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void actionPerformed(ActionEvent e) { if (!progressSlider.getValueIsAdjusting()) { - sliderLock.acquireUninterruptibly(); - long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - /** - * Duration may not be known until there is video data in the - * pipeline. We start this updater when data-flow has just been - * initiated so buffering may still be in progress. - */ - if (duration >= 0 && position >= 0) { - double relativePosition = (double) position / duration; - progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); - } + try { + sliderLock.acquireUninterruptibly(); + long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + /** + * Duration may not be known until there is video data in + * the pipeline. We start this updater when data-flow has + * just been initiated so buffering may still be in + * progress. + */ + if (duration >= 0 && position >= 0) { + double relativePosition = (double) position / duration; + progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); + } - SwingUtilities.invokeLater(() -> { - updateTimeLabel(position, duration); - }); - sliderLock.release(); + SwingUtilities.invokeLater(() -> { + updateTimeLabel(position, duration); + }); + } finally { + sliderLock.release(); + } } } } @@ -635,13 +630,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie * thumb at the given width and height. It also paints the track blue as * the thumb progresses. * - * @param slider JSlider component + * @param slider JSlider component * @param thumbDimension */ public CircularJSliderUI(JSlider slider, Dimension thumbDimension) { super(slider); this.thumbDimension = thumbDimension; - + //Configure track and thumb colors. Color lightBlue = new Color(0, 130, 255); thumbColor = lightBlue; @@ -655,8 +650,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } /** - * Modifies the View to be an oval rather than the underlying - * rectangle Controller. + * Modifies the View to be an oval rather than the underlying rectangle + * Controller. */ @Override public void paintThumb(Graphics graphic) { @@ -705,12 +700,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override protected TrackListener createTrackListener(JSlider slider) { /** - * This track listener will force the thumb to be snapped to the mouse - * location. This makes grabbing and dragging the JSlider much easier. - * Using the default track listener, the user would have to click - * exactly on the slider thumb to drag it. Now the thumb positions - * itself under the mouse so that it can always be dragged. - */ + * This track listener will force the thumb to be snapped to the + * mouse location. This makes grabbing and dragging the JSlider much + * easier. Using the default track listener, the user would have to + * click exactly on the slider thumb to drag it. Now the thumb + * positions itself under the mouse so that it can always be + * dragged. + */ return new TrackListener() { @Override public void mousePressed(MouseEvent e) { @@ -1007,14 +1003,14 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Don't allow skipping within 2 seconds of video ending. Skipping right to //the end causes undefined behavior for some gstreamer plugins. long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); - if((duration - currentTime) <= twoSecondsInNano) { + if ((duration - currentTime) <= twoSecondsInNano) { return; } - + long newTime; if (currentTime + fastForwardDelta >= duration) { //If there are less than 30 seconds left, only fast forward to the midpoint. - newTime = currentTime + (duration - currentTime)/2; + newTime = currentTime + (duration - currentTime) / 2; } else { newTime = currentTime + fastForwardDelta; } From ad5106d7d431aaf4d1eba68aff3c737b83d65c7b Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Wed, 11 Mar 2020 13:43:31 -0400 Subject: [PATCH 009/106] Addressed Codacy comments. --- .../relationships/CallLogNode.java | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java index 055cddcc09..3151d75780 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java @@ -102,53 +102,57 @@ final class CallLogNode extends BlackboardArtifactNode { /** * Returns the phone number to display in the To/From column. The number is - * picked from one the the 3 possible phone number attributes, based on the + * picked from one of the 3 possible phone number attributes, based on the * direction of the call. * * @param artifact Call log artifact. * - * @return Phone number. + * @return Phone number to display. */ private String getPhoneNumber(BlackboardArtifact artifact) { String direction = getAttributeDisplayString(artifact, TSK_DIRECTION); - String phoneNumberToReturn = ""; + String phoneNumberToReturn; String fromPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); String toPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); - switch (direction.toLowerCase()) { case "incoming": // NON-NLS - - if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } else if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(fromPhoneNumber, phoneNumber, toPhoneNumber); break; case "outgoing": // NON-NLS - if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } else if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(toPhoneNumber, phoneNumber, fromPhoneNumber); break; default: - if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } else if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(toPhoneNumber, fromPhoneNumber, phoneNumber ); + break; } return phoneNumberToReturn; } + + /** + * Checks the given string arguments in order and returns the first non blank string. + * Returns a blank string if all the input strings are blank. + * + * @param string1 First string to check + * @param string2 Second string to check + * @param string3 Third string to check + * + * @retunr first non blank string if there is one, blank string otherwise. + * + */ + private String getFirstNonBlank(String string1, String string2, String string3 ) { + + if (!StringUtils.isBlank(string1)) { + return string1; + } else if (!StringUtils.isBlank(string2)) { + return string2; + } else if (!StringUtils.isBlank(string3)) { + return string3; + } + return ""; + } /** * Circumvent DataResultFilterNode's slightly odd delegation to * BlackboardArtifactNode.getSourceName(). From 1581e07ea29d764536590500b72c50898dd3ee92 Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 16:35:22 -0400 Subject: [PATCH 010/106] Make all interactions with Gstreamer happen on the GST Java bindings service thread. --- .../contentviewers/MediaPlayerPanel.java | 265 ++++++++++-------- 1 file changed, 145 insertions(+), 120 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 6df0cf8161..d2d8ace001 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -377,14 +377,16 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } timer.stop(); if (gstPlayBin != null) { - gstPlayBin.stop(); - gstPlayBin.getBus().disconnect(endOfStreamListener); - gstPlayBin.getBus().disconnect(stateChangeListener); - gstPlayBin.getBus().disconnect(errorListener); - gstPlayBin.getBus().dispose(); - gstPlayBin.dispose(); - fxAppSink.clear(); - gstPlayBin = null; + Gst.getExecutor().submit(() -> { + gstPlayBin.stop(); + gstPlayBin.getBus().disconnect(endOfStreamListener); + gstPlayBin.getBus().disconnect(stateChangeListener); + gstPlayBin.getBus().disconnect(errorListener); + gstPlayBin.getBus().dispose(); + gstPlayBin.dispose(); + fxAppSink.clear(); + gstPlayBin = null; + }); } videoPanel.removeAll(); resetComponents(); @@ -539,39 +541,52 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie return; } + // Setting the following property causes the GST + // Java bindings to call dispose() on the GST + // service thread instead of running it in the GST + // Native Object Reaper thread. + System.setProperty("glib.reapOnEDT", "true"); + // Initialize Gstreamer. It is safe to call this for every file. // It was moved here from the constructor because having it happen // earlier resulted in crashes on Linux. See JIRA-5888. Gst.init(); - //Video is ready for playback. Create new components - gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); - //Configure event handling - Bus playBinBus = gstPlayBin.getBus(); - playBinBus.connect(endOfStreamListener); - playBinBus.connect(stateChangeListener); - playBinBus.connect(errorListener); - - if (this.isCancelled()) { + if (!Gst.isInitialized()) { + logger.log(Level.INFO, "GStreamer is not initialized."); //NON-NLS return; } - JFXPanel fxPanel = new JFXPanel(); - videoPanel.removeAll(); - videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); - videoPanel.add(fxPanel); - fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); - gstPlayBin.setVideoSink(fxAppSink); + Gst.getExecutor().submit(() -> { + //Video is ready for playback. Create new components + gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); + //Configure event handling + Bus playBinBus = gstPlayBin.getBus(); + playBinBus.connect(endOfStreamListener); + playBinBus.connect(stateChangeListener); + playBinBus.connect(errorListener); - if (this.isCancelled()) { - return; - } + if (this.isCancelled()) { + return; + } - gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); - gstPlayBin.pause(); + JFXPanel fxPanel = new JFXPanel(); + videoPanel.removeAll(); + videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); + videoPanel.add(fxPanel); + fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); + gstPlayBin.setVideoSink(fxAppSink); - timer.start(); - enableComponents(true); + if (this.isCancelled()) { + return; + } + + gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); + gstPlayBin.pause(); + + timer.start(); + enableComponents(true); + }); } catch (CancellationException ex) { logger.log(Level.INFO, "Media buffering was canceled."); //NON-NLS } catch (InterruptedException ex) { @@ -588,29 +603,31 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie private class VideoPanelUpdater implements ActionListener { @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent e) { if (!progressSlider.getValueIsAdjusting()) { - try { - sliderLock.acquireUninterruptibly(); - long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - /** - * Duration may not be known until there is video data in - * the pipeline. We start this updater when data-flow has - * just been initiated so buffering may still be in - * progress. - */ - if (duration >= 0 && position >= 0) { - double relativePosition = (double) position / duration; - progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); - } + Gst.getExecutor().submit(() -> { + try { + sliderLock.acquireUninterruptibly(); + long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + /** + * Duration may not be known until there is video data + * in the pipeline. We start this updater when data-flow + * has just been initiated so buffering may still be in + * progress. + */ + if (duration >= 0 && position >= 0) { + double relativePosition = (double) position / duration; + progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); + } - SwingUtilities.invokeLater(() -> { - updateTimeLabel(position, duration); - }); - } finally { - sliderLock.release(); - } + SwingUtilities.invokeLater(() -> { + updateTimeLabel(position, duration); + }); + } finally { + sliderLock.release(); + } + }); } } } @@ -978,87 +995,95 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie }// //GEN-END:initComponents private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Ensure new video position is within bounds - long newTime = Math.max(currentTime - rewindDelta, 0); - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_rewindButtonActionPerformed - - private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Don't allow skipping within 2 seconds of video ending. Skipping right to - //the end causes undefined behavior for some gstreamer plugins. - long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); - if ((duration - currentTime) <= twoSecondsInNano) { - return; - } - - long newTime; - if (currentTime + fastForwardDelta >= duration) { - //If there are less than 30 seconds left, only fast forward to the midpoint. - newTime = currentTime + (duration - currentTime) / 2; - } else { - newTime = currentTime + fastForwardDelta; - } - - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_fastForwardButtonActionPerformed - - private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed - if (gstPlayBin.isPlaying()) { - gstPlayBin.pause(); - } else { - double playBackRate = getPlayBackRate(); + Gst.getExecutor().submit(() -> { long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Set playback rate before play. + //Skip 30 seconds. + long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Ensure new video position is within bounds + long newTime = Math.max(currentTime - rewindDelta, 0); + double playBackRate = getPlayBackRate(); gstPlayBin.seek(playBackRate, Format.TIME, //FLUSH - flushes the pipeline //ACCURATE - video will seek exactly to the position requested EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), //Set the start position to newTime - SeekType.SET, currentTime, + SeekType.SET, newTime, //Do nothing for the end position SeekType.NONE, -1); - gstPlayBin.play(); - } + }); + }//GEN-LAST:event_rewindButtonActionPerformed + + private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed + Gst.getExecutor().submit(() -> { + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Skip 30 seconds. + long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Don't allow skipping within 2 seconds of video ending. Skipping right to + //the end causes undefined behavior for some gstreamer plugins. + long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); + if ((duration - currentTime) <= twoSecondsInNano) { + return; + } + + long newTime; + if (currentTime + fastForwardDelta >= duration) { + //If there are less than 30 seconds left, only fast forward to the midpoint. + newTime = currentTime + (duration - currentTime) / 2; + } else { + newTime = currentTime + fastForwardDelta; + } + + double playBackRate = getPlayBackRate(); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, newTime, + //Do nothing for the end position + SeekType.NONE, -1); + }); + }//GEN-LAST:event_fastForwardButtonActionPerformed + + private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed + Gst.getExecutor().submit(() -> { + if (gstPlayBin.isPlaying()) { + gstPlayBin.pause(); + } else { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Set playback rate before play. + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, currentTime, + //Do nothing for the end position + SeekType.NONE, -1); + gstPlayBin.play(); + } + }); }//GEN-LAST:event_playButtonActionPerformed private void playBackSpeedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playBackSpeedComboBoxActionPerformed - double playBackRate = getPlayBackRate(); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the position to the currentTime, we are only adjusting the - //playback rate. - SeekType.SET, currentTime, - SeekType.NONE, 0); + Gst.getExecutor().submit(() -> { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the position to the currentTime, we are only adjusting the + //playback rate. + SeekType.SET, currentTime, + SeekType.NONE, 0); + }); }//GEN-LAST:event_playBackSpeedComboBoxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables From e947e4d530c137d1b658542ef78c97e99360ecba Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 13 Mar 2020 07:51:51 -0400 Subject: [PATCH 011/106] Tidy up BlackboardArtifactNOde.java --- .../datamodel/BlackboardArtifactNode.java | 485 ++++++++++-------- .../datamodel/Bundle.properties-MERGED | 3 - 2 files changed, 261 insertions(+), 227 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 17b8248f06..1126cb1c80 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -60,7 +60,6 @@ import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.Score; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import static org.sleuthkit.autopsy.datamodel.DisplayableItemNode.findLinked; import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus; import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool; @@ -79,45 +78,56 @@ import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; /** - * Node wrapping a blackboard artifact object. This is generated from several - * places in the tree. + * An AbstractNode implementation representing an artifact of any type. */ public class BlackboardArtifactNode extends AbstractContentNode { private static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName()); - private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, + + /* + * This cache is used to avoid repeated trips to the case database for + * Content objects that are the source of multiple artifacts. + */ + private static final Cache contentCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); + + /* + * Case application events that affect the property sheets of + * BlackboardArtifactNodes, with one exception, CURRENT_CASE (closed) events + * which triggers content cache invalidation and unregistering of the node's + * ProeprtyChangeListener. + */ + private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( + Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, Case.Events.CURRENT_CASE, Case.Events.CR_COMMENT_CHANGED); - private static Cache contentCache = CacheBuilder.newBuilder() - .expireAfterWrite(1, TimeUnit.MINUTES). - build(); - - private final BlackboardArtifact artifact; - private Content associated = null; - - private List> customProperties; - /* - * Artifact types which should have the full unique path of the associated - * content as a property. + * Artifact types which should display the full unique path of the source + * content in their property sheets. */ private static final Integer[] SHOW_UNIQUE_PATH = new Integer[]{ BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID(), BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(), - BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID(),}; + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() + }; - // TODO (RC): This is an unattractive alternative to subclassing BlackboardArtifactNode, - // cut from the same cloth as the equally unattractive SHOW_UNIQUE_PATH array - // above. It should be removed when and if the subclassing is implemented. + /* + * Artifact types which should display the file metadata of the source + * content, in these cases always a file, in their property sheets. + */ private static final Integer[] SHOW_FILE_METADATA = new Integer[]{ - BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID(),}; + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() + }; - private final PropertyChangeListener pcl = new PropertyChangeListener() { + private final BlackboardArtifact artifact; + private Content sourceContent; + private List> customProperties; + + private final PropertyChangeListener appEventListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); @@ -133,23 +143,25 @@ public class BlackboardArtifactNode extends AbstractContentNode actionsList = new ArrayList<>(); actionsList.addAll(Arrays.asList(super.getActions(context))); - AbstractFile file = getLookup().lookup(AbstractFile.class); - //if this artifact has a time stamp add the action to view it in the timeline + /* + * If this artifact has a timestamp, add an action to view it in the + * timeline. + */ try { if (ViewArtifactInTimelineAction.hasSupportedTimeStamp(artifact)) { actionsList.add(new ViewArtifactInTimelineAction(artifact)); } } catch (TskCoreException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting arttribute(s) from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_resultErrorMessage()); + logger.log(Level.SEVERE, MessageFormat.format("Error getting attributes of artifact (onbjID={0})", artifact.getArtifactID()), ex); //NON-NLS } - // if the artifact links to another file, add an action to go to that file + /* + * If the artifact is linked to a file via a TSK_PATH_ID attribute add + * an action to view the file in the timeline. + */ try { - AbstractFile c = findLinked(artifact); - if (c != null) { - actionsList.add(ViewFileInTimelineAction.createViewFileAction(c)); + AbstractFile linkedFile = findLinked(artifact); + if (linkedFile != null) { + actionsList.add(ViewFileInTimelineAction.createViewFileAction(linkedFile)); } } catch (TskCoreException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting linked file from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_linkedFileMessage()); + logger.log(Level.SEVERE, MessageFormat.format("Error getting linked file of artifact (onbjID={0})", artifact.getArtifactID()), ex); //NON-NLS } - //if the artifact has associated content, add the action to view the content in the timeline + /* + * If the source content of the artifact is a file, add an action to + * view the file in the data source tree. + */ + AbstractFile file = getLookup().lookup(AbstractFile.class); if (null != file) { actionsList.add(ViewFileInTimelineAction.createViewSourceFileAction(file)); } @@ -288,12 +301,12 @@ public class BlackboardArtifactNode extends AbstractContentNode map = new LinkedHashMap<>(); - fillPropertyMap(map, artifact); - + /* + * Add the name of the artifact's source content to the sheet. + */ sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"), NO_DESCR, this.getSourceName())); - // Create place holders for S C O if (!UserPreferences.getHideSCOColumns()) { + /* + * Add the S, C, and O columns to the sheet and start a background + * task to compute the S, C, O values of the artifact. + */ sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, "")); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, "")); if (CentralRepository.isEnabled()) { sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), VALUE_LOADING, "")); } - // Get the SCO columns data in a background task - backgroundTasksPool.submit(new GetSCOTask( - new WeakReference<>(this), weakPcl)); + backgroundTasksPool.submit(new GetSCOTask(new WeakReference<>(this), weakAppEventListener)); } + /* + * If the artifact is an interesting artifact hit, add the type and + * description of the interesting artifact to the sheet. + */ if (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) { try { BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT)); @@ -404,10 +420,15 @@ public class BlackboardArtifactNode extends AbstractContentNode map = new LinkedHashMap<>(); + fillPropertyMap(map, artifact); for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), @@ -415,23 +436,28 @@ public class BlackboardArtifactNode extends AbstractContentNode np : customProperties) { sheetSet.put(np); } } - final int artifactTypeId = artifact.getArtifactTypeID(); - // If mismatch, add props for extension and file type + /* + * If the artifact is a file extension mismatch artifact, add the + * extension and type of the file to the sheet. + */ + final int artifactTypeId = artifact.getArtifactTypeID(); if (artifactTypeId == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()) { String ext = ""; //NON-NLS String actualMimeType = ""; //NON-NLS - if (associated instanceof AbstractFile) { - AbstractFile af = (AbstractFile) associated; - ext = af.getNameExtension(); - actualMimeType = af.getMIMEType(); + if (sourceContent instanceof AbstractFile) { + AbstractFile file = (AbstractFile) sourceContent; + ext = file.getNameExtension(); + actualMimeType = file.getMIMEType(); if (actualMimeType == null) { actualMimeType = ""; //NON-NLS } @@ -447,12 +473,16 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", @@ -484,7 +519,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), "", - associated.getSize())); + sourceContent.getSize())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", @@ -493,14 +528,14 @@ public class BlackboardArtifactNode extends AbstractContentNode getAllTagsFromDatabase() { List tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(associated)); + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); } @@ -560,89 +595,30 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); - try { - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(associated)); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); - } - sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); - } - - /** - * Used by (subclasses of) BlackboardArtifactNode to add the tags property - * to their sheets. - * - * @param sheetSet the modifiable Sheet.Set returned by - * Sheet.get(Sheet.PROPERTIES) - * @param tags the list of tags which should appear as the value for the - * property - */ - @Deprecated - protected final void addTagProperty(Sheet.Set sheetSet, List tags) { - sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); - } - - /** - * Gets the correlation attribute for the associated file - * - * @return the correlation attribute for the file associated with this - * BlackboardArtifactNode + * @return The correlation attribute instance, may be null. */ @Override protected final CorrelationAttributeInstance getCorrelationAttributeInstance() { CorrelationAttributeInstance correlationAttribute = null; - if (CentralRepository.isEnabled() && associated instanceof AbstractFile) { - correlationAttribute = CorrelationAttributeUtil.getCorrAttrForFile((AbstractFile)associated); + if (CentralRepository.isEnabled() && sourceContent instanceof AbstractFile) { + correlationAttribute = CorrelationAttributeUtil.getCorrAttrForFile((AbstractFile) sourceContent); } return correlationAttribute; } /** - * Used by (subclasses of) BlackboardArtifactNode to add the comment - * property to their sheets. + * Computes the value of the comment property ("C" in S, C, O) for this + * artifact. * - * @param sheetSet the modifiable Sheet.Set to add the property to - * @param tags the list of tags associated with the file - * @param attribute the correlation attribute associated with this - * artifact's associated file, null if central repo is not - * enabled + * @param tags The tags applied to the artifact and its source content. + * @param attribute The correlation attribute for the MD5 hash of the source + * file of the artifact, may be null. * - * @deprecated Use the GetSCOTask to get this data on a background - * thread..., and then update the property sheet asynchronously - */ - @NbBundle.Messages({"BlackboardArtifactNode.createSheet.comment.name=C", - "BlackboardArtifactNode.createSheet.comment.displayName=C"}) - @Deprecated - protected final void addCommentProperty(Sheet.Set sheetSet, List tags, CorrelationAttributeInstance attribute) { - HasCommentStatus status = getCommentProperty(tags, attribute); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, - status)); - } - - /** - * Gets the comment property for the node - * - * @param tags the list of tags associated with the file - * @param attribute the correlation attribute associated with this - * artifact's associated file, null if central repo is not - * enabled - * - * @return comment property + * @return The value of the comment property. */ @Override protected DataResultViewerTable.HasCommentStatus getCommentProperty(List tags, CorrelationAttributeInstance attribute) { @@ -702,8 +678,8 @@ public class BlackboardArtifactNode extends AbstractContentNode getScorePropertyAndDescription(List tags) { Score score = Score.NO_SCORE; String description = Bundle.BlackboardArtifactNode_createSheet_noScore_description(); - if (associated instanceof AbstractFile) { - if (((AbstractFile) associated).getKnown() == TskData.FileKnown.BAD) { + if (sourceContent instanceof AbstractFile) { + if (((AbstractFile) sourceContent).getKnown() == TskData.FileKnown.BAD) { score = Score.NOTABLE_SCORE; description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description(); } @@ -748,30 +724,6 @@ public class BlackboardArtifactNode extends AbstractContentNode countAndDescription = getCountPropertyAndDescription(attribute.getCorrelationType(), attribute.getCorrelationValue(), Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationAttributes_description()); - sheetSet.put( - new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); - } - /** * Gets the Occurrences property for the node. * @@ -808,14 +760,14 @@ public class BlackboardArtifactNode extends AbstractContentNode T accept(ContentNodeVisitor visitor) { return visitor.visit(this); } + + /** + * Used by (subclasses of) BlackboardArtifactNode to add the tags property + * to their sheets. + * + * @param sheetSet the modifiable Sheet.Set returned by + * Sheet.get(Sheet.PROPERTIES) + */ + @NbBundle.Messages({ + "BlackboardArtifactNode.createSheet.tags.displayName=Tags"}) + @Deprecated + protected void addTagProperty(Sheet.Set sheetSet) throws MissingResourceException { + // add properties for tags + List tags = new ArrayList<>(); + try { + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); + } + sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } + + /** + * Used by (subclasses of) BlackboardArtifactNode to add the tags property + * to their sheets. + * + * @param sheetSet the modifiable Sheet.Set returned by + * Sheet.get(Sheet.PROPERTIES) + * @param tags the list of tags which should appear as the value for the + * property + */ + @Deprecated + protected final void addTagProperty(Sheet.Set sheetSet, List tags) { + sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), + NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + } + + /** + * Used by (subclasses of) BlackboardArtifactNode to add the Occurrences + * property to their sheets. + * + * @param sheetSet the modifiable Sheet.Set to add the property to + * @param attribute correlation attribute instance + * + * @deprecated Use the GetSCOTask to get this data on a background + * thread..., and then update the property sheet asynchronously + */ + @NbBundle.Messages({"BlackboardArtifactNode.createSheet.count.name=O", + "BlackboardArtifactNode.createSheet.count.displayName=O", + "BlackboardArtifactNode.createSheet.count.noCorrelationAttributes.description=No correlation properties found", + "BlackboardArtifactNode.createSheet.count.noCorrelationValues.description=Unable to find other occurrences because no value exists for the available correlation property", + "# {0} - occurrenceCount", + "# {1} - attributeType", + "BlackboardArtifactNode.createSheet.count.description=There were {0} datasource(s) found with occurrences of the correlation value of type {1}"}) + @Deprecated + protected final void addCountProperty(Sheet.Set sheetSet, CorrelationAttributeInstance attribute) { + Pair countAndDescription = getCountPropertyAndDescription(attribute.getCorrelationType(), attribute.getCorrelationValue(), Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationAttributes_description()); + sheetSet.put( + new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); + } + + /** + * Used by (subclasses of) BlackboardArtifactNode to add the comment + * property to their sheets. + * + * @param sheetSet the modifiable Sheet.Set to add the property to + * @param tags the list of tags associated with the file + * @param attribute the correlation attribute associated with this + * artifact's associated file, null if central repo is not + * enabled + * + * @deprecated Use the GetSCOTask to get this data on a background + * thread..., and then update the property sheet asynchronously + */ + @NbBundle.Messages({"BlackboardArtifactNode.createSheet.comment.name=C", + "BlackboardArtifactNode.createSheet.comment.displayName=C"}) + @Deprecated + protected final void addCommentProperty(Sheet.Set sheetSet, List tags, CorrelationAttributeInstance attribute) { + HasCommentStatus status = getCommentProperty(tags, attribute); + sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, + status)); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED index 9ac85bd1e7..8289f947da 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED @@ -78,9 +78,6 @@ BlackboardArtifactNode.createSheet.taggedItem.description=Result or associated f BlackboardArtifactNode.createSheet.tags.displayName=Tags # {0} - artifactDisplayName BlackboardArtifactNode.displayName.artifact={0} Artifact -BlackboardArtifactNode.getAction.errorTitle=Error getting actions -BlackboardArtifactNode.getAction.linkedFileMessage=There was a problem getting actions for the selected result. The 'View File in Timeline' action will not be available. -BlackboardArtifactNode.getAction.resultErrorMessage=There was a problem getting actions for the selected result. The 'View Result in Timeline' action will not be available. BlackboardArtifactTagNode.createSheet.userName.text=User Name BlackboardArtifactTagNode.viewSourceArtifact.text=View Source Result Category.five=CAT-5: Non-pertinent From 2977b986010539d10721f64a1c9d909cf2ea9dd7 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Fri, 13 Mar 2020 13:49:33 -0400 Subject: [PATCH 012/106] Fix for changes to the CentralRepoPlatform class. --- .../datamodel/CentralRepoDbUpgrader13To14.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index f4ddbca089..9d6473055e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -39,7 +39,7 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { try (Statement statement = connection.createStatement();) { - CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.getSelectedPlatform(); + CentralRepoPlatforms selectedPlatform = CentralRepoDbManager.getSavedDbChoice().getDbPlatform(); // Create account_types and accounts tables which are referred by X_instances tables statement.execute(RdbmsCentralRepoFactory.getCreateAccountTypesTableStatement(selectedPlatform)); From a158cfcf699742431a9e80243734a68b66c237e7 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Fri, 13 Mar 2020 13:56:58 -0400 Subject: [PATCH 013/106] 6147: Do not create device accounts in Central Repo --- .../CorrelationAttributeInstance.java | 3 +- .../datamodel/CorrelationAttributeUtil.java | 39 ++++++++++-------- .../datamodel/RdbmsCentralRepoFactory.java | 41 ++++--------------- 3 files changed, 32 insertions(+), 51 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index 1ab978bc84..4d5e2857a1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -294,8 +294,9 @@ public class CorrelationAttributeInstance implements Serializable { // Create Correlation Types for Accounts. int correlationTypeId = ADDITIONAL_TYPES_BASE_ID; for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { + // Skip Device account type - we dont want to correlate on those. // Skip Phone and Email accounts as there are already Correlation types defined for those. - if (type != Account.Type.EMAIL && type != Account.Type.PHONE) { + if (type != Account.Type.DEVICE && type != Account.Type.EMAIL && type != Account.Type.PHONE) { defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(correlationTypeId, type.getDisplayName(), type.getTypeName().toLowerCase() + "_acct", true, true)); //NON-NLS correlationTypeId++; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 04aa6fc16e..636c59886e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -27,6 +27,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -247,25 +248,29 @@ public class CorrelationAttributeUtil { // Get the account type from the artifact BlackboardAttribute accountTypeAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)); String accountTypeStr = accountTypeAttribute.getValueString(); + + // do not create any correlation attribute instance for a Device account + if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false) { - // Get the corresponding CentralRepoAccountType from the database. - CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); + // Get the corresponding CentralRepoAccountType from the database. + CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); - int corrTypeId = crAccountType.getCorrelationTypeId(); - CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); - - // Get the account identifier - BlackboardAttribute accountIdAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID)); - String accountIdStr = accountIdAttribute.getValueString(); - - // add/get the account and get its accountId. - CentralRepoAccount crAccount = CentralRepository.getInstance().getOrCreateAccount(crAccountType, accountIdStr); - - CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, accountIdStr); - if (corrAttr != null) { - // set the account_id in correlation attribute - corrAttr.setAccountId(crAccount.getAccountId()); - corrAttrInstances.add(corrAttr); + int corrTypeId = crAccountType.getCorrelationTypeId(); + CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); + + // Get the account identifier + BlackboardAttribute accountIdAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID)); + String accountIdStr = accountIdAttribute.getValueString(); + + // add/get the account and get its accountId. + CentralRepoAccount crAccount = CentralRepository.getInstance().getOrCreateAccount(crAccountType, accountIdStr); + + CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, accountIdStr); + if (corrAttr != null) { + // set the account_id in correlation attribute + corrAttr.setAccountId(crAccount.getAccountId()); + corrAttrInstances.add(corrAttr); + } } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 1232d708a6..6129ea45b6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -193,7 +193,7 @@ public class RdbmsCentralRepoFactory { result = CentralRepoDbUtil.insertDefaultCorrelationTypes(conn) && CentralRepoDbUtil.insertDefaultOrganization(conn) && - insertDefaultAccountsTablesContent(conn); + RdbmsCentralRepoFactory.insertDefaultAccountsTablesContent(conn, selectedPlatform ); // @TODO: uncomment when ready to create/populate persona tables // && insertDefaultPersonaTablesContent(conn); @@ -766,33 +766,6 @@ public class RdbmsCentralRepoFactory { } - /** - * Inserts the default content in accounts related tables. - * - * @param conn Database connection to use. - * - * @return True if success, false otherwise. - */ - private boolean insertDefaultAccountsTablesContent(Connection conn) { - - try (Statement stmt = conn.createStatement()) { - // Populate the account_types table - for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { - int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); - if (correlationTypeId > 0) { - String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), - type.getTypeName(), type.getDisplayName(), correlationTypeId); - stmt.execute(sqlString); - } - } - } catch (SQLException ex) { - LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in Accounts tables."), ex); - return false; - } - - return true; - } - /** * Inserts the default content in persona related tables. * @@ -838,11 +811,13 @@ public class RdbmsCentralRepoFactory { // Populate the account_types table for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { - int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); - if (correlationTypeId > 0) { - String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), - type.getTypeName(), type.getDisplayName(), correlationTypeId); - stmt.execute(sqlString); + if (type != Account.Type.DEVICE) { + int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); + if (correlationTypeId > 0) { + String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), + type.getTypeName(), type.getDisplayName(), correlationTypeId); + stmt.execute(sqlString); + } } } From 1fc3bd524a4e6b8bc092160c521210d2ac4f4212 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 13 Mar 2020 15:35:55 -0400 Subject: [PATCH 014/106] 6132 prevent NPE in video content viewers when video is unplayable --- .../contentviewers/MediaPlayerPanel.java | 219 ++++++++++-------- 1 file changed, 118 insertions(+), 101 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index c518abdd45..53cf9e8bf4 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -241,7 +241,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie progressSlider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { - if (progressSlider.getValueIsAdjusting()) { + if (progressSlider.getValueIsAdjusting() && gstPlayBin != null) { long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); double relativePosition = progressSlider.getValue() * 1.0 / PROGRESS_SLIDER_SIZE; long newStartTime = (long) (relativePosition * duration); @@ -264,20 +264,23 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Manage the video while the user is performing actions on the track. progressSlider.addMouseListener(new MouseListener() { private State previousState = State.NULL; - + @Override public void mousePressed(MouseEvent e) { - previousState = gstPlayBin.getState(); - gstPlayBin.pause(); + if (gstPlayBin != null) { + previousState = gstPlayBin.getState(); + gstPlayBin.pause(); + } } @Override public void mouseReleased(MouseEvent e) { - if(previousState.equals(State.PLAYING)) { + if (previousState.equals(State.PLAYING) && gstPlayBin != null) { gstPlayBin.play(); } previousState = State.NULL; } + @Override public void mouseClicked(MouseEvent e) { } @@ -289,11 +292,11 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void mouseExited(MouseEvent e) { } - + }); //Manage the audio level when the user is adjusting the volume slider audioSlider.addChangeListener((ChangeEvent event) -> { - if (audioSlider.getValueIsAdjusting()) { + if (audioSlider.getValueIsAdjusting() && gstPlayBin != null) { double audioPercent = (audioSlider.getValue() * 2.0) / 100.0; gstPlayBin.setVolume(audioPercent); } @@ -327,11 +330,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie endOfStreamListener = new Bus.EOS() { @Override public void endOfStream(GstObject go) { - gstPlayBin.seek(ClockTime.ZERO); - /** - * Keep the video from automatically playing - */ - Gst.getExecutor().submit(() -> gstPlayBin.pause()); + if (gstPlayBin != null) { + gstPlayBin.seek(ClockTime.ZERO); + /** + * Keep the video from automatically playing + */ + Gst.getExecutor().submit(() -> gstPlayBin.pause()); + } } }; } @@ -556,10 +561,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Video is ready for playback. Create new components gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); //Configure event handling - Bus playBinBus = gstPlayBin.getBus(); - playBinBus.connect(endOfStreamListener); - playBinBus.connect(stateChangeListener); - playBinBus.connect(errorListener); + if (gstPlayBin != null) { + Bus playBinBus = gstPlayBin.getBus(); + playBinBus.connect(endOfStreamListener); + playBinBus.connect(stateChangeListener); + playBinBus.connect(errorListener); + } if (this.isCancelled()) { return; @@ -570,15 +577,16 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); videoPanel.add(fxPanel); fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); - gstPlayBin.setVideoSink(fxAppSink); - + if (gstPlayBin != null) { + gstPlayBin.setVideoSink(fxAppSink); + } if (this.isCancelled()) { return; } - - gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); - gstPlayBin.pause(); - + if (gstPlayBin != null) { + gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); + gstPlayBin.pause(); + } timer.start(); enableComponents(true); } catch (CancellationException ex) { @@ -598,7 +606,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void actionPerformed(ActionEvent e) { - if (!progressSlider.getValueIsAdjusting()) { + if (!progressSlider.getValueIsAdjusting() && gstPlayBin != null) { sliderLock.acquireUninterruptibly(); long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); @@ -635,13 +643,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie * thumb at the given width and height. It also paints the track blue as * the thumb progresses. * - * @param slider JSlider component + * @param slider JSlider component * @param thumbDimension */ public CircularJSliderUI(JSlider slider, Dimension thumbDimension) { super(slider); this.thumbDimension = thumbDimension; - + //Configure track and thumb colors. Color lightBlue = new Color(0, 130, 255); thumbColor = lightBlue; @@ -655,8 +663,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } /** - * Modifies the View to be an oval rather than the underlying - * rectangle Controller. + * Modifies the View to be an oval rather than the underlying rectangle + * Controller. */ @Override public void paintThumb(Graphics graphic) { @@ -705,12 +713,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override protected TrackListener createTrackListener(JSlider slider) { /** - * This track listener will force the thumb to be snapped to the mouse - * location. This makes grabbing and dragging the JSlider much easier. - * Using the default track listener, the user would have to click - * exactly on the slider thumb to drag it. Now the thumb positions - * itself under the mouse so that it can always be dragged. - */ + * This track listener will force the thumb to be snapped to the + * mouse location. This makes grabbing and dragging the JSlider much + * easier. Using the default track listener, the user would have to + * click exactly on the slider thumb to drag it. Now the thumb + * positions itself under the mouse so that it can always be + * dragged. + */ return new TrackListener() { @Override public void mousePressed(MouseEvent e) { @@ -982,87 +991,95 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie }// //GEN-END:initComponents private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Ensure new video position is within bounds - long newTime = Math.max(currentTime - rewindDelta, 0); - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_rewindButtonActionPerformed - - private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Don't allow skipping within 2 seconds of video ending. Skipping right to - //the end causes undefined behavior for some gstreamer plugins. - long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); - if((duration - currentTime) <= twoSecondsInNano) { - return; - } - - long newTime; - if (currentTime + fastForwardDelta >= duration) { - //If there are less than 30 seconds left, only fast forward to the midpoint. - newTime = currentTime + (duration - currentTime)/2; - } else { - newTime = currentTime + fastForwardDelta; - } - - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_fastForwardButtonActionPerformed - - private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed - if (gstPlayBin.isPlaying()) { - gstPlayBin.pause(); - } else { - double playBackRate = getPlayBackRate(); + if (gstPlayBin != null) { long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Set playback rate before play. + //Skip 30 seconds. + long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Ensure new video position is within bounds + long newTime = Math.max(currentTime - rewindDelta, 0); + double playBackRate = getPlayBackRate(); gstPlayBin.seek(playBackRate, Format.TIME, //FLUSH - flushes the pipeline //ACCURATE - video will seek exactly to the position requested EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), //Set the start position to newTime - SeekType.SET, currentTime, + SeekType.SET, newTime, //Do nothing for the end position SeekType.NONE, -1); - gstPlayBin.play(); + } + }//GEN-LAST:event_rewindButtonActionPerformed + + private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed + if (gstPlayBin != null) { + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Skip 30 seconds. + long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Don't allow skipping within 2 seconds of video ending. Skipping right to + //the end causes undefined behavior for some gstreamer plugins. + long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); + if ((duration - currentTime) <= twoSecondsInNano) { + return; + } + + long newTime; + if (currentTime + fastForwardDelta >= duration) { + //If there are less than 30 seconds left, only fast forward to the midpoint. + newTime = currentTime + (duration - currentTime) / 2; + } else { + newTime = currentTime + fastForwardDelta; + } + + double playBackRate = getPlayBackRate(); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, newTime, + //Do nothing for the end position + SeekType.NONE, -1); + } + }//GEN-LAST:event_fastForwardButtonActionPerformed + + private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed + if (gstPlayBin != null) { + if (gstPlayBin.isPlaying()) { + gstPlayBin.pause(); + } else { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Set playback rate before play. + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, currentTime, + //Do nothing for the end position + SeekType.NONE, -1); + gstPlayBin.play(); + } } }//GEN-LAST:event_playButtonActionPerformed private void playBackSpeedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playBackSpeedComboBoxActionPerformed - double playBackRate = getPlayBackRate(); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the position to the currentTime, we are only adjusting the - //playback rate. - SeekType.SET, currentTime, - SeekType.NONE, 0); + if (gstPlayBin != null) { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the position to the currentTime, we are only adjusting the + //playback rate. + SeekType.SET, currentTime, + SeekType.NONE, 0); + } }//GEN-LAST:event_playBackSpeedComboBoxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables From 87cc28942665aebf5a87e115f3e96a788ea12f21 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 13 Mar 2020 21:28:48 -0400 Subject: [PATCH 015/106] Tidy up BlackboardArtifactNode.java --- .../datamodel/BlackboardArtifactNode.java | 477 ++++++++++-------- 1 file changed, 277 insertions(+), 200 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 1126cb1c80..0b4d09a7b1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -78,23 +78,27 @@ import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; /** - * An AbstractNode implementation representing an artifact of any type. + * A BlackboardArtifactNode is an AbstractNode implementation that can be used + * to represent an artifact of any type. */ public class BlackboardArtifactNode extends AbstractContentNode { private static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName()); /* - * This cache is used to avoid repeated trips to the case database for - * Content objects that are the source of multiple artifacts. + * Cache of Content objects used to avoid repeated trips to the case + * database to retrieve Content objects that are the source of multiple + * artifacts. */ private static final Cache contentCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); /* * Case application events that affect the property sheets of - * BlackboardArtifactNodes, with one exception, CURRENT_CASE (closed) events - * which triggers content cache invalidation and unregistering of the node's - * ProeprtyChangeListener. + * BlackboardArtifactNodes. + * + * NOTE: CURRENT_CASE (closed) events trigger content cache invalidation and + * unregistering of the PropertyChangeListener subscribed to the application + * events. */ private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, @@ -105,8 +109,8 @@ public class BlackboardArtifactNode extends AbstractContentNode> customProperties; + /* + * The node's application event listener. + */ private final PropertyChangeListener appEventListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { @@ -180,19 +187,20 @@ public class BlackboardArtifactNode extends AbstractContentNode artifact.getSleuthkitCase().getContentById(objectID)); + if (content == null) { + return Lookups.fixed(artifact); + } else { + return Lookups.fixed(artifact, content); + } + } catch (ExecutionException ex) { + logger.log(Level.SEVERE, MessageFormat.format("Error getting source content (artifact objID={0}, content objID={1})", artifact.getId(), objectID), ex); //NON-NLS + /* + * RC: NPE ALERT!! The decision to return a Lookup without the + * source content in it has the potential to cause NPEs within this + * class and in the UI component clients of this class. The node + * constructor should throw. However, that would be an exported + * public API change. + */ + return Lookups.fixed(artifact); + } + } + + /** + * Unregisters the application event listener when this node is garbage + * collected, if this finalizer is called. + * + * RC: Isn't there some node lifecycle property change event that could be + * used to unregister the listener? * * @throws Throwable */ @@ -244,7 +292,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"), @@ -390,8 +447,11 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, "")); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, "")); @@ -402,8 +462,9 @@ public class BlackboardArtifactNode extends AbstractContentNode map = new LinkedHashMap<>(); fillPropertyMap(map, artifact); @@ -437,7 +499,7 @@ public class BlackboardArtifactNode extends AbstractContentNode np : customProperties) { @@ -445,10 +507,10 @@ public class BlackboardArtifactNode extends AbstractContentNode getAllTagsFromDatabase() { @@ -589,15 +652,16 @@ public class BlackboardArtifactNode extends AbstractContentNode 0 ? HasCommentStatus.TAG_NO_COMMENT : HasCommentStatus.NO_COMMENT; for (Tag tag : tags) { if (!StringUtils.isBlank(tag.getComment())) { - //if the tag is null or empty or contains just white space it will indicate there is not a comment status = HasCommentStatus.TAG_COMMENT; break; } } - //currently checks for a comment on the associated file in the central repo not the artifact itself - //what we want the column property to reflect should be revisted when we have added a way to comment - //on the artifact itself + if (attribute != null && !StringUtils.isBlank(attribute.getComment())) { if (status == HasCommentStatus.TAG_COMMENT) { status = HasCommentStatus.CR_AND_TAG_COMMENTS; @@ -641,38 +705,25 @@ public class BlackboardArtifactNode extends AbstractContentNode tags) { - Pair scoreAndDescription = getScorePropertyAndDescription(tags); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoreAndDescription.getRight(), scoreAndDescription.getLeft())); - } - - /** - * Get the score property for the node. - * - * @param tags the list of tags associated with the file - * - * @return score property and description + * @return The value of the score property as an enum element and a + * description string for dislpay in a tool tip. */ @Override protected Pair getScorePropertyAndDescription(List tags) { @@ -697,8 +748,8 @@ public class BlackboardArtifactNode extends AbstractContentNode 0 && (score == Score.NO_SCORE || score == Score.INTERESTING_SCORE)) { score = Score.INTERESTING_SCORE; @@ -725,41 +776,57 @@ public class BlackboardArtifactNode extends AbstractContentNode getCountPropertyAndDescription(Type attributeType, String attributeValue, String defaultDescription) { + protected Pair getCountPropertyAndDescription(Type corrAttrType, String attributeValue, String defaultDescription) { Long count = -1L; String description = defaultDescription; try { //don't perform the query if there is no correlation value - if (attributeType != null && StringUtils.isNotBlank(attributeValue)) { - count = CentralRepository.getInstance().getCountUniqueCaseDataSourceTuplesHavingTypeValue(attributeType, attributeValue); - description = Bundle.BlackboardArtifactNode_createSheet_count_description(count, attributeType.getDisplayName()); - } else if (attributeType != null) { + if (corrAttrType != null && StringUtils.isNotBlank(attributeValue)) { + count = CentralRepository.getInstance().getCountUniqueCaseDataSourceTuplesHavingTypeValue(corrAttrType, attributeValue); + description = Bundle.BlackboardArtifactNode_createSheet_count_description(count, corrAttrType.getDisplayName()); + } else if (corrAttrType != null) { description = Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationValues_description(); } } catch (CentralRepoException ex) { - logger.log(Level.WARNING, "Error getting count of datasources with correlation attribute", ex); + logger.log(Level.SEVERE, MessageFormat.format("Error querying central repository for other occurences count (artifact objID={0}, content objID={1}, corrAttrType={2}, corrAttrValue={3})", artifact.getId(), sourceContent.getId(), corrAttrType, attributeValue), ex); } catch (CorrelationAttributeNormalizationException ex) { - logger.log(Level.WARNING, "Unable to normalize data to get count of datasources with correlation attribute", ex); + logger.log(Level.SEVERE, MessageFormat.format("Error normalizing correlation attribute for central repository query (artifact objID={0}, content objID={1}, corrAttrType={2}, corrAttrValue={3})", artifact.getId(), sourceContent.getId(), corrAttrType, attributeValue), ex); } return Pair.of(count, description); } + /** + * Refreshes this node's property sheet. + */ private void updateSheet() { this.setSheet(createSheet()); } - private String getRootParentName() { + /** + * Gets the name of the root ancestor of the source content for the artifact + * represented by this node. + * + * @return The root ancestor name or the empty string if an error occurs. + */ + private String getRootAncestorName() { String parentName = sourceContent.getName(); Content parent = sourceContent; try { @@ -767,32 +834,31 @@ public class BlackboardArtifactNode extends AbstractContentNode np) { - if (null == customProperties) { - //lazy create the list + public void addNodeProperty(NodeProperty property) { + if (customProperties == null) { customProperties = new ArrayList<>(); } - customProperties.add(np); + customProperties.add(property); } /** - * Fill map with Artifact properties + * Converts the attributes of the artifact this node represents to a map of + * name-value pairs, where the names are attribute type display names. * - * @param map map with preserved ordering, where property names/values - * are put - * @param artifact to extract properties from + * @param map The map to be populated with the artifact attribute + * name-value pairs. + * @param artifact The artifact. */ @SuppressWarnings("deprecation") private void fillPropertyMap(Map map, BlackboardArtifact artifact) { @@ -806,7 +872,9 @@ public class BlackboardArtifactNode extends AbstractContentNode 512) { @@ -830,16 +899,18 @@ public class BlackboardArtifactNode extends AbstractContentNode map, BlackboardAttribute attribute) { @@ -852,10 +923,10 @@ public class BlackboardArtifactNode extends AbstractContentNode 160) { value = value.substring(0, 160) + "..."; @@ -874,30 +945,6 @@ public class BlackboardArtifactNode extends AbstractContentNode artifact.getSleuthkitCase().getContentById(objectID)); - if (content == null) { - return Lookups.fixed(artifact); - } else { - return Lookups.fixed(artifact, content); - } - } catch (ExecutionException ex) { - logger.log(Level.WARNING, "Getting associated content for artifact failed", ex); //NON-NLS - return Lookups.fixed(artifact); - } - } - @Override public boolean isLeafTypeNode() { return true; @@ -914,52 +961,83 @@ public class BlackboardArtifactNode extends AbstractContentNode tags) { + Pair scoreAndDescription = getScorePropertyAndDescription(tags); + sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoreAndDescription.getRight(), scoreAndDescription.getLeft())); + } + + /** + * Adds the tags property for the artifact represented by this node to the + * node property sheet. + * + * @param sheetSet The property sheet. + * + * @deprecated Do not use. The tags property is now computed in a background + * thread and added to the property sheet in this node's event + * PropertyChangeEventListner. */ @NbBundle.Messages({ - "BlackboardArtifactNode.createSheet.tags.displayName=Tags"}) + "BlackboardArtifactNode.createSheet.tags.displayName=Tags"} + ) @Deprecated protected void addTagProperty(Sheet.Set sheetSet) throws MissingResourceException { - // add properties for tags List tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, "Failed to get tags for artifact " + artifact.getDisplayName(), ex); + logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and source content (artifact objID={0}, content objID={1})", artifact.getId(), sourceContent.getId()), ex); } - sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } /** - * Used by (subclasses of) BlackboardArtifactNode to add the tags property - * to their sheets. + * Adds the tags property for the artifact represented by this node to the + * node property sheet. * - * @param sheetSet the modifiable Sheet.Set returned by - * Sheet.get(Sheet.PROPERTIES) - * @param tags the list of tags which should appear as the value for the - * property + * @param sheetSet The property sheet. + * @param tags The tags that have been applied to the artifact and its + * source content. + * + * @deprecated Do not use. The tags property is now computed in a background + * thread and added to the property sheet in this node's event + * PropertyChangeEventListner. */ @Deprecated protected final void addTagProperty(Sheet.Set sheetSet, List tags) { - sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), - NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); + sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } /** - * Used by (subclasses of) BlackboardArtifactNode to add the Occurrences - * property to their sheets. + * Adds the count property for the artifact represented by this node to the + * node property sheet. * - * @param sheetSet the modifiable Sheet.Set to add the property to - * @param attribute correlation attribute instance + * @param sheetSet The property sheet. + * @param attribute The correlation attribute instance to use for the + * central repository lookup. * - * @deprecated Use the GetSCOTask to get this data on a background - * thread..., and then update the property sheet asynchronously + * @deprecated Do not use. The count property is now computed in a + * background thread and added to the property sheet in this node's event + * PropertyChangeEventListner. */ @NbBundle.Messages({"BlackboardArtifactNode.createSheet.count.name=O", "BlackboardArtifactNode.createSheet.count.displayName=O", @@ -971,30 +1049,29 @@ public class BlackboardArtifactNode extends AbstractContentNode countAndDescription = getCountPropertyAndDescription(attribute.getCorrelationType(), attribute.getCorrelationValue(), Bundle.BlackboardArtifactNode_createSheet_count_noCorrelationAttributes_description()); - sheetSet.put( - new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); + sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), countAndDescription.getRight(), countAndDescription.getLeft())); } /** - * Used by (subclasses of) BlackboardArtifactNode to add the comment - * property to their sheets. + * Adds the other occurrences property for the artifact represented by this + * node to the node property sheet. * - * @param sheetSet the modifiable Sheet.Set to add the property to - * @param tags the list of tags associated with the file - * @param attribute the correlation attribute associated with this - * artifact's associated file, null if central repo is not - * enabled + * @param sheetSet The property sheet. + * @param tags The tags that have been applied to the artifact and its + * source content. + * @param attribute The correlation attribute instance to use for the + * central repository lookup. * - * @deprecated Use the GetSCOTask to get this data on a background - * thread..., and then update the property sheet asynchronously + * @deprecated Do not use. The count property is now computed in a + * background thread and added to the property sheet in this node's event + * PropertyChangeEventListner. */ @NbBundle.Messages({"BlackboardArtifactNode.createSheet.comment.name=C", "BlackboardArtifactNode.createSheet.comment.displayName=C"}) @Deprecated protected final void addCommentProperty(Sheet.Set sheetSet, List tags, CorrelationAttributeInstance attribute) { HasCommentStatus status = getCommentProperty(tags, attribute); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, - status)); + sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, status)); } } From fccf6b53cde0e62d8dac6dba3971b95875a5ef09 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 13 Mar 2020 21:35:06 -0400 Subject: [PATCH 016/106] Tidy up BlackboardArtifactNode.java --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 0b4d09a7b1..eb3571e0f1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -268,9 +268,9 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Sat, 14 Mar 2020 10:53:24 -0400 Subject: [PATCH 017/106] Tidy up BlackboardArtifactNode.java --- .../datamodel/BlackboardArtifactNode.java | 384 +++++++++--------- 1 file changed, 201 insertions(+), 183 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index eb3571e0f1..2283e9d14f 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -93,20 +93,16 @@ public class BlackboardArtifactNode extends AbstractContentNode contentCache = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(); /* - * Case application events that affect the property sheets of - * BlackboardArtifactNodes. - * - * NOTE: CURRENT_CASE (closed) events trigger content cache invalidation and - * unregistering of the PropertyChangeListener subscribed to the application - * events. + * Case events that indicate an update to the node's property sheet may be + * required. */ private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of( Case.Events.BLACKBOARD_ARTIFACT_TAG_ADDED, Case.Events.BLACKBOARD_ARTIFACT_TAG_DELETED, Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, - Case.Events.CURRENT_CASE, - Case.Events.CR_COMMENT_CHANGED); + Case.Events.CR_COMMENT_CHANGED, + Case.Events.CURRENT_CASE); /* * Artifact types for which the unique path of the artifact's source content @@ -120,20 +116,23 @@ public class BlackboardArtifactNode extends AbstractContentNode> customProperties; + private Content srcContent; // May be null. /* - * The node's application event listener. + * A method has been provided to allow the injection of properties into this + * node for display in the node's property sheet, independent of the + * artifact the node represents. */ + private List> customProperties; + private final PropertyChangeListener appEventListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { @@ -149,19 +148,25 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", @@ -581,7 +570,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), "", - sourceContent.getSize())); + file == null ? "" : file.getSize())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", @@ -589,15 +578,17 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); + if (srcContent != null) { + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); + } } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0}, content objID={1})", artifact.getId(), sourceContent.getId()), ex); + logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0})", artifact.getId()), ex); } return tags; } @@ -668,28 +661,34 @@ public class BlackboardArtifactNode extends AbstractContentNode tags, CorrelationAttributeInstance attribute) { + /* + * Has a tag with a comment been applied to the artifact or its source + * content? + */ HasCommentStatus status = tags.size() > 0 ? HasCommentStatus.TAG_NO_COMMENT : HasCommentStatus.NO_COMMENT; for (Tag tag : tags) { if (!StringUtils.isBlank(tag.getComment())) { @@ -698,6 +697,10 @@ public class BlackboardArtifactNode extends AbstractContentNode getScorePropertyAndDescription(List tags) { + /* + * Is the artifact's source content marked as notable? + */ Score score = Score.NO_SCORE; String description = Bundle.BlackboardArtifactNode_createSheet_noScore_description(); - if (sourceContent instanceof AbstractFile) { - if (((AbstractFile) sourceContent).getKnown() == TskData.FileKnown.BAD) { + if (srcContent != null && srcContent instanceof AbstractFile) { + if (((AbstractFile) srcContent).getKnown() == TskData.FileKnown.BAD) { score = Score.NOTABLE_SCORE; description = Bundle.BlackboardArtifactNode_createSheet_notableFile_description(); } } - //if the artifact being viewed is a hashhit check if the hashset is notable - if ((score == Score.NO_SCORE || score == Score.INTERESTING_SCORE) && content.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { + + /* + * If the artifact is a hash set hit, is the hash set a notable hashes + * hash set? + */ + if (score == Score.NO_SCORE && artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) { try { - BlackboardAttribute attr = content.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME)); + BlackboardAttribute attr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_SET_NAME)); List notableHashsets = HashDbManager.getInstance().getKnownBadFileHashSets(); for (HashDbManager.HashDb hashDb : notableHashsets) { if (hashDb.getHashSetName().equals(attr.getValueString())) { @@ -748,18 +762,29 @@ public class BlackboardArtifactNode extends AbstractContentNode 0 && (score == Score.NO_SCORE || score == Score.INTERESTING_SCORE)) { score = Score.INTERESTING_SCORE; description = Bundle.BlackboardArtifactNode_createSheet_taggedItem_description(); @@ -798,7 +823,6 @@ public class BlackboardArtifactNode extends AbstractContentNode map, BlackboardAttribute attribute) { - final int attributeTypeID = attribute.getAttributeType().getTypeID(); - - // Skip certain Email msg attributes if (attributeTypeID == ATTRIBUTE_TYPE.TSK_DATETIME_SENT.getTypeID() || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_HTML.getTypeID() || attributeTypeID == ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_RTF.getTypeID() @@ -933,11 +954,10 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(sourceContent)); + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and source content (artifact objID={0}, content objID={1})", artifact.getId(), sourceContent.getId()), ex); + logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and source content (artifact objID={0})", artifact.getId()), ex); } sheetSet.put(new NodeProperty<>("Tags", Bundle.BlackboardArtifactNode_createSheet_tags_displayName(), NO_DESCR, tags.stream().map(t -> t.getName().getDisplayName()).collect(Collectors.joining(", ")))); } @@ -1019,8 +1038,7 @@ public class BlackboardArtifactNode extends AbstractContentNode tags) { @@ -1036,8 +1054,8 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Sat, 14 Mar 2020 11:17:26 -0400 Subject: [PATCH 018/106] Update oruxmaps.py Use new geoPointList with geoArtifactHelper along with changing point of interest from trackpoint to bookmark. --- InternalPythonModules/android/oruxmaps.py | 90 ++++++++++++++++------- 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/InternalPythonModules/android/oruxmaps.py b/InternalPythonModules/android/oruxmaps.py index 4577ea5f2f..d08414cdf4 100644 --- a/InternalPythonModules/android/oruxmaps.py +++ b/InternalPythonModules/android/oruxmaps.py @@ -44,6 +44,8 @@ from org.sleuthkit.datamodel import BlackboardAttribute from org.sleuthkit.datamodel import Content from org.sleuthkit.datamodel import TskCoreException from org.sleuthkit.datamodel.Blackboard import BlackboardException +from org.sleuthkit.datamodel.blackboardutils import GeoArtifactsHelper +from org.sleuthkit.datamodel.blackboardutils.attributes import TskGeoTrackpointsUtil import traceback import general @@ -68,7 +70,10 @@ class OruxMapsAnalyzer(general.AndroidComponentAnalyzer): try: current_case = Case.getCurrentCaseThrows() - poiQueryString = "SELECT poilat, poilon, poitime, poiname FROM pois" + skCase = Case.getCurrentCase().getSleuthkitCase() + geoArtifactHelper = GeoArtifactsHelper(skCase, self._MODULE_NAME, self._PROGRAM_NAME, oruxMapsTrackpointsDb.getDBFile()) + + poiQueryString = "SELECT poilat, poilon, poialt, poitime, poiname FROM pois" poisResultSet = oruxMapsTrackpointsDb.runQuery(poiQueryString) abstractFile = oruxMapsTrackpointsDb.getDBFile() if poisResultSet is not None: @@ -77,12 +82,14 @@ class OruxMapsAnalyzer(general.AndroidComponentAnalyzer): longitude = poisResultSet.getDouble("poilon") time = poisResultSet.getLong("poitime") / 1000 # milliseconds since unix epoch name = poisResultSet.getString("poiname") + altitude = poisResultSet.getDouble("poialt") attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT) + artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, self._MODULE_NAME, time)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, self._MODULE_NAME, latitude)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, self._MODULE_NAME, longitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE, self._MODULE_NAME, altitude)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, self._MODULE_NAME, name)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, self._MODULE_NAME, self._PROGRAM_NAME)) @@ -96,32 +103,61 @@ class OruxMapsAnalyzer(general.AndroidComponentAnalyzer): self._logger.log(Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error("Failed to index trackpoint artifact for keyword search.", artifact.getDisplayName()) - trackpointsQueryString = "SELECT trkptlat, trkptlon, trkpttime FROM trackpoints" - trackpointsResultSet = oruxMapsTrackpointsDb.runQuery(trackpointsQueryString) - if trackpointsResultSet is not None: - while trackpointsResultSet.next(): - latitude = trackpointsResultSet.getDouble("trkptlat") - longitude = trackpointsResultSet.getDouble("trkptlon") - time = trackpointsResultSet.getLong("trkpttime") / 1000 # milliseconds since unix epoch - name = "" - attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, self._MODULE_NAME, time)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, self._MODULE_NAME, latitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, self._MODULE_NAME, longitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, self._MODULE_NAME, name)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, self._MODULE_NAME, self._PROGRAM_NAME)) - - artifact.addAttributes(attributes) - try: - # index the artifact for keyword search - blackboard = Case.getCurrentCase().getSleuthkitCase().getBlackboard() - blackboard.postArtifact(artifact, self._MODULE_NAME) - except Blackboard.BlackboardException as ex: - self._logger.log(Level.SEVERE, "Unable to index blackboard artifact " + str(artifact.getArtifactID()), ex) - self._logger.log(Level.SEVERE, traceback.format_exc()) - MessageNotifyUtil.Notify.error("Failed to index trackpoint artifact for keyword search.", artifact.getDisplayName()) + # tracks -> segments -> trackpoints + # + # The reason that the track and the segment are put into arrays is that once the segment query is run an error occurs that it cannot find the + # trackname column in the track query. This is avoided if all the tracks/segments are found and put into an array(s) that can then be processed all at once. + trackQueryString = "SELECT _id, trackname, trackciudad FROM tracks" + trackResultSet = oruxMapsTrackpointsDb.runQuery(trackQueryString) + if trackResultSet is not None: + trackResults = ArrayList() + while trackResultSet.next(): + tempTrack = ArrayList() + trackName = trackResultSet.getString("trackname") + " - " + trackResultSet.getString("trackciudad") + trackId = str(trackResultSet.getInt("_id")) + tempTrack.append(trackId) + tempTrack.append(trackName) + trackResults.append(tempTrack) + for trackResult in trackResults: + trackId = trackResult[0] + trackName = trackResult[1] + segmentQueryString = "SELECT _id, segname FROM segments WHERE segtrack = " + trackId + segmentResultSet = oruxMapsTrackpointsDb.runQuery(segmentQueryString) + if segmentResultSet is not None: + segmentResults = ArrayList() + while segmentResultSet.next(): + segmentName = trackName + " - " + segmentResultSet.getString("segname") + segmentId = str(segmentResultSet.getInt("_id")) + tempSegment = ArrayList() + tempSegment.append(segmentId) + tempSegment.append(segmentName) + segmentResults.append(tempSegment) + for segmentResult in segmentResults: + segmentId = segmentResult[0] + segmentName = segmentResult[1] + trackpointsQueryString = "SELECT trkptlat, trkptlon, trkptalt, trkpttime FROM trackpoints WHERE trkptseg = " + segmentId + trackpointsResultSet = oruxMapsTrackpointsDb.runQuery(trackpointsQueryString) + if trackpointsResultSet is not None: + geoPointList = TskGeoTrackpointsUtil.GeoTrackPointList() + while trackpointsResultSet.next(): + latitude = trackpointsResultSet.getDouble("trkptlat") + longitude = trackpointsResultSet.getDouble("trkptlon") + altitude = trackpointsResultSet.getDouble("trkptalt") + time = trackpointsResultSet.getLong("trkpttime") / 1000 # milliseconds since unix epoch + + geoPointList.addPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time) + + try: + geoartifact = geoArtifactHelper.addTrack(segmentName, geoPointList, None) + except Blackboard.BlackboardException as ex: + self._logger.log(Level.SEVERE, "Error using geo artifact helper with blackboard", ex) + self._logger.log(Level.SEVERE, traceback.format_exc()) + MessageNotifyUtil.Notify.error("Failed to add track artifact.", "geoArtifactHelper") + except TskCoreException as e: + self._logger.log(Level.SEVERE, "Error using geo artifact helper with TskCoreException", ex) + self._logger.log(Level.SEVERE, traceback.format_exc()) + MessageNotifyUtil.Notify.error("Failed to add track artifact with TskCoreException.", "geoArtifactHelper") except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for Orux Map trackpoints.", ex) From c6fea4118f2166156a3abcb0ee65fc3634c94bf5 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Sat, 14 Mar 2020 11:20:51 -0400 Subject: [PATCH 019/106] Tidy up BlackboardArtifactNode.java --- .../org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 2283e9d14f..caa2481a4c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -394,7 +394,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Sat, 14 Mar 2020 11:32:47 -0400 Subject: [PATCH 020/106] Improve performance of set display name for BlackboardArtifactNode --- .../datamodel/BlackboardArtifactNode.java | 48 +------------------ 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index caa2481a4c..b4aafc2bcc 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -207,6 +207,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Sun, 15 Mar 2020 21:07:08 -0400 Subject: [PATCH 021/106] Update viber.py Address comments, remove inner try block. --- InternalPythonModules/android/viber.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py index 4bc2d0c5d2..1ad418b478 100644 --- a/InternalPythonModules/android/viber.py +++ b/InternalPythonModules/android/viber.py @@ -133,12 +133,8 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer): attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), self._PARSER_NAME, contacts_parser.get_contact_name())) artifact.addAttributes(attributes) - try: # Post the artifact to blackboard - current_case.getBlackboard().postArtifact(artifact, self._PARSER_NAME) - except Blackboard.BlackboardException as e: - self.log(Level.WARNING, "Error adding viber contacts artifact to case database.", ex ) - self._logger.log(Level.WARNING, traceback.format_exc()) + current_case.getBlackboard().postArtifact(artifact, self._PARSER_NAME) contacts_parser.close() except SQLException as ex: From 77cafd322b14d8027b53e2d96ee74cd95c8e8ed2 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 16 Mar 2020 07:45:41 -0400 Subject: [PATCH 022/106] suppressed warnings for BasicComboBoxRenderer usage --- .../optionspanel/EamDbSettingsDialog.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 3b047b0e10..3322460b7d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -68,6 +68,7 @@ public class EamDbSettingsDialog extends JDialog { private class DbChoiceRenderer extends BasicComboBoxRenderer { private static final long serialVersionUID = 1L; + @SuppressWarnings("rawtypes") public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { @@ -137,6 +138,14 @@ public class EamDbSettingsDialog extends JDialog { } + /** + * Sets the drowndown renderer so that an item is unselectable if inappropriate. + */ + @SuppressWarnings("unchecked") + private void setDropdownRenderer() { + cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); + } + private void setupDbChoice(CentralRepoDbChoice initialMenuItem) { // setup initially selected item CentralRepoDbChoice toSelect = (initialMenuItem == null) ? @@ -144,10 +153,8 @@ public class EamDbSettingsDialog extends JDialog { manager.getSelectedDbChoice() : CentralRepoDbChoice.DB_CHOICES[0] : initialMenuItem; - - // set the renderer so item is unselectable if inappropriate - cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); - + + setDropdownRenderer(); changeDbSelection(toSelect); } From 13bf9f79a2350371c6f21e3c3b586f36262a5363 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 16 Mar 2020 12:06:04 -0400 Subject: [PATCH 023/106] created TextZoomPanel --- .../textcontentviewer/TextZoomPanel.css | 33 +++ .../textcontentviewer/TextZoomPanel.form | 159 +++++++++++++ .../textcontentviewer/TextZoomPanel.java | 214 ++++++++++++++++++ 3 files changed, 406 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.css create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.css b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.css new file mode 100644 index 0000000000..448b01a21b --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.css @@ -0,0 +1,33 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2015 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.label { + -fx-wrap-text:true; + -fx-text-fill: red; + -fx-font-size: 2em; +} + +.bg { + -fx-background-color: rgba(0, 0, 0, .8); +} + +.masker-pane .masker-text { + -fx-text-fill: white; + -fx-font-size: 1.5em; +} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.form new file mode 100644 index 0000000000..16abcf12ac --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.form @@ -0,0 +1,159 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.java new file mode 100644 index 0000000000..4e27ede7e4 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.java @@ -0,0 +1,214 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.contentviewers.textcontentviewer; + +import javax.swing.JPanel; + +/** + * This panel shows current text size and allows for increasing or decreasing font size. + */ +public class TextZoomPanel extends JPanel { + public static final int DEFAULT_SIZE = 12; + public static final int FONT_INCREMENT_DELTA = 1; + + /** + * This interface allows for retrieving current text size and setting the new text size + * for a panel. + */ + public interface TextZoomable { + /** + * Retrieves the font size (in px). + * @return the font size (in px). + */ + int getTextSize(); + + /** + * Sets the font size (in px). + * @param newSize the new font size (in px). + */ + void setTextSize(int newSize); + } + + + + private TextZoomable zoomable; + + /** + * Creates new form TextZoomPanel. + */ + public TextZoomPanel() { + initComponents(); + } + + + /** + * Returns the current zoomable object that will receive zoom change events. + * @return The current zoomable object. + */ + public TextZoomable getZoomable() { + return zoomable; + } + + /** + * Sets the current zoomable object that will receive zoom change events. + * @param zoomable The new zoomable object. + */ + public void setZoomable(TextZoomable zoomable) { + this.zoomable = zoomable; + updateEnabled(); + updateSize(); + } + + /** + * Updates size displayed to user based on current size; + */ + private void updateSize() { + int size = (this.zoomable == null) ? DEFAULT_SIZE : this.zoomable.getTextSize(); + // TODO update text panel + } + + private void updateEnabled() { + boolean shouldEnable = (this.zoomable != null); + this.zoomInButton.setEnabled(true); + } + + + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + toolbar = new javax.swing.JToolBar(); + jSeparator1 = new javax.swing.JToolBar.Separator(); + zoomTextField = new javax.swing.JTextField(); + zoomOutButton = new javax.swing.JButton(); + zoomInButton = new javax.swing.JButton(); + jSeparator2 = new javax.swing.JToolBar.Separator(); + zoomResetButton = new javax.swing.JButton(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0)); + filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); + + toolbar.setFloatable(false); + toolbar.setRollover(true); + toolbar.setMaximumSize(new java.awt.Dimension(200, 23)); + toolbar.setMinimumSize(new java.awt.Dimension(150, 23)); + toolbar.setName(""); // NOI18N + toolbar.setPreferredSize(new java.awt.Dimension(200, 23)); + toolbar.setRequestFocusEnabled(false); + + jSeparator1.setMaximumSize(new java.awt.Dimension(6, 20)); + toolbar.add(jSeparator1); + + zoomTextField.setEditable(false); + zoomTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT); + zoomTextField.setText(org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomTextField.text")); // NOI18N + zoomTextField.setMaximumSize(new java.awt.Dimension(50, 2147483647)); + zoomTextField.setMinimumSize(new java.awt.Dimension(50, 20)); + zoomTextField.setPreferredSize(new java.awt.Dimension(50, 20)); + toolbar.add(zoomTextField); + + zoomOutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/contentviewers/images/zoom-out.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(zoomOutButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomOutButton.text")); // NOI18N + zoomOutButton.setFocusable(false); + zoomOutButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + zoomOutButton.setMaximumSize(new java.awt.Dimension(24, 24)); + zoomOutButton.setMinimumSize(new java.awt.Dimension(24, 24)); + zoomOutButton.setPreferredSize(new java.awt.Dimension(24, 24)); + zoomOutButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + zoomOutButtonActionPerformed(evt); + } + }); + toolbar.add(zoomOutButton); + + zoomInButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/contentviewers/images/zoom-in.png"))); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(zoomInButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomInButton.text")); // NOI18N + zoomInButton.setFocusable(false); + zoomInButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + zoomInButton.setMaximumSize(new java.awt.Dimension(24, 24)); + zoomInButton.setMinimumSize(new java.awt.Dimension(24, 24)); + zoomInButton.setPreferredSize(new java.awt.Dimension(24, 24)); + zoomInButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + zoomInButtonActionPerformed(evt); + } + }); + toolbar.add(zoomInButton); + + jSeparator2.setMaximumSize(new java.awt.Dimension(6, 20)); + toolbar.add(jSeparator2); + + org.openide.awt.Mnemonics.setLocalizedText(zoomResetButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomResetButton.text")); // NOI18N + zoomResetButton.setFocusable(false); + zoomResetButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + zoomResetButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + zoomResetButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + zoomResetButtonActionPerformed(evt); + } + }); + toolbar.add(zoomResetButton); + toolbar.add(filler1); + toolbar.add(filler2); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(toolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 885, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(toolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + ); + }// //GEN-END:initComponents + + private void zoomOutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutButtonActionPerformed + // Find the next zoom step. + for (int i = ZOOM_STEPS.length - 1; i >= 0; i--) { + if (zoomRatio > ZOOM_STEPS[i]) { + zoomRatio = ZOOM_STEPS[i]; + break; + } + } + updateView(); + }//GEN-LAST:event_zoomOutButtonActionPerformed + + private void zoomInButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomInButtonActionPerformed + // Find the next zoom step. + for (int i = 0; i < ZOOM_STEPS.length; i++) { + if (zoomRatio < ZOOM_STEPS[i]) { + zoomRatio = ZOOM_STEPS[i]; + break; + } + } + updateView(); + }//GEN-LAST:event_zoomInButtonActionPerformed + + private void zoomResetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomResetButtonActionPerformed + resetView(); + }//GEN-LAST:event_zoomResetButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.Box.Filler filler1; + private javax.swing.Box.Filler filler2; + private javax.swing.JToolBar.Separator jSeparator1; + private javax.swing.JToolBar.Separator jSeparator2; + private javax.swing.JToolBar toolbar; + private javax.swing.JButton zoomInButton; + private javax.swing.JButton zoomOutButton; + private javax.swing.JButton zoomResetButton; + private javax.swing.JTextField zoomTextField; + // End of variables declaration//GEN-END:variables +} From d732e20839e7e8c10d4eda295487cd5e1b4ea3ee Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 16 Mar 2020 12:33:44 -0400 Subject: [PATCH 024/106] 6032 Move file name translation and make task --- .../datamodel/utils/FileNameTransTask.java | 61 ++++++++++++++++ .../utils/FileNameTranslator.java | 69 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java create mode 100755 Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java new file mode 100755 index 0000000000..b11b7e2c64 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -0,0 +1,61 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel.utils; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import org.openide.nodes.AbstractNode; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; + +/** + * An AbstractNodePropertySheetTask that translates a file name for an + * AbstractNode's property sheet. + */ +public class FileNameTransTask extends AbstractNodePropertySheetTask { + + private final static String EVENT_SOURCE = FileNameTransTask.class.getName(); + private final static String PROPERTY_NAME = EVENT_SOURCE + ".TranslatedFileName"; + private final String fileName; + + public static String getPropertyName() { + return PROPERTY_NAME; + } + + /** + * Constructs an AbstractNodePropertySheetTask that translates a file name + * for an AbstractNode's property sheet. When the translation is complete, a + * PropertyChangeEvent will be fired to the node's PropertyChangeListener. + * Call getPropertyName() to identify the property. + * + * @param node The node. + * @param listener The node's PropertyChangeListener. + * @param fileName THe file name. + */ + public FileNameTransTask(String fileName, AbstractNode node, PropertyChangeListener listener) { + super(node, listener); + this.fileName = fileName; + } + + @Override + protected PropertyChangeEvent computePropertyValue(AbstractNode node) throws Exception { + String translatedFileName = FileNameTranslator.translate(fileName); + return new PropertyChangeEvent(EVENT_SOURCE, PROPERTY_NAME, fileName, "Foo"); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java new file mode 100755 index 0000000000..34a6506d02 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java @@ -0,0 +1,69 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.texttranslation.utils; + +import org.apache.commons.io.FilenameUtils; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; + +/** + * A utility to translate file names. + */ +public class FileNameTranslator { + + /** + * Translates a file name using the configured machine translation service. + * + * @param fileName The file name. + * + * @return The translation of the file name. + * + * @throws NoServiceProviderException If machine translation is not + * configured. + * @throws TranslationException If there is an error doing the + * translation. + */ + public static String translate(String fileName) throws NoServiceProviderException, TranslationException { + +// //If already in complete English, don't translate. +// if (fileName.matches("^\\p{ASCII}+$")) { +// return ""; +// } + + TextTranslationService translator = TextTranslationService.getInstance(); + String baseName = FilenameUtils.getBaseName(fileName); + String translation = translator.translate(baseName); + if (!translation.isEmpty()) { + String extension = FilenameUtils.getExtension(fileName); + if (!extension.isEmpty()) { + String extensionDelimiter = (extension.isEmpty()) ? "" : "."; + translation += extensionDelimiter + extension; + } + } + return translation; + } + + /** + * Prevent instantiation of this utility class + */ + private FileNameTranslator() { + } + +} From e64d7bec042bab3d77bc142edfce17de4e10e324 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 16 Mar 2020 14:25:21 -0400 Subject: [PATCH 025/106] 6032 Remove per node message box for missing context men item --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index 16cf40680c..a6a0a66590 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -119,7 +119,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { } } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, MessageFormat.format("Error getting arttribute(s) from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_resultErrorMessage()); } // if the artifact links to another file, add an action to go to that file @@ -130,7 +129,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { } } catch (TskCoreException ex) { LOGGER.log(Level.SEVERE, MessageFormat.format("Error getting linked file from blackboard artifact{0}.", artifact.getArtifactID()), ex); //NON-NLS - MessageNotifyUtil.Notify.error(Bundle.BlackboardArtifactNode_getAction_errorTitle(), Bundle.BlackboardArtifactNode_getAction_linkedFileMessage()); } //if this artifact has associated content, add the action to view the content in the timeline AbstractFile file = getLookup().lookup(AbstractFile.class); From d042f73777f95697cc783e2b63dbcbb98ed5c0ed Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 16 Mar 2020 17:42:57 -0400 Subject: [PATCH 026/106] moving forward with text zoom panel --- .../autopsy/keywordsearch/Bundle.properties | 1 + .../keywordsearch/ExtractedContentPanel.form | 34 ++++- .../keywordsearch/ExtractedContentPanel.java | 55 +++++++- .../keywordsearch/ResizableTextPanel.java | 26 ++++ .../autopsy/keywordsearch}/TextZoomPanel.form | 12 +- .../autopsy/keywordsearch}/TextZoomPanel.java | 124 +++++++----------- .../autopsy/keywordsearch/zoom-in.png | Bin 0 -> 503 bytes .../autopsy/keywordsearch/zoom-out.png | Bin 0 -> 518 bytes 8 files changed, 163 insertions(+), 89 deletions(-) create mode 100644 KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ResizableTextPanel.java rename {Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer => KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch}/TextZoomPanel.form (87%) rename {Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer => KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch}/TextZoomPanel.java (76%) create mode 100644 KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/zoom-in.png create mode 100644 KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/zoom-out.png diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 21cd0d02b2..a7c42018e9 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -318,3 +318,4 @@ DropdownListSearchPanel.jSaveSearchResults.text=Save search results GlobalEditListPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. KeywordSearchGlobalLanguageSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. +ExtractedContentPanel.zoomPanel.AccessibleContext.accessibleName= diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index de0bedc049..684c0fb488 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -45,8 +45,8 @@ - - + + @@ -145,9 +145,11 @@ - + + + - + @@ -177,6 +179,7 @@ +
@@ -426,6 +429,29 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 8cad2a6140..bbd73ff132 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.keywordsearch; import java.awt.ComponentOrientation; import java.awt.EventQueue; +import java.awt.Font; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.util.ArrayList; @@ -27,15 +28,19 @@ import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.Level; +import javax.swing.JLabel; import javax.swing.SizeRequirements; import javax.swing.SwingWorker; import javax.swing.text.Element; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; import javax.swing.text.View; import javax.swing.text.ViewFactory; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.HTMLEditorKit.HTMLFactory; import javax.swing.text.html.InlineView; import javax.swing.text.html.ParagraphView; +import javax.swing.text.html.StyleSheet; import org.apache.commons.lang3.StringUtils; import org.netbeans.api.progress.ProgressHandle; import org.openide.util.NbBundle; @@ -48,11 +53,13 @@ import org.sleuthkit.autopsy.coreutils.TextUtil; * combo-box to select between multiple sources. */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives -class ExtractedContentPanel extends javax.swing.JPanel { +class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextPanel { private static final Logger logger = Logger.getLogger(ExtractedContentPanel.class.getName()); private static final long serialVersionUID = 1L; private String contentName; + private final Style bodyStyle; + private int curSize; ExtractedContentPanel() { initComponents(); @@ -123,7 +130,13 @@ class ExtractedContentPanel extends javax.swing.JPanel { * set font size manually in an effort to get fonts in this panel to * look similar to what is in the 'String View' content viewer. */ - editorKit.getStyleSheet().addRule("body {font-size: 8.5px;}"); //NON-NLS + bodyStyle = editorKit.getStyleSheet().getStyle("body"); + Font defaultFont = new JLabel().getFont(); + if (bodyStyle != null && defaultFont != null) { + StyleConstants.setFontFamily(bodyStyle, defaultFont.getFamily()); + StyleConstants.setFontSize(bodyStyle, defaultFont.getSize()); + curSize = defaultFont.getSize(); + } //NON-NLS extractedTextPane.setEditorKit(editorKit); sourceComboBox.addItemListener(itemEvent -> { @@ -135,6 +148,18 @@ class ExtractedContentPanel extends javax.swing.JPanel { copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy()); selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll()); } + + + @Override + public int getTextSize() { + return curSize; + } + + @Override + public void setTextSize(int newSize) { + curSize = newSize; + StyleConstants.setFontSize(bodyStyle, newSize); + } /** * This method is called from within the constructor to initialize the form. @@ -170,6 +195,7 @@ class ExtractedContentPanel extends javax.swing.JPanel { hitPreviousButton = new javax.swing.JButton(); hitCountLabel = new javax.swing.JLabel(); jSeparator2 = new javax.swing.JSeparator(); + zoomPanel = new TextZoomPanel(this); copyMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.copyMenuItem.text")); // NOI18N rightClickMenu.add(copyMenuItem); @@ -276,6 +302,17 @@ class ExtractedContentPanel extends javax.swing.JPanel { jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); + javax.swing.GroupLayout zoomPanelLayout = new javax.swing.GroupLayout(zoomPanel); + zoomPanel.setLayout(zoomPanelLayout); + zoomPanelLayout.setHorizontalGroup( + zoomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 32, Short.MAX_VALUE) + ); + zoomPanelLayout.setVerticalGroup( + zoomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 26, Short.MAX_VALUE) + ); + javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); controlPanel.setLayout(controlPanelLayout); controlPanelLayout.setHorizontalGroup( @@ -312,8 +349,10 @@ class ExtractedContentPanel extends javax.swing.JPanel { .addGap(0, 0, 0) .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) + .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 197, Short.MAX_VALUE) .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -340,20 +379,23 @@ class ExtractedContentPanel extends javax.swing.JPanel { .addComponent(pageTotalLabel) .addComponent(hitOfLabel) .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(hitButtonsLabel)) + .addComponent(hitButtonsLabel) + .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(0, 0, 0)) ); controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator1, jSeparator2, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox}); + zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.zoomPanel.AccessibleContext.accessibleName")); // NOI18N + controlScrollPane.setViewportView(controlPanel); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE) + .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 994, Short.MAX_VALUE) + .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 994, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -389,6 +431,7 @@ class ExtractedContentPanel extends javax.swing.JPanel { private javax.swing.JPopupMenu rightClickMenu; private javax.swing.JMenuItem selectAllMenuItem; private javax.swing.JComboBox sourceComboBox; + private javax.swing.JPanel zoomPanel; // End of variables declaration//GEN-END:variables void refreshCurrentMarkup() { diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ResizableTextPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ResizableTextPanel.java new file mode 100644 index 0000000000..719e54ecc7 --- /dev/null +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ResizableTextPanel.java @@ -0,0 +1,26 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.sleuthkit.autopsy.keywordsearch; + +/** + * This interface allows for retrieving current text size and setting the new text size + * for a panel. + */ +interface ResizableTextPanel { + + /** + * Retrieves the font size (in px). + * @return the font size (in px). + */ + int getTextSize(); + + /** + * Sets the font size (in px). + * @param newSize the new font size (in px). + */ + void setTextSize(int newSize); + +} diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form similarity index 87% rename from Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.form rename to KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form index 16abcf12ac..07e86d925f 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form @@ -60,7 +60,7 @@ - + @@ -76,10 +76,10 @@ - + - + @@ -100,10 +100,10 @@ - + - + @@ -131,7 +131,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java similarity index 76% rename from Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.java rename to KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 4e27ede7e4..9235cea52d 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -3,80 +3,72 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package org.sleuthkit.autopsy.contentviewers.textcontentviewer; +package org.sleuthkit.autopsy.keywordsearch; +import javax.swing.JLabel; import javax.swing.JPanel; +import org.openide.util.NbBundle; /** * This panel shows current text size and allows for increasing or decreasing font size. */ -public class TextZoomPanel extends JPanel { - public static final int DEFAULT_SIZE = 12; - public static final int FONT_INCREMENT_DELTA = 1; +class TextZoomPanel extends JPanel { + static final int DEFAULT_SIZE = new JLabel().getFont().getSize(); + private static final int FONT_INCREMENT_DELTA = 1; - /** - * This interface allows for retrieving current text size and setting the new text size - * for a panel. - */ - public interface TextZoomable { - /** - * Retrieves the font size (in px). - * @return the font size (in px). - */ - int getTextSize(); - - /** - * Sets the font size (in px). - * @param newSize the new font size (in px). - */ - void setTextSize(int newSize); - } - - - - private TextZoomable zoomable; + private final ResizableTextPanel zoomable; /** * Creates new form TextZoomPanel. + * @param zoomable the component that will receive text resize events */ - public TextZoomPanel() { - initComponents(); - } - - - /** - * Returns the current zoomable object that will receive zoom change events. - * @return The current zoomable object. - */ - public TextZoomable getZoomable() { - return zoomable; - } - - /** - * Sets the current zoomable object that will receive zoom change events. - * @param zoomable The new zoomable object. - */ - public void setZoomable(TextZoomable zoomable) { + public TextZoomPanel(ResizableTextPanel zoomable) { this.zoomable = zoomable; + initComponents(); updateEnabled(); - updateSize(); + setZoomText(); } - /** - * Updates size displayed to user based on current size; - */ - private void updateSize() { - int size = (this.zoomable == null) ? DEFAULT_SIZE : this.zoomable.getTextSize(); - // TODO update text panel - } + private void updateEnabled() { - boolean shouldEnable = (this.zoomable != null); - this.zoomInButton.setEnabled(true); + boolean shouldEnable = this.zoomable != null; + this.zoomInButton.setEnabled(shouldEnable); + this.zoomOutButton.setEnabled(shouldEnable); + this.zoomResetButton.setEnabled(shouldEnable); + this.zoomTextField.setEnabled(shouldEnable); + } + + private void resetSize() { + zoomAbs(DEFAULT_SIZE); + } + + private void zoomAbs(int fontSize) { + if (this.zoomable != null) { + this.zoomable.setTextSize(fontSize); + setZoomText(); + } + } + + private void setZoomText() { + int fontSize = (this.zoomable == null) ? DEFAULT_SIZE : this.zoomable.getTextSize(); + zoomTextField.setText(fontSize + "pt"); + } + + private void zoomDelta(int changeFactor) { + if (this.zoomable != null) { + int curSize = this.zoomable.getTextSize(); + zoomAbs(curSize + changeFactor); + } } - + @NbBundle.Messages({ + "TextZoomPanel.zoomTextField.text=", + "TextZoomPanel.zoomOutButton.text=", + "TextZoomPanel.zoomInButton.text=", + "TextZoomPanel.zoomResetButton.text=Reset" + }) /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -115,7 +107,7 @@ public class TextZoomPanel extends JPanel { zoomTextField.setPreferredSize(new java.awt.Dimension(50, 20)); toolbar.add(zoomTextField); - zoomOutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/contentviewers/images/zoom-out.png"))); // NOI18N + zoomOutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-out.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomOutButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomOutButton.text")); // NOI18N zoomOutButton.setFocusable(false); zoomOutButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); @@ -129,7 +121,7 @@ public class TextZoomPanel extends JPanel { }); toolbar.add(zoomOutButton); - zoomInButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/contentviewers/images/zoom-in.png"))); // NOI18N + zoomInButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-in.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomInButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomInButton.text")); // NOI18N zoomInButton.setFocusable(false); zoomInButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); @@ -174,29 +166,15 @@ public class TextZoomPanel extends JPanel { }// //GEN-END:initComponents private void zoomOutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutButtonActionPerformed - // Find the next zoom step. - for (int i = ZOOM_STEPS.length - 1; i >= 0; i--) { - if (zoomRatio > ZOOM_STEPS[i]) { - zoomRatio = ZOOM_STEPS[i]; - break; - } - } - updateView(); + zoomDelta(-FONT_INCREMENT_DELTA); }//GEN-LAST:event_zoomOutButtonActionPerformed private void zoomInButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomInButtonActionPerformed - // Find the next zoom step. - for (int i = 0; i < ZOOM_STEPS.length; i++) { - if (zoomRatio < ZOOM_STEPS[i]) { - zoomRatio = ZOOM_STEPS[i]; - break; - } - } - updateView(); + zoomDelta(FONT_INCREMENT_DELTA); }//GEN-LAST:event_zoomInButtonActionPerformed private void zoomResetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomResetButtonActionPerformed - resetView(); + resetSize(); }//GEN-LAST:event_zoomResetButtonActionPerformed diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/zoom-in.png b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/zoom-in.png new file mode 100644 index 0000000000000000000000000000000000000000..b79109cb64e018e921fb8be0fb716f896cf6947e GIT binary patch literal 503 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+uenMVO6iP5s=4O z;1OBOz`%C|gc+x5^GO2**-JcqUD+Qq^06@rew+J&4=8lh)5S4F<9zGIv%XA$B1b>Q z^E~KUnIQA~!)gXD$D9KhYGIBXqARvM&^gX^-`Bhf9F)h8vU}|)MeLMpT+T5S85n%Kc2dMSxiXzl9D)P?#FC=y|XJ; zy$##L?vazV+t@+TWch)O=cRrWY)U`0@@rsfeD9xY9{=u(rR&Z;?K1bBN7}7pArrKH zRoH~gy)J)K4R(zBdvv#ccK_Xn+ndo=IEp-hHbq!5I3{0&I46O{!wSlC8fw1-L(eTe xYLEok5S*V@Ql40p%1~Zju9umYU7Va)kgAtols@~NjTBH3gQu&X%Q~loCIB`mtm*&& literal 0 HcmV?d00001 diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/zoom-out.png b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/zoom-out.png new file mode 100644 index 0000000000000000000000000000000000000000..cf666e044a1f4b4ead7df33fc09c826d13582645 GIT binary patch literal 518 zcmeAS@N?(olHy`uVBq!ia0vp^{2ZylwGFn-m*}Rw?ICaZj>%u(C7n2y5>Hhii$7J1lfkQ3nOXHt<>$x2~u(7W6z(k-x2gXzK${Z znf_My#D(EN|EZR^MwFx^mZVxG7o`Fz1|tJQOI-s)T|<))15+ylBP#;~Z39Cf`H@lX z28xE<{FKbJO57S6VwR-2D?NY%?PN}v7CMhd8i N!PC{xWt~$(698R^w-*2a literal 0 HcmV?d00001 From 1085baf9cdf32763e9c0365161bd4c64084ecb44 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 17 Mar 2020 08:43:04 -0400 Subject: [PATCH 027/106] Extend file name translation to BlackboardArtifactNodes --- .../datamodel/AbstractAbstractFileNode.java | 44 +--- .../datamodel/BlackboardArtifactNode.java | 202 +++++++++++++----- .../autopsy/datamodel/Bundle.properties | 2 - .../datamodel/Bundle.properties-MERGED | 6 +- .../utils/AbstractNodePropertySheetTask.java | 16 +- .../datamodel/utils/FileNameTransTask.java | 2 +- .../utils/FileNameTranslator.java | 14 +- 7 files changed, 182 insertions(+), 104 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 1d53e46ca6..e2043846fe 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; @@ -28,7 +29,6 @@ import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; -import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.openide.nodes.Sheet; @@ -66,6 +66,7 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; /** * An abstract node that encapsulates AbstractFile data @@ -94,15 +95,15 @@ public abstract class AbstractAbstractFileNode extends A IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); } } - + try { //See JIRA-5971 //Attempt to cache file path during construction of this UI component. this.content.getUniquePath(); } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format("Failed attempt to cache the " - + "unique path of the abstract file instance. Name: %s (objID=%d)", - this.content.getName(), this.content.getId()), ex); + + "unique path of the abstract file instance. Name: %s (objID=%d)", + this.content.getName(), this.content.getId()), ex); } if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { @@ -490,39 +491,16 @@ public abstract class AbstractAbstractFileNode extends A } /** - * Translates this nodes content name. Doesn't attempt translation if the - * name is in english or if there is now translation service available. + * Translates the name of the file this node represents. An empty string + * will be returned if the translation fails for any reason. */ String getTranslatedFileName() { - //If already in complete English, don't translate. - if (content.getName().matches("^\\p{ASCII}+$")) { + try { + return FileNameTranslator.translate(content.getName()); + } catch (NoServiceProviderException | TranslationException ex) { + logger.log(Level.WARNING, MessageFormat.format("Error translating file name (objID={0}))", content.getId()), ex); return ""; } - TextTranslationService tts = TextTranslationService.getInstance(); - if (tts.hasProvider()) { - //Seperate out the base and ext from the contents file name. - String base = FilenameUtils.getBaseName(content.getName()); - try { - String translation = tts.translate(base); - String ext = FilenameUtils.getExtension(content.getName()); - - //If we have no extension, then we shouldn't add the . - String extensionDelimiter = (ext.isEmpty()) ? "" : "."; - - //Talk directly to this nodes pcl, fire an update when the translation - //is complete. - if (!translation.isEmpty()) { - return translation + extensionDelimiter + ext; - } - } catch (NoServiceProviderException noServiceEx) { - logger.log(Level.WARNING, "Translate unsuccessful because no TextTranslator " - + "implementation was provided.", noServiceEx.getMessage()); - } catch (TranslationException noTranslationEx) { - logger.log(Level.WARNING, "Could not successfully translate file name " - + content.getName(), noTranslationEx.getMessage()); - } - } - return ""; } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index b4aafc2bcc..055d322203 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -76,6 +76,9 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; /** * A BlackboardArtifactNode is an AbstractNode implementation that can be used @@ -124,7 +127,7 @@ public class BlackboardArtifactNode extends AbstractContentNode> customProperties; - private final PropertyChangeListener appEventListener = new PropertyChangeListener() { + private final PropertyChangeListener listener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); @@ -187,6 +190,17 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft())); } + } else if (eventType.equals(FileNameTransTask.getPropertyName())) { + /* + * Replace the value of the Source File property with the + * translated name via setDisplayName (see note in createSheet), + * and put the untranslated name in the Original Name property. + * Also set the tooltip to the original name. + */ + setDisplayName(evt.getNewValue().toString()); + setShortDescription(evt.getOldValue().toString()); + updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, (String) evt.getNewValue())); + //updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, (String) evt.getOldValue())); } } }; @@ -198,7 +212,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"), + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, this.getSourceName())); + if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { + /* + * If machine translation is configured, add the original name of + * the of the source content of the artifact represented by this + * node to the sheet. + */ + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), + NO_DESCR, + "")); + if (srcContent != null) { + new FileNameTransTask(srcContent.getName(), this, listener).submit(); + } + } + if (!UserPreferences.getHideSCOColumns()) { /* * Add S(core), C(omments), and O(ther occurences) columns to the @@ -414,14 +463,20 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.displayName"), - NO_DESCR, - associatedArtifact.getDisplayName())); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), - NO_DESCR, - associatedArtifact.getShortDescription())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactType.displayName"), + NO_DESCR, + associatedArtifact.getDisplayName())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactDetails.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), + NO_DESCR, + associatedArtifact.getShortDescription())); } } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting associated artifact of TSK_INTERESTING_ARTIFACT_HIT artifact (objID={0}))", artifact.getId()), ex); //NON-NLS @@ -465,17 +520,23 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"), + sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.ext.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.ext.displayName"), NO_DESCR, ext)); - sheetSet.put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"), - NO_DESCR, - actualMimeType)); + sheetSet + .put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.mimeType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.mimeType.displayName"), + NO_DESCR, + actualMimeType)); } /* @@ -489,13 +550,16 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.filePath.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.filePath.displayName"), NO_DESCR, sourcePath)); } @@ -507,26 +571,41 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), - "", - file == null ? "" : file.getSize())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileModifiedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileModifiedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileChangedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileChangedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileAccessedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileAccessedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileCreatedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileCreatedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileSize.displayName"), + "", + file == null ? "" : file.getSize())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", @@ -544,13 +623,16 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.dataSrc.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.dataSrc.displayName"), NO_DESCR, dataSourceStr)); } @@ -570,17 +652,23 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.displayName"), + sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.fileSize.displayName"), NO_DESCR, size)); - sheetSet.put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.displayName"), - NO_DESCR, - path)); + sheetSet + .put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.path.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.path.displayName"), + NO_DESCR, + path)); } return sheet; @@ -1036,8 +1124,8 @@ public class BlackboardArtifactNode extends AbstractContentNode impl * @return The Future of the task, may be used for task cancellation by * calling Future.cancel(true). */ - public static Future submitTask(AbstractNodePropertySheetTask task) { + private static Future submitTask(AbstractNodePropertySheetTask task) { return executor.submit(task); } @@ -104,12 +104,22 @@ public abstract class AbstractNodePropertySheetTask impl * * @param node The AbstractNode. * - * @return The result of the computation as a PropertyChangeEvent. + * @return The result of the computation as a PropertyChangeEvent, may be + * null. */ protected abstract PropertyChangeEvent computePropertyValue(T node) throws Exception; + /** + * Submits this task to the ExecutorService for the thread pool. + * + * @return The task's Future from the ExecutorService. + */ + public final Future submit() { + return submitTask(this); + } + @Override - final public void run() { + public final void run() { try { T node = this.weakNodeRef.get(); PropertyChangeListener listener = this.weakListenerRef.get(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java index b11b7e2c64..88ccac2d2f 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -55,7 +55,7 @@ public class FileNameTransTask extends AbstractNodePropertySheetTask Date: Tue, 17 Mar 2020 09:44:15 -0400 Subject: [PATCH 028/106] Update cachelocation.py Change GPS_TRACKPOINT to GPS_BOOKMARK. Change how cache file is processed and read. --- .../android/cachelocation.py | 73 +++++-------------- 1 file changed, 18 insertions(+), 55 deletions(-) diff --git a/InternalPythonModules/android/cachelocation.py b/InternalPythonModules/android/cachelocation.py index 1fb162a817..3697fb44b0 100644 --- a/InternalPythonModules/android/cachelocation.py +++ b/InternalPythonModules/android/cachelocation.py @@ -41,6 +41,7 @@ from org.sleuthkit.datamodel import TskCoreException import traceback import general +import struct """ Parses cache files that Android maintains for Wifi and cell towers. Adds GPS points to blackboard. @@ -74,60 +75,24 @@ class CacheLocationAnalyzer(general.AndroidComponentAnalyzer): def __findGeoLocationsInFile(self, file, abstractFile): - tempBytes = bytearray([0] * 2) # will temporarily hold bytes to be converted into the correct data types - try: - inputStream = FileInputStream(file) - - inputStream.read(tempBytes) # version - - tempBytes = bytearray([0] * 2) - inputStream.read(tempBytes) # number of location entries - - iterations = BigInteger(tempBytes).intValue() - - for i in range(iterations): # loop through every entry - tempBytes = bytearray([0] * 2) - inputStream.read(tempBytes) - - tempBytes = bytearray([0]) - inputStream.read(tempBytes) - - while BigInteger(tempBytes).intValue() != 0: # pass through non important values until the start of accuracy(around 7-10 bytes) - if 0 > inputStream.read(tempBytes): - break # we've passed the end of the file, so stop - - tempBytes = bytearray([0] * 3) - inputStream.read(tempBytes) - if BigInteger(tempBytes).intValue() <= 0: # This refers to a location that could not be calculated - tempBytes = bytearray([0] * 28) # read rest of the row's bytes - inputStream.read(tempBytes) - continue - accuracy = "" + BigInteger(tempBytes).intValue() - - tempBytes = bytearray([0] * 4) - inputStream.read(tempBytes) - confidence = "" + BigInteger(tempBytes).intValue() - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - latitude = CacheLocationAnalyzer.toDouble(bytes) - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - longitude = CacheLocationAnalyzer.toDouble(bytes) - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - timestamp = BigInteger(tempBytes).longValue() / 1000 + # code to parse the cache.wifi and cache.cell taken from https://forensics.spreitzenbarth.de/2011/10/28/decoding-cache-cell-and-cache-wifi-files/ + cacheFile = open(str(file), 'rb') + (version, entries) = struct.unpack('>hh', cacheFile.read(4)) + i = 0 + while i < entries: + key = cacheFile.read(struct.unpack('>h', cacheFile.read(2))[0]) + (accuracy, confidence, latitude, longitude, readtime) = struct.unpack('>iiddQ', cacheFile.read(32)) + timestamp = readtime/1000 + i = i + 1 attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, AndroidAnalyzer.MODULE_NAME, latitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, AndroidAnalyzer.MODULE_NAME, longitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, AndroidModuleFactorymodule.Name, timestamp)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, AndroidAnalyzer.MODULE_NAME, - file.getName() + "Location History")) + artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, general.MODULE_NAME, latitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, general.MODULE_NAME, longitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, general.MODULE_NAME, timestamp)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, general.MODULE_NAME, + abstractFile.getName() + " Location History")) artifact.addAttributes(attributes) #Not storing these for now. @@ -136,15 +101,13 @@ class CacheLocationAnalyzer(general.AndroidComponentAnalyzer): try: # index the artifact for keyword search blackboard = Case.getCurrentCase().getSleuthkitCase().getBlackboard() - blackboard.postArtifact(artifact, MODULE_NAME) + blackboard.postArtifact(artifact, general.MODULE_NAME) except Blackboard.BlackboardException as ex: self._logger.log(Level.SEVERE, "Unable to index blackboard artifact " + str(artifact.getArtifactID()), ex) self._logger.log(Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error("Failed to index GPS trackpoint artifact for keyword search.", artifact.getDisplayName()) + cacheFile.close() - except SQLException as ex: - # Unable to execute Cached GPS locations SQL query against database. - pass except Exception as ex: self._logger.log(Level.SEVERE, "Error parsing Cached GPS locations to blackboard", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) From da735c673e88667f532f0b1a77bef51a7b354f93 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Tue, 17 Mar 2020 10:10:56 -0400 Subject: [PATCH 029/106] Update browserlocation.py Change GPS_Trackpoint to GPS_Bookmark --- InternalPythonModules/android/browserlocation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/android/browserlocation.py b/InternalPythonModules/android/browserlocation.py index 84c2a601e7..c202c36d2a 100644 --- a/InternalPythonModules/android/browserlocation.py +++ b/InternalPythonModules/android/browserlocation.py @@ -95,7 +95,7 @@ class BrowserLocationAnalyzer(general.AndroidComponentAnalyzer): longitude = Double.valueOf(resultSet.getString("longitude")) attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT) + artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, general.MODULE_NAME, latitude)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, general.MODULE_NAME, longitude)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, general.MODULE_NAME, timestamp)) From 85077c3eca4b782ceeb050e874b3f733b4bf4c4e Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 17 Mar 2020 11:09:02 -0400 Subject: [PATCH 030/106] 6077 scale down large thumb for documents --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index b4142afab9..2db041a7bd 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -303,8 +303,10 @@ class FileSearch { image = ImageUtils.getThumbnail(largestChild, ImageUtils.ICON_SIZE_LARGE); } } catch (TskCoreException ex) { - logger.log(Level.WARNING, "Error getting children for file: " + file.getId(), ex); + logger.log(Level.WARNING, "Error getting children for file: " + file.getId(), ex); } + image = image == null ? image : image.getScaledInstance(ImageUtils.ICON_SIZE_MEDIUM, ImageUtils.ICON_SIZE_MEDIUM, + Image.SCALE_SMOOTH); return new TextSummary(getFirstLines(file), image, countOfImages); } From 26b2c0582670431de6cdbc1350237ed8445ea153 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 17 Mar 2020 14:29:13 -0400 Subject: [PATCH 031/106] working through font size adjustments with html editor kit --- .../autopsy/keywordsearch/Bundle.properties | 36 ++++----- .../keywordsearch/Bundle_ja.properties | 34 ++++---- .../keywordsearch/ExtractedContentPanel.form | 30 ++++--- .../keywordsearch/ExtractedContentPanel.java | 78 ++++++++++++------- .../autopsy/keywordsearch/TextZoomPanel.form | 19 +++-- .../autopsy/keywordsearch/TextZoomPanel.java | 7 +- 6 files changed, 118 insertions(+), 86 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index a7c42018e9..3dd312becc 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -6,13 +6,6 @@ OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search ListBundleName=Keyword Lists ListBundleConfig=Keyword List Configuration -ExtractedContentPanel.hitLabel.text=Matches on page: -ExtractedContentPanel.hitCountLabel.text=- -ExtractedContentPanel.hitOfLabel.text=of -ExtractedContentPanel.hitTotalLabel.text=- -ExtractedContentPanel.hitButtonsLabel.text=Match -ExtractedContentPanel.hitPreviousButton.text= -ExtractedContentPanel.hitNextButton.text= ExtractedContentPanel.copyMenuItem.text=Copy ExtractedContentPanel.selectAllMenuItem.text=Select All KeywordSearchEditListPanel.saveListButton.text=Copy List @@ -33,7 +26,6 @@ KeywordSearchListsManagementPanel.importButton.text=Import List KeywordSearchListsViewerPanel.searchAddButton.text=Search KeywordSearchListsViewerPanel.manageListsButton.text=Manage Lists KeywordSearchListsViewerPanel.ingestIndexLabel.text=Files Indexed: -ExtractedContentPanel.hitLabel.toolTipText= KeywordSearchEditListPanel.ingestMessagesCheckbox.text=Send ingest inbox messages for each hit KeywordSearchEditListPanel.ingestMessagesCheckbox.toolTipText=Send messages during ingest when hits on keywords from this list occur KeywordSearchEditListPanel.keywordOptionsLabel.text=Keyword Options @@ -299,15 +291,6 @@ SolrSearchService.ServiceName=Solr Keyword Search Service SolrSearchService.IndexReadOnlyDialog.title=Text Index Is Read-Only SolrSearchService.IndexReadOnlyDialog.msg=The text index for this case is read-only.
You will be able to see existing keyword search results and perform exact match and substring match keyword searches,
but you will not be able to add new text to the index or perform regex searches. You may instead open the case
with your previous version of this application. SolrSearchService.DeleteDataSource.msg=Error Deleting Solr data for data source id {0} -ExtractedContentPanel.jLabel1.text=Text Source: -ExtractedContentPanel.pagePreviousButton.actionCommand=pagePreviousButton -ExtractedContentPanel.pagePreviousButton.text= -ExtractedContentPanel.pageNextButton.text= -ExtractedContentPanel.pageCurLabel.text=- -ExtractedContentPanel.pageOfLabel.text=of -ExtractedContentPanel.pageTotalLabel.text=- -ExtractedContentPanel.pageButtonsLabel.text=Page -ExtractedContentPanel.pagesLabel.text=Page: DropdownSingleTermSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources: DropdownListSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources: DropdownSingleTermSearchPanel.ingestIndexLabel.text=Files Indexed: @@ -318,4 +301,21 @@ DropdownListSearchPanel.jSaveSearchResults.text=Save search results GlobalEditListPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. KeywordSearchGlobalLanguageSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. -ExtractedContentPanel.zoomPanel.AccessibleContext.accessibleName= +ExtractedContentPanel.hitCountLabel.text=- +ExtractedContentPanel.hitPreviousButton.text= +ExtractedContentPanel.hitTotalLabel.text=- +ExtractedContentPanel.hitOfLabel.text=of +ExtractedContentPanel.hitNextButton.text= +ExtractedContentPanel.hitButtonsLabel.text=Match +ExtractedContentPanel.hitLabel.toolTipText= +ExtractedContentPanel.hitLabel.text=Matches on page: +ExtractedContentPanel.pageCurLabel.text=- +ExtractedContentPanel.pagePreviousButton.actionCommand=pagePreviousButton +ExtractedContentPanel.pagePreviousButton.text= +ExtractedContentPanel.pageNextButton.text= +ExtractedContentPanel.pagesLabel.text=Page: +ExtractedContentPanel.pageTotalLabel.text=- +ExtractedContentPanel.pageButtonsLabel.text=Page +ExtractedContentPanel.pageOfLabel.text=of +ExtractedContentPanel.jLabel1.text=Text Source: +ExtractedContentPanel.AccessibleContext.accessibleName= diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties index adf1364da2..c131f5c8cf 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle_ja.properties @@ -42,13 +42,6 @@ OptionsCategory_Name_KeywordSearchOptions=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u OptionsCategory_Keywords_KeywordSearchOptions=\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22 ListBundleName=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8 ListBundleConfig=\u30ad\u30fc\u30ef\u30fc\u30c9\u30ea\u30b9\u30c8\u69cb\u6210 -ExtractedContentPanel.hitLabel.text=\u30da\u30fc\u30b8\u4e0a\u306e\u4e00\u81f4\u3059\u308b\u7d50\u679c: -ExtractedContentPanel.hitCountLabel.text=- -ExtractedContentPanel.hitOfLabel.text=/ -ExtractedContentPanel.hitTotalLabel.text=- -ExtractedContentPanel.hitButtonsLabel.text=\u4e00\u81f4\u3059\u308b\u7d50\u679c -ExtractedContentPanel.hitPreviousButton.text= -ExtractedContentPanel.hitNextButton.text= ExtractedContentPanel.copyMenuItem.text=\u30b3\u30d4\u30fc ExtractedContentPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e KeywordSearchEditListPanel.saveListButton.text=\u30ea\u30b9\u30c8\u3092\u30b3\u30d4\u30fc @@ -69,7 +62,6 @@ KeywordSearchListsManagementPanel.importButton.text=\u30ea\u30b9\u30c8\u3092\u30 KeywordSearchListsViewerPanel.searchAddButton.text=\u691c\u7d22 KeywordSearchListsViewerPanel.manageListsButton.text=\u30ea\u30b9\u30c8\u3092\u7ba1\u7406 KeywordSearchListsViewerPanel.ingestIndexLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb: -ExtractedContentPanel.hitLabel.toolTipText= KeywordSearchEditListPanel.ingestMessagesCheckbox.text=\u30d2\u30c3\u30c8\u3054\u3068\u306b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u53d7\u4fe1\u7bb1\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1 KeywordSearchEditListPanel.ingestMessagesCheckbox.toolTipText=\u3053\u306e\u30ea\u30b9\u30c8\u306e\u30ad\u30fc\u30ef\u30fc\u30c9\u3067\u30d2\u30c3\u30c8\u304c\u767a\u751f\u3057\u305f\u3068\u304d\u306b\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u4e2d\u306b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1 KeywordSearchEditListPanel.keywordOptionsLabel.text=\u30ad\u30fc\u30ef\u30fc\u30c9\u30aa\u30d7\u30b7\u30e7\u30f3 @@ -355,15 +347,6 @@ SolrSearchService.exceptionMessage.noIndexMetadata=\u30b1\u30fc\u30b9\u30c7\u30a SolrSearchService.ServiceName=Solr\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u30b5\u30fc\u30d3\u30b9 SolrSearchService.IndexReadOnlyDialog.title=\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u306f\u8aad\u307f\u53d6\u308a\u5c02\u7528\u3067\u3059 SolrSearchService.IndexReadOnlyDialog.msg=\u3053\u306e\u30b1\u30fc\u30b9\u306e\u30c6\u30ad\u30b9\u30c8\u7d22\u5f15\u306f\u8aad\u307f\u53d6\u308a\u5c02\u7528\u3067\u3059\u3002
\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u7d50\u679c\u3092\u78ba\u8a8d\u3057\u3001\u5b8c\u5168\u4e00\u81f4\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u3068\u90e8\u5206\u4e00\u81f4\u30ad\u30fc\u30ef\u30fc\u30c9\u691c\u7d22\u3092\u5b9f\u884c\u3067\u304d\u307e\u3059
\u304c\u3001\u7d22\u5f15\u306b\u65b0\u898f\u30c6\u30ad\u30b9\u30c8\u3092\u8ffd\u52a0\u307e\u305f\u306f\u6b63\u898f\u8868\u73fe\u691c\u7d22\u3092\u5b9f\u884c\u3067\u304d\u307e\u305b\u3093\u3002\u305d\u306e\u4ee3\u308f\u308a\u306b\u3001\u3053\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u4ee5\u524d\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3067
\u30b1\u30fc\u30b9\u3092\u958b\u3051\u307e\u3059\u3002 -ExtractedContentPanel.jLabel1.text=\u30c6\u30ad\u30b9\u30c8\u30bd\u30fc\u30b9: -ExtractedContentPanel.pagePreviousButton.actionCommand=pagePreviousButton -ExtractedContentPanel.pagePreviousButton.text= -ExtractedContentPanel.pageNextButton.text= -ExtractedContentPanel.pageCurLabel.text=- -ExtractedContentPanel.pageOfLabel.text=/ -ExtractedContentPanel.pageTotalLabel.text=- -ExtractedContentPanel.pageButtonsLabel.text=\u30da\u30fc\u30b8 -ExtractedContentPanel.pagesLabel.text=\u30da\u30fc\u30b8: DropdownSingleTermSearchPanel.dataSourceCheckBox.text=\u9078\u629e\u3057\u305f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306b\u691c\u7d22\u3092\u5236\u9650: DropdownListSearchPanel.dataSourceCheckBox.text=\u9078\u629e\u3057\u305f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u306b\u691c\u7d22\u3092\u5236\u9650: DropdownSingleTermSearchPanel.ingestIndexLabel.text=\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb: @@ -374,3 +357,20 @@ DropdownListSearchPanel.jSaveSearchResults.text=\u691c\u7d22\u7d50\u679c\u3092\u GlobalEditListPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 KeywordSearchGlobalLanguageSettingsPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text=\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u9032\u884c\u4e2d\u3067\u3059\u3002\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u304c\u5b8c\u4e86\u3059\u308b\u307e\u3067\u4e00\u90e8\u306e\u8a2d\u5b9a\u3092\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 +ExtractedContentPanel.hitCountLabel.text=- +ExtractedContentPanel.hitPreviousButton.text= +ExtractedContentPanel.hitTotalLabel.text=- +ExtractedContentPanel.hitOfLabel.text=/ +ExtractedContentPanel.hitNextButton.text= +ExtractedContentPanel.hitButtonsLabel.text=\u4e00\u81f4\u3059\u308b\u7d50\u679c +ExtractedContentPanel.hitLabel.toolTipText= +ExtractedContentPanel.hitLabel.text=\u30da\u30fc\u30b8\u4e0a\u306e\u4e00\u81f4\u3059\u308b\u7d50\u679c: +ExtractedContentPanel.pageCurLabel.text=- +ExtractedContentPanel.pagePreviousButton.actionCommand=pagePreviousButton +ExtractedContentPanel.pagePreviousButton.text= +ExtractedContentPanel.pageNextButton.text= +ExtractedContentPanel.pagesLabel.text=\u30da\u30fc\u30b8: +ExtractedContentPanel.pageTotalLabel.text=- +ExtractedContentPanel.pageButtonsLabel.text=\u30da\u30fc\u30b8 +ExtractedContentPanel.pageOfLabel.text=/ +ExtractedContentPanel.jLabel1.text=\u30c6\u30ad\u30b9\u30c8\u30bd\u30fc\u30b9: diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index 684c0fb488..a610023951 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -45,16 +45,17 @@ - - + + - + + + - @@ -145,11 +146,11 @@ - - + + - + @@ -181,7 +182,7 @@
- + @@ -430,9 +431,18 @@ + + + + + + + + + - + @@ -442,7 +452,7 @@ - + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index bbd73ff132..cc4014922a 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -32,8 +32,6 @@ import javax.swing.JLabel; import javax.swing.SizeRequirements; import javax.swing.SwingWorker; import javax.swing.text.Element; -import javax.swing.text.Style; -import javax.swing.text.StyleConstants; import javax.swing.text.View; import javax.swing.text.ViewFactory; import javax.swing.text.html.HTMLEditorKit; @@ -56,10 +54,16 @@ import org.sleuthkit.autopsy.coreutils.TextUtil; class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextPanel { private static final Logger logger = Logger.getLogger(ExtractedContentPanel.class.getName()); + + // set font as close as possible to default + private static final Font DEFAULT_FONT = new JLabel().getFont(); + private static final long serialVersionUID = 1L; private String contentName; - private final Style bodyStyle; private int curSize; + + private final StyleSheet styleSheet; + private final HTMLEditorKit editorKit; ExtractedContentPanel() { initComponents(); @@ -72,7 +76,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP * extractedTextPane taken form this website: * http://java-sl.com/tip_html_letter_wrap.html. */ - HTMLEditorKit editorKit = new HTMLEditorKit() { + editorKit = new HTMLEditorKit() { private static final long serialVersionUID = 1L; @Override @@ -126,19 +130,10 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP }; } }; - /* - * set font size manually in an effort to get fonts in this panel to - * look similar to what is in the 'String View' content viewer. - */ - bodyStyle = editorKit.getStyleSheet().getStyle("body"); - Font defaultFont = new JLabel().getFont(); - if (bodyStyle != null && defaultFont != null) { - StyleConstants.setFontFamily(bodyStyle, defaultFont.getFamily()); - StyleConstants.setFontSize(bodyStyle, defaultFont.getSize()); - curSize = defaultFont.getSize(); - } //NON-NLS - extractedTextPane.setEditorKit(editorKit); - + + styleSheet = editorKit.getStyleSheet(); + setTextSize(40); + sourceComboBox.addItemListener(itemEvent -> { if (itemEvent.getStateChange() == ItemEvent.SELECTED) { refreshCurrentMarkup(); @@ -147,6 +142,14 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP extractedTextPane.setComponentPopupMenu(rightClickMenu); copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy()); selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll()); + + zoomPanel.setEnabled(true); + zoomPanel.setVisible(true); + } + + + private void setStyleSheetSize(StyleSheet styleSheet, int size) { + styleSheet.addRule("body {font-family:\"" + DEFAULT_FONT.getFamily() + "\"; font-size:" + size + "pt; } "); } @@ -158,8 +161,22 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP @Override public void setTextSize(int newSize) { curSize = newSize; - StyleConstants.setFontSize(bodyStyle, newSize); + + int caretPos = extractedTextPane.getCaretPosition(); + String curText = extractedTextPane.getText(); + + setStyleSheetSize(styleSheet, curSize); + + editorKit.setStyleSheet(styleSheet); + extractedTextPane.setEditorKit(editorKit); + + extractedTextPane.setText(curText); + extractedTextPane.setCaretPosition(caretPos); } + + + + /** * This method is called from within the constructor to initialize the form. @@ -302,11 +319,15 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); + zoomPanel.setMinimumSize(new java.awt.Dimension(150, 26)); + zoomPanel.setName(""); // NOI18N + zoomPanel.setPreferredSize(new java.awt.Dimension(200, 26)); + javax.swing.GroupLayout zoomPanelLayout = new javax.swing.GroupLayout(zoomPanel); zoomPanel.setLayout(zoomPanelLayout); zoomPanelLayout.setHorizontalGroup( zoomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 32, Short.MAX_VALUE) + .addGap(0, 401, Short.MAX_VALUE) ); zoomPanelLayout.setVerticalGroup( zoomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -348,11 +369,11 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addComponent(pagePreviousButton) .addGap(0, 0, 0) .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 401, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 197, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -381,12 +402,12 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(hitButtonsLabel) .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, 0)) + .addGap(56, 56, 56)) ); controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator1, jSeparator2, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox}); - zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.zoomPanel.AccessibleContext.accessibleName")); // NOI18N + zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.AccessibleContext.accessibleName")); // NOI18N controlScrollPane.setViewportView(controlPanel); @@ -394,15 +415,16 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 994, Short.MAX_VALUE) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 994, Short.MAX_VALUE) + .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1096, Short.MAX_VALUE) + .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1096, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(controlScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(controlScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)) + .addComponent(extractedScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 422, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form index 07e86d925f..c3bfb59d2c 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form @@ -1,6 +1,15 @@
+ + + + + + + + + @@ -143,16 +152,6 @@ - - - - - - - - - - diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 9235cea52d..31952a2fd6 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -86,7 +86,10 @@ class TextZoomPanel extends JPanel { jSeparator2 = new javax.swing.JToolBar.Separator(); zoomResetButton = new javax.swing.JButton(); filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0)); - filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0)); + + setMinimumSize(new java.awt.Dimension(150, 23)); + setPreferredSize(new java.awt.Dimension(200, 23)); + setRequestFocusEnabled(false); toolbar.setFloatable(false); toolbar.setRollover(true); @@ -149,7 +152,6 @@ class TextZoomPanel extends JPanel { }); toolbar.add(zoomResetButton); toolbar.add(filler1); - toolbar.add(filler2); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -180,7 +182,6 @@ class TextZoomPanel extends JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.Box.Filler filler1; - private javax.swing.Box.Filler filler2; private javax.swing.JToolBar.Separator jSeparator1; private javax.swing.JToolBar.Separator jSeparator2; private javax.swing.JToolBar toolbar; From 04638faa85268212992ad7917ce346f76df40dca Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 17 Mar 2020 14:57:11 -0400 Subject: [PATCH 032/106] updated to use TypedBasicComboBoxRenderer --- .../optionspanel/EamDbSettingsDialog.java | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 3322460b7d..09b98a7337 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -38,7 +38,6 @@ import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileFilter; -import javax.swing.plaf.basic.BasicComboBoxRenderer; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -65,19 +64,17 @@ public class EamDbSettingsDialog extends JDialog { /** * This class handles displaying and rendering drop down menu for database choices in central repo. */ - private class DbChoiceRenderer extends BasicComboBoxRenderer { + private class DbChoiceRenderer extends TypedBasicComboBoxRenderer { private static final long serialVersionUID = 1L; - @SuppressWarnings("rawtypes") - public Component getListCellRendererComponent(JList list, Object value, + public Component getListCellRendererComponent( + JList list, CentralRepoDbChoice value, int index, boolean isSelected, boolean cellHasFocus) { - CentralRepoDbChoice item = (CentralRepoDbChoice) value; - // disable cell if it is the db connection from multi user settings // and that option is not enabled in multi user settings - setText(item.getTitle()); - setEnabled(isDbChoiceSelectable(item)); + setText(value.getTitle()); + setEnabled(isDbChoiceSelectable(value)); return this; } } @@ -136,15 +133,7 @@ public class EamDbSettingsDialog extends JDialog { valid(); display(); } - - - /** - * Sets the drowndown renderer so that an item is unselectable if inappropriate. - */ - @SuppressWarnings("unchecked") - private void setDropdownRenderer() { - cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); - } + private void setupDbChoice(CentralRepoDbChoice initialMenuItem) { // setup initially selected item @@ -154,7 +143,7 @@ public class EamDbSettingsDialog extends JDialog { CentralRepoDbChoice.DB_CHOICES[0] : initialMenuItem; - setDropdownRenderer(); + cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); changeDbSelection(toSelect); } From 87b6398cfc6ce5396e0bfa4706493fc80b52559f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 17 Mar 2020 14:57:20 -0400 Subject: [PATCH 033/106] updated to use TypedBasicComboBoxRenderer --- .../TypedBasicComboBoxRenderer.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java new file mode 100644 index 0000000000..8788651f73 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java @@ -0,0 +1,71 @@ +/* + * Central Repository + * + * Copyright 2015-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.centralrepository.optionspanel; + +import java.awt.Dimension; +import java.io.Serializable; +import javax.swing.JLabel; +import javax.swing.ListCellRenderer; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; + +/** + * This class implements the same behavior as the BasicComboBoxRenderer while + * providing type safety. + * @param The object type that will be used in the combo box. + */ +public abstract class TypedBasicComboBoxRenderer extends JLabel +implements ListCellRenderer, Serializable { + + protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); + private final static Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); + + /** + * The main constructor for this class. + */ + public TypedBasicComboBoxRenderer() { + super(); + setOpaque(true); + setBorder(getNoFocusBorder()); + } + + private static Border getNoFocusBorder() { + if (System.getSecurityManager() != null) { + return SAFE_NO_FOCUS_BORDER; + } else { + return noFocusBorder; + } + } + + @Override + public Dimension getPreferredSize() { + Dimension size; + + if ((this.getText() == null) || (this.getText().equals( "" ))) { + setText( " " ); + size = super.getPreferredSize(); + setText( "" ); + } + else { + size = super.getPreferredSize(); + } + + return size; + } +} From 291d778ee2a96bf2d36e15f08ebe50650ed719f7 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 17 Mar 2020 16:16:04 -0400 Subject: [PATCH 034/106] 6151: Do not add account_id column to non-account correlation attribute instance tables --- .../CentralRepoDbUpgrader13To14.java | 25 ++++++------ .../datamodel/CentralRepoDbUtil.java | 13 +++++++ .../datamodel/RdbmsCentralRepo.java | 31 ++++++++++----- .../datamodel/RdbmsCentralRepoFactory.java | 38 +++++++++++++++++-- 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index 9d6473055e..dbd1e77da4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -51,7 +51,7 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { if (type.getId() >= CorrelationAttributeInstance.ADDITIONAL_TYPES_BASE_ID) { // these are new Correlation types - new tables need to be created - statement.execute(String.format(RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform), instance_type_dbname, instance_type_dbname)); + statement.execute(String.format(RdbmsCentralRepoFactory.getCreateAccountInstancesTableTemplate(selectedPlatform), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddValueIndexTemplate(), instance_type_dbname, instance_type_dbname)); @@ -61,18 +61,19 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { // add new correlation type CentralRepoDbUtil.insertCorrelationType(connection, type); - } else { - - // Alter the existing X_Instance tables to add account_id column - String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); - statement.execute(sqlStr); - - // SQLite does NOT allow adding a constraint with Alter Table statement. - // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. - // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. - if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { - sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + } else { // existing attributes + // Alter the existing _instance tables for Phone and Email attributes to add account_id column + if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { + String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); statement.execute(sqlStr); + + // SQLite does NOT allow adding a constraint with Alter Table statement. + // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. + // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + statement.execute(sqlStr); + } } } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java index 826c315c02..69ea8d4e05 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java @@ -325,4 +325,17 @@ public class CentralRepoDbUtil { closeStatement(preparedStatement); } + /** + * Checks if the given correlation attribute type has an account behind it. + * + * @param type Correlation type to check. + * + * @return True If the specified correlation type has an account. + */ + static boolean correlationAttribHasAnAccount(CorrelationAttributeInstance.Type type) { + return (type.getId() >= CorrelationAttributeInstance.ADDITIONAL_TYPES_BASE_ID) + || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID + || type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID; + } + } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 63f8e2f13a..148513f40c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -1002,18 +1002,26 @@ abstract class RdbmsCentralRepo implements CentralRepository { public void addArtifactInstance(CorrelationAttributeInstance eamArtifact) throws CentralRepoException { checkAddArtifactInstanceNulls(eamArtifact); - - - - // @@@ We should cache the case and data source IDs in memory String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()); - String sql - = "INSERT INTO " + boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType()); + + String sql; + // _instance table for accounts have an additional account_id column + if (artifactHasAnAccount) { + sql = "INSERT INTO " + tableName + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?) " + getConflictClause(); + } + else { + sql = "INSERT INTO " + + tableName + + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " + + "VALUES (?, ?, ?, ?, ?, ?, ?) " + + getConflictClause(); + } try (Connection conn = connect(); PreparedStatement preparedStatement = conn.prepareStatement(sql);) { @@ -1032,10 +1040,13 @@ abstract class RdbmsCentralRepo implements CentralRepository { } preparedStatement.setLong(7, eamArtifact.getFileObjectId()); - if (eamArtifact.getAccountId() >= 0) { - preparedStatement.setLong(8, eamArtifact.getAccountId()); - } else { - preparedStatement.setNull(8, Types.INTEGER); + // set in the accountId only for artifacts that represent accounts + if (artifactHasAnAccount) { + if (eamArtifact.getAccountId() >= 0) { + preparedStatement.setLong(8, eamArtifact.getAccountId()); + } else { + preparedStatement.setNull(8, Types.INTEGER); + } } preparedStatement.executeUpdate(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 1232d708a6..d50d344a5e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -83,6 +83,7 @@ public class RdbmsCentralRepoFactory { public boolean initializeDatabaseSchema() { String createArtifactInstancesTableTemplate = getCreateArtifactInstancesTableTemplate(selectedPlatform); + String createAccountInstancesTableTemplate = getCreateAccountInstancesTableTemplate(selectedPlatform); String instancesCaseIdIdx = getAddCaseIdIndexTemplate(); String instancesDatasourceIdIdx = getAddDataSourceIdIndexTemplate(); @@ -147,7 +148,13 @@ public class RdbmsCentralRepoFactory { reference_type_dbname = CentralRepoDbUtil.correlationTypeToReferenceTableName(type); instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type); - stmt.execute(String.format(createArtifactInstancesTableTemplate, instance_type_dbname, instance_type_dbname)); + // use the correct create table template, based on whether the attribute type represents an account or not. + String createTableTemplate = (CentralRepoDbUtil.correlationAttribHasAnAccount(type)) + ? createAccountInstancesTableTemplate + : createArtifactInstancesTableTemplate; + + stmt.execute(String.format(createTableTemplate, instance_type_dbname, instance_type_dbname)); + stmt.execute(String.format(instancesCaseIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesDatasourceIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesValueIdx, instance_type_dbname, instance_type_dbname)); @@ -357,7 +364,7 @@ public class RdbmsCentralRepoFactory { + ")"; } /** - * Get the template String for creating a new _instances table in a Sqlite + * Get the template String for creating a new _instances table for non account artifacts in * central repository. %s will exist in the template where the name of the * new table will be added. * @@ -365,6 +372,31 @@ public class RdbmsCentralRepoFactory { */ static String getCreateArtifactInstancesTableTemplate(CentralRepoPlatforms selectedPlatform) { // Each "%s" will be replaced with the relevant TYPE_instances table name. + + return "CREATE TABLE IF NOT EXISTS %s (" + + getNumericPrimaryKeyClause("id", selectedPlatform) + + "case_id integer NOT NULL," + + "data_source_id integer NOT NULL," + + "value text NOT NULL," + + "file_path text NOT NULL," + + "known_status integer NOT NULL," + + "comment text," + + "file_obj_id " + getBigIntType(selectedPlatform) + " ," + + "CONSTRAINT %s_multi_unique UNIQUE(data_source_id, value, file_path)" + getOnConflictIgnoreClause(selectedPlatform) + "," + + "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL," + + "foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL)"; + } + + /** + * Get the template String for creating a new _instances table for Accounts in + * central repository. %s will exist in the template where the name of the + * new table will be added. + * + * @return a String which is a template for creating a _instances table + */ + static String getCreateAccountInstancesTableTemplate(CentralRepoPlatforms selectedPlatform) { + // Each "%s" will be replaced with the relevant TYPE_instances table name. + return "CREATE TABLE IF NOT EXISTS %s (" + getNumericPrimaryKeyClause("id", selectedPlatform) + "case_id integer NOT NULL," @@ -380,7 +412,7 @@ public class RdbmsCentralRepoFactory { + "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL," + "foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL)"; } - + /** * Get the statement String for creating a new data_sources table in a * Sqlite central repository. From 6b2f81134a9fcc4392e3e60e4db597d6cfe540f9 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 17 Mar 2020 18:48:29 -0400 Subject: [PATCH 035/106] Address Codacy comment. --- .../CentralRepoDbUpgrader13To14.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index dbd1e77da4..0acfd34ea5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -61,19 +61,17 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { // add new correlation type CentralRepoDbUtil.insertCorrelationType(connection, type); - } else { // existing attributes + } else if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { // Alter the existing _instance tables for Phone and Email attributes to add account_id column - if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { - String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); - statement.execute(sqlStr); + String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); + statement.execute(sqlStr); - // SQLite does NOT allow adding a constraint with Alter Table statement. - // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. - // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. - if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { - sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); - statement.execute(sqlStr); - } + // SQLite does NOT allow adding a constraint with Alter Table statement. + // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. + // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + statement.execute(sqlStr); } } } From 1c20055a7efe934b82454ee4101472032dd3e3f3 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 08:02:16 -0400 Subject: [PATCH 036/106] semi-working version of zoom panel --- .../keywordsearch/ExtractedContentPanel.form | 14 +- .../keywordsearch/ExtractedContentPanel.java | 14 +- .../autopsy/keywordsearch/TextZoomPanel.form | 217 ++++++++---------- .../autopsy/keywordsearch/TextZoomPanel.java | 48 ++-- 4 files changed, 120 insertions(+), 173 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index a610023951..f57d011dd9 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -105,7 +105,7 @@ - + @@ -147,8 +147,8 @@ - - + + @@ -433,11 +433,11 @@ - + - + @@ -452,12 +452,12 @@ - + - + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index cc4014922a..cb3e5b43f6 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -236,7 +236,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP controlScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); controlScrollPane.setPreferredSize(new java.awt.Dimension(600, 100)); - controlPanel.setMinimumSize(new java.awt.Dimension(0, 0)); + controlPanel.setMinimumSize(new java.awt.Dimension(0, 20)); controlPanel.setPreferredSize(new java.awt.Dimension(600, 81)); sourceComboBox.setModel(new javax.swing.DefaultComboBoxModel()); @@ -319,19 +319,19 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); - zoomPanel.setMinimumSize(new java.awt.Dimension(150, 26)); + zoomPanel.setMinimumSize(new java.awt.Dimension(150, 20)); zoomPanel.setName(""); // NOI18N - zoomPanel.setPreferredSize(new java.awt.Dimension(200, 26)); + zoomPanel.setPreferredSize(new java.awt.Dimension(200, 20)); javax.swing.GroupLayout zoomPanelLayout = new javax.swing.GroupLayout(zoomPanel); zoomPanel.setLayout(zoomPanelLayout); zoomPanelLayout.setHorizontalGroup( zoomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 401, Short.MAX_VALUE) + .addGap(0, 200, Short.MAX_VALUE) ); zoomPanelLayout.setVerticalGroup( zoomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 26, Short.MAX_VALUE) + .addGap(0, 20, Short.MAX_VALUE) ); javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); @@ -370,8 +370,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addGap(0, 0, 0) .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 401, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(144, 144, 144) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel1) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form index c3bfb59d2c..06185c7333 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form @@ -3,10 +3,10 @@ - + - + @@ -20,139 +20,108 @@ + - - - - - - - - - - - - - - + + + - + - - + + + + + - + - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 31952a2fd6..58c264da2c 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -78,29 +78,18 @@ class TextZoomPanel extends JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - toolbar = new javax.swing.JToolBar(); - jSeparator1 = new javax.swing.JToolBar.Separator(); zoomTextField = new javax.swing.JTextField(); + jSeparator1 = new javax.swing.JToolBar.Separator(); zoomOutButton = new javax.swing.JButton(); zoomInButton = new javax.swing.JButton(); jSeparator2 = new javax.swing.JToolBar.Separator(); zoomResetButton = new javax.swing.JButton(); filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0)); - setMinimumSize(new java.awt.Dimension(150, 23)); - setPreferredSize(new java.awt.Dimension(200, 23)); + setMinimumSize(new java.awt.Dimension(150, 20)); + setPreferredSize(new java.awt.Dimension(200, 20)); setRequestFocusEnabled(false); - - toolbar.setFloatable(false); - toolbar.setRollover(true); - toolbar.setMaximumSize(new java.awt.Dimension(200, 23)); - toolbar.setMinimumSize(new java.awt.Dimension(150, 23)); - toolbar.setName(""); // NOI18N - toolbar.setPreferredSize(new java.awt.Dimension(200, 23)); - toolbar.setRequestFocusEnabled(false); - - jSeparator1.setMaximumSize(new java.awt.Dimension(6, 20)); - toolbar.add(jSeparator1); + setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 2, 0)); zoomTextField.setEditable(false); zoomTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT); @@ -108,7 +97,10 @@ class TextZoomPanel extends JPanel { zoomTextField.setMaximumSize(new java.awt.Dimension(50, 2147483647)); zoomTextField.setMinimumSize(new java.awt.Dimension(50, 20)); zoomTextField.setPreferredSize(new java.awt.Dimension(50, 20)); - toolbar.add(zoomTextField); + add(zoomTextField); + + jSeparator1.setMaximumSize(new java.awt.Dimension(6, 20)); + add(jSeparator1); zoomOutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-out.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomOutButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomOutButton.text")); // NOI18N @@ -122,7 +114,7 @@ class TextZoomPanel extends JPanel { zoomOutButtonActionPerformed(evt); } }); - toolbar.add(zoomOutButton); + add(zoomOutButton); zoomInButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-in.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomInButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomInButton.text")); // NOI18N @@ -136,10 +128,10 @@ class TextZoomPanel extends JPanel { zoomInButtonActionPerformed(evt); } }); - toolbar.add(zoomInButton); + add(zoomInButton); jSeparator2.setMaximumSize(new java.awt.Dimension(6, 20)); - toolbar.add(jSeparator2); + add(jSeparator2); org.openide.awt.Mnemonics.setLocalizedText(zoomResetButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomResetButton.text")); // NOI18N zoomResetButton.setFocusable(false); @@ -150,21 +142,8 @@ class TextZoomPanel extends JPanel { zoomResetButtonActionPerformed(evt); } }); - toolbar.add(zoomResetButton); - toolbar.add(filler1); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(toolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 885, javax.swing.GroupLayout.PREFERRED_SIZE)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(toolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - ); + add(zoomResetButton); + add(filler1); }// //GEN-END:initComponents private void zoomOutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutButtonActionPerformed @@ -184,7 +163,6 @@ class TextZoomPanel extends JPanel { private javax.swing.Box.Filler filler1; private javax.swing.JToolBar.Separator jSeparator1; private javax.swing.JToolBar.Separator jSeparator2; - private javax.swing.JToolBar toolbar; private javax.swing.JButton zoomInButton; private javax.swing.JButton zoomOutButton; private javax.swing.JButton zoomResetButton; From 11c0f4e3139f60395d4da0547a4780d2bf938f90 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 09:27:40 -0400 Subject: [PATCH 037/106] fixed resize issues --- .../keywordsearch/ExtractedContentPanel.form | 19 +++-------- .../keywordsearch/ExtractedContentPanel.java | 32 ++++++++----------- .../autopsy/keywordsearch/TextZoomPanel.form | 4 +-- .../autopsy/keywordsearch/TextZoomPanel.java | 20 +++++++++--- 4 files changed, 35 insertions(+), 40 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index f57d011dd9..b4c0490559 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -45,8 +45,8 @@ - - + + @@ -180,7 +180,7 @@ - + @@ -449,18 +449,7 @@
- - - - - - - - - - - - +
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index cb3e5b43f6..8dc9b244fd 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -30,6 +30,7 @@ import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JLabel; import javax.swing.SizeRequirements; +import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.text.Element; import javax.swing.text.View; @@ -130,9 +131,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP }; } }; - + // get the style sheet for editing font size styleSheet = editorKit.getStyleSheet(); - setTextSize(40); sourceComboBox.addItemListener(itemEvent -> { if (itemEvent.getStateChange() == ItemEvent.SELECTED) { @@ -143,8 +143,15 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP copyMenuItem.addActionListener(actionEvent -> extractedTextPane.copy()); selectAllMenuItem.addActionListener(actionEvent -> extractedTextPane.selectAll()); - zoomPanel.setEnabled(true); - zoomPanel.setVisible(true); + // TextZoomPanel could not be directly instantiated in Swing WYSIWYG editor + // (because it was package private, couldn't use constructor, etc.) + // so it was identified as a JPanel for the WYSIWYG. This function is called for + // initial setup so the font size of this panel as well as the font size indicated + // in the TextZoomPanel are correct + SwingUtilities.invokeLater(() -> { + if (zoomPanel != null && zoomPanel instanceof TextZoomPanel) + ((TextZoomPanel) this.zoomPanel).resetSize(); + }); } @@ -323,17 +330,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP zoomPanel.setName(""); // NOI18N zoomPanel.setPreferredSize(new java.awt.Dimension(200, 20)); - javax.swing.GroupLayout zoomPanelLayout = new javax.swing.GroupLayout(zoomPanel); - zoomPanel.setLayout(zoomPanelLayout); - zoomPanelLayout.setHorizontalGroup( - zoomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 200, Short.MAX_VALUE) - ); - zoomPanelLayout.setVerticalGroup( - zoomPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 20, Short.MAX_VALUE) - ); - javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); controlPanel.setLayout(controlPanelLayout); controlPanelLayout.setHorizontalGroup( @@ -401,7 +397,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addComponent(hitOfLabel) .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(hitButtonsLabel) - .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(zoomPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(56, 56, 56)) ); @@ -415,8 +411,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1096, Short.MAX_VALUE) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1096, Short.MAX_VALUE) + .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE) + .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form index 06185c7333..59ce7e1a50 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form @@ -24,7 +24,8 @@ - + + @@ -115,7 +116,6 @@ - diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 58c264da2c..3ec657ab92 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -14,7 +14,11 @@ import org.openide.util.NbBundle; */ class TextZoomPanel extends JPanel { static final int DEFAULT_SIZE = new JLabel().getFont().getSize(); + + // how much font size is incremented or decremented when zooming in or zooming out respectively private static final int FONT_INCREMENT_DELTA = 1; + private static final int MIN_FONT_SIZE = 5; + private static final Integer MAX_FONT_SIZE = 140; private final ResizableTextPanel zoomable; @@ -28,7 +32,6 @@ class TextZoomPanel extends JPanel { updateEnabled(); setZoomText(); } - private void updateEnabled() { @@ -39,14 +42,22 @@ class TextZoomPanel extends JPanel { this.zoomTextField.setEnabled(shouldEnable); } - private void resetSize() { + /** + * resets the font size displayed and triggers the ResizableTextPanel to + * set their font to default size (i.e. JLabel().getFont().getSize()) + */ + public void resetSize() { zoomAbs(DEFAULT_SIZE); } private void zoomAbs(int fontSize) { - if (this.zoomable != null) { + if (this.zoomable != null && fontSize >= MIN_FONT_SIZE && + (MAX_FONT_SIZE == null || fontSize <= MAX_FONT_SIZE)) { + this.zoomable.setTextSize(fontSize); setZoomText(); + + System.out.println("zoom in button " + zoomInButton.getHeight() + " reset button " + zoomResetButton.getHeight()); } } @@ -89,7 +100,7 @@ class TextZoomPanel extends JPanel { setMinimumSize(new java.awt.Dimension(150, 20)); setPreferredSize(new java.awt.Dimension(200, 20)); setRequestFocusEnabled(false); - setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 2, 0)); + setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING, 0, 0)); zoomTextField.setEditable(false); zoomTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT); @@ -136,7 +147,6 @@ class TextZoomPanel extends JPanel { org.openide.awt.Mnemonics.setLocalizedText(zoomResetButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomResetButton.text")); // NOI18N zoomResetButton.setFocusable(false); zoomResetButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - zoomResetButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); zoomResetButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomResetButtonActionPerformed(evt); From 8992b195235da51ba676c1c014f0a3fdb8e54580 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 09:32:01 -0400 Subject: [PATCH 038/106] added licenses --- .../keywordsearch/ExtractedContentPanel.java | 2 +- .../keywordsearch/ResizableTextPanel.java | 19 ++++++++++++++++--- .../autopsy/keywordsearch/TextZoomPanel.java | 19 ++++++++++++++++--- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 8dc9b244fd..2a99b24e83 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2011-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ResizableTextPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ResizableTextPanel.java index 719e54ecc7..290ed2b633 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ResizableTextPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ResizableTextPanel.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.keywordsearch; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 3ec657ab92..a01dd82ad5 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -1,7 +1,20 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2011-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.keywordsearch; From 8fdb645124e0b0233668f9d2e74221204da10d96 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 18 Mar 2020 09:36:46 -0400 Subject: [PATCH 039/106] Remove X-log from file discovery to focus on user created docs --- Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java index d86d470102..32a2cf19cb 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java @@ -273,7 +273,6 @@ final class FileSearchData { = new ImmutableSet.Builder() .add("text/html", //NON-NLS "text/csv", //NON-NLS - "text/x-log", //NON-NLS "application/rtf", //NON-NLS "application/pdf", //NON-NLS "application/xhtml+xml", //NON-NLS From b15ec80caad9e2464d9c62f7d9e10d69eca2f213 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 10:07:06 -0400 Subject: [PATCH 040/106] tracks last known anchor --- .../autopsy/keywordsearch/ExtractedContentPanel.java | 7 +++++-- .../org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 2a99b24e83..86785b1f3e 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -65,6 +65,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP private final StyleSheet styleSheet; private final HTMLEditorKit editorKit; + private String lastKnownAnchor = null; ExtractedContentPanel() { initComponents(); @@ -169,7 +170,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP public void setTextSize(int newSize) { curSize = newSize; - int caretPos = extractedTextPane.getCaretPosition(); String curText = extractedTextPane.getText(); setStyleSheetSize(styleSheet, curSize); @@ -178,7 +178,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP extractedTextPane.setEditorKit(editorKit); extractedTextPane.setText(curText); - extractedTextPane.setCaretPosition(caretPos); + if (lastKnownAnchor != null) + scrollToAnchor(lastKnownAnchor); } @@ -465,6 +466,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP * the content. */ final void setSources(String contentName, List sources) { + this.lastKnownAnchor = null; this.contentName = contentName; setPanelText(null, false); @@ -512,6 +514,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP } void scrollToAnchor(String anchor) { + lastKnownAnchor = anchor; extractedTextPane.scrollToReference(anchor); } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index a01dd82ad5..9035ed329d 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -59,7 +59,7 @@ class TextZoomPanel extends JPanel { * resets the font size displayed and triggers the ResizableTextPanel to * set their font to default size (i.e. JLabel().getFont().getSize()) */ - public void resetSize() { + void resetSize() { zoomAbs(DEFAULT_SIZE); } From 906fc50a087cf5fe944b452ee94e68e1cf5a744e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 11:02:53 -0400 Subject: [PATCH 041/106] using list renderer --- .../optionspanel/EamDbSettingsDialog.java | 5 +- .../TypedBasicComboBoxRenderer.java | 71 ------------------- 2 files changed, 4 insertions(+), 72 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 09b98a7337..fda6935999 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -24,6 +24,7 @@ import java.awt.Cursor; import java.awt.HeadlessException; import java.io.File; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -31,9 +32,11 @@ import java.util.logging.Level; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JTextField; +import javax.swing.ListCellRenderer; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -64,7 +67,7 @@ public class EamDbSettingsDialog extends JDialog { /** * This class handles displaying and rendering drop down menu for database choices in central repo. */ - private class DbChoiceRenderer extends TypedBasicComboBoxRenderer { + private class DbChoiceRenderer extends JLabel implements ListCellRenderer, Serializable { private static final long serialVersionUID = 1L; public Component getListCellRendererComponent( diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java deleted file mode 100644 index 8788651f73..0000000000 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Central Repository - * - * Copyright 2015-2020 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.centralrepository.optionspanel; - -import java.awt.Dimension; -import java.io.Serializable; -import javax.swing.JLabel; -import javax.swing.ListCellRenderer; -import javax.swing.border.Border; -import javax.swing.border.EmptyBorder; - -/** - * This class implements the same behavior as the BasicComboBoxRenderer while - * providing type safety. - * @param The object type that will be used in the combo box. - */ -public abstract class TypedBasicComboBoxRenderer extends JLabel -implements ListCellRenderer, Serializable { - - protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); - private final static Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); - - /** - * The main constructor for this class. - */ - public TypedBasicComboBoxRenderer() { - super(); - setOpaque(true); - setBorder(getNoFocusBorder()); - } - - private static Border getNoFocusBorder() { - if (System.getSecurityManager() != null) { - return SAFE_NO_FOCUS_BORDER; - } else { - return noFocusBorder; - } - } - - @Override - public Dimension getPreferredSize() { - Dimension size; - - if ((this.getText() == null) || (this.getText().equals( "" ))) { - setText( " " ); - size = super.getPreferredSize(); - setText( "" ); - } - else { - size = super.getPreferredSize(); - } - - return size; - } -} From d47768e708d7cab7a54da902bca0fb7e8c1ded6a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 11:56:53 -0400 Subject: [PATCH 042/106] changed to percentage --- .../keywordsearch/ExtractedContentPanel.form | 5 ++ .../keywordsearch/ExtractedContentPanel.java | 7 ++- .../autopsy/keywordsearch/TextZoomPanel.java | 53 +++++++++++-------- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index b4c0490559..0b8ebb982b 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -147,6 +147,8 @@ + + @@ -180,6 +182,7 @@ + @@ -430,6 +433,8 @@ + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 86785b1f3e..2df4e81905 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -220,6 +220,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP hitPreviousButton = new javax.swing.JButton(); hitCountLabel = new javax.swing.JLabel(); jSeparator2 = new javax.swing.JSeparator(); + jSeparator3 = new javax.swing.JSeparator(); zoomPanel = new TextZoomPanel(this); copyMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.copyMenuItem.text")); // NOI18N @@ -367,6 +368,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addGap(0, 0, 0) .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(144, 144, 144) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -398,11 +401,12 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addComponent(hitOfLabel) .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(hitButtonsLabel) + .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(zoomPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(56, 56, 56)) ); - controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator1, jSeparator2, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox}); + controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator1, jSeparator2, jSeparator3, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox}); zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.AccessibleContext.accessibleName")); // NOI18N @@ -440,6 +444,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP private javax.swing.JLabel jLabel1; private javax.swing.JSeparator jSeparator1; private javax.swing.JSeparator jSeparator2; + private javax.swing.JSeparator jSeparator3; private javax.swing.JLabel pageButtonsLabel; private javax.swing.JLabel pageCurLabel; private javax.swing.JButton pageNextButton; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 9035ed329d..7b3cde27ee 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -28,13 +28,23 @@ import org.openide.util.NbBundle; class TextZoomPanel extends JPanel { static final int DEFAULT_SIZE = new JLabel().getFont().getSize(); - // how much font size is incremented or decremented when zooming in or zooming out respectively + // How much font size is incremented or decremented when zooming in or zooming out respectively. private static final int FONT_INCREMENT_DELTA = 1; - private static final int MIN_FONT_SIZE = 5; - private static final Integer MAX_FONT_SIZE = 140; + private static final double[] ZOOM_STEPS = { + 0.0625, 0.125, 0.25, 0.375, 0.5, 0.75, + 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10}; + + // Identifies the center index in zoom steps (what identifies 100%). + private static final int DEFAULT_STEP_IDX = 6; + + // The component to receive zoom updates. private final ResizableTextPanel zoomable; + // On initialization, set to 100%. + private int curStepIndex = DEFAULT_STEP_IDX; + + /** * Creates new form TextZoomPanel. * @param zoomable the component that will receive text resize events @@ -59,32 +69,31 @@ class TextZoomPanel extends JPanel { * resets the font size displayed and triggers the ResizableTextPanel to * set their font to default size (i.e. JLabel().getFont().getSize()) */ - void resetSize() { - zoomAbs(DEFAULT_SIZE); + synchronized void resetSize() { + zoomStep(DEFAULT_STEP_IDX); } - private void zoomAbs(int fontSize) { - if (this.zoomable != null && fontSize >= MIN_FONT_SIZE && - (MAX_FONT_SIZE == null || fontSize <= MAX_FONT_SIZE)) { - - this.zoomable.setTextSize(fontSize); + private synchronized void zoomStep(int newStep) { + if (this.zoomable != null && newStep >= 0 && newStep < ZOOM_STEPS.length) { + curStepIndex = newStep; + zoomable.setTextSize((int)Math.round(ZOOM_STEPS[curStepIndex] * (double)DEFAULT_SIZE)); setZoomText(); - - System.out.println("zoom in button " + zoomInButton.getHeight() + " reset button " + zoomResetButton.getHeight()); } } + private synchronized void zoomDecrement() { + zoomStep(curStepIndex - 1); + } + + private synchronized void zoomIncrement() { + zoomStep(curStepIndex + 1); + } + private void setZoomText() { - int fontSize = (this.zoomable == null) ? DEFAULT_SIZE : this.zoomable.getTextSize(); - zoomTextField.setText(fontSize + "pt"); + String percent = Long.toString(Math.round(ZOOM_STEPS[this.curStepIndex] * 100)); + zoomTextField.setText(percent + "%"); } - private void zoomDelta(int changeFactor) { - if (this.zoomable != null) { - int curSize = this.zoomable.getTextSize(); - zoomAbs(curSize + changeFactor); - } - } @NbBundle.Messages({ @@ -170,11 +179,11 @@ class TextZoomPanel extends JPanel { }// //GEN-END:initComponents private void zoomOutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutButtonActionPerformed - zoomDelta(-FONT_INCREMENT_DELTA); + zoomDecrement(); }//GEN-LAST:event_zoomOutButtonActionPerformed private void zoomInButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomInButtonActionPerformed - zoomDelta(FONT_INCREMENT_DELTA); + zoomIncrement(); }//GEN-LAST:event_zoomInButtonActionPerformed private void zoomResetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomResetButtonActionPerformed From 065a7313c399f10a27a143e5c6f840697c40abc3 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 12:01:35 -0400 Subject: [PATCH 043/106] added override annotation --- .../centralrepository/optionspanel/EamDbSettingsDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index fda6935999..4c70d6aa5c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -70,6 +70,7 @@ public class EamDbSettingsDialog extends JDialog { private class DbChoiceRenderer extends JLabel implements ListCellRenderer, Serializable { private static final long serialVersionUID = 1L; + @Override public Component getListCellRendererComponent( JList list, CentralRepoDbChoice value, int index, boolean isSelected, boolean cellHasFocus) { From 83cfe0b9f9454ab563105f07a622c895171e804e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 13:42:20 -0400 Subject: [PATCH 044/106] vertical bar to separate zoom --- .../autopsy/keywordsearch/ExtractedContentPanel.form | 11 +++-------- .../autopsy/keywordsearch/ExtractedContentPanel.java | 11 +++-------- .../autopsy/keywordsearch/TextZoomPanel.form | 6 +++++- .../autopsy/keywordsearch/TextZoomPanel.java | 4 ++++ 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index 0b8ebb982b..444e9a7cac 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -150,8 +150,6 @@ - - @@ -170,7 +168,6 @@ - @@ -307,11 +304,6 @@ - - - - - @@ -434,6 +426,9 @@ + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 2df4e81905..0722157fec 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -211,7 +211,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP pageNextButton = new javax.swing.JButton(); pagePreviousButton = new javax.swing.JButton(); pageCurLabel = new javax.swing.JLabel(); - jSeparator1 = new javax.swing.JSeparator(); hitLabel = new javax.swing.JLabel(); hitButtonsLabel = new javax.swing.JLabel(); hitNextButton = new javax.swing.JButton(); @@ -285,8 +284,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP pageCurLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); pageCurLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.pageCurLabel.text")); // NOI18N - jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL); - hitLabel.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.text")); // NOI18N hitLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.hitLabel.toolTipText")); // NOI18N @@ -328,6 +325,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); + jSeparator3.setOrientation(javax.swing.SwingConstants.VERTICAL); + zoomPanel.setMinimumSize(new java.awt.Dimension(150, 20)); zoomPanel.setName(""); // NOI18N zoomPanel.setPreferredSize(new java.awt.Dimension(200, 20)); @@ -371,8 +370,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(144, 144, 144) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -389,7 +386,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addComponent(pageButtonsLabel) .addComponent(pagePreviousButton) .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(sourceComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(pagesLabel) .addComponent(hitLabel) @@ -406,7 +402,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addGap(56, 56, 56)) ); - controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator1, jSeparator2, jSeparator3, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox}); + controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator2, jSeparator3, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox}); zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.AccessibleContext.accessibleName")); // NOI18N @@ -442,7 +438,6 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP private javax.swing.JButton hitPreviousButton; private javax.swing.JLabel hitTotalLabel; private javax.swing.JLabel jLabel1; - private javax.swing.JSeparator jSeparator1; private javax.swing.JSeparator jSeparator2; private javax.swing.JSeparator jSeparator3; private javax.swing.JLabel pageButtonsLabel; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form index 59ce7e1a50..4a190ad1a9 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form @@ -20,7 +20,7 @@ - + @@ -62,6 +62,7 @@ + @@ -86,6 +87,7 @@ + @@ -104,6 +106,7 @@ + @@ -114,6 +117,7 @@ + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 7b3cde27ee..2aa3f13324 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -137,6 +137,7 @@ class TextZoomPanel extends JPanel { zoomOutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-out.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomOutButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomOutButton.text")); // NOI18N + zoomOutButton.setBorderPainted(false); zoomOutButton.setFocusable(false); zoomOutButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); zoomOutButton.setMaximumSize(new java.awt.Dimension(24, 24)); @@ -151,6 +152,7 @@ class TextZoomPanel extends JPanel { zoomInButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-in.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomInButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomInButton.text")); // NOI18N + zoomInButton.setBorderPainted(false); zoomInButton.setFocusable(false); zoomInButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); zoomInButton.setMaximumSize(new java.awt.Dimension(24, 24)); @@ -163,10 +165,12 @@ class TextZoomPanel extends JPanel { }); add(zoomInButton); + jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); jSeparator2.setMaximumSize(new java.awt.Dimension(6, 20)); add(jSeparator2); org.openide.awt.Mnemonics.setLocalizedText(zoomResetButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomResetButton.text")); // NOI18N + zoomResetButton.setBorderPainted(false); zoomResetButton.setFocusable(false); zoomResetButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); zoomResetButton.addActionListener(new java.awt.event.ActionListener() { From aa6ed94b14f5e95b2f543eb0e220865ef73f3dd1 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 14:07:34 -0400 Subject: [PATCH 045/106] Implemented a safer and correct way of calling Gst.init() --- .../contentviewers/MediaPlayerPanel.java | 21 ++---- .../contentviewers/utils/GstLoader.java | 72 +++++++++++++++++++ 2 files changed, 78 insertions(+), 15 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index d2d8ace001..53bae5638d 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -74,6 +74,8 @@ import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstException; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.event.SeekType; +import org.sleuthkit.autopsy.contentviewers.utils.GstLoader; +import org.sleuthkit.autopsy.contentviewers.utils.GstLoader.GstStatus; /** * This is a video player that is part of the Media View layered pane. It uses @@ -540,23 +542,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie if (this.isCancelled()) { return; } - - // Setting the following property causes the GST - // Java bindings to call dispose() on the GST - // service thread instead of running it in the GST - // Native Object Reaper thread. - System.setProperty("glib.reapOnEDT", "true"); - - // Initialize Gstreamer. It is safe to call this for every file. - // It was moved here from the constructor because having it happen - // earlier resulted in crashes on Linux. See JIRA-5888. - Gst.init(); - - if (!Gst.isInitialized()) { - logger.log(Level.INFO, "GStreamer is not initialized."); //NON-NLS + + GstStatus loadStatus = GstLoader.tryLoad(); + if(loadStatus == GstStatus.FAILURE) { return; } - + Gst.getExecutor().submit(() -> { //Video is ready for playback. Create new components gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java new file mode 100755 index 0000000000..d04e0f4ac0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -0,0 +1,72 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sleuthkit.autopsy.contentviewers.utils; + +import java.util.logging.Level; +import org.freedesktop.gstreamer.Gst; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; + +/** + * + * @author dsmyda + */ +public class GstLoader { + + private static final Logger logger = Logger.getLogger(GstLoader.class.getName()); + private static GstStatus status; + + /** + * Attempts to load the gstreamer bindings. Only one attempt will be + * performed per Autopsy process. Clients should not attempt to interact + * with the gstreamer bindings unless the load was successful. + * + * @return Status - SUCCESS or FAILURE + */ + public synchronized static GstStatus tryLoad() { + // Null is our 'unknown' status. Prior to the first call, the status + // is unknown. + if (status != null) { + return status; + } + + try { + // Setting the following property causes the GST + // Java bindings to call dispose() on the GST + // service thread instead of running it in the GST + // Native Object Reaper thread. + System.setProperty("glib.reapOnEDT", "true"); + Gst.init(); + status = GstStatus.SUCCESS; + } catch (Throwable ex) { + status = GstStatus.FAILURE; + MessageNotifyUtil.Message.error("A problem was encountered with" + + "the video playback service. Video playback will" + + " be disabled for the remainder of the session."); + logger.log(Level.WARNING, "Failed to load gsteamer bindings", ex); + } + + return status; + } + + public enum GstStatus { + SUCCESS, FAILURE + } +} From 10e16281ed0904206b0e701c8a0a3985ed8c3a07 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 16:31:04 -0400 Subject: [PATCH 046/106] don't raise warning if settings not located --- .../CentralRepoPostgresSettingsUtil.java | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index 3f75e9e183..86f929ba0e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -63,9 +63,21 @@ public class CentralRepoPostgresSettingsUtil { private CentralRepoPostgresSettingsUtil() {} - private void logException(TryHandler handler) { + /** + * Uses setter object to set a value as specified by 'value'. In the event that 'value' + * is null, the setter will not be called. Exceptions that are raised from the setter will + * be logged. + * + * @param setter The setter to call. + * @param value The value to use with the setter. + */ + private void setValOrLog(ValueSetter setter, String value) { + // ignore null values as they indicate a setting that is not set yet + if (value == null || value.isEmpty()) + return; + try { - handler.operation(); + setter.set(value); } catch (CentralRepoException | NumberFormatException e) { LOGGER.log(Level.WARNING, "There was an error in converting central repo postgres settings", e); @@ -73,10 +85,10 @@ public class CentralRepoPostgresSettingsUtil { } /** - * This interface represents an action that potentially throws an exception. + * This interface represents a setter that potentially throws an exception. */ - private interface TryHandler { - void operation() throws CentralRepoException, NumberFormatException; + private interface ValueSetter { + void set(String value) throws CentralRepoException, NumberFormatException; } /** @@ -96,15 +108,12 @@ public class CentralRepoPostgresSettingsUtil { return settings; } - logException(() -> settings.setHost(muConn.getHost())); - logException(() -> settings.setDbName(PostgresConnectionSettings.DEFAULT_DBNAME)); - logException(() -> settings.setUserName(muConn.getUserName())); - - logException(() -> settings.setPort(Integer.parseInt(muConn.getPort()))); - logException(() -> settings.setBulkThreshold(RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD)); - - logException(() -> settings.setPassword(muConn.getPassword())); + setValOrLog((v) -> settings.setHost(v), muConn.getHost()); + setValOrLog((v) -> settings.setUserName(v), muConn.getUserName()); + setValOrLog((v) -> settings.setPassword(v), muConn.getPassword()); + setValOrLog((v) -> settings.setPort(Integer.parseInt(v)), muConn.getPort()); + return settings; } @@ -120,24 +129,27 @@ public class CentralRepoPostgresSettingsUtil { Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); - logException(() -> settings.setHost(keyVals.get(HOST_KEY))); - logException(() -> settings.setDbName(keyVals.get(DBNAME_KEY))); - logException(() -> settings.setUserName(keyVals.get(USER_KEY))); + setValOrLog((v) -> settings.setHost(v), keyVals.get(HOST_KEY)); + setValOrLog((v) -> settings.setDbName(v), keyVals.get(DBNAME_KEY)); + setValOrLog((v) -> settings.setUserName(v), keyVals.get(USER_KEY)); - logException(() -> settings.setPort(Integer.parseInt(keyVals.get(PORT_KEY)))); - logException(() -> settings.setBulkThreshold(Integer.parseInt(keyVals.get((BULK_THRESHOLD_KEY))))); + setValOrLog((v) -> settings.setPort(Integer.parseInt(v)), keyVals.get(PORT_KEY)); + setValOrLog((v) -> settings.setBulkThreshold(Integer.parseInt(v)), keyVals.get((BULK_THRESHOLD_KEY))); String passwordHex = keyVals.get(PASSWORD_KEY); - String password; - try { - password = TextConverter.convertHexTextToText(passwordHex); - } catch (TextConverterException ex) { - LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); - password = null; + if (passwordHex != null) { + String password; + try { + password = TextConverter.convertHexTextToText(passwordHex); + } catch (TextConverterException ex) { + LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); + password = null; + } + + final String finalPassword = password; + setValOrLog((v) -> settings.setPassword(v), finalPassword); } - final String finalPassword = password; - logException(() -> settings.setPassword(finalPassword)); return settings; } From 60f6077fc7ff807f08987027820fb1dc81acb667 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:20:53 -0400 Subject: [PATCH 047/106] Reverted form changes --- .../autopsy/contentviewers/MediaPlayerPanel.form | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index 793e31830b..e5a4279d54 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -63,7 +63,7 @@ - + @@ -129,6 +129,12 @@ + + + + + + @@ -326,4 +332,4 @@ - + \ No newline at end of file From 0ff95aa2769e66e3e2f4cdbeb1f6ab8e3b850a25 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:22:05 -0400 Subject: [PATCH 048/106] Added new line ending : --- .../org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index e5a4279d54..0b00c43d8a 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -332,4 +332,4 @@ - \ No newline at end of file + From 2a439826dafa961f318ca7e24e57336bd50db321 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:33:22 -0400 Subject: [PATCH 049/106] Updated bundle message and form file --- .../autopsy/contentviewers/Bundle.properties-MERGED | 2 +- .../autopsy/contentviewers/MediaPlayerPanel.form | 8 +------- .../autopsy/contentviewers/MediaPlayerPanel.java | 12 ++++++------ 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED index bf669b8cc4..c0a6f73aaf 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED @@ -41,7 +41,7 @@ MediaFileViewer.AccessibleContext.accessibleDescription= MediaFileViewer.title=Media MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio) MediaPlayerPanel.noSupport=File not supported. -MediaPlayerPanel.playbackDisabled=A problem was encountered with the video playback service. Video playback will be disabled for the remainder of the session. +MediaPlayerPanel.playbackDisabled=A problem was encountered with the video and audio playback service. Video and audio playback will be disabled for the remainder of the session. MediaPlayerPanel.timeFormat=%02d:%02d:%02d MediaPlayerPanel.unknownTime=Unknown MediaViewImagePanel.createTagOption=Create diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index 0b00c43d8a..793e31830b 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -63,7 +63,7 @@ - + @@ -129,12 +129,6 @@ - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 2d69819e1a..40122acea7 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -214,7 +214,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //The slider is a shared resource between the VideoPanelUpdater //and the TrackListener on the slider itself. private final Semaphore sliderLock; - + private static volatile boolean IS_GST_ENABLED = true; /** @@ -424,10 +424,10 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public boolean isSupported(AbstractFile file) { - if(!IS_GST_ENABLED) { + if (!IS_GST_ENABLED) { return false; } - + String extension = file.getNameExtension(); /** * Although it seems too restrictive, requiring both a supported @@ -547,8 +547,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie */ @NbBundle.Messages({ "MediaPlayerPanel.playbackDisabled=A problem was encountered with" - + " the video playback service. Video playback will" - + " be disabled for the remainder of the session." + + " the video and audio playback service. Video and audio " + + "playback will be disabled for the remainder of the session." }) @Override protected void done() { @@ -562,7 +562,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie GstStatus loadStatus = GstLoader.tryLoad(); if (loadStatus == GstStatus.FAILURE) { MessageNotifyUtil.Message.error(Bundle.MediaPlayerPanel_playbackDisabled()); - + // This will disable the panel for future use. IS_GST_ENABLED = false; return; From 9d58f0220cfbd919c01afa1f5f5bb0cd847a958e Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:42:01 -0400 Subject: [PATCH 050/106] Codacy comments and adjusted bundle message --- .../sleuthkit/autopsy/contentviewers/utils/GstLoader.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java index b2ad257847..57da88e0a2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -61,7 +61,14 @@ public class GstLoader { return status; } + /** + * The various init statuses that tryLoad can return. + */ public enum GstStatus { SUCCESS, FAILURE } + + private GstLoader() { + + } } From 45e9222bccda7c2add909fdd09255d2251ad1848 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 07:48:10 -0400 Subject: [PATCH 051/106] 6032 translated file names in results view --- .../datamodel/BlackboardArtifactNode.java | 234 ++++++++++-------- .../datamodel/BlackboardArtifactTagNode.java | 15 +- .../datamodel/Bundle.properties-MERGED | 3 + .../autopsy/datamodel/ContentTagNode.java | 48 ++-- .../datamodel/DisplayableItemNode.java | 25 +- .../sleuthkit/autopsy/datamodel/TagNode.java | 135 ++++++++++ .../directorytree/DataResultFilterNode.java | 23 +- 7 files changed, 317 insertions(+), 166 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 055d322203..6663c87bb3 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -127,7 +127,8 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_score_name(), + Bundle.BlackboardArtifactNode_createSheet_score_displayName(), + scoData.getScoreAndDescription().getRight(), + scoData.getScoreAndDescription().getLeft())); } if (scoData.getComment() != null) { - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, scoData.getComment())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_comment_name(), + Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), + NO_DESCR, scoData.getComment())); } if (scoData.getCountAndDescription() != null) { - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_count_name(), + Bundle.BlackboardArtifactNode_createSheet_count_displayName(), + scoData.getCountAndDescription().getRight(), + scoData.getCountAndDescription().getLeft())); } } else if (eventType.equals(FileNameTransTask.getPropertyName())) { /* * Replace the value of the Source File property with the * translated name via setDisplayName (see note in createSheet), - * and put the untranslated name in the Original Name property. - * Also set the tooltip to the original name. + * and put the untranslated name in the Original Name property + * and in the tooltip. */ + translatedSourceName = evt.getNewValue().toString(); setDisplayName(evt.getNewValue().toString()); setShortDescription(evt.getOldValue().toString()); - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, (String) evt.getNewValue())); - //updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, (String) evt.getOldValue())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), + NO_DESCR, + evt.getOldValue().toString())); } } }; @@ -225,17 +241,15 @@ public class BlackboardArtifactNode extends AbstractContentNode( Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, - this.getSourceName())); + getDisplayName())); if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { /* @@ -431,8 +459,8 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, "")); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_score_name(), + Bundle.BlackboardArtifactNode_createSheet_score_displayName(), + VALUE_LOADING, + "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_comment_name(), + Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), + VALUE_LOADING, + "")); if (CentralRepository.isEnabled()) { - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), VALUE_LOADING, "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_count_name(), + Bundle.BlackboardArtifactNode_createSheet_count_displayName(), + VALUE_LOADING, + "")); } backgroundTasksPool.submit(new GetSCOTask(new WeakReference<>(this), weakAppEventListener)); } @@ -463,20 +503,16 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactType.displayName"), - NO_DESCR, - associatedArtifact.getDisplayName())); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactDetails.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), - NO_DESCR, - associatedArtifact.getShortDescription())); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.displayName"), + NO_DESCR, + associatedArtifact.getDisplayName())); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), + NO_DESCR, + associatedArtifact.getShortDescription())); } } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting associated artifact of TSK_INTERESTING_ARTIFACT_HIT artifact (objID={0}))", artifact.getId()), ex); //NON-NLS @@ -523,20 +559,16 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.ext.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.ext.displayName"), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"), NO_DESCR, ext)); - sheetSet - .put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.mimeType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.mimeType.displayName"), - NO_DESCR, - actualMimeType)); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"), + NO_DESCR, + actualMimeType)); } /* @@ -556,10 +588,8 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.filePath.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.filePath.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"), NO_DESCR, sourcePath)); } @@ -571,42 +601,33 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileModifiedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileModifiedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileChangedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileChangedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileAccessedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileAccessedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileCreatedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileCreatedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileSize.displayName"), - "", - file == null ? "" : file.getSize())); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), + "", + file == null ? "" : file.getSize())); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", file == null ? "" : StringUtils.defaultString(file.getMd5Hash()))); @@ -629,10 +650,8 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.dataSrc.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.dataSrc.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"), NO_DESCR, dataSourceStr)); } @@ -655,18 +674,15 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.fileSize.displayName"), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.displayName"), NO_DESCR, size)); sheetSet .put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.path.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.path.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.displayName"), NO_DESCR, path)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index a6a0a66590..6068615592 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2018 Basis Technology Corp. + * Copyright 2013-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,13 +24,11 @@ import java.util.Arrays; import java.util.List; import java.util.logging.Level; import javax.swing.Action; -import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; @@ -46,14 +44,14 @@ import static org.sleuthkit.autopsy.datamodel.Bundle.*; * tag name nodes have tag type child nodes; tag type nodes are the parents of * either content or blackboard artifact tag nodes. */ -public class BlackboardArtifactTagNode extends DisplayableItemNode { +public class BlackboardArtifactTagNode extends TagNode { private static final Logger LOGGER = Logger.getLogger(BlackboardArtifactTagNode.class.getName()); private static final String ICON_PATH = "org/sleuthkit/autopsy/images/green-tag-icon-16.png"; //NON-NLS private final BlackboardArtifactTag tag; public BlackboardArtifactTagNode(BlackboardArtifactTag tag) { - super(Children.LEAF, Lookups.fixed(tag, tag.getArtifact(), tag.getContent())); + super(Lookups.fixed(tag, tag.getArtifact(), tag.getContent()), tag.getContent()); super.setName(tag.getContent().getName()); super.setDisplayName(tag.getContent().getName()); this.setIconBaseWithExtension(ICON_PATH); @@ -75,6 +73,7 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFile.text"), "", tag.getContent().getName())); + addOriginalNameProp(properties); String contentPath; try { contentPath = tag.getContent().getUniquePath(); @@ -82,7 +81,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { Logger.getLogger(ContentTagNode.class.getName()).log(Level.SEVERE, "Failed to get path for content (id = " + tag.getContent().getId() + ")", ex); //NON-NLS contentPath = NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.unavail.text"); } - properties.put(new NodeProperty<>( NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFilePath.text"), NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFilePath.text"), @@ -146,11 +144,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { return visitor.visit(this); } - @Override - public boolean isLeafTypeNode() { - return true; - } - @Override public String getItemType() { return getClass().getName(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED index 3a16272a96..0d5c75740d 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED @@ -92,6 +92,7 @@ Category.two=CAT-2: Child Exploitation (Non-Illegal/Age Difficult) Category.zero=CAT-0: Uncategorized ContentTagNode.createSheet.artifactMD5.displayName=MD5 Hash ContentTagNode.createSheet.artifactMD5.name=MD5 Hash +ContentTagNode.createSheet.origFileName=Original Name ContentTagNode.createSheet.userName.text=User Name DeletedContent.allDelFilter.text=All DeletedContent.createSheet.filterType.desc=no description @@ -347,6 +348,8 @@ TagNameNode.bbArtTagTypeNodeKey.text=Result Tags TagNameNode.bookmark.text=Bookmark TagNameNode.createSheet.name.name=Name TagNameNode.createSheet.name.displayName=Name +TagNode.propertySheet.origName=Original Name +TagNode.propertySheet.origNameDisplayName=Original Name TagsNode.displayName.text=Tags TagsNode.createSheet.name.name=Name TagsNode.createSheet.name.displayName=Name diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java index e213e460cb..89d6c2fae2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2016 Basis Technology Corp. + * Copyright 2013-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,7 +24,6 @@ import java.util.List; import java.util.logging.Level; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; -import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -39,18 +38,16 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Instances of this class wrap ContentTag objects. In the Autopsy presentation * of the SleuthKit data model, they are leaf nodes of a tree consisting of - * content and blackboard artifact tags, grouped first by tag type, then by tag - * name. + * content and artifact tags, grouped first by tag type, then by tag name. */ -class ContentTagNode extends DisplayableItemNode { +class ContentTagNode extends TagNode { private static final Logger LOGGER = Logger.getLogger(ContentTagNode.class.getName()); - private static final String ICON_PATH = "org/sleuthkit/autopsy/images/blue-tag-icon-16.png"; //NON-NLS private final ContentTag tag; - public ContentTagNode(ContentTag tag) { - super(Children.LEAF, Lookups.fixed(tag, tag.getContent())); + ContentTagNode(ContentTag tag) { + super(Lookups.fixed(tag, tag.getContent()), tag.getContent()); super.setName(tag.getContent().getName()); super.setDisplayName(tag.getContent().getName()); this.setIconBaseWithExtension(ICON_PATH); @@ -58,6 +55,7 @@ class ContentTagNode extends DisplayableItemNode { } @Messages({ + "ContentTagNode.createSheet.origFileName=Original Name", "ContentTagNode.createSheet.artifactMD5.displayName=MD5 Hash", "ContentTagNode.createSheet.artifactMD5.name=MD5 Hash", "ContentTagNode.createSheet.userName.text=User Name"}) @@ -79,15 +77,19 @@ class ContentTagNode extends DisplayableItemNode { properties = Sheet.createPropertiesSet(); propertySheet.put(properties); } - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.displayName"), "", content.getName())); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.name"), + addOriginalNameProp(properties); + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.displayName"), "", contentPath)); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.displayName"), "", tag.getComment())); @@ -95,23 +97,28 @@ class ContentTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getMtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getCtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getAtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getCrtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"), "", content.getSize())); - properties.put(new NodeProperty<>(Bundle.ContentTagNode_createSheet_artifactMD5_name(), + properties.put(new NodeProperty<>( + Bundle.ContentTagNode_createSheet_artifactMD5_name(), Bundle.ContentTagNode_createSheet_artifactMD5_displayName(), "", file != null ? StringUtils.defaultString(file.getMd5Hash()) : "")); @@ -128,8 +135,7 @@ class ContentTagNode extends DisplayableItemNode { List actions = new ArrayList<>(); actions.addAll(Arrays.asList(super.getActions(context))); - AbstractFile file = getLookup().lookup(AbstractFile.class - ); + AbstractFile file = getLookup().lookup(AbstractFile.class); if (file != null) { actions.add(ViewFileInTimelineAction.createViewFileAction(file)); } @@ -144,13 +150,9 @@ class ContentTagNode extends DisplayableItemNode { return visitor.visit(this); } - @Override - public boolean isLeafTypeNode() { - return true; - } - @Override public String getItemType() { return getClass().getName(); } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java index c723d99b55..c6bc88129a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2012-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; +import org.openide.nodes.Sheet; import org.openide.util.Lookup; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -142,4 +143,26 @@ public abstract class DisplayableItemNode extends AbstractNode { return selectedChildNodeInfo; } + /** + * Updates the node property sheet by replacing existing properties with new + * properties with the same property name. + * + * @param newProps The replacement property objects. + */ + protected synchronized final void updatePropertySheet(NodeProperty... newProps) { + Sheet currentSheet = this.getSheet(); + Sheet.Set currentPropsSet = currentSheet.get(Sheet.PROPERTIES); + Property[] currentProps = currentPropsSet.getProperties(); + for (NodeProperty newProp : newProps) { + for (int i = 0; i < currentProps.length; i++) { + if (currentProps[i].getName().equals(newProp.getName())) { + currentProps[i] = newProp; + } + } + } + currentPropsSet.put(currentProps); + currentSheet.put(currentPropsSet); + this.setSheet(currentSheet); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java new file mode 100755 index 0000000000..7d4d8d467c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -0,0 +1,135 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.Lookup; +import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; +import org.sleuthkit.autopsy.core.UserPreferences; +import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.datamodel.Content; + +/** + * An abstract superclass for a node that represents a tag, uses the name of a + * given Content object as its display name, and has a property sheet with an + * original name property when machine translation is enabled. + * + * The translation of the Content name is done in a background thread. The + * translated name is made the display name of the node and the untranslated + * name is put into both the original name property and into the node's tooltip. + * + * TODO (Jira-): Consider modifying this class to be able to use it more broadly + * within the Autopsy data model (i.e., AbstractNode suclasses). It's not really + * specific to a tag node. + */ +@NbBundle.Messages({ + "TagNode.propertySheet.origName=Original Name", + "TagNode.propertySheet.origNameDisplayName=Original Name" +}) +abstract class TagNode extends DisplayableItemNode { + + private final static String ORIG_NAME_PROP_NAME = Bundle.TagNode_propertySheet_origName(); + private final static String ORIG_NAME_PROP_DISPLAY_NAME = Bundle.TagNode_propertySheet_origNameDisplayName(); + + private final String originalName; + private volatile String translatedName; // Only computed once, in a background thread. + + /* + * The node has an event listener that is wrapped in a weak reference that + * allows the node to be garbage collected when the NetBeans infrastructure + * discards it. If this is not done, it has been shown that a strong + * reference to the listener prevents garbage collection of this node. + */ + private final PropertyChangeListener listener = WeakListeners.propertyChange(new NameTranslationListener(), null); + + /** + * An abstract superclass for a node that represents a tag, uses the name of + * a given Content object as its display name, and has a property sheet with + * an untranslated file name property when machine translation is enabled. + * + * @param lookup The Lookup of the node. + * @param content The Content to use for the node display name. + */ + TagNode(Lookup lookup, Content content) { + super(Children.LEAF, lookup); + originalName = content.getName(); + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + abstract public String getItemType(); + + @Override + abstract public T accept(DisplayableItemNodeVisitor visitor); + + /** + * Adds an original name property to the node's property sheet and submits + * an original name translation task. + * + * The translation of the original name is done in a background thread. The + * translated name is made the display name of the node and the untranslated + * name is put into both the original name property and into the node's + * tooltip. + * + * @param properties The node's property sheet. + */ + protected void addOriginalNameProp(Sheet.Set properties) { + if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { + properties.put(new NodeProperty<>( + ORIG_NAME_PROP_NAME, + ORIG_NAME_PROP_DISPLAY_NAME, + "", + translatedName != null ? translatedName : "")); + if (translatedName == null) { + new FileNameTransTask(originalName, this, listener).submit(); + } + } + } + + /* + * A listener for PropertyChangeEvents from a background task used to + * translate the original display name associated with the node. + */ + private class NameTranslationListener implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + String eventType = evt.getPropertyName(); + if (eventType.equals(FileNameTransTask.getPropertyName())) { + setDisplayName(evt.getNewValue().toString()); + setShortDescription(evt.getOldValue().toString()); + updatePropertySheet(new NodeProperty<>( + ORIG_NAME_PROP_NAME, + ORIG_NAME_PROP_DISPLAY_NAME, + "", + evt.getOldValue().toString())); + } + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 522d3836c3..a412bb5970 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2012-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -187,27 +187,6 @@ public class DataResultFilterNode extends FilterNode { return propertySets; } - /** - * Gets the display name for the wrapped node. - * - * OutlineView used in the DataResult table uses getDisplayName() to - * populate the first column, which is Source File. - * - * Hence this override to return the 'correct' displayName for the wrapped - * node. - * - * @return The display name for the node. - */ - @Override - public String getDisplayName() { - final Node orig = getOriginal(); - String name = orig.getDisplayName(); - if ((orig instanceof BlackboardArtifactNode)) { - name = ((BlackboardArtifactNode) orig).getSourceName(); - } - return name; - } - /** * Adds information about which child node of this node, if any, should be * selected. Can be null. From 060467f6199039097a605caa1b8d31c99efe0108 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 07:57:27 -0400 Subject: [PATCH 052/106] 6032 translated file names in results view --- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index 7d4d8d467c..e0b5d89905 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -39,7 +39,7 @@ import org.sleuthkit.datamodel.Content; * translated name is made the display name of the node and the untranslated * name is put into both the original name property and into the node's tooltip. * - * TODO (Jira-): Consider modifying this class to be able to use it more broadly + * TODO (Jira-6174): Consider modifying this class to be able to use it more broadly * within the Autopsy data model (i.e., AbstractNode suclasses). It's not really * specific to a tag node. */ From 2a3187556733f0fc730224052aa88b99c5825870 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 19 Mar 2020 08:11:14 -0400 Subject: [PATCH 053/106] updated spacing --- .../autopsy/keywordsearch/ExtractedContentPanel.form | 6 +++--- .../autopsy/keywordsearch/ExtractedContentPanel.java | 6 +++--- .../org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form | 2 +- .../org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index 444e9a7cac..e83ecc14e3 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -45,8 +45,8 @@ - - + + @@ -146,7 +146,7 @@ - + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 0722157fec..f99ead0d3d 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -366,7 +366,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addComponent(pagePreviousButton) .addGap(0, 0, 0) .addComponent(pageNextButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(18, 18, 18) .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(zoomPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -412,8 +412,8 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE) + .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 745, Short.MAX_VALUE) + .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 745, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form index 4a190ad1a9..887bad8a34 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form @@ -24,7 +24,7 @@ - + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 2aa3f13324..d4507a0fd7 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -122,7 +122,7 @@ class TextZoomPanel extends JPanel { setMinimumSize(new java.awt.Dimension(150, 20)); setPreferredSize(new java.awt.Dimension(200, 20)); setRequestFocusEnabled(false); - setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING, 0, 0)); + setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); zoomTextField.setEditable(false); zoomTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT); From 89ccc44a56a36a776926655f4bd80cef40cea056 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:24:29 -0400 Subject: [PATCH 054/106] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index e2043846fe..99685d29a4 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -493,6 +493,8 @@ public abstract class AbstractAbstractFileNode extends A /** * Translates the name of the file this node represents. An empty string * will be returned if the translation fails for any reason. + * + * @return The translated file name or the empty string. */ String getTranslatedFileName() { try { From cdea715cf702fe3f95f5e99b3f2d0fd9bc9559fc Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:30:02 -0400 Subject: [PATCH 055/106] 6032 translated file names in results view --- .../autopsy/datamodel/BlackboardArtifactNode.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 6663c87bb3..a716d5eb64 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -209,14 +209,15 @@ public class BlackboardArtifactNode extends AbstractContentNode( Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, - evt.getOldValue().toString())); + originalName)); } } }; From a287d4704ac7d2a9ddf139b8cf97f101e1f29915 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:31:36 -0400 Subject: [PATCH 056/106] 6032 translated file names in results view --- .../autopsy/datamodel/BlackboardArtifactNode.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index a716d5eb64..cbf37d77ae 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -229,7 +229,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(this), weakAppEventListener)); + backgroundTasksPool.submit(new GetSCOTask(new WeakReference<>(this), weakListener)); } /* From 915facbcb3fce881750d8feb8a283830e1b35600 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:36:46 -0400 Subject: [PATCH 057/106] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index cbf37d77ae..87eb7b6610 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -462,6 +462,9 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 08:43:03 -0400 Subject: [PATCH 058/106] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/TagNode.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index e0b5d89905..20bf7d9c95 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -55,14 +55,6 @@ abstract class TagNode extends DisplayableItemNode { private final String originalName; private volatile String translatedName; // Only computed once, in a background thread. - /* - * The node has an event listener that is wrapped in a weak reference that - * allows the node to be garbage collected when the NetBeans infrastructure - * discards it. If this is not done, it has been shown that a strong - * reference to the listener prevents garbage collection of this node. - */ - private final PropertyChangeListener listener = WeakListeners.propertyChange(new NameTranslationListener(), null); - /** * An abstract superclass for a node that represents a tag, uses the name of * a given Content object as its display name, and has a property sheet with @@ -106,7 +98,7 @@ abstract class TagNode extends DisplayableItemNode { "", translatedName != null ? translatedName : "")); if (translatedName == null) { - new FileNameTransTask(originalName, this, listener).submit(); + new FileNameTransTask(originalName, this, new NameTranslationListener()).submit(); } } } @@ -121,13 +113,15 @@ abstract class TagNode extends DisplayableItemNode { public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); if (eventType.equals(FileNameTransTask.getPropertyName())) { - setDisplayName(evt.getNewValue().toString()); - setShortDescription(evt.getOldValue().toString()); + translatedName = evt.getNewValue().toString(); + String originalName = evt.getOldValue().toString(); + setDisplayName(translatedName); + setShortDescription(originalName); updatePropertySheet(new NodeProperty<>( ORIG_NAME_PROP_NAME, ORIG_NAME_PROP_DISPLAY_NAME, "", - evt.getOldValue().toString())); + originalName)); } } } From 9c14a4de791b96725f0c4e0bd391732f984142e1 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 09:05:40 -0400 Subject: [PATCH 059/106] 6032 translated file names in results view --- .../datamodel/BlackboardArtifactNode.java | 108 ++++++------------ .../datamodel/Bundle.properties-MERGED | 2 - 2 files changed, 37 insertions(+), 73 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 87eb7b6610..2c6bc93446 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -152,25 +152,19 @@ public class BlackboardArtifactNode extends AbstractContentNode( NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), @@ -638,18 +608,16 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - if (srcContent != null) { - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); - } + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0})", artifact.getId()), ex); } @@ -725,7 +691,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 09:06:39 -0400 Subject: [PATCH 060/106] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 2c6bc93446..48d95b506d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -127,8 +127,8 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 09:13:20 -0400 Subject: [PATCH 061/106] 6032 translated file names in results view --- .../autopsy/texttranslation/utils/FileNameTranslator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java index 71b8a859b4..cfd04dcb93 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java @@ -44,6 +44,9 @@ public class FileNameTranslator { /* * Don't attempt translation if the characters of the file name are all * ASCII chars. + * + * TODO (Jira-6175): This filter prevents translation of many + * non-English file names composed entirely of Latin chars. */ if (fileName.matches("^\\p{ASCII}+$")) { return ""; From 06eba0fe63a2176a8abdbfe4ad7db606513be877 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 19 Mar 2020 10:45:19 -0400 Subject: [PATCH 062/106] checks whether or not cr buttons need to be enabled each event change --- .../centralrepository/optionspanel/GlobalSettingsPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 78b2e9ca87..e84d2b90f7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -731,9 +731,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i enableButtonSubComponents(cbUseCentralRepo.isSelected()); } else { load(); - enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen); } + enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen); } /** From df3f1ec2e81eaa68ddff0239765efd981d4c9e67 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 12:10:58 -0400 Subject: [PATCH 063/106] 6032 translated file names in results view --- .../autopsy/datamodel/AbstractAbstractFileNode.java | 4 ++-- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 5 ++--- .../sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java | 4 ++-- ...{FileNameTranslator.java => FileNameTranslationUtil.java} | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) rename Core/src/org/sleuthkit/autopsy/texttranslation/utils/{FileNameTranslator.java => FileNameTranslationUtil.java} (96%) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 99685d29a4..74ac603e0b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -66,7 +66,7 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil; /** * An abstract node that encapsulates AbstractFile data @@ -498,7 +498,7 @@ public abstract class AbstractAbstractFileNode extends A */ String getTranslatedFileName() { try { - return FileNameTranslator.translate(content.getName()); + return FileNameTranslationUtil.translate(content.getName()); } catch (NoServiceProviderException | TranslationException ex) { logger.log(Level.WARNING, MessageFormat.format("Error translating file name (objID={0}))", content.getId()), ex); return ""; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index 20bf7d9c95..9e0f1c7268 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -24,7 +24,6 @@ import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.Lookup; import org.openide.util.NbBundle; -import org.openide.util.WeakListeners; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; @@ -53,7 +52,7 @@ abstract class TagNode extends DisplayableItemNode { private final static String ORIG_NAME_PROP_DISPLAY_NAME = Bundle.TagNode_propertySheet_origNameDisplayName(); private final String originalName; - private volatile String translatedName; // Only computed once, in a background thread. + private volatile String translatedName; /** * An abstract superclass for a node that represents a tag, uses the name of @@ -103,7 +102,7 @@ abstract class TagNode extends DisplayableItemNode { } } - /* + /** * A listener for PropertyChangeEvents from a background task used to * translate the original display name associated with the node. */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java index 88ccac2d2f..8b755ec3dc 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.datamodel.utils; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import org.openide.nodes.AbstractNode; -import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil; /** * An AbstractNodePropertySheetTask that translates a file name for an @@ -54,7 +54,7 @@ public class FileNameTransTask extends AbstractNodePropertySheetTask Date: Thu, 19 Mar 2020 14:15:47 -0400 Subject: [PATCH 064/106] 6108 central repo schema updates in app service --- .../datamodel/Bundle.properties-MERGED | 8 +- .../datamodel/CentralRepositoryService.java | 119 ++++++++++++++++++ .../datamodel/DataSourceUpdateService.java | 68 ---------- .../eventlisteners/Installer.java | 31 +---- 4 files changed, 128 insertions(+), 98 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java delete mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED index 345d5a420e..44f4462515 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Bundle.properties-MERGED @@ -7,7 +7,14 @@ AbstractSqlEamDb.cannotUpgrage.message=Currently selected database platform "{0} AbstractSqlEamDb.failedToReadMajorVersion.message=Failed to read schema version for Central Repository. AbstractSqlEamDb.failedToReadMinorVersion.message=Failed to read schema minor version for Central Repository. AbstractSqlEamDb.upgradeSchema.incompatible=The selected Central Repository is not compatible with the current version of the application, please upgrade the application if you wish to use this Central Repository. +CentralRepoDbChoice.Disabled.Text=Disabled +CentralRepoDbChoice.PostgreSQL.Text=Custom PostgreSQL +CentralRepoDbChoice.PostgreSQL_Multiuser.Text=PostgreSQL using multi-user settings +CentralRepoDbChoice.Sqlite.Text=SQLite CentralRepoDbManager.connectionErrorMsg.text=Failed to connect to central repository database. +CentralRepositoryService.progressMsg.updatingDataSourcesTable=Checking for v1.2 data updates... +CentralRepositoryService.progressMsg.updatingSchema=Updating schema... +CentralRepositoryService.serviceName=Central Repository Service CorrelationAttributeInstance.invalidName.message=Invalid database table name. Name must start with a lowercase letter and can only contain lowercase letters, numbers, and '_'. CorrelationAttributeInstance.nullName.message=Database name is null. CorrelationAttributeUtil.emailaddresses.text=Email Addresses @@ -21,7 +28,6 @@ CorrelationType.MAC.displayName=MAC Addresses CorrelationType.PHONE.displayName=Phone Numbers CorrelationType.SSID.displayName=Wireless Networks CorrelationType.USBID.displayName=USB Devices -DataSourceUpdateService.serviceName.text=Update Central Repository Data Sources EamArtifactInstances.knownStatus.bad=Bad EamArtifactInstances.knownStatus.known=Known EamArtifactInstances.knownStatus.unknown=Unknown diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java new file mode 100644 index 0000000000..6413a377f6 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java @@ -0,0 +1,119 @@ +/* + * Central Repository + * + * Copyright 2018-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.centralrepository.datamodel; + +import org.openide.util.NbBundle; +import org.openide.util.lookup.ServiceProvider; +import org.sleuthkit.autopsy.appservices.AutopsyService; +import org.sleuthkit.autopsy.progress.ProgressIndicator; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * The Autopsy application service for the central repository. + */ +@ServiceProvider(service = AutopsyService.class) +public class CentralRepositoryService implements AutopsyService { + + @Override + @NbBundle.Messages({ + "CentralRepositoryService.serviceName=Central Repository Service" + }) + public String getServiceName() { + return Bundle.CentralRepositoryService_serviceName(); + } + + @NbBundle.Messages({ + "CentralRepositoryService.progressMsg.updatingSchema=Updating schema...", + "CentralRepositoryService.progressMsg.updatingDataSourcesTable=Checking for v1.2 data updates...",}) + @Override + public void openCaseResources(CaseContext context) throws AutopsyServiceException { + if (!CentralRepository.isEnabled()) { + return; + } + + /* + * TODO (Jira-6108): We should consider adding coordination service + * locking to the central repository in collaborative environments. + */ + ProgressIndicator progress = context.getProgressIndicator(); + progress.progress(Bundle.CentralRepositoryService_progressMsg_updatingSchema()); + updateSchema(); + + if (context.cancelRequested()) { + return; + } + + progress.progress(Bundle.CentralRepositoryService_progressMsg_updatingDataSourcesTable()); + dataUpgradeForVersion1dot2(context.getCase()); + } + + /** + * Updates the central repository schema to the latest version. + * + * @throws AutopsyServiceException + */ + private void updateSchema() throws AutopsyServiceException { + try { + CentralRepoDbManager.upgradeDatabase(); + } catch (CentralRepoException ex) { + throw new AutopsyServiceException("Failed to update the Central Repository schema", ex); + } + } + + /** + * Adds missing data source object IDs from data sources in this case to the + * corresponding records in the central repository. This is a data update to + * go with the v1.2 schema update. + * + * @throws AutopsyServiceException + */ + private void dataUpgradeForVersion1dot2(Case currentCase) throws AutopsyServiceException { + try { + /* + * If the case is in the central repository, there may be missing + * data source object IDs in the data_sources.datasource_obj_id + * column that was added in the version 1.2 schema update. + */ + CentralRepository centralRepository = CentralRepository.getInstance(); + CorrelationCase correlationCase = centralRepository.getCase(currentCase); + if (correlationCase != null) { + for (CorrelationDataSource correlationDataSource : centralRepository.getDataSources()) { + /* + * ResultSet.getLong returns zero when the value in the + * result set is NULL. + */ + if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getDataSourceObjectID() == 0) { + for (Content dataSource : currentCase.getDataSources()) { + if (((DataSource) dataSource).getDeviceId().equals(correlationDataSource.getDeviceID()) && dataSource.getName().equals(correlationDataSource.getName())) { + centralRepository.addDataSourceObjectId(correlationDataSource.getID(), dataSource.getId()); + break; + } + } + } + } + } + } catch (CentralRepoException | TskCoreException ex) { + throw new AutopsyServiceException("Failed to update data sources in the Central Repository for schema v1.2", ex); + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java deleted file mode 100644 index 2450ca3440..0000000000 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/DataSourceUpdateService.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Central Repository - * - * Copyright 2018 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.centralrepository.datamodel; - -import org.openide.util.NbBundle; -import org.openide.util.lookup.ServiceProvider; -import org.sleuthkit.autopsy.appservices.AutopsyService; -import org.sleuthkit.datamodel.Content; -import org.sleuthkit.datamodel.DataSource; -import org.sleuthkit.datamodel.TskCoreException; - -/** - * Class which updates the data sources in the central repository to include the - * object id which ties them to the current case. - * - */ -@ServiceProvider(service = AutopsyService.class) -public class DataSourceUpdateService implements AutopsyService { - - @Override - @NbBundle.Messages({"DataSourceUpdateService.serviceName.text=Update Central Repository Data Sources"}) - public String getServiceName() { - return Bundle.DataSourceUpdateService_serviceName_text(); - } - - @Override - public void openCaseResources(CaseContext context) throws AutopsyServiceException { - if (CentralRepository.isEnabled()) { - try { - CentralRepository centralRepository = CentralRepository.getInstance(); - CorrelationCase correlationCase = centralRepository.getCase(context.getCase()); - //if the case isn't in the central repository yet there won't be data sources in it to update - if (correlationCase != null) { - for (CorrelationDataSource correlationDataSource : centralRepository.getDataSources()) { - //ResultSet.getLong has a value of 0 when the value is null - if (correlationDataSource.getCaseID() == correlationCase.getID() && correlationDataSource.getDataSourceObjectID() == 0) { - for (Content dataSource : context.getCase().getDataSources()) { - if (((DataSource) dataSource).getDeviceId().equals(correlationDataSource.getDeviceID()) && dataSource.getName().equals(correlationDataSource.getName())) { - centralRepository.addDataSourceObjectId(correlationDataSource.getID(), dataSource.getId()); - break; - } - } - } - } - } - } catch (CentralRepoException | TskCoreException ex) { - throw new AutopsyServiceException("Unabe to update datasources in central repository", ex); - } - } - } - -} \ No newline at end of file diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java index 9f888e43f2..da58e8936b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/Installer.java @@ -39,16 +39,6 @@ import org.sleuthkit.autopsy.coreutils.Version; * central repository, sets up a default, single-user SQLite central repository * if no central repository is configured, and updates the central repository * schema as required. - * - * TODO (Jira-6108): At first glance, this package seems to have become a rather - * strange package for the "package installer" for the CR to reside in. The - * org.sleuthkit.autopsy.centralrepository package would seem to be more - * appropriate with so much going on. However, having a central repository - * schema update occur in a "package installer" with no user feedback is not - * optimal. Furthermore, for a multi-user (collaborative) installation, a schema - * update should be done in a more controlled way by acquiring an exclusive - * coordination service lock and requiring shared locks to be acquired by nodes - * with open cases. */ public class Installer extends ModuleInstall { @@ -84,9 +74,8 @@ public class Installer extends ModuleInstall { /* * Adds/removes application event listeners responsible for adding data to - * the central repository, sets up a default, single-user SQLite central - * repository if no central repository is configured, and updates the - * central repository schema as required. + * the central repository and sets up a default, single-user SQLite central + * repository if no central repository is configured. * * Called by the registered Installer for the Autopsy-Core module located in * the org.sleuthkit.autopsy.core package when the already installed @@ -105,8 +94,6 @@ public class Installer extends ModuleInstall { if (Version.getBuildType() == Version.Type.RELEASE) { setupDefaultCentralRepository(); } - - updateCentralRepoSchema(); } /** @@ -198,20 +185,6 @@ public class Installer extends ModuleInstall { manager.setupDefaultSqliteDb(); } - /** - * Update the central repository schema. - */ - private void updateCentralRepoSchema() { - try { - CentralRepoDbManager.upgradeDatabase(); - } catch (CentralRepoException ex) { - logger.log(Level.SEVERE, "An error occurred updating the central repository schema", ex); - if (RuntimeProperties.runningWithGUI()) { - doMessageBoxIfRunningInGUI(ex); - } - } - } - /** * Display a central repository exception in a message box if running with a * GUI. From 1b77e34e705e539b65542cb67030b329b475e48a Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 14:55:38 -0400 Subject: [PATCH 065/106] 6108 central repo schema updates in app service --- .../optionspanel/Bundle.properties-MERGED | 1 - .../optionspanel/GlobalSettingsPanel.java | 41 +------------------ 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED index 9ea90a452a..395330b4db 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties-MERGED @@ -39,7 +39,6 @@ GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change GlobalSettingsPanel.onMultiUserChange.enable.description=Do you want to update the Central Repository to use this PostgreSQL database? GlobalSettingsPanel.onMultiUserChange.enable.description2=The Central Repository stores hash values and accounts from past cases. GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository? -GlobalSettingsPanel.updateFailed.title=Central repository disabled GlobalSettingsPanel.validationErrMsg.ingestRunning=You cannot change settings while ingest is running. GlobalSettingsPanel.validationerrMsg.mustConfigure=Configure the database to enable this module. ManageCasesDialog.title.text=Manage Cases diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 78b2e9ca87..4f37b7905a 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -74,8 +74,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i ingestStateUpdated(evt.getNewValue() != null); }); } - - + private void customizeComponents() { setName(NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnCorrelationProperties.border.title")); } @@ -84,10 +83,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, ingestJobEventListener); ingestStateUpdated(Case.isCaseOpen()); } - - private void updateDatabase() { - updateDatabase(this); - } /** * This method invokes central repository database choice selection as well as input for necessary configuration. @@ -102,7 +97,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i new EamDbSettingsDialog(); if (dialog.wasConfigurationChanged()) { - updateDatabase(parent); return true; } @@ -208,43 +202,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } } - private static void handleDbChange(Component parent) { SwingUtilities.invokeLater(() -> { boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); - if (successful) { - updateDatabase(parent); - } - else { - // disable central repository due to error - CentralRepoDbManager.disableDueToFailure(); - } }); } - - @Messages({"GlobalSettingsPanel.updateFailed.title=Central repository disabled"}) - private static void updateDatabase(Component parent) { - if (CentralRepoDbChoice.DISABLED.equals(CentralRepoDbManager.getSavedDbChoice())) { - return; - } - parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - - try { - CentralRepoDbManager.upgradeDatabase(); - parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } catch (CentralRepoException ex) { - parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - JOptionPane.showMessageDialog(parent, - ex.getUserMessage(), - NbBundle.getMessage(GlobalSettingsPanel.class, - "GlobalSettingsPanel.updateFailed.title"), - JOptionPane.WARNING_MESSAGE); - } finally { - parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } - } - /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -598,8 +561,6 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); } - - updateDatabase(); load(); this.ingestStateUpdated(Case.isCaseOpen()); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); From f4cdb6e8e5fb51c22de3996d14c08eec05227c43 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 14:57:29 -0400 Subject: [PATCH 066/106] 6108 central repo schema updates in app service --- .../centralrepository/datamodel/CentralRepositoryService.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java index 6413a377f6..8b442efc24 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepositoryService.java @@ -50,10 +50,6 @@ public class CentralRepositoryService implements AutopsyService { return; } - /* - * TODO (Jira-6108): We should consider adding coordination service - * locking to the central repository in collaborative environments. - */ ProgressIndicator progress = context.getProgressIndicator(); progress.progress(Bundle.CentralRepositoryService_progressMsg_updatingSchema()); updateSchema(); From b3e4da6d8c97e79493a7aec8f2c5c8dc77b678be Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Thu, 19 Mar 2020 15:01:52 -0400 Subject: [PATCH 067/106] 6175: No support for new Correlation attributes in Find Common Properties --- .../sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form | 1 + .../sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java | 1 + 2 files changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form index 93a06ca05c..d7c106797a 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form @@ -106,6 +106,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java index a2c1c01529..77eb7dbbb3 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java @@ -154,6 +154,7 @@ public final class InterCasePanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(correlationComboBoxLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationComboBoxLabel.text")); // NOI18N + correlationTypeComboBox.setMaximumRowCount(50); correlationTypeComboBox.setSelectedItem(null); correlationTypeComboBox.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationTypeComboBox.toolTipText")); // NOI18N correlationTypeComboBox.addActionListener(new java.awt.event.ActionListener() { From eef8736fadfe02c1a833f883a6577cc55ff87180 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 15:02:33 -0400 Subject: [PATCH 068/106] 6108 central repo schema updates in app service --- .../optionspanel/GlobalSettingsPanel.java | 161 +++++++++--------- 1 file changed, 80 insertions(+), 81 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 4f37b7905a..c3ffa0be00 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -50,20 +50,18 @@ import java.util.logging.Level; */ @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel { - + private static final long serialVersionUID = 1L; private static final Logger logger = Logger.getLogger(GlobalSettingsPanel.class.getName()); private static final Set INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.STARTED, IngestManager.IngestJobEvent.CANCELLED, IngestManager.IngestJobEvent.COMPLETED); private final IngestJobEventPropertyChangeListener ingestJobEventListener; - - - + /** * Creates new form EamOptionsPanel */ public GlobalSettingsPanel() { ingestJobEventListener = new IngestJobEventPropertyChangeListener(); - + // listen for change events in currently saved choice CentralRepoDbManager.addPropertyChangeListener((PropertyChangeEvent evt) -> ingestStateUpdated(Case.isCaseOpen())); initComponents(); @@ -74,7 +72,7 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i ingestStateUpdated(evt.getNewValue() != null); }); } - + private void customizeComponents() { setName(NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.pnCorrelationProperties.border.title")); } @@ -83,35 +81,37 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i IngestManager.getInstance().addIngestJobEventListener(INGEST_JOB_EVENTS_OF_INTEREST, ingestJobEventListener); ingestStateUpdated(Case.isCaseOpen()); } - + /** - * This method invokes central repository database choice selection as well as input for necessary configuration. - * @param parent The parent component for displaying dialogs. - * @param initialSelection If non-null, the menu item will be set to this choice; if null, - * the currently selected db choice will be selected. - * @return True if there was a change. + * This method invokes central repository database choice selection as well + * as input for necessary configuration. + * + * @param parent The parent component for displaying dialogs. + * @param initialSelection If non-null, the menu item will be set to this + * choice; if null, the currently selected db choice + * will be selected. + * + * @return True if there was a change. */ private static boolean invokeCrChoice(Component parent, CentralRepoDbChoice initialSelection) { - EamDbSettingsDialog dialog = (initialSelection != null) ? - new EamDbSettingsDialog(initialSelection) : - new EamDbSettingsDialog(); - - if (dialog.wasConfigurationChanged()) { - return true; - } - - return false; + EamDbSettingsDialog dialog = (initialSelection != null) + ? new EamDbSettingsDialog(initialSelection) + : new EamDbSettingsDialog(); + return dialog.wasConfigurationChanged(); } - - + /** - * When multi user settings are updated, this function triggers pertinent updates for central repository. - * NOTE: If multi user settings were previously enabled and multi user settings are currently selected, this function assumes - * there is a change in the postgres connectivity. - * - * @param parent The swing component that serves as a parent for dialogs that may arise. - * @param muPreviouslySelected If multi user settings were previously enabled. - * @param muCurrentlySelected If multi user settings are currently enabled as of most recent change. + * When multi user settings are updated, this function triggers pertinent + * updates for central repository. NOTE: If multi user settings were + * previously enabled and multi user settings are currently selected, this + * function assumes there is a change in the postgres connectivity. + * + * @param parent The swing component that serves as a parent + * for dialogs that may arise. + * @param muPreviouslySelected If multi user settings were previously + * enabled. + * @param muCurrentlySelected If multi user settings are currently enabled + * as of most recent change. */ @NbBundle.Messages({ "GlobalSettingsPanel.onMultiUserChange.enable.title=Use with Central Repository?", @@ -122,33 +122,31 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i boolean crEnabled = CentralRepoDbUtil.allowUseOfCentralRepository(); boolean crMultiUser = CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER; boolean crDisabledDueToFailure = CentralRepoDbManager.isDisabledDueToFailure(); - + if (!muPreviouslySelected && muCurrentlySelected) { SwingUtilities.invokeLater(() -> { - if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, - "" + - "
" + - "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description") + "

" + - "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description2") + "

" + - "
" + - "", - NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"), - JOptionPane.YES_NO_OPTION)) { - - // setup database for CR - CentralRepoDbUtil.setUseCentralRepo(true); - CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); - handleDbChange(parent); - } + if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(parent, + "" + + "
" + + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description") + "

" + + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description2") + "

" + + "
" + + "", + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"), + JOptionPane.YES_NO_OPTION)) { + + // setup database for CR + CentralRepoDbUtil.setUseCentralRepo(true); + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER); + handleDbChange(parent); + } }); - } - // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected + } // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected else if (muPreviouslySelected && !muCurrentlySelected && crEnabled && crMultiUser) { SwingUtilities.invokeLater(() -> { askForCentralRepoDbChoice(parent); }); - } - // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected && + } // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected && // central repo either enabled or was disabled due to error else if (muPreviouslySelected && muCurrentlySelected && crMultiUser && (crEnabled || crDisabledDueToFailure)) { // test databse for CR change @@ -157,10 +155,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } } - /** - * This method is called when a user must select a new database other than using database from multi user settings. - * @param parent The parent component to use for displaying dialogs in reference. + * This method is called when a user must select a new database other than + * using database from multi user settings. + * + * @param parent The parent component to use for displaying dialogs in + * reference. */ @NbBundle.Messages({ "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary", @@ -171,21 +171,21 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i // disable central repository until user makes choice CentralRepoDbUtil.setUseCentralRepo(false); CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED, false); - + Object[] options = { "Use SQLite", "Configure PostgreSQL", "Disable Central Repository" }; - + int result = JOptionPane.showOptionDialog( parent, - "" + - "
" + - "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "

" + - "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2") + "

" + - "
" + - "", + "" + + "
" + + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "

" + + "

" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2") + "

" + + "
" + + "", NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, @@ -193,21 +193,22 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i options, options[0] ); - + if (JOptionPane.YES_OPTION == result) { invokeCrChoice(parent, CentralRepoDbChoice.SQLITE); - } - else if (JOptionPane.NO_OPTION == result) { + } else if (JOptionPane.NO_OPTION == result) { invokeCrChoice(parent, CentralRepoDbChoice.POSTGRESQL_CUSTOM); } } - + private static void handleDbChange(Component parent) { SwingUtilities.invokeLater(() -> { - boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager()); + if (!EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager())) { + CentralRepoDbManager.disableDueToFailure(); + } }); } - + /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always @@ -552,15 +553,15 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i private void cbUseCentralRepoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseCentralRepoActionPerformed //if saved setting is disabled checkbox should be disabled already store(); - + // if moving to using CR, multi-user mode is disabled and selection is multiuser settings, set to disabled - if (cbUseCentralRepo.isSelected() && - !CentralRepoDbManager.isPostgresMultiuserAllowed() && - CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { - + if (cbUseCentralRepo.isSelected() + && !CentralRepoDbManager.isPostgresMultiuserAllowed() + && CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) { + CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED); } - + load(); this.ingestStateUpdated(Case.isCaseOpen()); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); @@ -581,20 +582,17 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i lbDbNameValue.setText(""); lbDbLocationValue.setText(""); tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure()); - } - else { + } else { enableButtonSubComponents(cbUseCentralRepo.isSelected()); if (selectedDb == CentralRepoPlatforms.POSTGRESQL) { try { - PostgresCentralRepoSettings dbSettingsPg = new PostgresCentralRepoSettings(); + PostgresCentralRepoSettings dbSettingsPg = new PostgresCentralRepoSettings(); lbDbNameValue.setText(dbSettingsPg.getDbName()); lbDbLocationValue.setText(dbSettingsPg.getHost()); - } - catch (CentralRepoException e) { + } catch (CentralRepoException e) { logger.log(Level.WARNING, "Unable to load settings into global panel for postgres settings", e); } - } - else if (selectedDb == CentralRepoPlatforms.SQLITE) { + } else if (selectedDb == CentralRepoPlatforms.SQLITE) { SqliteCentralRepoSettings dbSettingsSqlite = new SqliteCentralRepoSettings(); lbDbNameValue.setText(dbSettingsSqlite.getDbName()); lbDbLocationValue.setText(dbSettingsSqlite.getDbDirectory()); @@ -608,7 +606,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i } /** - * This method validates that the dialog/panel is filled out correctly for our usage. + * This method validates that the dialog/panel is filled out correctly for + * our usage. * * @return True if it is okay, false otherwise. */ From d67e250789870de8fff5f49b004f06e33f169b1b Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 19 Mar 2020 15:10:55 -0400 Subject: [PATCH 069/106] file cleanup --- .../textcontentviewer/TextZoomPanel.css | 33 ---------------- .../keywordsearch/Bundle.properties-MERGED | 39 +++++++++++-------- .../autopsy/keywordsearch/TextZoomPanel.java | 2 +- 3 files changed, 23 insertions(+), 51 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.css diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.css b/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.css deleted file mode 100644 index 448b01a21b..0000000000 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/textcontentviewer/TextZoomPanel.css +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2015 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -.label { - -fx-wrap-text:true; - -fx-text-fill: red; - -fx-font-size: 2em; -} - -.bg { - -fx-background-color: rgba(0, 0, 0, .8); -} - -.masker-pane .masker-text { - -fx-text-fill: white; - -fx-font-size: 1.5em; -} diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED index 27263e03ca..9aeeabc046 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED @@ -42,13 +42,6 @@ OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search ListBundleName=Keyword Lists ListBundleConfig=Keyword List Configuration -ExtractedContentPanel.hitLabel.text=Matches on page: -ExtractedContentPanel.hitCountLabel.text=- -ExtractedContentPanel.hitOfLabel.text=of -ExtractedContentPanel.hitTotalLabel.text=- -ExtractedContentPanel.hitButtonsLabel.text=Match -ExtractedContentPanel.hitPreviousButton.text= -ExtractedContentPanel.hitNextButton.text= ExtractedContentPanel.copyMenuItem.text=Copy ExtractedContentPanel.selectAllMenuItem.text=Select All KeywordSearchEditListPanel.saveListButton.text=Copy List @@ -69,7 +62,6 @@ KeywordSearchListsManagementPanel.importButton.text=Import List KeywordSearchListsViewerPanel.searchAddButton.text=Search KeywordSearchListsViewerPanel.manageListsButton.text=Manage Lists KeywordSearchListsViewerPanel.ingestIndexLabel.text=Files Indexed: -ExtractedContentPanel.hitLabel.toolTipText= KeywordSearchEditListPanel.ingestMessagesCheckbox.text=Send ingest inbox messages for each hit KeywordSearchEditListPanel.ingestMessagesCheckbox.toolTipText=Send messages during ingest when hits on keywords from this list occur KeywordSearchEditListPanel.keywordOptionsLabel.text=Keyword Options @@ -358,15 +350,6 @@ SolrSearchService.ServiceName=Solr Keyword Search Service SolrSearchService.IndexReadOnlyDialog.title=Text Index Is Read-Only SolrSearchService.IndexReadOnlyDialog.msg=The text index for this case is read-only.
You will be able to see existing keyword search results and perform exact match and substring match keyword searches,
but you will not be able to add new text to the index or perform regex searches. You may instead open the case
with your previous version of this application. SolrSearchService.DeleteDataSource.msg=Error Deleting Solr data for data source id {0} -ExtractedContentPanel.jLabel1.text=Text Source: -ExtractedContentPanel.pagePreviousButton.actionCommand=pagePreviousButton -ExtractedContentPanel.pagePreviousButton.text= -ExtractedContentPanel.pageNextButton.text= -ExtractedContentPanel.pageCurLabel.text=- -ExtractedContentPanel.pageOfLabel.text=of -ExtractedContentPanel.pageTotalLabel.text=- -ExtractedContentPanel.pageButtonsLabel.text=Page -ExtractedContentPanel.pagesLabel.text=Page: DropdownSingleTermSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources: DropdownListSearchPanel.dataSourceCheckBox.text=Restrict search to the selected data sources: DropdownSingleTermSearchPanel.ingestIndexLabel.text=Files Indexed: @@ -377,3 +360,25 @@ DropdownListSearchPanel.jSaveSearchResults.text=Save search results GlobalEditListPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. KeywordSearchGlobalLanguageSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. +ExtractedContentPanel.hitCountLabel.text=- +ExtractedContentPanel.hitPreviousButton.text= +ExtractedContentPanel.hitTotalLabel.text=- +ExtractedContentPanel.hitOfLabel.text=of +ExtractedContentPanel.hitNextButton.text= +ExtractedContentPanel.hitButtonsLabel.text=Match +ExtractedContentPanel.hitLabel.toolTipText= +ExtractedContentPanel.hitLabel.text=Matches on page: +ExtractedContentPanel.pageCurLabel.text=- +ExtractedContentPanel.pagePreviousButton.actionCommand=pagePreviousButton +ExtractedContentPanel.pagePreviousButton.text= +ExtractedContentPanel.pageNextButton.text= +ExtractedContentPanel.pagesLabel.text=Page: +ExtractedContentPanel.pageTotalLabel.text=- +ExtractedContentPanel.pageButtonsLabel.text=Page +ExtractedContentPanel.pageOfLabel.text=of +ExtractedContentPanel.jLabel1.text=Text Source: +ExtractedContentPanel.AccessibleContext.accessibleName= +TextZoomPanel.zoomInButton.text= +TextZoomPanel.zoomOutButton.text= +TextZoomPanel.zoomResetButton.text=Reset +TextZoomPanel.zoomTextField.text= diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index d4507a0fd7..a9897963ae 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -49,7 +49,7 @@ class TextZoomPanel extends JPanel { * Creates new form TextZoomPanel. * @param zoomable the component that will receive text resize events */ - public TextZoomPanel(ResizableTextPanel zoomable) { + TextZoomPanel(ResizableTextPanel zoomable) { this.zoomable = zoomable; initComponents(); updateEnabled(); From dc1d9483a26e4ee30314294e24e0f60b8c748d01 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 19 Mar 2020 16:15:23 -0400 Subject: [PATCH 070/106] Codacy suggestions round 2 --- .../org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java index 57da88e0a2..b6804d488a 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -26,7 +26,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; /** * A utility class that loads the gstreamer bindings. */ -public class GstLoader { +public final class GstLoader { private static final Logger logger = Logger.getLogger(GstLoader.class.getName()); private static GstStatus status; From 62be8d53605142d0864968627ab1d80860d5f389 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:05:53 -0400 Subject: [PATCH 071/106] 6133 add new default video thumb image --- .../autopsy/filequery/FileSearch.java | 49 +++++++++++------- .../images/failedToCreateVideoThumb.png | Bin 0 -> 2481 bytes 2 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index daa4124e8d..ae0e939498 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -95,6 +95,7 @@ class FileSearch { .build(); private static final int PREVIEW_SIZE = 256; private static volatile TextSummarizer summarizerToUse = null; + private static final BufferedImage VIDEO_DEFAULT_IMAGE = getDefaultVideoThumbnail(); /** * Run the file search and returns the SearchResults object for debugging. @@ -456,6 +457,15 @@ class FileSearch { + "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS } + private static BufferedImage getDefaultVideoThumbnail() { + try { + return ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png"));//NON-NLS + } catch (IOException ex) { + logger.log(Level.SEVERE, "Failed to load 'failed to create video' placeholder.", ex); //NON-NLS + } + return null; + } + /** * Get the video thumbnails for a file which exists in a * VideoThumbnailsWrapper and update the VideoThumbnailsWrapper to include @@ -476,7 +486,6 @@ class FileSearch { cacheDirectory = null; logger.log(Level.WARNING, "Unable to get cache directory, video thumbnails will not be saved", ex); } - if (cacheDirectory == null || file.getMd5Hash() == null || !Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash()).toFile().exists()) { java.io.File tempFile; try { @@ -488,7 +497,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } if (tempFile.exists() == false || tempFile.length() < file.getSize()) { @@ -502,7 +511,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } ContentUtils.writeToFile(file, tempFile, progress, null, true); @@ -523,7 +532,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } double fps = videoFile.get(5); // gets frame per second @@ -535,7 +544,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } if (Thread.interrupted()) { @@ -544,7 +553,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } @@ -573,10 +582,10 @@ class FileSearch { logger.log(Level.WARNING, "Error seeking to " + framePositions[i] + "ms in {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS // If we can't set the time, continue to the next frame position and try again. - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -588,10 +597,10 @@ class FileSearch { if (!videoFile.read(imageMatrix)) { logger.log(Level.WARNING, "Error reading frame at " + framePositions[i] + "ms from {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS // If the image is bad for some reason, continue to the next frame position and try again. - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -602,10 +611,10 @@ class FileSearch { } // If the image is empty, return since no buffered image can be created. if (imageMatrix.empty()) { - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -660,7 +669,7 @@ class FileSearch { videoFile.release(); // close the file} } } else { - loadSavedThumbnails(cacheDirectory, thumbnailWrapper); + loadSavedThumbnails(cacheDirectory, thumbnailWrapper, VIDEO_DEFAULT_IMAGE); } } @@ -674,7 +683,7 @@ class FileSearch { * information about the file and the thumbnails * associated with it. */ - private static void loadSavedThumbnails(String cacheDirectory, VideoThumbnailsWrapper thumbnailWrapper) { + private static void loadSavedThumbnails(String cacheDirectory, VideoThumbnailsWrapper thumbnailWrapper, BufferedImage failedVideoThumbImage) { int[] framePositions = new int[4]; List videoThumbnails = new ArrayList<>(); int thumbnailNumber = 0; @@ -683,7 +692,7 @@ class FileSearch { try { videoThumbnails.add(ImageIO.read(Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, md5, fileName).toFile())); } catch (IOException ex) { - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(failedVideoThumbImage); logger.log(Level.WARNING, "Unable to read saved video thumbnail " + fileName + " for " + md5, ex); } int framePos = Integer.valueOf(FilenameUtils.getBaseName(fileName).substring(2)); @@ -699,12 +708,12 @@ class FileSearch { * * @return List containing the default thumbnail. */ - private static List createDefaultThumbnailList() { + private static List createDefaultThumbnailList(BufferedImage failedVideoThumbImage) { List videoThumbnails = new ArrayList<>(); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); return videoThumbnails; } diff --git a/Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png b/Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png new file mode 100644 index 0000000000000000000000000000000000000000..876402c150904d298d8362f4f6b870cdf3735553 GIT binary patch literal 2481 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 literal 0 HcmV?d00001 From ed367ac36a6423ee63d5e13cf09376414e8516ae Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:08:58 -0400 Subject: [PATCH 072/106] 6133 clean up changes for video thumbnail --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index ae0e939498..6a5543c9c9 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -23,7 +23,6 @@ import com.google.common.cache.CacheBuilder; import com.google.common.io.Files; import java.awt.Image; import java.awt.image.BufferedImage; -import java.awt.image.RenderedImage; import java.io.IOException; import java.io.Reader; import java.nio.file.Paths; @@ -457,6 +456,11 @@ class FileSearch { + "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS } + /** + * Get the default image to display when a thumbnail is not available. + * + * @return The default video thumbnail. + */ private static BufferedImage getDefaultVideoThumbnail() { try { return ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png"));//NON-NLS From 3d55cc60298fbcaaa5aece2e6b83735007af5155 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:46:48 -0400 Subject: [PATCH 073/106] 6077 add image to indicate image extraction not supported --- .../autopsy/filequery/DiscoveryUiUtils.java | 6 ++++ .../autopsy/filequery/DocumentPanel.form | 22 ++++++------ .../autopsy/filequery/DocumentPanel.java | 32 ++++++++++-------- .../autopsy/filequery/FileSearchData.java | 8 +++++ .../images/image-extraction-not-supported.png | Bin 0 -> 4333 bytes 5 files changed, 43 insertions(+), 25 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java index fc2752a659..5fc2bbc767 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java @@ -35,9 +35,11 @@ final class DiscoveryUiUtils { private static final String RED_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/red-circle-exclamation.png"; private static final String YELLOW_CIRCLE_ICON_PATH = "org/sleuthkit/autopsy/images/yellow-circle-yield.png"; private static final String DELETE_ICON_PATH = "/org/sleuthkit/autopsy/images/file-icon-deleted.png"; + private static final String UNSUPPORTED_DOC_PATH = "/org/sleuthkit/autopsy/images/image-extraction-not-supported.png"; private static final ImageIcon INTERESTING_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(YELLOW_CIRCLE_ICON_PATH, false)); private static final ImageIcon NOTABLE_SCORE_ICON = new ImageIcon(ImageUtilities.loadImage(RED_CIRCLE_ICON_PATH, false)); private static final ImageIcon DELETED_ICON = new ImageIcon(ImageUtilities.loadImage(DELETE_ICON_PATH, false)); + private static final ImageIcon UNSUPPORTED_DOCUMENT_THUMBNAIL = new ImageIcon(ImageUtilities.loadImage(UNSUPPORTED_DOC_PATH, false)); @NbBundle.Messages({"# {0} - fileSize", "# {1} - units", @@ -82,6 +84,10 @@ final class DiscoveryUiUtils { } return Bundle.DiscoveryUiUtility_sizeLabel_text(size, units); } + + static ImageIcon getUnsupportedImageThumbnail(){ + return UNSUPPORTED_DOCUMENT_THUMBNAIL; + } /** * Helper method to see if point is on the icon. diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index 8064993a0c..29a89baf96 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -27,21 +27,21 @@ - - + + - - + + - - - + + + @@ -62,7 +62,7 @@ - + @@ -158,13 +158,13 @@
- + - + - +
diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 2df3a78f38..6aef2df1e9 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -92,9 +92,9 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere previewScrollPane.setViewportView(previewTextArea); sampleImageLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); - sampleImageLabel.setMaximumSize(new java.awt.Dimension(120, 120)); - sampleImageLabel.setMinimumSize(new java.awt.Dimension(120, 120)); - sampleImageLabel.setPreferredSize(new java.awt.Dimension(120, 120)); + sampleImageLabel.setMaximumSize(new java.awt.Dimension(100, 100)); + sampleImageLabel.setMinimumSize(new java.awt.Dimension(100, 100)); + sampleImageLabel.setPreferredSize(new java.awt.Dimension(100, 100)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -104,19 +104,19 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 648, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fileSizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(isDeletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(previewScrollPane) - .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(previewScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 587, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(sampleImageLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addContainerGap()) ); layout.setVerticalGroup( @@ -130,7 +130,7 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(previewScrollPane)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(isDeletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -155,7 +155,8 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere "DocumentPanel.nameLabel.more.text= and {0} more", "# {0} - numberOfImages", "DocumentPanel.numberOfImages.text=1 of {0} images", - "DocumentPanel.numberOfImages.noImages=No images"}) + "DocumentPanel.numberOfImages.noImages=No images", + "DocumentPanel.noImageExtraction.text=No Image Extraction"}) @Override public Component getListCellRendererComponent(JList list, DocumentWrapper value, int index, boolean isSelected, boolean cellHasFocus) { @@ -164,7 +165,10 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere if (value.getResultFile().getAllInstances().size() > 1) { nameText += Bundle.DocumentPanel_nameLabel_more_text(value.getResultFile().getAllInstances().size() - 1); } - if (value.getSummary().getNumberOfImages() > 0) { + if (FileSearchData.getDocTypesWithoutImageExtraction().contains(value.getResultFile().getFirstInstance().getMIMEType())) { + numberOfImagesLabel.setText(Bundle.DocumentPanel_noImageExtraction_text()); + sampleImageLabel.setIcon(DiscoveryUiUtils.getUnsupportedImageThumbnail()); + } else if (value.getSummary().getNumberOfImages() > 0) { numberOfImagesLabel.setText(Bundle.DocumentPanel_numberOfImages_text(value.getSummary().getNumberOfImages())); sampleImageLabel.setIcon(new ImageIcon(value.getSummary().getSampleImage())); } else { diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java index 32a2cf19cb..8efabf2704 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java @@ -291,6 +291,14 @@ final class FileSearchData { "application/vnd.oasis.opendocument.text" //NON-NLS ).build(); + private static final ImmutableSet IMAGE_UNSUPPORTED_DOC_TYPES + = new ImmutableSet.Builder() + .add("application/pdf", //NON-NLS + "application/xhtml+xml").build(); //NON-NLS + + static Collection getDocTypesWithoutImageExtraction(){ + return Collections.unmodifiableCollection(IMAGE_UNSUPPORTED_DOC_TYPES); + } /** * Enum representing the file type. We don't simply use * FileTypeUtils.FileTypeCategory because: - Some file types categories diff --git a/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png b/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png new file mode 100644 index 0000000000000000000000000000000000000000..158b719935dd9a265dc01b8e8e4fd086e10f3183 GIT binary patch literal 4333 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 literal 0 HcmV?d00001 From f0df100758fe5fdc5a55cf5cedff3b69b1f2e055 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:48:39 -0400 Subject: [PATCH 074/106] 6077 fix capitalization of MIME type --- .../images/image-extraction-not-supported.png | Bin 4333 -> 4543 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png b/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png index 158b719935dd9a265dc01b8e8e4fd086e10f3183..3ab47f4f5687db4a27fa83beb2faa5516b93ff24 100644 GIT binary patch literal 4543 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 F{sp@PHO>G4 From 422d17c53e77271cbb787347bb83fbafa032daff Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:53:35 -0400 Subject: [PATCH 075/106] 6077 fix size of image --- .../images/image-extraction-not-supported.png | Bin 4543 -> 1045 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png b/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png index 3ab47f4f5687db4a27fa83beb2faa5516b93ff24..2df9278f76ee3709b8f366ed3d33f8f6a73ec6ea 100644 GIT binary patch literal 1045 zcmeAS@N?(olHy`uVBq!ia0vp^DIm!lvI6;>1s;*b3=BdgAk26#O}>JGfq9jui(^Pd+}oSJd9Ms4S|8>unw@wqY{sTu zzL_OATn!wPnBOoemK~6*iv4}|ZKwU`@|_zOKdBa3+120tWU)%im$$zY^M#Lok}Ig! zlDA~m`LQe7_(#vo#E+^^dmjHfq1OKN>%_03ZZq#Cmb{8st03@GK-jwH9NX!42De_m zHC9c^n6^S8N#oaD#U6=ShFu*JTGNjHdlT5M+x<|Z*Wy)y4ex4T+`w&<|!St+!t z^Jzt7c|h;SJY$lW-txbRTmMDr?7w%*{;x+fQs}7D`DGAfh zURv|#Z}!&xb)W6z!&{y0!m2+#1o}YoTHWlmmL^+&+Rk3585;9GX^DcX(TclP@t+@k zKFHqmcvby_WZnPbK-1e&#Q&TLpKYlvulLIpWZRclS-#h&=6wdqCC`(Xx3BNh>WV|D zPrYmZ@!2lk)O7jhrrYvnuiq-w?6%#1rE==mS$`OlE}8!jpXvTT>iklmHn-C@i$j0A z`T`v|$M3A%CMKYdlv8G}s)%9*${t&GCFE@UMMhT5Nr9UCey*xuR0D}7hgZ!E-Mg}( zN#vwO%$f50=dUdSb0m6Jf@sg;rN6J74PV*3Si$vD#6#ZNjIIrWKy!0%a&IUN1{t<2 zYVW<>y+D=TKR>5$-Tr1fFc>m5_HVuZFa4D%&<3fjFM03vfLeG{Q@2)cI0cN}ObzX9 zmix_|K;3P7)^ILRaDBuBRB#T)Slja{JP{OyqWZ5nFmCH6=C0)4f#ZkJ20+L+2(*u=cFWNS&iRpxcoDU+s(8oa43UE$27IYrdK zBw0kza7ij_i=gvn7gj;%z&Ng8rM9%TqwYMVT)hSx55M5q@PKdeqC2dYe?v3M-Bk^b zfeNPIv5f!GP?>P{`rY{xKU4-E;d=k;-#_N*B2s^a&I^hGvoeFHtDnm{r-UW|)Thh@ literal 4543 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 Date: Fri, 20 Mar 2020 08:56:18 -0400 Subject: [PATCH 076/106] 6077 fix ordering of logic in case they become supported --- .../org/sleuthkit/autopsy/filequery/DocumentPanel.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 6aef2df1e9..6ea00a39ef 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -165,12 +165,12 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere if (value.getResultFile().getAllInstances().size() > 1) { nameText += Bundle.DocumentPanel_nameLabel_more_text(value.getResultFile().getAllInstances().size() - 1); } - if (FileSearchData.getDocTypesWithoutImageExtraction().contains(value.getResultFile().getFirstInstance().getMIMEType())) { - numberOfImagesLabel.setText(Bundle.DocumentPanel_noImageExtraction_text()); - sampleImageLabel.setIcon(DiscoveryUiUtils.getUnsupportedImageThumbnail()); - } else if (value.getSummary().getNumberOfImages() > 0) { + if (value.getSummary().getNumberOfImages() > 0) { numberOfImagesLabel.setText(Bundle.DocumentPanel_numberOfImages_text(value.getSummary().getNumberOfImages())); sampleImageLabel.setIcon(new ImageIcon(value.getSummary().getSampleImage())); + } else if (FileSearchData.getDocTypesWithoutImageExtraction().contains(value.getResultFile().getFirstInstance().getMIMEType())) { + numberOfImagesLabel.setText(Bundle.DocumentPanel_noImageExtraction_text()); + sampleImageLabel.setIcon(DiscoveryUiUtils.getUnsupportedImageThumbnail()); } else { numberOfImagesLabel.setText(Bundle.DocumentPanel_numberOfImages_noImages()); sampleImageLabel.setIcon(null); From 599f5c673a00fbccf52537802cd430948e614ca8 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 09:02:10 -0400 Subject: [PATCH 077/106] 6077 fix insets and add comment --- .../sleuthkit/autopsy/filequery/DiscoveryUiUtils.java | 10 ++++++++-- .../sleuthkit/autopsy/filequery/DocumentPanel.form | 9 +++++---- .../sleuthkit/autopsy/filequery/DocumentPanel.java | 11 ++++++----- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java index 5fc2bbc767..c9ad380a32 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DiscoveryUiUtils.java @@ -84,8 +84,14 @@ final class DiscoveryUiUtils { } return Bundle.DiscoveryUiUtility_sizeLabel_text(size, units); } - - static ImageIcon getUnsupportedImageThumbnail(){ + + /** + * Get the image to use when the document type does not support image + * extraction. + * + * @return An image that indicates we don't know if there are images. + */ + static ImageIcon getUnsupportedImageThumbnail() { return UNSUPPORTED_DOCUMENT_THUMBNAIL; } diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index 29a89baf96..d38b254a90 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -39,9 +39,9 @@ - - - + + + @@ -59,8 +59,8 @@ - + @@ -157,6 +157,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 6ea00a39ef..5c308df129 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -92,6 +92,7 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere previewScrollPane.setViewportView(previewTextArea); sampleImageLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + sampleImageLabel.setIconTextGap(0); sampleImageLabel.setMaximumSize(new java.awt.Dimension(100, 100)); sampleImageLabel.setMinimumSize(new java.awt.Dimension(100, 100)); sampleImageLabel.setPreferredSize(new java.awt.Dimension(100, 100)); @@ -114,9 +115,9 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(previewScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 587, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(sampleImageLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap()) ); layout.setVerticalGroup( @@ -128,8 +129,8 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(previewScrollPane)) + .addComponent(previewScrollPane) + .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) From d5d06241520b102eadb311f467f97dbd92824eaf Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 09:06:30 -0400 Subject: [PATCH 078/106] 6077 make image a tiny bit smaller --- .../images/image-extraction-not-supported.png | Bin 1045 -> 2512 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png b/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png index 2df9278f76ee3709b8f366ed3d33f8f6a73ec6ea..520055fdc72f6f53a7b65b1e553b31e040fb120b 100644 GIT binary patch delta 2488 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 From 4fc92a32111028cb840552271ae661c8f740e949 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 09:29:40 -0400 Subject: [PATCH 079/106] 6176 reset test result text for translator option panels --- .../translators/BingTranslatorSettingsPanel.java | 4 ++++ .../translators/GoogleTranslatorSettingsPanel.java | 2 ++ 2 files changed, 6 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java index 4d8dea3d4a..4d5074a81c 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java @@ -55,16 +55,19 @@ public class BingTranslatorSettingsPanel extends javax.swing.JPanel { authenticationKeyField.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { + warningLabel.setText(""); firePropertyChange("SettingChanged", true, false); } @Override public void removeUpdate(DocumentEvent e) { + warningLabel.setText(""); firePropertyChange("SettingChanged", true, false); } @Override public void changedUpdate(DocumentEvent e) { + warningLabel.setText(""); firePropertyChange("SettingChanged", true, false); } @@ -256,6 +259,7 @@ public class BingTranslatorSettingsPanel extends javax.swing.JPanel { String selectedCode = ((LanguageWrapper) targetLanguageComboBox.getSelectedItem()).getLanguageCode(); if (!StringUtils.isBlank(selectedCode) && !selectedCode.equals(targetLanguageCode)) { targetLanguageCode = selectedCode; + warningLabel.setText(""); firePropertyChange("SettingChanged", true, false); } }//GEN-LAST:event_targetLanguageComboBoxSelected diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java index b81ce9fdb1..d03a03cffc 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java @@ -337,6 +337,7 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { if (dialogResult == JFileChooser.APPROVE_OPTION) { credentialsPathField.setText(fileChooser.getSelectedFile().getPath()); populateTargetLanguageComboBox(); + warningLabel.setText(""); firePropertyChange("SettingChanged", true, false); } }//GEN-LAST:event_browseButtonActionPerformed @@ -407,6 +408,7 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { if (!StringUtils.isBlank(selectedCode) && !selectedCode.equals(targetLanguageCode)) { targetLanguageCode = selectedCode; populateTargetLanguageComboBox(); + warningLabel.setText(""); firePropertyChange("SettingChanged", true, false); } } From 0cfe249b482b67dc0ddaf3a2caedbc0d1e915530 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 09:33:35 -0400 Subject: [PATCH 080/106] 6176 clear correct label --- .../translators/BingTranslatorSettingsPanel.java | 8 ++++---- .../translators/GoogleTranslatorSettingsPanel.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java index 4d5074a81c..845679b79b 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/BingTranslatorSettingsPanel.java @@ -55,19 +55,19 @@ public class BingTranslatorSettingsPanel extends javax.swing.JPanel { authenticationKeyField.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { - warningLabel.setText(""); + testResultValueLabel.setText(""); firePropertyChange("SettingChanged", true, false); } @Override public void removeUpdate(DocumentEvent e) { - warningLabel.setText(""); + testResultValueLabel.setText(""); firePropertyChange("SettingChanged", true, false); } @Override public void changedUpdate(DocumentEvent e) { - warningLabel.setText(""); + testResultValueLabel.setText(""); firePropertyChange("SettingChanged", true, false); } @@ -259,7 +259,7 @@ public class BingTranslatorSettingsPanel extends javax.swing.JPanel { String selectedCode = ((LanguageWrapper) targetLanguageComboBox.getSelectedItem()).getLanguageCode(); if (!StringUtils.isBlank(selectedCode) && !selectedCode.equals(targetLanguageCode)) { targetLanguageCode = selectedCode; - warningLabel.setText(""); + testResultValueLabel.setText(""); firePropertyChange("SettingChanged", true, false); } }//GEN-LAST:event_targetLanguageComboBoxSelected diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java index d03a03cffc..26387e9353 100644 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/translators/GoogleTranslatorSettingsPanel.java @@ -337,7 +337,7 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { if (dialogResult == JFileChooser.APPROVE_OPTION) { credentialsPathField.setText(fileChooser.getSelectedFile().getPath()); populateTargetLanguageComboBox(); - warningLabel.setText(""); + testResultValueLabel.setText(""); firePropertyChange("SettingChanged", true, false); } }//GEN-LAST:event_browseButtonActionPerformed @@ -408,7 +408,7 @@ public class GoogleTranslatorSettingsPanel extends javax.swing.JPanel { if (!StringUtils.isBlank(selectedCode) && !selectedCode.equals(targetLanguageCode)) { targetLanguageCode = selectedCode; populateTargetLanguageComboBox(); - warningLabel.setText(""); + testResultValueLabel.setText(""); firePropertyChange("SettingChanged", true, false); } } From 39dc88814071414652f3ab7cec1915779ecc8e8b Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 20 Mar 2020 10:14:47 -0400 Subject: [PATCH 081/106] 6032 fixes for review issues --- .../org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 48d95b506d..8358dd7d34 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -432,7 +432,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Fri, 20 Mar 2020 16:48:30 -0400 Subject: [PATCH 082/106] Fixed the condition to load up the cache. Also added synchronization around reading/writing to cache. --- .../datamodel/RdbmsCentralRepo.java | 42 +++++++++++++------ .../InterCasePanel.form | 1 - .../InterCasePanel.java | 1 - 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 148513f40c..5f8f00850b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -80,6 +80,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { .expireAfterWrite(ACCOUNTS_CACHE_TIMEOUT, TimeUnit.MINUTES). build(); + private boolean isCRTypeCacheInitialized; private static final Cache typeCache = CacheBuilder.newBuilder().build(); private static final Cache caseCacheByUUID = CacheBuilder.newBuilder() .expireAfterWrite(CASE_CACHE_TIMEOUT, TimeUnit.MINUTES). @@ -106,6 +107,7 @@ abstract class RdbmsCentralRepo implements CentralRepository { * @throws UnknownHostException, EamDbException */ protected RdbmsCentralRepo() throws CentralRepoException { + isCRTypeCacheInitialized = false; bulkArtifactsCount = 0; bulkArtifacts = new HashMap<>(); @@ -215,7 +217,10 @@ abstract class RdbmsCentralRepo implements CentralRepository { * Reset the contents of the caches associated with EamDb results. */ protected final void clearCaches() { - typeCache.invalidateAll(); + synchronized(typeCache) { + typeCache.invalidateAll(); + isCRTypeCacheInitialized = false; + } caseCacheByUUID.invalidateAll(); caseCacheById.invalidateAll(); dataSourceCacheByDsObjectId.invalidateAll(); @@ -3013,7 +3018,9 @@ abstract class RdbmsCentralRepo implements CentralRepository { typeId = newCorrelationTypeKnownId(newType); } - typeCache.put(newType.getId(), newType); + synchronized(typeCache) { + typeCache.put(newType.getId(), newType); + } return typeId; } @@ -3243,7 +3250,9 @@ abstract class RdbmsCentralRepo implements CentralRepository { preparedStatement.setInt(4, aType.isEnabled() ? 1 : 0); preparedStatement.setInt(5, aType.getId()); preparedStatement.executeUpdate(); - typeCache.put(aType.getId(), aType); + synchronized(typeCache) { + typeCache.put(aType.getId(), aType); + } } catch (SQLException ex) { throw new CentralRepoException("Error updating correlation type.", ex); // NON-NLS } finally { @@ -3265,7 +3274,9 @@ abstract class RdbmsCentralRepo implements CentralRepository { @Override public CorrelationAttributeInstance.Type getCorrelationTypeById(int typeId) throws CentralRepoException { try { - return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId)); + synchronized(typeCache) { + return typeCache.get(typeId, () -> getCorrelationTypeByIdFromCr(typeId)); + } } catch (CacheLoader.InvalidCacheLoadException ignored) { //lambda valueloader returned a null value and cache can not store null values this is normal if the correlation type does not exist in the central repo yet return null; @@ -3285,11 +3296,12 @@ abstract class RdbmsCentralRepo implements CentralRepository { @Override public List getCorrelationTypes() throws CentralRepoException { - if (typeCache.size() == 0) { - getCorrelationTypesFromCr(); + synchronized (typeCache) { + if (isCRTypeCacheInitialized == false) { + getCorrelationTypesFromCr(); + } + return new ArrayList<>(typeCache.asMap().values()); } - - return new ArrayList<>(typeCache.asMap().values()); } /** @@ -3358,16 +3370,22 @@ abstract class RdbmsCentralRepo implements CentralRepository { private void getCorrelationTypesFromCr() throws CentralRepoException { // clear out the cache - typeCache.invalidateAll(); + synchronized(typeCache) { + typeCache.invalidateAll(); + isCRTypeCacheInitialized = false; + } String sql = "SELECT * FROM correlation_types"; try ( Connection conn = connect(); PreparedStatement preparedStatement = conn.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery();) { - while (resultSet.next()) { - CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet); - typeCache.put(aType.getId(), aType); + synchronized(typeCache) { + while (resultSet.next()) { + CorrelationAttributeInstance.Type aType = getCorrelationTypeFromResultSet(resultSet); + typeCache.put(aType.getId(), aType); + } + isCRTypeCacheInitialized = true; } } catch (SQLException ex) { throw new CentralRepoException("Error getting correlation types.", ex); // NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form index d7c106797a..93a06ca05c 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.form @@ -106,7 +106,6 @@ - diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java index 77eb7dbbb3..a2c1c01529 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java @@ -154,7 +154,6 @@ public final class InterCasePanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(correlationComboBoxLabel, org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationComboBoxLabel.text")); // NOI18N - correlationTypeComboBox.setMaximumRowCount(50); correlationTypeComboBox.setSelectedItem(null); correlationTypeComboBox.setToolTipText(org.openide.util.NbBundle.getMessage(InterCasePanel.class, "InterCasePanel.correlationTypeComboBox.toolTipText")); // NOI18N correlationTypeComboBox.addActionListener(new java.awt.event.ActionListener() { From 7577e2973182ebfbd3c686d7569b2056ac937749 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 23 Mar 2020 08:28:07 -0400 Subject: [PATCH 083/106] addressing codacy comments --- .../sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java | 2 +- .../src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index f99ead0d3d..17e94837cc 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -150,7 +150,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP // initial setup so the font size of this panel as well as the font size indicated // in the TextZoomPanel are correct SwingUtilities.invokeLater(() -> { - if (zoomPanel != null && zoomPanel instanceof TextZoomPanel) + if (zoomPanel instanceof TextZoomPanel) ((TextZoomPanel) this.zoomPanel).resetSize(); }); } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index a9897963ae..4b0f7677a4 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -28,8 +28,7 @@ import org.openide.util.NbBundle; class TextZoomPanel extends JPanel { static final int DEFAULT_SIZE = new JLabel().getFont().getSize(); - // How much font size is incremented or decremented when zooming in or zooming out respectively. - private static final int FONT_INCREMENT_DELTA = 1; + private static final long serialVersionUID = 1L; private static final double[] ZOOM_STEPS = { 0.0625, 0.125, 0.25, 0.375, 0.5, 0.75, From 35f0eef4fa1614f0a43dc5423f30abe893ae6505 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Mon, 23 Mar 2020 10:31:29 -0400 Subject: [PATCH 084/106] Update oruxmaps.py Update what is passed to addPoint --- InternalPythonModules/android/oruxmaps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/android/oruxmaps.py b/InternalPythonModules/android/oruxmaps.py index d08414cdf4..bc148f1cf4 100644 --- a/InternalPythonModules/android/oruxmaps.py +++ b/InternalPythonModules/android/oruxmaps.py @@ -146,7 +146,7 @@ class OruxMapsAnalyzer(general.AndroidComponentAnalyzer): altitude = trackpointsResultSet.getDouble("trkptalt") time = trackpointsResultSet.getLong("trkpttime") / 1000 # milliseconds since unix epoch - geoPointList.addPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time) + geoPointList.addPoint(TskGeoTrackpointsUtil.GeoTrackPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time)) try: geoartifact = geoArtifactHelper.addTrack(segmentName, geoPointList, None) From 6485951dbd40aeb67534da295a09e6a7def3673e Mon Sep 17 00:00:00 2001 From: apriestman Date: Mon, 23 Mar 2020 10:31:42 -0400 Subject: [PATCH 085/106] Doxygen warnings --- .../centralrepository/datamodel/RdbmsCentralRepoFactory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index f76c13cd63..c01d3ee4e4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -526,6 +526,7 @@ public class RdbmsCentralRepoFactory { * on the selected CR platform/RDMBS. * * @param pkName name of primary key. + * @param selectedPlatform The selected platform. * * @return SQL clause to be used in a Create table statement */ @@ -802,6 +803,7 @@ public class RdbmsCentralRepoFactory { * Inserts the default content in persona related tables. * * @param conn Database connection to use. + * @param selectedPlatform The selected platform. * * @return True if success, false otherwise. */ From 491b74a0f58c5c03d466da198e927729e65f8b4c Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Mon, 23 Mar 2020 10:56:08 -0400 Subject: [PATCH 086/106] Update oruxmaps.py Update addPoint with correct parameters. --- InternalPythonModules/android/oruxmaps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/android/oruxmaps.py b/InternalPythonModules/android/oruxmaps.py index bc148f1cf4..7a939e1972 100644 --- a/InternalPythonModules/android/oruxmaps.py +++ b/InternalPythonModules/android/oruxmaps.py @@ -146,7 +146,7 @@ class OruxMapsAnalyzer(general.AndroidComponentAnalyzer): altitude = trackpointsResultSet.getDouble("trkptalt") time = trackpointsResultSet.getLong("trkpttime") / 1000 # milliseconds since unix epoch - geoPointList.addPoint(TskGeoTrackpointsUtil.GeoTrackPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time)) + geoPointList.addPoint(TskGeoTrackpointsUtil.GeoTrackPointList.GeoTrackPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time)) try: geoartifact = geoArtifactHelper.addTrack(segmentName, geoPointList, None) From 4e28a8686f8f54434a921d71d6d2c446403b88cd Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Mon, 23 Mar 2020 18:52:06 -0400 Subject: [PATCH 087/106] 6185: Consolidate duplicated code and remove unused code from Central Repository code --- .../datamodel/CentralRepository.java | 9 --- .../datamodel/RdbmsCentralRepo.java | 62 ++----------------- .../CommonAttributeCaseSearchResults.java | 2 +- .../CommonAttributeCountSearchResults.java | 2 +- .../CommonAttributePanel.java | 4 +- .../InterCasePanel.java | 2 +- .../CorrelationCaseChildNodeFactory.java | 2 +- 7 files changed, 10 insertions(+), 73 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java index 5b81dc6b3b..6a4a138cfb 100755 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepository.java @@ -806,15 +806,6 @@ public interface CentralRepository { public void processSelectClause(String selectClause, InstanceTableCallback instanceTableCallback) throws CentralRepoException; - /** - * Returns list of all correlation types. - * - * @return list of Correlation types - * @throws CentralRepoException - */ - List getCorrelationTypes() throws CentralRepoException; - - /** * Get account type by type name. * diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 5f8f00850b..256e5407c9 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -3134,27 +3134,12 @@ abstract class RdbmsCentralRepo implements CentralRepository { @Override public List getDefinedCorrelationTypes() throws CentralRepoException { - Connection conn = connect(); - List aTypes = new ArrayList<>(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - String sql = "SELECT * FROM correlation_types"; - - try { - preparedStatement = conn.prepareStatement(sql); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - aTypes.add(getCorrelationTypeFromResultSet(resultSet)); + synchronized (typeCache) { + if (isCRTypeCacheInitialized == false) { + getCorrelationTypesFromCr(); } - return aTypes; - - } catch (SQLException ex) { - throw new CentralRepoException("Error getting all correlation types.", ex); // NON-NLS - } finally { - CentralRepoDbUtil.closeStatement(preparedStatement); - CentralRepoDbUtil.closeResultSet(resultSet); - CentralRepoDbUtil.closeConnection(conn); + return new ArrayList<>(typeCache.asMap().values()); } } @@ -3285,45 +3270,6 @@ abstract class RdbmsCentralRepo implements CentralRepository { } } - /** - * Returns a list of all correlation types. It uses the cache to build the - * list. If the cache is empty, it reads from the database and loads up the - * cache. - * - * @return List of correlation types. - * @throws CentralRepoException - */ - @Override - public List getCorrelationTypes() throws CentralRepoException { - - synchronized (typeCache) { - if (isCRTypeCacheInitialized == false) { - getCorrelationTypesFromCr(); - } - return new ArrayList<>(typeCache.asMap().values()); - } - } - - /** - * Gets a Correlation type with the specified name. - * - * @param correlationtypeName Correlation type name - * @return Correlation type matching the given name, null if none matches. - * - * @throws CentralRepoException - */ - public CorrelationAttributeInstance.Type getCorrelationTypeByName(String correlationtypeName) throws CentralRepoException { - List correlationTypesList = getCorrelationTypes(); - - CorrelationAttributeInstance.Type correlationType - = correlationTypesList.stream() - .filter(x -> correlationtypeName.equalsIgnoreCase(x.getDisplayName())) - .findAny() - .orElse(null); - - return null; - } - /** * Get the EamArtifact.Type that has the given Type.Id from the central repo diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributeCaseSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributeCaseSearchResults.java index e096638434..6b1fe1ab72 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributeCaseSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributeCaseSearchResults.java @@ -123,7 +123,7 @@ final public class CommonAttributeCaseSearchResults { if (currentCaseDataSourceMap == null) { //there are no results return filteredCaseNameToDataSourcesTree; } - CorrelationAttributeInstance.Type attributeType = CentralRepository.getInstance().getCorrelationTypes() + CorrelationAttributeInstance.Type attributeType = CentralRepository.getInstance().getDefinedCorrelationTypes() .stream() .filter(filterType -> filterType.getId() == resultTypeId) .findFirst().get(); diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributeCountSearchResults.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributeCountSearchResults.java index 85923e53b6..80a65b2835 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributeCountSearchResults.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributeCountSearchResults.java @@ -129,7 +129,7 @@ final public class CommonAttributeCountSearchResults { } CentralRepository eamDb = CentralRepository.getInstance(); - CorrelationAttributeInstance.Type attributeType = eamDb.getCorrelationTypes() + CorrelationAttributeInstance.Type attributeType = eamDb.getDefinedCorrelationTypes() .stream() .filter(filterType -> filterType.getId() == this.resultTypeId) .findFirst().get(); diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.java index 43d834e39d..5e7aa3adb4 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/CommonAttributePanel.java @@ -255,7 +255,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer filterByDocuments = interCasePanel.documentsCheckboxIsSelected(); } if (corType == null) { - corType = CentralRepository.getInstance().getCorrelationTypes().get(0); + corType = CentralRepository.getInstance().getDefinedCorrelationTypes().get(0); } if (caseId == InterCasePanel.NO_CASE_SELECTED) { builder = new AllInterCaseCommonAttributeSearcher(filterByMedia, filterByDocuments, corType, percentageThreshold); @@ -366,7 +366,7 @@ final class CommonAttributePanel extends javax.swing.JDialog implements Observer filterByDocuments = interCasePanel.documentsCheckboxIsSelected(); } if (corType == null) { - corType = CentralRepository.getInstance().getCorrelationTypes().get(0); + corType = CentralRepository.getInstance().getDefinedCorrelationTypes().get(0); } if (caseId == InterCasePanel.NO_CASE_SELECTED) { builder = new AllInterCaseCommonAttributeSearcher(filterByMedia, filterByDocuments, corType, percentageThreshold); diff --git a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java index a2c1c01529..f36f8ab520 100644 --- a/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java +++ b/Core/src/org/sleuthkit/autopsy/commonpropertiessearch/InterCasePanel.java @@ -118,7 +118,7 @@ public final class InterCasePanel extends javax.swing.JPanel { void setupCorrelationTypeFilter() { this.correlationTypeFilters = new HashMap<>(); try { - List types = CentralRepository.getInstance().getCorrelationTypes(); + List types = CentralRepository.getInstance().getDefinedCorrelationTypes(); for (CorrelationAttributeInstance.Type type : types) { correlationTypeFilters.put(type.getDisplayName(), type); this.correlationTypeComboBox.addItem(type.getDisplayName()); diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CorrelationCaseChildNodeFactory.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CorrelationCaseChildNodeFactory.java index 49617c9dfb..67e0366a9b 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CorrelationCaseChildNodeFactory.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CorrelationCaseChildNodeFactory.java @@ -111,7 +111,7 @@ final class CorrelationCaseChildNodeFactory extends ChildFactory(); - List correcationTypeList = CentralRepository.getInstance().getCorrelationTypes(); + List correcationTypeList = CentralRepository.getInstance().getDefinedCorrelationTypes(); correcationTypeList.forEach((type) -> { correlationTypeMap.put(type.getId(), type); }); From fff830702ae2ed57c60e6fe8cf5ba5cd4a50f96b Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 23 Mar 2020 21:37:07 -0400 Subject: [PATCH 088/106] updated panel and resizing --- .../keywordsearch/ExtractedContentPanel.form | 16 ++-- .../keywordsearch/ExtractedContentPanel.java | 16 ++-- .../autopsy/keywordsearch/TextZoomPanel.form | 74 +++++++++++++------ .../autopsy/keywordsearch/TextZoomPanel.java | 61 +++++++++------ 4 files changed, 108 insertions(+), 59 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form index e83ecc14e3..2ed8bb9073 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.form @@ -26,6 +26,9 @@ + + + @@ -45,17 +48,16 @@ - - + + - - - + + @@ -180,9 +182,9 @@ - + - +
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java index 17e94837cc..6cc5e01d42 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/ExtractedContentPanel.java @@ -228,6 +228,7 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.selectAllMenuItem.text")); // NOI18N rightClickMenu.add(selectAllMenuItem); + setMinimumSize(new java.awt.Dimension(100, 0)); setPreferredSize(new java.awt.Dimension(100, 58)); extractedScrollPane.setBackground(new java.awt.Color(255, 255, 255)); @@ -398,11 +399,11 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP .addComponent(hitTotalLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(hitButtonsLabel) .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(zoomPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(56, 56, 56)) + .addComponent(zoomPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(0, 0, 0)) ); - controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator2, jSeparator3, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox}); + controlPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {hitButtonsLabel, hitCountLabel, hitLabel, hitNextButton, hitOfLabel, hitPreviousButton, hitTotalLabel, jLabel1, jSeparator2, jSeparator3, pageButtonsLabel, pageCurLabel, pageNextButton, pageOfLabel, pagePreviousButton, pageTotalLabel, pagesLabel, sourceComboBox, zoomPanel}); zoomPanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ExtractedContentPanel.class, "ExtractedContentPanel.AccessibleContext.accessibleName")); // NOI18N @@ -412,16 +413,15 @@ class ExtractedContentPanel extends javax.swing.JPanel implements ResizableTextP this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 745, Short.MAX_VALUE) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 745, Short.MAX_VALUE) + .addComponent(controlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 980, Short.MAX_VALUE) + .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 980, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(controlScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(controlScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(extractedScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 422, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addComponent(extractedScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)) ); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form index 887bad8a34..46d8e3d66f 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.form @@ -8,7 +8,6 @@ - @@ -20,13 +19,35 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -47,13 +68,6 @@ - - - - - - - @@ -65,14 +79,17 @@ + + + - + - + - + @@ -90,15 +107,19 @@ + + + - + - + - + + @@ -111,6 +132,10 @@ + + + + @@ -120,12 +145,19 @@ + + + + + + + + + - - diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java index 4b0f7677a4..eb716df8df 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TextZoomPanel.java @@ -111,17 +111,13 @@ class TextZoomPanel extends JPanel { private void initComponents() { zoomTextField = new javax.swing.JTextField(); - jSeparator1 = new javax.swing.JToolBar.Separator(); zoomOutButton = new javax.swing.JButton(); zoomInButton = new javax.swing.JButton(); - jSeparator2 = new javax.swing.JToolBar.Separator(); + javax.swing.JToolBar.Separator jSeparator2 = new javax.swing.JToolBar.Separator(); zoomResetButton = new javax.swing.JButton(); - filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0)); setMinimumSize(new java.awt.Dimension(150, 20)); setPreferredSize(new java.awt.Dimension(200, 20)); - setRequestFocusEnabled(false); - setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 0, 0)); zoomTextField.setEditable(false); zoomTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT); @@ -129,56 +125,78 @@ class TextZoomPanel extends JPanel { zoomTextField.setMaximumSize(new java.awt.Dimension(50, 2147483647)); zoomTextField.setMinimumSize(new java.awt.Dimension(50, 20)); zoomTextField.setPreferredSize(new java.awt.Dimension(50, 20)); - add(zoomTextField); - - jSeparator1.setMaximumSize(new java.awt.Dimension(6, 20)); - add(jSeparator1); zoomOutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-out.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomOutButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomOutButton.text")); // NOI18N zoomOutButton.setBorderPainted(false); zoomOutButton.setFocusable(false); zoomOutButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - zoomOutButton.setMaximumSize(new java.awt.Dimension(24, 24)); - zoomOutButton.setMinimumSize(new java.awt.Dimension(24, 24)); - zoomOutButton.setPreferredSize(new java.awt.Dimension(24, 24)); + zoomOutButton.setMargin(new java.awt.Insets(0, 0, 0, 0)); + zoomOutButton.setMaximumSize(new java.awt.Dimension(20, 20)); + zoomOutButton.setMinimumSize(new java.awt.Dimension(20, 20)); + zoomOutButton.setPreferredSize(new java.awt.Dimension(20, 20)); zoomOutButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomOutButtonActionPerformed(evt); } }); - add(zoomOutButton); zoomInButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/keywordsearch/zoom-in.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(zoomInButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomInButton.text")); // NOI18N zoomInButton.setBorderPainted(false); zoomInButton.setFocusable(false); zoomInButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - zoomInButton.setMaximumSize(new java.awt.Dimension(24, 24)); - zoomInButton.setMinimumSize(new java.awt.Dimension(24, 24)); - zoomInButton.setPreferredSize(new java.awt.Dimension(24, 24)); + zoomInButton.setMargin(new java.awt.Insets(0, 0, 0, 0)); + zoomInButton.setMaximumSize(new java.awt.Dimension(20, 20)); + zoomInButton.setMinimumSize(new java.awt.Dimension(20, 20)); + zoomInButton.setPreferredSize(new java.awt.Dimension(20, 20)); + zoomInButton.setRolloverEnabled(true); zoomInButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomInButtonActionPerformed(evt); } }); - add(zoomInButton); jSeparator2.setOrientation(javax.swing.SwingConstants.VERTICAL); jSeparator2.setMaximumSize(new java.awt.Dimension(6, 20)); - add(jSeparator2); org.openide.awt.Mnemonics.setLocalizedText(zoomResetButton, org.openide.util.NbBundle.getMessage(TextZoomPanel.class, "TextZoomPanel.zoomResetButton.text")); // NOI18N zoomResetButton.setBorderPainted(false); zoomResetButton.setFocusable(false); zoomResetButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + zoomResetButton.setMargin(new java.awt.Insets(0, 0, 0, 0)); + zoomResetButton.setMinimumSize(new java.awt.Dimension(50, 20)); + zoomResetButton.setPreferredSize(new java.awt.Dimension(70, 20)); zoomResetButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { zoomResetButtonActionPerformed(evt); } }); - add(zoomResetButton); - add(filler1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(zoomTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(zoomOutButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(zoomInButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(zoomResetButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(zoomTextField, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(zoomOutButton, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(zoomInButton, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(zoomResetButton, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); }// //GEN-END:initComponents private void zoomOutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutButtonActionPerformed @@ -195,9 +213,6 @@ class TextZoomPanel extends JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.Box.Filler filler1; - private javax.swing.JToolBar.Separator jSeparator1; - private javax.swing.JToolBar.Separator jSeparator2; private javax.swing.JButton zoomInButton; private javax.swing.JButton zoomOutButton; private javax.swing.JButton zoomResetButton; From c599357679a99f30f434210bfef4133132a66696 Mon Sep 17 00:00:00 2001 From: apriestman Date: Tue, 24 Mar 2020 11:43:39 -0400 Subject: [PATCH 089/106] Added screenshots to make module installation clearer --- .../images/module_install_netbeans.png | Bin 0 -> 39717 bytes .../images/module_install_python.png | Bin 0 -> 39640 bytes docs/doxygen-user/module_install.dox | 8 +++++++- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 docs/doxygen-user/images/module_install_netbeans.png create mode 100644 docs/doxygen-user/images/module_install_python.png diff --git a/docs/doxygen-user/images/module_install_netbeans.png b/docs/doxygen-user/images/module_install_netbeans.png new file mode 100644 index 0000000000000000000000000000000000000000..db50799d1c7804d5467ac69c4fef10f276635a74 GIT binary patch literal 39717 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 literal 0 HcmV?d00001 diff --git a/docs/doxygen-user/images/module_install_python.png b/docs/doxygen-user/images/module_install_python.png new file mode 100644 index 0000000000000000000000000000000000000000..cb393c30b52835b1dacbff90e9db30b0ace722ed GIT binary patch literal 39640 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 G!u|!ctML8+ literal 0 HcmV?d00001 diff --git a/docs/doxygen-user/module_install.dox b/docs/doxygen-user/module_install.dox index 31a02b3098..1882ca70e2 100644 --- a/docs/doxygen-user/module_install.dox +++ b/docs/doxygen-user/module_install.dox @@ -9,9 +9,15 @@ There are two types of modules: \section module_install_nbm Installing NetBeans Modules If you have an NBM file, then it may contain one or more Autopsy modules. To install it, use the plugin manager at "Tools", "Plugins". +\image html module_install_netbeans.png + Choose the "Downloaded" tab and then choose "Add Plugins". Browse to the NBM file. It may require you to restart Autopsy. \section module_install_python Installing Python Modules -If you have a ZIP file with a Python module in it, then unzip the file and you should get a folder. Open the Python module library folder using "Tools", "Python Plugins". Copy the module folder into there and Autopsy should identify and use it next time it loads modules. +If you have a ZIP file with a Python module in it, then unzip the file and you should get a folder. Open the Python module library folder through Autopsy using "Tools", "Python Plugins". + +\image html module_install_python.png + +On Windows this will be under your user directory in "AppData\Roaming\autopsy\python_modules". Copy the module folder into there and Autopsy should identify and use it next time it loads modules. */ From 42960d23deed1af3f5f96938676053dcb1abb856 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 14:18:27 -0400 Subject: [PATCH 090/106] 6077 remove unused import --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index c35ebe481c..5832625b73 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -49,7 +49,6 @@ import org.imgscalr.Scalr; import org.netbeans.api.progress.ProgressHandle; import org.opencv.core.Mat; import org.opencv.highgui.VideoCapture; -import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.casemodule.Case; From 67ac4555be8924e2d5f01a9aed1610c529667d10 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 14:20:13 -0400 Subject: [PATCH 091/106] 6077 remove stray pixel --- .../images/image-extraction-not-supported.png | Bin 2512 -> 2485 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png b/Core/src/org/sleuthkit/autopsy/images/image-extraction-not-supported.png index 520055fdc72f6f53a7b65b1e553b31e040fb120b..99a40745a7438ed05bafee1c5e311f0ef13aff66 100644 GIT binary patch delta 2389 zcmV-b399zc6SWhNR)0!KL_t(|UhSQEY!ufW$G_`i*K3=@z}m(TY(rAxI7vfHkf{=- zxvUVS4J4$YNu|oQOO6JG(mEA_au#Zt#BC8ciD1?Ikrc2)D^(RJ;>bl!A|&EaOo9mF zO0axjY_NB2uXm@v-`knZtTDz$HuJ{3&*<&Wy!UoJ^ZmYac7Nmt?K&teE!6<1U<$0s z^)O%q%F4?6{KG0-8Ca`<;@}th&{gqzy(lRu(T~D791gf#E`&lMJ?7>nCME`5U0qz5 z^_VbQw{Asoaj|}M71)5jsH&=pay2e4PV;y?;+@kJ(Xb{?r&EiMkB`!gLw|bpX+U*# z^%Y-IQBk3%Du4Q;va(W3OG^`GnDt{#`{D`%%;K|~)2C0@)~{c$rz!>tYsT7{YeZir zL>aJS$Bsy54l7oy&{GuG3u|cBlr=UJWq^^1T~p!@9jv9fCYXsFQI8$Tkdu?6$0~*j z*3{6KwKj+tU?g%_w{D#ts~9R+Q?tefV$Yal@eosuc7KKs)|NG9t&Pc=n27Pjib+jP zMMFb_*jEe>G(<&XW24w7=@DfBxr0C;Aodl*19ise>FE*sY(T8f=UY`%QzNF++qP{( zUS6I^R16Qfxw+W6bEgoWvXNr_(7Ot&o+Di-&ORkMH8pN1r29_c`h*PMo-4CNk~_ zA>-v&kpEN>GSl>EN#RF&y1To@zT^fp;@m&q#)r>rz{${MI@tuo!%6Q>s=5ww@_hOl z0tnG-5FO~I*ZBA+QE*@jX3z3ql*l6&_AsEn7N0Kp6%K5#MGsPcNcdP?@M{sG&4*6< z#DsavFn8l?xMi}QBnk2xaDEqd%`L^@L#L>uCzJFBEN)PgdEUaO&NYEABbM@-O$yM~ zgSaWb!~^ed!t8tXXbF(pfTn%e_skM}_VG6)Xi{X9pozvM4$hQ`7(G4_@$LlhFWLNK zQlPUFJr};irIuEI%I6YRgz2FzgfaQWczEX<$j#KFEkGBr@O>&V29*&Ytm$F;18sD!(3N zt=@v4{OLg|$Jb&UvQ}=vQ{_)1#o0!mHE_e#b_Cz<*^ASydXyx{W5CI;(Qxz&T&6bM zIH?fY;Jkl-5$=2Thh)mYNi8bJBfq_izR9QuF|<)Lb?kp=__9UB$bvKmG<{i%`v0D$ zrpIV}cocIR?pRoe)HEY*fW(f&l%nOB=5C{oJB)*xqQJ3JXg>N4WSZ?rV!(N{9Y28! zm%lIl-1f)LT!5T{Y?^)zp2P`xnEJD+VjL8P2df=_2(6r#eQW8?8-cC)BVE{vy8)M9%NJdf=x(HCjy27M z2f?L(Q}}Ad0&M@=aU_Z^ybE29eB4`Ej)z{HNgcFxNIMTeq8mvQry_0E1Gv5D$H=%| z@rmx%vpE0BSM+(K0}moN$%CZH6D$?KH*y&;Wcbit^F9uL5umY8_!2|t#F$&BV0=!N zIF^MGX+W@cKWcvc53(Uqzrbz;V(vm_VIi`AZxa#HFyai*j_<+l`(MJ*_8xItjtSB9 zZq&?Km^SxOvP3RMmH}rz#DDUh$C36n8dQppqZHC_i<(8OU5zfoETT zpCet|tN2+0GZ|rTr*Guq+{7NKa z6kP~+xID}C)0T+TqPI}|)?;Le+{iT(9t;65{^Bg5R(?E{{1_pZHD~}ICC1!{6rQJwtx(9&7e_#zdf;^ z0kJghF$zDy9kAoEJCUj%+YS2}5bQ=E$WKAH>%ot}B>N0Idt<+e*x7$$_v$?e1~fRR zDrf;Z=f{`giRZKR4DuuQ!?`yBBVZ;xa!>|XjJ=wm^ZW2o#eQ`AY2+h@LNp5wP*r|p zF$(8T3Fol^_U!{|*WvXUf2Og2Pk^c}S6;pi(FJYcL9BYaAe_er*tZXebs|0~8BUCX zOAk&Yz?m?}hj%4H^#K-RF9QM{@OLz!0~e?nYNF6g`G^3WWy1|&2v0A%!ZL|SuA-CbD_d;$_4S!2Z z3pQ-npdTrQ8rGIIX3EOS#5=p7ZQi_@f0h&>Jw2VH6vF^(Yv^nc*)x{2<;5mfu3V|d zDuxQy)L6)~&*f|x!yOK4LFb{P_o~`vqK?#(f969^Z}IzG(wyOi=gl8jwQ7}~q8Kc! zomorPwl`N8z?e!G0y$A00000NkvXX Hu0mjfu6VMZoR)1wlL_t(|UhSO=Y!t^G#=rC9&S=4@jK#*owyCus--L6s=Y z%L-A_KtdXtRH|IN9(hrd2+47%O@asl zLjr;`#>V!Y?epFC|DW5v>=^@RWV5qoeyh3LotZoDe&0OzR(~F7*FkY{u?9c|Q(#T5 zhnNj0EiLWy536u_V69@s!7ucoD^gimiK3z+{V0sX;egBKLMRl{V{UHZ;^NTN)y0Kb zj|sD7%N7(C7V1Y=fDP!2s;a6eR}&HvG>^w4-Z@PX4Qt|bI<>^a#3aimka&vR_Sj9lW zni~4D)&>y+j6@D=*RIuL6$1rpYS!35>=~0R9%8D|&VS&++Oo#1wJ})}6EU7xG3n{) zICt)x*jEe=G(^Su^XJ7rNslN4$Q=X%0kN+b9H=u!Pfw57X9MDWKHtikni?^k-nMNU z^78UTqGE8EI&~^`?%XNFC+)#SpW7rPB_+Y{_w%k|ka4@+=Q} z1}LmS8Gm3g$^eT|23U+Tz+#jE7NZQX7-fLPC<81eax22=bc#nSWToTcAsqR`-*M=p z&k<_)9A_y`oVZ{HvhD~W>y=kA{pkW^XXw$A!jJTHcXx|@$qhJ<)Bk)2A3nPt$3ty& zvPnpUlir`uWxf@=`E#vhhNs!-wGrO>BZZT>PouHCFjHEYUaf71F z^AG|Buw}P9(aEvX5XtvOMu)4c=uu7vrF*V$KQ~kDUnfvCK{In zIDb>eVnkXp65UDQU$Xhfq(EmUdMdVQBl_?Ku3my=c;gN5t2tJ=aF%;s;AM z;`xRxc<^WUM2XM1+-{70=C_zvzZ*}yJ`bMM5Q%QwbLVcm3E%GDfx69y^*DKu$bb`Q z{NNLuYV?aSPM97lzaC6nwHZ(T@j)ub*J3m#uGoyH%br21vz0z;;D)R9FuvWh7k?*P z^e9P?$AIHs<6Qk0XrngVIH?d?;kI$7nI?V-`qvtWYmK=+Nha2@;{vW zvRTB)f;0wrzpTUA|DL3#$7pc4?ZvmHqcID^)s$8e$T`_j*Ce}DXp1<0M1L({MRlRPF5lYTl$jDy1PV6_8*79Z6M zd62_^HZLw6KSo`pkL2=G=%O$TSr1Rg=*$#7Q$I;bLF%O2sR=R+VCZt=j2W~X$YFpp z3*(=95&17K#XSq=U|e1n)qotNP0mEpFg;Jdp{ZI(jId3FL|pG!E0Jp+;D7U@qxCG> zPoKtx1`VSgx*HkUqf9g5esJjozFNKj+y8nL$)XGILYHGY?yV@pLodys4%#}Tod+P< zjg+yIkTLTC++OfwWL>ZLM0d+6ocZJ{`n=JB2N4|SLCW|smWtmSxeOREd}yzEAGKcu zXzUZd#1J|$^41AR%bh5WWq)Bv8W618kD6cogKS9FFR&YdxVw;@pO2i|M1(X9IRmt# zd$9Zdmr>u|BW}wvA)4L|pD`1Y=RQi7$i>hypz%ZeC+`IuZf~WLg-ai9wxe_8EaVja z8h1|>5mGU93^-qj%8Bz)AM7IGlk^Mo(X1jHlZ#4_zwk~GBO61*fPaIF@m9uSoTbLb zK_x$YQGV)nvyi>09M8QmN4loR!1f08)V_*kKY9xnX{?_>W1euc(@EPHWWBfnKi@D% zs$pku>}|l;OYr;Y6&Qx$bRpc~@+{X+TQbrM-bUfukC7#EBiBs0KLjfAXJ-+$@@Z7^ z{vc8sQngA3X3y@pYoY%}a^BiR^>6H6wFkj~1_xCIEkNh|_)+WnM*jQ>;XF3LzI{O5TD&psPc-%kP}Swi%eNuApe;OzmG8_7 z=dl6y?E~VSNK6?9Cx*kN2Pcx?OzP*uyAq-L0E@Ag0f7$qJG|(?1!{)86q;zi6TVB~ z>TE~s)dzHW(R9oU{*Pbb|MWMM+5swr<_3$Hazef-FEaK@y=1uo#n20vmsb0lbEc;>KXsI1#kxZMLDT*Z0#tUa1kesh00000NkvXXu0mjfnk%(j From 67a0952e7b488a7f305587cab113813189741ca5 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 14:38:52 -0400 Subject: [PATCH 092/106] 6077 change text when file type unsupported --- .../org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED | 1 + Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED index c5dd80db41..50086b7c9b 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filequery/Bundle.properties-MERGED @@ -16,6 +16,7 @@ DiscoveryUiUtility.sizeLabel.text=Size: {0} {1} DiscoveryUiUtility.terraBytes.text=TB # {0} - otherInstanceCount DocumentPanel.nameLabel.more.text=\ and {0} more +DocumentPanel.noImageExtraction.text=0 of ? images DocumentPanel.numberOfImages.noImages=No images # {0} - numberOfImages DocumentPanel.numberOfImages.text=1 of {0} images diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 5c308df129..30a94a75ca 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -157,7 +157,7 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere "# {0} - numberOfImages", "DocumentPanel.numberOfImages.text=1 of {0} images", "DocumentPanel.numberOfImages.noImages=No images", - "DocumentPanel.noImageExtraction.text=No Image Extraction"}) + "DocumentPanel.noImageExtraction.text=0 of ? images"}) @Override public Component getListCellRendererComponent(JList list, DocumentWrapper value, int index, boolean isSelected, boolean cellHasFocus) { From 2b47ec24a10a6a65b1c00f9b405e010f659fa354 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 17:04:07 -0400 Subject: [PATCH 093/106] 6077 change text area to text pane to eliminated boxes --- .../autopsy/filequery/DocumentPanel.form | 72 +++++++++---------- .../autopsy/filequery/DocumentPanel.java | 48 ++++++------- 2 files changed, 55 insertions(+), 65 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index d38b254a90..74b8e8bedd 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -34,10 +34,7 @@ - - - - + @@ -47,6 +44,13 @@ + + + + + + + @@ -58,11 +62,8 @@ - - - - - + + @@ -70,6 +71,13 @@ + + + + + + + @@ -119,37 +127,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -171,5 +148,20 @@ + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 30a94a75ca..4ddae94fce 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -57,10 +57,10 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere scoreLabel = new javax.swing.JLabel(); fileSizeLabel = new javax.swing.JLabel(); nameLabel = new javax.swing.JLabel(); - javax.swing.JScrollPane previewScrollPane = new javax.swing.JScrollPane(); - previewTextArea = new javax.swing.JTextArea(); sampleImageLabel = new javax.swing.JLabel(); numberOfImagesLabel = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextPane1 = new javax.swing.JTextPane(); setBorder(javax.swing.BorderFactory.createEtchedBorder()); @@ -78,25 +78,16 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere fileSizeLabel.setToolTipText(org.openide.util.NbBundle.getMessage(DocumentPanel.class, "DocumentPanel.fileSizeLabel.toolTipText")); // NOI18N - previewScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); - - previewTextArea.setEditable(false); - previewTextArea.setColumns(20); - previewTextArea.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N - previewTextArea.setLineWrap(true); - previewTextArea.setRows(5); - previewTextArea.setWrapStyleWord(true); - previewTextArea.setEnabled(false); - previewTextArea.setFocusable(false); - previewTextArea.setMaximumSize(new java.awt.Dimension(164, 94)); - previewScrollPane.setViewportView(previewTextArea); - sampleImageLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); sampleImageLabel.setIconTextGap(0); sampleImageLabel.setMaximumSize(new java.awt.Dimension(100, 100)); sampleImageLabel.setMinimumSize(new java.awt.Dimension(100, 100)); sampleImageLabel.setPreferredSize(new java.awt.Dimension(100, 100)); + jTextPane1.setEditable(false); + jTextPane1.setEnabled(false); + jScrollPane1.setViewportView(jTextPane1); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -111,14 +102,17 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(previewScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 587, Short.MAX_VALUE)) + .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 586, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap()) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 585, Short.MAX_VALUE) + .addGap(120, 120, 120))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -128,15 +122,18 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 17, Short.MAX_VALUE) .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(previewScrollPane) - .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(sampleImageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(isDeletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(39, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 97, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(37, Short.MAX_VALUE))) ); }// //GEN-END:initComponents @@ -144,9 +141,10 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel fileSizeLabel; private javax.swing.JLabel isDeletedLabel; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextPane jTextPane1; private javax.swing.JLabel nameLabel; private javax.swing.JLabel numberOfImagesLabel; - private javax.swing.JTextArea previewTextArea; private javax.swing.JLabel sampleImageLabel; private javax.swing.JLabel scoreLabel; // End of variables declaration//GEN-END:variables @@ -177,8 +175,8 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere sampleImageLabel.setIcon(null); } nameLabel.setText(nameText); - previewTextArea.setText(value.getSummary().getSummaryText()); - previewTextArea.setCaretPosition(0); + jTextPane1.setText(value.getSummary().getSummaryText()); + jTextPane1.setCaretPosition(0); DiscoveryUiUtils.setDeletedIcon(value.getResultFile().isDeleted(), isDeletedLabel); DiscoveryUiUtils.setScoreIcon(value.getResultFile(), scoreLabel); setBackground(isSelected ? SELECTION_COLOR : list.getBackground()); From 04d962ddf4ffbc2bf41cc6c38f895bdf53c326cb Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 17:12:32 -0400 Subject: [PATCH 094/106] 6077 fix size of panel --- Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form | 6 +++--- Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index 74b8e8bedd..3be707bb11 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -46,7 +46,7 @@ - + @@ -73,8 +73,8 @@ - - + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 4ddae94fce..1c2c41a2de 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -131,8 +131,8 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addContainerGap()) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(39, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 97, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(36, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(37, Short.MAX_VALUE))) ); }// //GEN-END:initComponents From 8e2bae77ef909ea4f04a198bfa4101274dad9e00 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 24 Mar 2020 17:20:27 -0400 Subject: [PATCH 095/106] Revert "6059 change file name of xml to check to match file name it is listed in" This reverts commit 026b6be3bc7951ef6355b2ec6712555aea940d91. --- Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java | 2 +- .../org/sleuthkit/autopsy/modules/plaso/PlasoIngestModule.java | 2 +- .../org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java b/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java index 12415fac87..e729248b47 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/PlatformUtil.java @@ -69,7 +69,7 @@ public class PlatformUtil { * @return absolute path string to the install root dir */ public static String getInstallPath() { - File coreFolder = InstalledFileLocator.getDefault().locate("core", "org.sleuthkit.autopsy.core", false); //NON-NLS + File coreFolder = InstalledFileLocator.getDefault().locate("core", PlatformUtil.class.getPackage().getName(), false); //NON-NLS File rootPath = coreFolder.getParentFile().getParentFile(); return rootPath.getAbsolutePath(); } diff --git a/Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoIngestModule.java index fbc4ebc12b..d359332f84 100755 --- a/Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoIngestModule.java @@ -269,7 +269,7 @@ public class PlasoIngestModule implements DataSourceIngestModule { String architectureFolder = PlatformUtil.is64BitOS() ? PLASO64 : PLASO32; String executableToFindName = Paths.get(PLASO, architectureFolder, executableName).toString(); - File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, "org.sleuthkit.autopsy.core", false); + File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, PlasoIngestModule.class.getPackage().getName(), false); if (null == exeFile || exeFile.canExecute() == false) { throw new FileNotFoundException(executableName + " executable not found."); } diff --git a/Core/src/org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java b/Core/src/org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java index 6a84a2285c..a8bf0591fb 100644 --- a/Core/src/org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java +++ b/Core/src/org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java @@ -423,7 +423,7 @@ final class TikaTextExtractor implements TextExtractor { } String executableToFindName = Paths.get(TESSERACT_DIR_NAME, TESSERACT_EXECUTABLE).toString(); - File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, "org.sleuthkit.autopsy.core", false); + File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, TikaTextExtractor.class.getPackage().getName(), false); if (null == exeFile) { return null; } From 93645568e006e206e5feff98455a5bf73fb98ee1 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 17:21:31 -0400 Subject: [PATCH 096/106] 6077 eliminate unnecessary scroll pane --- .../autopsy/filequery/DocumentPanel.form | 50 +++++++------------ .../autopsy/filequery/DocumentPanel.java | 35 ++++++------- 2 files changed, 33 insertions(+), 52 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index 3be707bb11..ce8baeac5f 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -34,7 +34,13 @@ - + + + + + + + @@ -44,13 +50,6 @@ - - - - - - - @@ -62,7 +61,10 @@ - + + + + @@ -71,13 +73,6 @@ - - - - - - -
@@ -148,20 +143,13 @@ - - - - - - - - - - - - - - - + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 1c2c41a2de..44a1ddd4a2 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -59,8 +59,7 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere nameLabel = new javax.swing.JLabel(); sampleImageLabel = new javax.swing.JLabel(); numberOfImagesLabel = new javax.swing.JLabel(); - jScrollPane1 = new javax.swing.JScrollPane(); - jTextPane1 = new javax.swing.JTextPane(); + previewTextPane = new javax.swing.JTextPane(); setBorder(javax.swing.BorderFactory.createEtchedBorder()); @@ -84,9 +83,8 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere sampleImageLabel.setMinimumSize(new java.awt.Dimension(100, 100)); sampleImageLabel.setPreferredSize(new java.awt.Dimension(100, 100)); - jTextPane1.setEditable(false); - jTextPane1.setEnabled(false); - jScrollPane1.setViewportView(jTextPane1); + previewTextPane.setEditable(false); + previewTextPane.setBackground(new java.awt.Color(240, 240, 240)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -102,17 +100,16 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() - .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 586, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 586, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(previewTextPane, javax.swing.GroupLayout.PREFERRED_SIZE, 583, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(sampleImageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addContainerGap()) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 585, Short.MAX_VALUE) - .addGap(120, 120, 120))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -122,18 +119,15 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 17, Short.MAX_VALUE) .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(sampleImageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(sampleImageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(previewTextPane, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(scoreLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(isDeletedLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(36, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(37, Short.MAX_VALUE))) ); }// //GEN-END:initComponents @@ -141,10 +135,9 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel fileSizeLabel; private javax.swing.JLabel isDeletedLabel; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JTextPane jTextPane1; private javax.swing.JLabel nameLabel; private javax.swing.JLabel numberOfImagesLabel; + private javax.swing.JTextPane previewTextPane; private javax.swing.JLabel sampleImageLabel; private javax.swing.JLabel scoreLabel; // End of variables declaration//GEN-END:variables @@ -175,8 +168,8 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere sampleImageLabel.setIcon(null); } nameLabel.setText(nameText); - jTextPane1.setText(value.getSummary().getSummaryText()); - jTextPane1.setCaretPosition(0); + previewTextPane.setText(value.getSummary().getSummaryText()); + previewTextPane.setCaretPosition(0); DiscoveryUiUtils.setDeletedIcon(value.getResultFile().isDeleted(), isDeletedLabel); DiscoveryUiUtils.setScoreIcon(value.getResultFile(), scoreLabel); setBackground(isSelected ? SELECTION_COLOR : list.getBackground()); From 960aad46a02163a630424ca12a7f8ed2d1f7aaae Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 17:22:09 -0400 Subject: [PATCH 097/106] 6077 add border back --- Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form | 5 +++++ Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java | 1 + 2 files changed, 6 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index ce8baeac5f..d46e5446e6 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -149,6 +149,11 @@ + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 44a1ddd4a2..cd16939750 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -85,6 +85,7 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere previewTextPane.setEditable(false); previewTextPane.setBackground(new java.awt.Color(240, 240, 240)); + previewTextPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); From 93fdb663c8096284e7f38a9fef6997111aadb91a Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 17:26:03 -0400 Subject: [PATCH 098/106] 6077 fix panel background color --- Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form | 3 --- Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java | 1 - 2 files changed, 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index d46e5446e6..d813999dd5 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -146,9 +146,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index cd16939750..8a785d95c1 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -84,7 +84,6 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere sampleImageLabel.setPreferredSize(new java.awt.Dimension(100, 100)); previewTextPane.setEditable(false); - previewTextPane.setBackground(new java.awt.Color(240, 240, 240)); previewTextPane.setBorder(javax.swing.BorderFactory.createEtchedBorder()); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); From 0fb9e2547e95bc47289ecf70e7858bc29fbf789e Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Tue, 24 Mar 2020 17:29:48 -0400 Subject: [PATCH 099/106] 6077 fix resizing --- Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form | 4 ++-- Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form index d813999dd5..6a5102fada 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.form @@ -37,8 +37,8 @@ - - + + diff --git a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java index 8a785d95c1..2a021ef47b 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/DocumentPanel.java @@ -103,8 +103,8 @@ public class DocumentPanel extends javax.swing.JPanel implements ListCellRendere .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 586, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addComponent(previewTextPane, javax.swing.GroupLayout.PREFERRED_SIZE, 583, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE))) + .addComponent(previewTextPane, javax.swing.GroupLayout.DEFAULT_SIZE, 586, Short.MAX_VALUE) + .addGap(0, 0, 0))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(numberOfImagesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) From d506102bcada1cab1a6330caad19a854e12d848a Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 25 Mar 2020 09:56:54 -0400 Subject: [PATCH 100/106] evaluated normalized path so artifacts could properly be found --- .../src/org/sleuthkit/autopsy/recentactivity/Chrome.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java index f194c6b69e..5b86b3b9b0 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java @@ -560,7 +560,8 @@ class Chrome extends Extract { // find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact. try { - for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(fullPath), FilenameUtils.getPath(fullPath))) { + String normalizedFullPath = FilenameUtils.normalize(fullPath, true); + for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(normalizedFullPath), FilenameUtils.getPath(normalizedFullPath))) { BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT); associatedObjectArtifact.addAttribute( new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, From 203f340ce2be65a4050f9d6a42e9105006569b46 Mon Sep 17 00:00:00 2001 From: apriestman Date: Wed, 25 Mar 2020 10:15:05 -0400 Subject: [PATCH 101/106] Most File Discovery doc updates complete --- docs/doxygen-user/file_discovery.dox | 14 ++++++-------- .../images/FileDiscovery/fd_dupeEx.png | Bin 158799 -> 193209 bytes .../images/FileDiscovery/fd_fileType.png | Bin 5108 -> 8637 bytes .../images/FileDiscovery/fd_icon.png | Bin 145915 -> 162305 bytes .../images/FileDiscovery/fd_main.png | Bin 458620 -> 488848 bytes .../images/FileDiscovery/fd_paging.png | Bin 121224 -> 109569 bytes .../images/FileDiscovery/fd_resultGroups.png | Bin 271086 -> 293912 bytes .../images/FileDiscovery/fd_videos.png | Bin 428386 -> 429675 bytes 8 files changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/doxygen-user/file_discovery.dox b/docs/doxygen-user/file_discovery.dox index a92b41dc43..0f9db8d801 100644 --- a/docs/doxygen-user/file_discovery.dox +++ b/docs/doxygen-user/file_discovery.dox @@ -2,7 +2,7 @@ \section file_disc_overview Overview -The file discovery tool shows images or videos that match a set of filters configured by the user. You can choose how to group and order your results in order to see the most relevant data first. +The file discovery tool shows images, videos, or documents that match a set of filters configured by the user. You can choose how to group and order your results in order to see the most relevant data first. \section file_disc_prereq Prerequisites @@ -37,17 +37,17 @@ Once everything is set up, use the "Show" button at the bottom of the left panel \subsection file_disc_type File Type -The first step is choosing whether you want to display images or videos. The file type is determined by the MIME type of the file, which is why the file_type_identification_page must be run to see any results. Switching between the file types will clear any results being displayed and reset the filters. +The first step is choosing whether you want to display images, videos, or documents. The file type is determined by the MIME type of the file, which is why the \ref file_type_identification_page must be run to see any results. Switching between the file types will clear any results being displayed and reset the filters. \image html FileDiscovery/fd_fileType.png \subsection file_disc_filtering Filtering -The second step is to select and configure your filters. For most filters, you enable them using the checkbox on the left and then select your options. Multiple options can be selected by using CTRL + left click. Files must pass all enabled filters to be displayed. +The second step is to select and configure your filters. The available filters will vary depending on the file type. For most filters, you enable them using the checkbox on the left and then select your options. Multiple options can be selected by using CTRL + left click. Files must pass all enabled filters to be displayed. \subsubsection file_disc_size_filter File Size Filter -The file size filter lets you restrict the size of your results. The options are different for images and videos - an extra small image might be under 16 KB while an extra small video is anything under 500 KB. +The file size filter lets you restrict the size of your results. The options are different for the different file types - an extra small image might be under 16 KB while an extra small video is anything under 500 KB. \image html FileDiscovery/fd_fileSizeFilter.png @@ -71,7 +71,7 @@ The possibly user created filter restricts the results to files that suspected t \image html FileDiscovery/fd_userCreatedFilter.png -This means the image or video must have a "User Content Suspected" result associated with it. These primarily come from the \ref EXIF_parser_page "Exif parser module". +This means the file must have a "User Content Suspected" result associated with it. These primarily come from the \ref EXIF_parser_page "Exif parser module". \image html FileDiscovery/fd_userContentArtifact.png @@ -155,9 +155,7 @@ The bottom section of the panel is identical to the standard \ref content_viewer \subsection file_disc_dedupe De-duplication -Assuming the \ref hash_db_page module has been run, all files in a result group with the same hash will be merged together under a single instance. You can see the number of instances of each file under the thumbnail, and each file instance will be displayed in the middle section of the panel. - - +Assuming the \ref hash_db_page module has been run, all files in a result group with the same hash will be merged together under a single instance. The file path to one of the instances will be displayed along with a note such as "and 1 more" indicating how many duplicates were found. Selecting the file will display each instance in the middle section of the panel. \image html FileDiscovery/fd_dupeEx.png diff --git a/docs/doxygen-user/images/FileDiscovery/fd_dupeEx.png b/docs/doxygen-user/images/FileDiscovery/fd_dupeEx.png index e711bc95ccc99b17bf8ae77c3e1501bfa1ae68e9..4d15a718e2bd132c5d5ed1ed66eca78e279b5a6a 100644 GIT binary patch literal 193209 zcmaI71yJVNvVe=bI|B?pxDO74!;ibWyZ*SlyAFf9ySux)ySux++4r7Z=iPc$uTrUW zI^F3`C2Os(SCTL}88Jk-Z*U+WAc*1sVFeHnumTVeP)iu7znbIOYfBIiI3{x;Avtj& zAtE~mTN86DV-OHPSVppolHv+h$W#Y=hg>{Lc;d9BnF1I9u>%lCPt632BGDZSLc%7j zWG5^iR|vyQx$T=L6jwtM9t0|1a|VGcJa2D@ftM_9RDrwI?sheiwng~lZJE_EwPAYY zwb%+0`yK$Lrsrd-F*4^Jb081y7;tje_)H0mNkLT^+;C8n>2&dzpiigVCDKx|4F=NBcc3 z{>eF6C(!2-SD5g*?@`q|6%nMm(70jcHN@H+6GZzARIcqKWI~StB)qoM3CYX;d#k68 zLjNwUDNWh>x|SqpmL(O#@zrYsVdKl46UwOd~ih;jOM9ifA&Ul;h|MXIAmiipVBJ+th6cc7{ zMw6dB|MRW^_LB%igdhBrAMY3(y&Iyj8?_k(c^e!|fHD-qUXN+pA0rl2mxR z(Z52Eq8Q348}(-Zn;nj$pW*gT4rqG6F+GTNPz6S$Okb*NxN&}zz@T9iOob3fBB5dY z+90)9ynS#;Ayhg1L>O`*K>!#g|5>&|F@9Z z*uox-YE&!8Iz3qqnCL+4o{?*24nlhWrtTy=a8H!WK-s>OZB#WlKEEPVUldfX+z3Wg ztX@&UI9D=QRN}H&w0tmg{?*v;`GhUufViSzO$;az5hgjQMEFrc%%I)e%i)8>+t5HIfHNqBlQbw)XKRQ@z25$2OO#mte6_%JWxE)JRrHFy#h#g9qk%9 zbhUV7LTUPyw>9i2>{RX0n{nIGHc_r3kq7Rs$8L!aTD0?95>cb}m{bHgcr)O~C-=;+ z`mau}+{$#yvdW#OKNi>)XiBRV4vXE2Zx$rxR~JO*H%nONz2@iUn@U_tw&wWFf13wd z?pvJCaFpFRB3Va|;a{f5bA}wPF9xzs{3QLUYIZq?Kb^ifyLdY{I$Ju+mG_{OR(X+= zQQ9H&7WkNtq&y@omR%=wls{=04A++sH(6|S&s6Bh>h$46-uloQ(8}UI=q~Rb$}G*YVeP(xz*fgD$yCOK#~d<2Fb;XxHW5NMjU|I67y%W5 zCxtebklJTu9IY`+7eEJ3*G8MAj;l7HXcFq|`?KReUSG*h#90~Ij{ zXJ~Db;UdWG##!Oab$GwH(xZOvx%`5ST`2iSGGZ*xZSd~-?%PpR%V~>))|qyJ4MLM} zQ-_U$i?&O&N5C66vKMluSi(?XQHg2kk-(Ix&Y})U6;jobmFc6zBb9Cc+EiP=$8^Xp z`hnsFa7%THeWhu^WprxOHfW2=r`{*_i|q>!R0DL~_t3Y5f2cdj&r2Xb8&Y6F0NH=S zU!;eZ*bbmK{21GIhj;{kKW*Bum!vBZ-1n!dZGVlP7gIQz7nFsT)fPKC|exXtAJE23~qC>ye80 zM+Yx>O5AUIB>-w6>>G0f%N=t_-FRJiUH({l%7qpiIUE|RvCv9HZQH=lm8p5(e&Jdj z=0AJMiV1f=*twnnnGTtZwt6iqx6)%2w_bN$I(`~G+B2Hjn$?YZjs-`fugcS<1!eB4 zXI1nXyq$x#6MhYW4d#|Ul=bwq44y6YCfc%bDl>m_YaYDMG$Sy>MF!Z}nyrf0LRTr5 zIhxHc3rnR5C0)s}B`YLpB(`i1Z91QmCRCGjy;kGvjjP9Vtfo}PRdyE7*4CQ{C{^jF z7zo$C*LDD*4aG*HQ@B&k+vW6C<(nd^C2J)$aJ5#njpZ5|PQ9EY9sp6Q(jFBi7lo@! zZEkH<=Qqo9Dn-hw8c#M=dRG(fU9Xc+dBNdczr8r$zO#w4Kl)6(wzi1pmDHc~dGC0i z_=SRdO+-&j(EXt^uCOc1ce>T{_uw3*k znZvB~UrA1dbSLtEAzzT+T+iR=omAfO)sf?4Sb3V7thxZ!zN$hAHBkl9n zeY+B1w|Dj)^cx`;6af@>2!2Q_1Gn}iZYI0uZunc$oN7l^W*e5>#q98V+|HT&lI!dJP4i z@z=d~`!Vs0{y^ZQ@Ez%z*w7Cz3I;x%XV-V}#e~$N0X~{9t+(<06_+m8cVYBIQKV~ zMUk>u-r!GxcW?Hf!DoLN63ReQOc`Ual zec{3>$?&q5?y=Qz#f!2{5*z=j7}V?Ka&o!$Cp8H>RMsB)q(7KYhbz@jCfCLEe6W33f|n`E9itzHHr8wR`niR%f!)oUf|}uRUoJ zhHyT0P{C}dwwpb8K7~9fitS8$ol|}7*0e$HYLj7wth&6z2!672yx$3U^rTe)TVVh-kx^S1w`Ez=3DMTysQ!|dc^I535#zjB8T##=wl-aL zX8qnd7qbzC0`0b|J)NSHxG9A?55!jGirHEPH!RvAv)k82fNufslKkVOZ*G0yk9#9|Ke1f5(VPa%N)uQOX;dC)T%5L4 z4^=51?!{=eMe#j)*zNB$=%#7T9Hz)1^XQaaWKpg0&R6;!RUT1$*u-xzAJ-C44J_Up zu5Wm(1L1>p&N{v>72cI>dJM%znKLW3(u{>}IKSoC(>8t#qzEN!`uMyWY?5;p057 z`wfkCEz$e@8T#%TYMSL0+L2`G*5N+t%`q8=X)_y@Jmoj!*1pxfw%p`H*LMWy`b_d- zUpA%DR^8FgPGd*vLLQp#Bq&?ht8=+9oRY&!?s_WaG`SMuc?&+}8nNB#cznMXJ*9p) zWNB86sr~x%<1`Id5!~x|Xthl$agrBSceU=EzS76-r6HvY=Bf)Cs}tdfX2z8cbpa@g zeBsyiN*zjYU5DJ495Pn>^#1a2wxj&q72TZ!%I@6MTyyJF&VCx5O!Cllsis+c`5C3( z;44n3TBA2_9>@x%=vT%9iPVm|B+|72$`>^W;5UY z9Y+?wGYcI5Xm~Thv-QdyfA<(X#vX2aC4|GRtFL81oWdxd{2L-?XgtwJJ+*D`CMBn$VXbWs7}7Q_0=h>y`fd z>xFUZ#ow0i7jk*Zoh`fN6pxK-v(b9=(e_+l`mbVAeo~E{^4!Z*MK^Svt>NAI85puNlwX(GS2wkr^WT zLkL3{KJL!id^9h$vDVryK?`>lR3&QK&fNXIE1a3$S4K{I-Vu}kxko%Lmd`gD59ck| zoeu*G7k_-*)VldTVbXn8V%lB$GdM@WK4NAyNgvl;LO)~^b56jY7#Ko_VwB-W?!{%U zA)ui%f=tT>^t00)dONfFl+}k~czbr-N5nzQ<*kOB#z$J(v8PQ^WZ9$MBO zYkaP6H0ZB;D7O1Y4j?V2eqHXuBB@0Gy+o~r&X2d|3sJ4Z(syNC}?6sC&S0|QQ0qj~!w@w{L zokHh6&iw70X4j6gk)_m-|XRg>@tp>o&2PbJvZI5?s&L2N@!G|+zi!nt=l`+cBrednDm^9X}GGS%y?U`U2co( z%0bxTb7{qhLM9BMn=5!u{{m(^?DU818Ex>rX+4y@RiGk(6AUpv>5;&XB|L$#ZW zvEQ#bk@%UpJM%%o!P!yk1^qmqcRjsHDukC7O~~0hw?vh-+3P|2_i>I9DxaxhSMdH~ z*A|Mc97XI*&g30Le?zw4;#1$Lb+g%2d+#I=vedS$LibX$CtWVPo0wlnn?maBY2BQ* zb?;z$m|ObIg8W?LoCm>PQFxPaT>ySvaC#N-$u=cnn;RHf=vG_&mejUN}17xdzm+s7@RJO1Oj z#>dJTr_T|gI(?eZ^)>i`DbmM@ow}w9M-F;c^W#%zvLcV#;os5e?|_~1+35KWNFr=~ zgCdZ+*_my)X!=0mdC#HN`f|T2>)hk>?rtl%@4m@Qlh}iqw;p?AMCDLc{g6N-lnl)`rdWjBQDFPypHBD+ z?Hm(1X@bYob=iEq4*C14y5r*E^$i^uo< zxe!R`0rdCht9QK3r!DQOOlDcfYF%W$i^`2pzuPB1_izf%(K?>7IuA%>Cb=oEsyTtF zU-JxY?;C_h4A;+dLnz<}e<^}bYE!%ud2ssA((1k8Qf2~FWsi4;ZDHj{jKgUv^TjdZ z!opIPOWjkBLg6JQvi-C9&|XtV7*oSwy4z_g^oLs8%-MB9)_Xqqa{Gt#uR6P{3EQ3< z?onx`wt*)x-hlRd+~+ZEJHl&>C2Ru*FDRJ}aOhv>RpW$q>$aC~o0j)Cq@h!nd-L6K zR6{W^(HmD#&JkT}e>{P!Pto^64<7B;WS+aAuD9-DEBJi=9L{`~_F2z|L(^?{tKLIz zyHU|pe2bfmSLd7smo(QELbg+d=`KRN0S_OG1a^+!ydV7*h%b^1TDrnupP>nFRSS+h zfV{kq5FvcL9O6~uQ65VT&p#TjOrC_C*5`ZBd0vf9HrqEzw)k=niFhus#rc9a8k6#N&nwYUFE$^XUdE3p4i z@)Y+(8W)exrz-nf=AElf$jw%(o#Lswn%Z^7#Z5bsp`oEStvk;aso@NF!G9n;(*^(k zP2~R*|DQAepRoTz`u_p_e=~8FKmAwCo&PtfoBxXcEd%~fMer}!4@D^aD`Nkf)IYfY z|E(APPwDXgpQu0kT~5|(iKclIq-ZzvR$E3L3j<4Ik*Fc9Ae3RGsN#IU50O8_2PA^@ zXd}P1qWzY~lRLh^HC;S?-+S>DU1W&3u9v=Us-A;%-|a0%i82gKkUp=EUF5I|bzWEn zIeYoubU)cY2lzZg1WLR8<+Tz7$2r`Vef!jil* z9B-me$Xlr|7zwK5%zJ>rjds{#_+K1VTi*C{9-xOH*lM8bqk3v__>{oTDm!ZPj4Aa z4YQXl30lnIQhZ0L7Sh%Ir~#o4Mr<;63p4g#^E#x z=(&633ia}(|Ukst521YCo)2k*=NVDuH*)#tdIa4SC69LpK&rjn% zTniqHh;DIfe*R-{=-`I|W=R&rh+_!wM>)b*w>dHSMvS3h85yf)DG$S+{nlh#S>6Y$ zW#YQM9fFgVzPV5Ll9-oDox%c>(V{$*xk2pLn5W>tfOv!hQSwVlKRr0tz!Xcgrp+-W^mMt_F z27&SjAT3}<-r^W252BHP`7HyRmX_AQ4gev;Wf7M>OzxJ+)HQG7>>cOKO;@#Z`X{k? zmRJ73$R%Q^v`?urU?j<4ceqxq zRFAWDBk=i%M|bJDg!a zZaR~_-Tf7RjcuO8M?cx=><5ZqH3#=phKtof+Ln1<#1Ss8^zo!ReUT*3-2?XT47%Sq z$Su~U1eS>AON`v6_U>_Ehm@MOY5NCrDPg1{ZDry|mDewZK7MfIDOHXq&bp)vDb1_N z^^;b5&Xq#*p~W#Gk*sLHT<)uiw;Z6+2XO53o0${PAwb1x&E_HOtwPcLy7lYxhxKhn z9BwR9Qpf7{Pe@1`#?Cc;U^&^s!xz!}r5mlGtyjkyw4-{QR}IvuV9*!ky}Ahxt8Xxx`LhvW0%woo8PCdNq?lEpV6nWmgO3#rc++d^a0t8 z6M=%Zlr=a8`!}#X5*2|0Ogcuvwo@`A`@X)+F<7}hhknn&Fuz^_SvYuNJ)oqz1S%!z z06Llo77!mu6p8|n1C*O$dNs^(3)=#W2on!!0y|^6+g%27J zpn@Z=9<2TCjKW!97Z**!fI>}@j4Cl;)Y>iXHxOqYf#uIXa4>6wh!x?SEC-oQ+Y2L= zV{VAjyOU0iL^r7pr>M6U%@IDW9!&3WTfQ{)&6JK(-CLI`jxrGqLnOL7nPg&GP!8e` zBLWi_sknh)j-1R61P-h`POZmK#k$K>$V#ghcnX%HiODL4Xf5zc+i?~l!@|ULYSxC1 z1R_u#F-4fn9?=s2Y{_hKsG$>08PK!Q+C6*+wfr21y?u5fwP(!B)j4Q6J zV2yxMV)Y)lRU<&-6;iM|Ug-(GKhq+YctdN(_~Es4`1;VSlVNk+!RszKjIci3cCZ-k z0BWz~FWr3b6rL$qx6o$Xu-u%(hWw<;xy8Vz>eabL+qAx!Y35YAC0k&3+EDhYz0N<> zyxo3F6Samee0a@J=hSHX5MtI#Ry^EI*$2s_hQ zQV^$Oa)J|rI$I1QuKKB6A%74lpd_>xKZD_>g5is}f_5L9?*%7ivMAIw%*HeweM`r{ zTi?&!Fmj|MaAwBWh?&UBX5f$N$;YIK1toLw(rJ2Xn*K*Cm5!xLi}e}@u#TY7YGZI9 zLNzqOH!3Qy%Io51S|J(VO($Z%M1n=no3|186t4#;E|eC}T&|*)$r_!L_iNGBb}B=c zL{naBOT94Jw|+yrn_F5LK{Q$BS=!|m51J!vQ}y#;t&9}1JM?C`+#usMy0w>=tT)cj zJ|MxasBj*XJy|uqUdh3+Gl3+XSO-0>IShn<0o%CNM6>4$Sjv=7s?3|DaH-JZ^msVc zc{Dgt6VW^dX+pTBb&6Ix#N?zhG2`2@1RLbp2Pq)JK_UbAIAs7hdcaw`CJ*Fn;;h#$_c=D>)d6n0MeQdqXRR3aN5Vo^OE1<=An*n0XViJGX`PNU6bX>}5< zIgOOgq({p}DUyW&Rzc?n7n&ESk*GJLmO@GzBn9aw73v?#Sb|OlE1sAQ28jljptz59 zfuNqu!pAqY+l!{2X&A*{8b|~K6X44)k(-U-tRMl#PZK3%7&Z7!NPmoKW(7a6@0%nF zTp;aeTA77|nD{g&RKzsO05Mj;2rzwa+ltD$p$FCvo($vQPUA?890lo?grUgDa@4Yb zG27^CRbF8`Uj#k?_{~s~eHurbjv$&Anw;4}JP-~eEDA*;4vR`32RN2Y<$Y+#H?lZ! zmTFt1)$W-pqe^Nd{Cl`o`bW{6HL_K zKN=;p3~3F(6lNF2k{G2yp_)5nfs>wfn2`ucFp>tcHNK$x=cGZTC=uhJK}|t6ovLMh z4G#RGni8g)fP@vM*GZUMdXI9h64)qgY^`l^38>dWJ_wCnu?v69Bi5rH0IId~jUtw} zhYG(jyg!r`!iW=ZMA_!gaah9XSOlxcu|%9X^!Sj%ewd#uVuU<$9D~7WZUG7s@ zC#|3!O^R%}-2t`yS#nq1u`C-+Q1)?zWGuqzgucM3olNaII=Ddx1%_&UtEZ^ymgfC~ z;+3jh8N}!IQpFG}lxR#lpX0$^wu5G5Cs zu1onl4Oowj;bu|e1|2zw6NVOV^CvGK3N;p!Gi5Se|1HJ~zX-e&xNCg*KEvJYU>>bF zMQCX9DI4amxm^E}SHAZA{j?#JJoh6`PMT(E6y-$*!JoEfy+%z#Fe)M>iz`0yG5S6w&}G%7$4SIoQ;W#EnxI$ z`UT9*J5GZPK!ReXgu*<#JaQ=g#Q3W*ENtfX@^E$lQl{(L?MFiFV6go+#Wc0>BAhTm zQL(1j$SdN|PXuK($0vL)KIFpIF<1;0&O}NEF;kkN*<}lvxC2KceEWQyoWZ0Zk&~gjqx|Wnf9$yC$VC+)NjGaFYJ(ssI^P@X zjx!f(kV{E~B&3AnAHTmr@0M&}EkFl10vEwrfLER|s4kX`=3gxuKYyH0H3?^BGF%}9 z2*ps#VVX?Vf1(}O$2|tah1jN@6uBqi0NYYl`L{?iW|!UlyJ zSg=M5i4~xPWcgD;NwL)~v{#N}dNwyBdl=ZNfF^=UooKcCbHs~qW2!LfEH%TDY3tM= zDpy6aI7TX-j5V@u9?$USkm$%omA`yZiN@FAxIcl#jD^lK=5-u^35-5_Se#ESp z(gCY-Yr4ouvj(Gr5?F`?gc<~#$P_u9wyCN6p1g|TqWm&5HJU?09#$^G*yBLraTql# zky3G>8Q*swX>4=AY-m#M-~+4bR?9bxj8II4er0#_ZtaTs5KX!)=-x^jM87tTPUhk= zccipfWv{-=i)|KX#_~-MEh{_8Q9W(kIqvogv(8YHSvC zY5)BeKs0#?F`1H5JDK*vAR;sym6@|4CQ4Ip>=pTTbj;c<@IfNq|#irAJtW=F{!^QV~;$AQWO{ zW}6f~hafH^E{8vdAVjkBjGt(4aMYQ4tA+WZ1&4LX0{o&aPQhj*0NCSM6hx0-L2Kyn zGoModS`dp%I~O2dHY6+%umX>5uR(%MVb;LCEGK6f9bbSANa^eW?AiQb9RT#j^&ezp zH)O+8miOWu=Y!U@FmfNdl8FkCG2at4RJAh#$mYvhPI-a`$ zK7%@zb4t?kj3lxFu+_2gu(@rk4M=UvH2Hq2RShYX-w z=U8jW4{8*Q!m+_HE;KXjKkFJw_>9c9=JSyD#d7v;8|tJbkp2KU=Tcla`0{v(=ZUjlKQi}-0!<@1F1~jCJ1mpANML;oO!V*ByU`ONegowsog+Q5U z2{bJo$iA7w;V1JglhX!A!gT;+2sa7jYCf z8P)XTDAUgl9+PEi7UeLA1^3k`mRsH8vpSB1q-3J(-6}=Ol4fuS#K?ka=N!4TXMYMo z5F-KFs4i6CGY&XRk592?1@bNGH6?Lq0e*0!_!j^b;@fO|njAP3W>JlRq*ATj-doXp z#$+vQqtwEMkx@*5W0>H8S)GhpiDU(QBwgRLA6zWVPh*=ZdnilRN!Wb3etAJ1$G`2& zjVV!8-NdCzO0{M(39N7B^G~tXiAIWbXDWNBdyt^!91(v)suxBeV-vVMOBsU7ZF5US0pO?fwbI7t=jG(f>A7d?v2K*RLYt>vi4SeXFOHW6O z5&*S@27?PF$fjfjEnH`x4*bX@7nlH1dIQdo`BdVn<|EhEQ?Fa6IcgQYtuO73S_my~ zqhJM8TBJaN=K9I!`TQsqT!z;ixZ~ecOs6>VZ9S~@2a2VgwH`=VU#7n2ZNBHpaeA_ zB;&!Z7@h$3QKj7S1P8msqPEf9AYwZYFf(kU%h&Ah+tznJbq%fVRsXJ!HSFKI!)i_T zfh8sOf+aIAU|~PY@oo(|Bvf>F63 z36fUJ=-eoYmaL0hO54NCaEA7VqPG=Ake@LdXF|1CZqIb3kEPMe}+>tc$>5Kb^{E<37W``J;O{pf63-x%J_wY<7Dwe z&_yCO?}d1WSijj&$e^8yhsvR=QK)Iur|V!l>=aBX<|hlL>{3k8`uz+XMePSYqMzJh zZ2#&=YX&aS)u*hcw>bo@Jd&`~1ryo#hY`t5JEDj{k>fv58nvU!M<^bG+pXr7^DCo` zYlPI@C#(!~=TB$F9@Lf*mw{@^d^;df=a8)695{aDeUIt7V^DV)v#E|?mrqD`;nDyY z@hJmTq#Ge%>M`^pysZk4{O^Hb>5vp5x69>a@%ti4ZAbhXA*hXT$au3nd4=%dS_x!W zG~|9tIF>L$=SKlS0-=Jrr)Z||y+pLw71=3QaBj(YPBLX1#`gAMWh}t_Ako~=_)tdi z;wALKp}}JIKmGO{_tM- zFsYCRmRACU;=n4n%`~GK3QDzOR&$L`;1z;O@bVCU-R68)t+l7#)v3zM3#vHgWH7Z= z^Wy~nOxqK-my*ZWZ!xjh_#wzS)Z2>y7E}#6%W0(&YfQD6n1Bd>#UbCE2Aog3ypK zCCbq#F-eS093LHWQi5bt3qdQp7)PnQl(wmx61^?Lf$i`p;JM}vPl1fa-g~~T34(ee zxT(#B#4T64ESG0DmnfXJ?D3YSj&xO3t_>MA{8BAa z_m?VV&PVs&r3V&jC?-jSseN8 zS+*2*s%M$>d_Y~;pLip2WXU56g(J)XN2Y0sy zgjl~XICh{hyAEd9pN_kTvR=gW527aI(bN#eAc`1be6tJ+^=Si4FNi77`C@hG+#qdc z#y;69Wl}2SWfEUr?eh1>f$Tf`yr`wrGOR!Uv;;A0flBNG14i&cOlFb4jm7jTiHHDx zkXf1^3r@lGkDgFE&%1>m4^H6(cxiz)fk7f8C#kSH7oNWjcntF0GBqCIew^jza^t40 zN|V+I&nElx3$ml4>xc6i!yD|S398V-wPENM>zqzX$#E^OZ~7U zV1h`dvB(t)2fHl-P=cib9O3qHcJ`;{e!l}}SMD(2ak(3Ril2rP6+6#ziJ9_bCtK;? z^z!XC*!slDu#3P+?4WQcAhsIDO3Z~~;{8FNX2S>~yD&N)ubmzp(T3X)4|prP6to+Nn+b*WWBqdg=i{)25}r0Qep z3%VgpeDDXw7@Cd2{PY8`k9HC1Jh$BWLBsTwo4JApo5wJj{ntbMdj$=JMk&wQ!Fojx zV^@Vk2)qMbsFMO*b}qlAbT&i_>wIo3SvbHTNP%e?KZneI9YXU^OM-kf<61;uM*IW| zH$x^(rcAnQPQ)@mSgvXT){?1#Ouw8{ux^GZ5;zZWB4B;2WB zSUesDvxNCVOgzz7de1Q3T6X{g7xch15j;zW#opWpsc_azHoNY8pusp8R{Ga+YQS3jdHX%Ihf#MnU4FDp1 z!9X?Ijr#MwpLDV;FoC_W0vIZ8<}&o( zqhH=bIJNDs%vB7{uQodxX;JuN0xLT5;5iod8Jq&4mN2Y!xe`xYn;DuH4M+{j2n+1@ zUlIrB!HUSiY?6o#6BRHsRjHIrM9;bu=fAceThBOhq7S5H?uFh=ww;)^wcwdAh>8=i zIfKGsv;q+jepsRggXYk(lK^twtWhivOe*cWc7v_YmQbe<4l0o@3GIX)T5|HkK9wnx z*N7m5uF%WyU7Jh{p=Dj{0yrmamBKoel)iJ?d5FmjWZr{k`FqFzH%gkQjk&I~^oed1;SF=JRP9lqh2!fU4 zr!;N=;zZI_w-U*+w7QKdc*LociL5RdiTs_NsDUe9K>IfFO&>?TY+-D#gfa$vRwKYE ze*>X>P)+kt+9Ci>Fh8M~h(EAYi?S4vrI#~T4J`;1l9-v2U|tFP-~{pSWJjqZqQ{Og zmApc36!91^yjKoKF@r-tR46PFD-Th{OamSWb0Q}ZKYz+W+dxM7q?j5=vgF7G2_`0w z@jDmpNnH$IY~F%ZR7`Za-5Z?mt0v22qflIj+sDtDhTJ?-FObB1u?Fc!9)vZ5K8k$V zQnfPyO9}%EJBzG`c^D(waV{l$yfN-7>;X_nUzs2pTogJ69pAO$u93d^(P9INKuCiJh5gePnM&h z>Cu2X^Z1tILIS1io!f8_T(emtSNSa^HyjK{J_CZprV`=;wzjkT#QON#vM&oh$yJM5 zA7@e{L;HTUr(>=|fl8@DjfN4YOB705Tksi`3WuHzWo(;5XQdPy&L$>bwTB1g(Va%F z-AV>V^QXM{C6wUVWJQLGUB&ylWy(=-;%__U-x@HHG_F7G-t?PSB3*3j!6?pAywE}$UY zjTy`3Lyz0a8nyoZNaw|w2!9G?;~(thz!{sYhl;UaIv_W1ZC00w_iW#f7qitxC4U-7 z0)P;J$&g7QbL_7n3AH*QF+Rx03?U8F4=7$FJ2xwL#oTEXCZ%Kh!PxfvR=(!xd(q|{ zXtKvg41*~y&BVEwJ-1ko#r(Mbi0a(+1@hWLaZ;ZgY5|+^2qyVT(zIUdH-RVS`gx#g zhxCJDum|oig;vv+KqwA)*iiRAjJzRO);7GA@!QbIE2EmN$2D)HFigCcDGD(KCk;lt z_uJWz!PFMl;BkPc=-K&dQxJ=(ZcakeaBYTF2QR?l({&;B*5F1sOFYZ5L2iK^hvZdhDX;L< zpxfUi!u}C{s}ovqWp(>fesZN!A}Gc%x~t4`Kgtv#@)L)tZEMbBl4b17rT41~;17jTlWD`5OY8jY2@ptK zH12387-G$%fW!~(1jG`kYE|r#pt+;kj}poWX5^t(Irg<&?l55peGUl`Xo1xE-^J$R ze>Y<#wbeHKm{7dU4QMz(`er$dY%AG#Fbn)Uqi>HYM+}`yr5|4|^ zjIl!h#f;Qmy2-A<_xmO*9TW*E&B0lC6kF18Vr7bG4ReY-f{%B_tA`j{1z=Gtxu)+W zs$=7Qfoil*-w>iQW$9$z_e{*^4iBLXl4cGm_*Exy2;mTn`GTX!lE+5?Xk0i^sQq>v zZN2UJ&ST0j6~BJNR5_kL;7DEptg1FX5_?8A)!klb7BWlI;vuimbg|QH?&m9?s;1Iu z{4u8e)`2K#Kxr+=XeYI(C*g;8NnYbn6{mK2cgv$B&#TipQeDQ@8`c2S3Buu$&Zf}8 z<#-e?cgiDzV$TdyuDo**Nz||`VYQU9!WUX#-VH8fQt(BjgcGwMAlV%3FARvZeuhzq znzPZ~xoxR(xV$Aq6Rw+23m$YGjn23_NT$=owFLB5r+ab{3`HC%e#^sc`Z(sxSGT>@ zFbp49;Y^Pl#jmgL+wwYttD2XYyEr`GY)Oq1?Mc3&dc3fxu?Hr=|33hNKz+Znvt)Te zO|^*Xb%MCd{A`Pf4RtoHOG@E9S`gR9IC#W<*EZS< zXK(`IM#4x9Y7N2WbsPDM`7UE4HH=N!w0R@{oSxaB`Yl5)(eF4904gwBV*mBpQ7GeN3Bt#J{pq5yEz|R z!5C0Am>7>4wc}i!8^f8c==?>(puk#L=ELcn`F59Yzu2am75$@KMAYQY_x$&4x^+L3 z8#Zv?1E1v&{?(^A{`4RWyD5SPNpjl#EugftHs=Y z>#dB`M{zS%6&ns}Y+>M?WML*{%D+(6d7VBb!gi$167$dAiJ1|Ag_~;0u zBX!~^CQyQ?mJp9eOgT-r)4}QTw1K7e63yBuV~r7_ddTg!?`GGIom`$>;QWP4)M^cy zh!wrz3-gw`ToA4g&&njttHD0bG122dB#v>JASXpog zR1SfODHuf|4t}qhp8tx&+EC~2uj|b3A*d1HR8xQRglB(3`#%Y;?O_b;rcv8SUf{;@ ze?t|kMbgg%4Zp$~NBQBKZxZR0+PN2~9@D(~jnCuxAxA#&2`<0(P1GRefd?Ps^36AS z?ebgPZ1xf5l&|kabb?iW`2!zkqgCg3ufN83;uinlsb!AIn2HC&#ACx!p#v5Zpi>;M zySW2ne=&-LvLj~RxoHl2D9;*)$+*!teyBwihd6LCmKz9)bc6}EUku~phAgZ&K=s=D z-1v7rr!->r#A7`2{4b&O9^K9lFv&HNq(N$8;#3ipPT={EQLR2sSPGb5I7_W`jx=l0 zN&lQMT4eRur#P~@%F2SG6oEldZ#b^qN{K2VFZ|T=c%^`n&9D!@MDOaCK?nj*leD(L zKg!(PCfC-t+1c44?m0GY?xK7j8ThOmnPKi;kLny;zP`utlXKkNNZ8xm;plRecP_6p zyRUfY@dZvlP{Z>Byui|^!{%0pPOHh~i+g-v2&!@lF!fwA9Lr%EiS+FPiXi4lEI*jiQ^($GCxfznIcs_ zwyc(`l>G*t*hI?HC<5Y4;RO|TcDC_LM+tojMmHje7O=^2YSk(#n!{Jiw6|Wyv@f&2 z7twh7#Gv&^%0&UtO-P#vwT|T z#ura(LS3QWY>~u}4$p^fBJ+7P>lTPi0%lUehOh#s#tXB{@iG=i==&_JKF#L(x3THl znB*?4(2>-R!vp{Adk0F3Abg3&7P?x6D2z(B7;)xfC}9f_jzr3_uCz$gpIF3(q1nU5 zF9*3!Se!E`{M=dT91d0F)8-48Rvu1Dq^D56hv$1(n_+|{O$>3|q1kE@_j|;He(ns< zPY8HYQ7T1vI>3v9+?12X43Y%l1fd_Hq#%?Mq{LW@(K2V(ga+Ry2uhTc!ViKx(^g89 z5IMNAd4{GRcw|` O{q;X7=#3XSKYXl~ZalTLHxx6UBI+7#@V{w}0u41)<40u9va_>I=m#t; zE>Yjv${p!Q(k#W3&~7)0lR+^ZP-Hem*<7xaB^kOnd>dy`R)a7&Qyfr44iHV2j`ByH z93J2tT7j=6iOoUFAkEOyAXJLy`Cwh1VJgV;Iz@h3(IS_LNIBh#li^T8lerA*B%Y86 zrHTV$Zjw7VrWOT@ct6(g-Pe##8YYK;K#o{FF*1~h`ys{2nd|f>FAm$lM*~;qeza@+ zzV>l(K=fyewjep>$rcB-j!rObX%b_TQZbDghwM+{Qu&kJ?UStNs0C?g+7e6#WH~pC zev%WviyCEh-X9Q6mlO;YqC+5RrAOi<>wS+eU2mZmJUlU=qGu@yM`_Sv!}zQ|_Y zHE!LzLFP;5AA6GT-?+$bFiUd&F%6)9mSV_}Gtm{@x`}s!9VMe&)a6)Pp}mCGzNX zcW5`RvVQv;?9@L`zqgC8>$FNOij_0xxq9hKIVeaHqAccvFFnC4e|d#|KPB$;smzwB2a@Vy znbcXn@%7uh|EXnq9m&?_Hs{Y(IC(OnIzPiJ-`mBLibvje3ZX1YWeBRQtzGBDS)XIa zSGaVs4g|dN?VBvDRCwUR63S#;zkG?8U)i9nIwY|mTwW%eF|1SAC%0;o}MQOf}F|dHZHLle~v5(>CQgLpua<7^EQpWOO&Et!I)({ z-=|zY&f?O?*(G6a`6W(Vc!|J=+i&~o32^&9}e9XMX>4eDG7Bjr@e{!1n}!pKHrzDrGX0V1%QW zCL~!x635h=yWHKmOW->Og9IrgzV^_*htraoDB|S80{vz}EG4^xP9BUd9Yt#TNP{!l zFvLV4wG%}+alY~8(LLjVgp(c6O9_G4BT;>t-4Z2r40!KAsZu#ea77w`n`m#c zLga7oB9MG~;~cY2lL6Y+<~ftYoYvtuQV3gM*YW6d$eenfN9g&?L?s@%aE|vq@+iy8 zO9XyEW)jl0Pu%aZwXx2vI~|;h^L)!euc+Acz*N%?7zKQwo$Gu48s25z#6yyU434AvGByBdr@p7cMx*wN3)3cc+J1Uq>j*ZjYK!h)LucZ#f#p&2xNd>Zx$S6U%o`Tlp);uy^m0C10mezlL?6C$j-dOBX14U9#R?N^+0onKK+&c$m3T z1P)qFSX;MryN=T*6$=ZFN+j@Pe!*e`;cP&uQbh=b5Qc29&)PxObZi0NI9}K(4HTYH$dHFq+Vp!=}oJyoaYk{`p<8lT4LCk*R2N=^R8kR&+ zW0*G=mHeDNQc6$>BO*V*;fOn5XYJA(2z3VOs`R@1c!B2TI}0ovf01%^f!%vINa9HAO$!D1)}6>8-QRbS=RnMx2_X!km-@2s=eZ_(={$jrmj zk}y!}~5TtsWQ9CS&U#~vvoiqUj2s?LVje;B?2PAQg` z=b4|&s8rvFuxrTVI^DFvcE9%?Z+mKF_!rg{&x;r_FH*?d#^nmriq=?R5QT%<9#}$# zwT%aLMQ&n!$|I!mQIRe{My)o(OE0{iM?dfao~JQsM&IPGDYZ{Dqq$I<;q=LqbUV9T zzjlMyFI}S3?10Oef9d7X3{ED<07!yJqqU;j>XNiubUQ6d zrI5#;eio@UcW$n+y}M6sZV|10g2*ST8Yhwo z?WaYHe5zoP7$a~ZAI)c(!)GM*Y$B;`^J~4JoGHHAN&-x>dS~LKgxHmzD{ywgTM3zpRM)yUr*I|(o4~W3Cf7cK6^Li7aFIn zO#VA);T4_KLJ%sCvu956!;M$Cxz+|DSz1}7y}N_wgXbl* z+6jpQVI}=uz|ztjRx0|vj2+P;P5M};xv^GfWvNV>W^}tLcWyT5?S*Wt)mb?m;e;U! zYiL`dW@7GLU&Ag`xO;n#db`a0QkkXM5;IW=8%r`H(E2cet&5YYM3Bm{uTmDk)5D>L z%Ye*pj5u^I$t4a(=77{0$TCB>vroT&nJl%KEW_A*!BCzg3gg#L zd z$k#?UHWL*Os05ClI>s{}{#(?4|9{~1@BTJkIm6io$-w0GkqA%_lp%-&Hj|XX3Q-sm zXonRseKOV?9U>WX>F#y5+WTagB~+3y^3WL9hi-6;k3dGa)J07!ecsB_25XK~9~1hMAcaq`AR<{Vyo#yR^Ie@A*cE zE8?r%IN0A5f2T1y%Opf@BD29LWz6_m9&S9;gTy#bLRrX3ZbXL36<0Z|=kRim5A|;a`52vgo%S0)ZP09x%L)k%Zr>ka+7fd(jhx9#G&s!(1Uuw?Dj4joyy9m*QsON3fk8w1zLg0B+bSqGRd&gVQdf6>oDkT zVB<@a%MpvEkXp&IzXeu@|lyWM6! zI?HUWhEj%<0pK6f(kSwpPH$45Ar3DT@;+~LIqV89SXNscOpFtta`$zX#kfr3tVDW} zBga3%nFszePM>@N&$ZdQ{dwv)KTBr!unfRcB+_Et0`;zBK6;Xw*_Y7aHP*iO50KI# zgFaGkVpW?vTc6`h{3{3%;Clw&6L|#KR62EJ9fVPg09CnN87Qhz=ZW*C$OA!hVm{#f+Q#Yqa-T?02_`U5c+1mC&bB4)gAD z3#m}VnW3Aev^pt~F6RXR+T{j(StNTpIT~jPQ7|u~20L50^~I=i6C8mKn5&h!e*4?3 ztUk@$+*#(!^W1&=D?I+tM|tb*AHKJ{pvm%tfP!(7N|L$!fFmcyEwV^DkV@iNN#e4p zZDu%%&cW${0)f%8BqmPAW9?oThMYQnlEEOR-|L~YLZI=aL-;-_@Q_O6Rh_nk3d)F5 zLKgQ~)q>etncdxeUVZ0k?g-CfP#Ti~HgA>E+C!;4+}&omdp}Jr&i4R`uQi^pvDT6# zF*Zx{_$TsaCucJT{akZf78>nY(##^1A_{zbKfq)e+S7R*sPHHS5pjEu9w`;SoW~() zk3i;aPR&k-B+2k~L?tZKXm_Z$y3Ehd6GS1}_t@WV%}GqDa`@y2qd$<5HV<+*^yu1}INqoh40e{w!FRSD|8&70@RC zyiE<#S+tN~EuM6^VdGN)kUZrfY?42hSQ2ZIaUK`uYll(^e&C^OUJoin9)D+z8$EwY z=1$PG(3x7qC^v2b);T!86%#Am=_~s88L_Mxw zc?0*6Ptg}C`%%c&@-mehHyMbGmmYeWty@>Qd-W!Z$5+uW{S@)_n^d!mY~vCSH}?={ z&U4ZCNZ-E5qfv$Wr4|?8dY#pNgCm9Y?)sh$J92!dZN&iAstSM~_kspxx?H zo?T$Sv4g~8cDBTgdXx7*c^;)&WSOGg7+`I{OeNy=jaa{g1i@+ z1LGKD^8Rpn=q!1^v#k4(67|$VH-=shI(=xjEkdX~gt{;WNa-;%bCwe)eudMgpW)=m z3gu{yBd7ib+owLt`qe+7eebJeW)q=~BFj&cT7%65S=u2r0|I{!>-G?`2h!mO4lUZW z>ig_BX6Ury+&L@qv8pU8C~Z;qmq)fsQUh@e`#k|_j#H2SBE8;k)2YWeKcQ072&WK6 zQ>_Y?&(x?@LLNG|!r9|TIJ$ZiuUx@O!{){|Ce0W$J7gFYDryt+g;z>hG^tSJQ0Dqf>+(0Bv=U=%ac0k-V=V*^u2%TPPy7O( z`P?7ztO6~5D4g4vocW(0IroXM3{LkR&Zyy%Ze;c{`cXNExGik2E$o6vhfPdDE21EGEsz)~e(a z`gw6eSTs2G`ig-yAT8QgC?y#b@k=-u^m}-IM3$!X8*M$+#ggMbT< zJ<0h;9%g-Wi!0Z!69qL80rQKCd8fSR6Q>DTk|G2IK}ZmU2LXU{uc3U|M{OE)4IgqVEQaSPDoFD)n7y(zZZ-Dih$_s>`z z{l&%qAJmSzDPDR)Q#;CAo=9eJx$tVBYuw^}eC_%@I*Z4-d*yA^$|5(`*61`F+}gZE zZ?nX_GptlAtT=~DVs^6*ufF~U!RZ#CI(~{*zV}TAU-)xm(&zn;o+IqW>|A`6PNzlE z>L5xLs(#3S_sgH;AOEAT)4#Vt7)6{|IKis#b1W=z^YSaG)FYig&A(}NSgJin#8Ez$ z{gC7S9-&K+B!x?U%o@9q{IioyP16DoIi*3JmTswWP3(waEe-+h zN0Dpp&~q#Q1H?4{QJ{3~&9Bfiilx=3SejYFSDM|Olt%q7$~8bhT4WyD;-OV&Jf|@O z!M%G4$Im^)b3gredGOp4zJ@r1G?6r#`IF!5IySfZY;88#-`{0ruF7K4&EGhwWoK`f zy><&NJqB4yr&CAhfM=e6o^JOp8{6B+w{CI%e3jdq36DQ=3L!jh+}WUae1&o-(W1iH zbDFm<-@~LC##Xp?z0IK8X7%VyzTv5WCmwx-KlM4YXI*g<;$yA8|!zNOn&blWjm z*5LHn7icuj&}`npnO#by8T@jD2sB7b7&z$;z{%Ior0Xl94(Yry? zdW(IP(Coa7=j~$LARl@A`3Q41N^$)+Xzf+mxc&x-P4nO13}Xdy7iVHDaRy0h==249 z`x%>CeOmP`?(BVwYT40j8k`AOS`JuVg+P|+#BHQ(61$i;uJ3c@_D#;5Iz?tOV&~E8 z#$Xd>L+F_VB^9;MXJvi?KP=Je^=Nea2$wT9D(DCu~siNT)i3d&b2#Sx&ocO4*%kJKTA}ZWzcuIgF9)xryJpDfjQuB zu-1Z<2x}1%tSais#l(niDwx|%YzAV)SPeC%!;#ITqd9**bGF)ogv%-@FGL4rvbe`X=gxCf@+DS+C0`;_8WURE6_T?(|wYDj203p^19CBCyvtE z-9<`4r_;pqB9IwrmeK09P$K1#_dUTQk331E+2ZESTkP)db7ZxKbB<=S#r*sN^YimK zBvuHN*5CxaUWZPvLpiPzh9P083{ujpH%YBU_#TyV1<{YOR#PcSyV=gBEQ-> zGLxaLCN0VqAfNVFDf8z^=W$#N1NMg+W+;HIK-xklUBpxkB?AZF6V@31D*khaj7wrv z;X53yyF+xtfzYT4VD1EmM*Igs+)y4c^|8qqp#y#OhaLM9S)}ehf`qB@?&M(Djz3Z? zDfS@aDej+@dPs(JpX)d|hX3*5SM~tbc2hXm2+fXqi1pN?We4;(Z(#cSXa)QAUH02e z;(mfEN9?Z7Q+w-s+=?wnYZ2bjlgyqv%CjH)1%Cg3`5*b!k3PjW_SWd9iaTH4g}MF?@yZ-~ zk3Gvj>1}god7j@mzQ6_XCV|L?iLlf6V?q=>)uc7Crn>{CRwnP)*eS=4juso&!;VrH z#Ms;>38~=%;SwK7pd>=vQToAFf7dY%vJ=Q!7f?sVUvun z{=19Jt|)4AHA-HDG#)}2_O~097s~X-06$dh?{%>Q!@vF)f5CiB@xpe@nR6%ENj*%q z##^u6;Q60tmDP_TgDTD4ZF<|Uko8_8?K`$QU&HzL@MNDrO7I*;3d+7_ex^-i{sgT~t_HEv${6J+a)xO9zh#!+jBG-HbpDPEA`ygnsA zC6Ia~bWco&>l<~1wA890&n!I48=Kc@bW$>x5J<&rb%t_S!3)du5`&OFLgZooCh_St z2GrXD554%a47xw08aW!xPQK7fS9HG1+*$8Z^w80njo;Q1g)txp0iDe9#V@?Wpchb{ znWLLIe&yHx9;eSf$*pT&=FK-h``)rM#ad#E380c9A7P5I=QJPe$zq6R3oT);b958# z`%x5>7>@Df)L7pki^w{O6nRsR^a31$X1BwtTqTWTgvd>GqL8Z$>p-PcD6K|j1MO*? z@~LVctwTD^J)KIVQktGSGC?rV@VdxWhg3iFuN>XOaGiafSJfE(MkwP+CiqJtwqunM>22`sR zWNhj5y3{Hqw6yFr_n9e`iPIEkWuc371ir>(3CR3f`<{=;4Ektg<{On4dh@a{`@nnZ|tyTG&ikAM^#SLJg%K7rD6@ z(w{j6-CeZnVDH_aW7}NX4*An{%deju@W4V;G$^`J!oi_~$Yhh27&4+_THPt8JpoQk zGVi(JPEHw;#Dv7xj`B^%%3L+gPm5_Yn>b*1%lDpl+30lsfwOGS)>ym#4PN=e-=o>t zWsoM69Vi!*rIK`z5XvQ1k33G6_EElMe&z)08#g(A>Z2?jS*7AjZ06W$3U1y?xO?X| zo$f6*w_m0|_$DgbLzzC(CM2d#I#(r4GcMoSXTQ_q=?6|QNDQ5Jn=~yWbV#QiBbB0B zaV%C0i}R9`$II+BGSWdtW4}x0B(t@nbh>TkS0g-O$$Ss2;RDY-!Pe#;@n9FNG{5+% z$9VHwm#`w?(|_{sxVqis!Ka?Y_ciramv>&h!M8sDP5$~vpQBP+0D4$4hY0^>AJXOu%nshTiby^9uqM(FJ`)i^N>|FkK0Z`T>bAxYfh*7~1u_s;Lp z@2^vhdnjeee8t?1rni%kv?X3>a;Ls@1)y?y(SQ~hn-FMCHJc?|^kFY$(2w&786gP# z2q8V3lMIp!hrmN(@GZ(@iUg@FYQVUYNc0nJTI;~wN8 z%|2Shiq*lIJkeeXl@I=g3*6*BSd9Kg5k1a~QXNJar^V`1Z#D>`2*1~*-;0sj!(kZo zJEV!p8_1kN3WZV{;pI_f#$-65iE5g#S|jbZa&X#j^WcMzaB_K>iD4t247$W7yfdo<$3gESn0F|h=dgxzwEIsv*@qGwbszThFjyT2bJ+WS zembg(` zNnZT08%wTl-C*PLv-s%H%s%6$@YJ{a52$4>hj^tqp#6;HUFg8nw zgSGQw3P6q{$EM9qj%=I)Ap{6L^feV3w!@lRIW38v;##MhryOzwXr++vE-0n!I3CXN z=nMY|Z@#=vJH1WW6O@%ki3))qV#6B8ANtQ(KJsEAZg&j2lA!ViL3o5#-Lc_0f|B6w zotRsfUS?zC(KEjz%M4X*HnUZd0k0sc4DtLXs3BKR|hccC*dBjXQXO;mqn0 z+Ra^*hF|}iALq-T`y#Ksd6Sma_%pW&eUF*)BCGRf_{1mw8aLnh9>*U!g%dj%v5IsG zCoHQwYjEkSq-mS-g@V+F>-Aca;7Ht+S=zV|x9*6DS3 z@xoo^=by$&53L-1Yw2}&ac&Re47fV&-q*Qusl%Z2*GbR*G>h2`r81x_Q7I&>9>uRd zL)`CS<9G0a4BvC4CL=X5Qc1KY&?Q5v8)TlMq6AX(3Toet+}l`z%l6q`|2lDZo;ZD- zxc_Ga{@q;PB|@CDq(I<7W;0q%MYJf9#!(IK?f>Ap=RZKLT48a~Ft^|nrx5RF#BrTow@I4x-_vc- zlervWQp!HmbxB!_QW-ax2qBO*-?+_ab&?b2hw(UWc+4J-M~hTR3aM%y?V}Z$$=JBJ zO|LsZDUFmVSVP?Fp?!-NDqPklA;r0rFbwf^?y%46K_RpGqUU5lR9T>B1uDs?E+6CB zxdj%N=K0~9Z_}5^^YjGotZ4yKNJR3vm z1eIzH;Vi9YgLsf2w8!%5D&1a>D2nKG2W)O{Q?1s}I%2jq&&?gxUO{k%?lnC=M-BfgnZ6B4NP^tTouwV1-~18>9qJNwgGLlh?O~eo!=} ziBT=B=L_OA&cTlpD3=?nqySyS-(mAjUzq&4Qc@s`IIh&?`dcT8ykM7WHl@hp?nYYb zp?sxy@U@U*S-^YT=#-aB4BhZzWLg^5iaIfo?RNl_jvK0`$I$|D$e%D~VJE()A_shI;@r#rgWDaa;e1GQ*&Ityos*_ z6)zxYY_NXun{+xUek}RO3m+yZS9s&fP2Re@OTDxNLept0WOW|V+~H1phV#c}_}-m9 zpLjr0_J<+=b`qB34#e4yJ^o>qk3P-Z z{32l_5W;fvT8o**lPn&6fXYmO)X=CKZeF><{`NnktgjFS4LW9kO$13Mu*Q)Z1D>N4 zmTA|!^m~1L8L&DV(LXhhPEwSxWCHH(HaPd_V_bb_lf|W3JWmk@4iy+~Z|vd+A&Jqf zZR}DhOZvMV`f&^@V!l>kcXOZPXG*NCZQx8s7%cE}pZFwy@Grl{;!?ngr878HAxn3d zi>mCmE8MxAaI{tdVK8P1y!_5AwD!@j{wabE%J)d_T*0f%Akux@%+ds{K7Pdc8D@_?$lS^&sZ?jtO0n0>*x7DzZ{wR}v{49*4Y3B2 z^fH?p|Ata|o^t5}l*=BaNa73dqY$eX=_Ec$-%%DClj_`g>pQ}VL51K)4y6-M;Q>lWwEK0rK3^3kwO@cjVK*We5$ zGn7gmQe-%%5mKOJ?$md}fzWtffXx!D6Yje zF)Ifi)l!M=-3`|6ZP47?qZ*cRQgHgz5|2FgIQ_K4t=l)rjHSNYWRT=q*JEc+LL1GL@g*GaWni^^jg%}l7IFmCi)~4X{>{2J?2#<&Z8q$$2TI3X(a}as{ zdkadPn`n!(hj8Q=tcn9HYJPnMVrphBoEmqWPmNW@p@^qZ8@f0cC@&6xTz7wc;s^u| zYm4m!XqHn_1V%1xH__%a5#E33B_{b&F|B%ZL8@MBd6{VlwxFG5Fd-U+UQcR z2DE#Y`QA-d2A1o4>-hc=sw>B7_FK$}j1^Hs&CL*RU*`wydn}(w`H=7kokZaf1?wv( zvOvdrWqTj#24jQMkl}U{`cWYcu-szomLF<(1rx~-w#cj%#k4{kdcMbZYS^@u4QUL7 zdzYEgatI|Kyg;JWc}mrP#GR{O=Jw^!vwZv^&OH8`)aI9%oAW4_@>6%cE{MC9Msu4= z_XI1)eHP~&wHd|Wq0^8&LEOGe>RQB!#ae}p6}AwyTPtZa_xQcv`G4?qi7$TPn>_x& zEYCjv2>aW0ypl(E|2ng?K9}FVg|iSR37!eKb9axWW2<--Nvn}^XKjnHr08alw7WQ~ z@XLllyHAojlC;dxm06VCP({Hc%d*4tNk;e#LISO4a3 z@vYB&hww~_lr@ABSQN6?ru(%&qSjwW%vMp>62vVA*Dq2!U&gRVW>ucy$oO<^0plP| z1>5_ues@4~Z-@5&4=7hNR*pSKZSgqeN|o6e5A8epeMfssu)lqqPUm~M)+Q_Q{}cCS zL6TJ4ILHfG5=E2Z0udlUiXbq+Ui)ty!6s+rOW4eDP;hWpy{hw!#?C z%}h*pS9MkXmFGL}_rA|-a)l{8gpp*)4#{{OFa$nSTtQ?Ed7g6P<`+n|zfGVeg)49@ z)Mgy2t%63|;Q0YXaSWjx(ydJf!H}Q%*e~Mz^jUuEfBg;KS-n9wiLq88T+PyQlcURH z+RYwOp5q4&}CkbNqOn$4@M9XYmfNub$`Ce|ny{pK;}OMkN%q z+Xd}8O~rAL(w%~BTO1TZI2hp~5{r_CMl)ogu>yk~ZfxBo3?&W!{n#`m8K$gW`7RgF z{VS4a10&yEc)qi*5|~LpgD6V^rVed21sLB4)Y$UwYwVQ$V#;qOr=a=Mm5uu$C^;!; znDpCQW4L|$HY>}EG+TAjG-W)@QA(B}7;Oov6_j*Q(%b)-B@4A|L`veQ^b2Z(8&qld z0d5$O3f;1nOLn`HJw_2@Xt;LZFVNwbc zGmLhb4L#cJI$K+t42B~Hqdv#f3X5~|)T>oCHrBBVi?o|{qBueu%SLCbT#up4U{x5B zB@q%(jv^^?ge_QJTIA_RpCE8@gfMJwb5zH+?D7>nY!2+1Vg4TH}b)CZL2sC`oS01{*0Aj#GvX?PLurYyv$$9FsQ(zh#bYeiYt*j3 z$$Vp$Z0=$1hL(D9u`E8B_AMVuotQ)4`+F~H)6c{~$WHuqCgcfXZO`&$rZ~8J$^X4q zPu)XkV6x*qENCBGs=m+Z`#r8>5Ez!11VOk&tMxMkjrY==nWr%`gK`8(3`tzxn(yA) z=IWbYVq^Oivg`)4GoN93wni<4dTeoPn>J+Ze`sSE==##_|X_ld!0IOX5FeJ{_@v08_PL8z&Uf_|W zhN6)8fy2X3EOYJkbsQy0qKu=DFVhGDwr+JPtNT zH$IL{cc_GmAVyd@#&QZ7C%79oNXI*PLZZSd(p7{(1cPmyYR-nyNY8t~kAJy3OVfhU zaD#Ys5g`XOXMTX0<>M?ZDJp@)^K5x*H01-6rFY4T4!ZC$+EV1Dnq>-$EBaVHpeQt1 zp~*5y97B=zs0Q2EYD7T2T-T`r*H;7;k1#LF!$C^aiE)fTYJ-yH+5oITQ@>G2OX#>Pw&rP8XRs)uaf0iYSfJZ$ z+gy0_C2p(^5Xwgwhxs{|n(H!(1~{t6+^mZbHE`XsvJjAJFOe*8g~m~u!Wcqd5xRy^ z_dE?hArQyey1heQ#9VpnkLhgv1<`PWBp)&!zq>0#r4$-l0^Q97qQAG=loK%i-Wqfg zW^gRzLQFNeOb8iLmi|2^5c0jM(f#4{0M=i=fhqJ9aC^gMbui87YW7~0zW|O467_z9FrG0VWoj9eJq9|P0(1LefoKhA3ed> zUwM_wZ@o<%XXHhx)>#X2l;DRxQ4$gO6@1sh^K1BiP_C_w#_>JEu)=5*F&ON!v$KQi zNIYK>cn)FUQ)HUnXa|Ff!o!sgg*8O+n8Fz5=H^)2?obOtq=eC6MBoPq7hEr3ZhuLX)i$H7q&*O5p^mdd6DMd|%6gu!+E{i2F8 z!E5l8M_~;HjopLji_#w=C(o^rqO@q4zrGRiAoNkfk<8>W^6swh57wvRKBaOh@h+x4 zfO~6K$uxZY0NXRc@=Q;-dljxQ`Ew8IM>?QVntes{UVDJO$3`$Mv6*`qrqkFZdx&^d zS{Bq{e&`|2=>5}=xOaLvG^pSERqR(OOumP50_vOK?xbRz6d2i{P%C`#)vIWw8N_e0 zFxN#EhSmHnT3OC<$KlzfIo=s<@Mo73PE>uKc5?pmX2w^C9%og-r+?-YvD2n8-{S4> zzRbnzmzfO%o_*#${OQZDpelm@pml`}px+LN~#wG+^m{xSMansLOI_ znJ*;ybwy`uK&LMFe6P(HhBNr4;8ZpsefvA~uD{K#haSeQ`iR~xmo{shI`urq{SNhf z6G1U~_VrZobYc*_^l~YRnbTx!#9}8yh@fsiU zXPAA@wD^7wrKtvy8(b@JT+2*Tk|!0i;!Ifs3Uqff@-!pKQ%2jX+`9Y)`Wr8!^FG_R zHrRUTL+laH`CN;JX2{b1nXZ7eC0~{rkU)Y_<8~#qaUx zqYI#~lG`V+Y0AdSpQqjFQBP95ppOYNWUGaiBh+vk+qgrz>7!08VUf6csi$LSnnkQl5c?PS+<*-%GWAoV5ET99QGI5C=KR(G-!( z$rI1>)vvzB-P>Js4uMw?;E?zRGg72cjw|apuEcdEjcT2vv&UIpIEBGseRGXLzeAG7 z#3p5JCnXvcgjL1Da!8{o(2nJWXHT%WTx0XbfWc4@R0141QD1~WX@M*(TIV>@M=_?^ z@~Bq_#OY0}-KHCDuoJ(*+T9C`hS$l=h}@>=LQ~}LZn(mjvaJeHc8>48T?-*lwmjU$ z#8;H>Aw2|WYwt0@+et`easXO$7_GAJeVf!NPSV@9$Z*7-T|ltDzRrmw$7#0fcAxZueGKqii4v}YqBIo2}uz6*w~bpOCj(oHH37C$3skEnO``H;quihJalBG z1o5k!4}bWF*}8j$QGZOWR%2~_op?0j*2X3qoozf$>=kOOy;5_O{u&^%gTTE9B{zdV3zXdS`#V zygyh>BseML#KmEe#!%=2S2q_&1s=Xj1HEiA61@Rd{I zohI=6azJz@D!V~B4oWDDkhrczoAP;ZU6(x1%i<2ou+!e~JgwjD*;4Mq2~8J1hhj2RwUO=($BcF8PO?|{EkKbf{yRSFiSJa{p z{lbGINr(NMhtN>=Uh_anNZ1!v_omW&!2S2Zhpc(9GCOT7I8^vl_G?FRfshq+Y0w0WD4VgyraCf_dLz^HQJJ#y-c69q0I?&+)AbuM-c~N#5Kc#wC2u z2a(60;CIiR=efr#JW-Jo(ttVm-iU)|1*@mt$tQ_=ac`@V;(lc8WO*;_p%4^PAz2~p zeYh?m*jMrG|DAlfS5PDVpI;FFy@t|m4{E-^_r-(_2uV^RU$R6qNHgC0&MRnp9YMkF z)_L;i9NP5Jwn`BX7;au>w|knIx*_lt^@?D2eub0v@6%{i5Y}TnPH|mDz2W01i?^}N zZ164q&VT%Kyz%S*oFH&;Tu9xO zO^zOYnDy<5yiuVO3G!GIgcfNuPTw=C#*|hsW_;hj?&}?K}SxN37ww2B|d&iISjm!>B8e zRw0Vpc$GDJYp;^0DOpw^a>d%lEiPZZOR797vok#M=o9n?+iY~+p;vT?3xg|tc6O@7 zag*8l0-3H8I9nKPiAOz})hgS4&CB1sNR}FsIAhcw(r8vmlM?OJZiO@(4o6pf+^SEk z6B?BUi?hodTRBdFLsn?wbU>HpV?J-yJjTh8#QdBu?cz zw$m@0k5o|dDFH1k#u}{2%NwOF58+XC4b(02B&6TppgTy3$6E*!VT-ayJW64p-(6t0 zQmRa$iUWn~@EK4lO~#sX2rzd4ASf@ncE3T+SbGRbHhnOdNvn!v54>*4^PEhl6gDrt ziB>Zn_PKWJ3Qskj!wmzxNnx(*_;{X&)|!f6AukH@G{y6L(k#Ig1tp!xCCd_YVbMj& z^Nc68rD3g6u8nm;VM~wV3m^O_k3abg=gxnRt2eF@k0boRq1~v`oSk8&(MDRq?s!0w zXEYi$jF8;zr367pt=V8_XPY>U5DJd2EV8*R!4p)gH8wii)ao-FU0kBDhCGfzSVrTB zuvVkpsH2oqrq%^`p2KXb$?EN!cviE%y~*}Y2V0btn@N&#_1aZ}pi+YLy?{z9WM^xW zTD6Anxuo%cJXLsph;Yi`%=J8!6y#|{p$&O=i&1Zrc6))aQYFt)+N}n{81f{;CK=uJ zn>e9Qz15;Ve+1!P!P*qd#M?bt)5)TwOypSf#0Mq{@ZEBVG`eiZQc59&Aun{`Ua>UWa1^{fO_wmL~im0H?F5L60;nlMLAfly^@7lomi!g)JNfhqZ?h`r}n zG96bJ(}Sr!*rpWkHmB6sN!{smD*6EdrODsh3Ns~~+QX~;X)o%Y+B6+`-v4uYzs>4C zlYlMx!S^yG571B3!>B#Hw72$wk(&E10f&^|i5d7o(d>J|yodLK_I^QjZ=l^%zb9$# zC^A^-Fv{zE{;#fMoCGH{3}Q{K77!&F<0vMqROocO42MI!dX1g_F6(PuY~=9S&whzc zXB)2)va~cu&#%*LX%;F~8bWin;&H}67>yZ@hRmGy`JqpLkjBYn`rE5CjvhsCwHWpi zdY#))t1|D_sEHFk550F5b?XU!@1?6;e*4=v7-mDo zsK{w)SX*6Zy!(H$>!kck{|vwKNWh|(mJM|i57s_i;ZVQ)y+yp!olSeMqnIK=n5lmI z>25B|L1)+jlU5vRe!9;O!h<2Dd%vgn{tl&=FXq&12H%$i6@e}+8*3?XY(e+wcJFZK z`oF@J=Wv5ku`?n=O9eJZW@C0X-=eqkF}kfPjatbnEig3Nv$PxK;a9D>)N9bLm4kU^ zTWqcFB9%iW6ePJ}VdWTu?rpSiiKS#IoPY3Zzr{>T5@(kPBZsvugRk4jc!#(jQB(tl8EBJY24g5Rf(>ZQ!YIRD zxl3AmnC;Olna&Y5M>;<4+!D=&2DJuMLa5ftLBMlL({Pr;D1ogVxO->7ts5_a-Yi!; zLZg&M2IZT#ivjyOS^qABQI%w^f+EG54U&9|j0AAe#TW~CK^5s_NGwr*OxAk^Wwsf1 zc96>AS3IPn>8Aq<;ZSIwbOcVN&U|eS>&;`tB4V(ETZuV&LXsyTwlH||l#+f8a z>gdd3QccuNNi#zdB}nNq9$RXGq~(SDm;dm`xpwn9*Vi@~Bq^b%XjGcaHW!#_AHgb* z;dn%^dlSd^N&S%bJ-x^iD@S=~aRo=Z9NUdJ`!M{`%Xg`UzsUSUt885T4Wgu==D9e^ zD=qZGQkWDd@jFHu(j-C6rW82zx;1usyXZoJPO(-~7|k%zL}^J5c(;9Q!h)5hiX!(a z_9ky6d)`oqDA)UT;`g&=zXL`HQ8ucg_CfjOI`qI#T7t+YHLO=alS=NZa%QOdy&LJCtNfWk^hlBVQYhUYj)EK)f{5on!bjK%c=szDVY z3`J4UZp|~0iaZ%J7!27>Q}->>rypT`y~CAjH(8!v;C)X%#+z4e(eLljYPZRX zl-X8;(QcO@@Tk-ro_y?a#{D6i8yz;c2E6d>Q=EQ!nYCLtsCbfYXOm{LNmyyo>-S5~ zWp|hDZkMH{1&p;UA6+5O3&M(z%`1dq1L684X@njZRO_I0xis@#@T;ZOW_x`Vq(upj zjq4G{6ttR60vB8fGLL9f>ntoCp;oIf9z>InQyE~=MkDuFpw=REc?fA?Ny%~KWH6AW zI^#MnLY8b+D3kF<+x-hs8IvzDJjUor;esrKOG=b}RX_>{H3=+fDa*lk!pwD~1gXfa z-hXBlWwVpChtuV15)PW=n@WGPEqToEI-ZSu;&rt9L<_s$H*TluROHkUIyvy=ft+cl zsvWTcHA$A6LlnV@#lqVAn4bs!OEu*aodiyVe!$ppZ@QiP25R#_O>8Q?zn7D-2Yo{K zByJ{uZSlZ${-IC5|2368Kw2B3RM3wkfA-}~5>X>gw>fe0EWOdbP%%|HWq+jYi~oPUyLuI- zDZOhqh`;+PE7#A_AEvzX2VW#SbCx%oD_s5dWi~c;sV|?V*zRz%f1Q&v6@K<3Kf$Rb zOFQ}!i}`DaVS-f_e1#4y>Ff&X=r7|0FYwgkKI+UxF5kG!^{dy2b6DHnU~N^|bGZ1dam zGpl=8xBE%6153dEFsmPk82kTxDBWCrjSZ2J7vLx#om;j$H*mci-wzn|E}_&L_G+gOg!YKLeoNyY_!Ac>WWbSz;-QmsH3g4VF!?egpY_&0gs z*^|u7Hd$L6GtLr>gmE;cyPI%lW0x$C=qH9;x9RW1v|1^J67)7Cfu{%>0ZS_$n_DBi z&_NlO(~lly?b0ThvTXJH_`>jGpZG8@ef}!-dBM(R2jK){S~4@&;N@4o!Thm@sLx1x zg@=w8i3S^N-@L%G|6a`QfU$)g0nY9i-}f2rj_`!Uu`xk!3sV%x>=v#57R`--u+hd1 zTyESQlBN&Sntg`xz-MeNVc_6S+Mo&xX#!iFoVE3o-N6pCGf&eDeb&3bOOdaYG!g_- zm=e(=yBKGTwvr-~w|L{wE-6?nfFkhM|THyIvGVF5h6pFj5N;KjWuJV(G)bjceiibmE{|Ro^D;*3nxwW*9&p4 z%2FoZwJ`^wRcjtN^zQxny>_QP)4DMRZHjWpF$SF%fMhrrbL-X(jw~+IY&1a$Tv@{Q zwGt?!Z~_HFqog7Xf(gE=R7QQ@o74@L%9s=aT^Q1Iq83O=lBQIu4Q{MoB-fU~c+9C& zC-~rtAEC$!E?&Awx7WiDLxdJk4~TZhH0m|#jV6oB$GCLqb((dLGY=i%+#Bz3`N~y3 z^x{XDUzlh0{1)wM#M4hc!IfKg84QPIO>3bEltM~DBXHSR+u+f&IkPhj27?~;TAPK% zS(>dTt!ABf-nc-c(O@_?L$fi%wQE<9%4KtNlUA#NvXbrfZRVHeFvgIjnnrV(TBCt- z6?fNe;kh2JQ&z1?MKd0FZ(@h@9Dp;qoy+}bJSMzH_yz310j``50_zrXAI z0|b=VPblBJMx6>Q?Lp>+oeHZM#H8j{h&^>!O!+qt$6V|o52m@{@V(-dZ>Rr@Jb)=oQ^ryIzo%cs82L+QDf{xf8yfw2PDsbIArH(k6y zP_6g`^qH>>a9l-U6}eFaRWOcVoNAI}L|$A(n`>;YuXFplL0E@u98qh`Gc$jhnZ*W5 zxn)a@fGjWQ-n_=AKKcw{tKiwuY1Zz3i|x(^a}`UgJ;Uw0102Vt?$?OMnhS56;aB?X^duL~cX;T`5~1r5)i=mQ%5Xde2{R`i=FWE6+BARk43&117u991pWk4ZjB!F2HM_`Y)I(MSY>_eC z>QG-&L^oD3;WjQd2Y#*j5O91T3|hcqf%;W zKr1*&Eu1H&MI2f3>=JoVV2gs#5m;3rb7rUnO`^dShEax+E<)t!Yy`^SNP|!UFKpmv zisfd7uf1}S^WS?5&v7u?A#kch<1v0EAWsWYEQ<>*0_l+nht-?w{QjSQjc1$eoQ2qmkj53RzsN@ZP`i zNxt|mew{em#&iUZS02yCPSkXl%WtgsR^C5?0`V2i8@vq^)R+5-#Vl$8ISwJfW(+G0S#q4 zmo^3|_l)#zD}WO+=MCMeG#EplqrkSkaFjE1`mJxP%ny4zhYUwoVQyyty18f~N> zFzk=0h4bh<)t5{+UIf@-CLhb2oQpzNc!Ho!@}(gNU!$whZYB1L(3` z4S_BTL?4+rwC@d#Bg^ zzIC%-K`QJ$DySgYw=P{Hj$^VsXKQ<#-e8Bk zC~Jj1*Tvtn1R0Ca1;S`{Ha8h|wo%sbrnF_y(er3En=H>SqLY-_*%}LT4ORyumX9rS zV{Mb@{3Y_R#@U%V&ddtCg=O>dHPX4GT=acbo_w0LzfJSm_wmQ)*Ezk=!VI<;&3}+@ zZ+sU&gJ*hGdOMnEJ>-mqXR%-SD%VB@ zO)=)S*(H5XNZ=_PApyOQ;*#RvRWXwc!G1%^eLYZ2)rHC_MSEH)H&bj}u^${1QwqNj z`Vb{TGJR_?Q#OF9i^>0s8{)s$P@35tWU_-)E?FV5T7YA)!pETSTtVo0XkB2ka#F8W z6n;ff(+=C67@d8SjkTL7X8|2oA$Lee1H$G4f}bPJA7MC}p+8hSdfFxQpw+I@t1IS? zIQZ8TwXnkS!ZMGaTITa#`X+Ilv9Yzy5C6bPMtPrWH+!tqLRxdntghdpkQrGV(An5w zJl1S?c8Q9Vr6Y@kwUpdhBf${@fS8-%< zhEM$bKjPZ;HO_`J2<2mnlz2yzcka;b4rn5I?RyvK4LW@6qaQ|u4nj)0+dVqbE`vfd zSUAS{SKr{)#(?!Utb&FSF2YQ>_Mc zvRS0NLU(kPB-hw9BdGYu=7*VI`Z3mT{27Ds6~==YQ^XuS(L|&XS{g)=(QG$3JMZ)5 zmoD+0PR5`&A_x_ZR0LjyILa`&Md*yv4^_Fj6(gLOtLp>iR*vAbt9<1v7kTTuYy8q@ zK0z&bo;R+(K~D~_7W&DEZokLuZkM2%P~<}#p~&Nuk;q80f;*iK@2qWeeXC7-{xb}_ z1#;t6W)?oqr#|&#yt8zhzxbY_1qBL= zTL^a35U1YY^wG!3QlD%T;itj>FBqCbp^m8)*`E#eYUhTK1xJl8`hSr$Dw z3SU%8_NiL}+S4S#R|1rS2wbvEk;G$+F@#}-APC6wjMnTdo$U@$lpve|jwz^C8XP^c zLQtvE?QSy~4QN#B%+1b`6o%d1T{@i|jvhV6Xf#41*zFDZ`qy9O<3IRAJalxCB+=Yi z-(aR$VR?Cu>o-=ZRqI%*a2$u>a7Yxzbhfq_4tDAGd)VAC>h(y{F?lybDuts$u!gJG zE_3AQDcqn!BMjK?Y;bJm3^VlxLVDC{4U{XeT9Xw8?YSm1^KGKxfH;Y9ybx0us-a7@ zvcMp4>F;#OO@b_PdZR8gjW)^(vMfOu7fC`IWJs?<7*GKOg{b=d?}*gYLpyz4)U2kY~xo%X)ERVt!#3YWCkcw_Co zC->d~&jeh)Hx$bIheC09{XRV=-aj86M6&HYgX%%8sXh4b{o2#%p;R3nQt$DO?zayy zg%8@N64-s3hn)iW8>2{b!A8{ND=%*l3qe-2NYadGoHB|>^as22dONId-X)47@`=A( z%F?EwwI)kbMs_r@d{|s*@hnJP(5!@*yg+!0%oJb>8exTxe&ktpx&uD-6Q5ymZjQT~ ztNivq`yUA%%gjQZ)+3MOZuU6$?Q_^C1lP8=Y0WJ&>s46IT{@d7=Jd0iJv~p=Z1OLz z)!7^`GCwoN+1_ogT`3UmQ5;+2J74?)Cmwp3r=EW=OG`(nv|31S5p6s?Pg0o+`H>Gl z&55}Y|JxtF%*`F>`m=PCka|_4tznNDDukUp>r6dsV(N9bQ>pjKkSWY`wDrIzIx&08 z{WRMI{k7L1Hhlq{eyk={vt>|NKG5Ltt|+BK78pk&WroD1uwuUr#8p+Q?I)2sCmGzL z&;`O6q_jv|;EJ4DwZOVyxsBltX(mV`ADuzb-yt5aVw^fsINZ9jPC7oq(@)LOSX{<+ zJdQ6fqr98^@Q-|e+t;tMy52##l4jLqWqF1{TF_p|7+opY+KJfx)=lQy6~auA=9B6> zRiVFQdGx6niUJ%NaP`g_zU#2Ge3G-zoMi6xo4kDf0>dcgiDzHr%GNHkjX932RQcEk zUf{y&Ys9;+u(0qjNEefj7;f*9ZLM+n;wn#_K1nU~IeX%1gcS^iV}vXfCc*$C6>)BO z>&_Ob@#sVeYBd<4o}SrE63ac%tCR=bvMw1>+q>*4d#x+rU#E$tb}w29a(v zTR+O|!p|Zttl#-vl4Kn(s9x2xB?gYVz^tpT#!;2$$ICa#dqsoFv@c z+MrRNC9H>x2D^0oW8yp^*%~lNQ*Lf=(~Vt36ie0+@CSN}B+9nrk+xfz7J z!e4xKmBFxwMx%?2z;93wLt5=4WRYTX_dHpyQBL`0tpO*fQg}0b=!5^5_S|X4<6UlE z`772gz4flEGt!iO_j2z5)Dr~M)Y^V}F|Q_|eQ6KgV5B_!`>iNFsMylqZS9^vX`);S zH38)73HGTtSer_P6b@;cvEA8XZhnEVVoBox%7XGjlyX1{a#MDJJC28y2I*LAkt0-r z0UX!aZ+Y=t7i^iVEmPVlc5VTTrhdFmufK~_ib20ets3I`6?|{R;=(LgiIR%(ctoQ; z$FSGo)bZm;saV@wqu1Rf*M=LnZ=n@@@WUTqxEpcdowvx+h-x)NI*OTQ3xVM1@-o$0 zo#sp(sbF(^9c#fS(<{(snqNAlZ4s18II@2QI12j-eabI8n4pAaVy+izk@|G zYXwVlvk2ufJKwqy)he}GgG#5u+RaNSV~EDP_(27Q zi!DrvIkN&^DJqp(iGq>>HNgxSV@ie7?1A461sYJ4pahG~HLjyTIptWS?0z|ewH75L z1qNMMax~fqEE;1=9;y^fs0eC5@vpT8Sx{(;6$Xt!TU&A%>Zx*Ztl5;CaCV*7kDBCwXuw6!t(iECnvRe>pg?kD9|PdwZCKaW84$03|i? z1>QR#?5VjAs_C?r`zuE6gTKy03Hqsl*qVFXs&=X?;NaqGuw*$Dg-2&p=hbsN+}yrH zoN1!CN0KCLb+*~q*dUI_Bxzc1c^pZWWoWI-P^!&KLW8mU>U=E-30#Zs7-|Yu8a}`B z_kM(K=LTNjlVv%z_6g>WJjK${M?eM$H^6st=FTqh-~IA0piP83`y9XX2fxR7d4Yd3Bae(W^sjX6%6h_yP@SLV6(`VCq~ALH1?HyJ(q3BGsk6`pPce7-+K zSDSpGw~bp^p7RsxEe9%99Ac#Hl0>UWxkfcT$1^j#{Jp>RNzShi`J-39%kO`4jbHpo zgN25N*tby0gRs&bvEe~2^ZNw{>fmxQHFTEG&H-lZ04Zhf@tq`}5>-6P=}GnMM{G zp#(`(rr*O}Tkzl_2m5 zl;lr7_gOY>UFPE-d6Av94ztY_n$8lto0lmvi{lgogSR=d{63z4^aFISU*+8JG@Ttq zH_KRj_!PVLJ2(g<)Fl7_AOJ~3K~#>!Ru$EX$0Ntj@aVB8X;v4=^O$~bn_|4ius0yh zH^}2n1haU4j?)@}8Po0j5y%jet%J>RkT|AbI7sP)iof+Ye~RDxgD>z0fA}>H zLCI9i;+S`CUzxBh>v(#==4g{!gC3ccSRonfj8xaCc$zd`!xYD%|Gh96PIr8Edk%=djfg0ac)SD-$&%a2Rukgr| zFHmoW+*zx0;kyy57yktKjd$%B)B=pKsLASn|IJ`>U^znUA8&R#bt@*EKMJOs0EGZ! zN?+GsdnpwMKEZ-gWixq>DfEQBDEIxKn_HXI>MhQkIDt^I#79j|;CP&1k@$g+QYGKg z8bg+62;ow#HW0Q%HEErfsG_Nkb*!LTZBn#zhP@ry?H2uh58tmaic|W%9-i`0j!WPN z6h(^bc??HG3f1G;_q>NYYj?PO={mh`7gsvuQO-BN_D!y>U*_jN^;3NNTuhQ>j7B3K zJM$1ofzcow&Gp+idGY8s*n1bcz&; zaTJrJIk(o=kSah)MJ=o`ND~~P=&!F)WHIg59EHy5Z0xW&H;ZyTq>@DA0Yc`~>H)WI z?2zXoQoTlv_5BPv{gD z$n!GTq+t?J+e>=u{aRW9Wj%CZuxe5v>ZnP2SR+tqU4A~J%YqeKls2P0&#`;m_7jUp zX-g@O++q@hQG0{wL}e|C;&9P}l<)3HYBQ!g?hiXR589FJe!Gs@kD?qTn)kk*;y@ui z#828AEaU;!3AxWJJscjor;79t!%{rJMsRp&d_d}HN->?P8r^$O*=qu_hj;XL&qiSF z{$?l3A<7izujE|1owDA!L8seeb@eve-7T^_rzrBWx^=Sc+r!7{oc(&@itiEl^MroMZgzo2tIDb4kAQW^ih|D0D)HK7Zf;hPUJJ)_@s&$^?i8&+ zlSDDa)}Ql}k9f>J+~VVpKh3ZGFQ4UZr%w^o7}MwRvybtZ+hTS7F7Y7YN@gLcarDJc zabvto_{=A9SLV^f0ms8dj2tt#_?K+lyw0&B50hja{A`VJ_aZNS`E#88=ugq~k8Gi4%-9yz%ny@sX!j2z)hp?sa)#5z|%+dk~tl)3k$wvipN1{Xqj( zxyKOuzyF||;XnpITxziA7B-Wr(J4-tc;KV+eO}*Z8NM$tsUV9A!Z{ZiYWzyb+~T90 zI`c5IOLbgd62-7~bCSb5nAF>ruY#lS$>UfFT+L~%%Auq z&Bg+k&R@b=nMb3r#v|~3c6Z0H*q~ks3B%LOdI@9WF&g!8>Vrg+6->Z`CZZX{1BGVauEg)=#GgXcL71E(H(0MiXFTNFZ@r0|Zu8M+&(c;y)Oelh(vu95 zUFMeO2tWKu7>`&#_Xqf$JA7;7#S}Oze}%^;|ANH3WUs&GGJllMHWu~ z6nw+`RY>S6=%=O!4jlyRjB)G*+mxVQFv3U=Lg_5Bj9bNulJiN`)Fva;6Rs_8Z~4NZH-&_l(Tgx4SQAeP4e# z=ia!HSs-H#l~PGns>p~N5$B%sf1m&J{2m0!VQN^2!;tL|KPA(SaiJlOq72!RsyCVK zlsJg#=q?W)+#~PV%*`zj2QBlJxoms^tnw*tmIzK^V{w~+nhVLOt;s@$rs2K^UN+Ra^>nfTzujpjaG;D zppVAKZwJgwPt)o42>ghs-=iN4XgBt$P0!+3hA@n!*S6w~XpiIWsfl_9ayV~NpdnR}_B5G+@X-dLBu1OGMl>sH zutd823xo7Q7aId{gpv|lripze(grYFStLfGq{s+D8bLx3#i==2CMM}}wfSEyX0X(uCp=p)`iW5yEVqiZQ1`D~+DGYH`A zYZ0pl6;?M6c<0LZX|@_faYPiwS$Hzt)WkYQ2t%n*Oz%l1L2H4~F(uFD@BQ6p`8z-I z6n5M|>L?x1rJ>|`xV9Q$lhXT^K}Z`AxQ@%5cM^fYk~WRz7X9`bUF{M?0Vbn{QoX_rX5FYv0E4yL@@ChxH%*JXeK9Vef5D?%$_&;U|&J7R}so z*m=N5ZobW0yP>JE8k(|*aVe@MH;~qeE+t`3kwUx9-R63C;7Ga zeXcbt{L%{-=;gk_02e#ME2SExISkba^GN8-qTYrEKo9WF_IYgpMOo%0mROT-+yYTmDZQo$y;h*u; zr61?vd*9&tZjSlb5c)CwZVQRVB!<1+9ZsEGW_!JXU9QmF-{Z}l2G5>d;_gO^YPmwk z@8Sn7Y~_GbxLyJ2#k3kBwwBa)29%2eUs&w!v>3EHv^zfiMxU)_57#ab$C{1pIxjwd z8qY5Clb`-^u3x#vv6CwZm1FhBZQ6}GMhccrE#ehC97mxX#lR2PZPlp<0f|<`Qqc7y z9&Q~lhy;EtIcT(b>+Sc5aG0N)q2KAy>-*Reo`32b_wKB+z1zg}yR2N8V!z&?y5tev z8BkciPJH_fRMKZ58XyV+t1yXCk{%xWQ!`xKKTb2q;neat}PRZ6TkQ2h+F?wTq|kobRcRXxH`w246Lw$4BvWkOf1hS+pKrbi zjb@(<=jWI#miXAE(_C9$VPbBHu-!&slh962;L2fU?gx45rT>o71%I5T>^y+g2oDz{3Z384TJyb^d9NA3u)c<**%mikLiIrnZ^!+|R@aa!dELQpT|MM#6&YZ?^Tt4>V z3w-%2e@?AhBJu~^+1S7?m5GA@H(x|52Pp($9C2{4N8|?_G#lK#bDNJ&J;#&ho}|<6 zGF6*ns#u`aE|EyXM5V(0wFjIzbsERf~5*{lisC&5@yPxHcV6;hU_% zTnKaIQE$f5^Tv!r(8bZ@x*6+Q%KU_fmH}}@(L8MAd7LA8bVyJmAiCj$deqJ1|8D-8 zL1TEY5Qph{jfJm0uHPB(&dnaLeD@vJw(9glpCmf~D=8`GZ9<)LZj(UcpgD7*$bb2Z zKgo0@L>WIl7-buqoM)4F128V&rb_>i$dLIg#UmaAkqvK_%GTc^rd*w%l($)1eU~`g z#?DV8L>_Iq2n2qAKt8{~r=F}bomYJM+wZa7*KBXxC%=3gJ9j|;Td(o4r_b<_tG~&~ zSN?$3z~YZ@fUaER#F-WJdpEeSFpbGgaJie%SY0P~>?{X*Ks-=*xiSwPJfvwH@Dnbc ztYPgRppraaei-o||LCvM>AXsA@CsH`Cy^!_OtU-x=sK{nAyH%ss2aiaQ}OdC6+&=W zDQbq5pyP)k^SE1i@UBT+Hlayzd*k6AQyL60dxyIh^E9`8&i}8J8RbprRdp!A( zpXThjIi_nxDie9Gef3wF%=>Ka>{7|QREjnyR%TGv46ZRWJc~Q`H(97nvvRh=@>GQ@ z@2~OlH?A?iY_YXIAPyW#1($xHSy`%4vWjf39zYB^*I};_V8RGDFF0uQ=m!Z#+w33I zDHS|E{R7YOEC2K#lJicpxN?F^7hfco%MISGu&7i{bMYhp7_1tJme`JDf3v|m zul^yozWeJGU618Y{8toflOL`+Gxp~HpsVF->2T`BBdlB8*Hab82hw4JuKy6$%xn_qu*<)K&#Qp{ZLuYR^>^8 zhz*WR6Zulg%ztW90DpEEN#`h;DuH7wbdxnkSu#xyD=TXtO487aHfj4@8hX+rTZj~C z#q<#b4r#;G@On;kwrtF<^CMxSOg;T@llK{?G@}h11>sr;iyU|>4LIY6S92J5@|mVT zSmIk>`z>zVy-&X%koUmoB*m7=h)=w*z<>6$pFxQZM#hK~=YXZ4QcOS?B;I2T0ZD=u zX4KPuWRO4dt(eh0YzT8V^JvVeDPUMES%$qPyg4PlV2sg{|ZmqF<;)EBY68VOD4yiKe`Ob zfKR^kN$v&?E#D_LlEUNymC_{Bxe9+C2>O*WQ?)tHOwBXZZDI97>UEEs(Iq}QbAeLh zU*m>rSVoM2@-t@jIH+EjqXVc&sSfFVHOdZdDr1kP9NQt=RtRfMjXzxMk3O#vWBzFK z$f0O_c>NI8_f?%km;~207-1trfec;hgI&VTw|Vh1mpJ|81XB|hj!jz8r&2jSpHFa| zNeYF}@t$*@d^N|3C*=N4M{L%@gYBrt=g^6jfXNcn+_6`~p ziyl*Di}xb+?Xd#Y~h6grdM% zFI5?>a*eRt;OWyfP9IyqopxB?>~i7Ri@f#9E4ZyXQ^MdBatN*QghUlRWG)BQ60s$b zwnDmjEO(09%xRRbaqKb!U8T{s=>!S&zC*JYQ1@5SP7kLbF;<>#TTz}~!6`n0om;_D zJ4m_9boC5Z-g&^CI|r%K>>0|goqE`8hX9A2tsXCa^a&o^y-Uu?QExTyTno37r!*%x zlP~h18K-ME3{pW9h7?^J;RF=j^z>KCDRR;RqtIEC(1@uiQpL>GAu|<0Y+3lmB8u~P zNfy{h65=SPTGEs&F@ugyf&Gaf5e6SaeGqZ&);5K_VtLu7fAD{C^}7%0C)?PzLoPSP zv!DEBRP_uSdpqP>WqSQOm%sDdtY7~<3hn~Wee%CSlot8p-~Pw^PygieAM)BTUBv1n zy_ravqCrxz(;$ZgyJ5J3Y9(RPZWj3 zaZHl=KZP&|lPY}!KSUVV+TP@#-lABUK$BqGIh5ldrG?PxYK}OqCr(V(scaNdYAoAM zUzf=IWWs=@(2~3%J zk(WM8;>Wm-;M(B{_5AB$MSbh1w+h2b=6~H)%GzoH>1hT6L1zj4LWUTGI3h|AcQ~-!*4=l-eR2wlwwIN zVvHlPhJIzhB<8RY43Q3=Dn0P%Bu-hsLLrnyXDNI!s=&3Zhr4Z?R>amUfBh62bDPrmUbu`#MQb&9^-x(e)fEy1v9sYfA*&&~= z^I!bJMf&k6k~l!9G#n?4%#dRi#lj%1rZny$R&03h85RJ1K*U@8RaOKsuJ9d2U5%@{ z!=XyqE-1xh?IibZUnBPSh$2a8<^pjXgJ0y**Zw(oZrtJBFa0kB zE6*_h;z!sOeHM~EXe(CoT|O4Q#rInQ&g@xQI$|v}eEr%3>Y>7!nnD*!+`adJTh%t_ zPoCkNHUlP*xrjvWOIlP3J#nD*m^W^lg-`qX;>ylpU)f&6Mgx z7pZuJqB2xa#i))t)iZPkWK-jAfU)}0!y$FFnK*)?8vDom&8WfuzlPEv2Ibk?hM$gD-f{yphLIYBJg51>kYK9D3wb11T=OIc(~cctCTRYPb@61UcSdi zKRU(7U#hYCpvx=Yx(l&QwQM0uaB#PWk%mDOX3C+WRx9(~yIa)e6}lggD?+VWq!;w4 zP3MVyh2xaDe&sHI`ltVtU-@VMD@sc04_8^gb&clsI#NgU+AZQiA7x2G4a!b^bHzfA zwf!v|TX0Z6;MCctSl`{i?C$a6Q>Uor^IW@qm#In~$90*=3I4;+eVlTs%GI}S^4!H4 zKKrT9vAVm7XtpWKgpzV8TQ(j79R}z@g5@e?7$KEG1_B(1gL;!tD?F!)W6#hF^Mtxc zeW!O@gOC0D>$0cb&zC`1yW zROU~V8X*l9*?@$FL?eYkWh=yUGmHHFAN(Ptt$6$HZQi`~kU=CfpPN7@ie^JoEhu{3 zIwlraLJ^vjr%DdC2VLHIZ->chnWdWG+{q4C@5LDHQkZ;>h4UBKIe_g4?+~?0i7Z(yfFw$Yq96^R=(M_Scl|zjE5s?3sm-6DWam&qW0Dvd z`GkHSNm`cSI37~k2$?EqmTloU7D6lmx|PPw-G`xJ2S;@f53^QlO)MK zYSVM{0-v0hqgt9o+X_sA-|KSziHqF6{w{OV^X%;J&}elimL`zOW@>hpPJ0)Oq}gbZ z%azcP#P6pnXQf=>;?tAF(&gZw!OqqujxrRAIh0fkdOehLK%(~<_-PA{lrr@IYcm=~ zMk`N|T08@tU=o8JfVNWHS9%diOpKB|8#*8LjvlSoG>;uA z_GiN-@v0~mxnJYVZ6=ikk~nNKMt!=O;*5_ z8Y2>^Nu+~62&+|&mzCpdfhX)YZX{6u$~ci()C#vi=GhUZW| zd69$*ynp9DQzuSwC~JIHu-?a@Qd-|A4>>Le5_ux&vUH?XZd#rYGQ zdEpD3JvGZ@6_6UO<;d`?vQ%%Q713xZ>g^mae)=alb}UCJFYyD=#Dr*&b=L0xOJaQX zww|HY>T>n1FS1~661r0ak)T|x@Z`BCc<|sML8HalQwvmG3wP!?uV21J)Cnn6b1W^+ z;JSuxuT8t%W8h2X3N@6~qTgBL($n+Yy1GRW7}hp-a2zO?s~|P)i9xC;2*Lc^6gpJ& z8y&v%2VdvXbLZ(aHwe2vt<6n#Hy`3RTSzm&l>(t01PPua@ROJ@H28iOl7vCx&}i)8 z6mo2AbwP(rmo%k(kxxDU6s_G=r0wza$}CTwTjBd}-(@i`IC**zyHp^)xk}XO5?Kz$ zmS9IHPoW%}sMlw2dz-1_#}K6gW`2hL#1y~tCx6PoYf&vnC@Ue-Hoah)R@fzu8Vm*p zxUP>Z))B@403ZNKL_t(z3yc+E=Ow0VNaO^@^jRwH@|*wqzh`g#3f1Bad(Aera*6F2 z_BsLOf``?Q==2ht+ys*oB|iUyA7^sX6vli)WuY$8=!=C)%PP#7Nsl zs~9B>v5vTZFJ^B|lY|ixN#3$ij=(8M5<6kN8FS@Ei5H(4@R3XBIoQ8UJDBFPKmOlR zn5Yu%*SUY~PiU;ZMx3;9+yulagq-3#U;Q;&yWb^O{BY^{LyXfQ9>yH1FGEkLN>{R4 zYmCrH(ucgpphbd(%An21)OIb)IAxT@F zbQ}|h0~+-$c6J<=Y6S{~GL8^f3?K|KQAj-KBVvP8IlNph_1?*}dQ=IBq7b7a;y6Yp zK9*%+TrcZs_EE~m4??8TG+J$1^%kWPRLV7^v9KMFso5ozkZf*muzL3nGqouyl`4J^ zuzygeGEu=uIDhsOQfLw>sqgL)4!RhfkdUyx@sN)`{~Uu}i+F#ZcDIXVD{`d?8n@S& ztWD7AbdkzMIS#MC{T5F>{T$zY?JqfV?lfmlpW*Fm*RgGjwcSltmQS$XXyZCIgLa#8 zd6FQC2or&FTn0ge<5*||)rmzMnd973vuy0{apRr0SYKbmDY(o}P0|m29z58fUT+X5 zF|~;agbuNkqSJ2E?>32|U=)zBt+eGy3LB)L@Aos1y+$Z2!z?94aYi=GSjUnyNHtv9 z%8YF~Tq8;aQrIceH1jx1AuuXcRdkf8RwiSW>eSyS4QaqhromS!(^e?7W*91t%_!f4 zP(y%xmh6^?>-`TqeLqT$Lk=+o8=$XQ%B7@8S;lC!J)@Jrbi-CneArSer1gQ zfMHJjji%FaN~#%CtdAmy#9x=K8d(=ac8^MX0frP1@rdj@{^<@`uOpl8p-;DRqIU6Co-tg&7xnGSBjb&oIAKrBDWCK^Ud}KWPmSFwpEJ{N>B*R40opFHcgd zm9dp%x2{>;h+(PMMxJgDiEZ z*WX|e<;eAXj1*`oXm|JNbg$xv?@-DQ$a@Kj9B$Dj9}XBa-sC%9`WL(#ZgJzmJxr7! zWJss$Ba}s131ZvA&F9$JZ)2CAOH%Qo{P`KeF z(_zlC7=$tPc8fs}vs^0R$UdgmCP9;E5Yj@~5NJGAv9qep_JkI=bz)-U;hTjmX`1beWD};)5F6OzldIuvkQDV5iy2?wJo?&fmgZxAhEXa8dey@p0 zH0@r(#V5|-LZ+hU4tfY|A&HWNSO|11urq5#B;ygf z$+cz1j*ZghE-T~QN(*7qbUh*sHl_a4w5v%cDNQ3iB;aL61R#@#y+KxpREG>)}m*jNkgRmr=UR&;2J~;N^`QY~9+&sT+Eg3f=ua6q`&= z&*6Io{O|xvO7^!OQg8*W-AyKS!m)*A%lE&;D zS6fZ)9@NP%%yIwv6;3Zyk>*F3ldn;bcM&GSn6xD0=!|c&N>-U&Q+hN~rs}a7GA^=o z{$Uf~k)xE6k6dp!`80h=KVG|uD;3o`oBfSx4`7kiGvul@#9T`uz`^= z1MLvUF~-Yb+Xebz#LfG=XkqjJ{NY!)bi9gXSybm1xpMVBd)sYp~Z$o6e5ZE*mF8M6TwpTDN6Y~%91QzIM3#-dqlk^C(bVrqFG(tAXhA*g8L`U8qnvk2wURtbedkzo1)zxEsdf^G8}(&?dBahoXV z(A5^kcqlQABj9AU#P+Q}Bx=;@T6reRlQi31_70k$1p{s9_z^}+Y};`B>{&kb6TiW! zQ>Sp8E>S3%U%bdW-}qN7O_gaT5p5$-Qlp(7gFFQN1h*(CcotF6$BryanDQc>VtUET z#3rY67(XJUj~0r^7~)7{8#fI_*bX=M);ZW}B1{o!`B;|3P83?WC?yE`hNSD`+LGn@ z3YX4JGd1IIx6>oo9i(^~dlkL>3v6xvA2@EF#rYNX_CwzI&Re|km4A+B`xH;quq*rc zZ9x=kf_jHyxk_Y#?tj?8?qSP~AW7oG>cvq%_~C;rZD<;{JY@;zG4GMq8cU`Ms2SrK zno+~YAs2EyOp(MHTQXbM4v|hK0$VAxZ6iejI-%bS39)d!JTeK1Lmy$epd5@;4EiBq zl%x%5I%7`)j-x=>NC|<7NOYWrwuC0o0mh`wQoHp7^2GvGH^C&U7Z)d_4*vA8tHQ%_%j8#!9dKDm6JrKNf7eTP<%P*`5!!uj*O_udTx z6Ei(CNnj-JU4Nf;r@^^XCmBQ?3Y7w0xx}$tf$H2WuYKp+?C!47@AoJbOXR!)K@{Lv z4!N8IaZHkEf}oFOd3br7$!eK;qdR&SL~%rt@oXJs5y^xIog$(PY2auWs4jQOs|D>h)gh%0F~jGgoP04aA4bZTIVXn;i6PPqLXa6NIl&~A6i3_BuN`#bjlhv zDSaySunt944%^F&F~nouXJbsp+#mBriw`;IH1aDZkA-m#^*}K;)X5`ZFf)9&4mT9T zFq9ETBT7b$hQOmSmqR4e2ZfT3WUhsLEHV9v;0a@zS9+329vLkT)B5I-SymkJxE_u^ zkKMcUA-TY0MYD%;s{x`%epdSEVEmYmVEB551M}fvY#tl8&A4`&6>4gN{(w7w@itd) z_PEt>xZ>p5nZHC(nLyi9OgRE?cb_l5@-4J5OrAYO`*VHD`4V4>^PIl;S-ScPE2U|2 zJA0T|6U?~Wf4IiX(h1z2puVw9b+$&|GFa6D$rER=Yo}=3UZodTDV8Jpp~H!_7RO#% z=CoVn%)}J^a*i*q?lSYtvwZvA@9^TJVq}d-}3AzJ#uw%IT{dHb@_1_Tozk($Lq!Ose zLz@_*JH!k~>;WoCh>f2rFfyS#XpqZ$%udg+y0*?{H=oSZIGot~!G?-4{j`mv$g z4XIWpFw)I}1)6fs1=D5F2q``L6nc3cT{ywo=5@?eK)K}LI0{>O$iyY^J4CvTP%*;T z45EZwR78XW-hX`^>E1Gqts{g|qlKUa=uBNo z3~BHMGYVVi;VMfU9YhZwc7iz3gjqN#3KPO0BF<@CSKzog6e-uzN+d}TVOt8VtZc<7 zL0Z|6qf_-Z3s?w?w6V#gDmg~tI2Lgf5C#JjI#po9fWe?k5QMbaJ<#Cy`m8-%V|Ha^*Osi5ky+>{DEQ<24%f9i;8j?*>Fcg3yLaxr|;| z!p-L?R4TL^+w5*Xpx5rQzP^cP=ddh|l5lTzojdQ}0VAD-=9CmD(uBUr*04&*blZ|$3vrwv1XGyN9+6#e<;mr7ljXesPg0t(iMEdoPZ&P7jA$W5k$?)Ep5)1*sqS(fRF=aXxMu5RZ97`9O8+ zC{%yE^@k6NPK^Q8#iOCB;rB5*>^#b6JsgV<{jy`@r5XQPhpt^QTHPlja>rvqud$xY z;i`Xlf75Y99geH zm}8#H{jYwF<1akJ>0_q|dolUt6&8v`-n;S+mR)5#N-$HCbfb{12lqMu{PQHCU}w9{ z<+Up$wMF#FC&-m^6jwLNefkAn{pNR=d+9&mjOQ^MCj4B%<4fIu$-=C(D60Bj-b^EdE%Ty-V?Ms zu(M~lc5R#Qz4CwKcfUoU)J4V)Iu;lc0U_EB!GtKCfYN9y#>57tBzSPRpRB&f)@=i#h0OZQFdJk}A!qh^6$d8$< zmGK7&iwh^%XsomTu)*Yt%dwS3e*UL^2<=FI`!~LvHcm)G6d8oFaq|U2t;yMvP8ibn zeQMJsloE70b&j80Axsh+H^;`-8s&mbUl*8~pXD!Kew_=)r?~}v*BY)iDmiZJP#~I zt|aL94NJH)*r ze&A6qyR<`tG8REALI)Z*Z{wB%v<|RDOwVb1B3!EZ#eZ# zjwDu;%f~6YCukpBM(Q4OGdZ3(JHv?+(@alQ*lG9J-{}#?9%1Zaiyfk{!Lg@)hJW`v zUm?0C5e-eBvC2LQVDXNhe<-Zy*~B* zU6LfG)$X#px5wnf1WOA`6t_09-6De^K!-7TFVBrzH+lA%7l?NExqI&($4>~Vu|>bv zqCe;}HM2;mQl{4*&}y~W+1}&W@fCjdAN&kk`}@3qrAMn5as1dK7oUET*WSL&>`aZt zxf%N17H_|OnMS*dLG#QrPxI}sf1Q52gF7(^g*<+@&9XaBuiK~I?y$79%vZklRW6;o z!1mT2LD1*Pr=O)(p5)CpzRUePH&|LeMHme@bLJd(@7$qT-vtvfS)E{aXNM@%6v|Z` zN1%E=g3u>P(r)aTi3)kkrZwoJb&{@vP0Gkr%3$d<%$7vMAvC=}lt{gzmPoH8q0&K5 zW`0d61PX~Z5R(p!WNCe+)Tq%%Dl^uwBvOBARzM?#B0^(?B+?;?G3X>2l`=?kNP$pF zAu~Rw8277X5~`AE*eQ{WTA;*-%qSfNYsBGdTaTC9n7_)cc@zhg`uxo3ohOAH8_?9_ zD5xWARl$+`&d~QM4zWig#1@ZpT#r);5g+hn#TeDV9Kl?TiUW*3^fewK4`i)FkNiExK9e>Y-4D6-_72}qD%5`JC%C=% z1hrm7E>39PxY(Unwb;F zdGGQS`k_y2^*)v9NtT~D&-Eanv0rCzuffd4=Q!|tRGzptbcg;89q3YM=ElM>gu@iEk3~fVIFZ#e;7*XAf`VEu|7`Ao9oE=rIO;9goea~>1Coc!j>q@ zCNU0493V}a{)>{3f#@)knNAplxCN4 z^EEC$^#pTEHIO!U?meU%Xaz(`T(7^37NNg!#D{e)y%2^U8N$<8wdwJb72s^xMQc32SRx2<6ZZ1LkL^==A&K zi)Ca!kLV9bIzGij(^ny8{v2^`iMPM``#3T|%Ly#2LZSRgN)w+%y2qFvgp}5*+<*A% zB;9S6n5D7NquB^hxe^u2quc7D;~2{p*p6a;sf_2?#CkwKH0Z=;dTIh`No)pm>X$L9 zN2wH}MU2XoDX0r$I93{6R!FO0bIwS~SS#9m=H-x6w%&Qm8x{r6fuW;m7HUR1DdJLZnG{lMbXYF^MoF z84gGoGnT3zKG24~Bgr_J+zcH^CQWX}S@_fa`e(TQM~^ zm(m(!2?H#aCqY0IC(O*w&}ug5cG`UZ^1D2J@e+>hFu$BffdtH(!NZV*^3(K|0lcyhr zgmHw?21{9lBEk}qL}+4}{;s7?ht4obu%$!@jmm0jg_LPv4p74tyh*WNdZc_p6eS2t zWy7Vw$_^T-)~Y}XgcQV4f|Q5eP)wM43=KNY0RP!AGb~R~;xMfZY2D~>5R!5XdNbB) z_F;QUb;cAGMjm}Eix0x$jJ5BWv0i&IWRt3lQ1D2Sc~r1EF8>{-_($;*b2zZ2ZAheE zSCfA34^+2|c?3~vj(9Q0xmD(|-23pO^2?=4d#a(}f=^ywpUap;EZL7ig>1n3@HfnyFZ*T7)=9gG3 zD$dCQJ6rc5>SKwJyrn37`jg!G#;eS(?XdF1X-cg<)?V4hs#KU3)8r0zx&CmKd^IL- z+2m_A{$JkSEJ(8KKJWXTbMC!)bFIwUtGcRs@0p(No&~@FGZ-vGf>=nIf@y}fkQ`yz zvK$PD?FdKM5e~gLY=$0Whb&8uumnX|qD+aR1u+Pc0!V-uV1StcX9k1Wdb)dhuYIrF z^RDL{Kir#HSq<=kjNrU>R9AOpW#02Y-~ao5pF1;4Yj+o0ETi@gNtZ%O)64X3zRPB( z$3kU-t5060JX`0DMA2E@TeQ%$aZ(irct7o`2cZNDQ zP^09#$$OecTKZUBZ??G_U8#nf3Nai+<%tT?ac}qWYpNchyd1ZT{e=gethJb+#s208 z^n+7OPI##NLYHXh4xri9)T+&tpd@BKTPd*7l^Y~i{-LZ?`r zan&p-C{Uh6dW8%Xk{VPB1=lAg;VA9khkYCcWtHMgO)xP%O~2FPgAX=1zcRt)OH(LE z(zA!`tp->$E0>l@9LfE=YXo7)(p(+CAn3-5Q;XBgomQktN@^%nGD&fYHHwR8DV7V!ejhorOkhGD?0=i$jHFihPpDQWY0P|%N^O}+ z$;HKTY33^a{uDd=eYRUEoo-C5C2^Dx23?e+u)4tc^AmjbD~q`PE^oflBaCX)T%Ur~ z*g64PC{j}NY$xh`BkpJ^gC!V!0{kS zQVx%fnDDD8VTj_8uC~O1ChBQ04#kN&zUPrjL2Y7+iSh(~ZJv~nqu?%-txydB03ZNK zL_t((w2e+IQDo?|PtaLM#hQz!=eTrck*WF=rP2f;)2y{FAlw0J@E)_ZI)}YB&7FTs zVh2o?d&r)l(+%lu1-#PvUzl8YoPM~5@d8XbpfN2e$q?TwBCWvjK6-^_sHg~&1tzTo zn`Vy@Db+Dg&}RMPiPl4l7{X*nhLQqf1Xc=k?ll!Mx3-NQ^yIaVCk^ex-tj>Y5G65T z7*MU2vL-3V!x)<(o1z$NEQ3KnKNwK1l(EXeh|CYG^8+W1^1xQ1gyVX6ZUG?@(ljQC zQj$0(O`z8qAf;q(ZVsKq;%F)@3JBzxv_f-dlSX}t z)zuANdFc;HqL2r7ZqpyMdE(MJR+eVi+1lX#hY#pQAxagAHrMI2n^da}++vl3!#%oT zkD`<~Qc&N8l(Y8|!37Z%|TZ zLI4i%(4OxgXw&5q;p%AlLBnIt)6Ewm^0qPo+=1$_SnPe#DrsVOY^= zz_dc%esvrDnZL~asS7mkKA;#x^nUySpZ|rQL#)j6e&If~+B6p_vwO77!Tt{6dv7Cd z-o%-92@kr&%>(vTo%SH1e(^kP>~iLBe3kY)HxSzj=g_kJ#3Fm)033&bvZOY~cx8e! zb!4;2%Bf52l&9$a@#{={>M6ee``_SGU;QdeWuKqFI?acBeSZAlE>AyojjMWw=(OSw z-ue+$+2mBC%-Ymv}Vbg+Pl;+z=zzwm}Ptwb|K`UoUfixIMN~ zoCrbXIIpp@!P-AFh3wBiluAdS!w&Dg{4Y5Fv zY+Kr0%j$Z-J8%Cnd+XnV^bp^7aFszPAv%%hRFjh6`W^+xK`4u3JhVy>DOj1^x%!c& zIp|Yy3b?M%`Nx-8+uvYmw#LV=Epq4KA)??ArANe3K(8Bt6LZ+wWe^Jz9a5?Jyz zVU+nL$|aZS#x(9@bsj$4;?ns=4qIIk9WXf?^1>%B^N;`GZ}8vzw|^U*_zaHrICyZ2 zL9+?*04oL2pvywTAr6=Z?YPjrft@7L7yvtwvkDlYHQw}-`xO`!f z{jR1qQNWQJnS^}hx$}JXv(NMEfB&EJ@n_C5eeNvXc7ik(S@0N_rH1GVsyz;|uasTdp4%%%R zlXJA%0e&&_|Av94RCHOmkn+rzCH_>(!G4W?>JZ01x*rk`QlzVhb%fRljk)aM9BYju zPV?9&e~rnhY1Y^7aQnNzjf~dlhf`QIlSPSIoFOu>G6T)N!4VqQl@uE;<)Wb@LK4R% zK_R4q6goCV8cQ5onn{aN5F?H(P3xl78M@s=`YlV?kwoz-Zrtbm;uMcxJjLAX6n?RW zbgJ~^GaQ9&{Ng@y6A2iF2o1fcMXfsE^Ix)TJoI_#I|*S|(u>xK%>iCnU{uJIW2x5^ zm6A^!6^OM&`X6n$!sM!^%oC@M9i~~uPg(knwV2q9ym><9tHL4nQ92|hJ=Q72Pt*VG zSapmX!|xcAVoXX93<#r;I8H`BLo*6yC=8nRQIo^{UFx+e#_Ei)kc1FrJklh}0yvf0 z1dby~oa|v5MIouR48oAI?=xR26NFui(G(mPlUQoiI!Tlgsfcp5MyuPx=#)5$XiPSc zQV=I`h6u4)xFqU#5g1A(pQ}$?rrjG*`qG#A{tsT|kN)V}%+Jr$>-Tx_`RBQF=O#}- zeU0D$<{z@OdUVf>{~?XZ zDfajFn5@-E(vTns=mimF$IH~iJlLR=B$a|n*+UA4X6`MP4%jpcIURe3^B|lhLvbmA zRT4*LM}_0KI7*CKzDA)VonfLx4zE{IA!HU{ay*Gp$3uxWhS(T{IZ1FBo?=5Urqw2U zALq?ca{QpPWA8z8T(_AOOJ(nG`H@ehW(4pb9nRy8Ys1fh6_2Qh>6m9!j;Wvecx8QT zxI7t}8V&^Fr#qXDQB3*km8-BLrOQ6rc|Q(7A5+t?k0_Pqq_0zm6N~U6FLhiEwvQMN z)L4@LL{Zh)z&HwRJtDJ>=3smLwIWZGV;->&*r7^lh9yK};VnB-T9Y_o^Zo1Wcn$8) zEaS!=GsP;sPKPto6I6>XlhJ^MnK|}#!Z-VSq}Jj(f+@$PdvL^8|A+sPBh%!@gL|kW zc<|OO4o7K{;#x zg5mjvf{P<1L3fXKGo&{#BnDc!v{EiA%4JEM7(TcWFf~`?#;pNcJG*Q?{D23y{uROC zF69ZBD7$z{((Nbo1C6!<;V5h(QK>*$kyi>TBnl~9JXIu(JvP^N_{?WM$#-7*0ZDHk z3Os-5bk;dFv zW)^0-_VH)wr77R};X9mJS>)7I8Q+7VXDJCmFX-cFhsStz#eyM;|ZjK%@NF~w65cGT8yZa&KQi+MFI@%i2L^Bu+G6rd)iIW7c z;9|uz)o#HA*5cMdy1za~Hav@ z&cWU~hkM&J_cth2CMlQdT)upXAN}wpdYv9mT)oP<3m1s`13K+Pk|be%ae>8Z9V--@ zo0}{y&f^t4qA(;eF|O;71}Ro+mX=P@Z*?doF-Cz&HHpcR^(CcnDh{bBg0{p-m|axF zP^Tm3fl7=?ag~cipu|x51V;%{QXJ(XtVQdLG3vPvHc2uyRA!+hMTUtIj>3`I@RcHQ z^6wX!Bv|yDDsm-EUlHJ z|HrYv)F4J`t23&S{Au;n9uK)=zSUz-sTuSA4hPq~p)GfpnxEAoHSQ&~!*Cd*VMvU5 zV#T9tc%w&Z`S{RmbA-{zA8##2*il`98Dj8a&C!~J`_xz2{Nd|-@RQs0r>6009z^u^h>;2sIc2Tz?BZYB&+V-e)kU3SI$zKK2NJwd$j7eH_6*Bk{UTTQ54k@u z6zU$`sToRMkvp4fwAXeJOACC~@whTK&sVF63D{W9g)ulFw)obyoJ(UOyC-gK!5|2*yCJW?^;>j$@6p=Xq~E%au?dBOhwEl*q<*OB z4K&L0aD*a>!RQ3f%@XX^7I2MAni{N8G@BjbgDy+e5=+YsEWt&p}GX z!pt1gQFTKz2D|fUcSy}t~L0~r#?n27+}3R#u_|F;uk%4QGh;Dsd2@)_)68#jNKEoX^hsX%?A!SDUvYlx!6_cByW6ozyo zo6)h!hc00djy-W$B_d+4e?+CU%(?krVs7TM_!G0Zl?FR&52^V752qJqY1HRA93Nffb#z2(4zOAD9BDJV$B*Kk3|5$~!%>lyk=?!{>eG8t)k#(4? zdF=0d1pOQ)uRr?4uXq&wGE^3%%!gGy9@WpdgJd1%LS{p#5CWsqjPYnK)?|>BA@)g1 zG0YHTVXC~!F;h#kLoQ7WNsU4w3o`_9#EYMP zmK!&3u)e;*&6_t_US0-a*xueiYr|7dJ;et%Z}Y|*Z%{6mD3yGCZK)Is43d;iyU)_% z66en~SzF&lrx8K(h|b{wL9fH&nG3YqM-2KsrW+HKtCJ*&;r;9HGd**P#?%}~yL+rZ zTw~$XDGr)#&Yix%>c#`oG|XW11`gYOJOSlWjY@fff|LXv%$cb}#WNqw?9c%!cx31tuE?5&E?SY~|0gvH51mlR>{$B#k>}6Ihib<>pyL&kR{Ru$YQ$Q#$NW`m$D5(DYU2~H z(fD9%?HF#$o~T1Tj^608HmsrVG*bWzCZS&Sc+IU+tyGzL>I#KkM7Y1hRCS^uPTdEL>P(@WE}|&VYjFKpf*($!qHyB*vhZ7dX|JqfvO0z3o+^ZcMBb(uHM? ztfDkKhfWeYMpMvzCLEXD5ATueA5!VZ)JoHA-P^_OYd%$+#9x`^_UkXPdf23V?in2Q z3^lJpZRs?H<~DELYT+&{@qD$;xl)O}q>39=`S_#0=Fr8nb_^BqR6K_VF=4soHAbqc-hake(KE2j1JDW2!4+b0_ zwYmDSGt{e+U;y{-g-93f-+hzz{_hfW4hY+QVjJKUES{@KjYk-zbO#Ypq$!E)(2Vu4 z0mNVn8KZCz3&LVR>K6zCL8VkeshFAR3O8>)pxp`SR6I()WYBD~|8NV>?J?b`f)42q zV5(4{*K6T94&9*5>dp~isF<9oVuV97keF0(^~xoDU$JrjHm+58YLY+r)?568fAmcb zdI6VL7FaklMJo=e&&|>bQgmwY3qC;@bNAsk!V!Gp>GRxQ-Jw*AsTPZTxORvzhBQuS z4F+^NeU#%O9T%rkp;9lBx|aHEkxsYIyYIb6xme=-#U)C`5;6(!m8DQ{aY^uepLUR7 zNU2slmY@Aa-njo`y6H_4FQyy7LGuRf!yN{PAq97W!Qg;eQn68xr?-xkA335 z;D>+se^F5LtSHH>T1P8GwYEs%)R$>>H+cKye}WAU8MKawyNXjw6$bl#TK$ySsbcov z))^K=Obg=MgpGEu2;(2*S7JK+AtE{A911$0B4(eLi4z!4O88gGAFga@pDMVT2?O1%;Xism2acLglf&TcGG! z5|cGy#UC}NH23ZanW>RkJ5H8Z9`fmgkk~Xk2Ay0*(qsx5W9xV&WWK^xx&LZ-9%c9* zIjW$`u|A^%!;Nn8hn!RR!*>_~}FiZn6Yy}io*?jb7+bCjwR z^rDDPr;jly%cmCc{UULi&>QqQY#!hVh3|PJX^b@mbZWT&@E$YM(*(T%Q5e#86loH$ zxxP-S6YAv>v*#{yaBx8D=!hszv!6r4nR=aDA6#eS;eDD1M>KbLP%Dc>VZ_4H5*w@c zsdx_i{eYl1;LMpbeD1|B@E`u*cd<#z*47S}pSXfRFg-Ivx7)=Uc=z3R_}mx2M7dJs z?ZZ7DKYyNunHk!x7D;Mo9v$)E!77up3(QT=aR2^?{KC(Ffqrb5KYfO~w{Eeyu|cQP z;xo@ZPkm+z-z~6raLDS1w~6DJP)lNyP^wgzE6)+dF@s(QgvBqFPzvHi(@!iq%_@1b zEpUqGySRZG)%8jtaFsglz0bTHSsPgX78#4mv$d_!AVg->(KZ@uiWk{XtBzOBLSzd6aP2Dcb|_;6D(85n7=&STp~{-2#;}PW z;RP}OWF2?g3zKg!d=I{}VjXLBE&YLd5ZaN!HTO0hJ->;LS3Cw}$`nmS_H zdZ-I$NVP#%OYE8ybI@TBJET)n^wR^x=03t|^x*@x`?sim@hhY<IVnPn=jrWuZI&i8VyQ!tpAVnc#XeD;^d6G(T>B&W&I(3cJ&28?ky~6BNm9nSk zN`WfW@k`Sr`vGUq`*fQD{f^}BodYgCHA^gFT7x4zzrvv1Bj|)gjSA&*naPPMbh^*& z8*NN#aUDg;_j&vM`&iLMh?G|E2<fyMV>gg#5V$G#FpXu6Z{^;co z7^GdoFkxk?K-u?Dag66U6kG?tUZpl&CrVRpt_FPn<)5HjOQa>9Q{-3Y=JCreo`{&4 zC^1p>sCY#Vdl5;iOTX7<>iji|^OvdYzDK*&B_32rqY6dQ;n^$a*}T5X`aze~?T9pa zK%7Vh5k!&6Y8-nhi4A$-KmHOgz3~S9b{Cx*;wZsrfsRw+Bt?k?Sq4`Xh+{(>JH+ne zeDSY-jZSBuy*qywT@<*J7ogc8+J6tvUuREun5g>y$P&vs zS4Oget?Yo6a(D=sEd6V9koBm6#pVh8m@pg=1bw0?!1r8SS7B3&)j1|dh^!ACL%Y*s z$5WJ}m@te-Q-r zhd4=@pF4$DaJYHnJ!YmCIdy6oecW&ImwHBvP0H9ndbME|kj#|yUfIy?;n6TGpvN6MzYftjt z+i&yZw|>I*VUNd_7g$?eBU7%nzFaK%Kp(VD4$}nNHj=Mjs+tSQjua9L=mNui?WcU z23I(Eu9JxZaZ0LGb`GUF^MK|>46!v?dR}B)*))ntk~mA>D?zF?j!;=BO*u$M;V372 zFW9VAEH(*6H$#;v$3coL6o!(NbTBMT*J-!z zb8l;h=dPaPPp;p@pPOU-?i$Ub78jP6dG_NUr!iMzdUl%EfBYspYkNoo?!h7PZ~RlD zE7!1}yUb)SWN!WpZ+E(QBE~j5c;zw!nLVS0Qs^L|{?y|%AFNU94VasmrFs22(QDr( zOf1!j2HQGh`o*8;Y@Sua)Lz+-;qW0d>5STg_&j?Gi`!W`r9?Xf>uj5KC@yphY%QC1B7%1Qo(?r{a| z&+w1_S(w3puAwvxV|1#qNlJJ7EsEuUh0{LWZpz`-D(i3Wu(orX`LjzL?0!K1aFw7R z6D0}Cv6L$X{F0wn%W0$%6xql&cJ3E%nNt5iz@ zzvOapvdHFP%nx6?!52PxiRH4#*$a>1)@!&$pZhPpj3ZsnUw)iZSD&MKaGxLFcnMRP z!t*a-<6WL9by$CEi>=*l`c9SYW)C+pSjvQE>(0NReee?HzCo9-P^Q6d z_aW}~CceB+bz+j!XRmPkMndS-DVBPaiW0|Y3OIyaaO#;VV64EH3^7(N8On7iRTTvV z?W2@IdxtdHMMz1kvRfV|!xb3;Rwm5O`kY@Xa?}Yp+E++?zJNiV001BWNklm@NdZ{RVYEz(sOWiy2;Lz<7eS;Saw(hMIy!s19ptW%`QSF1zxls#VJ$h`Y} z*zz+}Sv?gJRWiS^F?pBykd$W)o^Wv8LKa*TD#!R|4?|ag5(Y=6q&gx=Qgo8yxrN+& z8ly@@v`I4c7Kd&>z%N&EtRRd-qA;X3Q6&yK3_3Bc<54boARPKpO0`<%@y9Q7u)R&m zb15i6JJl%1<^JkA&piJEaT2q9_B3Dk!k2lte!zb7fc1y#JoWTb+`e(0*_AnzqnK>e zIcgqI@QYwFMR|Sg0rgvRJpbv>;}u+Wz0Th5HY-aDeE9C`G$tnrqlDL9 z`3_TabF>BtI`+7E>n@Kyah2JnWopF=hs{0YQD!r7ghY8|;y7e;?H;<rtVKx|B_!HvtTre&vjPZX5muAxm^94?F{_bM=Rk+VvN@O(RL(iwib?C3rIQ+7zJ5mt?o z@nY13^|Rv38HUS_fEps>P1;N?Cciw6Moy7?OULz6aqK@m0dBJVDc$wvs^QRMPeiqjyQIumx_|gn<|+D^WH zlcz3SqFko{G|EX3CPo?`ltZmDiLwrH{D7c;h)xWSBQx8Z32{*%C04nlX-dKO zner5^{Wd>-ZH?!jy+kyKNt!#vu|>xzmmj~v?!$Fl-(`QV$$qQLLaji#F1Y<+muf|0 zMFFW&78hpe9(5QbEwu3|i3x6AU&nJM_}B}J{D{*HAQgvOyHpB-G)^g2%A}6R z;bFknfBy}lC}d@2frG;k*DomBH85KSAL!T-jAuwE2fqgXf|I$n)%5<1%!1l zXcF5&Br!ECu4mDyX1*af_X#*!5&Wy)+#|rHT=5Ay5h5;9nsShy$jo&4N7h(PoZ63A zoyq*5j+CRum<%x^vjN4)4m)8obH7ICYy0E${G&}XQe;grj#SyI-{|ARNsK*U@&RF# zz)n-7Oo)=0BuTRRU9E9k7ep53$iVFiAuOKb;+M4q4bGgO1tIy$Fa0v>TkGs}dMwSJrhTxD4*Mi=in50G!7f3+i%4Uu4B*r<2QjQK^ySWaFZ`%=ZvP$~1zt{7sGa{CS^7XByK`*zs! zh8QDph*4kYuz@KXjrEv4=%=UM@nF-jpY=~s+Q#e)!pc0XV@GJxW7~ij`}xcxO;O|j z?n%|XI8(uw31HX*@+-V)+#!dd{>%YMZOLgqt0h@On zoPM99LXD}C;e36DpG?*`>ULQ_JVNV`b#)3UKgL9rZOMSYEwgZZep;j)Tm1JTXwl_5eH{ugl zri+Iuy;et)DiN&*uYRRD{BLO zn5!>xX5tRM{T}Q0KcHMNtUbI#XMMoLq#~BtYQEdi6eo*lm7-+!J_uujh`{!2w)PSr zl)<3$jg$c4P%ii^%+~q2=RSo}4xL^Xr%>eVrO)8XcaS#D6h7O>iV%@nI?a@NL!h)^ zv8~ff>X&u0&gqo}2$$c9as;Mw28Tt&z=0LBWdb^+Au2JjSG`F*CZ& z*`vxHFJ-hnuGbq5sN?GvnID8gh@Wv-4f&;H{q#a0MD{z5anYFGB zd4@s=9M`22?4^zuRGZZG+vZNv=Kh6lbOvz{yGm>Wv0br^)uZAu%zXK|pPy z0s=anE{WExTsqIpRE>jni_Ps_ZhY__KljC7U}0f_&CQ3rf8z#~YLPczdj*pwOwTQH zYUwn7sY0jMV`5^0yLay)bjIB*`$eK+kwURV8V9sm`}oyKTKx#W60`YmoyOD@^=g&U zphVDVbL;wb%B3>ZN|mXpNu2sDNx4d=eZ(LL5voM7R%N16A&5F8VFV@{2uvE|IErGy z!*g6xonn>5Bry&WPbvcR=yzgF7IxBDgj6WkAx*QPG&_v4OT{p_G)(PhgH0BM%I=LB zFVt}yT-QTNGWFg#nWF3ntWLAwsvUNS9e3LcDKOTctU_xug3k+?!RfWm0#sJ!2j8&G zNsO{jI9hzT0fr%JF{t;k;#Srf!LGB$Paf zZxeRp(;O65Dz#WXx{}$Q`#jNDB-uGcMTazJ%FLZUi)?nd*zXh0PSX?` z$11vqdocG2X3QH@O=lQ!%GLL={(ITGvY3(`{X9G2(m*uep(K6#CIe*7U19_-OQYO>abSh(!9dbC@DQ)kan za2;B$Hje7j3j+L-&+@4X>stq0JU5S5blK^py!yr}ahfuCf0Lz^66HdT-q8_<0W2)e zGB;o6!RiKK64LI)CFrb-a zm3@tRnafwMaPQ$J57zf6`6Zq_1I<8lZ}o`!M1^~6Tg=uAeDcZ1P)Wkv{0bK??s00V zfwqe0e*R0u(&f&pZ_pJTlxXt8$~^DA_cpr+J#O7^QZG-D3WtNeD0_D$KE~Af^p|Ie z^cKpMIIcoiiP70QE{Qd9V(Ik*!ht|1hFYzNFqR~OB+7dIYQ-Y;qKoSYWTDSvPoC!V zL6GQQMSMf@-Bg5Cz0>i02n+ z9_>@BR&a|x-F^p&B1$s8u`r5a!Kc@1ffa;dL~s2eXIBV7#!E5GFhTr^6Bnx^6=pw;TAsRW}_Za;j; z&2N93c5@pkvQh+-8p@>-OViU_x^RYq?-FTE99t|71;0$WSiy5VHrJc%?C#)-1SL|U zD8*GJ9M{2+Q1X4W&X})C3Usb!WNG;f2?bfG&2>DK5hOZAsN8Jh(- zv_@sSbR3*a#q%6o$Hny&t|M`U#5xYr3bYL{i8v8Hw{lFC%jpkbQI5nIP7%tjzqaW8>qn z=U9RjR>A5EVtG)24g0#p&oC zrJ822D9RNCuprUt~2&Q8N?F^jC@ZV^;6)@=UeD<%tHKr+EFl-y!_m=aEaxy#4YUT>j#h zvA##KROG`uAJQqVFy%kb72QP8$zx15uVCebYAqPrB4p+rMdhjcF$Sp}OTgvZuoG`@ zEBLeG^Z#5!>GX7oD9oBXyh6yqgYPhCzlACul9+^EN7HX-Fm;pF#vp`2N`;f{U5K?M zH6hYTK!>DB1WMzV1SZMN&5lGVfg=sdGkBiC@dT$API2ppZ}RN(&(dkfS-qn5SX!xp zw0K32?|$zcCTayf^TOj)r^>v0eUJTvfQpS->`!odVU{RqlIU3uk2=JWW^tiGeY(Q* zyiXbzSbfkWPBp*q!f8640}5UlB@Ia&BmRHh-ZVzC>^#$Z&N+9BJt89`m&(lAyQ_L% zNOqHKin}O?lE+fDL=>!PxKy4`wvd$Rk*iC67pv+9;7N zvYTS>UEQ@WSy@?Cxktu&*K>}4+#8XR)%r7n+5NA(E2A|@v zhtQTFcEPW4@8FPl6ceYGvrBF8PSd{lDSYQgII&A+1yXuB(kICnrqB;TcF|drQP-otIY$(2lZIowy21cK$-{NVg#CotyaHp3#xL+ZiBkEWQ&Qmh z4uM}{VQCc*1SOxn;g}FZ-Ej%3B_8f>Nqg*awO-4K(5JfSg{vp2W;s+Iay#p|oY9$~FhxARx z!tydG!EiVx%~GnR3UQPmOJ!WgrL(ligZmq--&x16wrMoyNis=Lu2QKsDA($Y?roBe z#_Vowqx=%JN`)}d#Bsqty@+&N%7M@S@X!87;wYsY zxHMWdR!?eg6ouNv|Ci_4Yqf;*xue|dwYjLZ%oA% zG-?h)fFh<;mZUl(F*;wFBav8?uqa1h^aMPwir-7_JWf)L);Tm^N`sUF-*fSlgH@mt zUHH=|s%&L3ygE5zN`aCF<+wAIq%OurSgEi=VQex5rHhFlu~7CwB8@0mrs9}C&{zYi z7;LpYR#+sZ#K@1oT`m6{q%%^Zo?(_U9XzLgyy=SF92=@;d7n0~RRbXl6;U2nEQ^87 z9P^7#IHi*jH9Ou2iYZ{}vjB8?x_n5j0Mhx%K8gfBd`uhM)i0pC@Q6QeQjCIo06G?nC6s5|rCCTTAq>TqjK;Ity*0 zc#PcIg3bHf{wMz}oLpw>$yJhsjKcHO+@K2v) zc+f)|O@DuzoA1Agd-fuCcK0~3)ZzZt2A}%!7a88UMVM)xTv*_ll@)rUkS$?pv>I&u z-fz?V^cQHJJ;#gBKgo8l$5#1e9uu$O*g+wxn^f?B7Ue`FH*&)dIgPsHqZ08q)L-ZHH(Kqc~$6YSJvl=zP5(gvDmX3@!y(X2|l1 z0z*oY#Tc8Q+zi=JnAjrXTzPS&M0o<`8XVW)IS#dYhi5Om#9VEe)2j=_OAQXYJ;vQG zI;*m_)Mlh5X`JxEI~!;@;+0R$@#^dQ495w#?ryO-e}YDyv z3XJ0fE~z#+L79d57I8EzIE|JpNvKxKWQit@6Rc+`l}hx+ z5m(o@k+Q^{-4R>e_h@&PxV?42*|i0lCB^)F8|f;9(L{%boIQJ_g3Ok9HXah{kXqnDQo_ax$1zmaG|f(inZJ*466T^B-oc1UQbqY4l+(s+zrhpbfNOmX zWs3_8M+xP+i?tdh!NXFkRB#=MR1W9PoaHkwy-2NE1Ch}?+~fVLH+lX24_Q31N~`I! zAm%`Nd5cJ#fMc;LMW88pmh-Ct&z-f*x4=mSmmXMt`;QJ8XFfpyzULyPg9u%u@Npc8 z5gKdrHM!RL`xYgZ@MDJO3nQj$ONXyQ9_a=7_IRv(vs zq_ePqkdi2h7!OCJag3w#n_a0=Wp8JPppxHxFR``VW%bm6yLZ<)aq2Y2WCVf7-tHDsXvTwWs)55?ql)qZypkkKN+hSB;&Y!H zGaCK{Pd)WKXU?DF+u!&j4tpcUqnNp-;8*{vf6V{=Yrn?Y*;8aT<*8?%?&6 zp5V#npXPu2Uw@OG!y%P=ong02Vh@Ppi1$CZ%t3E}awWzZq+{6Wjo2SRt?UyeDJ^TL zm3*QM(j?!6WF}9&Tak|e0*kibI3Cto(j=Rv-VNY53fIlUrpo4QUtI)6tW`&TMyW7P zUQ_Ei63_Ke!p{pD&}f+qfJrTfcK9K5sc+EuK zdE>#Dd(n^wckkdn?t|xH%!qmkp8M2isg#@4nr)UARzU?^y}i!n{SAaj za2!k28(=;hklen7^Zl!oe&rvNRvUzeBT@%UJ!NnA4!`i#ukwR8|B5}~@>ryJ%P*tS z9c)&@k75|#XSMMHx9{!pV4R@JHQxNeyL|2G#~9ze%O8LHk6Bt?qup7cX&g4oC8{S+ z@Y)}Ji_iWi{{^ubQLC3p9LuIY$2oI=WBU2;9$O5Z`Sl@>MV5-|b+XPcKI=z5WjpmR z+rn1Cv?AfJD}VSg45f$rV_Z+*IC)cuED1z21sAl)a4Uea7$b_CjX-NlmVoO!BsxJG zgDWJ;fam1v7knpQ!?+GwX|g0g#k;OTx}b!m=KAbC+@$1Kq#YpbnA6Kk+!*$_yQ}$$ zmoBiqbA<=@A_n7-mDM>`PI|a*ndJq^g(o}Qxwj2MGwAi%?;FB6VmL^!cr?5=(O98e zh3}O)IPCM@TeqnHu0hJS+J-dkDU7D?! za@pW0K^zLQk!EZxI#am88ejUU{~E8f#;vl7HU0(Ur=U7|o zAf0^0Iq3Jfxv{|@9CLcnBRULu_r?PTVMwdt&^eJZ*VdS7p9o27se|a1+1a^wFL~zTv#c$z zQd(%R*gnJaPrpb%3;FFo_xf*f$btEWn1LKB001BWNklC!>z$dP9 zW+2Fb$+b-_@>Fi_5iNYA;>aE|y)jSiIr-2i3I#$I1Aw)1nlQIT3Ruo;(q@r8I?agV zkT_0B(j>2pG!ozUuu70-8OB(`I3Y+}G6Pmy=2~@vQk7I^gu@}_as{gtj;lZ^l5mJr zf+!3r2R=q>2K`+Qx|VXSMx|OJjWkjkPMti16@uP)K-lXt9u9DP2UlibGF&%czOz8d z^Et8D;U`}C2?l$+c+WgbW-T^Y8t_-{#@wHg|4sfO1(}SfbZEWYq8DU>FStoPX>wzWSA~5XOgeIvw8l;di+E z@E%qQ<`$MwQs9@Wc=Z}d3UQ_gof79CKgY|Tdz;t({0d8}XIWlcWM}6ggJDRcUSVbV z1Z$_(@Eyt3%O7&}<{kROg#I{T7$pqjjFtHo+CmgZ#BoZR=DqU9>bzw0~P(l>LY#u1gEv$B`ig`-n`z55S^5BFND4`I>pi+Y|GH>WB(z|)9 zOs?LUf`Kbc?rW7Y4=+uI3n|331j5Q<*f0eeO^D)Jwf{~Sn*V>$Y+3OjE^^KGXe1KH zdgqT?ab)p1(v$J=*q&pAZFgn$#7}&>*i<(J>qyA!TIeY{!M#~b9#ibny9|V{kQ^hG}hEgppU;s?)k{o zT4ARxb<-N;e3y2-oydw~AuTH>K^(A-OR#zt6<)_Hci1%#+26X$OV6L>FSFBZ>~_(W z4N}Lj^TxZh3Zu5sD^lYdKw#$Q=Q zoW983&6|AV&N`$d%9v7CEag%v2oO=QZ=Hg>3T)J_cy`3&kKXIDxy|%$P zG;D2d@x%)qE?wSc?L+J1nPMti7 zasm#zyR4q*K&H97eveke#dV7S5EjRk#7T_7QmRzQQh_hv?AZ=i`hEP8M{}XY=Kh$o z&pgE_8M>p|520WknyoobJ@#L+ z`q*={YGs_7MRQ<&rxaBiN;~xwv&J-T}(P=ZGN8R`BR)+ zZS%*kUtw#%NB_Vh(UR?bNz{|9RSnBB=JvruVm&0FPbO1bBWS6ZT6+N;7>5~W*Vg#j z7oO$ZsmGA2#1CHkOAZeYsnu)Lyc(Z<{!45R_IUr+eHQ21^oIlX#s?gBLw@q*pTQ{j z)_1?d-MjmsOANz(s2JQiMdmuJ4-5}u0glJPzF~Km7Ak0h)j{qp#LLk|$BINW#^fq# zni{m)VI9sMX4Zae@~FH0Bq1aDR*X zTt?LI(>v(m1$El<^Yk5;44;MhIifJ3F;^vxBktdSi0hZQv%Ze2JesWroA);Pi+}MO zeD!C)&d&BWYilcf;u9~ju&}_x&HL!ZWiDU7#<}xreDL1;Tz9YW#FH0LUcma*OCSXE zb9F}JKAjV1c(}RF_uqLBRhg$RSby>wvQSxP{FyTWo+BH;#M5VIL_#seM9o%u9@UA?41VH~7Aaw;KGkVj z+SM+eC zTC9D9sx?!CI_-Kd1}b408jTbwMh$W69tU?qL?dR@X>s||4O&YLvODX%^75y6!F`gI zr6rOm!U)Oy!ZH~S&820YTPsspzlZeRW##k={evCGHl-UW2KNUDdi=!F3a=jQla3%sGlOQ)I;vRwPu&^*swK3*{xBEB_bbI?OE_689y^k~?go{!hNs4=+@9@}}laxJ&UOZyAmyqmAf<{JV zPUA&&uI}w{#UAqb6DN6admAqtagf2biTKLbK96h%{O-5Dhe;!D+}vTVc@OEnpI7CJ`JBW`B~N;5M|GQFj66mqgN;fV=G<|q?&Y#=qpkk|wh z8mur#N8x!6zVdK`5`L+ahn}QBDHjA}M$;@;2!a65aZ$>mvjpGw@q8a4C8JSH$qg8e z`d|!!7of8Yzf_@GZP08qas|n8Xfzu*%Ar2Ln6oO4rCP00DwPPKaeu3x!Ay*0e5I6&)&Fp8*^e3sfZjD@q z0gy$*6VuXz{43)mDe6g?elBt%RIXN{BuIDKJ+6%=NmJq^&IeL$@@sB#JsOb0!H^ZL zJ2|pV%&rOrdB45Q@n#Z%HWmtKe=eGdBD|tL=Am?Ucr-`J^J5BS?jz07ToX^JnIOt% zIHVJQXMx-@_P8aqAZ=JX2kgVR=?56*H5pwRxub=)WInw8B0bY7$4AAUhMuvNJ5zY0J<|wWxTM7I5@V z9Tkq);=ZUU`3dnV{mGjGm+*yfBGFx z%(bbs=lJ}~pW)h@-{;|t4`?qhu|G_x^e^+J`mtTEpXbtb&Mx5b5JU*0YA>6G)pwT>*OM?Cvhto!f~)g(pKhhIiw>H zPHyN990gVp^(=a<3+Y^-LrW%8jL?WIo#F=cq;pl|HIog;Sfkl|xJ$P? zV0F0-Dqx|#%Ij}E^#JA94cN7 zX*IRE1ukBAnmZdGaG3SD_PsZ`wf-7^{++kk8+K7F5@nLTodeR$P;D&p=`a5Syyh!J zcAkf~-k@GtSgcT3R1;rSON zdYrL!55h3wUJ}!oFH<#|v{hlF5%J#kU(pDck;+i>6{B9v*8U;iedApg7duF)c>A3< zSzA5D{%DBr`8?R&WodqqZ+`E4wCYVBZ0*oH9C2^+0Of$u8KsiMl2J-h78{oJkpdhX zJTNI)W*84LbS8>EZ-v4^Stn;NS~JrUlRro^Ye=;w%`904j`^64Y#jB3Pr@O#ctD9s z8d->fqYBD#ro-ceb2@2-nW$jQ1SW*B#my*ho5`z4iveBa_61|iu?N*eIZe});c!T= z+$RVsRKq%zN`=75-$NxO*lgN??z)OJjS)CFu8WciM|oHao-at!499WMX^878!f;Gx zz;R<*^K+ET&0L@o9#TqzphVp3W@CVvS&l79I($W&cVMr2(y!-Y$glWRu;sQ$xOAOPDo44;Wzp%)KC!gTt>Pdd^gYR?h z)M)~*!otcbS8m)S8;)^GJ`1fTwQ_(kiYyuP=A}QOR4MU~e)U)QgIC|B*6HAteX{Nd zX~>5+ZKzgiq-au;5e)}L|F@)EuF#yHCyvMY%G-ic4#v1xp{P`A1VKQO#EeEUsWzlK zA#ef$-z^SQic+bB$THG6EkbIhSg8wK<>tv;o0Aw!p@2J%BGWowv&+0x!Esd1{uNpA zbt(_giQH3}rYT91kfwQSRGLNTEJJ4+UA!&@Rw~Dnfzbvna@$tE=+1|j%;s=^;p8jr z$#YT&ag4>JHUW7en zL;0}>os^UqZAj7#iNSXTLQPw2u_kY667oo0Qc@zFHsxRmVfHa*k6I;0Uo5`S8u}a@g^T@u|O+JoEmoaGL-93ZVD8Z!G6MEtI7*cK23LPNR(`mA=%LhW0}!fXp*HneEMa} zN@JJr4hP)HD(q|+Zr|G>-PYJE*KkmbMq@Vi#%Pu3v68ZfQJt@X`ejBxYwiJStg7^ z=H}+u+u7sv`KLLt(nkrwaQ!Y{{mHLz@7^75UHgz>f6TcvX9?4YL}m;IL%O>MoanUi zTuHaThpLpwl8oN|Hc1pwYb`MXYBkBZr!O!V9q`__zmIXi^IXb-hg1S(EmEhv_4eDO zMpLd;aXc50Xd|(X%iR1ToA+)p4o8eeAr)T|C`H9@;>iJlrx-;6K~O?Um%%t9O*LVZ zhta|?%CUS>ShA1N6gUMC&Ook!704pdWPRAX97n0nA$Wugib0vrxl|`c;8IDlruG=lLKWA z*P5=kC*=rc3ZR$A0!>H5>mxvbV^}zQOd*|&fx;f4nx-fzD;^0;O*C6^eCVEfS7$h? z)*eIIiAU~#kG4NeR{Ub-@A}A4Iu%*%@gGzw{Pr5-!&^jA$|$zf6fBt`j@Rbaog1ik zKjeen7VCG{3BxgdsYc+}C|gM{jZpoEl!c_?xa^J%&!2gmac__CnKrct*U^LbkefQUel^Zx>MBQEG9eJ9_J%cOO zktWTBMZpo_0fQx*ZrP6d|0GuE0%+z=J*Crl)O5RH3d+lmIq2lLE=b6PqFO2=-3TGl z>9Roxfl>lB0VWHHa(vF6`(;j_{`cwc4cXfK7W)tXHRJGrQ8WbC!S@82rD*dING(y0 zOPolqUEk)(wK~#Exq9mk!&tJuxxvy(ljWt8+!|iR4IJ7Fa|pddtySTLPhRA=zwtIF zmIE%FT%mWEvcB;UVM>G;q-$7SayZ;iD3ulC*wAP+a15M!>=b)@A%4ZBQu9g70sUd0 z!^05>LAg|+-y3uL>K#7y_!6b6PZ|X5@8vBvnYPHnq%Wj{5(1NkBz{1Bp^b7qtmDyW zckqKMXU=^BBO2Vec>u;hIlq&8ONF=HDpCd=~6Bk6lF@vW2MvNU^wE^wJyQ|S2#Gz!%;3$D2&PSEkIrul_y|r&S%VYz9Nzy z1U2VleGuvbdm_+C>0pgTk*`&Z)M-sRaPdP~G;QA^@ixllL zI!&n68q{hP;=Kd1ETLMfVNHTlDbt#pBTF^b8k7*AW0EA{{>DT8uiyG@_7Aps;<*bv z`TUFg^nduv=%B>aJ9qet7=pRjYWASk} zIu+~B{AY2dTZ;ViX=Vx+v!aP94~a_4lmyG1@@v`K+y+Vu<2le@LZVrs_6W|FiF+OAQXrJq0qr z7d~^#&(VI$vUYWo`&ZVr51_a7Spt zAM^TNc_2l=g_nPp#zK>O`~Q~A?&Uyot8og?n3csZ90{V%Lg!1gnoE>DLmWL#cejG; zZ&9u(qz8VGx4h&-k0gy0RdpG)BNYbft>4SAno~YAkR9Rkav$SFu^Hshl&TFXwKgZ$E>K@QOHf{7ee(flF1*0qjSmqdeCJR8AJ*5elGud#r8B(t zgUeia;z^9$!1nqWBk{|EQo~{4d_Yi^v`RHf%B9irc@T|xct={vAh0H84OZRp8mV^`~MtAWsFlroa9xSc5;)^V6}@* z4E3gmbR^wDLK+*8E{n^C)fGXfZE&>Wf;vrGmU&||zzgblQX$fe3{9d#66td9K@80r zufCxX!lztGa2$`%e7eT%+Y$Q%gEbyHap`x*xT!!U8Hp~~i_)cB5iFhdk%1vl^B6)% zEK+$?N&$5@e+cL-VXn1Ev$}vEq|{66WO0ToC7$$gM4mo1g2t zPZbG)a`JHq*B07*naRID(V6g2zmt@=<^|^X$gIgc2(^%;6r|({3xpIxKy!;A_t7q^^C4>+R54+^= zl*RLW&YZtUnpyh&A%FC(KjG^?`_n94xJZ9Iq}6UyYt7Maw}~^0=Qy+)4cc=pd{=U? zyG=PLqch8}+vo1RF7vG#OQ*m!JybNH6x1m%&$IaVf1YUb0cjKy1U_r0PtvKEx%9(V zxqf+<#l;oswKA^j;sgOw!JQlLv%9;=u-BvHc{oB4CK|_aP)ZV%0zB8lTE(zGW<1Wh z&|#F2X1Tg2MczHn1n*UZnkbaGSw+hfLy>SCgvo6#NN}W_-usQty~3$UbI-Ll1(6}b zW+qoOvz-25MB&5~6chk+3@)Ejk&45U%&%Qz3chZ!>d(a+dvvLj-)}!&r8F+SSv51L z9WC;0fr&ceWafb=V`pLXVkSf)j}rJ3#Ev~KUrwq_C$E1jb1#@yZys?=<&qaV z2TFCsD4h*KJ>q6PmTsC>d>;8pkMu`#Y?XiHJ+(8#_M=6nGe6HqLQ+f*(#Ky31n+uJA+(WVM7p*CP}VWd^Gh&9bGteV1ruh3A`1Z+1uTtG1sJjXem`2T>kyPAlbTvqe3n|dw~}_9^uQ+5IP=vA6&*u#^_70 zqIb99m;N4=EF!#dli}%Qq}7=20OdNUxdx~DbJUDr|LQH|xyO9bp8I#WF4DPSy<)yFaJk4!m{(jYuMz6xmrY?%FhpV zb}FSy#|Pz4LAOR{*ev(&DaR57F7<|oazc!)5Df*HkPvCoQI``JAA>9*OA^8`W!R6% zN**76c$+)xw^>>|0ZQ=J+uQuy*PmwNewSN!cX{GO4J{qQMBuqTmVK^V-r)4jwF1F$S%ZA}k~*`4!HcKE?R*22$tU?^w`9QhC~XgUOq3 zEI5uu`T|dY>k6zgAG17@d$WbjN!PP}sgJCzittk2<^-8I3J>TB0LF2ryu-;rYOO^H ziMCljm==KaqiRxt?**i3im@84CrN!d^{FOFLXxDUX-1qRB;^3NP&(o?L89q)Ln@UD zLP*jyBpMH?1l6h6FesJiv^!W5GMwB-l*Twd=qv&h;UMAF?|hfr*KhOED=+iuuYQ%r z(pg-;LMydwT)W1-Ya7@M?%ue=iPaAGyCeSiuU_TT&%MCO#Whr^N~O`l@qEHK{sgAHK=b(jw11{WO=a-b5k!YEF|kK$ZjM&d=hk~~@vr~YAL6(T zo__in*49?=f)Z9J4h{}D-0u?iN022{DrHQTkP3&2=jN+!w}cmz$&5iWL>r4S5}jnZ z|4}J&a7daXVT3>miRZW^Mq_neEvlp-)fz_@upOO;nWV}G8!07P=Zc$_hLplHs`Iup z9jE9dzlO9<@~J)zD0jD_4OCm}vv_?2bRVpOm?m1HKRPl1Xm)URTFe=OPmv3N?= z^!Z5P%cbCsikT2dZf2V9CJL=L=N>aVw4$f}zI?t?(=PI(0Z>k>MwtNSC%$eeW(Wxr zerx{w$^V9Y*bviU%^azhGgXn|ugS2_uHu=&MTx?LEFNiCnvUI8eiBWXN)}v7v@Xsr5fiu ze?<4opJC)>L?~`6mr5ld&O*Fao5#;SL2vgVpJ+DOefWU!Kv6E8W1$sr;^Z2e!ws5` zy?}G-8S3#rM?XBElPR_~uVR1W|6ut1C!w(bn>R5*1>0&c*zeNXyw72~!|%QMJ}qs~ zqaj@a<0}VjR$0RY zo#(9&uTlwMr?*Y7ufYh$qb`f5E2N@daXILN^Wmq)II8-Z&-eE?) zTIS?Z12Nd6lCV!?c}O?F3+e>r2BrEuwS_eh z0VqXKZ!zC#@U8#%+uYlDNN>2$=G}ctRhJJxe4p*TF2DMZeuabGke~bcFEDq)W2bkY zcdpzd%@moh2#usFJ;K-!jx0%-UngZxqXa~0f-7OaKcXM@sYd(6`Y&iy?-FM%ZrpsI z`MIkk@o9Fqe}oBd<4YG~GK^-bP-tVYGWWiDE({NIf7obXab3aOyi2`l7>_dUk0I#` zmi-z|P$i5lZlEw$<9j8H$Vjs>mJtYz*9x%1h{{reuz7>bu$y5MkDzAIRuO4U91oCg zLYC!$3&%*LgnCWz>~k*XPFcbKOkF@42B6-Xx#b;c_B4k$sqhJR~s{nj6UX}bh2iVGhNR!DuOCPP?Hs(v9k!5Tp2OK zeAJ)y{}K15L6%Rl9+I@K%g2uJ%jFh-}67u|9O5-wH8#;Vh!l3t-}qZ)e$RPwWG!23%7co zPQjYjx^?*Qyc09p`8L6K!hsVLHvX*NR%OQ+SP)~sWtAgMKxenF=* zs~X@6hm(pG!{HEbIH1!#PhdkmSW39=r4yt)(TNSZWhTEpA=E#?3qTc>RsH zdFH7nSUs^$Q5vGC#@*X@*xB1drz4*H$P@U+ppC%uTzNng$2{E2xPE=Wm2in#Z5JIv zGdY3pd9b{M&;^kn@bLCc{=q-^J$ieZ$F7{^qt8A~qt#}XrcBZ?!~QO!guVSCVc?;P z8G(`nN)d!1p$gGLLRpfhDdX{&aXO>WB~m(%FxpkZI;Eq+I#o)#lFmV?%nKyK1^lIV5WWNV`qf5P=^lMB zFdJj=ggR&^TU77nB@XHXt{JtI2W(QYP{DY>Yp+1@u8_hUB=4Cgn2)H9i}T)L?dZIy zf{O2YBoTBF+mQvuMqn3t_lIS(cA=y|9O|PB;V5;$=oJgp11*2V>-+k-$GGs+3#_cT zKIJfI;!6)LTv|;?4`CFZG-%^Y%0;@%yKnwCJkZNf4#@K!R?ZNC!1DsUu!i(%D4ApP zj8?r)=?elB?Vt@RVVb3&Ay5%Y3O4RuN1#|=KgS<`^#@31)FVN+RmYfs&Y6%`uU*3i zmi3j>?C2g=Xo@1^+O0m(!yc`q#>34WhQpM4ErPNn3;`lMC3$#nRt2s+>TyV;+2n;! zJTAyA_dgr2!x=-;zc3od>)TRC?DzhC@&&R5|)=wu(Wa#6}B)^vD4q< z)o*{5t$Q!?*4wxFFMsXV_?>_DkJ;Y(LsnKh40}^P^TG>!=bJAvnC8^#4T|xUY$}Y;tadCSG^Dmif9fOUlsFqBM3-hfVk+LCw><*=4vnD4 zWH#kQC!-Ne+24cyZq@IuZDp#j0$kQ&N}t)ldCa6xNDS#Lr{1z8p(auRqg_cmUS+w_ zB2Y2s+D&fvcZia8tdJNo8j)nF*~Zod!)r5QBvx5G43Sifa!IQhQDz!zGV*MOR2mr? z!qUggB*L?FS2gF)YFbeYG%<0DPOHmKZ;Qcrn`?J=2u?=q+!>PBG&dT%)WVdVy?u6i zd#LK6sIB9WD(m4Zg~H;A!X5I~;MWW)u`VcU!Hggq|J#7)S6YkERkFSsAdjJ|q;kF> z_Y*P;4;K#ChQ=O<5DHiCDuuv^vI<62+D^rXlm{*{jSwDDR3po#4pW6h8%wD*S)MbS z&6rLnBuPx3)X060tk5XGMiSRRmj}t~Fp6okI|N}=aWNghT?QWM#87I@aCeK%2M_2( z0VhwLX8A;b^aNh$^W?LiLX>ZSaKHahT9kkcP5ay#Mz=SxMM+T@q#x33HK;GOXrDR3 z-FM&Na#AO$FXJtTC@-MXS!OhzF-s>bcbBnT#JhKwC!c(hr#}2)vb^AxS6^j&Ynvnv zdHks-*xTA*Iv&w#G^o`R%2H4Oz8_L=MBKbLWNYtrt~_;;C!dl85~9c_2m*%tJzjg| z4ZiceTa1T_^N&8pM?Q9i^N*el+_f|0oq#X^(Im|#;dU! zYhgCc7*8^a!d5M01!Z1hO6$CN(!HmZk|;Uvk+=B1s|=mvf|T!pw0J_`NzbuOrSo#@ z!u?)a=gvQB-1DN;8p`4zfaJCi?($Mrcq6TyBCmYqhGZ!giXp|puw{&OfNybFoh$L& z;V4U_n5#PSgGWLwgar@(+zZ1p0=bBYs@}79KA<1)gvC({!{O4o8X658>vEqDkj@h* zoG*AjIEX`~QXC}h%>o;Bfkiq;D;>-q=9uDn$SStN9!t8LLyVP`3#z3#hK@SO_aD}% z9(?tqO;krk(?j0sfvPJG6=Hj2jH+G%$3smEI_?3c>foE_@KC~&cq>bE{3(08Io*EA zV3zUxO3AloP3~N~%~PLvj-u1#ttnU=@nF#BO1pudrubROt!uCFGtYk%A4t~LnWhuc z9NO#W>FjQ^)E^>FKhCbKvw!0zr^A@+ty@gTL)5Kz5&J`Q86ky-4QrHPgUwb#I-K&l z@9}18`0UaWx6>h;voYt|EmWh%^Ur;pkc?hE;_M4Q#^phuyXg?EmniS;^U-q&K^$Vm z6et$F&gO9N6o;Zkm2zbflFtHZ*Dh4)ipA02a^wv9kq)IV{QQ4LXQ>H7Q5fkU-OAvb z2u}(Ss9JbLQmo=*LPc5gHaRGVnSIa#9@P^*1$?h z5GCwy4Jl3YH8Pn}*KK-dj7|aZVoq~Jsj7Wlj zR^(%CNm6ehJD!AvfRMqwox#pW(}p?rImSCdd-{!zumV6ss-MbV75z305Jb zCRWO&M|}?^9A|Jmn7UP&1mP)^AK(QsNo|?-@_AY-=dm(o^T7sx@CW~t<)qE;{=rvR zKhx!J{ilC}cC*Ivi8i16{Lk_`|Khj#+E>2Cm8T!!(uV_{e&%C*=?{OGhoc@wc%a9m-d3AHff;c!H6!x9Uh%U9N^EqQ!<@+R>hAnZu|(2(hjy`CXy`R)+aB?dRF1fitR zmb@%Tl8_fZ>2u|Dh7mK0d_-#6)EiH;(o9H)U*X+5+sGnjY6R1L&8sin#S0`Nw8RaG z2qh*hD6~Wgi7+LBa_W#LT;eAP461HXHBEsbn+UR0lkb%u_(5nE@JuY=o#umRSycgA z;}X>lj_-n6QYu7+b&{%TbrBUgqgwsB`o`+HG*@KhT=j8cjSI7Y??*K1O|rZoFLR2b z#PiB3=#(;>Wu$3An&wrlsD~8_<%guYq!vYpAVf;{GZlG3HcPQ(Nv<{H{XV-7H@JEI zI^)5BP=#=6iA$X&>g^V(F1T^y8mAvyCmW~kfHpas;{j)C4WgvRv!DJXH^2I))T0{a%6ZE11nSEurD!x76h+E-Hm0@I;o9|Uy!y(keEj+6_{eh~0ipQg zFMWlNf8yhO^II?S$dml!k9`);6AXp}u3o#!{{AkZ5cKx?2xIVUMkoa; zR3wQ{S-97xEe&a2u-EImi@lwz;9eD#(uY1nAr202spP@u9i+%TDKhF(B9$1grv}AMT~IgnVM&%rKnI+RDgV2X)l7ZO4@s#4?>a^ zxvQV8Yye7DXVHA{^*`9q;UW_4IC^Li7H=1?J=2dWl2 z$QN;J2U3?hR6Xa3eD~|jL85&=`X8vBqH63}Kr0;5e}#KJ8G9`6ZI3Ft^WomUU*^kVjt}z-6oCVfk?*6HTU`7^!h>=X-pMHX zo2*8XQKl$-pP5ofzs||-Y5ussLz1VIflqDNXGs}GnI;{Mnap}j@)^skr_sWvdFB#f zmN6Cr``q*N&p*ogi{IkOV#aGXx0onHIO>t!d==BIAtp_*lDyMqdwm%-n9!GSE$(tN z&G|Fhu(rBHKA3RMvpmslB2PWa-~G~;_`}`%{Q1v(mcADdubgFT^A_jN-a~qe+Hv)s zLsjDYp?}mK8S|?xzyixw90}7M#LNyGo!-Mt_z?`HSDyL_Bq6;4Z0%%Z`9rMq@G%G_ zK?*#tg|Au^sX*u!!~HENeWVRgzCi^AUQH4v;0J&iV|7lcrU+3YRY(|zNZ~P?X~?F` zR6$e?eV$SXFC=b1dBx?xQ?7fATcb>4<#h9>Qzg zE<#UPZs!d43#PL%&83Kya~`|fIg??*_rCWAk3DvhFf1rZnan)mxXzs)yw15RkB~`R zJ5#fR=PODKr8W3|Sb=5TszoUuKdez}bZN9#sdrCfM8f@hxA^tH{Wp1V^A6op7Z{E* ze)U)X9DnEU{!eUfZc&(&FMsL(WUZZ`@zG@T_6Gc;Fa8#fKk+12AKpQP0;3!+(^^5A zr+A(lG@`&G@+6+p_!5fgjC58am4}Hg5;dQ|sw>R$>nN{exh|+Ffr?9fVHlU2k(J)h8Q z8LSo*dY9q&9mbwgT>HT0YY1}bd`)~i%{YK@LyKVH_~%!QDe;ku1QoU zkq{DjFx0vOQVH*1Kyindhc{0@OX-3n2UsbmUSTbHK0_!EKZsFbz;rxv>)Ohfl%xsc z>4aJ%!OIn1Dw)l4nvDjrNKjsQSh^vgv@jlyxq0&@qx~_HVIONX%S&C(o;t3)x967lf7A2$MhzGkp^0FjUJ`(A$ds0wVC>S?%C@cmkJm- z3+bXn7=tO?dmjsBSx}T^)ki;H*n1f3kbzjLDA{2#d;z zVI3Jmn94_K5yGp&MurcX7+lV~2030H%A)C-GHX6 z73$%D`QG8GitUI6MYYms?SX>4(8e}bln>G?$JXrPXtv)htmNn6n8VLMgxKqf#;`c3 ziiKqUyo&P3nqSPRBJ-Nj#mLQ~1;PFE{ChT6Y!}!5VqpQaXqB~#)2cXZ*b)mPl${6g zJd3Ca>X$9eeTf`p{6w_DMt6NNm|TgLNADE^hW%Y6%6Wi%G2vynHjEaju@Y*6U_SL@4Q6NZIev| zLPi*wK%-4Nj!2i+DYVB%Rq}G7-e7q$}_{A zPYofaiz6h5&0q51BL@*CTP5hN!3e=ZDfJPz^noHS4tE0Y8f$Ih~3ZXPA6a=wC`WjS0VTPDep~xIc z%F{?nJShmgfB+9!IL4bUU6S+FS6^ZE>)J;ng>qr@rP4>BUKVx|s&{;}oHUjpCQ`)UIy07Z?b7QMtUV!A65E_K<=_EFxnoN?At23Ldvbz2eg6J=knpNU-g0?xm z@-CSgu|Lxw`gp#jxvVHs*xH$qKgd|A)yXCqfp+*HFBCvQVI88nv`}in{4p&}&T=c} zk6sSm|bxGhU z$J@1Fq(mrCfh4Fy+$s=>VWz>PmdTzaGZNMOfOAg9AiN5ATvqjPl|o~xo9;YpR8}3~ z)>dBUxk5AV(zXU6U9Y*QwjEk)mv|P3e;uel#)V5P4zzBpv$f}Cj_5^YEuVMFD+?SFis0rv?fYwD9w9VEKRw7>n{0Z!uivuIQPhT z)=#Y9D@zbXpfxIPQc>oq!wdlV_tvt8n^C8d|{SRt2;2JkUsnUJ(|rXQiZIpu8~eA4DJp1 z!cYDrLE!V<@4U#vR>H>S2L0{(#L5yzF-fh76#_qrX|Jvm#S!B)bD(ac={6-d-}(mE z5k!%zT7Ba3B|iJYXL$07OPn};78xk=tYA8sG1%=<^L@5Ax7Z)-u)TR7vW(T`4uy2w z-gGjfC|q6WWHw`Gug_#Ma|ee9Sy{UGwb6LeqpV&_3X2ue)jcDTzT04VD16_?O4rb( zgyWPN1FN)i_W%GO07*naR9aZKO0SM8Ypes~7lo@970wpm1|@eXvbwSeRDJKZ8c?K^ z2wQ~=mHWD$^xc}*fYJIuW%Vk*v|NB{THJ+9YkQ<}@`F)HkFJ`<`+~#gpI{Ew*K=#a zQMRf*@~e;MeU8jk$5y0=n`nDrxj0;*%Ok_4Q&$gZ2loAd=W`o@IF6gL2NjfuN}4`0 zR@h2qwFmz@Zs!z7>q+MxRVk2W{@q#p7O1ycGpFequ z2UcU^5D`W!t*$XGa<&VLPHLR_@F)4^t?P_u1*cWX+GAIk^qa&vVgt`t)RHyUPkxdQJ@r><1YNct_SoOMMOj><-6+smLQw^kRG6ZC z4bnM^tSuZWOgN^e6bjGQs0D4>QIld;5(E*oz(W_Bsh#nmr=H-gcV6SQH?Hy2<#Tv` z$o+>qw3`W6uie1ZET_+(<+FxD-?TyA~_U*56W-VvD?;~SFvu;RBL0RTVs$dfeDKwr0DJ@4J0*uo;M2R1vbhpYTpo>Dw|vB~8NmU?}Ht!njDq{5ced+u?NDSe5kh!NyiYjEV(j__AS#s=)OYK z6*kI0a3qv5&M!GfyDT&^9voT+pmMXoH58&k?10wQZ5Ze4n=}3Vd8*p&MN!iE2my5I z{Ap&c(9CPIals|5Axau7byr*rB+oHglczc9ETdkBOqcAB#`O0imZc)B68pN$nNFwd zZf~)>+vCCJL%OXNouxMQW`Y+;;<$;QB<{~|47oA*zR&sdr^$Z*Uvlou6~6tw@37oS zSU&d%!SXs@5Hj&R>X*+kYzT_d&|PV9*=vT@VKe`+I$M2Yq^jspEHQL!PFDzK2vE!g|h5QIu79MprF- z7EASfmh&n~r*L~-=*SGpbAhBP5Jd&Mx5m2Fy>QE5JwN!RaQQ&0!%kMsV^UWB#>25o zDes`pHw;5pq@vx0No$QR9gkKDIq!UM3H?$Zw#ysW2O&L=@&ndN-#Y`_BS58v^iQ?k zo{t0OKxqouGoe`Mp0|h0*+bxwJhEbU1p^D!ogA~U9x44i9twJ& zuo6c>`bVop#o<6|k0Ykcye0kU8rUAjr7VZZdSQ=$3*5zJaTv7+QmlB-f7fCml@RY8 z_!oa-uAWpldQKdYoNG~TTk72>v3ZZ-i+@1lV}FS_FZf^Yze7K+F=)0)Wlk}h@V0>y zB`gIoyHzPjBw!jy?rY8M$%u_v$w+iKC3BwXhCE1z1Q*WoY`w|!%il&sHKu11%77mz1@f>~H+tSyhOw&~Ai2<=mtjJ3GV(-+V3y^pnja63H{yZuO$c7WPH(q8oyNd7& zw9MTKSi5wkumW9z@k2b*AQD|>BLRUT3K9Y&LRcn~3FBGLaGW`oU@lm1_z0!Yr6vpu zObPwI#xkSZY4O9Cud+YdCr9#y&why4-@M0oXP2#qJA`43=m_4uv4fG8IO$LnitVji zSUW@c9!u*nHj8=XhZA0V=MK+&=nUOP;>u6F0Ba?+W&^7{in7EDLi{i%43|i1ErME` zl!PCC=M}#Boj>8tH(o{hiqcrHC13cdpW?;ue~ZCTW5`gmm>DU4&|$hWLevxLfzN(# zhA}awz<)LR$%u^<1hIC1V- zT1yGdnxfPo{n8Nv^q6+@S=#lFaR2HTneDlOw$uvGw{*K6*~p_m$O#k3M}no(3MCEJ z2#Rdp(M-ic6le`eELc5N(&=iXvIlPh4On4_!hjPimeN|*x*jJ_1i6hX~ zV>&SuBTJDAJkKLV00PNoPK)a5$Sne6T~Q5dvxKf#=Uw zfeL+aP`V072@WnVIq;oX;aZ@KbszVo#2~9O4~vv;Ads#C3M*vQ^5YaSPXz~lRI?B; zQC483V^Wr-^ZM4C4LZx~_`V?11=Dm)e_v9IWBO%=XB;A~(M(W&z~0^t)6t0A_wLf` z?NiP&RI5c<4!Q>ffHX}`^C>7v&9$OFZQ%jl%TgUf3u3Wi7T&vOa z;LOE~oLE0az1?;#R&kA5qeT=a;CWaickkce-p!kgCsSI93t-;4d7TFj9v z^PQhl3WRZ8_69c;nrdJ)+O6@OtZAx190!b11bCjepuP!&aw}ftd4yhw@B0oTr7Iu1 zEgc_s-Y6s7fU9-sR?kXRAasHBt0p01{$ByR|4mtG-cJ}kTvc-fon%Bcj#=+mOk|FJ z67Nw+4}*n^Q2oVFmpE*At7=7^5`DO$cVR~kNdX6qPxH`^J@|aP5G^`7!5#CF+GAL( zV-xhz75_ra=snYlJ)*a{)*y961r|psQwxq%juZnYO{glAm*yP0NCy@Pb)Ajxw8+pv<&z$C~B4RfmBFu!W*5K`;z|JOoVX4FBY)n&G zY$Il{xyQS<)&AM_I2+6>@PE3I>*()0B>LO{91>P*J=!nMWz{N(@lmRtOo&mvoTX)2&K>R(s`s^ z#TPdaB0N9>9uDyK*lX|DH~gTkR?N*L&c|I{unrRZuH5>7JNqLYN^ft#{o6Nr_~2Dk z7_xHl6MXW8zs8lbYqXl~P#aC4)E<`}|2bBc6N1=hJj}S$c!hV~{B?wyQIMjwMz||A zg>l}+Fsc!W2GcSpPAt*`Ju4{-$I+6M6t>`>{r(^Fp-U@7zFY51CNmd~kUrMejHj9# zH+PthuW|d~i0$2+r(?~TwV2o5v2>hT&&%Q1VqGaB_NlYPTzIOLH>I$XYV23zzw zbGCsN1^bhG497#>dhG^sIO4gdFA>xelD3cZT%^saxqeQ#+z06oMjmFStNTLJ<Kx&Kcxuh)8y&!9~lYIWOzs3`v_&CitAoShM zYcc^-SoZr@+3&r``7?hJ-)oYO2Bb6RgEi9PDM7vKv1SwcTY{C97WrsOt>Gg@N#HAr z98}7%H`ASQNSrrxI5lJAO|I4*Di3*&5i2g8AE?{^h5)U`eIIo}4;7QM=t_zKk zqQb(tCai2aLJEyAiq+*+qFO>x7<$`#q>UKeZr~}4l9s{PLs;0~*{3(^Gn$O3M=@(l z9ZsyS5Qd83a6mV%p^YZXGDg#sM!k*j6-EUl5&ZZIALp&#{33t+&%em$zVJ)@&cFB) zzxZc=oR#$!e%vMweS%Jt@gyVL+v4V}4ZilR?{NE;#ww2ocdoJ7IbSKuZgJ)NzEhTg zVZYBi*WPA%d6jpsUE|D|Gi+`=;E^+DxN-9?-81Ld+PK4BzfasaLoEpz@9%Nz_8s1N z`z@C1O`d=13W?|A1wMY5&{^t`G+UHK$t=&9?C&rfPAH0;JWH{{Qb<{?z)O^{thE|s zlRd|X6^hYxL_Lg&{gBCY!YnHZBcDL}U=4+FA*8~T4((RGc4W0#5K6iWt8{I8QhEsG zqrw0w)PaxDc?K(W(72xZxpH4r2ftLVj@ne}yVeHf$;xYQK{>c&62-1Iv_h|yT9cQ# zW0?w7ktr90E_3vcbpBWALP6G4OK|C^4_188uF^Tf(Rm>c6wG5aorfytVgr&{2qSS6 zM1FMaIx>)oh2hcQ21;q|0zgR|`TwK!pZ4fn%ONXN&jU^KXUehky|s&jDesBHEP$yN zhIPSv^YL@v>7fta*+W(J+|re*Y^qDQLWpAnthI+e(_`|nJx&b}M_S#F+GgL6@hlcc zX@N-svV4b@m(iBHY<>MV>Hg&3;(1^3#)BS7r@^lB$f6eeq2`7OnARH1ijiw?{@BeYZVJ)l>3(ED6awz@7fAw`9-26TA{4Jii@@M(v zCx4Mk7uH#-8$4y0rIPUkhd=19(CA3o4d^r?r2QzP(O+OZe34Oln{oa+R_9n_DGHxF zm(0=gk>_iN<`V4vnEgLhK zj7e`6lvWUg34!X+T>2<0YnO+idQ9pW&8f)bsGyW(1zbtJ2d}Do_vx5@CFl z4v0iVUQD^Q`2+4s!PPt4q*;#5A;nVmGGgIlG8_tO0p%ftM0w70Dujop6qhf3mMb5A zn)M~0sA5M?3z%gko153Tcjuo|_n^Ic5or~M5UFgX&gCFNROr)L6T~%1EF;8DM&eCa zS@qcK7mUX_?UrKJD@Z2_?FWp#f|sv7VD-f3vDQ%UexFm_K1vh_nNw&*kxRyDK&M$y zZ)#F4*xq;eGS4>$XbY1<+5=C3RRLuxDU?AjDe}~FA-Te5H1OHm95I=cpg|}@IhG_M z`alms$1Rs=Yb#^9ORU=JJh8UwxtGG(V=A>u8doTTa_blgE+|#4;hm>cfpmwyL{chI zl`vR5p$L56`4EMqv~wCmMkp+K6`U~=w9%x~DOs9R7AZ-i#q!b$%S+3INq}FggLTCU z!bYrAt_`85xN!CizxXqs zwo0g&;4co^>+r$#$V^z$1if`)CmfmbN$v`-hBH$Z(ZM_9d_vLZV>xW z)Zy-3$^P~|!st9M@>B2&1tml3I;CpE4TtXqIafNJLm8&vFKXKHEDxL{W`?zfb5(j4o-% zF%RzCH`I7nPIg?TTN-ogOH8es8oJsB`Gm@ z)~hNEMK#z$6h$O);%adv`;DehKV3}uBfbFXtH#33!hQy3(=ERjN>jV7pk zrpgKo>I1$Y9&`&Gq`MUh*(MIFEuAm#Q2BEpds$U~R^h^9;CHv`wnvU_ZFQw|A4@>b z*Yop0lsFtr<$QDy2blE3HNIF3RoO#qlRZqXFV+(unAEEgR4i~T-=nk%j!oxP%KyM? zbm+pJE1D9ox?G6&3^s>h9B~AZXBT(#@7X;c2CR;MB`d_S0bDKw#oR?+g@W*r7T)wG zE%6Yu^T(W${~o<@olmc{Jn-_FXK1S>6ciFqQ$^9VU@@GHC8(;nk{V)G6!C(G&NmoxW+qg|R9I!MQ zGTFNWw>?-nk6Q22lNn80(yF()@)!RDUitOE!Ph=H;*(1&Y~Q=ji8v%yigDgyEetT) z2~^-h+Ln0>nd1N13@SM4##p>0iT9;Z{78q=Yp?%3qM)GOJj2SV&vWL?8r_<}_Y|dp z$qe@TCEMF~2y17^%b3DQ;uw}sBwTvp7kKk^!!X+?FP9PJ9>%y8uCa=mw?sQUO--Jl zm{@|Uch%JqTIxweC`-iLI%RFO%V=|p z;b6v_Z|)NKuy&$Jd(ESnbjhb1JQ(cZDM+F^r_R+W_0ai3XO`)tKu~acrA>dNxjT}y zF(jqKk|<$aQWc3cn!pcfuRh8&>+l=D_3P{nwyD)aqz}S}Oy|{Y+On~;$ESYfKjyV- zf5c?+Iww!YeE1VT&YyhkYwY#*c(^;HR2Eef2osQxXGF0f)Loh@PvNVae(zoSo9{B* z$O)I+N=)J-j9b-t(nHG3HA>kA#msk)C#~5Y%oq%In3M)%JhBpUAxVo8YXo)*X>KU2 zQ$FYD7Au`9=Sh#%_Boz>_CI2MrAbo?eBp4s*1~v_@!;O?p|jU%bbby=LYxGg|In{+ zmn3F^aMJdppAS1;?v$Nml|M>F1a%zjH z@yruX@uA1y@r(QT@fPE0pWQxOUYA5+iJ3t?DEQ3BL-%l>d5i~&mq!C8n-R6RNt}eP zDmS;JBg?E00X6bGXY*!`v>ohppHk=Ky&Pp?vaJsm*j;Gwq(G=Dgk+$^R9@SK$b_x3 zx6<{>Bcy9`F>YJ0_i*NC+;K`w)(mG8myr-7A1_M zGgOIxOvz}p&v-IqG957(?XccGK@vm+E34SBL91D(RkACu#_@T$|{{Fw_<*)v4*d*rBC!Xc%-DTdo zm7+^cnJqEsj~Hyd&5S)BePo?D2w6RO9-U9wzIBhKwRJo{L|bQLC~{4n7hE`ho;&w9 z*}T8OlaD{nWZWZ68gw`AA*`k>G~@jVzVI1%dsu|STFp}S(~QAn$Wk^y+6+v__Jf=3 z?e5|Q5g>^iE`!^feJ-9q$FRT4YPU;1NtsOg6#0bE_gQW)QSUTJr&Bx+Lam4*k0@%Q ztz|ID9bQN}e3O+PB5zULjB+f$t-%#q$+-3STNvKH5N8mS`+RnNwy3qNu`; z+Pc-f)>XA~>B4t*u9mn9kx~x(7bSH(&#Szy8e3|zEJYjR2D&PEBc$i34psO?Y^Lg_x8hLC)Ye@9=aeUTTxME?%VQlC z!Rl&UlgA)Ms+y(5af$ChEI3qG&5=RRg_0HlKX$=a`F>%PV-=#}czCE9{*GX)<~-Eu z{Voohr|dBj!9w?H^=pm>l#DorXcF>Z2$Baw^x-;raZ4|b;fdw}I1Xw*4)Ir3h&d_i z@OdeYeSa6QR9Z?{Rt#U=pq?1K(L=8OonIxcHTnE6|JS@D)>%tx#7UcTQNYDe^6p?C z?bjHp2FCL!&5ZAx3>hcP-g=d9_O>bdTi8^Pw3oRQwaIoih*s8kxfPR#60x^U^!h89 zkA9ZysgIKHZ86>ML6IXyDWao^n>7Mui9L@*3r=c9m0UCReXsWhsfdvtRPoOE2-*sTE#&Yl8=y9_uF? zlx0f2mT~L)9cEh7+s~2Nm>_PG)LLw8+~$=ZY!G-cQe?zYOskWiZ4b|@k!B@{7x41S z+jMGmo_%taZ+!O#FTH%7pr$yv+M(HqkVX;(9%Y&%Wk6g%Ng+@28~^Y(xqtU2$`eG9 zhaX7dAYeS35Jo<&?i!!|<^O~?uYZ@x^lc*Fr`1^DPrv<5M$;+jWJXpL5O@S_f#+EU z_s2~4_Sm}lJ-Uy56wed%cT?W}-ULrtmQH}eJ3wDZYmwFv2ZnYnK6|-(=Zh+l?HZNtW$k za*L1&!)!olbAm?oxG{ohnmYBt&Uoqju(ffCR`e?@EvLNv#vhQ|EzX@TnPwCG03JOp z(KG;gT~;b+rHz=XXIvZ}KrVzLt13VX z+Eh(E3Ms)zOF)3tB|<2-hSjCJ%v6J^(Hc{hOa^^)KA}h_r1^-+Y=9AGXxBnkR@R*I z*IlO3Y8(W$jMgBf8%~EkrsI8lsmQG)R}x#HsH|}ZU8C9L`A>a<^A{iG<(GfRH^1|3 z?)>n(+<5t0q_YgHB?x_%n=Kwcv&!X*=eTs?6iac;c7KSL>%4jO9;Y8YkLUZ8+7S2= zR+fZez+^IIG}!0zqZcUilpo%^&b`}rSYK{)_ttGZC1^DhwtHJ>U1K^LqD{_pI%BuD zPqz`#-W%cHy+eJRxdS*1&{;-0OPNk5*iz8#Ec0M{gHeBo!%sdK7!FlZaWF+3s$BCF|NDem zjt9FAYzT)MuRQ>>FQNku6*jvty}YlgHvd^y&m!}Gw_l&rACCDY#Ic;1v5UX!yuE!f zs(-A->X>~&OTqR49`!6WU$VcqM{$3TjsO0ylP{lQ>%!-`_?f>zEENGBp9(c^^mcft zPD9w{#B|Ion~?_rdhHb3y%E*~c&#jv3^dOYg(xV5>)||pHxc5Pfmf*ayTUA(KmPxfR{Vb& zN`Lwn{tM2Yc@AL=cQ$S^8XL;4GrMLfZ10uae)k*nc7C66_7!g2>JUX8KJxTmr@OLB zHY>5Dyb5 z+1MQuhCYQd{9nYqS&VJjectz5!yeCEr{=n2-@ZMP-Ry3vNs*L9iV7)f2ofoF1Sx_b z7y%5}F!GS6l%Pz&4yXksT|t3|kX5lN2?OlsGln^Kj=|x9+X!)S36V*2=@) zRdwoilYxb(^Uy$}>ee}@s&<|A?f?J#eqUxvT5*eZ7|;kTM~4G&22W}tFtF+`9D^N`sc5Jc)G{KlBLj=`Anw} zy^^J7hnHV^3GEb_Noe&$o_gX@-gxaMK@4;qZK=tQ5?=kr@3QpNM@f?ruYdFNjE4iF zmZQ|F>XVl_3W0D{0HojcSnu`;)G~u0;?}(f2%SS&V6~&jASooNaiqqfDQIbl3qj=q zo2zO?RrgbeUXK?ae}<2}4EbE4D6P zB#i$jCWo){?XUmO6l`Nu2~LA@I8PGyn-sg23+oqn>E;o6F=x5!^XB!Guwn7NYCoDQr=R;aZ%Qc}bS!Oon6PAmXSQu^)xRz98_I zP)ZTkleIigu_mt>m_D+-gz|*$+}KAbINH5OYpILUKHxBU z!hBvZnJ28R_R-2Qm<(w8f;5z@F89dibMD-|jc|_P-hD!`#^J$;*WSK~5Q@k$nT*El9c(k7&Fg-6M_#vS38m3iVvR#d4`Hh5 zYUwPdFl5;jXCW<8Jf-oJN8kl$rI^iTV2bLJ)0$p)shXM!L1{|zEF;g-lQ7D$)kM|@ zy%eXy%VN>T>-U-jVUL423!Y~ysPIv>@6@VeNoR5T{cUt&!I!vbPjn0VQ;M@f^|UeR zSd`iYf24b;Q`{|v%IhhmIN?aXr${^_^28Yn)=5g=orayxuDdy@GIh9xu+-`F%RP*# zIwSYw!YcmM<9gyMaHrp&sLSh5h4b+|RG#tTo@!&UF!vM-9@4Y^(KBv=1$XW-o#mv0 z^@M(~Fa#9x%(S)om_hll@q7<&dqh^`G(DIWFdrNc4F;@?2FyS7DO&wC)c66f-Mzst z|Mutk%uoLU=Ps;sZ<1m5?_v7^!t20t3uY6D9dUn|tDpHPKGaV5`XBu}x}zgL@?#(1 zH$VSX?%q8h`||HW?18;X5jM#-*N}~6Y$Il8KH=GO%NV7hp=oD^JMktLl%xH*f6KjJ z{JUIVUZ-P9nvD*D08dzqE72lBy9g_ERZ>w;?vHD0#e3Xm1*Dp$+ zeeTD(yyb{OczW2!;8U8)-JPa_@m|9I?(bsDo7mFUMOF>&-nl@L{Rp;984O>dFgL1X zo$_&|#g?E{pH6(9P_^;B0LqMXJ|;`X(C}zRK3SeIo#))XevQ&t=5xcPi*2soJVahy zq19=yH_EuNeS_i9a`V;e#A@hJduK?33P`vQW6>Kp>DovJ8 zh+M*zt3ArXF&N(`iUVR9G948paX}f*@WPlzyu#AzMeZL=`K{0WD!UJEBC&Nxc!@QJ zz*iiN#ytAiCd-fcl~3MwiV|uv}r|#jakgj(TGM{;B`V| zAxTGveC;d0M4BXw?%X2o2|8OE?HASEqBS_736xLdDFUg9yf(g$Xtrb6Ran=g$O^25 z+~nlOl9gbb#aGa5NUYY#X-Sb=lB^1I#f>%}eEz?ocl9~E^$qUj9h!y2rZ7k1EF_s@ z?*I<>=j3^ZcK^p&UVo1MT8mDzI#`;`6{f2nL+XFTtv7#_`?r4&6C|LjW*4s$vw!`F zFMsDPg2=HJGy1J^23t3FS`l$5N|GkS=({PUaPL1uoX&l&i#}5GUb`W2PxJi`LX3 z2V-nqCF!bUH3s7Zo(fNr(3Nn^2s{soqOb<6LDz?xF$P;$EEZXJrVF7kbqi2gmgH%{ zWIks)ozrMGm`$g&yIs5>AZj$hmgHqwuMHi;p&%cR2m+sMHph4*tgfx0J%uMM+jp)pn*X$m1oCPRjUT}GoZd6H9_s?eZn@>2L-fRqZQ6bN1UF^#KH zVvejVu%#i(GfYudwXvqcj0HhJ5Jp6COwbJ~Dd8%nXrAY!S%Ryls6wznH>|{%6}krH zpC-=Daf0etfC_OI@hxP{Os+y!vSvh8LA*-2S@r$~oy4*5a^GXq>3COe{_MuQ4uVmU zFshZkJDH-M)P_3AA`|lA$8_Jt19)a5Exy;(^Ypd9=W_oci|4UebPEhs_g$uG3#_^t zd|&@oYsGzPUlk`IDZ%0sJdDV4?^?5qIs~_noH{eXK5ZO2wk16r;8|$EI@4=pamvHC zLx#x&F9(%_EKcV-jpXPu0y+6P(VK^G|`LF*m&oqCOyr4&%vvvISt|C^gqbaP@ye5Q!%uSUmw%IQ-F}NN25mlN9dW0JCk4I?D2s&1 zEiu(qQzN7&H$3l}$e-|rAD)`KGt~v}`=oSh1NvPEG_)g+!)ZxjHCk27L!nAMU!a6S zdIee=FbVf}|4&AvzrdCrCclBi&|7(yxbYbKN4Lo4DUWVF$A#WGn$F-$m>=!X^r1{4 zwGxdX(iSf$`SizM;Fmx5CA#e<&p-1xhx^~A-wiQEHN`l0{t?byaNM{xpxrE3-RKj@ z5l*HQF2&CTd71OU=N{*^S8p<%7+(1BV`wj7HZN(kdc@6yPCo)&a_!oHE06Se^Nk~f zoKh}%{1-p|F+TR}3uJ}la8j@{G5pJa^=}xD2E;K0VKptX)?u9{cZ$YRnn@o|v2H@{G#Q4(RBcH(P*S2$2q|jNwX3QG zO|=3kT}U2WV%IeArjpcIqPf62$a0v@1V@J%yAQ4-oJXU1m3Fg9>dANT+lTQB;4RN?CFw zqa(-mohjwK@=Io&6hE*Sr;wf^^fkM8Btf`B7~SXU6_2rz|sP zlN8!gmI6$PlA@ZH);=*;cb;1VWhoiY4EG0Plvd=mKXGmI9F0~?5O{>jJ2@oURxqFE zl(Qj|VR6h#CkCgM(eV%WG&?vexU8q*J7Xb4zU=7{g#N zq`$Jvc=rL_c89FAOpgv|L_U2NX*I%`;@!qqn?CGTdkXV27f}DASBQ zPjR*+P#PsA+H)sDNqYfV4X1ZF$|6Ur3RRTlRVb>ohN38NWmPF_oJA-_)NCSzqSa`k zlwv*`GntIY=4s6lEo<(fIObf`iF#f2jEia(<19#F(L!KljRC4_NrjXY##HNmY<&&M z+LNeGR>oR7oV6GsDa`u|&p$o2-C2S5EeeEgpwJsR} zbQEFNBD^A_oHzmrk%q}kP?m-b^XGiyH-?B?Q-*#?wzb0Tx4*_wu}8T#q>-jfg~DCl z#{1My;=DFABW7>C$-S__ywPT3=~13Ehjc{A_3QVz{GrFmzx5i$d_wru-{#Eif~8iIJjs|y@07-19J||xJoU&`c7FHYb3bVF^wu(uT-+est170IQk3L0wa;8b zk!N*Fny8zZYVWOEtaK2(3!i&zzYyQ$j_j{flrA^HuftiY_Ipg{mZi4D(-6cGFYeQ{ z0aBT&LBU!Iv&YfoK8ToD#q@d~VP*4gv2pHMqNXO9%*h5bM0rT)=7{VFPw(LiMK+&S zDBv<@soSn<0pljce8T?0hzED?FrB8H+gL}~J6t;7;llYfzVWqJxp{M+7am_>mP~2& zOSbPiv{o1l?Ve^fy~&;1`vkGzowu*EelEaS#rB;8hDQl2D{Ur2LBHEXtC%d`XKlU9 zg-1HrvgG{5r!ZPGc=+25kmU!u3HnI@L&cMHlS zBZ_^rpL64_I~*Md`kf!<&g;K{9}EfG3LS%rU?psDGno;14$mua6l8!jb+eUHRdQDg z{J_#^dYH`T=7S+7wG}(l8In;+CLDfK(`yH4RpN?6QsXh5O2(rU8A_Z7Z@xL@=YF_B z@aO@DGnmc|t19ALC!^8M==Ns}?tPn`gAUsV38hNv1M>Y`7uL{oXVDe!ze1PT5~nm; zDvY7JSwtdAcfxP9LQqiO-9vIYw4UGAE=Q-3l{UM`Y=YG?^n!NuC;3J6$G|Darg6lhGk6XwdJpxp;1! zM%-p;eU*Y4p0fy(l8y%m&m$l2asAFNdv_lt?Dg?HMV`#b(;QotNN13qqUATpl_Sjy ztSQNgf(DX(_45YPRV1`yf;1MZw@ev%b0p z&al3|#cX^;5QJPhf1XySLATwhCe1}gkrzyplxXQZ+DZ-w`@HhTw@LGaKr1}$QRF3# z0wE>R_s{}#eaMzLa8@=PYGjP^KBiWjq)T zFxC>qO_cDEGOdDch*LOsMV77#8tTeQ0jI5DS|ChaNhu^!RR^c5ci)=o=F0N7Oj(K*7cknK8X`ll6tt<@l;dQ6{?Qob*Vg)K0on>9(!7a zJP8lU+Tvhqakc2NJnlQM-WS%|jI@8uqx=Xc5D8>W{62tvuJn zjS{?ZO5{Vg>6qt&WNx{z>d@{EgU$+Mf}`=AX`V5B_`#)fWZT>H`d8Tfvp=L4M?5f=Jekn_@*j}@M1$GXN3UMwv8^tn z(UiBskd3IKmFy3Pd~v?U4?KUBH@^OLmcH;g_=!)_Ys?TX!^sj|SfbKlwV=$4njj%g zb*HFnY3rXA;^7Hub&XV&v!_ZBSQVvM5*VU{%$RhWr{pEEVU$_g18aTX>F0_ zAW#j;J^PL{zvZb?}MmTT0(&5E85M7c_w)L#lOLaKmGR@jrYjS zZIEe|P{yD=Nw;a~Hzhq^U~@ww0%uAFhXcaE&|YeAuwxnTO$hr9@Dh|!_!^o^3aK1f zQs5bnd{WZfsKQRAEy4IuC@elgT&CIk6#a8Qjxi;|@3B9-3FBQ965&NC)j-QBISykb zSRc<*M81QWCJZI*R*p@+PL^9H2fNHwK)d;2I!hm5Yx8-Qmj#}$5w3$R+bAvYBS8w- zB;_}L^`CO#!c$zl_yqkpV)?NPl;;}UcbR_0RUPH^ zTFmpjdg5i!N@I*e*PcJ&90q|fmUK4bVDAA%l0ur{OomcmY{}v1h{=3{F^1mK8lJC_ zWr@Bm{= z&TnneYBcHh*J!jNhDS%d`T84}JjLWQw(s3x?a~IGbc_cBI^AU^2M;Logk~5}njGb6 z#=HAW#z&;%0fQpvaDRX;YT*zHg!S0oA99quO)Mp7MZ4Kzf9EdSw{NhqwaLoH7A~7| z_xcfD5LDCzVQF_;G**{U(&8yinUy#KyzUmFxX=CDHyBT+%<=*wC4ts>o}wrU3R|Is z!YHKM>*I$ZO8MX_erRzl3`|K`IMO1;8H+1Qa%)JllswC;$I3GjGa*S5@+`xZ2BlT) z6|R1-?M4gTXfw}J;M7hcq^zei8tV*dVI3=Fm7I5~Mn4@d`ehY#)3q2=l_{zgezv-< z>y{`fB$Bc^2<7|lDHV$ecd-~0Ib%6}55dGk>(YgUl8_69jp9VLxf8)~cHO-A?*yWr zP>Xkk$-i6jUVM)Mm;0{rLY!HZv-n!;oz9t(r^U~T?^dVkY68JAhVVGd|L*zosqazn zt}4}&6u&sWJAaSwL)8|iQ?YDMUSU<0dyMrzdCifBxzvT>0e)EE`OxeNmM4x3*vt-i zQ5XDKa30ZWkvvGSp2C(TWiz62@e<`YXFQ+M2qN@2BGrQ1VH<&mEF}Nk^$DN8`3_G% z@jO=_|0tuEzRa}wfZZ}dN<-s!ew%J%o$=$JLFJOwM#QcaWCuf*yA68Hn9qLthly`~ zo1gpnpXFcw>aXyPfA`D$onL4o8e^nvAY}um3ueh2<<$Y0>Ye%QME!eNJSxr-kLy!`5$y!yuLjAki! zc1EnOuk*F9y+x-LG9Jxn9!RcT+vVcbHF{yh-u`{gUEZSGjyQiIBFQp5td1`!C{NaBYDD)fn4E$mDX`355kj4iQ6gvh%D zED?7<0sbR2S3g4BYC-PkFMpWU-9KfZzfIVFoOa`BNd5?!XG}~LIMTh4XEx8_myTCo z+d;=3QIKQv9THcNxJ3nYQN^aaL(2>G#Xx5erR@bI%&3$g(kp#i}4eXX^A+e(BIhRVI zg{)9CwP#dH2c}Let9ni9B%ZFkp491hA&ys}wqDii1&DVw)siQPU5l|*@qrW-Q<54n zCY3;GjglTlIfNG+IPq6Qtnwt#_DCMmPkQ&R;-yKH3k^VL+Z{fS{O7AoQ7Ai^~mp zS#tC44xW}=%5$2dh`s%NhSL%Kl_j2xsv2NrErZ=X#-kynkw{;&y3#{gLlieiXEQ?I zqu=WghfPXjP}*|&@_F9Aaf>v~$g>PzRG!ODw};SM{mnE6=Ym70IJC22mrLTv^?eh?;mH zwW2VF$!tQS*&+%;3Q?CT)KgPeR~5QrZ)jaj>S;-lmFU`&deX6Tj2;rQwxiTjdFSwI zZmyHHN#*!#lwi#J{io>8glZnH&3xB}+*L=gI}x+uG;zP!o^yg*IzHyrLyu8U28DRH z1bFCw#lkB6^fATBP2{O4J>`8mWbMDSCsNHV3fCHRe^PaNvNB&BmP#I$ET7vNlHXa#3}8>e>)ZgJZrjs^AUl(m{9FFwa2;>zK)CT|B- zE?0xe1wMv$Lom!T28WJTV@i9~Bb{5Ki<`vFZiRhQKBjaOttO_hD5+WRFSD1Iq-BoN z4yh&Ekki!Dysxu(I?Cmis?Sv$;y36rOU- zrVbqk7~@FO37(FT-a1(_K+F#a+Yu|vs|2!27pHm2{$PxBf~OvTf_wL0=I(=gsC`Y5 z&uBKiZ?UARJSH5)(DK&v77!6XC(EQRr`E9=Tt$)b9{X4{g!q*<2uZet3 z6e{9wpP%~qzt1xt`_JjFt&nGi$lsz7uj2SL(^fj zl9dSUh(r@hOnd1EXs-PTMUmr)7R{Ez6pk=&BSi;M_-GrG9e$O_8(?LDD5{A@QjEE| zdxuYb{KxpI|MI`)8{d41x%fD@Zv1nM88b-}j40~0SpZn10HsdfBZP#)R&NYiNID%4 zlg?9Nec0)2R1XrJWhMV>aP^TG!|$lw3jU*w(46Re>hYuO_ES&TKZP9r<*;0IMJwPq=&YI?YxL zI2z3s8=L2e;uzrv1W|{L%}2m#ve^VLazxD*X_|tTc+N5$jp_FKxS?QjG^ET*9(n8{ zrf}8Ykct^i5^mhONmdxFP+ZyCz>j10ha<-0IsI;zI1(I8rnKiF`Fx7+dvtqCH2W*0 zrC@Zl%WycVQAS=}901O08qI)>^%e5Ma{0nV8i9w`?~)gD%EFP%6KpmIQy{aH$^F}S zzCyTV8qF@A2$)UB40i7^na;=y2VsNd_4AyI+jvq_c0v@|PZmeXO-4$(%;q zAP6D~GRmT?o0}>@EmYOaBpoQFaD_$6y4~mGfU6pzL=Duhu5VM_1PM`zWm&E5W$isw zQdeaX?)_G!a26CV7P2|wL;#61#!~f=+tfTXVO*T}iFb)z-em<{%%<0D(~7O}?hU#S z3)5Y(kdm+KLdC<;AN|lIw-$g4=_UJ+*YMO{AX%&y6=y<8?%gt8oWj|UC%RR@URK}F zG0xx^?{tC!a0`9w;tbl!o#}Z!m0f3ikP9AHA?#u-s{Z+%K9@jYBah(OWy;AOYG7~$ zXeWrIW33Iv-12>gxB2SklXyo3v!R+L0C;G8OOX~`=)hdk41GtUct z{k0u_?wNpt0wChrl#k+!Y@AjSkwTjXc zXoCRXm-IadRQ0RWQV<1_Znw{Lw}-GTe7{6^ORRRDo{TJhQ^?Af>a^VK$x+bs$YA?A|TezB49>3$9(C^Rdkf zbeco^2%~_N+dp}W`w>ZihQJJ@dAm(vb@^k zXMgtZa{0qQL$lu`_Q01Cy$Zcp;|WMgIOui}<`;n%&>e-|hpGU}? zAoQ6}Ax#D8+#p?y5Rgyr&m1F7+79h+C#9NB$&{nl?(7FnQ zF0n{0u@I8HZEK#CrXF}M@!{w@JmR7R1h*Y5`QDbIGYw&%Ac9pl! z91B-lg{4rULOUseCpAXa6BZ>aqDGRie_#oHMX%kY9fdgI*x9**RFY=gCXOc@9_+Bv z?X$FbfmVAJKL~i_k;lmMjC3}^TEk#;3sFiekXnn*=6G1z&6sd)6+h~*c4-T(C5O9v zOp+muW{33;1T4*IGvKhm}Jw!HVJe|{wBTSkieL<_yqY*Wb zMlek#9@S5~@HGR6Dv?|xYGxs%s< zW&tkLLW16%PA?w{`5b#rkCW-*Wcnl)#ONY2UYz(L5fXR2`WNpZbRWv1X9b+F30;k3I2yN+GeXIPt}vdEAG*0%w-K;;i_t-`Y;mPl7X(Y|{x!eibEu}wu|YRHZ%X1gz;t>Hq$Am)c$x%CRy zmmg>J&Mk`btKd2E2lsJNo5n{!gzI+kT76s;bJ^2eAMP?U1vZCFM!dSV!G*hbaLa3i ze#F+Z-$(!EJABi6%={JdLCStwF!mH31Vg8|+FPa-de|~!>k~iBAKm>5Np}rjNxmV@ z^L#JH&kwPaZHg=*aTAOxpp>UbD8WMo33X8JOhT@{#@}TvS*W-DkEs0pD~Zx$Z-=Iu zge~6nC~1j8NvqW%YJZfLe3~XpZ2FHN)fS%iAfGWFZ!;U0w3;4Qo_vBv!$TC{%_NzF z`FKP!+avZYtwzM*(U33*X~u$A-`-~P@i4+`8*{}_nFR8&Tst$PdxXxxP9*{4EBGY zM)O%VFZ~GJrGO~1SSv_#fij}pfL2_sKW^SUq-7J{8SmqYoT4<8 z4l-lVp@$fjY+YVue>9_*`+Ve?H8%SlHdj41FRZXPEVy&)ke9ym2H&`KkK&r4NT3lY z(xN~*!BVTkAf3?hn)pi4TFr4H=lB2k3uvvNv=pYqmp;X;py64}q{QeLYYi$W5w3(% z@W!ht!%@le&wD)iq(|5ieDmJ>d=QEfW583V2cndfFjZ2WdO%Oy=dv1))~GTeC4QZB zw$>q)ti68~5@+ADv(C~ z`gE06K`Djj`_(EjG_TLS7ms(f zq?#0(l28d6kw-ool6wm0D})B=1<`Ceg(dJpf+zrEL8+>^!d9zO?fdvz*Y8syN@o`Iad{_MS|5A%goky{KU9ZyR|4I!7O z(^0V?`b6E+e6q7&@QNP$Z5Q!LEHvr}b>cB~LZ0nP5({`GAs_O>p4N8SMWHL|G1T$8 z>+EQ1fluld!bFu7;S>+$IK!|!o_^YgFi{U#liZo9FALxQ>8o%H^H6bYMsTM;ujBCP zLvr+FdVH*}?6L5DNFG;3d8b1AblO@!hab^=@jUtG?@{b$NMrFm2!udIK0{lwGD>)7 zdYf=_lliM}(^y?2%q^4TkPFR#vcHZA`&a=@FXC$1<<-M|aw&18;O!zOF^=@I(&wBSBkK*dT0gBcF6k0 zA4RE^vjQ zGn!G0bB{dAJNNb(PR5`?dj;n&h8!FeT)Q)-@%j#N4E?U~Y^VP54=i-G; z^4!tsv~i-qI?1cAzeQ;@k3RM&D$IEKm79zXcPXZOlx57z-@eHUAGyGdw~z3`4x?ep z+GfDu(2}GQ-}e!+L`j9OC01o<-*7nEMcjXlVdHH&_6l3)+JqX~an*L@fXu;kW*Hsq z5Qhp^#8_+5>O9&`x%I|32pR$V;|JKpB3BE}Ki(yIGskOtEq0V_R_NcA_>=hlRRX_*mY@TH7gw63YL#^C@4wBx`+vfG^coErGATwi{6b-!#M%OzXJ}m~ zFr7tOfktz%bBk}AUk8<9#0ndmpQY7ppn?h3X@rQXg_Nx-2dxpLDL7U6KRZ2W#Grl4 zox8XB(y#v#_jc}KXFFhXthE?taYBJI7%W9ufROZBZK7~afBhn_Y~SGX-+U7{QzS)3 zmd_DWK{ACjEpXisPm2ovoo3kFGD=1WExGW43%v5q9lrI_A>Ec{xgXGKYMe<3ltWpI zOAWcP6iy&@C8m_`BQn^|HNvG_yqvMJ6yp2k`+g9jWVJf27Ms=Ns#?09Bzbks?K@^g zYEfZIa+*OW3PWtuR{GQudp*$OjN8iRF?zz=A*ns~lPqqRn--J#K0!V3b5 zGG{b8q$o;I8s{oeHXa>T*e72S2P^Ds-y$y!t!9tQS02T0c1W^I}7{93)gBn-*%l+o4`UUdTS zJUJ_^TkuWFT5hRRQ7B}!I$sPd)dJGhm7JAemG2QWk_+5nd-}LSoK2n|3p*hn+WL!k zg`gIFtxlW@LiaA|=FSMkvjG^fu>N;v>q^xkxb=I8p2g4A%CTzilP3WDla;r-&= zx@}PPKyPtM>`nx!eF)9@u$Xm=lQ}>rN!|_-FRWtr?_(z=v9AC_VM>-g#~?7Q+&`q( zZL@T~%l`FS_}x{oC3nC4MJ|5kXV`l%pndr=q4E)aNIPh9czBOeH$h15udU$Uy+^*f z#;($cxQ(Ta>MpU`4#|p~L1BoL!Vfj6OK9j2;o#{`hxs;RpL+K=K$o}Do@#KIHJiSa1J6`_FJ+d<8+2=pRo3Gtu=T3@4GMyAm zhADZP5C#>)F>ZR4Wrj2wzoUpmi~Bb+${^$ZYrlfJd6gHw|G%QY6cL3L%d?P>m2h}i zl1^?DGojo+#BU~qfx=t8%=f?Ob1)qfj5M=kijoDoJ!a)%mrGZE2F`W4bN$c28&J9_ z`Sb{5a?&wKwMwJ)IJ5bj{rhhccl-4E>jnrT< zr`)(9Fu7tn0Y9)vRpP~fD=D3&Fajksv38_cNr9r6mpB~CSG;-PvvW=I(I0B@*v0qP z$7ZVAhpKD7Ui(>BBVj~+6M;rbg|$VsidPCH6`uZocze?rS+o1R?|065x2m_cuHJ9o zZSKt6SvW&-s3AGrL{kf8S&~87k}Nw)03m=JK?o8fu^j|Pz9b)F#6e&n5p2VD>_Cn! zN2Vy5At{NHDDE7RvvJnD&Ru)&+TZmo`S4a%SN9zyhyl(F?f`SqU3SV#Y_TP(MysoUZhv+L$Vma(Xe6QdZw(>rg^c zQca|#nQBzErgWApO96rJc^IJ?=n;8d;2~+mF_9;!)w;xu7Ga}cqgMiW11 zV5ak@v*#a0>x48-7!M8^9v!mWZc%S`2^wt>igY}p*=kl7)=*)Slt6i87(73uv%JJ! z{}yR7rdjK-(Osgqf1kipNad4emd$f(G}g}G42(xZoK!fkPNTcZTlZceY6jGrO`35) zGg1Uf5qH{jyGu9(^L8n>gus7n-C!eOZv`(v2BT^nZ>7mmMosS5l zMur}d-<+l)IRdYu9aya?jUm+0bSr$U@p8739ZV)Ez0r_ff5d1sLKh`vp(%=@!aZqo z!jUYfQoDq#NDWFzl;Y;kMO(-@r1={Q)!8%oTePPDPOokKnW?a z)}iEd>M1HCkyH|6W=EYxdKD(BVwg-zIk&J5f0zHULLp~PZsf5^XI_c9X_C=m=DS)@ zF3Ne)ShbdN9@}`lB3j!R-@I?%-_?TPibIEi^WuJ}$+0FHajW57J8n4u?3Mf1n) z=GJ;~9I~`n-JN8c&R6?xVd{ChtP#f(%te^#+}w3~Rwqu?;O;bT-~k@ITe$C&u5r5{ zWmtTjtM_82qjv~O1+2&9%N}8B@Px&44&^x>+K6awmyGudhCA1|&=&NS=Iwg};>HpO zuZ*!<-^Vppxv{o}38!Mk)3D?>6r4Yupn5TQneD}`O z2u}R|40-lLElQJ2aWpJxHWanMQk2t4i;@Thc@BdK3?~(6U6&=pL66DaOZ1O^kGgjQ zB}`Iwpr_Rkc}GkT+)eslGKqD z8KwZEB|8Tr(s2eRBJiPic*v-qpgb53Qo=~FdvruC4EgaN{{)40+`RP`g)xLR!}-ha zVR*aG?)?d-`68Q-Kg`ydpU3xoN~=jzA00ssBsolSpRJ3}68SldzeQ1ALHVGKMEHu5 zlvJmb6d0RR>(+Vpkzb0$Z=MX6o&iT_o%H}hQmADe&Y+I z2iv^wQ~xEK4?TnDg%sr>>Eu;fp2AE@lF5kHl0civ=u>LVNEJEw5EnqDZSm?Q~0FHm8CwU)hJAE6W$Nv;CC zD8|W2wLbO&R9NXb{lF48Vw4wPokQnMyjp?9BiB$16peNlp(IKw>b00WORGbsGcoaa3cHrHsZoe$=G1u~EG?DkO|sctM@J+ppm_ zmpB;gv$C>A((mIr!#K;x%LG$uio8GuK4n^9g<^02fGCVeMxZf@9KBAK@>tEg|`r&=`H9x z7bb$!Z)Qc+oc`+;rk$rmlrsd<%;4i5C@{r|NuoGmU^>(%F*#HmzE@ZD{wb6-0y=;B^TO~ ze(1P$AvR-Ei{KBz||c0N;u~UR)wI|u5mON(^w8!U)yAm52y=8;u4(l$%STO2Gf|8 z>HD(KXNUzY>Hjw*>d(^%{}7APFMh-D+N4sDe}*2L}|H z#xszXDgCQHNC#QSy3a*Zfxu(SOpcXof9Jb8&S%XsmR{}JL-f1A$A7SejOgEfl&4x`ZlX_lZS zFtO8PL{$?A?WQM)lh`b#w|ATSH=k!?-a&FM=zY=x%YjD|NZy>1=p^< zO~((I6d6HHQ4a%*fnkzTivqUR6p4V`I#4-QYw}S+kyHn&k#O!@hn3C-k3IYdAA0W7 zyz$mmKKnc0WPdkjFzVweMcjzdWr1*pWDM!Vv9=k}k0G^+qn;&RSwRLl*aBZhh(eH$ zOQe-ZCrO8zNtwQ@2cf3|v@Y=^)%)Ze)(Mn1jbT*PDo{HEvMNr55Lh=|qs~0P&SGpe zakb7?Ll;vqA*HDP7%X!}wwU4Jh)VZcIgt2KlxtXD=dvpn=lB-(}G^MOWbJDZg*K4rqtsm^{|eo zB7&$!&9CG8k`h5uOejss;n6nZevhOq2wVw8j@B?qbB6sP!_kCX8%kY4?S-*;NII=0 zoO5VXR?VHR3TUBZwR*SJdq3Bk3V~9=+{rvED1{Jn8BX;M4v;!o#mRSInTnH8 zrw7;M?!>xVyfZ4`WDT>hd0*6!I_DmkhMu@7cM@}de4p;bbACs&&4NRJUT%s9xd5l1 z*J5gw<2a#CcAKpHxMcM2?~$d2|Agik-}Kjc&+Csybx+BW-`J&|2*|i z{{?D?2e^2H!U{~S#lhtZoWFgWyQ^CyVT{-Auz8eFUkMo40m;rjDr(TEH7KbNZW%r= z_Ig|vKJBQA4c=br@YvnAX{~Ls;|Yq%9$}ax>ptV8M@e?9$rTP^PZ^0$ukBB0kt-jA z{ByHqf5=7YKmH#+L1W2r{Ra=Rw)`afdv8*fJsfpp&?S!7$%a5&d<;pG6yadnZXiwAafbx8#A5e@-zWu#>oZDEd){SMxBvTI2vL4`xWuAWSC%Ap%+k~m%iN_@6swO`y5%NW@U;P5Z@AKU|BhsYcr8n=9x^=b> z`*>bKl4>U7W#Wd9@=6M4@TI~!NHaqi2^uxaS{%K*>w8nZra}p{F2OoH)xKd9Kp%N`YdL9@sy2O<}rYI3!gx}~Awl`_CYdB}H z<%GN#k>?{yozaw46D3t#=_o@VDZ}Y@(-8SywJ^1Y$>0F1C0UtQ#g6ju{0J8Wq?sm& zWBkacPzqBNG@C8*R>Y_`BDX$={Rya?w{Gro>ETN#-(x&VxVO8*nX_9Aj*i$|U1GQs z(c9OQnPKbfCd(H#Sy|e^mmyX{FHLYx@bnXpv$eHBt=*;`O7c<4WIQ5IhIHEvgmVO* zVsmYc(oC^h4vZ6w@*#E_IXWDVP@cjILsmB~5Ckg0eJoSw_XFwe#tj6vqx|B^92m5a`Z1(ln(} zZ{qtt+Eki;A*-fH3Q1X(RfFRkLdmIwq+-}gSLsTnQV3%!O=@YXM#ocC@oFqg6Uf}V zy}ozy0ae|JiRPkqQY>!TXI#$N)Kbj#dne6A%-8-im-|dlIn$fYu~}kqYki7eDoz%e z$J>6nfbx;2w5C&yp_>_yTy-Watm==8T(?-+o$&6@*r#^Ew|{z~d75$gput9-s4wRQ zwOf46-F&?-+=Bx==T4;>EEKxt1QXT$IYqQsC`ONsW~C>|HftoS5^rCUl~o59M3PWL zM+sIO6vC2tH703F7&lQiryNhX_4ofF*@vD(oWF!ye+ZN!4ca*ExZoT&eMxFV4mvsK z15Mkv#8ji$$k9Ho?szN8Msl!Vj}3tvBwWv?D(_e9${bzBk*fY#zzwxwK~H@)7fmZ zvZnaTSH8^I3tL3?F4wk4xOkcR@)~A!jf1Oivv&5wY^=s~S`aFSCmp$w6eAF&g#wx# zMdVi(^SI@)wDAxV9kVz3940R?bxA#}5qQ-_UZ{fc=p}^l*xA3s{^8eHI}=f+DN2+` z1ec%OqOo33>K%|%YW(DX#B|^^1FZVUE7goI!@#CkacY1zEo zes@=fc6$5^g_;_j>~wlH7pl9;*&IlPK+RX_Qb@GcQ|(}NF)`L5gdz|MCn|N3#p0`Q zUeF3FDx%YrA~~BVcz#f=?@fhUsEUZPDqftZ@KvRqukoF=RT9s%JI|}YOPsNILgA*Y zOsz`FvOo(-6vZ@}OGJ$pwe}K0sF2Q*Ob#fMF)H#A^*S<&5MGs98i+`O}4bP7^CrIHDxTFo1YcZS)3;^ zMpw(y=@c}_qJ)}mkg8NSB|SXlq3yeyGwP zNZALa1@kl@cgzDlk#q0hbVAgu5I*7QpFbRN%Cu#VUpFDASFK|n>M51M34wqU56*y( zAH!l1KSlH*@M{5$Pj4{(!VZIeLB~`?gw1uynPy1ug@n<_u+{ar@W_WzcT#S>dL1>X zCZ_r;e?s%gyNsSGDbGDlu6%Ak^axwmuJFD~XShOx495{A&n5e;hJbh*htqlWRkZH%^WQ=|7C9?NFi}ErKeM@2NJlSv75V@%oWpP?9rntWcbr6ex z?D1!F@$=~31^2xy3|2|3EO4@q6g8airimH`qcu`^RfMKtDomG@g+{tcmjr?^s+nec0$`80pwlONzqU;P8V@%l|Z@FQoru(iyqt8cKgpX0oMgQF4WJF7ghdIOWTsISl_5@4@uG`&QGxdjLRITqB`bYq#j8|kVG$Utn@-U%SZmQ*VsUu0 z`^Ms?QUMV7%CDxi##OoNQdW~zDXGOVVWWW`)d@n6FbavAEgFp)p(n9!g|aLtii|8B zGwk=tyfMC#_(4EWYvKhpJbx-*z+g>Ek&P%#j`9`fE< zdVjc2d;pDZNl^G~zn!pJ6Fk+9c{%Z@wd*`1ms#0-lvn@c%S=Win2Z_!;8o6O%eJwU zYZpm_I(N@*(7kn^Pd;>!&E+QX_=sz}SGa2}+50q@k~FuxYJIM556Gfr@WE3SQ43k_ zG*Hsu6)9_jJsKU!z>2w!^cX32vI$shtQNNd^UsG{lt#$o39~pg$^Ky$rCDw&2YG3* zo}|&J<8)p*m7O6#R-L`A`Vpz72oPh@#**t2tu5n8fi8SD&i*(>sW7>w-|taZDZTx> zoLyh7G^F)9w#>*)i4y@?krTBd;%JGtZXI#$%5}c{&DVMEsZH+RJ!I7HbMgEd*KYfK z<`>`3AAR|C#s>*2k8ILfDscur_S^>AWN7PgaA(NsN`q)s^U$Sbl#qP!OV?@Fmr#*o zrQ6}$nFh5Wq_ecim%jXc{-^)>pOd61QCo6!`wF?bL{ay7RHUB1V6+V5uOMTN>S<~ zlJtlyE06-B+Vo;6D&3YdmB+=?l2Qw7;%G!Z%WIMkt`E6X`#ec6=X>`HKKI3MaDTT) zBaVnXNntctQ*CCA#b{jx)LDlqA;~oPSTou$32PD8?+X6SAK#%H4seA=8$o6YOfE6f zXZL7A;VPz|vjv{@SYKP>$;TgOse6V$d+8-eG=KWF?-J4A=YI4@c>UfRB#GgTn=y|* z^(#EQ`VgJo@9@d@93l=6`NYTG$L9Ngf}d_eWAiJ-OLe--%lz!mHF@FX5zl|;2#d$Y z`Vx(}#Rb2{)osCJn}3mwhXs4t?{V<;>y)X0vT~|BWf&)ociCJqgJd&D^2j-C&s3{j ztMP<4pQ0FRt6Y03mZ(4F&>E&24{PVXODo*e*E^lqD1nw0)6|Ko5RkUIMoAo=s<^gp zD$g*+qP3lxJ}P*2HNmRZ{Roh@3gRfO!A)KNR#c5zqtT=mw~3d#Jbd{v9(wpP=eI7< zXmkjI04W8|6A1iDFRKEi3@H5?w#+F_fu3X(g+m4jwYW)KYaoHr3dUN|+Ppxttl2~m z_yOa|h&)LNynuSGhLI39m(b1<$8B=qLD)j>?vU-@!j6V`p+}e(Rn6f^q%@dPlN{{v z{Po*3&pyGA{^(C|`SMfLn=z#>@bZF=TP75Ox3ByFtqoQiwzkgVq=!-gQ7uLV0Z0!g ze1x>r<2ue$?DdaGCj+d7NQDTg$nuO{Z;#&KE`B}c+{2I2?W`kgNirU>x3`Th$MnZT z_O^G}KRm#e8qW);*P4t)pCqjS`sXfQq!o9lMKPmEpS|5XjQayht+86;dxkI!iKN2T zV@#pR%c5HU$!eNDGb+ud^;D2vj=WuG@te&e>Mxq(l9*-CbZ$88sIk)07n| z-GYPuf#}rZ0@j{#=^x7@+zDN(oiSf$uak2N=B|Yp*HiGPlbdRB%4ja;{MI>-6*IjX zi4g(%LYMTB9(P{LX$%Axp9l%j>=urtsHAz6a`^V^Tsy4s_-FoOmQBLfzV$rgqCjiI z{`X%*zxg_~ANdf)lh07bF|RE*Xx@LDCAmS8&9P@Ccd_ibjM~}?x04C` z>4d+2?hNFTJQci|JvXG z2Nk7x22g;ibLsJq^6>dj^5)CG&td;9pL&+NpMRdGE^MF> z-0x3#?b=O3-!Po?s0V`8<(Q@A23?%z3JV{?g4 zt%flr-EPEa1V_CIHk!2K?A39_5iow>X#_@rCbP<<{*z zvI2(V0#AZ)Wffa#9B4zHR56X#IgG6`xvh?gY6Z3Wfb6Kil#W76&@GPo4pSzS+A&EC zr56#mLrNv_k`OQSNoB@nx4{SA_Y`Xz53$qRXJ_{aJBIrQeL_?6_>&n+jez~@J9L8= zxcN#(Z{ufa7bBiMFZqR^xkTaabMMyIdGqGWv^#a;Mw__a;LN2FE1MHqag9IzYQneQ zc!T}J9-n&d)BI<@^6SLsp25^4-tLc45C1Ml;~PlERaIuxRCoFA8l9{)$A^;;)kPhF zQdJ_Cnz^K>{l0Myp)FE4d|yphi?&L0nI4u>xXRchjwer2RN6P|Ku(QR-W2nMtH_8m zB#{;sHpp3vkYbuH<>tr9?BKS>B2{Jn3#7nMIj8+NByKNr?($aW9QF3`e2H-yB_z%EGC|nHVQDlPq-la44@i1D zM2!|jStrwi%s8yb2&0I0qr=MbCQ+?{wT6EGh{%-qz6Z`=jYSztGB~IrUX{oBhc1(4 zDW$l9la-w3Xn&v4u*YCm(*s+;2!}8Z>3i?$chL!dVWl}+h00^s_~QCpxDy7SSyMS%Vb6+DAx>I}#3GJd zFinLzh=iD*kX<=%-hM_e7J!AvvC4%TvXvI5ClSi@^>jiujqX z`(2onYFFU$8t?n)Px4Fu(cfcrWr=R*9AEpBzfYR%V6B)7+ubxT*;z-aHCa(qDN zG*{m~V31DmLb!f)%wPWLCpkLEY1P`?xx3B!*iefK9(itTcwjB~;6{tkuuJr0I1uswVQPuw655<+iG z=_Y6_#`%CkDKXXj*(uk}prl0zgL96W@ku2tFURcP)?|kR>fJ6vIXqdz_acN49ss7SNa}4^SeV z#aBRStKvB~UYIJi9~b}=?B860H-6d^o`^bl ztqFJa3nbnFcd{NAJC5r+FL89^3Y|`qR;$a}$_3(vz^0a3XgR;K!l&Nb;qzaAmCFx3 z!No^DLi_ReBfCvR2;H?05;y-TpZzy~m!qBUVl$1Cy25C@+e^clE>lT_b5(?>aH#31 z$Wsc>Q}aVy8;dj5I@P&qlc9vFl6f4IMKN_yt2tPzijZ{GD&6xc#MIR7?`BIzr7Cof zt71!2JMF)x3{_7lr0}t>ijTE362Gjby}suW`2j0u&hqe+A7FiXm4p5P*RH(C^I!Ws ztwx)NE>!3fvvn4+j&(<7-+o}|&Loc`-;n^;@YKicDP?+yq>r_5L22_ZXy2{1dJYn9M{=DRL zaWOTYEogA;$$Od?#X>y5o`1j?WoAZfCmyU7XVcFUe=ScHb?y`a%9~Gt-8(qdIqIOZ7ESjdeqxq!OodE7HKAKa}t75STb0;MZa}BSX>r)rGt^$ebwCH>~ z;^?=pak!V0Wsdr)A`TPojNtY-=wbN)03ZNKL_t*BaJ2VrcD?hoqZW5IFJL>%$Twfb zZf_%;fh?q% z)nh^m>S9dl64JZ?JW{P`#{mdMJ+49IV{}dwMMQx|;5B*e^_!gET;jXmeVwxxyWHCA z)7@C6S<_s&Qz>?X@s&Ue+t{S0<9rW4XKy&M_+pbV@rf^C|@G1Ko@#CvUStcCW$8-2()6w#$@3aoZWA@O_Wj3L7 z7AGxnqk%0lOx&g@4sq5nI2w`{IZ>mD5*~58OW5e5g@+6j?Vwh@-cq8xpqf$xrLD53 ztu4vZ5-mMywHm(f58uC0tYoFnGi1IwLw8!qw6>e>B^Y~NmN8)((dFY`a9C}t>7Jlsk_w5&APpF85S}_t z8g!Ln$XaAMQPW00TnppuRWHm)zFph`?W7Go^L&2#i&XYgk zPOabP;Q~V9gqmJM+&nGm0Ta|a8deXhOeNGklZUzmQr;W}3?j1n-r(f5Fx!i&3h?!$aw5 zWU!dg2GoL)jd_;+N#hgmFquC&k#Tk*iWT|8ElP#&q5KZ6R>$+Ib#E>5iCbIMBtm=O z<<$W=T`y=Ys=RCgwWSSy^izKamG8jdHEL2b=Z#!L?W3VsCJO-Y*G5!`la#}rwCXG zl!M5}I>n%u;cUS9%WYnJZJX42G#gEtONz;1$@=;xxft=>;}`kn_ph>FRz{kgNy=p# zlRAZJro6SEVaA%vszdW!o2FN8nTT@B=wb5jg5lJ$p5x2-E zW0LWJcDr3op*?{g)bXUkIa}!^m5;U66tETsTzu#vANt70_^p5Zzj3&I$T+dAUbx7A z`Wt_Xjja{RY>1H+f7NJ%&N47nGM@57`bUSv%@*zYI(d;31QA|Xr*s0}^I7jk42MHd zf>1@rF`7aWc|J-C%Ceet;_Q@mQR#_&FCdH?1XB*}WIRSFg%J*&j(Fq74U9FMJNGc> zwl49V7ru%~EsB!dXtFG2KPyRF6I#s%8*3Znx}@Jbz!f=(F3HA2cAZ0cK0zaOaT>$vc(!Z+5G;J1yS=3Z4lwxvDJvvD; zSRkD`J1xJ=w0f^FO2`^ek)b zP2T*$%e?o}GMlR**KUk?_4R*+HTO}@ANHx&4UKwEqZ6W= zTU@!)XLY$r+?MqAcX{vAkMNCey-wSYF@<6<8F6_jChoMj_SO|@^^h<8>wm~k{f+mK z7Y~yab@uM|iE3}LeRD*+vq8{QXnmJkKln}3B;nTm`v_t11^B+j4@;zH5E4A!5UBr$ zxc82+ElaQaemk6VZoZYn%c)=Ip6;IR8BXAk^hmTxY9v8`Y{QU1+AthsKoDdZpe=zC zY{3u=NRU9-vL%AFU_)ce6is1Bif(blA%`=ZJRM%=?w4QXs+;c#`|Q2_$39hctKJ(4 zCe2m>4ZN;;p>C*i*8aY=e#=l=k1tD-B%+oGoGX!~C$pgjvP>1@%{F}%bM=`%>*p++ z2Qg=!@=SLYutEkzk1;rBNV74M+(2&m*qMtgM03_e46OR;!UDF}XElX^zn0 zI<1Mrh1YqM)<+j0rBu}-6dHaaZ;)D5lRb^nnp&;S{K_h=P8XqKCX*rigL~Y*`9=uG znUcILkJzPJYif-Ki%YA#__@#V?BgG2;4>cFy~Vl}=*2~1t08;6wYi1`yMbu#&T#;i_-mX3wk>FKES^27@CkWng53cc@CY`lHFUKMGxmlhv$( z5L^qRK@QomLdfGk6KNLL=5h5s?rfHLDTvyhW&+W`asTdsXeWbCjeCuY*tuo$ECr{C zu04%kIEVknSMiM&wU7N6*~Yt+lax227BP`##x$FC zjL9&>G`kIAQBaFLNi+dnnCX7dp>(?%l-x?D~1%Kl&|5^U~zxRJ|Fe*q&iy6Pepm>`!k8tG@ zt@Cvzx8GxH^9_`A6qAIV54TB2B|6cxI)ZwqpuOOUn*j>#u?S_U8K~DazSIE;QuTaE z>yahcKrlzdk|KjF_e@5Lt&J4js^g?0&vU#p2$xgZjA=H;r5Oua)7Fx)FL~fnSi8!( z#*?78nY!CZ7gE^na82PPc`7kRaOO(F`nfr_wldmXMYF9jMM-W-_QwZ&<9n~Ov-ttH zKK!SU-eteHgSR=Rgu2ma(_s6-h&;8(g%*V`iEA~A%ulbIipFjgF`AhW%m5 zTs=nWgsCD-dz`0F%q#D1G1ruonF#ocM3H6=Q+jeQsJGiJEVj6G_AITrCXrTHDKK7O z3x^+<>9(o?y8dqvLSdEN$glsIG=uLaQmb zdToIVmmQ?zkL(s0;Q6vzd3lrw)4b5uq(Fy6c^v65IWi6t2t9buLlvcm7jExLj4v@| zP826}=Gw$M!W0EXkq1#{!<4pkmMDr52qGau=F8cmtwtOtEG#V3YISHe+oWkm|6rf3 ztp~WmAgaW*k^%P<-ekO-l}21h}AZV6i!VPex+z_}8wlj8ybQKgMb zM^@%wONu;aJRVUx$Wz1e>Iy4s=lINLe*|Ba?CovSZZ~iaN}ChM33+CbUSfTCp6abG zGLA{&7P?jkrH{O!LI}`d;%y5X{JV9DDJ%YKg9x{@o3}(;KmR<~+|m`y%hX^E#tpA75ImF{EjVbB_7B zMLOLsNvs(S2jQ?&0cL#ZuqF5?92gFX4uQAokhb!Ky6RBHG0RfQP+MI=lJSIETOmBw zhH6{kEMA0zg{)Tgs)D+g)&`;aQK#?yEV}7<;&c?&ITEDul*E$9(EOuSeW>+SCnkU5 z1diu~SUkig9j*UE!v83QB2Gf3js=H!DD)F1yz+$M;AEHmqZHt&PtJy=W&(2sM(nNQs9z;TI^U~knCo#&?t!x?!(Rpl&g=izOu%a8{sp7 zn`;uSEaHvBEL^6h8{`K&6rBdXu}DqT$OjgA28#WCxVZ^WPdRgDnWq*S{QkX^aWUlM zYtXp+Dx$qdv^3AexJTF(egGNYQC0*nEue z5GOH8gG>^flZ>+-wYW~Z*~R-EUVHxzFTQY<&6@?Qi)}jX1|pF>*zYkcViFX>3O=}Z zpEH-c#8H=Sr^|ECUtl^M(Q3uK@X4px?rk!h9MJDshLe(7`#d%)IM_=WPc5BxLZcq@ z-~HTw%zyc_f0r-()Ki%3Hb3(DdA|P|?DmHYMma_oWM)KZcFF58av>wX=kd~@RE94k z4HzyD#!#FQhtiOC6S6^p)x5;>vQ#yzU zYf0k`xo{MvAjwubc zbT|QxS`A$_M5!uJWL$|chIATypj%sm5JIWGSM408verjZp|qwTSOel(jpYm1_}piH zoZB1k@yq}CA21yrpoO5-ooDszJ}c8PURdI|LeW$kw@{lJyq1!x`pyS#YaVD+IOEBM zCla7U2yTUdMyL=iONX_NdLs_rfWqRvC5i;rdWORTq}0_-E5g{4{r-SyUQiZ>@%}FT zvgA&;O|#ynJKqhUc<+fLjUz(E4WzCIuz%7HuSt@iql74qsnzP0Eg~E`eBEPAm?p-) z5k$AMC(_K`Igpx2#}r0UnxYDv2K$5Y1-{G}jK;Xq@XS-sGq)>s$APr&Q@j~YLXCuIvgaHA92p=nix+n&TJG}Vksdnhn<62gBZ`ewft zl8cou^LQ11vXSbf)HxK!kFE>#GeItSY)?4qYt=Kd#~;_SJ`}e{FOlWVF$VSA*J>t@^ zDm{xW_+wFz#>TgKW2?uRAN@)8B1ty(pdo(#S&DbwryTYv7q6n!0?~Yg+1$c5C4MwU zsa4$EBCU^ooaw0G-O-4a6=amGwk?;kuQS*AkX-k<-QOj%BMb&De$Ywdp$3B!UeiPG z??Z3@Bddq{fdq&D-$m*AlAsa$3K0`7=u0bgM$@yT(+8nL{P1)uHCjc~&@>wYA-1`9 z>mL)THP#m&Bh3ZElte?rQmcv5F(qLtCY%pRe-t{3F-9VFLFu^w^m)b0LR?)V>z592#dw;@w zwG!a7>jqIi(bVNCncgL*dIG|h&h=n1ks1g>nU!Fi^;mi}mnEd=AC!Im{fds8w5jm477&m=s!+ozwmSYMdu z`NuD^GCxOA8gvw4jc02x;MV3Y{b7c%nqhC3-QhlsImybZqBkn|?j6lLw|A%&k8$y_ zKf~(96`FGpMM11vd)QVZPH!wuHlch3AMIv~X_iu!=EMcUVbMZ?tD3Z{6{r(Ij2?10BhrIf}V zO(Wts3Vu`%vDP>r{=D!3NfsvwGKqNh#m_OG3{zP-T=LP~=5uMKO6nmgV$zwki4tG#hoCcZ~W6G?N-dHbG0tcz8gZ1WN!i z##l#LAM~4UwJ$W`@pqvktv5^u;rK<|r zP-LOKM@0!zj>)nKgMOb_DPI2M4|DhSE$-jFi7B$G;J{H7250)b_T6vNp6l@9OFznc z@7-WJKEM?P+1OG{bGi%jv|4lY$30wOj$t~Ua0n9q2qk1~;N(&|bR320z7QdFCnU~= z3A_x^{YsA5P{L46Qz4+Bq#~fEya<~n9}sB5dZcy#Mg-|eUmnN4NW>{0-t5ZMKLT$w z!;18$Doba7<;Bdzl@sGr@kl{Bn`9R!*8W1A3<=Gy#r;fDeU?e-kHqLnseKf<@?u8( z9r8?P#Gv;lxD!3gONzy3V_b8cvNcci!5#8R9BOVEDdy=cpCy+|6SfBX ztgR(98;eY)4`?=89NbNL{liV3eEu@mu4op!k`Kxamd>=;-reM-7k+{#o;+Z8??c|c zafj!hsxjWz{KTi8!2 z_-$&%ZR&E1)oz#N6~VB+i`NBly{cX`l7VgFjiEG_NE-x>yfE~l1g++I?!q-*dg6!B z$}{Nia_`PvzVf|yFxoMViv8B(z&F-&RCd_7L3;I=MyG zze#W3;7f;y!b*&aduk3V$TT$C5-m%la5QQf=MAH2N}89LqPo#kbHhj}>NOpjqL3Vn zQe0tCN)n+-r1$+^vS>9GRA7Me%SXf$SJKe_^%Xm~U z?PZV|8m)PzsiZfGELvR@001BWNklg z$w6fqwR%ir)stGycVG3q@jVA4&ssxr{nDqH?`mp^B~qHatf25^;KvHVAM!`=5BCvE zg^Lr643(jWF3K=j(t%qlD@tJ%I*?K!ggv?`$O>X=tqZAC7Y;g(ASe#OP>Iq=Ay7(^ z8xyc#rA1nalNJ|CobotZpu8Xw3LhmnX({poW6LVV9?(=?2H$5{hD%`_Yr4xTJod!% z4D%6R|MKr)2LsT8TBAX0X_3$W>3^RWp8o`~7VK?pVZ5i_YA`pqK&w@!jzUR~l`>p# zeIOKA4~4O~3R5Mu#MzQT9;W_{T1<{ai8y@!QH>%mh_xm+7HbOPD8g7zQ93-D+?1Ho zG0i3%Y;TZ_hG-4*OLMgI7WI0A#kDh7Zz#)>qDWCuIH-FcQIwYHv>;7KSZ|4I2{MkU z)gX>*#Pudo6oc?+aon8Zyr(oKh*BHyY~k1bsA^M`C9aex6joYSHf+=e--avc#1RE#e>v%alJ%g_H1Z@&6%wD%ZO zGVJwewcB($U8a)>-k30uI($cZj}n5?mSK{Q!h3-_Yz(VJhf*p~6{?%RlnPhjp=5Pv z@}A&TR^o`GD{Q!V8Xu;x8iCdyEvNMG<{WO+k6O`-6RZ7Wad&z;83I3tyy26p;YUR3 z5f4qVe&BvxoL;Y=p4dM8`^72Ye3&>714j|CKc_HMC-6!qDn+Ygx0pezi$h^JgM{)Y zjjQ4mr|M)M`(dJf7ToTSrpBlF07ruJPz-zVC?5QgY4@94*+x}Q-WTmG#l;cQEDc3E&XH@q`{7PavJ z+cxN^MWeNjYPFbd7I3gb>xGvXyAi^+kkSxEbyVqackeLVE8vO88Qk8WeQA|XU7P34 z&HMBch$mBI)wnl9ynQG#b~HNn$H=Qk*VGD5W!aA28z1TV{*Xy*oo8>~^UCkt;u~N2 zhq&xJSexOIIB%I|Dc*Z(Q9>u8 zfp@{sZ!NUiE8N+*$NXZKyZ5&#a?kqw9PfN^hiR{5X{|=B5%cknKf(Qtx9Q3n!>nX! zF+r*fGlku3i^8VZ((~=_-(r$kjGGW8H6A?3$))VFEAXHtSz=!o?GOn z|GiK1U;W%~@}<;p>8UmT+Rweh(n^QF{Q@36EuPqP7= zcZS^i&ey2t6V9&96W3uX2lUH5h;kw+&`MDAHOAWtV+&fXCbhapXo+goI2au8jSpYN zA-J@9o|VOU&R)8}rRzV$OE35M@WZ$Gmv6qsH{Ly9T#PC594Dqs^C`x{`q`N7l4Gu+ zSXwM-T*#OVA0VB;n~bK6aE%y>9B-j49fh%!Hdrc}I-=G{Fis;x!tPGa*7lgf1VFa% z4x}K~ih4~D3rV+LCyqU)G}M$pMv6#)EG0QHb8|5}d%Fzw3feWn`t>)rLq=$a>;z%O3B#I(R?}9k;C+0fU&>^%C9k!EL=do3r6W$@JYS>7H z5I|^Y3W-@uSPKgme9=OL$#xWJq!bioiPQ>ZEm|w^GH_Fs#1sN24N(`iU@#}VVS06gh5Cs8qR6rprXYN{kVnz9JfOyg7t z5S5Oy$Plh1Nfb%E2tr^@Nm5I|%h2au%3x*j8tb4aC7H>|jA3hQ6JO?JCZ*M#N9#K6 zP6w1i>l#UtRDn?+3J|LImrKHH=}d{WRdCHZtW!v9QA$xtNofRLSfZ+Nt1OEnd{*$e zI(oeWOlFuCLy{!ssi!~5blPX*&IiHUS&1j-97UFLuyvo|{vMtA1s;3s89sdPb;iR! z)9HkItIgcPBI$HYF_{F)0Ul|C=#Z+av-R>=RQfO>wf=b0OEe=H^53jjrMCsws@mNUD2FKKlMDr(uEy5i&o*y;JRY9~9p3f=(#4I#loL&!$ zV_AB*?uW|99XwKx6h%jD{Nv}#SK)n*yu1&)7W`qY=qz{YL^|Ie2bxZ`N{N|i>MY~b zRrdi`I9k8HOZ3h@wRaDYqk>%_*mjc9Yb9U$+MBqf$;N>vOTz(b{1!ah(_A|%xK=B9 zMJ{9W5q`9fF->+v8$G{{U)K2114g|)SYD?k9FyGwG2g_DrnuV=@U;%Lg$~VDoy25( z}k?ajp zUj6ECv3c`1@OFAw#Y-dw2up6J&rC6`%y&rbb6G+GQMU++wh?LnbsE_cxep3Klv|mOD^u3YO;EeD}3?c>bAHrUzr< zSkg-ivW)>(K5+??rL-FzCSyUp_x6|@Zw&d==dN;gZJC3eU390; z-~Bs(iG_tF)_(DO{O!N>m-)s!AMn<<-eGVr<@UG6?DP_%#?xH8@E4h1dy#YNE#})$ zi=Zak?0xKW)Hg?TT0=55<-`6>%6LrPi|BSG%_eNUy})=or`2eol_QQd$;txB+%oO8 zlHp{?FaO@JaenS1=a$yEbZ&)n>*wjr&0!jAEUe|Yw+9r(nA}V-Wq~oC#KWc5Dod?C zGAe1b3L5PU;SMMc+RV}5+H%b8y%EO1IJJy3!6>t2w!kZokcQlj5YrSb1wL{l+S965 zK-x>fI#p6SSQu)BdP!*nju0-+Lwmb9A@ zon{@CXb$>gCc`0itVqWaV?sroN7FO6x%aDojxYT`tL)~hTzleKzVIi0g5~8dON$K> zEm&RXQcDEZL21F;k9L25=qbfRtyT-(QWtLC4v%nE8@5u^qL@6(5keg`93Ax(R|uQK zno>`gz&Sjn^C;&kCaFKZsZ>`YTP4ti_oxt`MyMzV2ni|*+&&#g0aHfBsq`8jdE$D5 zvsa!##tFaw)mJFelt!yVduf4}f9xlD>7~z*X9XYL{eW+M>nq&4@hZv-meWyvoAT3eG3QkwU8wYABqi%u9?dNp!?uFrYA@6$vcXc}9b3l zW8))~R>-Jci8zN;5{E{(;0;x(MlETeb%OK+{F-x^qNFee>pfOzaw9N>W15wWCnE-v zG2?NM(O^idH9I?-tekOl+KYIvK?PcY)H*O`0pZrj!b*s}77xhV)NYbio=k@Fr` zIDF|))lI*U!FM6?SYM%fMA*RD0O_qf)M3kJya`?Mht`vi^g|wpd4vq)RX^K#&rHM3 zao+q8ofG1IvU;uM4-^1F)XprQ{VDkVOp4y07@VFCP03SUNOfXJcC7HK_~1h#Lmrhv z$!cxxPcSKGLQ4MF$9X&@^)oB>ll@Ts$TzEwFT-m&*U6U&H;XU;Ib6S24ZAxmc>qQqjP zr&*sv)w)Djq*m19Ia-ZRuvyIWo$q{|Zv8Fh+cEFo-XPCv^haZgA}7mIoHIm9vcB9U zHn3{Wve6rmd5lN_+&e!kMn%@`ZU?oi2Co z?UD{tp1!(DT67srQ^u)bGR_!J!;RV$j_G6@JKDqece(Suukj0S{iCY6D5ln0qq_}erUZTY3t`k0p-4a}6!G$%flrs2+t97syo>+z{R#}!vUDXT=NhHHWH_?IR zScqUT=(Og!aOG)scJK4Xx4+9I&FIX}@$!%Uab9}iacjwc?rBiD_x05hjArZC^ojX$x1`B-DG;u zV{vhwd$;bgdHWWlevb>69>bcFrG*vTL{P8Q@v2%C%Mg|l6?)6dvT7WP5mBAO7>u`+ z&XX3FvUH@=98=^R?C+CKCS|btJcD7MxX~cbbDRr(+EQwijEE`= z#^J#s5HTtbs*;r$wv;kV9=!x#QhmMRdHV1kI85UkV@T7SG%d)|jAA-wECj9A9A?;O z>;6sF&tByE_2=2#xx-{{pVF21GOXMU;eBB8lrl?sWB4_sD2by6-Gx=oox4n)8@4y^ zvb+6&Je^{_N6IkOSJGA!G*3y1a^QU#&`3hz2&`nRM^O2emE@4^r4dH}eq5-vMpkGg z5yF1zBleUYp@e1ynV%7fhZ8|@8m*&`Cw=}n@Z=xLsmq6ER)R;Y;l(4wgLt&b=ybZ> zp91Hf=#roLzK{8%{vnhVr&{D^)BoO!M+m^f-*b3KmOOIdBp&tLQbFubKB5z?Lte}X z?-_vpER)qUV@WuC1nME7Do#wCPey_yASQ-)|M6=aY^1bQ%yJYCg}WX~97X17NXbOj z+1cKvRfDyK21PzWNX3o&DW6>Q#0(gl8c2m7Oh7jAvBS@Ik+miG-tSRdoKQCB@JnZi zrNY$P$VL~r^%nZTP(NR?U>(h_CdxJY=^4%vC>3GL<*Ui@Y@O&Sv%{&1*GH}SXKg1x z;061mpOj8hs3nfN77#gJ{Nx%3dw-SR`WOEL^V6$C;dNqIv!kpQira zJ47)w8ckk({T_=eU4|Jv_wuKieB-;cyGz{oV271;!=@QLoLjxw}c4VEEs5~F`^E?S(l30G-~961Tz~2rS}PZL z>{5dcf1bwb1)hKAlYH?P{~>1=&roj)+D%0w{gENN?gU+*@}2uT+}?hltdk;}1xl1` z-*m*&gk|R0+kHTPoU$OhwFyll`|_%t7X{AZZ&N}SoFFa9>~ zz4g0fMMj?Hl%*q%BNl2M5?4~ll%4wx1{1~J-7yQRicZH-dLV6~WmK7-Lp7n)hiOTV zbTYL69QqOw2w{%`G+H>~TrkO3#(4B9Pk3&ECe4|5Q z#*hh2>hY4mouukCFLPQ+NuwSioW?da-bD-s1x4a1ZMb+S71*0PR?N*eiL}NS8H$oC zmzGdTjW^!9OPX%7G~cGvP~5z?%V?ZZ+7eS*io%i`OHqb{xOCuLPK3thFwRGn&rK2! zxA^s6{hNIJ<^LI5U+2ABJqF_%FMsNzyAkF^N*u>184yBL>vmUFd-_lYj?)6I10Y|D z=~0h+m|D7OdZhwjo{IAb;9QtWl_gdhic%b5h@_ARC6O|K^}P(Z9;(znPT{NC$3yR+ zb%E*GOqz7&7FoG)iMQVPE_+)Ku(@M-WsQ&j@aMUD?MXIww%FO)eJ^wQM`@6JSU6Q1M(2^vM(K=%LV2|-= zz{1)Z`^=B!vl)HCtlGK{P+gS_kNLp)jq`?OimvKd9 zSaldUN1jhG zMS(5L3ZrybPH-}`;$0wGSSxT*5)O;L60Z)Nlt}5TZux4eRa)}Nlr&8d0;o5(!20EM|fR? z4)0?Xp%5XY`EO)WTJbNd|C7R>O25x~IA_-T?qrhN|9~l}I9$gcDch6i`eQbz3Qksk z+E40czE^o7%EO6Hcz?q0`hzJ09Hp$im|6Y*fahLRKJSypSTQq+ovl*!GwWf0a`HMW zf*+xC1t&`bX8p0=%W!=YhjW|ddqe8 zMpJeRNOKRuanVC!Qo6wET!Ql@gA}@RZHA)}-+F6@m#_Q|zg=9S*xo|NtGLwRh91$D z*mj-fk9~^CxInd9$S1C#_9v7J3mDr#6axQXkM!~?QL8~mdx}CbiOxV#N01#)k`Gtg z51j(!(a*L(oX+Dv;(R0il|K`ILkKLU+ zl=&w0W`T-5C7y-lXZW!n`LDVD_*LfTn>1=7_@pGXyGv|8kfF`P39`b_GnS3bElfV4 zGq*r1Q9S?L1s?3)qt>kP+H3Fg{IeH0e{O+VCuW#VdF7R_vA?@bk=^I{rx#dW)$HvK zaTCj(yE)4XeU_FwSgRTJ3p%xVHt!G6ElYR4gENjS^St!z3oNdC-hbn}B(*l3?jqA^ z#$WxpzsAz)JYK-s%g>Pu&FYyy!G#xognDBhp*+e$ECt4c$sihLB*PnQZ0~dX_BM_4 zn#g**^-T9mu3b9=`GmdRfHW6m#v-FJ&%AJ!QjW;7C^Sz9kkZp1dmaMteu8SE0gs z{7{67L#ubye~$OK%FrLlfbANjhH_F?mq%5hX~G4_o4|LpCNOOiA@NQzoK7e+%lxt> znFFCLB6IjeW2Gk%o>oneM1m~S?Dq>w8wCN4!%hW-5P0E`%99y`RuRT(`hzKrNbuR0 zALs0911mCq=R0?hr6CfE?VUaD+o~GSI~)ox9JtEZ?L1mXp?O2-z_#;&yXl1s7!8}U z`QQ!y!T3Uw5Ua@FNmS0R&N53rOrOdcblh*bDbsNgj%y$whpAQC#j<%K3f zp<<2Jn&q?S=`64C_M5LVIOq{KYdrti&+`0}pP=tX+7PT72L3sYF8>6D^KG3hiMhH`^Q zJt|HZ_70d#M`ZaFW7=42i3#g%rB2?vT{U@9N>xZO57@w~RRU+_(Q4Rxk1b0^;|aa} z9j22J^?DtpG*bAZ1I=_YWMN?eNduGR^mn$Ij1O2ncNL{0$~(7lWk|vwrEitMx=KWQ zaJD2%OY$P8+nJ}9B>1u3vKO56pUyz#PZThnLRihN@BK_YsGkWzJyQ6J zM|`hG6KEOSoMP6m`Y0UH$-hJDWX*(+R$C)M8jp8Z55F+#SGbqr^dIn2eU z5Vbj+TR_wWGV&Pb@w;Q(g(+v}>g;{zRs8M%{qm>jeDXzFPLOpww6dIKEH@4gxODz1 zaxX@>s_=t5-pMPEUjoBd*TXl<3FQbvoxEb z_RiW7&I<;EA*-uvT)V!=!d#5Ao@wsTT2K~XO@We{ET5vWNNd?2_V9T|k|e}&jI(g| z`~^BulQ+Kq8rL3MU~l4iYGn~Cr{pH#%IZa4cNyi#VogpqmEdC%+2xt%YBajAzc)fl zjS?E;QXafJlR-Lc7BEb^k;sYzxY>w5wDx5q``p|#LCf( zH8oEVFK6d*M&OLV7U4}}y=SmBCLY{lGTP(T#$ASKN?bPSHacXZjKw+0;&Po~?|@OB zQEPQkwI)w~{4!_PH_7cb2cs$3q=`@&zBXl=-ovEtvb*=sNynPWXb)@pI5efpaSoD( z#mSsf)Y#k@aII5g^-PWZdnwni&(o|IY<@6huq)`+9iuD@KEg_bs+o#7@2ZuPw1C7q z&<-LQ>fS~ZLs^25VZ2$EVNz#YNnt(0IT9^#xuDDxm(R~r=0mKHD7=Z_`)CmIE|*_o3Fjc_ik+B$^?W&sSk8ftHU#fnSdAMy z<&8IgiSD{&bnrD~o_(Y@L5;+h2BBl5QY3L4rdid>7AXRPM_Qe8+?Y+m^ zGOW8*@S}PqpbTB(PAX!hiFHI_OQcj4CAyy5lD!lu`^1_8IjLjvoV>0N`+uNq!+ojcM z(`mNQu_8_sN-KO-)G#~Yk%+L#s46y<5Lls*-r;0e9b4zg(v0C~jL9-4<1xMcU7T^u zcNY*icDFV|J*)_|sdw>eKS$+&;(1D4m%v9xxc;lU1*Y#4sts`t(zGu5Gx&W5D2 zag0WN8Z^*x0?q}XeSN+T!P3^=(fu`fW_Zjcrp%@k7A>nnLzCYY6&tja8LG35S z@2o%YWY^KLP}Rp@JF*VQnYH_DKmE*T%s)zGA5TD!R{WPF;ux1h6(mXa%p=3sh&JQz_%nsKepbTna62s+J( zriH}_TyKoDgwXJeM>xDz6$#?V1MMF!T3{Be@Td+gapLto5t8zM#G-U$1Wgsp=u{PN z)(6oN)ildz+FV?dM6t)0%Xlv^-Vw)wT4Hder8iXcMjqiyA|V-#a)yJPsFBg@?W2W5 znK7MCjit498d1Xj-afm%Dc^bjbw>R@pMK#9{`qge#?>?HG+QkW_Q$;PFTO=XDL(uB zdAuKTW&WPT@9xp!D zMyOPbwfIQVPS-0Prvq)`JQ zES{9QF?5V(GD$g*p1druIIuZMY_Trp(t3@WP_!C~t7orr{z983ect>2n~aKt#YPh) z6z{(~W_e-EzL-?gKoR1rN2?%^x+JQFR+%ETCEvCEfOV)q6m^80T38qfWhor@7>?}u4l=`d3&9KWV1>zuTboso}TaPe$W3r z|L6HV#u3HpK;>3SQI|nYYPCdI|5h4ZTWmEVD=nj}2C1+ULzG68Re{S4j1=>;3S$hr zqX;iM)cFJ<1zLb@0PD`Vpw2YwhgPh(e(@BS&aKexw3u65=Kuaze@GY*?ojjQVMgGR8pxJaj!@V!6#Ce{l&{TZAw*s4TGMbc`s_9(|YOQd3?j;I^uPBzKqvMR`? z6Y8p_Ha2)QtDIJ=MLr#prU|3b2wzu_7dQ;UHNEZ_>TJx;=3}-t9@6b~X?MDz5h;#A zrlj${V&)H2HYxW*H1ZH4FT@cBBzR+}s*1^Y!p_bP)9DzKSM2TVpoC;$c9FU$nU06x z!$mBKQ)*S2CWqy7tmZLSVX*Y2WxlloAF~my)Ol}G7Xb8{LX6`o=IK@+KVtAEp)S&6o~4x z=9KO?P3}*nii0H3LGrvoD|vO8eixzc@^~B6k!1YAP#_P7B=3(y?T-x)s<8(6#>07} zTv44DUWtUTU6wXd}EtRHm$v35`}#}QBN zi4uXsUZ%rFx&vS9G3EJrz$btBs_k!vyg#CNALYj$4@CKWVgk(yoPD>Gpwn;jw|@Cm zc84`9tEcGoSGe}lt8~u3iZ0g}?LERd#U~$q!qc@+SSDq2V~b7_C^1@D?%Wv@&0NOE z31lPu2mc>D_?TkvE_CPN>WhfkOC)K;jD~b~i~gx|>?lnl1@YN=o(?nark;gvg!hKH zKZ74c0qXD6acYC`$0-d*xwr>E1JAPqA00qXe!k#G3E=-oL+M*L;EOK^`fZ0mQr0jW zIyScqAKmzn;q(lKE~l3|%%&2dg8xY>kF8_2hn~9+GM;P>Sel=M+A^8$(3$O`ea>`} z6UTy6OAFN5kTmI0PBJ#`-{l+Md>cL2qt2$h_0A93+Mcrcbb?OysI+1{o)D#ywXLTt zotxu@m*!bHv%(+z-iPRpWwI0Ppg&i zE5Gpb{L^3mExf3BZ~a%a;tMRyzD}oe8kL+zC$q$952Ye1>v^&^X6NQN zx&Qv}^1}}wGcI-@%7~?G{D1SrGYK+1&5!-u-{C(vHBa2~bh-xA%zSav_93&f($F){YIy{wp4W$c(5jM87&^9!N?T3CM9fPwV9gzsV@Ineyq?-XnGrx2iB@_>C{}2Uq=a;!~{Rm8k$B|d-si+p_RUG9AN4ztUvoL>An20OcW=ed9L9oFvMrYsAzQnb@~KKJTh z;jQoe345FCteig2aN`Nq38q;_J8iN3^kJ|p=m;evypj}UVDCyDE~VaDifoERP??IV zuBfdCQ&Z((WvgZlRkUOmMyNf_>JA*u?Mc4(z- ziZaJrkJ1uX;OmObN`LIl+}bS7{Un4NcEU z!SK9#N`F+N-ERSE!d?4$`DZbDjcrK$#owEFW-Wj8b@?~xc3Lqv z*Q1-Jynp`@+6v}dGn`%OaPCT%NuhDx(2861=lZO#4Om%Tn;CEZ z$p?JtC$1vOJ*@5V5B`_`lDFUgHM%|Uw#V{9i|xHl{)W;&0VZGA+iGfUKy zn7E6GUZb=xF&G!zy7?!J)_)VbH>8->DCGli-8rU{nk2bGJuJEQ<-g6DYnM6OQ>do# zqy&&LlgU@Peg8jXd;Om=-kB1|Ek=2UlLF@i)=FyQFjX@wqG`7hTHQXeOi1DgwB_OU zW42|DiZfK-ar6CM{LBjPec!O0beUUd^LX+gtOBLRdI!QI6GwN}lXf(tof20@IP1tw zIBaVZ{!QLGWE|s6K;bAMS)NZxQpaRcVT+)!3X?OM3@DvoIH*D>LB=G#7}bZ_ixER- zsCN}R55e~hN(Jjc)T&uLt*JA};^1KuPT-Ag)^r|g9UtC)$c;}PVrs{QGxH1vj$4l& zu(G;HRZhsK8F$B1TJ01e!fH@!h4;Z@G?`k2uTcV`ND#LYifoFhYE%?Ap^Na)bk2o< zg7tU<8;?dTUy44{Lr^90KAeSAYtl5u;)(Jcr8K6h8iD0d1<+Cjt3{K37D8ZcO>My% z69N)aBk&yYJh^?B62sF6xAA33qy!hQzRcwpzrZ{1ev8eAcQIwn%-lS4bBh#t#$<2E zg=^P%_xo=$9t<&6jq#37e}>my{R)H84)4GH9ipVgmw)_cdGPcBqV!mk@#O9&*xI6` zB2HUe`rNBzlL>>(rzC00aC-}5YU&`$u{+qqmN_!g#8HgYF=bU!*#c9WCONH<5~`vI z4e#Dz@p$X7WeAK(7b<&&7dX|Z{r+%mr~s1}Y&^O{D^9{dAq6su5e8hZgKZ_D6-$N# z!!?ab);j9iP*nz7RMf_j7deyBnBj21&ek@g!49S>D2oDH8*F8ekw!XCRpj($=WxPN zjzS%5BsEqjkP#&ggTa(F8|x1_ed;2enR)8nZLF!n;Uxna&fr56Q={VQ#u6}{jOoqH zk+j>m%7Byz2TE#cN~Ds+#28njlxeIIG{G{1-FK`DjTQ=vAvl!-l1)VlV?18E;9pkq zGagCh!7AK0AtsIxArHqH^~@?*e9Ef%SW5h;pYy~pDh~XV;<f8{G>-z zNv}@s){hJ``-8}#qWbA8^ArE_169-?D4$1%*~1y>d7RRd1Ce-UrT?in2c8!KJF>KH zDwhvcS$`xr<&Pt!gh0B4RFzcUqo~lsU{igYww}W8oleUu)F(+xl2FEXtV}1 zr}@gS{MX$2#y@3exXGi(>-4*l-H~N!agP4gbF5{jD4c{&A2G>sNe}5$A|t7kAd!kp zI9z2YJ1x+XbN!gtMT=km=mEcIZeo`&ajK(<*1n4rHOePw*Fow6oWqkp^WHxTzZb{X z`QnHt_}Gg6#Nz%(kV=1~q4dYUV)@QHlD9{2Zq+dy!^VyQ5wmjkB1QcGn?2>>olUma zZ*lMT?@&!1P`Ckc_cU{}*Li&V514K}Ax(dm#o4p0E}tilx}=d}I4X#xBg-cAd$T-w z{E(#GWoT7Ilmkg%RZ-qk&5o$fNLNFPnj5l6jBDBazA*o7>vmjjPfFEq<2f-|*1Pik%mrnO7 zCONxnQ!F*!dRl1$EsGU3bf9}N;>mD|7{%yzs3YynNS4mD5NUzZp&88U1Zh0l8+79# zi?pK1GrUvu+6k|{e4UN8A&(xd^YH8zvz?T4=T^CYe}l=WXd?a|M^K+^Z4lu|rM3!V z9eJ7Ig-4=j$p~vK))}Ob`*fN{rLy=ULX@+gxjGa2?ZdCK^B$#C=nR*VIEsjM2rzl? z@dwFyf%p47(<-d!k9Y%XZ$nf-$b(^2$?!GPNTFnma}m~A@DAN1>qGb^{Mr4rchv2% zI~pm@X&&R-(03m*RPJJ_tiNk#1}Q5=V!d0U6IvU9}FQ5uIzpe{0;tpdx{ zHr_V@d0B?4OQnc~#NwegBvMc+iK`vXdV~m<<)bQ*AcT8HgFWuuxk+8uRF$DHhGJ=z zg@py$Gqbc>Es`h-f5LmJvY;#rrddvwXOz>7qR1%9oYCHZ@!l>wo9m4C){(ZR6(!Wx zW3ULNsj7_1mRM`)&nz)AA;_g74JJf(q!Y+8B;Q?Cv9|G;Q)e$>g=4h2h45eq3}Mx* z{-lsd9R>Ra9!1S`yvOY9JaO8gszMu|bRt-w5O`(qO5&XcB@ou&ou~Fe;g6A6A+S=A zc!85(P2Hde!vH5_K+yBqZ|{!)^gm7AlgAakgYb~#c+OcJ?5|IToV++e=M>KllPCS1 zhsxlwxdKkE@x{?kIOLA{qk*M;pQm@v2$}vl1Lw2r@000l(O3=ak)M2%#8Dsa^CMznKhXAXQ1SGm1)UPbr8Azl->q1C zQZXLv@bu{|mR1&+ovDe`5K|f+-u^@G-1-+()fRX~m2WT^e8}$8Kck+GDGONaTUPoJ z`N-2-I76O+k~MK8Svr3nS7!|OcKGntJ@AU#ckeJ82|9CK?mu3q6=@!=4M02cX~A?* zBAmx5!Q8?eMe&d)Pqt{EU!WRHSviwZTf@6=?=Tv`%9%DVxq06I{xg6lIuW9* zdHIDm_~-xf2P|~v`A`1lukhBp-)C=QOj(tf-iRpc5vMtsj2LDa+0-@w;TR_jIEnRP z{VP1giN{u+PAqAshSBIQAN=P3%<9UoQhja}6^AsbtsPr?CAUAi&wJnhHR|0l)_N*u znN}7l1W6)@+A35@)*e$u45taBQOW$WVRlYnP4i$@igGH5qm=V6T%i4erZ?9^cS~kw zzeKcolb5ev;LXQ3sZBu?OQM!RX+beH6vKc4vw-oT?Z;V92zDQ`>;(HXg@$7)YlIBL zaI6KU%#p+_FZaoO!RB^GjVCKW8HpDL)$`1qN!j_hBz7&L)U$d)AmTc-z@(0ab19Rl zq-71APL}}&gv5DyfU+o^JA?|m!B`3^>w_;= zd6bC4>aAf1Th{=~eXv`&hB533;igoo2Bt5O)`i9{Oujb^ z`3)V>>(3J<3A;P%EG(?>$(<>KSf* z{2r&4&hg2O?~_$E-Wqh=raLpo?(Pm(7f*9c)5Mu+uSK3i|VlOosy!rHQl-0XbP?g+aT}f>UP`23zYaE}fzn z56E*HyqzxCTZ9ZPY|_*4Zw06XtY)bW+H zJZ#%JkslJzQ9KX-f7xh&NBN!4NtGY91wK#S^2a~oPa=QBr_?PUhKLzSKX%CJ5@Pe~yJf9DOa-iPt9(VV;XaJ;wYO2=UDJ{HK}v7(^JGn^50ltQL6h-88I zOq*zDjq2VVxjcG~6R+qXHtdV#AipJ8w9A$!9ew&Qum(*&gztv1|vZx=|fB1J$((&GhKVWesW$%F}9$VsWPGS{ZrKwel zjS4CwD1{9e<;W2Uk97hqHSKv16)c?+w8RwAose$a*wf zPz`nl5kfC20%rvdM$2wE8y}PBHMVwaZfp}tN$qU# zzWRVh7S1;ne=4j(jctNEGK2uDKvch22ypIwZ;kgJ>qE3$$PfxsKwXE_a0p_2hAOF! z@!n9BMHm32L@0$v;hVM_Ej5WwLhYvtim>;P7kT5Q4N7RFVr*T7i$;UfQJyA<;fRzz zpfYHs(OObV-Ml{FgbAvl1Rb}CdR-=a+nDJXq-1gV3@^U)CAN2-u=d~+y4`uS*6gmY zlj=67uU?})x4>K9`a1b=r#Uzs-Ly{q9eU?pvT*|O92p(vGmhnNl*V_;Zi=#k7=p+j46w|aI?xU3O9wor* zpla87&fen()YBn*ryjC<`W#DVF0e4aOt&{f6s1Vv$i^9YHeoUzF_{d=CmBUCVKf@B zy}d@6O-ZC=w%tQwvBn~lqTT9}=Q&ESq_4&nOZWX~Iq zsjJY;}IL{8=St_X61aF(cLcFJC>VwH%XM`r~bxe zM&pRR-J0#q3B%Et%NLg!GC`=CJGXZD_kQ+kT)cXYQBl)5+o78{Mo$V_K4LU-Oa>OO z3~66*?er3ZJZEz>!B|0sMn(P+zsqEN13`~8>R~Yy z`7ZS+53=|Ekl`VXX7Kead1fiAF-5+^B+qcxVw^*?PtocAJk#BGu=OLNI3+JNS!vnb z+h%q_b9(7zKK}3y^p@EhuXC=*$g3KXrVH3ZRX}AS%M8W@6)Y%dp{2`N4+5hQbN~P# z07*naR4(`ih42XJ4+k;<-uaMh77pbF)7=5>bcXSGgrmaRCWK?48;MZF;2qdfK7xBnVaEF~~#{MT-7X%HGGjtPd?k+tU&Xp&CA*^57g*UWJN6r6?=I5avKiAg?AR!3?oWPoOKAj&$g4{b#N}QKpU^HGyafV@ENY|t2*GH zTomjfS_U+baRFzQ=$JIoBuRqxL2=5<3g7r}_n$OUgf4rau>dG^6g2?%rcTtk!;fo; zmLZs8ZQW2fB*Lc%5i#1`#F`o{CCU6Or_NnwZSw(ZcW#mI%#x%r6k-Y!Y2&5N&miCZ6k z08Wsqgj*lKg)tS8R76r>rV~KX=`Qi~;fE-1up)RtwGHWR>qCGi&-vpm1D?Ax#lF%ZhtQ@tik*X=_XbwPy$C54Ohg@Hus|#p&o&a3ZDdPpDYp zQ$3}CS4SF+{-V&(p?bTo_WP5Q%7GI=ocP$M*;~bNrYWE9Pd$m5I=WJS-pG4=s8&ZZ z_@3wEvl?R8ksLiSs~Ni1uU$g^8jxS53X`pZmiJ;bLe;@%_ty*rdw&S5jlukGzJdi&c% zNt<|eiTaZ#6!SB@_js4{Ez4hBUF81FTfBO%&)2^AlUzLaI>a4nreHH%GK+MOs`Fsh z=$k7P<1x;c%^K*4uX*41>z{Y25XaxEBW&8wBz^xs{1>lKxg~t9u+vY_(S&@jV!EEv zdgT|GKmE7x)fyX*ZxD&V_7l$He2f$ZYjt3g8W>F^S(ed?3p&x1tSniXpQjp(Ns^R& zk}(_%Da)Ltr5Of$1HSR*TfFkp3+R4CyRBIeUE2K^dwY+hov^sL%It#2iv>n|JKTS~ zL4I?W%hzUk=k0B}t%STN$g>HZs7s*~(!q3Wd0LEFIx~;34kxBOetetX`t9H5?ZL;C zGD9YkaRf#=GHbz%O72pWV`@`TmNmxKVK7vRxtSjM_#>2< zqLNNCNMr~-!FWY${%bJ%C01UT@+ZIk-*f5AMHbG&#MS}LqQF)jYXzn@p*7{8_N`G! zy`$IZkd5+in9ATC-Ji##YQWb*5o^i0D(;ueD9mo zS=JP%ghrnz4%}dAEZwBdbTmK-kdeR@j;NJ#{l(WAj<>jV;~lj0y!h%HboyN$-1v~o zm#%a7_WQUpM|pvkK`E|*Rwt!9H-~&6P%|PT*zm{?>Ix zG1z6JsM+3lN~hna)$ZUNcxRbT#@M2ysZ76v;R2V| zc}t`fzOoG^LE>#mUS@P!J<5E9tRkEa=qlxbs8P&q@S1LJJZ53_6myF!40bj!)*yVt zIu;GyNrtV8(304J)Dh0r6otV%iIhp$urz2Ww7{ZqjWS>Rvf-o$ucZtIYHIHSTh}=v zry9GP$2AwSe>?v>nm}&CG4AL(Uhw>g@?p)RIOg3v$uK>#G8OWCzAaf^IRT$`^N^pPl46@BY(d*8sI+i`Auyo2Q1R(_!Upk2aXT2;)H7b zX#>&mK-3`;%O3kHJRCzH9WzJ>8Egg!gwSaE7#Gp$caU{PJhu$0g^K!E-NpL~Z%TAj zQ|lx&kqL`84p~l_j!MYRNNb#sk99y0Ihc6 zVG!Wl;IzbPPwgzW&d80Us*BJh<4yC+BS|#8{6b6=t#kjuV}y_KR-$4g?dcRmg{=rmwG3zZ=yAd#v}N>U%*t#; zoJPn<;WN*qu=M5)C6+`-^yfN^%bcpNkq)E^N}==afTx)x2~|~ve}g}Qy+Q_$T4Q|o zNQ?`Io-?k2mWSK4GY;t`(ueh-GXVp>(wpV_`72!e{Fix>o6q$4OVbo-!ob*$Vzg3B ziX2l_IBQAc6d?q06o&$es>1o2${9*iU`$|`I_HAF^q_LoBZb8gq0$Hqs3;2>B9yKqRf(w^Gp!IfVUcCQ?#2eIXD^YJ6PV=9vndSl!V|U< z-jT#{xbxZYJ7)+b7)omr6$PqALY*G|+;iRTzT#i!U4IO&7M9oQj6vyJ4LW~bwY2Pd1g zVwH0F^p{EF1**EHbREjV63@hVl_Eq3XKFUz|9w`k{}{59AglvZqorn&)yVEC>Tyng zafxCmc<}LU#y%ncz2Cz9`+pY~C&=y`-LL*M(|(XZgBU;?{V#OUmz*>@FqdAi_{AU<&ic+$eMWJ0^SP5UJUzHr2FsF z3GICUXG`o`Rt~Hi;)L4$Z_b4Jk%rPNE5iELh9(3NLw8YAjVs=H^EWwj;j6f64=X2F zUxxq$GB^yp#MF+e4u_d{Ad?8^E1amAmSYkbV`WU*YU4z~bTXpTiYbcWP5-bHmRc|PRorA4NtW_Nd!#}7PLuXO3Q zW?5PiJh(eSNx|y5J{Pa`k;d}L-7U_Xy2kbE*RiB*KeQCOWLi{6Z%I;c(xFm?iUleb z=r||HR>CwcLO7fK#g-X6F?TA8jF=WUkXDR*GIXMd+GrvQ4&kmsko0 zgDIubh`mijyl-;buO@7u)LtU23w5C-=$7U2H;80oQ*U}Doon1r60~+)I&+5M z-Y7J-;AwR`kHNx=Rt+nn6}G$X1C$qNJcM9Zw!@;-x^x z5v{(4GGQ{Q!aB7HJ~(fh+nS{)eDeT3Tr;@_i6omFpKr7+Vzvo{Ew($qL0R+==9X(tI$)bw&Y zLtf?7Rf(@W!Ue{oQVOjURr5%$Yllt4Yp|cDPGp1<>cBs|-#w0$*t%vi8Byd@oOMB+ zP1?*Zp9U;z_dlX43v?7<{6Z^wGxN;PF7V-d-=P>yg7VlfE>Vgq7yu-J8^P-c+!H5DsrWI*RG{=D2_B z1AJX0guyf|Sk46khR32L;DglxAuv8%M1+<|Ymto&#bK!I0c9%;-BJ>@G?Exg1y+ML zWZpGtafwy}r#wnXq?7pCU}YE=b>ml)D%1>PLy3cP{=h5fEf{CmT;8u3neoZY{;G{qs# zQk6M#3#S;Er&MK$@QusTgK?pO$=eXQafAv{>B0Np`$o8sWZpmggd&ojS_&c=h1cFW zPz@koxZq$_!S`%22p^Dk-Z?7w*?US4XFhR45P zveA8hYr8>1oJ#U7=x#H~K9M582p{O~Eplx*B8cRz6(h;Wi)Ro6t9}Xe>!7bGq57g*LFd7XRjiv}`nO#ij z&vxi{I&^f0?a`R6JO6~PY?I%*N6QWvR~3l@>oua5NBlFQNzw*|R0Z&B^NTQ_8XqZz~7O4XENU5gjrokQ2ctZF8 z8yODzgUUYd!!X;dEvyaiZ%BbETHP*6#$Zx(Tyna<%H{KySh;?gg-^cC?f1X+nI3~x zRWsLb(@Im2k}Mw~2}-fliZ~6tS|KFXI?BqB7bRI4l+@6q6IQqTnGB_xT1zRB4LDzG zO&rHaL^HHOUDqHKrYe|DrxfLsNjAY-m`M{BPoE=cx7mJr4`B>acxpVoq|MC2Df+WZ z+`9QLySuyObxCdNpg?+oR+2v1u40joAKEc_F)eEmM z+n?pb_rAyZ^Dpq={zsTR3pNhxvBKe3n%8!`k4Cj!1qDzx`lXK>AXC!`7&yDAK#r7fwvX@-N)$fcyBs_R2sll4@};c+P8 zL*aq5VYP2+hI_kcsgO~O%f?}A)6hh$tBIlrg~o{x2+T)&%q%XluzHr!`WjhXhD)3m zXe1hmbrvBN-a3595F*1O2IHG?)q1p62uGu$f{JP|0fD8YLJ2|T!N@>3h?EW&rMf93 zaE`9{Y?;A9O+P9^dW1g=KOKyL;yAk$+ca|>2^1ZANRQW!9yEG2%us)zM7kpqo_r>0 zzyCF5Q@!dA1`2;7lyp>$Ju>Ke@tj#vJ!29Gp(Fpy@bbI_w-Dk8OrMkHfwor|93s>p>1Bf=b!_`5$k|xhB9|7v?h@%Wp3sgY1+cc4!YGw$Z)nH;~?7k z3gv1NKOkaCHQi${c*t~=(qCMp+wKP1#AJ)tUVVl2Z{NVUl$I=s{D^TkqDCT=2Ct~| zDKm>b`fkkLy)|kXF`kTA>?&q#i(=X%oP>_-B<()7 z8dFvil-5KPpiQ&&XI2_YSJd#j@*NReF zy_|7rD4igVA|e@aer}0Bc>^t&#(Nd5Sn&CmS6NzG;Mz-$k3ZZb zpALBG<(O-iU*?1NZ(tvMM4C=X;yM1KU;1}>vNq+>WWvAt#-CD;EV2@GmK5FDaN9&_ ztd{iVBr|6$y?zd6hKDzL7?)7ihN>>e##2u9B+CmOG6Z|Jz#Fi(##v822?vAFCfFHt zc%9NTX%gceSJpV!D0z*VFvh?U=H(INM6n}%La+{@I`3LC#HMSx6QwZ*0s$!%K}4L@3>P<8D9-TFpZYl#Pd~z?&6?|9 z{~RmBg4v{D>*`fL`R_l$a*;jQC1JO+6gmly)+Y*pQi|Ldj7*czCTG!xwOQtf6(ikm4X-22c(H}1H zm9Kn;5CZ+B70$ouQNH|@PqVzd&UmszJDZXVg)|!H9gVXTCc_8MXtd1iU@uKMg}{Z> z$l{|zselwQ9kQY%N|C(X(V~SWgfxheLLrny#X2SPolkx9&UZ*8e{@6EDp3-&7RXE^ ztxFS>jv0$g&wWI9BCa}p;WSc5;Ap;6jAL;3Mdcts01U7ZRtm>#p}*x;{pM?%?-INum=dtB5KbH415ye9et> zSZ9yEw%9Fg8W(W!!M3X%h9Hmo>Ea1&)3-+Bh+~51p4>nxL$jjx#jZS6)rsX4y@Pg9Bg8}N6S7Yj0y9YDu1IV^E2An9H%8Qi2Ip% z@3=8e00{0U^6z5nK8Q)FKLl9CfQX*Zg3|&mJtp^PBM4p~y-s0@5D)i0gc#FgL5g%D z4<2VhX$7IiIggYP>nozGm{%3GwP-AtF5lqEN6&LmI(85C(V1jralrgwh6pg3Ob|Nq z(9_HO;UC-p@6eegFBbXCA0F_Y51i$N7hY#!N%HPf8*Fd4tglP1UAxY-scCOljK`6O z7iWCz(DqU;HpNuV?t2eU|YmRtuGM}1;1 za$x7_Bp)52iP*|w+Xfj7s04wQQ4kfNBtABj3q5p}!#sVEM-gzrB7!7X@XnLl+ppGkoRIKBoyu_a>M(@$N z;;nCaGe7pdKS)iosQ9(t{hzTP|8*{1zJ)Olc4ZhsNQrT+lHiOlF#N2dE#e6!$+9r9O zNun;x6|1WojE3uMUB65LC?is`+87oG12#^dXMgJ^?fx#UZIUgevE6lX$XGRGx}b71 zVvMvtkOz+x5nU84Ev+%HD{={;mvQFN$C*zL&?2z9yv|F1`ej6Ppt4l>71C-h_=uB= zet(JUS6@zbmm<&vn4;(OH_D1{skNRM-CJWalT1At9AWtz3s03@HSybDbAA z5^%)eDY6_TG`ZFw1dVF}gQW8hBgteE*0IC76-Ln5Ic=~w>+zvYtG^g%eS4@JK`CS! z38h9Q5dlxA=j?6YWVCV$Ya5y-fD7GLByC)zmbi`pa445T@X3l09hp)fL5U>3gXkydbmH}qa^>v8MB$rRDa zKK8pNsz=RFvYW^rYqYv&LMra{*4}4=`$jg5<5E8!aZW>5FWTXbx*%;;SCmTn}4Hy@`Bb$nLF6DcCvP!_I5sd`v%s?9`CG)^q!J z{vF~c{x+x_ALf8ya($Qi=5?I!A)=yc6kmSkDvgWed5)MiY@BK7dzO5#MBamqGbQzG&ebbZY^#{ofx)okt>F{d4gdfk07*naRBwHR7hc)o zr$72({=u(&im98kye=rDqMZlaOwnI~B2xqzv31LIPcR)rJ&qVvAlYYmQBf8d&Q?_O zmUi0W8cS4?wsyECt=D37sYhMAZm*(mKT?GnpH&pYjM;w6bQ^rXo4nY7at0|p zv%Qvu0VG0>h%0Sd?-`eTCrQJuZk3^pYa+(t6l!F1& z*&dlxJpGmpKKc_sLZ*9+hWiW_-%OAa9U==Wmi1AO+qd@EnNGR%!V8E{;bzSPk5q&Z z@ZRHs#W{O)V^l(?kPfK|HncAFgFBZd?a=wCAkQ+4Hc6yNnI?!5luT=M(Iu}%h_t@j z05o-CNdi)7a#J!~U1M$a6x%m192+B4d2@bqZ6W^PE$wr+N0-FYwSqkFvFWooH=p1UjT9 zD2a%Hh@;mVU~L0!i}h`Hn)dzn7LP1;9O#X1#H#E4XiK$@uP!)6(g$OgeWf=`EsJVGWFy2$V$ z;F|PV9AYH+kebC@n&SEpFoi~GliK1!?AnpKJXbFPr$?l5p|b% zQpeWe@~&y(y#b?p!$-%`=|_q6<4JyTjA?pOFo?TQol)F7B^2U~LMq~$29m^y)O+m0 zqw!mE3gU_HE#CPaBOu%fzwB|Uz@6t*zM<&7XNnr*w>(&!Bmx}zO;0|Fhv8zyD*eF< zh(0meBuL{h`O!7R*bsff&&`{HX_He77U+*Q2%^XC_DyVMSsEH{O)W3I{49^38}OBH zG}L$&GD-I3Kc@b^kHXR_m~<^gt;kQG#ogFX-&S5?T{U^F5qe ze~8%2>B$W;H$muvCJ6En3FRU>RyeVUFoGiQA!W*~95q(OWA5d6U!(7d@wK=EcX)7< zQcW`a3klkQ(h;L0TBSf*ge&0JN2RWWOlbPqCGs`^r z)>D+_0`tj?>o@l~bN0<_@4Q4~Yo2@VfTx~34I1W^pez+nz2#BPY^?Lr^Dm%`=jP5X zx8{48UZB4$$pwT4>?|NglAr|6Dyn_S?m@B>Xap<$z=CuHS2LMd>ZT!DPpmr|gGg^S zU1W@Bf)FKAX{69Z8ENa7y6uCcY2lVVU@{-$n>;1fokz*Y%6dW8_gD|hqYJ$MgFnN= zk9)0-G3yA7HWRSIIGsm31N zQ~2706||LrS~HnjM(ZUX`H}BtartS!vG*j^qC6xqko-W`;C8yt9Gc{ihuLFpFxEdWxmAQ-~Y3`=lgyTX(XpsVDDg)U-&yeORz7p zx3f#HFq98?eV;r_k+yYIjmJ5cnwPY}h_2yADtzOx))A~bqC0eT28);jM7Lp(#%d%9PDk7OMNEwep2yKvL{RNuIE`<;*jz$!V%k1v%vb=bT(O{A5 zUw@fEK(qm?Bw83UnL&)0Ow%8X*xI^E+s@PbjD!c1N~QrE9tboYyj@C7lqrR8j7H+{ zLeg}7^NKWG)+q9_0Pm?oOKm-sZHUpMwMCg;639rrkSG))CXc7@tR+%NGHufOJqn}; zyv26*5~)(#n2gDC5<;@_#BL&GUAkc^p%Gc44JetySkVWZaOrzIT(Nc2UlAilX9y?o zDj=KmcQ|L+y}ixK+S#KJS88Vxco9&(!;l4^!mlcV@a*nva_ZE178jS<7-Z>Gg3Q8$g@HhmDaW@I(4sjWSXousVs`_CLn@ z9&y(ou?xyXncCwz2A&Xy%lW`@=>E~q4>3@8hoVk8_>Mw2soVZIPxE9d`rc93N%?g= z_;mOUh&K>=_x$?q$BlOaO!sfMI{tHw=wgK@*THv*?s#&NDMY+$LVEWK`Hn5&PCL}M zaH^)2%AMaAyPTT1+tQHOGD?*^diH60{Q=hQ(*#9UWFTv#oD*Z+C2B1~8{)!g`l}PF z$(+h+OmB_Z{B<@KmN4-EY|Rr-eh2$oxA+?${Sp4z|M5w#-`JtZO6Dfg5IUi+5JA!y zjVQ`=7}biH%M{Y>=PWJvSan}zZ-1YSryfF?g0h)&``UFDmd}wbEYLPBK~)41QBmNX z#n-ov3Gw64S^PF8%$y`l#KUXg|62-Q|NnjSPEDFs3c&}khILIR>gI^_zb4+$N~ zhlBtr69p|oa4pVO=&~fw19mpU=p0=Z2oY(Tnzf}RR#r#IufEPR&%MIwhc?*R+ecVI ztUR`LeC6ULE{}=!*kD%5v?K5 zGT#2kLwx){JWD1VOGCxHiY)aqDs8(Jf}kh`)4jkXr6hOcgphM^G4*Lj84{&U#EHSYFS` zdJv;#w79{K{?-4H^G|#y8ykIMlq|0Q7c8#*1+H&C&u4$<7a-gw@3r{Gu|Ku!ZF)9} z5#>lDMuGZZo8Sb>X6UH!uBJa25Y3FX7R+`6g;#v$kDue*ttEcqN57xZnfJ0hT;VgH z_&7T|Q=*oXrD0TN?CtI198^`qaAiQhEGc533Jo5M*03;4YpR3&ivR6bf0>{9$-l+J zk37wvzVbZ3_^nvypJ)k2;&2rG9_Jr>J0JPT&-0e2AE)f+Z2n@OcR&4J4z|C}yxQYnHbPdWe8*E~5W3>`e(Sdw-+GxWt0)SMlqsn7pr@pwYaVKv2Io>RrpR+ponIEPBGMdU zprS_rg*Hg76Z$>N859LtrT1;qwrL$2Q;NIHQk5toCQD7z(6n9cs@9Aa7g=3C#m@FE zs@a?}*8~ZUNZ#u+TwcXDHS_TdQ)q%vG~QB$gr|x=fKJzg$?_CjA=SAipJ7VF43}4l z4tBO~AOb9`EVFX@JkNgZORTM*XLIukuC9-6WC`me$chXZBD%;BLNngKO=!{t6sZtC zt;Q3gR#P`EHYA%-CX+`qN|kH?Q6}CpE=}T(g-5*iWJ;5h>Rv1B(tjrsY>N<*);Bb+ zPEbiEyB#Mk#~Tj<&T# zO9GI`G-W<)^g$$i9#J4%V!{4L`*B#w*#+r!CC8>$@taA_BSkGc62f5+=$rUQBloGck9UFZ?+;QxYD&6iY8ts;>gkTiy#HGG zE_l*W?em!OXIBY6-1})O*)>{pC-v zys-hkP1ekA&L5A3^zQef9KME!h%g~eno47gL=pddMQO1BMXAyUzVoPDCSfX4QrpIW z3mT8U^KFULtV2vUu|uqdi5`;&Mk^agxdTOuoz)!F`;3Yu`sILX;;_;)>=|CWw8LB9 z{sf=ftH}m^WS;Ss$IkP@io>#5geC zP7wFrC}-{T!wB&zmsEEW(F8orwqWy;r(DzY2ZE*z9doW*u@X}? zd30$ylF`_!pjj9|2+Fu6sEoZfK6cYoi1%fnB+kLC3qy%Ma8^cDw{lMATLt1PY# zC|XY@6)H-sfUWvPZoWQY_0*7+m4dL`XWn?WE{|Cl3=@wtD9X_y^MgIgfuY)RMCYk( z_Z2C8<7kdoS7||=BrGl!)K#6PArJ6Jk!2vEc5U+I z#Z(u0*q)I@+`*~!@Qbzd`p41mR73Nfi57lmf38c zrkExro=3~47%i=H`{q?#TSIWTpim)VOvYfigq=_Eb&Xar2_I|m&SRSf+Z+nuh|~(L zbeHn?WLn}QI4?je%E1B$`&-nLIm5w_(c(Jwe4kTiAHv7T?$#zT1TvFhNi0kgTMRl8 zE&4;Iv)jq?pb}Xj1#d$4ahU2}i>PiRA>D1^odfz~pm#bcUWw%*}= zdc-`-P%^!@BNiV8O`S*s2^JbKDj~>}j7X_)9reNbHu?T!#6*EKid-2as-sn;kdem{ zqQ|>b^D1@Mbsj+@aXuaeTv9t%vS$bcw)Gelal#>N@)#?fqf8_#W7_hFKpPwj!v&^x zulutR9pw?YUXl=bQc9e4$dDSqCgXj|g&}_8aczTd9Kpv#BM5DWD^C-uTq&f8ombU$ zZEPlqEt@9Egn-Zj8*G9m36a8~p_3K?v`nv`@DKKYC=N}?Clc$j3-F}Z<1kc~TAkF1 zb|&uef!_J&5I}zT?|4^zXB2l$6@@sNem-Kb`eYQK0+_vnUcl( zB)0E7p89rF?ww#%r+35~RF>W=+Qoeym%B`ncdSfDqtWiyMaUk_Ki*Kq@{PJrN8tR^v#=$7M3v!i@f>= zpQf#AG9~E^3PRjwTRn^v2H!Sag{MRmhTMaf9*v;Y5R|}s$@Z03c=LPTgU$<7{WA6V zbsm57I3$B|){F>bbT(w#U=#JdhQ@x;{hjz#JYQ2+P= zKz8rvKW9;T?x7LRRZORzMo4s)x}QY|XrU1@Ly*>4p$ixYo&GA@RrrbSTIiKSvQl&Q z^!IRW`;%mYIVcb90AW^9dO)t`O!jV&<WnQz69zg2W3&HVDbfgl1`UmUqANY0eIF`YPk<^(kL{@fE6=QqSoImM-w! ziQ!stzh|dj_Rd1iuVGYNgjLRud;OdUEJK6 z5`>~^3|dO6#Ux*q zFhi;q(MBdW53oxTv*;<;lgMdnK`W;`fALGGYcJsXPq01zW3uIjQEeERf~{Fa6Jc}r zfFjF@4l3*DDZ$dvP=~ZZ4j7y{9y$x@c(cv_ z@XjKHM5)BUO-XT?R$j_b^aku)y-ud`t_m|GELM!2*Vdw)$4EntOIse7rUk8aczkMR z5)oqrO6N$S&_dxw!nw7r>sIzDWF$MhS|A~tY-_PG5QFU6CcA@zNi64R(>l!^t{^*) zr4~8?zB}WhNW;ct2k^<;8&wiKMr(wSI3Z9`4Y1QWiHU@(1FjUSa&#+7f0E9q^ z6l78)fm_eU^cRLl&s!TDLdMjVmQH~LA5ua%rqEmrk?0-sg9G{t%Z$f6xVAzXm8=Lh z@mfPyHLJBo#5D1hUAvPOI!P9pTA`#Ac;^$TKn6nan5^TtDw!-Jq01{6{a{6D2VajT zFi72D=blPTaes|>)ZQfTZOXaRF?uZYbZnA$=)=5EtJ3jy9dRTOZ$BD`&b zOFNeDcw_}L81niHf67ZQzCce0R3>oK1H!NUBJpqhL)_>rQFn-?C{QZkT93q0&niSV zKpKH`sX|!y7HOK6ICI>*_5#`bI&15vfgKjZh`wCp%2&TkZ?weeja4qW8+4KCH$HU4 za2F=ZcLxh~LhB#Co*~9>Ru=nbBTCoS*0`~GnJkw_n3&|9@L(j`B+rm@X|*GyI0E)6 z1krkehu+BW_NP8VQ`KC(^gLE?Bl`_8SCsv;TsZ$x?Cw=&H^0IDP-VKzj~Y1h4n5NJ`VwJ$ zO2&zZR$WLNPly^XB8`oVs~J*6=2OR@ms9j5MPJZ_!1kWx;?)V>34}B#ZCDtV1P4{^ zaGsPP_5tStw)M!6d}MVS*}i58!n3@hSzR~jqK^^f1JclaebCM%o3G6XjX*1pG7_yN zxC~dNNf4q7m`KO4zmFFUy~T#x+q-O>?UN}O^mF=p%F1Ys&wl2QxpMI`F*sb^((9>& z>d}d>)A|S7=#=Mq!gm2eE2J?;UE4}!7@bo!a~uhFe|U4#LXn${VXqG%v2TR}=hDqx zYK5>#?0b^<$hE<@7AX^wCm)Q+%RZC+J#_GCogFij&QMwUy7qT&popl<;C%8o`slGu zd!mgeh7L!iQ?lB*R8k;>L@R?Xaz>*Ss%l16S5TIy!H|RLHiP~mRWruf*@?7nAysD+ zQh>lK!R`HBVo+o{Nzy~6pbyaaPP7S+QW{N$G6~Awx3OxyhjwIBQF`Yj);(Vm` zEv>bvkkD2LkCG_`Z-vL!b>a*=pQa~>lzPuJg3co<1S-qWF(6}Nm&O>0Qh*UCr6DAq zX*@i?MnwpYC?wiwl$1yrDUIpU`T~^du7gxX8>~weo}?R?^B#Z5rln3)s;XF8 zUS+2C@zy1wf7FAWJn*qoVtGe#(1&FOAuyfnpo$!6)9db|$Ay3=qLk{`smHmM66YdL zb;4U_2+<}uS%|pMA;hGhX)L+PI^mVBaVf+D-&(|Y9F%`tAI7@^MDgfr72FY__ded8 z_4Dx+{>cU-$^F=zF}^`y>1Z$*k9khx31rfVIpy)diul$#G``_9HGb3J`_W|W9$e_X z2&t}~<*w(HZ!=kc_~`zGS2ErMhd;K;zo!)|(KiaSj@CmEk`SxJfb|ZI#WgdsvP{Ud zpb*j^%OP>LN1m6=ydg8U`Q9J=FfTmw`((PIzxXDuUcSnB=PDoi{`YZd*Kuw0Ixcfu z@V6PqeVo`p1J>4{vc!Kk8E4i{aocS&2eiphKJuog-iFB~cDl*U*PmxxYaTuKW(K_r zl*@spJ|G0c>hL=-rJ*v{ag!95Jn9&|8#Q)BKR9L-5qFAdPP``ZE+WI9rzjmRETOip z;o26Xj{+h1XtmM#z%orDJUR)su2w?d4f!)x$yW8@z8ht7_q5&_Vat71F-~T zpW(uH67?D~7c8s>c5Yq9dr2)|;mmo0N+)%+#K(j{Q6loyuiPN>8dS@q-e>Do!KhH= zI-{BI^8B+6%j-33r%M+5Bit#)<=Z>#%^icuE&i+j`sZ0)QLObPANchQTGcyXyqE;O_1g++7Cu;PTG%lmC0`-m3fIt^46tb=6Fr z>FMb`y?d|K`|Pv!=E^4&mN`B}xxjhEyrIW%&1-YC2FAjt#jBdb6y z>9lORIerq44Al}?az9C8@J2KWdF_35L~~Fg5?$frNR7&KU&w~k+}YL1H7_55HeAa3 zjn2M~p}}Stolodolxua(t7wD0FKhuy5QF=xHJOFS-rd*3sQXv+7h*_uQ`febRHXm7 z9!rYh15!ri8{Yo#8_tGrytK%LIEv3X*x~OsUcn!ktU!C5xLm$A9T@K*DHZeMOrKr4 zsa{FDjaTmLTX>uL@$Z#ppTXE|`4v2)qf96EN`Iub>$mrPb_dG&=RNY7)#!pTe^=n2 zY}oxM`x$}9z~crGJ?biO=0FOj4Pa!q%pt$ZIrqWue5kLSVuJ-`&u2FKJ?J|e*K_13 z@ecLgX(e0yW@f$k<00$r5>cKNzC>-(ZfY!A-E!1)KcXr8%Jzz>{QS}xQ)X4sc?B>0 zO7xb_gkL$$tyok1H3lPlS%(sd1!leB>(e(5?xZp`Uq?Zg((}y|=WdE~*oi{&ku8Ma zSjI3R2309hE_q6h@VW}MFx*er;Z4_spWR>vc5kHR;TRT|mh+2Hg^_Z(4}O!g$)~sE zR220Q#OhN0mO=`l4mw>fga-$P&W2M`SAH)=>7i)j@i#eTDf~b(Rl`m{fl202oC!=MNULt`3_`QKN;YHYwzG{uO`g|{9Cqy4 zDUgO6`W`*P9hE`Xz3fd}gmgRWLHpf*3gP$%QA{LO!Hl2KJ&u>`>wYhTbME`5)cMEH zZdNPt@KJw|Y`LdsZtytb;{r>lJ{na5P}B#blX5fqMsW0D{eYxd5E+UoK*{+pwPS6) zxvv)LYT&>OtZrATiCtwE;U(DoWJ|d+jZ#xwlADg}wn73Q-8?1=Y%K+u@QN!f3P%oV zeLckQ(5BvC6Vr4?>$t)t*{&kZHjrfvn*h2!j=ut9=J1aUJbYq`7L6;6u2BJhb}MvM ziu|*}M0AZL(q0}C+jNE52>4tx%8?8R>QqgzEdzCRbyQ)Pr+bp}kYbB& zkop`{5o{h{Zj-2j1o2%atvwG`l3+?gik(>C8Bd9MHz?5XF%%=v(KM6cN*om>%rL~n zk8x`mF?tD%bvft$5DqSngd*c>O|`#|5%lq!Gv1uPeJ>|ksf{5ig`%GPdZ71{#Q(pw z0H$MaSCgD~@}Z@aj}+BWZZH`L*vntB%f57ct#Z3yoYa4${(JZyLgr0pF(LHfTARHC z!6USet$JEdlu)#xZDQ7zW4(Qh_?s_sLlX1V zOY*R%N?K=s76dPmh>|LN6a1bAKH&xF6OEKyjeZ{PCax_}Rrl0@BWds5 z@k$19p=t2+rO1LA*ojC^PLfYQBrl$9G7T(TNt^2H2bTts20YV!FI;_tjUM-m_P}pP zgFk*B&!^xWQ=8DH4GGB!^}s9Y!B-euuP%Bed61?pM3W2lI`z2~I?nL_AW#;ZC}1!| zCfLZiHR-{^r0Omj4jLv_7F>hOLfuJk>zK_@v~MD#6h4B92Hn67+uGulGH;n^m^WU*t6lftX3Fp`XSHhIzx*ynuM1;qxWacOZ$Xp3m!oaa zZk{H_3{@T~Rh>FCWL5Ee$0bZL6>xGyD*WEf69}Dm=haSI-n;Gb9h^ zmCo^ro6o5zvHGn|k~%oEqBX7j@FfmYc@m{_;-0a7?Y7b@F8H1rUym`wK$;C}F27ob zY;ozs2+A+Ss+;+@=J)uOMTEYY=(VK`#a2HY30JemuW1xEhH#`C>QvQLbq(||;3dN{ z5%D(Pn~cueO7bK#gL!u?Jf9bzCLEuVl&_&DCd=C4l*ZnuaUEW2r%G9HTcDCC)N5nN z1r~5NuR4W2Tef70^N0MU}9JdskJaHYX*Wz#$2+Eq6*Qt6x13PsjPZXZ8lhh!YB z6-EAC?K~hS3+^B{e?#vbj^~r!HxfoE=d>cc5`}LDQT2)`n+l4;AAhX-Q+g{-6qeM; zga}F2Ajv@W`o0|ztGd+ zY$?_(-O+fAr7DXqMpBaqXQt97EXQGZ%EO=xq6s=7_|2*4m3gcpFXsZ;(a6R$1GME& z!-%82&r{T<-$GO?jFP%Rq-F(Z1pcO6Qv#UNk^{lzB)_$R*{P4YO4aCWHLgsVF!~HvN*wL%E6C$z5;Dq0C!`HiMm#-;!qAfa1DwAcy-9S-? zww9z#ZyCQd>}kSnSw=DQ)YkdPKB3jLj5+-AT2JumKF?;|E3J0#=P42XQkzfO`ZlAj z^Y?cDO9`M$!QjIsm;S?xZ_h&KvB=<|CREXhD*!weI`=s*E~mvkVXL3z`t}$i@R(wc`B1 z4eieTPR-Z^^2T3TrUpa|-E<`o^*1BKFBn!1MQ(kwPvHznwfHImX|`zmle2ZA3)a&n z$(s?cDZunSEfOAsWWO<2wtxR9mkU(3VVQaPnH6x{Iq;3(Bj&)&$J#ZW?P&98lj4#L z7$Tem-I==V2GlTxO=D8xvICrFB-vCXO!gqiYEV4gdP`qVxS76DpB7P_?NQUhNUaAW zq}*Q5qOR$S7S662dIHl(f$+6Xe}78HP|MWwh4QlyDO7@~S+x%I-QG8bsnRFSBKrj- zd^b1AnKt`z$oHDisO8mu>LJi42UA|$rLl;Qf+0NK90vcf>~{)0_-&a*%AWA*rgdX< z`VjYuc;K)238_u&G1rOri|f>K6;~O92fS^$V^CM{Pwe4Z^Y3Yo_2o1(3_7c05Q#6ldJ zeJWR!>SRxp%7dJnXc%sjoVN|g8!eft+Fb0M-;aLf+I_Is-$4f7bL*{`qS>8SJDQh^ z&&!0OmV-87b?ibZ9tdEm!RxTk6d)yAYeERSSk5)d0uPtppr`aq1Bo`D;*ADQ@gJTI zIO!@sg})y;{qCt`o%5HaA||f5Pc=Ri@LWH@X^$to!wa8xXFsc|PZAuRuFq?P7~1yr$ZcTPd6_zUt&jJE)+jNSSR^%xr~k6`@8oG4uDIc=!srcMR~AT zrnH?qy}@=m%CM*=nqCs?Of%@HaBvDC_b!lNsFr!HSaV^K5~kSs>+g)Z=>>OfQVflS zFNvfxx*39FS;bmuxfWA37|5BMtFS1P7A})-GeybMDM<-XUlSFhRc48sZ!8g-@Id=`ttN*^p-Pp1(DeI| za3MdSSmW_v9s9RrV4z8YL?q5)s+E<&g)H%4=uHVZwN(`8HTFsgF}fw1kAz((_{NX? zG_G+93lPeoFD@$}LnP8eJ!OkR@sm z|CqDSc_zgb>;979*Gp7$Gzoo&!1u77th>9V@{KHD%%CTvKkGie$zsv{%DR(Eq2ECE zwiRwz)k$uhMq^uuI|n;72mAQOJ}W!?PF#xQt!0}ddZw|t4+8gaGa)W3O0Eqnz2>i2hY2=iahMeR4(ekP;sf)H?z?5bKl+K z(FY|Id#bQqS^^*pL>3h8-@GZn2J3lVSW3ALF-06Ak&Fqdro9dVt{30lf z86?n+oWQIeXbwF6II&e;5FS2Fz_~;3iJPl}lKdq2d>?CE@`)w!#uLvTVsmOh+44oT ztH)&6wH-n{YMss889n@pF)prf%(KdD3OSOGtn>{>e=Y#;Ts9hZ0Y=L*TH79{c{(oA ze8=V%ItIKx=UEC)xhM>bnXbLJJ-t*6#)%VLKqM;J2gV9%c_{xe(r9|b)3Tb#oMC1O zp!>xg2yi+cvG_EJmO2T`xeI6c?Uy5KHS-iFrYa2FG%z{MztClf-eF?9l~*E?;_@@P zNV%!R-6q0@ck)6uG<8m+h#rQOepx5_ZXU^QExiWF#JToqC*Tk;h&`huFN>J1FZ~Fh zBkM@>+WP2Hc)t5Aj{TZ&XJ7)_6NDDgB`Et|at)C$2^2dj%7-SOW(8uD((>eG=W@%+ za4W)bZd{#Mt8pzKK?7f)M{4PtjwM(PSAz@$_| zP&raM`brPa;oUA(^fQqz_K>(722Dj$mM0CXorW=hG`gw1QBh=cvE4CCfvJXB-g;yc zgPJi^73okMV(Lnt6HoI~hDC5$MA4PMkwEfTxt&A_X}@Gk!j)z27wY_hLLAZ2_kLQ0_{0tM zfp$GuAGz1#h=hCkcKDEc%}RzoD&Z(i z?>_Ay8u(KJOTf{C{`IUMxBo4r-4(szxaIswxU>FNI3~i=F9P8`RwR8m))yH(6WNOV zchzbFcDeC6MDtv~2W3rLJ|Pg$p4NSzy^kAG%%g1}L>TM))cAept5X&q0~e14Gc1U4 zg;NuoljImv1q=Q{@$&t)<9WY#=HR;Z%j2N#Qznp&)sXsq-0V3Q5TOZ@U3({dd;+?4 z_4SQODiBqV!@TzSzMCAKyo94O7?&7FK38x2pqj1x)fAEq7N^JdJG~tJ+Xj;_RUf$w zvxi&ntSCJ@=VTyFaSvMIDaXpJ@lh{{qt}`+;?kI`{cTomH_x;E71R!2Cgt*bAwJoz zM_V3;vG4YSS8SUG7Y6bLPq(c^fjH0a%MNjioew7Vet*tqh*+UhJX+2Tl0`PPmQPVA z+DeyEl_I^0ts8^2lO#EcF`_3b+TINlXW#8!ndKqLI;jHVAhu4KhjEepVA~mH=FI(p z3U;qOBIgyF4BoLzJ+R0y*k@8pDcdU;ef8O}Wkx7>HFV<^^XL{uT(jdII`e+C2Y>7J z<_n{~L}7cRt1tY!`+D*9G2dR0besf?b6Zb9#r zlI-6?8qm!jiz~N4Yo&<$;a&^_X(YMI`w5R2etUV$?lAZFMc=}N(^~R)V#j8d=V!k} zsJ^As{s|>pTa%1u=_Cs;2r**h!?}a5>exgTr)zMQK*Lq{xjV0s;46-Wp<%A!N1PyW zajRS-bgF7JIIt5Iugzs52|1FcP(D3?yrf=HbFR5u_Obnh&!yAo{=&9a@bz!kl3|cD z$r>tAT2@E4Vg^#6q_bIef?hC6z>cR#T>{ZYbrz$bGG>y=MM#_5BOKjiM+`86r@h%8 zxK^0eWEX+WHg-8a*x3W|J=gv;(Js^J8eS^$#XzQFx{CTY9JFpXmx!1WBy6%>Vw1W&6x@)v^R3#6Ii#zsNa?zV*Ee8&8-}Q`$blzQ_e|Zg zl-9*8?)X7XS=F&;>;`8PS?EYE2MtcM^jC=$RU?29t#r0fd^$e5k~zz4LAvpJdN|=g zZS(Q8HdFVI>#J7BWs;=TsoK3i2F!$KCie0vmZPGfW<*A#J*1Gx)$!%;x!DZp+}M0e zXXMq=(5t}Q@zU&dbE=Y~(IL9OfK)yL_NY5nX$5GPV`AwT6x1wf?qZj-XI0qXe2Dru zD;h7OGWn~eAxKI7h4j=VBiHivOpU(rqQoF!vY(VAU+QnPKB9U)Ofp7%MDw->PPI%o zn<_vu!uU7Ch`&=|#C4V1KC`B8m{qJDb=OwEx@rNElQvep(rKTR5L%ESf!Z8Jv!O6P z$3r5Xii9$XUEMa(?&~o%q*mRTUeCZ#=z;Pycl_pLf0njX`|;%hgH3tT%Z_`#@1o^tR969nEOc2G(V`If!8F_M;Wfe2jx-}Db?UFlwjajb=K%52xQd?Q+>+`o8 z3%BKDV2D!iJssk8`v-6gBKf5oC*&z25>9UE1O7k+{G$y9RhvWO!~N+<#)}W#=#V5d zv>Sz{pSM*PCa0FS51-?jI{E>IelpqxFu#wyOIsLu)y=Xpr-ySHvVIU1SZgPzBYGc8 zEItWZI4f?=EDzjzRG<8e_$y~{?XwVm{&A|btb75PuQ*cdZ^9EEQk%^$uJ(^C05^0^ zLpuXTQOg}&BGpGrV>l2_fEm(xS3q9O0B{TkS4C~Y&KPoXTerQ_+%+~Z1YNRj?DI;j zuCA_8j@E8Ce#Jgr7N|?2*I=KsP>I-!3rNbFTkHEHxx9u3nP8c&ge6<{MDBbLFfw_f z-CMF38EDP+3>JCv=H=+E^*W3gM4Y2M_t}tMygGwvNyt^DC01qqa}=RzfSri!ysVpa z=b6-d7bAEJcUsehE7nfz*g=k>CTahha#Y^0fJWM$!^sYf8xXD~s#8ZVZ)|1S9juko zjBkZ!^tZ~Ja8PMvp4r$cjb!G0^CoR4Pz#*o!xrYoFHM5)2m><6ySXf{>u6+4v|W%k zbUQ*>i)I(;?3$L7En~4+)4e!qOmS4W?BkuNa(79totCc8-4i%z2GOxJj+xMZEEk?^ zZ|YK4_6k4^x}w|g$lfV3%5{iP03`+`g%|KkGD#Qfk8Dw~*H6{H3}}?BRH~D8{K7RW zi@J+*(X$NcnrC6L>u?t+GBO}<_~u?PX>+>RQ1Yz+hVDJYTGuS3WZMHUfoX1JJTpLn z+)lA}sFUq!9F1>eXi~`4AGJamF=}LSmQ#lCgN^F5Q-DKb>|do|(rjj=3#*eOHq_l5DIHfe~Oj1$3!K3%?t5e7iNhLb8N za~7<0lbRVDy9~NlOHFqXbafi)5w!7zNbP4E?5|EE)#nqzi-{i2NPdK1o?l9KEH)x@ zOSu^M3iZJY4c9ek)-1K36iuA4Zt~tt3mO#a~SKh6hqHkjnL5ov+BD*@2DE zKmT+V)c=c6t)H;c_E(`^p+j>5URDDo1t+mq33*`!L%Xu#wQSVvQ-B#U)fi(aLL zrF&RGtp&wwq9oQd$e^g zcsg9wPo`5&9#|LzZNk0%<6#7YiemPD3Wg>UiRXym0_!71VS~a1$5;>B><*&(*lD3| zheR%h_XNlI@ob~l5%XrI%AnP3i+rv;g%?Eu{;c1!WWJL7OQ}l#PjoSZBCmz7@ESQ7 zB80qNz*h!}`K3yE)7|z#eu9DU2A7K|vp4Q>dx*MU+P-EkoOA&PZg5a2u;fdjW?e-! zA;=VyOIMZNH5>C&rSS$|Dt5KA!3u)9XjX;QFg3P6P`_Ll@8ek;_b@VFEP(VlE+Rd` zcA-whV2;m6GwB&ndg+zN%e%gSTwa)e9DGg(1~k7pF8f!MwveIs67srg2LFsUSP5hO zSelTQZ_3gBn#$jYYm@1NuB!kmC$d3dNkSivHpMXXEi<2qG@L=KEF$5HwH2P${)H~5 z?~!IE^Ol9(=0lN@iPB7@?hPs|9P?Za$V_Kewdr)My8 z%_#)Il5Hr6IZ{AU%}Ad6cp21bi-HC5RVnk&E(8O@$|AsU+l*F)NgMK;iGtv(8C!sD z$OmI~XJ&0=!KWMKw(De)Ot*cr(sz_3g+;A_R@pmjg5A%}>c9L-EOWT#3P=Hu@~|HA z;*6SrHMG-cacWM2Sq;!pMhV&n5SX#zk0rbpb1WyjGi-PX-l@_zOHsEyO=ETxoa!$K zaX`*Zh3YPiC&0+ zvYX6RRi{@9I!t5uFe*npp#LtOFi-%2Fy0goc&A8>Oh&C*SN~AIiZzqVZI72)Ka4O5S*lzzpD|R z+n3Xqx-6whsE%9>D7UVhP)~+G)rv@#XOas7l$#o%Glsh$55HgKjCdd{h~&@&CnVFd zw9%oJ?J`@*>HK&w*r~#V^ZmlZDEd`wjquWCuUHS zQ!d7gTB4X>8Bd3y2lWAd1&Q}_pzx3|0Kf0*;%^)mbLu#^-B`ECIvoW5N*JJ-4O>-` zRSmCZCzxZctQDII%-~i1Ju67Tf;e>(lZoSQZLRK{R9|3iQ+W-)*{>xvLa0I8R~Wq# z9Hp=r_Tkt%=_Fr5zZE=JUOGSt`pZ}fk)7c|MmZova26Y=pa zlrvvWM_dcOT{S)|`wDiCj35a#cw|4%fBGO^z$KLM$li$T!8D2kt*#u6C&`eT$j-{s zb8E2A%Kk3X6@tJ89HZ$2K)3VmGVf-*9em6-h#ZI#Z+^DRq*d)g8x9U1qA3|@rJ{-+ z$j2NC>Pv|>Ca7s^>-%OVBS1gRPz;FEE|Uy*i6}_nEd+Br)0JR!2r_WW>e`jCb#_%gO*v%F0|ig@~2KB6S9b(c-`+@R%47=~&8^U{Nc zS!VB-@l|E_(1!?m#vnv>B01f1#O*71e5Lkj(*e+hkBofaVTqm9?+qMT_=4Jk(FPV0 zpIwC8%N+ERtyzbljkkb7x9x+J#Trm>?#iBgjL^i`EH}x9c}b^2kpU;KYcwjCI`dz= zkD%|RdNpl=5^x^g4u*WqHDawYFhAVsp?N%zpe7sVTyq0z>!=G;{pE0lUV-0qfnf%r z37UK1ku7dcvg4wH!5Jzc$cu{Ee-d7d0xrBq-2;3~;MBBKkX>!I^^2ZfkH%~(jzBdf zTq(HPL}ibXX)bX?mQgn>eYx*_oq-=7{JQ4v8`yS3^f+f&Z|bb-|JDL5GU{o}{Zxay zv^6hmbhsU3LP>`F`KpQzQ*dqhT#z5_2PkBPU599CA2}3=o8}|&XlCht1nJryu}kP% zQR@c**lymNZ5`AV73a&@hKW(jjk9a~D5%TK)0XTL2+x(&$?ut<&lW|wd4w%21i*pn z=p8G5C3gL+n@;#pKsXDhDu@=NTvpESgn&e$MX^`7z{4n9eu9I8>W|}pj}wF;C^?mT zA^w4tf73AVKrKUf4u{f3i6EE)gi>-|q#SKZAIO+r+$XnYK`?9|72qY3%Kkk9R=D%XyimisYfZYCt7{!eEbQqP4(O{ZGwDPi9|jGv`V}4(d%V_-r7nk|fX1tr#VGS+i_nCUX4UqKGApRZ`#oK%a0d!bU9)o6=p| zcBDMo;rZ@3uYpB6pCpb5U2HnD6D;-@+db(bVnm`M87|A6p{Sr&}~`0CwQr@;bvP5{4kTvMW=@|S6+8~ zH#2?5-uaG69u^P(LuN+C&IyyHdzUR&?a5+Gm{6lntT)+eFL?Q{c-x!!8!m6BHPg3)+nbQ(vrD9B5+7SqYKP&U+)op<_IGDeCu)hu7Qd9dK>l_Bn(t z%f!5Jw2ZC7;YE?f+|}9b^?^(OEqWXgcBI78IbdgRX7ZvM-8-}-Dx>Ld;W+Wbs)+Fh zg2>3VvUkL$r$m$n6J|M_baxd#{ajwJ^FV8^LbG8-;g9!{yC>6F?FFRefawpx{ju!0 zpXA8vf|;{GZTB`YNjVNK!qEAg9*2I+l%j*I?EOOvYtpBqQNi2A2e4dbF9B)LtvYMgAW1xyjw$~Y7C42VWJ#8a1clWsNP2%&7){w1lGCW_m z3W+L<))+5?EX8m0n7QxhbnmTM1Xo*#^?brZSGEcvA3upESu!uA68M z-R9m#Qf6X9*YWrj&8)@5%vN3n?KwZ<5K6`4c<$1gn8=4;f^1f8NKvYmXj@oh-Ywvv z*{^0FB#Jm&ZEofsm+N4&<_No|kGv*H?iIP=tKKF;I z#9Bac!XMIk%b;33<4mq5U#9Z8^hb%m5=a0^(YS@`c??7~b*8#ylKhK0 zq#qQ09z)-%r47*4mlZX1PyIO?11TZ2=qBS=BS--Rh}D>amT7-#=qWzr<9smw68g7z z%3GJSAqwe+$q$hGVys(54oQJY%w@QnFKV0qI>(Ie!OS`_LxfgSMkxIP%Ml(=r165`t#R#cz8Bds5_K4%XNq8CxiRB#%-_72R5lFz3k8} z@|>Gi4)tGeQLqbwjS2p><<9=|8FW*%`u70A|DSh?Jm>4TcAq+7YqO!UAh3t|Y`gqD z;2XhbeAFFVKmPw36{hxYEC07qsq{Smw(@^0A8^g=3GQMy6cO>5*;(cE#`{^6(r{r9 z_U%LsH};}S^~DLMn|ad{_~z0X6=n?meq^J_+f`oYuu=Pibs}qp$MeGNi@@t#?Z)WF z!;#VM&9?y5L}Pukn;@g$2R8rUIbXM}lyA4DL#S^&I7GI;P<9j}gU(TRc&c1)sW&>V z$*!>*z4in}kyKiSlvl5CJ3Lm{YF%&hQB#feSso|zHUtrYMtnxGVjebU$OmC>n2(by zZl8jornz}K?jra^Wv%tg3)@?`#`(TY`Svv2)}W>v>%-rq`6AA(7J$EwUyh`_>J?8e z{rWVpB9}Pf{lRCeeFr?4tr+vNZ1Lr9lt9bh+uEa*gE-{#>mkp{x0Pj6uOrB`OJ{?* zNauy2o80LM`~04f&kgU=lELnd?=hy!n)`092-%xnOqHp8$lG7ox7Q=$v9PBlHve7l z%NNALNr1#MnG-d}>>#qpjU zObDa8DxN^@d_L^geDyjR+?+vRW7pn5UIkfpKm7^25w?SIdBu6wSYPM{`-?oE5HVFn zHKO|d-LHIq!Rxb&_gOLJ`Do*fz4Nss=J(^nT<4qdKSNPu&1Q4f>p#%Wd_r5JnM%Wt zjBkZ6sZUx`q{-S-4D9cDTtz4wuQ&TlThF|?&jntHh2K5hwpq+cUZ@j)+bCe&ZzS9K zF3yu~dz@n3p2dH_1C zfQedTFF)PagY*YADyC=dry?1%z-SkIIMLy`obb*`q zD2={@$9o=)dd+o=P>fth|79fnKdzidJWck{P2@fp&8qC}85VQ4)^Y?Xv1hxCCNY3M z!q~&9MIXkj-`s2R<+h)EGPtzc@k6j9;wKyA?|yk&a0F=a1D=}S`toPEE}xcle9!X^ zF2(UXinE%)%0g~GmDgLXowuH6vv&j^!-ViV5&!jXiHx)#8#IHx{PR5T+P0t)=%?f| zWF&jBhQs<2;vT0f4y=YhCYJQM*Vl7zJjwi(JJF*BonAL~&F?SmX$LPWTH|3KDx^34 zis&+jVtVZja-!bMhF+shYI zc#8cK*t798e0M4Twl6!8O%#1@If436;CoH&drr3z0<1Z+-k?7dydZC^#O6f6aB)1( zTiWCEdUs2*ZNK3X7|;sdOrW~kVI^&OigFZ*e%|(WIKW;_X7hKw)*)@bGfAlmY4U83 z*qnM=T+=UxPR!&eubR_kI|}zERJyY&b=;nE;!HO60x(iy9_r}Y?7G|-cERxE?&qM2kzQkuQfN`Y|(d- zm$T3-GbZ_+zSu#}Z*qO~3|rYD((4jO)MaCEDo^?1dySEs2HR%5{$n`bR($p*5S?W2 zz`K?1){(4rVZVkXs1@yWucID+Ta%)fSBabGGyX;g@Dc`Sw=sED_8C8_5u>tF`4H-o z&$GTCz^{T{H_3A_myN<%SE9VgV`fu#3uhfyu}#7-;MWaSVk@$>@bygMWm(l{z0A(Z zEV2;v4b*4cdtW=*5(MkCc6h_bwk(nXcft0$y|%&EiM2+jC*M2C*AZVI?04vIuMxzr z1u+Km)*D?+l%=jtDx~`tr5I};&pMxkZ%MUk3>EOxdHE(;n)3%`h2@-r&a&DtHc-I^ zt&`raj)U!YP6$s+-VW%GT>#dx3ZWCBM|NfZAk?V2I+wQn=B9P)jb-4a3Gj^UGUlIX zgK3zd4mgaQ5J44K*tLJXoa_RjM_!9s*vnSz%^cetoA4I^!OeoAkGl64lf5MY5bYaS z!Iy{YjRfO&Z?_M3>iu&w<`9s+C1MS;|cE_;M+vvFo1hl3(S(4kzSSEN1 zb~aTK?5_6qbem)}-M2ei@l2iKF<&6PC2fx}(yt7^#d5d7|7@uRi8s95yIG%fI#@g{ z(S2w;PY-d2igj~FIvXsZZ&$jpQofe{zPc$)ji}UKUWVRP@wqp%-Hub!^uM#;3S+v? zy>UC{1tE~1F$KB#A?v(8YkPGufJ=cc?Jd8%tPQ-QYBHjb1Cf^wCi^XF-d-b5@}Q^A z&yBQ2i3|Hjgd4ceWfq-x(5o^K(-u)=q`!ZdlKe3Ic4d(AH=WnNHF`~$HGA;|!`1uN z(1lk$jtY9eNN;uT^CR&0*a|v4V+`7X>06q{l6n3?0JOKL3j~T%ESZcCU2LXg5D0plZocQ8>X zz{|(;H;|s)Ec<%?A~Zwd7?eqBv)RD*%*XcETubOxoNUQ)UGkz}9mV%D=Jgi$Ba}6; zCYVrNK`R0G_T?ueN5=KvEMA-c8HbW1d$#ED^G#UkS6Z<9V*q3?RcwUfWo(9Q_n)D` zeb>dGp9bb~f!H<2WWD=jd~Aa_GBLKVem9vDik}UGFKGvQ?t(8rT;%Zz2_K0+-b^Pi z7|ed(^6Yhs8WRDWi7ziZYKEty^fm!-KEnlHJ~k63{S7v5`=Ag=IG~4zyg~GD!uCJp ztXHDs|IXkP5()oLb~2sg%xhS0`1jE+v$`_>%bxz{7ygGm{m(D_!$bbf8~=}YGSpOB zoqT<{18$GEY*>T5HcA}XQ8FT+RIZm@A+aZHQV7mIw$8aSh7L@fMZ?THJ(|0JCe5e%hk-q#nq*bWOMt?6a&(H(!n z3id%*|FX0n8!j>VO6pjAS8yx)8z>>%B|-HV?- z<9B92OsHf;`rqF|!3(8V;t+TJFeWo3;1Kz>@8!h)72ILM-*jX@etidg3%fLUdqJ4_ zjAqejW@AFU_3e7~`KcHE%xtnkHe?%nwfT-7okzPzb45V}AtsVc#An;*_FQDB`(=Ei zrk85xg*K;Q|LY{S)5Ce0euT4E;~AhELh3I*NVeG!wy<{l<!J6LR2tae4kDO!MY+-*xXO5TZ`_0AL8;idV?Z~kC&qdae= zwrEg8&N1<1=|arL=oT#Yx%E|Z!uegUIR9n#mGHp%4%XAuj>nIU^vl-OQ)Q=|!G)K$ zD>t5%{hzP5>DOEFD_l0L%li5}($QqgMNjErpz4QzpEQB?27}Ng+#nRYv6nm+L4yV- zp6o%rcCFX%(1kPYmSP0GBE`W?EJ9#}=JsabhBujXjBt0tJM0x%yn!s@p%uW@MF4RV z@OebMc7)zCMFA-ysb(> zXclT!irR5nzdT*(^<*7f8d(vU9B#^d$%G!K+WeW-^{Fz+ye)k)+*I)LtwNYA()uud zS>Nk;vLD;)EGLh+-Tto6!ilVvZO;K3n%taY_vxAj4>o{Ji}T66Nkv3g)G#*@Ww*2H;czxdC8#gP6>3x zzY_*rx)Y1^b$EyHz3Mti+p-b{Up8PASOfpC-ah>UogQSJZr`_aoi`^=NKdw-Tca;8 zx!W>B#^NA9&f?z}FI)>26HV?$1w3gmJmdI@zh+h5} zzkq!Qym-Za5Cdh3KSf{mh1Czb5`p>P?oNf9N>jIox&w$i`fe@t%SM+bD+HP%Km&iB z8hmLWJwbd|?C58$5duC=Q3B>|!v8o%UGoou0oQu^c24AAglH(wK4oC8f9hx__W4H4 zwhVO&VowZV_wx!6SVV5V^Uppsju<@MmY4o8m~$~}SJA=#>~;IMoofli23}oh67E@3 zJ~248J6VQROjUHb{$l{%TQ`6-1}%Zk^N2;9ZHQ@cw_MJ4ZzF7d7uvn9z95yKJ(Z`8 zE>5zZy__653f=GS+4|Nrnc%QyGAB1-NDrEM~+MOvaiGZZ;%5&AHKbo-=RelO9<;B~{yT0Ykm6x#(X_R`f{!6EO`D>>q>+q)B~ZVZoWtH3k_ow}k@R*3MoF z9>h)&87nc42eo%KPgwXr(wuEiDDQ9o^kLvedz$kQMVblHkwJMG)GNQ_IrqH^E3>t$k_fw&PxXovb;XhB_|6gLqe{k;q z4TU;({)MCSdlj9};(QPlO^<-|0)ihAbmYvaRM&rFzcLk*wHHSFwNyB=t|j0FQNc-S zVq&%wNJ|u}$~mHl{VIi-;Lilkf)pbiZ#?FHhHfG$t0EPIG`Kpqij6kXlZ3jW1pE2G z*NcfFpO4mwFf9JDt9CcdaB0o|;qLE29GBFM#02>;i^L)It`Iq~{ z)KLLaq23aLO?c$RQsF(Kk;RN|#mDK>!#`|H%5SvsbUyw5rK#v^mZlYm!8jrohNgR@ zQaP(h9ay(9?M^)#ibx8NnHlK(eDv!^X6#=8 z%7*FCZJ^b=^aW%NFgB%_gd>vb%<(L;gd}_>P(w4QmnU4P+c@8?7&T)( zJ)t)sB|m$yar%-bi5@G-?}Ld$9`FmbZQ~HcM@3R2Y+ROf=Kf^^?Ag~r4MkC?uPyi| z1F5=IJaVEohk8VFR49J&v5}L)bF*Xp8jk_S5p)ZL@P+W@;GMaaENm=ZVEvN4tK3}VMa?4 zP*m`{c**aGJ9h;fsHKd>l;hRpe2x#mX~A0^W*Ew4!AxQ0FW0v;5nAt5Q#QcAD58z> zzJzWPgH%iuAPB5sx>poD#ZnRjq5uf793XhABOkNxkY5+S%+at(4t!Idy+scEJD5fE87 z`PB`EBSMXYA?mqO-2_JrM}ydZP=48!0_{9O8ZYZ7ATS;#=LTN#eFX+m*H%1%BPkuJ zepG1hN4_NL^ij@_8f-uIj1iMQd>}jw`O=AmQuf6F!6Z_4==)xL!}+zR%(hgh8{90_ zQj*4HpVUcTY@emeUkyqXh~B#pAclzqT;}!c6!ynq1LtTNk4Zz~BT7bpb?N-2l%M#a zafohSct&!wG8C*~{3-T;Z#P@_#S+fUW3h3>>at`pqr4yMcPG861#u-YX+HMv6Nh0> z&g>HtWTEItFcxE6Yl*oqn??>BkfQVdXmOA8aweoG-gJ<#d{!LZNwW)_g_y>9mBiQ4 z(Z*0At6g;r^Xf&peg2OVhT>q&?fP3$|HvW{62%nLFbPL0LVgJhP2Bev-U9Hjro{Jl z=7Zzjkpu+|R_OTS6S&=9Kl4f_^msW5 zLJ2wa`DZ}WoIO&4PQvO41F;?}SB>A8z}gBm5D}{eKpvJSGtwBZNfKrLXF!OG@~E~qIWPi0#~|@nIFle@`i(!e6we5jzrdvrqz@!+iOI=!01m=155&T^Q0fNc?@%BM;lpEwq_BG^ zckjhE;|(984DZRWpvYo`QGMWby5Wv!;d6xB{1VTVhLhOKq(RSv*-gW{$b_X%TFyqD z5pNlp(Kw6vWta$`W>i2lJ}gYVSX$Jcq`6Ru?u=F@H`VKR)O`%0mQH~Zkp;*L7F%RStUO0R0cH|JBu3hQ$#qi=x2^4#8c6 zySux)TX1&|?(U1byR&$33GNWwA-D$aCg;5SzW4Um&h$+6bXiwdS5-%`I6G(SR#8so z0e-`_1DpqjEFEzE%~7>I)JQ=QC?aMk5Wy%FrsS2DS|xz-gq;4h5r8Q7G)!tDFRmna zfpSvta(h5!BdzZ?l)3oQ{zJ{!&MmAt@}@@=+V(y#PZ06yLG06jG6sz!qd;UQ&O}O= zlo*@JucUA2!ul#-8IF`I)0H#y)GI`BBF_QrV_avB0|Xcwe0X+Yw%60WLZ0Gc<&4TGE@6t|>|!{>Rxia^JltCwy}iOX!A^CB6R8A_f)C}~ zDia!zCm*yi5o0qdqpli8juIvehZ>dzD!;lPXhZh3q#{VVRvn8hP7Q-p43G|pF7uQY zXA%KWt4Z(dQ`;9?B;~tADAGU}Kz;ViS5s`WRjn+d7jInmt?YIeu84+kqiJU39?}ob zYW!A0FEx&rn(?>;MU|K`hSMKh=jU(elqwoN1fW~RuOv;u^kkn|L%avzqYGvfu-K49x`Sj5zM zM>GZsi902)^+dnN>6&Jfw9{2VMir6M*~&#Y=^NVA^Z~1e^X#0M^0JgrnaeUer#hMO zgjDgTxg*>EvK%TQ$tP#CDpw}GVt+2p^CXM{&JUy z5OP=N2u=0_w^EeOkyr9}0L)bq4AmN}@|VYb}f;XF2jb~xLZh0TT?>NUI)$Wc&g8sTOpF>1n+JI$2mjV~?LR*I~dpZAy4 zUK*`mlh-rfJl;O8-?LijvIa$y*IlcV)dZiRyDhq^Z{Nm_AZ*VL-t< zSNuJ-5%=(nIsD;Rck7&kR@J|`h;EMrPBgm(mhh^^8st7aj`+7w z7)`qwj;@`u$vUc+6$w3-k?M9Zrb$due>2E`n-Zr&zqRD+6~fg-PQM|cC^S$`Ka}Dg zKbu&bRj8l<7K*@jSbqC9Ff_-diF}pXioMn`mAqehtLB>eqF%~mSIOc*Qc9Yk6HyX~ zArvGPRQ^jp$OUtjBC#YenlKN+UQF1uZyrOu#GrDEyYR7`k`pZxg?W`C2F+!Z8>MAf zR(cY`0Yk*yf59%F=6-eqJm1Mu(k=}!f%z0QnCzN~hs{?4h`4(z$1s2;iE%cy85jk| z;Y$7xWT}ixUkF~HFxC(E#-EmmNYdpvaA6yUWsZxgoO>M|SY)5E89Hvyw|nzDlQ^0x zhsbk+7tR<})M(77^y^vM0P_@-c~+8N)ar;sid|)&;<)f6&u$LJh*R9<u~*>dQGPc5rn-RU5C5?+VBw z(oRilKE#Y!i`0wL(x&5MJYr8LW2(DztE!At*Vf6{tElr274(0rvR&nyaI}I(3My2c zJG;-w%{8|04r48wVPb7cJh?<<#p7hrGAO<1?-HuQ2%`n90j5@e5SA(SOt!`OrP33< z3U@yiou;u3^ITt_LeHei0@EkFw#*O;7yUjP>fWqqebejs25jtb!pxcb3X3Tzi$5*d z-IpJhrm92IA%(2uHig)9yZcym>w4g9c8I61CwfQ0glQPJT#OfSKrgUL7^~Lk(Cb5UEqP zIucXi2pbuq6buDH;`hom2HIDur5oDFW)-teSqokm8v}ehO|kDcxwN58((5nR#u;(4 zXUJFChbZK;k4wQtnfF3-30iJXtd4_U5>s6hAGIqdkJnWo)JoOe(5i6Sm8k!sDA}n@ z6BUV92tY=oit(k`|K4c=*hLYRk>|h zvzOQWBUlUUK0=uZWn4?|35-`cW6Wssf9G&r+=*QauJ)=%B};x*tJBoelPfnkv8glr zU=C2$RG;GPxsiOky!rsQG~f~M`kJ}*Q&@DWqvXfFt2(<|z-TFb6DXWs%3($FmHncz zn3p}2I7MeKVutpED4%qp>$ojL5Mefwm- z-MYVAgIbD>Hd1%g1k5Tg##b8a-)u%kdlFFzijobLP2y)x-z;_ARg>0=ec`vp>KKc( z83skD5@+!&Cxsj*%`Z+8fnSf+eEp&9UGNoN=15i4AJrs9&zJ#LfZOl5e9q9 zQLvGampM4VV3E#9na7?6WrZ*MTl(5~^C1E-$i{-qq9? zPC(Nr82UhBB%WVRJLPdXq>X=xoPo@6Q^WIUOXNQr^tHFh#D63 z?i?@An!VC}&r``2;vb(H%5B1*51&}0YjHAZUv&AXG7Ekd;I7GHk?vf?sMzO{d*#PH zpuF^kN5%Jic-?;5gllNTNM6018?fvOA)AOdSr(vr9Zt3@QLC1`UXEMAzHgF@@1H7# z4;P&v^1Dc&fB_->`og%X13XF140NV;BfyF*^bsSeau!JbDyKfX!O9vXTgAyfwT6e9 z7Fx_BSxsgD{~P&8mDQVMpQ%nLLQE6AWYTzhV_gm3X`o{M{Har~p^oj+o;DfY{sybX zt7fEQnzDX)@>WmRXV9NAr#)qWZPLu^w&HWCt{} z(+z}4x+2{#V-yy9E{2i_^lW}Aq0R9)a|4J&dSyiO$!el1>nT-5I@Ijo*uvdJnH?ze zvYO&%S=2g{c8#tnvUoFR4-O#5V63Wlzf~TdZJC~mgdu+VUL40x`UEO_6}0elW>?IS zq0REyJ?vIXogw3-AxPq`sRD+G1YW2&71E#QEi1wxUy2bX(oX2TL77G`;8(Mx)bLR@~34kWXf39OpHA!de3 zY7=(4GnaHBTSp0vKH0b#FL6NxGhAY~GX^(4LoBhI{lYFwxr!7mzB8>-G5n))Zif&K zg=#6j_K*0=ekug}pK5QUPZ)>xOY-t8E^4le&0V-{CP~WZe@d4vtqIttvF)%39B23R z5;b%|2N$3JW>3ACGvkyQHNK#&*4ansZOl&Qii>J6>xQ2@_MAtB z8lE~+#jA@z&pF1XYyZmSR@_9u%z~DKULv!AOCvQAT1h$kl}pcM1ATi@{zdGTe|q0T zdoQH&u&~7mst9=u+`Z@`#&=EGdNIr4-B;DkU-d280M&WcAlaH_^>`Z;pY%z2?GA7M z?dP-Eu+HR8ZA-sL&J(FF1ZjagUPwv~;w3Y!8oZtpYcSxNRM* zbZoEF$PrK`P?@$4*GTCJ5?9^}OsjAI>b#{Aj4p?rDHBe;`Rl!H#_G`92A?@e2oDoK z`=F6|rhh;v3a!os2fY<)I6I@@2OpIJzUdL~R?zZv_Ws@CGL?e)JvS5ldzAvLVa_*{ z-uGwD_wuH$(H6S;fb$56X7oqjB$mF-}P1r&jK-$4owfr0V-X%MES_9#~n<7?8|uxk*m4`G;pvBufzH zr`IRG%vqz%8qZ@42c>g&KdU2~lfmNX!_ekQ*cMkin1R+((8t#w4p+V=pgj%V_Z&%? z<{YW68uJ>nA}iDIm_{24{xH54W)-2N&!@tly0sU4BBY;+rOxaK@_8r%k<4V*(xJt! zeyqF242Pc@CH7emmimI(TPz1>8R=Hk)fd`-9;< z?D??X`m@GgO>9qIan^?>uHmXy>POt+%F@uHIEUZx=st5Gsg}8+B^ZO#hmzts>fUN|2Wr7|=iUi@h39tkT*6UtDr7Oq@c z8*qgxPv+~byx5%#&?Z!Qm5jaeV%ah1KKL+ZbbUoq3k`u=u0=*k_--Qu_bd^iLdDH` zmtOnjX+T3598b#RE3it+T>s0-`P*D2Vl`)u!3^sv;C3oosaqNKof1lZu`9l#>~eWY z#_H)^!Zu?detJk+R`|zo9k}Xs|{?pn`3fy zVfPJp&yzLu!HuStK6^vw1H1bLOTEhovTN2S5esNTUsr^~KeWF?76}IrNc6Tv8w+}! z{1iE8>5dUeK-Mpef9>|g<;wxjIzl{H?PhxXFx~v@7ZLK}(oT6YC^8HUUAeGDj9L;X z+8q=T_0+0H(m+RX`oVG?UhL3(k&xmLAs9qsV%u^%K2#M$RFxTm2~g~zY|bg1#tSw5 zQ;1r>hziVJh#F5mI~@HAVrnOC@omxRc56ZXPL$c_lkObj5HVQwovl{%W5m$Z@}yEM zf3#BV*|Fb2l`|5hsS~P|IJee|VkMQOE1@kjJb_A56U2Uk66!144zxnj(5lj^aH_^y zvnLwU8t8Ls^Gl@FSRp#5(rZ!E_catb6@KWSD%DTm@zu`A-PU}3qSa*CD)q~YksZ-; z>G^YrDXAQ)UJ43azSpXs8&Rp&6a~7$sDqIV{_GG%g5|wWe~`foWYc?HLAXdxQL*cx z1pumP!6vNJ?V~Yr511a}{e4;oygXKDYC}BS#X5Ubrz#aNEdq|YWHV5r5*#9^**E6p zR4N1E(}i3OK<7c^TtKBQ+>z?|h-EMNGv~I*s&rxx`S6!5r2xzKc5KZFj$SHOhi&+S zi&J%n77*^V4ZEvp!oYghF-1~)u3VCQ^_q;hnE1s*+l2nH;>sSEj-*4G@&qW@_o`ikEbT#W_L|?6AKnKenMDd;FR& zQFID$!|clS9k`AGm0*qHFv|*%P+WMfR=;wdnlWdsxrtW&@}$NGFCub)jbwGD={6Oz zQb0OiqNcn`=?YIZFIHl0GNq=Qs6nn4Cq2Kg#YfF-4ciBMmg9xUTi8*UoUaM4R$Nfp zR)dH)J_3iXj`>kkraWk|`0hko5)=hGI#5gsx7JR^%`r~NyqwxEsInofvO=7IR;KyO zr=_LJ2v_&D*?lk+_)wA|+F~|0LM59bFakGw9v5zPy3dIiJ?sbSU%5;DdpvDyQ`1DNpPnzeD(hbsm%ikr8Q>7rnGg5@=Nn6w45JT_V=5 zsm&r;{^XD%*-QzXpM%LrX9K&_?u#m$WOpg@acIFiu$~eC-9$@lyxL{ufw8T*5zH#t)oDX5s zT+v=7D~p$Of9ezCGBdFx|31_E2G2{TXw=epc(c^`ed4Y4y4cQ&^iYV;H(+lV zxYfVM^jlAPb-}#EhW3DBsW^m5o?qMnq5!^_NvVd5w82Cp6{iLQQ?<}UrdnMd^G6LZ zxKv@I_Ins&DwY&=zx62?YYS2Zyq>d4YegRo-C`2W(hQnb84zyfu(Sz{T@9J`FTC%7-i=f{EFANMau!I%yQ@!|)bH=9Tc{Rf-Wi}p3hH$%=`>rqSZ&i8LS;@rS0v46hk>hxbjxPQ0Y9-- zLzhsTgbHEWSo7E0TS@uAi)v(F7!gtcF0NEaF4&tyKI$c<%mr3@Kdf8>UgNLN^Lj%R z1zsU*KSp|2k8sf*mKvEvDyP)ZNy_D5ORcP}Y%lyPZNKRtd_b!y0T%kTytzXHbry{H z1=T@S2}m9{!teYbby(#(2@jw-A$kmQI0NAxbsTLNsVwzSMF<&(BGIYH!R`d_zt#xD zl7yg$5W*RQJ)I~9$jG9IfNms6(#Z&Zyt(Ln|98p9f|D=x?>TB2xWA9XHbCb5yN2~r zTcIhy@l*T{ln!d>zzWs9=Kr*0wS!aq}pkY&^KBkeB$voo|~8ht%IJ&*IgAjp1- zNktQ584(4@(K6z#(O;4?V1fXAF@wM%ONMrE*eYUXDvfw(<;3MQswis-{e(0E|)&63cYiHW;@dt-COT^S(?kBgG zkUU%3z5}BEBZB-+f!HFbTU#jB+*tB0=g8r63VA6#UUy4 zIQFIf|1jJL6tDPdo-m#Q26_)GF%G-li2f8{*e9>66t`2KtIDX~aqcM>96>mYLwSwf z))|9rc)E;JiukkL0Ut?M3MS{uNMD{N*Z=ki!3uU)1h^o_;}Tr2kq!BYFRq{lsbh zy+%?KJ=e2It#B@(H$LTH*W@NR&e1v-R`YYZW-WZ(@7x#tH5UZdE1{50U6XVc!`xVSE5u= z1q_5vudi@z-u?XsMh}8?TyL(~?Ay;!4TyoD^F8d-E=d!6+Ad4pn_|4-mNi@SGYGDR z&pYrk+Q}9^0#Lx~*Rle=o~2)dyGy#|`k)CmueCG6>d8 zzKp51>Di&hPr8HfI(itXvKl%YZ2opz7dR-K_jn=U*=;s0(&;X`e_q?#?s@g9 zjrL7|w`8OEo59~0nLI2$%Ut;du5?vp1U!mHe6MUW=VhOt<}K`z;)TJ8fB5wyo%HS$IG0jRd30ZD_aH6^-AuXs(|hZO7+_*dsnd zbjT9rdwvr%I9oi@N1u)l#Wfwd?a)2e{qqo?!{v;@<#U-P8JOGqgi36kLc|2x5HZ~J zw(tiB)1Qj{lh6D#L7BUH^e6%JUScVWA3fZ#6?>@W9MZgoXddVYrPoYCQ+<~*%~ z_4Dxdz?8^xqBMo{f9`a8$Nr7qCKm3Oc`kM+`5Gw8NnG0jzE=!K&w;pY_ie(vo?dLISWMMhsV@uf`Pcuh%u*O&{ch z4E5ij9Q29$juF}%-?PpHeiE$o1bFL$DxRJqMMR6xf9mK&X@CtMAz?OU0JX~BzG_=LE*~9P>LQeFy?-G#x;irz{EQdigqs+#CeZL6> zLjnI;Gt6xCp>^YUK^9Tccsr@x+Erxd<4R=kr_TJ%Eywb&vRHL4yaP$5bEqzu_fo*h zcI5FKD2~bysCk4iK^^O{v)I#k^z?Gp$^1QVX4%Vre2YCpI2X{fY0$7iB)o7x*DAIn z40goG@T>cNP7wIH9fVYC%cQyS@aRPXa&WuLb&p)%7ks@m@chyG5st znA=cuvzBr`0i6ETs9GbQHTMZnDx(3q|)h7}TGLtu~FSZbFWU4)*UXn=lhJ}plCfA~QuFK!2r zvdbvH4N{6b-|F`=P84j%}f>~ypdNAY07%m4Pjfbh16~C^4s

GUL*BelgB9Faweo)u%@D?+!JBx;?czGZ7=go=Uue_*kkyOT!7$Ejyogu;dm1;No z`snze^f^w}sM+I-!`7#t+xzig^eGm#SA)k0bbbBiK9ySz=^#`W0#W0!xp{E<#R`Dn z^snBhaXG|z6pEVzUSfcUO#|_YHY(2?nQarWIh&KU#V9u@U*z@#~J$ zVfJ09r+7d9x-xW(j60)yT5ZAH_wI5k?p<=5$Ov`W>LBbt z{@jVuQaI>$#JT&n*cCyz8Gh{Z2w=~&?;2IW=f)AfoI{FO#$L#ioroYjx27i(mJc%Y zIfq&+-(D7I_|CZvX@IvKz6aXH+N(SNQPtSL(mX7+eK~x;VPNHV-Zk>;)+YxM@sB>v z$>Le@D@X-;*Ograb%UfIMBrP-iT~0F{o9(VHFU{JF3Swa1r3eMy&Spw%It zg43}8&HavV&}7)@p`Tl&E~nRd)~Nt(*xhmm(Dy%ixp|@4phPi&COhgjH$7q4{iu&w z-GWRgBVe2d>E2(QVX%CHi9O-Zyw*VT2RTmv>gCH0NQ1-a^I2h90p6C`X}4VI_^Aml z8=rZ6r|9Je(VpUWUGFQ%AprwOh;!YlIxzMeB7*o|HLB)r)oBFVwG@q-OkE2|7=UBv znWvL89YMRAvZVNP1A7~xXx_)uco4BSQ6qZKFWR0x1jQf}O)n>1rjtU?+K2@Vg0yg9 z8MfIa6b%00a2i^xDMp)a3w}Z{7xP=@m_)3<>;RSx|0%i5nxO{G-;G})(5V!pz>Wh> zwdHbfVZgpJFzkYCv}x%&#$Qi#kT~?mQk(9cAkFeC3SF;x%G1c*8{qX<(KJe`IgCR7 z$^ZlV^ix_)Sk0}=R^yd0lE5{9*O3&@^mWVf1DrR`!mH6Usa!ggB9b-D9C zXvMT!vs#C}?YG~r-Es_>(P*2nXmMz|Ag*y$H3#r}AoQa0`$~We7hCPDhyPlwH}y>4 zApTk>C^zL+)-MLRg!v`^?7dOZ;9Qk|4I;{*8pEK;RO+m-IYpQ>aaC#SXRB4~rR3_c z##%k*T8H|pV^!K;D>Wm0h##=0~c! zX5@1#1&!Z!v0%?@)2s;_r1pM|Zc;**9@H>+?{RFs=buH}Yv4!7TbA&-2P`wB*DxDj z5@YS}bRLXa!igQ&(7Q43KQ#+CIVEpv`>F&MQKp=NHuugNYpickz4ODX*d(1V+%K@dc3pfrhzTY>~qKX^5MSVFkLd7EL zGG+{4G|EE&DC6wK+ z6i?NraBK&G@Haxb8RwI89H*1F6oSA6T?XFJzM`*; zP&DjJb9k4))O^Hkd zeZSryz7o}aHFvaiM&Z_1uy+J65qe!Zt~v%;*4mT%z(;1aB0q7z0ED77$QWwM(xg!x z=zY+)DfDxsk1#+Z>Lny}kT(vFfSqkSaG3y~U$5KRQkfUUwn0gY%?DsWUdq6_}ScJ?<(P!HonXsFz9aGltYh7&_~>e zvqacgaAJiBv)U$McmR$V%TvfAs4Dcbuk`2P`PKa!hO~ZKK)2@wOW2??*bE}^<@=+= z<%pp_f@vjSOSf)3t3-@hBMHdlHiQN%HG|G z^o1wV)%cUwKC`MLT)xFn3oTgD*jI}iuSv6HM>eZ7cdHA3+>{UEkp)Pc;K9#k)mHw! zLI05DWh-uV0?#l=q4FjM!^9;BXOjkWJzzOZF2W(i6?cATsav1RfarckPkLnuMwH;1Z?S1&vNxW^bkW@=5Ad*c4mnk&Ct zb5X+%WswjYzw^5aDVG_M%*+)Z$zlo$rkxoQq?E+xrZP!# zM;62;5Xr4vQtJosz|xrxWT`{)(odoK{(PAm37WD-qsx@)k5`Atrqw9Hj>x3?08vC( zzFscQpl_}as?tHmiQ;_vLmOfkC2|lA(iCwsrhU{HbCJm^uP!tY*+*)~`i!h;Xkb9O-_#?UhLjFQ5PM zyx7{!aK68YuIoj1dSN>R9~y$Nh`z9I(Cu=_KD~7ljCq^Mc~Mrm`a%X$FoZDw*Ktv* z5DN*0g^lg>s}H%e_(&i^Y{(f$z+X1ARm=kPJl1`-)n{6nJsK3UU+?+4-ZbCZFd&CDM$_i__r+TG zWviMn1S!Mvyyb`N+Zd3Mzgo+7LGzy_>%Ot^Pbkp0fq?z*;&tx-z2Uo8ky+;IkRyS`nk~{{u~OuJHf> literal 158799 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�GeLR>BE_wIDYE>KwvmFdDqRm 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

KNNf$+)afXg$c2MQg;)q!qS0-|Q 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Ð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 JtCg_`|37()qZa@G literal 5108 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 W3zt~Yzg^b=0000MxpIrHtklaritbMLSF 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

NUN5YSOxR?MKGsD6+TmL9?tCGIr!LZdraS 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