PsDaVinci.psm1
# Copyright (c) STÜBER SYSTEMS GmbH. All rights reserved. # Licensed under the MIT License. Import-LocalizedData -BindingVariable stringTable <# .Synopsis Creates a new JSON configuration template for the 'Start-DaVinciImport' cmdlet .Description This cmdlet will create a new JSON configuration file for an import source. If the JSON file exists already it will add the configuration to the file. You must adapt the configuration to your needs by opening the configuration file in a text editor. .Parameter Source The name of a supported import source. Currently supported is 'ecf'. .Parameter ConfigFile The file name of the JSON configuration file. If this file exists already this cmdlet will terminate with an error. .Example # Adds a configuration template for an ECF to DAVINCI import Initialize-DaVinciImport -Source ecf -ConfigFile MyImportConfig.json .Example # Adds a configuration template for an ECF to DAVINCI import (short form) Initialize-DaVinciImport ecf MyImportConfig.json #> function Initialize-DaVinciImport { param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [ImportSource] $Source, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $ConfigFile ) process { try { $ConfigPath = GetFullConfigPath -ConfigFile $ConfigFile switch ($Source) { ([ImportSource]::ecf) { CreateOrPopulateConfigFile -JsonProviderName "daVinci" -JsonConfigName "EcfImport" -ConfigTemplateName "import" -ConfigPath $ConfigPath } } } catch { $ErrorMessage = $_.Exception.Message Write-Error $ErrorMessage } } } <# .Synopsis Creates a new JSON configuration template for the 'Start-DaVinciExport' cmdlet .Description This cmdlet will create a new JSON configuration file for an export target. If the JSON file exists already it will add the configuration to the file. You must adapt the configuration to your needs by opening the configuration file in a text editor. .Parameter Target The name of a supported export target. Currently supported are 'sdui', 'iserv' and 'ecf'. .Parameter ConfigFile The file name of the JSON configuration file. If this file exists already this cmdlet will terminate with an error. .Example # Adds a configuration template for a DAVINCI to ECF export Initialize-DaVinciExport -Target ecf -ConfigFile MyExportConfig.json .Example # Adds a configuration template for a DAVINCI to ECF export (short from) Initialize-DaVinciExport ecf MyExportConfig.json #> function Initialize-DaVinciExport { param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [ExportTarget] $Target, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $ConfigFile ) process { try { $ConfigPath = GetFullConfigPath -ConfigFile $ConfigFile switch ($Target) { ([ExportTarget]::sdui) { CreateOrPopulateConfigFile -JsonProviderName "daVinci" -JsonConfigName "SduiExport" -ConfigTemplateName "export" -ConfigPath $ConfigPath } ([ExportTarget]::iserv) { CreateOrPopulateConfigFile -JsonProviderName "daVinci" -JsonConfigName "IServExport" -ConfigTemplateName "export" -ConfigPath $ConfigPath } ([ExportTarget]::ecf) { CreateOrPopulateConfigFile -JsonProviderName "daVinci" -JsonConfigName "EcfExport" -ConfigTemplateName "export" -ConfigPath $ConfigPath } } } catch { $ErrorMessage = $_.Exception.Message Write-Error $ErrorMessage } } } <# .Synopsis Starts a new import from a supported source to DAVINCI. .Description This cmdlet will start a new import from a supported source to DAVINCI. .Parameter Source The name of a supported import source. Currently supported is 'ecf'. .Parameter ConfigFile The file name of the JSON configuration file. .Example # Starts an import from ECF to DAVINCI Start-DaVinciImport -Source ecf -ConfigFile MyImportConfig.json .Example # Starts an import from ECF to DAVINCI (short form) Start-DaVinciImport ecf MyImportConfig.json #> function Start-DaVinciImport { param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [ImportSource] $Source, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $ConfigFile ) process { try { $ConfigPath = GetFullConfigPath -ConfigFile $ConfigFile $Config = GetConfig -Config $ConfigPath switch ($Source) { ([ImportSource]::ecf) { RunDavConsole -Command "export" -Provider "ecf" -Config $Config } } } catch { $ErrorMessage = $_.Exception.Message Write-Error $ErrorMessage } } } <# .Synopsis Starts a new export from DAVINCI to a supported target. .Description This cmdlet will start a new export from DAVINCI to a supported target. .Parameter Target The name of a supported export target. Currently supported are 'sdui', 'iserv' and 'ecf'. .Parameter ConfigFile The file name of the JSON configuration file. .Example # Starts an export from DAVINCI to Ecf Start-DaVinciExport -Target ecf -ConfigFile MyExportConfig.json .Example # Starts an export from DAVINCI to Ecf (short form) Start-DaVinciExport ecf MyExportConfig.json #> function Start-DaVinciExport { param( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [ExportTarget] $Target, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $ConfigFile ) process { try { $ConfigPath = GetFullConfigPath -ConfigFile $ConfigFile $Config = GetConfig -Config $ConfigPath switch ($Target) { ([ExportTarget]::sdui) { RunDavConsole -Command "export" -Provider "sdui" -Config $Config } ([ExportTarget]::iserv) { RunDavConsole -Command "export" -Provider "iserv" -Config $Config } ([ExportTarget]::ecf) { RunDavConsole -Command "export" -Provider "ecf" -Config $Config } } } catch { $ErrorMessage = $_.Exception.Message Write-Error $ErrorMessage } } } function CreateOrPopulateConfigFile { param( [string] $ConfigPath, [string] $ConfigTemplateName, [string] $JsonProviderName, [string] $JsonConfigName ) process { $ConfigTemplatePath = GetConfigTemplatePath -TemplateName $ConfigTemplateName $ConfigTemplate = Get-Content -Raw -Path $ConfigTemplatePath | ConvertFrom-Json foreach ($property in $ConfigTemplate.daVinci.PSObject.Properties) { if ($property.Name -ne $JsonConfigName) { $ConfigTemplate.daVinci.PSObject.Properties.Remove($property.Name) } } if (Test-Path -Path $ConfigPath) { $Config = Get-Content -Raw -Path $ConfigPath | ConvertFrom-Json if ($Config | Get-Member -Name $JsonProviderName -MemberType NoteProperty) { if ($null -ne $Config.daVinci) { if (-not ($Config.daVinci | Get-Member -Name $JsonConfigName -MemberType NoteProperty)) { $ConfigPropertyValue = $ConfigTemplate.daVinci | Select-Object -ExpandProperty $JsonConfigName $Config.daVinci | Add-Member -MemberType NoteProperty -Name $JsonConfigName -Value $ConfigPropertyValue } } } else { $Config | Add-Member -MemberType NoteProperty -Name $JsonProviderName -Value $ConfigTemplate.daVinci } } else { $Config = $ConfigTemplate } $Config | ConvertTo-Json -depth 100 | Set-Content $ConfigPath } } function RunDavConsole{ param( [string] $Command, [string] $Provider, [PSObject] $Config ) process { Write-Host $stringTable.StartDaVinciConsole -ForegroundColor $Host.PrivateData.VerboseForegroundColor $ConsolePath = GetDavConsolePath -Config $Config if (($ConsolePath) -and (Test-Path -Path $ConsolePath -PathType Leaf)) { $CurrentLocation = Get-Location Set-Location -Path (Split-Path -Path $ConfigPath) try { Invoke-Expression "& ""$($consolePath)"" $($Command) -p ""$($Provider)"" -c ""$($ConfigPath)""" } finally { Set-Location -Path $CurrentLocation } if ($LASTEXITCODE -ne 0) { $ErrorMessage = $stringTable.ErrorDaVinciConsoleFailed throw $ErrorMessage } } else { $ErrorMessage = ([string]::Format($stringTable.ErrorDaVinciConsoleNotFound, $ConsolePath)) throw $ErrorMessage } } } function GetConfig { param( [string] $ConfigPath ) process { if (($ConfigPath) -and (Test-Path -Path $ConfigPath -PathType leaf)) { return Get-Content -Path $ConfigPath -Raw | ConvertFrom-Json } else { return "{}" | ConvertFrom-Json } } } function GetConfigTemplatePath { param( [string] $TemplateName ) process { return Join-Path -Path $PSScriptRoot -ChildPath "PsDaVinci.Template.$($TemplateName).json" } } function GetFullConfigPath { param( [string] $ConfigFile ) process { $ConfigPath = $ConfigFile if ((Split-Path -Path $ConfigPath -Leaf) -eq $ConfigPath) { $ConfigPath = Join-Path -Path (Get-Location) -ChildPath $ConfigPath } if (-not (Test-Path -Path $ConfigPath -PathType Leaf)) { if (-not ([IO.Path]::HasExtension($ConfigPath))) { $ConfigPath = [IO.Path]::ChangeExtension($ConfigPath, "json") } } return $ConfigPath } } function GetDavConsolePath { param( [PSObject] $Config ) process { if ($Config) { if ($Config.PsDaVinci.Tools.DaVinciConsole) { return $config.PsDaVinci.Tools.DaVinciConsole } } $RegKey64 = "HKLM:\SOFTWARE\WOW6432Node\Stueber Systems\daVinci 6\Main" $RegKey32 = "HKLM:\SOFTWARE\Stueber Systems\daVinci 6\Main" if ([Environment]::Is64BitProcess) { if (Test-Path -Path $RegKey64) { $RegKey = Get-ItemProperty -Path $RegKey64 -Name BinFolder return Join-Path -Path $RegKey.BinFolder -ChildPath "daVinciConsole.exe" } else { return $null } } else { if (Test-Path -Path $RegKey32) { $RegKey = Get-ItemProperty -Path $RegKey32 -Name BinFolder return Join-Path -Path $RegKey.BinFolder -ChildPath "daVinciConsole.exe" } else { return $null } } } } # List of supported import sources Enum ImportSource { ecf } # List of supported export targets Enum ExportTarget { sdui iserv ecf } Export-ModuleMember -Function Initialize-DaVinciImport Export-ModuleMember -Function Initialize-DaVinciExport Export-ModuleMember -Function Start-DaVinciImport Export-ModuleMember -Function Start-DaVinciExport # SIG # Begin signature block # MIIZbAYJKoZIhvcNAQcCoIIZXTCCGVkCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUWNp1xWtFSk3662NiZC1rSm+m # vymgghRtMIIE1TCCA72gAwIBAgIQLv6kF6bmtV9boNbBVSrC5TANBgkqhkiG9w0B # AQsFADB/MQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRp # b24xHzAdBgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxMDAuBgNVBAMTJ1N5 # bWFudGVjIENsYXNzIDMgU0hBMjU2IENvZGUgU2lnbmluZyBDQTAeFw0xOTA4MDYw # MDAwMDBaFw0yMTEwMTUyMzU5NTlaMG0xCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZC # ZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEdMBsGA1UECgwUU1RVRUJFUiBTWVNURU1T # IEdtYkgxHTAbBgNVBAMMFFNUVUVCRVIgU1lTVEVNUyBHbWJIMIIBIjANBgkqhkiG # 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzaRIVaSkAMSQj+/zPkMRDRo7TwC80M3tt/nX # uuPnfQNEilBRgRUj5lJ6AAxam4ayXCf38v371FOQ/IJpFSEU++H+LhCIpiCrjlY2 # m36N34SLUqgxjuFjBPj3gDUN8tATX3Svg0VGe8giXXo2aUYpPESSPfWblr3wmDU4 # eQ/Y6G6QqCAd3O9cqJo5Asp4x04mbo15nkaV0hyD0Bch/I5d6Wgirkirr5K/sC4q # ZQPH5BDnQ4p3JlnOqL76sCqjgiToMn7KRMNblYcqAbRvDjTucq4dwGbthOEfWjGQ # qJcgr8hbZgXxHKhoQwDjuB4KStbsAELIE0Ul2cYkXH93e/PzIQIDAQABo4IBXTCC # AVkwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwKwYDVR0fBCQwIjAgoB6gHIYa # aHR0cDovL3N2LnN5bWNiLmNvbS9zdi5jcmwwYQYDVR0gBFowWDBWBgZngQwBBAEw # TDAjBggrBgEFBQcCARYXaHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUH # AgIwGQwXaHR0cHM6Ly9kLnN5bWNiLmNvbS9ycGEwEwYDVR0lBAwwCgYIKwYBBQUH # AwMwVwYIKwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNodHRwOi8vc3Yuc3ltY2Qu # Y29tMCYGCCsGAQUFBzAChhpodHRwOi8vc3Yuc3ltY2IuY29tL3N2LmNydDAfBgNV # HSMEGDAWgBSWO1PweTOXr32D7y4rzMq3hh5yZjAdBgNVHQ4EFgQUYz6hg49VBlOi # YvOJKjgcMVfwTbkwDQYJKoZIhvcNAQELBQADggEBAJN+Vhe4Abpf8Wh//vApKk1o # BxJP5cp92phKg9lYyVpxf2aw1oiEp7X9z1Ihgdc6zkR2pP8fYrFU/fYu0aXapGMR # qf/3RwjYuBKGxB5U0jGAxHMtV+owcchQZcd12Td7BTwm0o848i0zGZu6+48bIfeZ # Ot+qoxldwQQrYQyn1+4PE7IfP03KkCX7+wJ4aOyWXvN8wUINvSswuecnVFi/MKSS # fhE4OydQcY93fYIhLGimh3TAVdTTfWN8OSfy+TOVAvC4FoHBM54sWzfU1Nr35EK+ # RuJbgcNIFaRBC2MkBH42Nh5g7PQDUo8aXMP9s00sY1oSOmhbXLbkQNxjMI8MDPsw # ggT+MIID5qADAgECAhANQkrgvjqI/2BAIc4UAPDdMA0GCSqGSIb3DQEBCwUAMHIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ # RCBUaW1lc3RhbXBpbmcgQ0EwHhcNMjEwMTAxMDAwMDAwWhcNMzEwMTA2MDAwMDAw # WjBIMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xIDAeBgNV # BAMTF0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIxMIIBIjANBgkqhkiG9w0BAQEFAAOC # AQ8AMIIBCgKCAQEAwuZhhGfFivUNCKRFymNrUdc6EUK9CnV1TZS0DFC1JhD+Hchv # kWsMlucaXEjvROW/m2HNFZFiWrj/ZwucY/02aoH6KfjdK3CF3gIY83htvH35x20J # Pb5qdofpir34hF0edsnkxnZ2OlPR0dNaNo/Go+EvGzq3YdZz7E5tM4p8XUUtS7FQ # 5kE6N1aG3JMjjfdQJehk5t3Tjy9XtYcg6w6OLNUj2vRNeEbjA4MxKUpcDDGKSoyI # xfcwWvkUrxVfbENJCf0mI1P2jWPoGqtbsR0wwptpgrTb/FZUvB+hh6u+elsKIC9L # CcmVp42y+tZji06lchzun3oBc/gZ1v4NSYS9AQIDAQABo4IBuDCCAbQwDgYDVR0P # AQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgw # QQYDVR0gBDowODA2BglghkgBhv1sBwEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3 # dy5kaWdpY2VydC5jb20vQ1BTMB8GA1UdIwQYMBaAFPS24SAd/imu0uRhpbKiJbLI # FzVuMB0GA1UdDgQWBBQ2RIaOpLqwZr68KC0dRDbd42p6vDBxBgNVHR8EajBoMDKg # MKAuhixodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLXRzLmNy # bDAyoDCgLoYsaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC10 # cy5jcmwwgYUGCCsGAQUFBwEBBHkwdzAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au # ZGlnaWNlcnQuY29tME8GCCsGAQUFBzAChkNodHRwOi8vY2FjZXJ0cy5kaWdpY2Vy # dC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElEVGltZXN0YW1waW5nQ0EuY3J0MA0G # CSqGSIb3DQEBCwUAA4IBAQBIHNy16ZojvOca5yAOjmdG/UJyUXQKI0ejq5LSJcRw # Wb4UoOUngaVNFBUZB3nw0QTDhtk7vf5EAmZN7WmkD/a4cM9i6PVRSnh5Nnont/Pn # Up+Tp+1DnnvntN1BIon7h6JGA0789P63ZHdjXyNSaYOC+hpT7ZDMjaEXcw3082U5 # cEvznNZ6e9oMvD0y0BvL9WH8dQgAdryBDvjA4VzPxBFy5xtkSdgimnUVQvUtMjiB # 2vRgorq0Uvtc4GEkJU+y38kpqHNDUdq9Y9YfW5v3LhtPEx33Sg1xfpe39D+E68Hj # o0mh+s6nv1bPull2YYlffqe0jmd4+TaY4cso2luHpoovMIIFMTCCBBmgAwIBAgIQ # CqEl1tYyG35B5AXaNpfCFTANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJVUzEV # MBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t # MSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMTYwMTA3 # MTIwMDAwWhcNMzEwMTA3MTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM # RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQD # EyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBMIIBIjAN # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdAy7kvNj3/dqbqCmcU5VChXtiNK # xA4HRTNREH3Q+X1NaH7ntqD0jbOI5Je/YyGQmL8TvFfTw+F+CNZqFAA49y4eO+7M # pvYyWf5fZT/gm+vjRkcGGlV+Cyd+wKL1oODeIj8O/36V+/OjuiI+GKwR5PCZA207 # hXwJ0+5dyJoLVOOoCXFr4M8iEA91z3FyTgqt30A6XLdR4aF5FMZNJCMwXbzsPGBq # rC8HzP3w6kfZiFBe/WZuVmEnKYmEUeaC50ZQ/ZQqLKfkdT66mA+Ef58xFNat1fJk # y3seBdCEGXIX8RcG7z3N1k3vBkL9olMqT4UdxB08r8/arBD13ays6Vb/kwIDAQAB # o4IBzjCCAcowHQYDVR0OBBYEFPS24SAd/imu0uRhpbKiJbLIFzVuMB8GA1UdIwQY # MBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD # VR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHkGCCsGAQUFBwEBBG0w # azAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUF # BzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk # SURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdp # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRw # Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3Js # MFAGA1UdIARJMEcwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczov # L3d3dy5kaWdpY2VydC5jb20vQ1BTMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsF # AAOCAQEAcZUS6VGHVmnN793afKpjerN4zwY3QITvS4S/ys8DAv3Fp8MOIEIsr3fz # Kx8MIVoqtwU0HWqumfgnoma/Capg33akOpMP+LLR2HwZYuhegiUexLoceywh4tZb # LBQ1QwRostt1AuByx5jWPGTlH0gQGF+JOGFNYkYkh2OMkVIsrymJ5Xgf1gsUpYDX # Ekdws3XVk4WTfraSZ/tTYYmo9WuWwPRYaQ18yAGxuSh1t5ljhSKMYcp5lH5Z/IwP # 42+1ASa2bKXuh1Eh5Fhgm7oMLSttosR+u8QlK0cCCHxJrhO24XxCQijGGFbPQTS2 # Zl22dHv1VjMiLyI2skuiSpXY9aaOUjCCBVkwggRBoAMCAQICED141/l2SWCyYX30 # 8B7KhiowDQYJKoZIhvcNAQELBQAwgcoxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5W # ZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazE6 # MDgGA1UECxMxKGMpIDIwMDYgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXpl # ZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMyBQdWJsaWMgUHJp # bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc1MB4XDTEzMTIxMDAwMDAw # MFoXDTIzMTIwOTIzNTk1OVowfzELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFu # dGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3Jr # MTAwLgYDVQQDEydTeW1hbnRlYyBDbGFzcyAzIFNIQTI1NiBDb2RlIFNpZ25pbmcg # Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCXgx4AFq8ssdIIxNdo # k1FgHnH24ke021hNI2JqtL9aG1H3ow0Yd2i72DarLyFQ2p7z518nTgvCl8gJcJOp # 2lwNTqQNkaC07BTOkXJULs6j20TpUhs/QTzKSuSqwOg5q1PMIdDMz3+b5sLMWGqC # Fe49Ns8cxZcHJI7xe74xLT1u3LWZQp9LYZVfHHDuF33bi+VhiXjHaBuvEXgamK7E # VUdT2bMy1qEORkDFl5KK0VOnmVuFNVfT6pNiYSAKxzB3JBFNYoO2untogjHuZcrf # +dWNsjXcjCtvanJcYISc8gyUXsBWUgBIzNP4pX3eL9cT5DiohNVGuBOGwhud6lo4 # 3ZvbAgMBAAGjggGDMIIBfzAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0 # dHA6Ly9zMi5zeW1jYi5jb20wEgYDVR0TAQH/BAgwBgEB/wIBADBsBgNVHSAEZTBj # MGEGC2CGSAGG+EUBBxcDMFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0 # aC5jb20vY3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20v # cnBhMDAGA1UdHwQpMCcwJaAjoCGGH2h0dHA6Ly9zMS5zeW1jYi5jb20vcGNhMy1n # NS5jcmwwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMDMA4GA1UdDwEB/wQE # AwIBBjApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01Njcw # HQYDVR0OBBYEFJY7U/B5M5evfYPvLivMyreGHnJmMB8GA1UdIwQYMBaAFH/TZafC # 3ey78DAJ80M5+gKvMzEzMA0GCSqGSIb3DQEBCwUAA4IBAQAThRoeaak396C9pK9+ # HWFT/p2MXgymdR54FyPd/ewaA1U5+3GVx2Vap44w0kRaYdtwb9ohBcIuc7pJ8dGT # /l3JzV4D4ImeP3Qe1/c4i6nWz7s1LzNYqJJW0chNO4LmeYQW/CiwsUfzHaI+7ofZ # pn+kVqU/rYQuKd58vKiqoz0EAeq6k6IOUCIpF0yH5DoRX9akJYmbBWsvtMkBTCd7 # C6wZBSKgYBU/2sn7TUyP+3Jnd/0nlMe6NQ6ISf6N/SivShK9DbOXBd5EDBX6NisD # 3MFQAfGhEV0U5eK9J0tUviuEXg+mw3QFCu+Xw4kisR93873NQ9TxTKk/tYuEr2Ty # 0BQhMYIEaTCCBGUCAQEwgZMwfzELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFu # dGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3Jr # MTAwLgYDVQQDEydTeW1hbnRlYyBDbGFzcyAzIFNIQTI1NiBDb2RlIFNpZ25pbmcg # Q0ECEC7+pBem5rVfW6DWwVUqwuUwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwx # CjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGC # NwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFCTU4An38FFz34Qf # oTGgMIfSKnAAMA0GCSqGSIb3DQEBAQUABIIBACXObqgXuVMiYnU6vQWDVXst2ctO # augKsiJ8s5dQN0c0p231f0MfeV3QlA1dyPeWGm3AtT44WRRdngx9Mp86p/XCrKr7 # pQ0L9WBHC+FN1mDJLJ5n12/YWyGsSdQh3asH7kr++b15HFEFcvbbdQBXxNyvh7r3 # BILUFNbbagu/kyU0rrvcF0PV5juwDGOTSntAMIpxhrHX0zIQoIyojYosxSu/XgaX # q9hU9CCO/ZyQ4/GgHR8JHErBSWfyJu/bngvUH73APEPoksDY29ttt7rO7iBaUL4H # sl5vt9dwyO6X9HZIAMYSnCcWOkHxwkrWMjQddIrg62enT/pt4nlUB96a9dahggIw # MIICLAYJKoZIhvcNAQkGMYICHTCCAhkCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEx # MC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBD # QQIQDUJK4L46iP9gQCHOFADw3TANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJ # AzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIxMDQyMDExMzIzM1owLwYJ # KoZIhvcNAQkEMSIEIDItOFxB+4JlE5as8mbaNG4KPsWIkzm2zY797ka7gcO5MA0G # CSqGSIb3DQEBAQUABIIBAADJBcGyLmanl3cxv5IabD36OZlLgPWoxcaqmc2jfnyg # +VkL4IV3ltSLZl2zjZhvNw+QSBJ93JfuQPs7IoD5n2xKZWqyjK0TOG8R4Z2/du+q # mg1iLJxHSVZU5zW0jAE8/eToQX14emmzxAsWG9n24eGOZTkdSOqVOrjItWKrCtc6 # oIRrvqHU+ppba6XIGwbMOJenT9HLwOA7Zm8l3diRvMs60Wk+WU5GrRpM/dDahUlH # 7WhHPd2KpVhiXH80VQ6LkuGKRrSJlgWLcz8Zb2ZrASTokrUFAQoojabcbPjeThZi # kGOuS4Yibk80lX8tu0/KPTU205ico74JR75hD0ruHiY= # SIG # End signature block |