diff --git a/WindowsEDB-to-CSV.exe b/WindowsEDB-to-CSV.exe index c2ff0a1..bb735fa 100644 Binary files a/WindowsEDB-to-CSV.exe and b/WindowsEDB-to-CSV.exe differ diff --git a/WindowsEDB-to-CSV.ps1 b/WindowsEDB-to-CSV.ps1 index fb43fe6..c374b5c 100644 --- a/WindowsEDB-to-CSV.ps1 +++ b/WindowsEDB-to-CSV.ps1 @@ -274,8 +274,9 @@ function Get-EDBcolumnData [Parameter(Mandatory = $true)] $Column ) + $Binarydata = [Microsoft.Isam.Esent.Interop.Api]::RetrieveColumn($Session, $Table, $column.Columnid, [Microsoft.Isam.Esent.Interop.RetrieveColumnGrbit]::RetrieveIgnoreDefault, $null) - $data = if ($Binarydata -ne $null) + $data = if ($null -ne $Binarydata) { switch ($column.Coltyp) { @@ -284,15 +285,15 @@ function Get-EDBcolumnData '14' { [Bitconverter]::ToUInt32($Binarydata, 0) ; break } '15' { [Bitconverter]::ToInt64($Binarydata, 0) ; break } 'Bit'{ [Bitconverter]::ToBoolean($Binarydata, 0) ; break } - 'Short'{ [Bitconverter]::ToInt16($Binarydata, 0); break } + 'Short'{ [Bitconverter]::ToInt16($Binarydata, 0) ; break } 'UnsignedByte'{ $Binarydata ; break } 'LongText'{ - try { [System.Text.Encoding]::GetEncoding("$($column.Cp)").GetString($Binarydata) } + try { [System.Text.Encoding]::GetEncoding("$($column.Cp)").GetString($Binarydata) } catch { [System.Text.Encoding]::UTF8.GetString($Binarydata) } break } 'Binary'{ - switch ($column.name) # Check the Name Column + switch ($column.name) { { $_ -eq 'LastModified' } { @@ -322,14 +323,15 @@ function Get-EDBcolumnData } { $_ -match 'ActivityHistory_Importance' } { - try { [Bitconverter]::ToUInt64($Binarydata, 0) } + try { [Bitconverter]::ToUInt64($Binarydata, 0) } catch { [System.BitConverter]::ToString($Binarydata).Replace('-', '') } } default { [System.BitConverter]::ToString($Binarydata).Replace('-', ''); break } } } 'LongBinary'{ - if ($column.name -match $ulist) # Check the Name Column + # Check the Name Column + if ($column.name -match $ulist) { try { [System.Text.Encoding]::GetEncoding($column.Cp).GetString($Binarydata) } catch { [System.BitConverter]::ToString($Binarydata).Replace('-', '') } @@ -416,7 +418,6 @@ function Read-EDB Write-Output -InputObject $Error[0].Exception.GetType().FullName } - # Get the Page Size [System.Int32]$PageSize = -1 [Microsoft.Isam.Esent.Interop.Api]::JetGetDatabaseFileInfo($dbfile, [ref]$PageSize, [Microsoft.Isam.Esent.Interop.JET_DbInfo]::PageSize) @@ -599,17 +600,14 @@ function Read-EDB Write-Output "Skipping $($TableName) - Table is empty" continue # skip table } - + # Iterates over all the columns in the table, Exiting information about each one. $Columns = [Microsoft.Isam.Esent.Interop.Api]::GetTableColumns($Session, $DatabaseId, $TableName) $ColumnArray = [System.Collections.ArrayList]@() - - # Iterates over all the columns in the table, Exiting information about each one. foreach ($Column in $Columns) { - $null = $ColumnArray.Add(@($Column)) + $null = $ColumnArray.Add(@($Column)) } $columnCount = $ColumnArray.count - # [Microsoft.Isam.Esent.Interop.Api]::GetColumnDictionary($Session, $Table) # Export Column List to Txt $TableName | Out-File -FilePath "$($outfolder)\$($dbfilename)_$($TableName).txt" -Encoding utf8 @@ -652,11 +650,17 @@ function Read-EDB } $r++ } # End While - # Sort in order to get All the fields - $outdata = $RowRecords | Sort-Object -Property @{ expression = { $_.psobject.properties.count } } -Descending - # Export to CSV - $outdata | Export-Csv -Path "$($outfolder)\$($dbfilename)_$($TableName).csv" -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append -Force - Write-Progress -Activity "Reading dB" -Status "Table: $($TableName) - $($key)" -Completed + + $rpath = "$($outfolder)\$($dbfilename)_$($TableName)_Records.csv" + # Get all the Headers + $Headers = [System.Collections.ArrayList]@{ } + $RowRecords.ForEach{ $_.psobject.properties.Name.foreach{ if (!$Headers.Contains($_)) { $null = $Headers.Add($_) } } } + $Headers.Sort() + # Create a blank CSV with only headers + $Headers -join '|' | Add-Content -Path $rPath + # Add the Records to CSV + $RowRecords | Export-Csv -Path $rPath -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append -Force + $Headers.Clear() $RowRecords.Clear() $outdata = $null [System.GC]::Collect() @@ -697,7 +701,7 @@ function Read-EDB } # end for each column if (!!$MSysTypes[[System.String]$RowRecordData.Type]) { $RowRecordData.Type = "$($MSysTypes[[System.String]$RowRecordData.Type]) ($($RowRecordData.Type))" } # Export Rows - $RowRecordData | Export-Csv -Path "$($outfolder)\$($dbfilename)_$($TableName).csv" -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append -Force + $RowRecordData | Export-Csv -Path "$($outfolder)\$($dbfilename)_$($TableName).csv" -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append if ($r % 50 -eq 0) { Write-Progress -Activity "Reading dB" -Status "Table: $($TableName)" -PercentComplete "$(($r/$RecCount).tostring('P0').trim('%'))" @@ -750,7 +754,7 @@ function Read-EDB } } # end for each column - $RowRecordData | Export-Csv -Path "$($outfolder)\$($dbfilename)_$($TableName).csv" -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append -Force + $RowRecordData | Export-Csv -Path "$($outfolder)\$($dbfilename)_$($TableName).csv" -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append if ($r % 50 -eq 0) { Write-Progress -Activity "Reading dB" -Status "Table: $($TableName)" -PercentComplete "$(($r/$RecCount).tostring('P0').trim('%'))" @@ -770,74 +774,106 @@ function Read-EDB $null = [Microsoft.Isam.Esent.Interop.Api]::MoveBeforeFirst($Session, $Table) # Create Pairs $pairs = [System.Collections.ArrayList]@() + $searchstoreid = $coldict[$coldict.Keys.Where{ $_ -match 'System_Search_Store' }] + $SystemItemType = $coldict[$coldict.Keys.Where{ $_ -match 'System_ItemType' -and $_ -notmatch 'System_ItemTypeText' }] + Write-Output "Please wait - Reading Table: '$($TableName)' - Collecting Search Types" While ([Microsoft.Isam.Esent.Interop.Api]::TryMoveNext($Session, $Table)) { - # Read the Work Id (Index value) - $searchstoreid = $coldict[$coldict.Keys.Where{ $_ -match 'System_Search_Store' }] + # Read the Work Id (Index value) and System Item Types $workid = [Microsoft.Isam.Esent.Interop.Api]::RetrieveColumnAsUInt32($Session, $Table, $coldict.WorkID, [Microsoft.Isam.Esent.Interop.RetrieveColumnGrbit]::None) + if ($null -ne $SystemItemType) + { + $col = [Microsoft.Isam.Esent.Interop.Api]::RetrieveColumn($Session, $Table, $SystemItemType, [Microsoft.Isam.Esent.Interop.RetrieveColumnGrbit]::RetrieveIgnoreDefault, $null) + $itemType = if ($null -ne $col) { [System.Text.Encoding]::Unicode.GetString($col) } + else { '-' } + } + else { $itemType -eq '-' } $Sstore = [Microsoft.Isam.Esent.Interop.Api]::RetrieveColumnAsString($Session, $Table, $searchstoreid, [System.Text.Encoding]::Unicode, [Microsoft.Isam.Esent.Interop.RetrieveColumnGrbit]::None) $null = $pairs.Add([PsCustomObject]@{ - 'WorkID' = $workid - 'Type' = $Sstore + 'WorkID' = $workid + 'Type' = $Sstore + 'ItemType' = $itemType }) } # End While - # Create HashTable - $Types = ($pairs | Sort-Object -Property 'Type' -Unique).Type - $HashTable = [System.Collections.HashTable]@{} + # Collect Types & ItemTypes + $Types = ($pairs | sort -Property 'Type' -Unique).Type - # Get each Type on its own - Foreach ($type in $types){$Hashtable[$type] = @($pairs.Where{ $_.type -eq $type }.WorkID) } # End foreach Type + # Get each Search Type on its own + if ($Types.count -eq 0) + { + continue + } + $workIDdataSize = $ColumnArray.where{ $_.Name -eq 'WorkID' }.MaxLength - # Colect the Data for each type - foreach ($key in $HashTable.keys) + # Colect the Data for each Search type + foreach ($stype in $Types) { - Write-Output "Reading Table: '$($TableName)' - Collecting $($HashTable[$key].count) 'System_Search_Store' Entries of type: '$($key)'" - $RowRecords = [System.Collections.ArrayList]@() - $r = 0 - foreach ($value in $HashTable[$key]) + Write-Output "Reading Table: '$($TableName)' - Collecting 'System_Search_Store' Entries of type: '$($stype)'" + $SystemItemTypes = ($pairs.where{ $_.Type -eq $stype } | sort -Property 'ItemType' -Unique).ItemType + if ($SystemItemTypes.count -eq 0) { continue } + + $ItemTypesHashTable = [System.Collections.HashTable]@{ } + foreach ($sit in $SystemItemTypes) { - [System.Byte[]]$v = [System.BitConverter]::GetBytes($value) - [Microsoft.Isam.Esent.Interop.Api]::JetSetCurrentIndex2($Session, $Table, [System.String]::Empty, [Microsoft.Isam.Esent.Interop.SetCurrentIndexGrbit]::None) - [Microsoft.Isam.Esent.Interop.Api]::JetMakeKey($Session, $Table, $v, 4, [Microsoft.Isam.Esent.Interop.MakeKeyGrbit]::NewKey) - $null = [Microsoft.Isam.Esent.Interop.Api]::TrySeek($Session, $Table, [Microsoft.Isam.Esent.Interop.SeekGrbit]::SeekEQ) - - # Get the Row Data - $columndata = [PSCustomObject]@{ } - foreach ($column in $ColumnArray) + $ItemTypesHashTable[$sit] = @($pairs.Where{ $_.Type -eq $stype -and $_.ItemType -eq $sit }.WorkID) + if ($ItemTypesHashTable[$sit].count -eq 0) { continue } + + $r = 0 + $RowRecords = [System.Collections.ArrayList]@() + foreach ($workIDvalue in $ItemTypesHashTable[$sit]) { - $data = Get-EDBcolumnData -Session $Session -Table $Table -Column $column - - # Convert FileAttributes from Int to human readable string - # if ($column.name.ToString().contains('System_FileAttributes') -and $column.Coltyp.ToString() -eq '14' -and !!$FileAttributesEnum["$($data)"]) { $data = $FileAttributesEnum["$($data)"] + " ($($data))" } + [System.Byte[]]$v = [System.BitConverter]::GetBytes($workIDvalue) + [Microsoft.Isam.Esent.Interop.Api]::JetSetCurrentIndex2($Session, $Table, [System.String]::Empty, [Microsoft.Isam.Esent.Interop.SetCurrentIndexGrbit]::None) + [Microsoft.Isam.Esent.Interop.Api]::JetMakeKey($Session, $Table, $v, $workIDdataSize, [Microsoft.Isam.Esent.Interop.MakeKeyGrbit]::NewKey) + $null = [Microsoft.Isam.Esent.Interop.Api]::TrySeek($Session, $Table, [Microsoft.Isam.Esent.Interop.SeekGrbit]::SeekEQ) - # Add column data to psobject - if (![string]::IsNullOrEmpty($data) -and ![string]::IsNullOrWhiteSpace($data)) + if ($r % 50 -eq 0) { - $columndata | Add-Member -MemberType NoteProperty -Name "$($column.Name)" -Value $data -Force + $p = ($r/$ItemTypesHashTable[$sit].count).tostring('P0').trim('%') + Write-Progress -Activity "Reading dB" -Status "Table: $($TableName) - $($ItemTypesHashTable[$sit].count) [$($stype)] $($sit) Records" -PercentComplete "$($p)" } - } # end for each column - - if ($r % 50 -eq 0) - { - $p = ($r/$HashTable[$key].count).tostring('P0').trim('%') - Write-Progress -Activity "Reading dB" -Status "Table: $($TableName) - $($key)" -PercentComplete "$($p)" - } - $r++ - $null = $RowRecords.Add($columndata) - } #end rows - $rpath = "$($outfolder)\$($dbfilename)_$($TableName)_$($type)_Records.csv" - # Sort in order to get All the fields - $outdata = $RowRecords | Sort-Object -Property @{ expression = { $_.psobject.properties.count } } -Descending - # Export to CSV - $outdata | Export-Csv -Path "$($outfolder)\$($dbfilename)__$($TableName)_$($key).csv" -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append -Force - } # end foreach key - Write-Progress -Activity "Reading dB" -Status "Table: $($TableName) - $($key)" -Completed + # Get the Row Data + $columndata = [PSCustomObject]@{ } + foreach ($column in $ColumnArray) + { + $data = Get-EDBcolumnData -Session $Session -Table $Table -Column $column + + # Convert FileAttributes from Int to human readable string (-band ?)) + # if ($column.name.ToString().contains('System_FileAttributes') -and $column.Coltyp.ToString() -eq '14' -and !!$FileAttributesEnum["$($data)"]) { $data = $FileAttributesEnum["$($data)"] + " ($($data))" } + + # Add column data to psobject + if (![string]::IsNullOrEmpty($data) -and ![string]::IsNullOrWhiteSpace($data)) + { + $columndata | Add-Member -MemberType NoteProperty -Name "$($column.Name)" -Value $data + } + } # end for each column + $null = $RowRecords.Add($columndata) + $r = $r + 1 + } #end rows + + $rpath = "$($outfolder)\$($dbfilename)_$($TableName)_$($stype)_$($sit.replace('/', '-'))_Records.csv" + # Get all the Headers + $Headers = [System.Collections.ArrayList]@{ } + $RowRecords.ForEach{ $_.psobject.properties.Name.foreach{ if (!$Headers.Contains($_)) { $null = $Headers.Add($_) } } } + $Headers.Sort() + # Export the Headers (for debugging/comparisons) + # $Headers | Out-File -FilePath "$($outfolder)\$($dbfilename)_$($TableName)_$($stype)_$($sit.replace('/', '-'))_Headers.txt" -Encoding utf8 + + # Create a blank CSV with only headers + $Headers -join '|' | Add-Content -Path $rPath + # Add the Records to CSV + $RowRecords | Export-Csv -Path $rPath -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append -Force + $Headers.Clear() + $RowRecords.Clear() + Write-Progress -Activity "Reading dB" -Status "Table: $($TableName) - $($ItemTypesHashTable[$sit].count) [$($stype)] $($sit) Records" -Completed + } # end foreach SIT + + } # end foreach Search type + $pairs.Clear() - $HashTable.Clear() - $RowRecords.Clear() - $outdata = $null + $ItemTypesHashTable.Clear() [System.GC]::Collect() } else # Get Other Tables @@ -845,6 +881,7 @@ function Read-EDB # Get Row Records # Try to go to the 1st record $null = [Microsoft.Isam.Esent.Interop.Api]::MoveBeforeFirst($Session, $Table) + $RowRecords = [System.Collections.ArrayList]@() While ([Microsoft.Isam.Esent.Interop.Api]::TryMoveNext($Session, $Table)) { $columndata = [PSCustomObject]@{ } @@ -862,7 +899,8 @@ function Read-EDB } } # end for each Column - $columndata | Export-Csv -Path "$($outfolder)\$($dbfilename)_$($TableName).csv" -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append -Force + $null = $RowRecords.Add($columndata) + if ($r % 50 -eq 0) { $p = ($r/$RecCount).tostring('P0').trim('%') @@ -870,6 +908,20 @@ function Read-EDB } $r++ } # end while + + $rpath = "$($outfolder)\$($dbfilename)_$($TableName)_Records.csv" + + # Get all the Headers + $Headers = [System.Collections.ArrayList]@{ } + $RowRecords.ForEach{ $_.psobject.properties.Name.foreach{ if (!$Headers.Contains($_)) { $null = $Headers.Add($_) } } } + $Headers.Sort() + # Create a blank CSV with only headers + $Headers -join '|' | Add-Content -Path $rPath + # Add the Records to CSV + $RowRecords | Export-Csv -Path $rPath -Delimiter '|' -Encoding UTF8 -NoTypeInformation -Append -Force + $Headers.Clear() + $RowRecords.Clear() + Write-Progress -Activity "Reading dB" -Status "Table: $($TableName)" -Completed [System.GC]::Collect() } @@ -1792,9 +1844,18 @@ fwba/X8= } catch [System.Management.Automation.MethodInvocationException] { - Write-Output -InputObject "$(($Error[0].Exception.InnerException.Message))" - Stop-Transcript - Exit + try + { + $null = [System.Reflection.Assembly]::LoadFile(".\Esent.Isam.dll") + $null = [System.Reflection.Assembly]::LoadFile(".\Esent.Interop.dll") + $null = [System.Reflection.Assembly]::LoadFile(".\Esent.Collections.dll") + } + catch + { + Write-Output -InputObject "$(($Error[0].Exception.InnerException.Message))" + Stop-Transcript + Exit + } } } # End function Load-ManagedInterop @@ -1822,8 +1883,8 @@ exit # SIG # Begin signature block # MIIviAYJKoZIhvcNAQcCoIIveTCCL3UCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG -# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBZAO2uGZXsoHas -# GAF4pjm5no/o6ZXntVWFvq/Dpd+DEKCCKI0wggQyMIIDGqADAgECAgEBMA0GCSqG +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCB/+58jvicmL6U0 +# 9MPkaV2kWq5nvGhesBOJlUYL6XaY6KCCKI0wggQyMIIDGqADAgECAgEBMA0GCSqG # SIb3DQEBBQUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNo # ZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1p # dGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2VydmljZXMwHhcNMDQwMTAx @@ -2043,35 +2104,35 @@ exit # AQEwaDBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSsw # KQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2AhALYufv # MdbwtA/sWXrOPd+kMA0GCWCGSAFlAwQCAQUAoEwwGQYJKoZIhvcNAQkDMQwGCisG -# AQQBgjcCAQQwLwYJKoZIhvcNAQkEMSIEIPQqWgV8KJantQ9yC8Ag8Z2yS1IjXqvv -# GgP4uLo7/dwZMA0GCSqGSIb3DQEBAQUABIICACvpeAUyGb/K/4jRWKTLwDGrlrM2 -# /h0mQohWyBRDuJDp6i5g5REwZvFrwhdAXWiA4wb9qxLMUzmZ9Le92qBlDyBnzjHh -# 0dxXiG219o4MdQXCg2I+Vny/8s8ltW3gFDfnkDzSRWA+rZv2MF5KUXn/JxXX8On5 -# +xXhoQHtzQJsQCOzkrs5DIqTW5SlyylBKXE1DgYaPgFdE2Hgfu0YoJfRdcvWDuK7 -# 0eVvKtjIvg5CM3f6TH/GjpcVxI2P2123tNV6hc8kkMHJsIE6JdB8h4VaHBg+/ibx -# ZFrzbIa3mG/73j2yxbCxcs3aY5B14gcFDFhoVbhb4OIHIFe1g6PZ7/+uFhTAiDZ3 -# N+aCLNmqxfRRhwG+pwcbwNqN4qesq14PxbmO2V2bAalp7uaZCcqyPQ3TnNmbh7Q1 -# nKwsjUYO8BjpKoBI8tcsIBFTPNzK5rptulDdRWEazvoq1dsoRDxUBy6ed5+KgEM3 -# ZpBApEfLW5b1eUjMPTQ3kBMQEIZbMlBlHhZ5IZztY459Vw3AP47XoHH2puP5D1pI -# o36Xc03qKiAlbFBFi5LLvkKvaXKz26759IZWKXGJG7rJCvu70LuPc5RFAC21YeRn -# 05+3APWpUnTzgDcIEwxReNw9SNyL1HhXfTXGsHWEQYLmzAfN8/LrIb8MlPc/MLqA -# VW+S2vmKgzM63IP1oYIDbDCCA2gGCSqGSIb3DQEJBjGCA1kwggNVAgEBMG8wWzEL +# AQQBgjcCAQQwLwYJKoZIhvcNAQkEMSIEIMGPERmtxpVNJFwUkomxNZf9TfS3WzYM +# Ko12oioN2JtAMA0GCSqGSIb3DQEBAQUABIICAGwJy945P2R2o8M1uDS2K1ofUZvH +# 4ywNmCUhaVf6b0klHJE+2VaraIBK7wcgDh3wTfVyWdiUfeBm1o4kRF5/CIVCx/Xa +# qyoTX/4Zehi81K1LnShISYb3F+oQydwL7NlAt9KKvVg+5GcHXV0i7kSiO7Cva69w +# FP4qBEgwpUGKytP8O90J+xNovqQpeHGANW4ii41eAVL/5m0TLNuY9fhFTLcEjLsT +# Nk3pl06IziC3y5VdMqOUvfS6Niho3yWKk/yle5c2c3AD9GG2lpr4VPfGeuPJ0FvN +# VdlWhmpbgD0RUduQeI7Bdk7yCCKW1a1C5wOVCAqZ9ERHb/grlIQujozr9xOMILik +# tnCIMZkzlHvZ/1udaLtTYmPT3gOkjdrFN07Vpp2l4g1NlwRJ9kphCb1K5KfAIS4U +# LkyM29lM7XnVkpjVCSbhyROWLhRAwfdKTp8R5CXlWXdEZao8h0NVhGUIU8AykZYi +# pSqJjQzCpdv/cugSuw5/B8YtCqa70G720N8RtUtzJoUoBcyJaeQ5J/SaswkmmTUd +# VjisICuKxpk/Dup1RmZ4hS7rqeIoVahFtgmiFpOFS6U0xGZvGRB/LtXWqXCvWLpL +# 9Gapf8x+hRa96W6tjeI5m3UOXM/wdT+RvgHshwEwk8Fdh2p8p/saEpUXm1hEYvhR +# nPDOvrHAAW23JuxmoYIDbDCCA2gGCSqGSIb3DQEJBjGCA1kwggNVAgEBMG8wWzEL # MAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExMTAvBgNVBAMT # KEdsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0gU0hBMzg0IC0gRzQCEAFIkD3C # irynoRlNDBxXuCkwCwYJYIZIAWUDBAIBoIIBPTAYBgkqhkiG9w0BCQMxCwYJKoZI -# hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMjEyMjkxMjQ5MDZaMCsGCSqGSIb3DQEJ +# hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMzAxMDIxMzM1MzRaMCsGCSqGSIb3DQEJ # NDEeMBwwCwYJYIZIAWUDBAIBoQ0GCSqGSIb3DQEBCwUAMC8GCSqGSIb3DQEJBDEi -# BCD/mQOcFAwj4lTwZNzT0YDr7OGSBewjHAf15RoM8um3szCBpAYLKoZIhvcNAQkQ +# BCAowa35UMgLy+JLwPCNlARDrJMpgHpSSsHK7H4o0A8g1zCBpAYLKoZIhvcNAQkQ # AgwxgZQwgZEwgY4wgYsEFDEDDhdqpFkuqyyLregymfy1WF3PMHMwX6RdMFsxCzAJ # BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQDEyhH # bG9iYWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIFNIQTM4NCAtIEc0AhABSJA9woq8 -# p6EZTQwcV7gpMA0GCSqGSIb3DQEBCwUABIIBgL6wAC5gsu0V4t5baKwBrqKbbJVT -# MDcDzG7bxt/lKT+pbAU6OCQIx1/rJ4h3FK9DT2pjQ8zC3jqtjG3WVd9TCpuoJvsZ -# IoIdaOp2Ewxp7alxkAjiF6VdZ1oQM6E44skcsOhd0fPMgnepKXpZrrTVOL2SXkf8 -# VsX5MpuOlAMbiywipoH3UdGokqcrduNG5ayCS2PKNEX3dcnfYYnt+UUqPAWBFToT -# lulvDfS9fsYLelPGajIyqor8psbXeJACY6S4KTODpBIKVrIGfkLoZvHz61YDXmOj -# K0YLX4IB6j/j0pfKlzrDPJurbaUG3BQNFDaPsPQvq8Yhys95CWgi29UjBX7FuZnC -# F9NqKSH71QSTfsLFvv/JYTFscIr/9yQnFS49wZAeDylYqb+9vkkJfcEPCX//cLD/ -# iGb5dZ8/uMYx65VOmTciPLkB0Bxp7QFpoRc7U/iBOZn382RK4m6U35gOnGXIHuPf -# EZ5gGpjzOZOfUn1M2FbAEJLpnUfbq/2tn5AdKg== +# p6EZTQwcV7gpMA0GCSqGSIb3DQEBCwUABIIBgD1WuCOaOMw4O4PLuGgkprbPOXT7 +# 2KeLPsBklaV1yZrtGZEZBZPywS2GX/eKjup7TAtfKqbEwXsbYIDs4o9/t+6bik8r +# m7PQtIsJ/hrio3WY9R+BeO9ANMXiEU0xHR+961eSezEFcTrnHF39R4LxfkpNajRD +# aUka14WPtkEOneexw6uzYQmA/YwcUyX+WLs1QwDG1KzmwNmeV7V7CnHzTdekrhq9 +# EXx23ZTHZQM9cLo4i8PLnX9ioFX8RT2yiqxh7wp0KN1ChwwK1FyuvCBVYiT4acmA +# VZB22t5Je9NSGhVoqeiUrYZnpR/zuOFzkofdp1ZitLo/sNxl91xdMAAjOudIitRe +# 6IkrRvdlFx9J62mqRWecn7kYaGZZX8Z6Tbq7jTbaYVwUEij7GoAtRipphsG1nz7o +# f8cFJoUniM73sCQx1KnOPKFApGxeNoQu4qgWWB5ndrJJXyYOizFXEaBUg8nE9boP +# EN1bwY7DdSupDKVvqQ4azj6+Te5eoZIp4uP67g== # SIG # End signature block