VaultCommands.ps1
|
#requires -Version 5.1 $Script:PathDelimiter = [System.IO.Path]::DirectorySeparatorChar function getVault { if (-not $Script:Context.Auth) { Write-Error -Message "Not Connected" -ErrorAction Stop } if (-not $Script:Context.Vault) { Write-Error -Message "Not Connected to Keeper vault. Please login first." -ErrorAction Stop } $Script:Context.Vault } function Get-KeeperLocation { <# .Synopsis Get current Keeper folder #> [CmdletBinding()] [KeeperSecurity.Vault.VaultOnline]$vault = getVault [string]$currentFolder = $Script:Context.CurrentFolder [KeeperSecurity.Vault.FolderNode]$folder = $vault.RootFolder if ($currentFolder) { $vault.TryGetFolder($currentFolder, [ref]$folder) | Out-Null } exportKeeperNode $folder } New-Alias -Name kpwd -Value Get-KeeperLocation function Set-KeeperLocation { <# .Synopsis Change current Keeper folder .Parameter Path New location #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] Param ( [Parameter(Position = 0)][string] $Path ) [KeeperSecurity.Vault.VaultOnline]$vault = getVault if ($Path) { [KeeperSecurity.Vault.FolderNode]$folder = $null if (!$vault.TryGetFolder($Script:Context.CurrentFolder, [ref]$folder)) { $folder = $vault.RootFolder } $components = splitKeeperPath $Path $rs = parseKeeperPath $components $vault $folder if ($rs -and !$rs[1]) { $folder = $rs[0] $uid = $folder.FolderUid if ($vault.TryGetFolder($uid, [ref]$folder)) { $Script:Context.CurrentFolder = $uid } else { $Script:Context.CurrentFolder = '' } } } getVaultFolderPath $vault $Script:Context.CurrentFolder } $Keeper_FolderPathRecordCompleter = { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $result = @() [KeeperSecurity.Vault.VaultOnline]$vault = $Script:Context.Vault if ($vault) { [KeeperSecurity.Vault.FolderNode] $folder = $null if (!$vault.TryGetFolder($Script:Context.CurrentFolder, [ref]$folder)) { $folder = $vault.RootFolder } $pattern = '' $toComplete = $wordToComplete if ($toComplete.Length -ge 2) { if ($toComplete[0] -eq '''' -and $toComplete[-1] -eq '''') { $toComplete = $toComplete.Substring(1, $toComplete.Length - 2) $toComplete = $toComplete -replace '''', '''' } } if ($toComplete) { $components = splitKeeperPath $toComplete if ($components.Count -gt 1) { if ($components[-1]) { $pattern = $components[-1] $components[-1] = '' } $rs = parseKeeperPath $components $vault $folder if ($rs -and $rs.Count -eq 2) { if (!$rs[1]) { $folder = $rs[0] } else { $folder = $null } } } else { if ($components) { $pattern = $components $components = @('') } else { $folder = $vault.RootFolder $pattern = '' $components = @('') } } } else { $components = @('') $pattern = $wordToComplete } if ($folder) { $pattern += '*' foreach ($uid in $folder.Subfolders) { $subfolder = $null if ($vault.TryGetFolder($uid, [ref]$subfolder)) { if ($subfolder.Name -like $pattern) { $path = @() $components | ForEach-Object { $path += $_ } $path[-1] = $subfolder.Name $expansion = ($path | ForEach-Object { $_ -replace '\\', '\\' }) -join $Script:PathDelimiter if ($expansion -match '[\s'']') { $expansion = $expansion -replace '''', '''''' $expansion = "'${expansion}'" } $result += $expansion } } } } } if ($result.Count -gt 0) { return $result } else { return $null } } Register-ArgumentCompleter -CommandName Set-KeeperLocation -ParameterName Path -ScriptBlock $Keeper_FolderPathRecordCompleter New-Alias -Name kcd -Value Set-KeeperLocation function Get-KeeperChildItem { <# .Synopsis Get the content of Keeper folder. Output and parameters are similar to Get-ChildItem cmdlet .Parameter Path Keeper folder .Parameter Filter Match the string in Title, Uid, Login, and Link fields .Parameter Recursive Get child items in subfolders recursively .Parameter Depth Recursion depth .Parameter SkipGrouping Do not group result set by folder .Parameter ObjectType Limit result set to Folders or Records only #> [CmdletBinding()] Param ( [Parameter(Position = 0)][string] $Path, [string] $Filter, [Switch] $Recursive, [int] $Depth, [Switch] $SkipGrouping, [ValidateSet('Folder' , 'Record')][string] $ObjectType ) $showFolder = $true $showRecord = $true if ($ObjectType) { $showFolder = $ObjectType -eq 'Folder' $showRecord = !$showFolder } [KeeperSecurity.Vault.VaultOnline]$vault = getVault [KeeperSecurity.Vault.FolderNode] $currentDir = $null if (!$vault.TryGetFolder($Script:Context.CurrentFolder, [ref]$currentDir)) { $currentDir = $vault.RootFolder } [KeeperSecurity.Vault.FolderNode] $baseDir = $null if ($Path) { if (-not $vault.TryGetFolder($Path, [ref]$baseDir)) { $components = splitKeeperPath $Path $rs = parseKeeperPath $components $vault $currentDir if ($rs -is [array]) { if (-not $rs[1]) { $baseDir = $rs[0] } } } } else { $baseDir = $currentDir } if (-not $baseDir) { Write-Error -Message "Cannot find path '$Path'" -ErrorAction Stop } [KeeperSecurity.Vault.FolderNode[]]$folders = @($baseDir) if ($Recursive.IsPresent) { $pos = 0 $dep = 0 while ($pos -lt $folders.Count) { if ($Depth -gt 0) { if ($dep -ge $Depth) { break } } $lastPos = $folders.Count for ($i = $pos; $i -lt $lastPos; $i++) { foreach ($uid in $folders[$i].Subfolders) { [KeeperSecurity.Vault.FolderNode] $sf = $null; if ($vault.TryGetFolder($uid, [ref]$sf)) { $folders += $sf } } } $pos = $lastPos $dep++ } } $entries = @() $recordEntries = @{} for ($i = 0; $i -lt $folders.Count; $i++) { [KeeperSecurity.Vault.FolderNode]$f = $folders[$i] $path = getVaultFolderPath $vault $f.FolderUid if ($showFolder) { foreach ($uid in $f.Subfolders) { [KeeperSecurity.Vault.FolderNode]$sf = $null if ($vault.TryGetFolder($uid, [ref]$sf)) { $match = $true if ($Filter) { $match = @($sf.Name, $sf.FolderUid) | Select-String $Filter | Select-Object -First 1 } if ($match) { $entry = [PSCustomObject]@{ PSTypeName = "KeeperSecurity.Commander.FolderEntry$(if ($SkipGrouping.IsPresent) {'Flat'} else {''})" Uid = $sf.FolderUid Name = $sf.Name OwnerFolder = $path FolderType = $sf.FolderType Shared = $sf.FolderType -ne [KeeperSecurity.Vault.FolderType]::UserFolder SortGroup = 0 } $entries += $entry } } } } if ($showRecord) { foreach ($uid in $f.Records) { [KeeperSecurity.Vault.KeeperRecord] $r = $null if ($vault.TryGetKeeperRecord($uid, [ref]$r)) { if ($r.Version -ne 2 -and $r.Version -ne 3) { continue } $match = $true if ($Filter) { $match = @($r.Title, $r.Uid) | Select-String $Filter | Select-Object -First 1 } if ($match) { if ($Flat.IsPresent -and $recordEntries.ContainsKey($uid)) { $entry = $recordEntries[$uid] $entry.OwnerFolder += $path } else { $type = [KeeperSecurity.Utils.RecordTypesUtils]::KeeperRecordType($r) $publicInfo = [KeeperSecurity.Utils.RecordTypesUtils]::KeeperRecordPublicInformation($r) $entry = [PSCustomObject]@{ PSTypeName = "KeeperSecurity.Commander.RecordEntry$(if ($SkipGrouping.IsPresent) {'Flat'} else {''})" Uid = $r.Uid Name = $r.Title Shared = $r.Shared Owner = $r.Owner Type = $type PublicInformation = $publicInfo HasAttachments = ($vault.RecordAttachments($r).Count -gt 0) SortGroup = 1 } if ($SkipGrouping.IsPresent) { Add-Member -InputObject $entry -NotePropertyName OwnerFolder -NotePropertyValue @($path) } else { Add-Member -InputObject $entry -NotePropertyName OwnerFolder -NotePropertyValue $path } $recordEntries[$uid] = $entry $entry = $null } } } } } } if ($recordEntries) { $entries += $recordEntries.Values } if ($entries) { if ($SkipGrouping.IsPresent) { $entries | Sort-Object SortGroup, Name } else { $entries | Sort-Object OwnerFolder, SortGroup, Name } } } Register-ArgumentCompleter -CommandName Get-KeeperChildItem -ParameterName Path -ScriptBlock $Keeper_FolderPathRecordCompleter New-Alias -Name kdir -Value Get-KeeperChildItem function Get-KeeperObject { <# .Synopsis Get Keeper object by Uid .Parameter Uid Keeper UID .Parameter ObjectType One of the following Record, SharedFolder, Folder, Team .Parameter PropertyName Return object property not the entire object #> [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)][string[]] $Uid, [string] [ValidateSet('Record' , 'SharedFolder', 'Folder', 'Team')] $ObjectType, [string] $PropertyName ) Begin { [KeeperSecurity.Vault.VaultOnline]$vault = getVault $testRecord = if ($ObjectType) { $ObjectType -eq 'Record' } else { $true } $testSharedFolder = if ($ObjectType) { $ObjectType -eq 'SharedFolder' } else { $true } $testFolder = if ($ObjectType) { $ObjectType -eq 'Folder' } else { $true } $testTeam = if ($ObjectType) { $ObjectType -eq 'Team' } else { $true } } Process { ForEach ($oid in $Uid) { if ($testRecord) { [KeeperSecurity.Vault.KeeperRecord] $record = $null if ($vault.TryGetKeeperRecord($oid, [ref]$record)) { if ($PropertyName) { $mp = $record | Get-Member -MemberType Properties -Name $PropertyName if ($mp) { $record | Select-Object -ExpandProperty $PropertyName } } else { $record } continue } } if ($testSharedFolder) { [KeeperSecurity.Vault.SharedFolder] $sf = $null if ($vault.TryGetSharedFolder($oid, [ref]$sf)) { if ($PropertyName) { $mp = $sf | Get-Member -MemberType Properties -Name $PropertyName if ($mp) { $sf | Select-Object -ExpandProperty $PropertyName } } else { $sf } continue } } if ($testFolder) { [KeeperSecurity.Vault.FolderNode] $f = $null if ($vault.TryGetFolder($oid, [ref]$f)) { if ($PropertyName) { $mp = $f | Get-Member -MemberType Properties -Name $PropertyName if ($mp) { $f | Select-Object -ExpandProperty $PropertyName } } else { $f } continue } } if ($testTeam) { [KeeperSecurity.Vault.Team] $t = $null if ($vault.TryGetTeam($oid, [ref]$t)) { if ($PropertyName) { $mp = $t | Get-Member -MemberType Properties -Name $PropertyName if ($mp) { $t | Select-Object -ExpandProperty $PropertyName } } else { $t } continue } ensureAvalableLoaded [KeeperSecurity.Vault.TeamInfo] $teamInfo = $null $teamInfo = $Script:Context.AvailableTeams | Where-Object { $_.TeamUid -ceq $oid } | Select-Object -First 1 if ($teamInfo) { if ($PropertyName) { $mp = $teamInfo | Get-Member -MemberType Properties -Name $PropertyName if ($mp) { $teamInfo | Select-Object -ExpandProperty $PropertyName } } else { $teamInfo } continue } } } } } New-Alias -Name ko -Value Get-KeeperObject function parseKeeperPath { Param ( [string[]]$components, [KeeperSecurity.Vault.VaultOnline]$vault, [KeeperSecurity.Vault.FolderNode]$folder ) if ($components) { if (!$components[0]) { $folder = $vault.RootFolder $_, $components = $components } while ($components) { $resume = $false $component, $rest = $components if ($component -eq '..') { if ($folder.ParentUid) { $resume = $vault.TryGetFolder($folder.ParentUid, [ref]$folder) } else { $folder = $vault.RootFolder $resume = $true } } elseif (!$component -or $component -eq '.') { $resume = $true } else { foreach ($x in $folder.Subfolders) { [KeeperSecurity.Vault.FolderNode] $subfolder = $null if ($vault.TryGetFolder($x, [ref]$subfolder)) { if ($subfolder.Name -eq $component) { $resume = $true $folder = $subfolder break } } } } if ($resume) { $components = $rest } else { break } } $folder $components -join $Script:PathDelimiter } else { $folder $path } } function splitKeeperPath { Param ([string] $path) [bool]$isDelimiter = $false [string]$component = '' foreach ($x in $path.ToCharArray()) { if ($x -eq $Script:PathDelimiter) { if ($isDelimiter) { $component += $x $isDelimiter = $false } else { $isDelimiter = $true } } else { if ($isDelimiter) { $component $component = '' $isDelimiter = $false } $component += $x } } $component if ($isDelimiter) { '' } } function exportKeeperNode { Param ([KeeperSecurity.Vault.FolderNode] $folder) [PSCustomObject]@{ PSTypeName = 'KeeperSecurity.Commander.FolderInfo' FolderUid = $folder.FolderUid Path = getVaultFolderPath $vault $folder.FolderUid Name = $folder.Name ParentUid = $folder.ParentUid FolderType = $folder.FolderType } } function escapePathComponent { Param ([string] $component) $component = $component -replace '\\', '\\' $component = $component -replace '''', '''''' if ($component -match '[\s'']') { "'${component}'" } else { $component } } function getVaultFolderPath { Param ( [KeeperSecurity.Vault.VaultOnline]$vault, [string] $folderUid ) $comps = @() traverseFolderToRoot $vault $folderUid ([ref]$comps) $path = '' if ($comps) { [Array]::Reverse($comps) $comps += '' $path = ($comps | ForEach-Object { $_ -replace [Regex]::Escape($Script:PathDelimiter), "${Script:PathDelimiter}${Script:PathDelimiter}" }) -join $Script:PathDelimiter } "${Script:PathDelimiter}${path}" } function traverseFolderToRoot ([KeeperSecurity.Vault.VaultOnline]$vault, [string] $folderUid, [ref] $components) { if ($folderUid) { [KeeperSecurity.Vault.FolderNode]$folder = $null if ($vault.TryGetFolder($folderUid, [ref]$folder)) { $components.Value += $folder.Name traverseFolderToRoot $vault $folder.ParentUid $components } } } function Export-KeeperVault { <# .Synopsis Export vault data to a JSON file .Parameter FileName JSON export filename (will automatically add .json extension if not present) .Parameter Force Overwrite existing file without prompting .Parameter ExcludeSharedFolders Exclude shared folders from export .Description Exports all vault records and optionally shared folders to a JSON file. The JSON format is compatible with Keeper's import functionality. .Example Export-KeeperVault -FileName "vault_backup" Exports vault to "vault_backup.json" and prompts if file exists .Example Export-KeeperVault -FileName "vault.json" -Force Exports vault and overwrites existing file without prompting .Example Export-KeeperVault -FileName "records_only.json" -ExcludeSharedFolders Exports only records, excluding shared folders #> [CmdletBinding()] Param ( [Parameter(Mandatory = $true, Position = 0)] [string] $FileName, [Parameter(Mandatory = $false)] [switch] $Force, [Parameter(Mandatory = $false)] [switch] $ExcludeSharedFolders ) [KeeperSecurity.Vault.VaultOnline]$vault = getVault if (-not $FileName.EndsWith(".json", [StringComparison]::OrdinalIgnoreCase)) { $FileName += ".json" } if ((Test-Path $FileName) -and -not $Force) { $response = Read-Host "File `"$FileName`" already exists. Overwrite? (y/n)" if ($response -notmatch '^y(es)?$') { Write-Host "Export cancelled." return } } Write-Host "Exporting vault data..." $logger = [Action[KeeperSecurity.Vault.Severity, string]] { param($severity, $message) if ($severity -eq [KeeperSecurity.Vault.Severity]::Warning -or $severity -eq [KeeperSecurity.Vault.Severity]::Error) { Write-Host $message } Write-Debug $message } $includeSharedFolders = -not $ExcludeSharedFolders.IsPresent $jsonContent = [KeeperSecurity.Vault.KeeperExport]::ExportVaultToJson( $vault, $null, $includeSharedFolders, $logger ) $fullPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($FileName) $directory = [System.IO.Path]::GetDirectoryName($fullPath) if (-not [string]::IsNullOrEmpty($directory) -and -not (Test-Path $directory)) { New-Item -ItemType Directory -Path $directory -Force | Out-Null } [System.IO.File]::WriteAllText($fullPath, $jsonContent) Write-Debug "Exported to $fullPath" $fileInfo = Get-Item $fullPath $recordCount = ($vault.KeeperRecords | Where-Object { $_.Version -eq 2 -or $_.Version -eq 3 }).Count $sharedFolderCount = if ($ExcludeSharedFolders) { 0 } else { $vault.SharedFolders.Count } Write-Host "" Write-Host "Export Summary:" Write-Host " Records Exported: $recordCount" if (-not $ExcludeSharedFolders) { Write-Host " Shared Folders: $sharedFolderCount" } Write-Host " File Size: $($fileInfo.Length.ToString('N0')) bytes" Write-Host " Output File: $fullPath" Write-Host "" Write-Host "Export completed successfully." -ForegroundColor Green } New-Alias -Name kexport -Value Export-KeeperVault # SIG # Begin signature block # MIInvgYJKoZIhvcNAQcCoIInrzCCJ6sCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCASikw5lZnTm09Z # tnaQx7U3SHjvSSrX5ceLk9AqRwFrc6CCITswggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0GCSqG # SIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTlaMGkx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4 # RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEzODQg # MjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C0Cit # eLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce2vnS # 1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0daE6ZM # swEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6TSXBC # Mo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoAFdE3 # /hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7OhD26j # q22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM1bL5 # OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z8ujo # 7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05huzU # tw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNYmtwm # KwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP/2NP # TLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0TAQH/ # BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYDVR0j # BBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1Ud # JQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0 # cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0 # cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8E # PDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz # dGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATANBgkq # hkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95RysQDK # r2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HLIvda # qpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5BtfQ/g+ # lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnhOE7a # brs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIhdXNS # y0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV9zeK # iwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/jwVYb # KyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYHKi8Q # xAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmCXBVm # zGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l/aCn # HwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZWeE4w # gga0MIIEnKADAgECAhANx6xXBf8hmS5AQyIMOkmGMA0GCSqGSIb3DQEBCwUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDAeFw0yNTA1MDcwMDAwMDBaFw0zODAxMTQyMzU5NTlaMGkxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1 # c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC0eDHTCphBcr48RsAcrHXbo0Zo # dLRRF51NrY0NlLWZloMsVO1DahGPNRcybEKq+RuwOnPhof6pvF4uGjwjqNjfEvUi # 6wuim5bap+0lgloM2zX4kftn5B1IpYzTqpyFQ/4Bt0mAxAHeHYNnQxqXmRinvuNg # xVBdJkf77S2uPoCj7GH8BLuxBG5AvftBdsOECS1UkxBvMgEdgkFiDNYiOTx4OtiF # cMSkqTtF2hfQz3zQSku2Ws3IfDReb6e3mmdglTcaarps0wjUjsZvkgFkriK9tUKJ # m/s80FiocSk1VYLZlDwFt+cVFBURJg6zMUjZa/zbCclF83bRVFLeGkuAhHiGPMvS # GmhgaTzVyhYn4p0+8y9oHRaQT/aofEnS5xLrfxnGpTXiUOeSLsJygoLPp66bkDX1 # ZlAeSpQl92QOMeRxykvq6gbylsXQskBBBnGy3tW/AMOMCZIVNSaz7BX8VtYGqLt9 # MmeOreGPRdtBx3yGOP+rx3rKWDEJlIqLXvJWnY0v5ydPpOjL6s36czwzsucuoKs7 # Yk/ehb//Wx+5kMqIMRvUBDx6z1ev+7psNOdgJMoiwOrUG2ZdSoQbU2rMkpLiQ6bG # RinZbI4OLu9BMIFm1UUl9VnePs6BaaeEWvjJSjNm2qA+sdFUeEY0qVjPKOWug/G6 # X5uAiynM7Bu2ayBjUwIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAd # BgNVHQ4EFgQU729TSunkBnx6yuKQVvYv1Ensy04wHwYDVR0jBBgwFoAU7NfjgtJx # XWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUF # BwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln # aWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJo # dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy # bDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQEL # BQADggIBABfO+xaAHP4HPRF2cTC9vgvItTSmf83Qh8WIGjB/T8ObXAZz8OjuhUxj # aaFdleMM0lBryPTQM2qEJPe36zwbSI/mS83afsl3YTj+IQhQE7jU/kXjjytJgnn0 # hvrV6hqWGd3rLAUt6vJy9lMDPjTLxLgXf9r5nWMQwr8Myb9rEVKChHyfpzee5kH0 # F8HABBgr0UdqirZ7bowe9Vj2AIMD8liyrukZ2iA/wdG2th9y1IsA0QF8dTXqvcnT # mpfeQh35k5zOCPmSNq1UH410ANVko43+Cdmu4y81hjajV/gxdEkMx1NKU4uHQcKf # ZxAvBAKqMVuqte69M9J6A47OvgRaPs+2ykgcGV00TYr2Lr3ty9qIijanrUR3anzE # wlvzZiiyfTPjLbnFRsjsYg39OlV8cipDoq7+qNNjqFzeGxcytL5TTLL4ZaoBdqbh # OhZ3ZRDUphPvSRmMThi0vw9vODRzW6AxnJll38F0cuJG7uEBYTptMSbhdhGQDpOX # gpIUsWTjd6xpR6oaQf/DJbg3s6KCLPAlZ66RzIg9sC+NJpud/v4+7RWsWCiKi9EO # LLHfMR2ZyJ/+xhCx9yHbxtl5TPau1j/1MIDpMPx0LckTetiSuEtQvLsNz3Qbp7wG # WqbIiOWCnb5WqxL3/BAPvIXKUjPSxyZsq8WhbaM2tszWkPZPubdcMIIG7TCCBNWg # AwIBAgIQCoDvGEuN8QWC0cR2p5V0aDANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQG # EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0 # IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0Ex # MB4XDTI1MDYwNDAwMDAwMFoXDTM2MDkwMzIzNTk1OVowYzELMAkGA1UEBhMCVVMx # FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBTSEEy # NTYgUlNBNDA5NiBUaW1lc3RhbXAgUmVzcG9uZGVyIDIwMjUgMTCCAiIwDQYJKoZI # hvcNAQEBBQADggIPADCCAgoCggIBANBGrC0Sxp7Q6q5gVrMrV7pvUf+GcAoB38o3 # zBlCMGMyqJnfFNZx+wvA69HFTBdwbHwBSOeLpvPnZ8ZN+vo8dE2/pPvOx/Vj8Tch # TySA2R4QKpVD7dvNZh6wW2R6kSu9RJt/4QhguSssp3qome7MrxVyfQO9sMx6ZAWj # FDYOzDi8SOhPUWlLnh00Cll8pjrUcCV3K3E0zz09ldQ//nBZZREr4h/GI6Dxb2Uo # yrN0ijtUDVHRXdmncOOMA3CoB/iUSROUINDT98oksouTMYFOnHoRh6+86Ltc5zjP # KHW5KqCvpSduSwhwUmotuQhcg9tw2YD3w6ySSSu+3qU8DD+nigNJFmt6LAHvH3KS # uNLoZLc1Hf2JNMVL4Q1OpbybpMe46YceNA0LfNsnqcnpJeItK/DhKbPxTTuGoX7w # JNdoRORVbPR1VVnDuSeHVZlc4seAO+6d2sC26/PQPdP51ho1zBp+xUIZkpSFA8vW # doUoHLWnqWU3dCCyFG1roSrgHjSHlq8xymLnjCbSLZ49kPmk8iyyizNDIXj//cOg # rY7rlRyTlaCCfw7aSUROwnu7zER6EaJ+AliL7ojTdS5PWPsWeupWs7NpChUk555K # 096V1hE0yZIXe+giAwW00aHzrDchIc2bQhpp0IoKRR7YufAkprxMiXAJQ1XCmnCf # gPf8+3mnAgMBAAGjggGVMIIBkTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTkO/zy # Me39/dfzkXFjGVBDz2GM6DAfBgNVHSMEGDAWgBTvb1NK6eQGfHrK4pBW9i/USezL # TjAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwgZUGCCsG # AQUFBwEBBIGIMIGFMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j # b20wXQYIKwYBBQUHMAKGUWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRHNFRpbWVTdGFtcGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNy # dDBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBpbmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5j # cmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEB # CwUAA4ICAQBlKq3xHCcEua5gQezRCESeY0ByIfjk9iJP2zWLpQq1b4URGnwWBdEZ # D9gBq9fNaNmFj6Eh8/YmRDfxT7C0k8FUFqNh+tshgb4O6Lgjg8K8elC4+oWCqnU/ # ML9lFfim8/9yJmZSe2F8AQ/UdKFOtj7YMTmqPO9mzskgiC3QYIUP2S3HQvHG1FDu # +WUqW4daIqToXFE/JQ/EABgfZXLWU0ziTN6R3ygQBHMUBaB5bdrPbF6MRYs03h4o # bEMnxYOX8VBRKe1uNnzQVTeLni2nHkX/QqvXnNb+YkDFkxUGtMTaiLR9wjxUxu2h # ECZpqyU1d0IbX6Wq8/gVutDojBIFeRlqAcuEVT0cKsb+zJNEsuEB7O7/cuvTQasn # M9AWcIQfVjnzrvwiCZ85EE8LUkqRhoS3Y50OHgaY7T/lwd6UArb+BOVAkg2oOvol # /DJgddJ35XTxfUlQ+8Hggt8l2Yv7roancJIFcbojBcxlRcGG0LIhp6GvReQGgMgY # xQbV1S3CrWqZzBt1R9xJgKf47CdxVRd/ndUlQ05oxYy2zRWVFjF7mcr4C34Mj3oc # CVccAvlKV9jEnstrniLvUxxVZE/rptb7IRE2lskKPIJgbaP5t2nGj/ULLi49xTcB # ZU8atufk+EMF/cWuiC7POGT75qaL6vdCvHlshtjdNXOCIUjsarfNZzCCB0kwggUx # oAMCAQICEAe0P3SLJmcoVNrErUyxTt0wDQYJKoZIhvcNAQELBQAwaTELMAkGA1UE # BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2Vy # dCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENB # MTAeFw0yNTEyMzEwMDAwMDBaFw0yOTAxMDIyMzU5NTlaMIHRMRMwEQYLKwYBBAGC # NzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMR0wGwYDVQQPDBRQ # cml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UEBRMHMzQwNzk4NTELMAkGA1UEBhMC # VVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQHEwdDaGljYWdvMR0wGwYDVQQK # ExRLZWVwZXIgU2VjdXJpdHkgSW5jLjEdMBsGA1UEAxMUS2VlcGVyIFNlY3VyaXR5 # IEluYy4wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCUcNMoSVmxAi0a # vG+StFJMNFFTUIOo3HdBZ+0gqA1XpNgUx11vB1vCZrvFsD9m5oA58tdp4gZN3LmQ # aMvCl2ANUT7MilI02Hf1RWlygBzon6iE0GpU3lgRrwrk1dhtLpGsR6dbMKUUHprc # vKpXk90/VN+vhzY1uik1tCTxkDCPu/AYJg7m9+tR2KqvMuYMaMLhii66eWUAGsBC # h/uZxjkGoJF6qZ0DgFd7rW7VYljbfYSNPeZNGTDgB0J/wOsKl0mn612DTseIvAKt # 4vra/FLFukyEyStnfQ8lWYDcLLCMCjNVrzGipmT5E2iyx7Y1RZCIpNwVogp3Ixbk # Gbq5A/41YNOLLd4cFewyB2F037RevBCRsUODZEt1qBf7Jbu3DiYo1G+zTj9E0R1s # FzyijcfdsTm6X5ble+yCJeGkX5XgsyPnZpyz/FX9Fr0N9pMPGWwW2PKyHEnSytXm # 0Dxdq2P4mA4CBUxq7YoV26L2PF6QEh9BQdXTPcnLysUv7SI/a0ECAwEAAaOCAgIw # ggH+MB8GA1UdIwQYMBaAFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB0GA1UdDgQWBBRG # 4H6CH8pvNX632bsdnrda4MtJLDA9BgNVHSAENjA0MDIGBWeBDAEDMCkwJwYIKwYB # BQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMC # B4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCBqjBToFGgT4ZNaHR0 # cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25p # bmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0dHA6Ly9jcmw0LmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI # QTM4NDIwMjFDQTEuY3JsMIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JT # QTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUA # A4ICAQA1Wlq0WzJa3N6DgjgBU7nagIJBab1prPARXZreX1MOv9VjnS5o0CrfQLr6 # z3bmWHw7xT8dt6bcSwRixqvPJtv4q8Rvo80O3eUMvMxQzqmi7z1zf+HG+/3G4F+2 # IYegvPc8Ui151XCV9rjA8tvFWRLRMX0ZRxY1zfT027HMw0iYL20z44+Cky//FAnL # iRwoNDGiRkZiHbB9YOftPAYNMG3gm1z3zOW5RdfKPrqvMuijE+dfyLIAA6Immpzu # FMH+Wgn8NnSlot9b4YKycaqqdjd7wXDjPub/oQ7VShuCSBWj+UNOTVh0vcZGackc # H1DLVgwp2dcKlxJiQKtkHT/T6LloY6LTe6+8wkVkr8EAv1W+q/+M1a4Ao+ykFbIA # 2LBEmA9qdgoLtenAYIiEg+48SjMPgyBbVPE3bhL1vIqjEIxYCfdmi6wx33oYX7HB # +bJ7zitHw4GgtpfPV8y8QRZImKmeDOKyXjQPDmQM/Eglm/Ns0GzBkVXM8h6UI34b # WZrHz9sbLSE20m5Svmxftvw5zju+I3WsmS/stNfWlOkwU0niUgwPHaz21kjXEA5A # g+aqv26wodqZcnGOlChoWDvSJ8KKgdOFbeAYKAMp1NY7iWV315zpGH19RipCR1NH # 0ND8iIubk3WGNf2rzEfqlOi3h2ywqVkU6AKXHdO5JV4otSKKEDGCBdkwggXVAgEB # MH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYD # VQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2IFNI # QTM4NCAyMDIxIENBMQIQB7Q/dIsmZyhU2sStTLFO3TANBglghkgBZQMEAgEFAKCB # hDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEE # AYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJ # BDEiBCCkZeVYj+oOVm+37SKqRpSsF0sNZykblA97Vl/f6r0iJjANBgkqhkiG9w0B # AQEFAASCAYBbIGdLtvw4ey4JJKPUR5QUd6gjXqauBPlb/h6HkPNBRH/Are9CqUiv # 1Z7zPOY01BsqPrXlY3z4b7Hw9816rGzK+zbu0N8D3dVGiBJAQiT5vrO82X5W2JBm # X1/kAl6jnMiKzfuDc2g5So7iEFhCd6XmcHEILN7r2FhQI8pv9RNQ5hrTsYPcbvHj # mcBzDFNrS9W/cWeiFw7f8XvQddgTTvCUtNbtsIuC2AKLajc1jMbhjoJnBcP5eAA9 # jivF8D8BsXEkXohlMKuTC6B1kWQrJ8D2ikPdd2cFPUkrp2567u+EJrVPBJcEmR2V # X3jwaF5+jriJL1qIxhqTS7YgJi72wl/at/0Q6ZZ//XYIc5qaoAn+6uMwKCXqY/fP # vxuuAfVobu33BPUFbpQV/sEE9Zm6sfWl6EhqE0ciMnIskiTfwFJJHN5ga5v4AI5i # bPnjh2JwbnKjiV8tPlwHFxHxy7XoMrX3KHspCULLO+afkZJUPnh5Nc156c+rhwt+ # DE/v9HB5VSWhggMmMIIDIgYJKoZIhvcNAQkGMYIDEzCCAw8CAQEwfTBpMQswCQYD # VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lD # ZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUg # Q0ExAhAKgO8YS43xBYLRxHanlXRoMA0GCWCGSAFlAwQCAQUAoGkwGAYJKoZIhvcN # AQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjYwMTIzMjMzOTI4WjAv # BgkqhkiG9w0BCQQxIgQgSCcdOAgn8A353djsSRZzFg3vLM1bIAGsAyC9VoVQ77kw # DQYJKoZIhvcNAQEBBQAEggIAoH7mxXXZUe4Bi4M2bp/aOe7Rq7l9dEbbDlnlkTw9 # JdG8hqR4ZWx2cx4iGKQCrPWNSskaRvyPo1O8rX4I8PwcUytgAuY2jQY7D0Pz4Sde # /1r7pFIltLJD0oAcNpniQ8iV3b1SKwcN6O0YVSMtRDr+NSc/YDjpN641lGPwiYRE # WrX4VGlsODoFf3etOpHuOr7oh5aLU0iJdNwPRFJHc0EIahoMtFeqOq33H6cAXj/T # Pb44CB1YlWEBSXj0Hs/Qa7XUb9NKblTSj3cZ6Z3ZXIXwJ1tZamcIgjUBtpVu20iu # 3yMLcOOM3ttq1Wu7WBb3IygFAkbc0dy1cy/woQUxAfaKUMCie5JyeqmedV+3egD0 # C1Z+RvSQnBKu5dU37ezx2JY+UijJFA3Lgn6pF6jWfx3GGl6WNmhXQSWkPaYWhvS5 # Bw1mCpINKXD+W1ZlC5sKcn6Mq4ZIvmxoUJQaaZ6rgJIr6TQK92We/zvmebLRrvfi # HHXWmjyT1ww8uYL4MdBEZm7c8hymTDTUEAV+9EJsZ3mqvrDnRipclQOxoUhdzscR # gpDVfTMdna3sbqims5xyK4lvPeZkUrVn2DjRZjlZglponRT4qJ/n0xPRxY8r5Z5Y # 9xSWwCOW9Xzkmuy/PvEDccAztliAXD9OiWiUcWjWGTZdbS/B16wdYlrQcv0Lxsku # SmA= # SIG # End signature block |