Microsoft.PowerApps.RestClientModule.psm1
|
$local:ErrorActionPreference = "Stop" function Assert-EndpointIsSupported { <# .SYNOPSIS Rejects a request whose endpoint is not available in the current cloud. .DESCRIPTION Several session endpoints resolve to the literal "unsupported" when the cloud the session is logged in to has no such service, or when an endpoint override was not supplied. Substituting that into a route yields a hostname like "<something>.unsupported", which would otherwise be sent on to fail as an opaque DNS error after acquiring a token for the wrong audience. .PARAMETER Uri The fully substituted request URI. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $Uri ) if ($Uri -match "^[^:]+://(?:[^/?#]*\.)?unsupported(?:[:/?#]|$)") { throw "This request targets a service that is not available in the cloud this session is logged in to. Log in with Add-PowerAppsAccount against a cloud that supports it, or supply the matching endpoint override. Request URI: $Uri" } } function Get-AudienceForHostName { [CmdletBinding()] Param( [string] $Uri ) $hostMapping = @{ "management.azure.com" = "https://management.azure.com/"; "api.powerapps.com" = "https://service.powerapps.com/"; "api.apps.appsplatform.us" = "https://service.apps.appsplatform.us/"; "tip1.api.powerapps.com" = "https://service.powerapps.com/"; "tip2.api.powerapps.com" = "https://service.powerapps.com/"; "graph.windows.net" = "https://graph.windows.net/"; "graph.microsoft.com" = "https://graph.microsoft.com/"; #tip1, tip2, and prod, gccmod "graph.microsoft.us" = "https://graph.microsoft.us/"; #high "dod-graph.microsoft.us" = "https://dod-graph.microsoft.us/"; #dod "microsoftgraph.chinacloudapi.cn" = "https://microsoftgraph.chinacloudapi.cn/"; #china "api.bap.microsoft.com" = "https://service.powerapps.com/"; "tip1.api.bap.microsoft.com" = "https://service.powerapps.com/"; "tip2.api.bap.microsoft.com" = "https://service.powerapps.com/"; "api.flow.microsoft.com" = "https://service.flow.microsoft.com/"; "api.flow.appsplatform.us" = "https://service.flow.appsplatform.us/"; "tip1.api.flow.microsoft.com" = "https://service.flow.microsoft.com/"; "tip2.api.flow.microsoft.com" = "https://service.test.powerautomate.com/"; "gov.api.bap.microsoft.us" = "https://gov.service.powerapps.us/"; "high.api.bap.microsoft.us" = "https://high.service.powerapps.us/"; "api.bap.appsplatform.us" = "https://service.apps.appsplatform.us/"; "gov.api.powerapps.us" = "https://gov.service.powerapps.us/"; "high.api.powerapps.us" = "https://high.service.powerapps.us/"; "gov.api.flow.microsoft.us" = "https://gov.service.flow.microsoft.us/"; "high.api.flow.microsoft.us" = "https://high.service.flow.microsoft.us/"; "bots.int.customercareintelligence.net" = "a522f059-bb65-47c0-8934-7db6e5286414"; "bots.ppe.customercareintelligence.net" = "a522f059-bb65-47c0-8934-7db6e5286414"; "powerva.microsoft.com" = "96ff4394-9197-43aa-b393-6a41652e21f8"; "gcc.api.powerva.microsoft.us" = "9315aedd-209b-43b3-b149-2abff6a95d59"; "high.api.powerva.microsoft.us" = "69c6e40c-465f-4154-987d-da5cba10734e"; "powerva.api.appsplatform.us" = "bd4a9f18-e349-4c74-a6b7-65dd465ea9ab"; "api.powerplatform.com" = "https://api.powerplatform.com"; "api.test.powerplatform.com" = "https://api.test.powerplatform.com"; "api.appsplatform.us" = "https://api.appsplatform.us"; "api.preprod.powerplatform.com" = "https://api.preprod.powerplatform.com"; "api.gov.powerplatform.microsoft.us" = "https://api.gov.powerplatform.microsoft.us"; "api.high.powerplatform.microsoft.us" = "https://api.high.powerplatform.microsoft.us"; "api.powerplatform.partner.microsoftonline.cn" = "https://api.powerplatform.partner.microsoftonline.cn"; } $uriObject = New-Object System.Uri($Uri) $hostName = $uriObject.Host if ($null -ne $hostMapping[$hostName]) { return $hostMapping[$hostName]; } # Copilot Governance and other per-environment Power Platform API routes use a hostname derived # from the environment id (<id-minus-last-2>.<last-2>.environment.<powerPlatformApiHost>), so # they can never be literal keys above. Resolve them to the audience of the Power Platform API # host they hang off. The base host is matched against this list rather than the whole table so # that a name such as x.y.environment.graph.microsoft.com cannot borrow an unrelated audience. $powerPlatformApiHosts = @( "api.powerplatform.com", "api.test.powerplatform.com", "api.preprod.powerplatform.com", "api.appsplatform.us", "api.gov.powerplatform.microsoft.us", "api.high.powerplatform.microsoft.us", "api.powerplatform.partner.microsoftonline.cn" ) if ($hostName -match "^[a-z0-9]+\.[a-z0-9]+\.environment\.(?<baseHost>.+)$") { $baseHost = $Matches["baseHost"] if ($powerPlatformApiHosts -contains $baseHost -and $null -ne $hostMapping[$baseHost]) { return $hostMapping[$baseHost]; } } # There used to be a fallback loop here that compared $hostName against each hashtable key with # -match, i.e. treating hostnames as unanchored regexes. It could never actually run, because # its iterator variable was $host, which is a read-only automatic variable, so every unknown # host threw instead. It is deleted rather than repaired: unanchored matching maps look-alike # names such as api.powerplatform.com.example.test onto a real audience, which would hand that # host a valid bearer token. Exact matches plus the derived-host branch above cover every # hostname this module builds. # A host that sits under a Power Platform API domain but did not match the form above is almost # certainly a route this function has not been taught yet. Falling through to the ARM default # silently would send a token for the wrong audience and surface as an opaque 401, so say so. # The audience is still not guessed; only the diagnosis is improved. foreach ($powerPlatformApiHost in $powerPlatformApiHosts) { if ($hostName.EndsWith(".$powerPlatformApiHost")) { Write-Warning "The host $hostName looks like a Power Platform API host but does not match a form this module recognizes, so the default Azure Resource Manager audience is being used and the request is likely to fail as unauthorized."; break; } } Write-Verbose "Unknown host $hostName. Using https://management.azure.com/ as a default"; return "https://management.azure.com/"; } function Invoke-Request( [CmdletBinding()] [Parameter(Mandatory=$True)] [string] $Uri, [Parameter(Mandatory=$True)] [string] $Method, [object] $Body = $null, [Hashtable] $Headers = @{}, [switch] $ParseContent, [switch] $ThrowOnFailure ) { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $audience = Get-AudienceForHostName -Uri $Uri $token = Get-JwtToken -Audience $audience $Headers["Authorization"] = "Bearer $token"; $Headers["User-Agent"] = "PowerShell cmdlets 1.0"; try { if ($null -eq $Body -or $Body -eq "") { $response = Invoke-WebRequest -Uri $Uri -Headers $Headers -Method $Method -UseBasicParsing } else { $jsonBody = ConvertTo-Json $Body -Depth 20 $response = Invoke-WebRequest -Uri $Uri -Headers $Headers -Method $Method -ContentType "application/json; charset=utf-8" -Body $jsonBody -UseBasicParsing } if ($ParseContent) { if ($response.Content) { return ConvertFrom-JsonWithErrorHandling -JsonString $response.Content; } } return $response } catch { $response = $_.Exception.Response if ($_.ErrorDetails) { $errorResponse = ConvertFrom-JsonWithErrorHandling -JsonString $_.ErrorDetails; $code = $response.StatusCode.value__ $message = $errorResponse.Error.Message Write-Verbose "Status Code: '$code'. Message: '$message'" $response = New-Object -TypeName PSObject ` | Add-Member -PassThru -MemberType NoteProperty -Name StatusCode -Value $response.StatusCode.value__ ` | Add-Member -PassThru -MemberType NoteProperty -Name StatusDescription -Value $response.StatusDescription ` | Add-Member -PassThru -MemberType NoteProperty -Name Headers -Value $response.Headers ` | Add-Member -PassThru -MemberType NoteProperty -Name Error -Value $errorResponse.Error ` | Add-Member -PassThru -MemberType NoteProperty -Name Message -Value $message ` | Add-Member -PassThru -MemberType NoteProperty -Name Internal -value $response; } if ($ThrowOnFailure) { throw; } else { return $response } } } function InvokeApi { <# .SYNOPSIS Invoke an API. .DESCRIPTION The InvokeApi cmdlet invokes an API based on input parameters. Use Get-Help InvokeApi -Examples for more detail. .PARAMETER Method The http request method. .PARAMETER Route The http URL. .PARAMETER Body The http request body. .PARAMETER ThrowOnFailure Throw exception on failure if it is true. .PARAMETER ApiVersion The service API version. .EXAMPLE InvokeApi -Method GET -Route $uri -Body $body -ThrowOnFailure Call $uri API as GET method with $body input and throw exception on failure. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Method, [Parameter(Mandatory = $true)] [string]$Route, [Parameter(Mandatory = $false)] [object]$Body = $null, [Parameter(Mandatory = $false)] [switch]$ThrowOnFailure, [Parameter(Mandatory = $false)] [string]$ApiVersion = "2016-11-01" ) Test-PowerAppsAccount; $uri = $Route ` | ReplaceMacro -Macro "{apiVersion}" -Value $ApiVersion ` | ReplaceMacro -Macro "{flowEndpoint}" -Value $global:currentSession.flowEndpoint ` | ReplaceMacro -Macro "{powerAppsEndpoint}" -Value $global:currentSession.powerAppsEndpoint ` | ReplaceMacro -Macro "{bapEndpoint}" -Value $global:currentSession.bapEndpoint ` | ReplaceMacro -Macro "{graphEndpoint}" -Value $global:currentSession.graphEndpoint ` | ReplaceMacro -Macro "{msGraphEndpoint}" -Value $global:currentSession.msGraphEndpoint ` | ReplaceMacro -Macro "{pvaEndpoint}" -Value $global:currentSession.pvaEndpoint ` | ReplaceMacro -Macro "{cdsOneEndpoint}" -Value $global:currentSession.cdsOneEndpoint ` | ReplaceMacro -Macro "{powerPlatformEndpoint}" -Value $global:currentSession.powerPlatformEndpoint; Assert-EndpointIsSupported -Uri $uri Write-Verbose $uri If($ThrowOnFailure) { $result = Invoke-Request ` -Uri $uri ` -Method $Method ` -Body $body ` -ParseContent ` -ThrowOnFailure ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true); } else { $result = Invoke-Request ` -Uri $uri ` -Method $Method ` -Body $body ` -ParseContent ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true); } if($result.nextLink) { $nextLink = $result.nextLink $resultValue = $result.value while($nextLink) { If($ThrowOnFailure) { $nextResult = Invoke-Request ` -Uri $nextLink ` -Method $Method ` -Body $body ` -ParseContent ` -ThrowOnFailure ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true); } else { $nextResult = Invoke-Request ` -Uri $nextLink ` -Method $Method ` -Body $body ` -ParseContent ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true); } $nextLink = $nextResult.nextLink $resultValue = $resultValue + $nextResult.value } return New-Object -TypeName PSObject ` | Add-Member -PassThru -MemberType NoteProperty -Name value -Value $resultValue ` } return $result; } function InvokeApiNoParseContent { <# .SYNOPSIS Invoke an API without parsing return content. .DESCRIPTION The InvokeApiNoParseContent cmdlet invokes an API based on input parameters without parsing return content. Use Get-Help InvokeApiNoParseContent -Examples for more detail. .PARAMETER Method The http request method. .PARAMETER Route The http URL. .PARAMETER Body The http request body. .PARAMETER ThrowOnFailure Throw exception on failure if it is true. .PARAMETER ApiVersion The service API version. .EXAMPLE InvokeApiNoParseContent -Method PUT -Route $uri -Body $body -ThrowOnFailure Call $uri API as PUT method with $body input and throw exception on failure. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Method, [Parameter(Mandatory = $true)] [string]$Route, [Parameter(Mandatory = $false)] [object]$Body = $null, [Parameter(Mandatory = $false)] [switch]$ThrowOnFailure, [Parameter(Mandatory = $false)] [string]$ApiVersion = "2016-11-01" ) Test-PowerAppsAccount; $uri = $Route ` | ReplaceMacro -Macro "{apiVersion}" -Value $ApiVersion ` | ReplaceMacro -Macro "{flowEndpoint}" -Value $global:currentSession.flowEndpoint ` | ReplaceMacro -Macro "{powerAppsEndpoint}" -Value $global:currentSession.powerAppsEndpoint ` | ReplaceMacro -Macro "{bapEndpoint}" -Value $global:currentSession.bapEndpoint ` | ReplaceMacro -Macro "{graphEndpoint}" -Value $global:currentSession.graphEndpoint ` | ReplaceMacro -Macro "{msGraphEndpoint}" -Value $global:currentSession.msGraphEndpoint ` | ReplaceMacro -Macro "{pvaEndpoint}" -Value $global:currentSession.pvaEndpoint ` | ReplaceMacro -Macro "{cdsOneEndpoint}" -Value $global:currentSession.cdsOneEndpoint ` | ReplaceMacro -Macro "{powerPlatformEndpoint}" -Value $global:currentSession.powerPlatformEndpoint; Assert-EndpointIsSupported -Uri $uri Write-Verbose $uri If($ThrowOnFailure) { $result = Invoke-Request ` -Uri $uri ` -Method $Method ` -Body $body ` -ThrowOnFailure ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true); } else { $result = Invoke-Request ` -Uri $uri ` -Method $Method ` -Body $body ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true); } if($result.nextLink) { $nextLink = $result.nextLink $resultValue = $result.value while($nextLink) { If($ThrowOnFailure) { $nextResult = Invoke-Request ` -Uri $nextLink ` -Method $Method ` -Body $body ` -ThrowOnFailure ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true); } else { $nextResult = Invoke-Request ` -Uri $nextLink ` -Method $Method ` -Body $body ` -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true); } $nextLink = $nextResult.nextLink $resultValue = $resultValue + $nextResult.value } return New-Object -TypeName PSObject ` | Add-Member -PassThru -MemberType NoteProperty -Name value -Value $resultValue ` } return $result; } function ReplaceMacro { <# .SYNOPSIS Replace macro to the specified value. .DESCRIPTION The ReplaceMacro cmdlet replace macro in input string with the specified value. Use Get-Help ReplaceMacro -Examples for more detail. .PARAMETER Input The input string. .PARAMETER Macro The macro to be replaced. .PARAMETER Value The value for the replacement. .EXAMPLE ReplaceMacro -Macro "{apiVersion}" -Value $ApiVersion Replace {apiVersion} to $ApiVersion. #> param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string]$Input, [Parameter(Mandatory = $true)] [string]$Macro, [Parameter(Mandatory = $false)] [string]$Value ) return $Input.Replace($Macro, $Value) } function BuildFilterPattern { param ( [Parameter(Mandatory = $false)] [object]$Filter ) if ($null -eq $Filter -or $Filter.Length -eq 0) { return New-Object System.Management.Automation.WildcardPattern "*" } else { return New-Object System.Management.Automation.WildcardPattern @($Filter,"IgnoreCase") } } function ConvertFrom-JsonWithErrorHandling { param ( [Parameter(Mandatory = $true)] [string]$JsonString ) try { return ConvertFrom-Json $JsonString } catch { Write-Verbose "Invalid JSON string: '$JsonString', falling back to .NET deserialization." # try to de-serialize the json string by using .Net json serializer [void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") return (New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer -Property @{MaxJsonLength=67108864}).DeserializeObject($JsonString) } } function ResolveEnvironment { param ( [Parameter(Mandatory = $false)] [string]$OverrideId ) if (-not [string]::IsNullOrWhiteSpace($OverrideId)) { return $OverrideId; } elseif ($global:currentSession.selectedEnvironment) { return $global:currentSession.selectedEnvironment; } return "~default"; } function Select-CurrentEnvironment { <# .SYNOPSIS Sets the current environment for listing powerapps, flows, and other environment resources .DESCRIPTION The Select-CurrentEnvironment cmdlet sets the current environment in which commands will execute when an environment is not specified. Use Get-Help Select-CurrentEnvironment -Examples for more detail. .PARAMETER EnvironmentName Environment identifier (not display name). .PARAMETER Default Shortcut to specify the default tenant environment .EXAMPLE Select-CurrentEnvironment -EnvironmentName 3c2f7648-ad60-4871-91cb-b77d7ef3c239 Select environment 3c2f7648-ad60-4871-91cb-b77d7ef3c239 as the current environment. Cmdlets invoked after running this command will operate against this environment. .EXAMPLE Select-CurrentEnvironment ~default Select the default environment. Cmdlets invoked after running this will operate against the default environment. #> param ( [Parameter(Mandatory = $true, Position = 0, ValueFromPipelineByPropertyName=$true, ParameterSetName = "Name")] [String]$EnvironmentName, [Parameter(Mandatory = $true, ParameterSetName = "Default")] [Switch]$Default ) Test-PowerAppsAccount; if ($Default) { $global:currentSession.selectedEnvironment = "~default"; } else { $global:currentSession.selectedEnvironment = $EnvironmentName; } } # SIG # Begin signature block # MIInOwYJKoZIhvcNAQcCoIInLDCCJygCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBEYSRGGl+//iNE # TLK/Ijg83nICp2k8zFpUo8M8RO6rd6CCDLowggX1MIID3aADAgECAhMzAAACHU0Z # yE7XD1dIAAAAAAIdMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQzWhcNMjcwNDE1MTg1 # OTQzWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDQvewXxx9gZZFC6Ys1WBay8BJ8kGA4JQnH5CMafqOASlTpK9H8 # o5ZXTXt0caVQTNMUPt445wXYD+dFtaKWTwDn1I52oUSrC9vJin1Gsqt+zyKJL5Dg # 3eQXbQNR61DmMy20GLTIO3SFed9Rfi/ophgCLGFLDR3r0KvHjwMb/jYWS0celV/4 # Lz27LfAekm8v9E5IXaeiXbAUYZKK090n4CVl3JBtbN+9DtI9SNu/yjvozW52/u7R # X/Ttpa/KDlpuokZ+Zcbvmtd9ur9gFLvZzh41o9MsE/clQtdaFWGvuo6Jua/ntpgk # ey3E5/vBFe+MJPG6phdnuo6r57ZudCudiI1bAgMBAAGjggGbMIIBlzAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFH6QuMwqcPG0hQlQ6c5jCtTTLrVeMEUGA1UdEQQ+MDykOjA4MR4wHAYDVQQL # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xFjAUBgNVBAUTDTIzMDAxMis1MDc1NTkw # HwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEwYAYDVR0fBFkwVzBVoFOg # UYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0 # JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNybDBtBggrBgEFBQcBAQRh # MF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv # Y2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # dDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQBKTbYOjzwTG/DXGaz9 # s6+fQeaTtDcFmMY+5UyVFCyj7Pv+5i37qfX8lSL/tBIfYQfWsMuBQlfZurJD6r4H # VJ2CeH+1fgiq8dcHdVKoZ3Sa2qXoX3cq9iS8cVb06B7+5/XJ7I0OxHH9fDsvJ3T3 # w5V/ZtAIFmLrl+P0CtG+92uzRsn0nTbdFjOkLMLWPLAU3THohKRlSEMgFJpPkm5n # 5UAZ35xX6FWCrDLsSKb555bTifwa8mJBwdlof0bmfYidH+dxZ1FdDxvLnNl9zeKs # A4kejaaIqqIPguhwAti5Ql7BlTNoJNwxCvBmqW2MQLnCkYN/VVUsR3V2x/rcTNzo # Bf/Z/SpROvdaA2ZOOd1uioXJt3tdLQ7vHpqpib0KfWr/FWXW10q38VxfCnRQBqzb # SuztR7nEMuzX7Ck+B/XaPDXd1qh72+QYyB0Z2VzWmO9zsnb9Uq/dwu8LGeQqnyu6 # 7SDGACvnXii2fb9+US492VTnXSnFKyqwgzUyFMtZK1/sHYTv6bG4TtQUygQxTN+Z # V+aJIlKO2MqZ7bKrAnOzS9m6NgoTdWOq11bTOZwKlIEV/EhV9SWkDmdpR/hPPT2v # 6TEj4F8PT/zHjRezIU5c/DGlt/VhY/pK0XkJtEyMmmS1BMtjU/rqBZVMIm3dnxQs # /TBByr+Cf8Z1r7aifQVQ+WSqzjCCBr0wggSloAMCAQICEzMAAAA5O7Y3Gb8GHWcA # AAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRl # IEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoXDTM2MDMyMjIyMTMwNFow # VzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEo # MCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAyNDCCAiIwDQYJ # KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeqlRYHNa265v4IY9fH8TKh # emHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo0dtS/EW6I/yEL/bLSY8h # KpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATvQVL4tcf03aTycsz8QeCd # M0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a1uv1zerOYMnsneRRwCbp # yW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1FyQfK0fVkaya8SmVHQ/t # Of23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfOGSWHIIV4YrTJTT6PNty5 # REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7ttOu1bVnXfHaqPYl2rPs # 20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJuz2MXMCt7iw7lFPG9LXK # Gjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxSCwyoGIq0PhaA7Y+VPct5 # pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOmVQop36wUVUYklUy++vDW # eEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3SkE/xIkgpfl22MM1itkZ # 35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGC # NxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPXLQaUEggxMBkGCSsGAQQB # gjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU # ci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDovL2Ny # bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0MjAx # MV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAwTgYIKwYBBQUHMAKGQmh0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0MjAx # MV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOCAgEAFJQfOChP7onn6fLI # MKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D5W4wMwYeLystcEqfkjz4 # NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBYnbu0+THSuVHTe0VTTPVh # ily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSIvgn0JksVBVMYVI5QFu/q # hnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6aR9y34aiM1qmxaxBi6OU # nyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4wPKC5OmHm1DQIt/MNokbb # H3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7RTX8AdBPo0I6OEojf39z # uFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK/fg8B2qjW88MT/WF5V5u # vZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSKYBv0VisCzfxgeU+dquXW # 9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkwYTu/9dLeH2pDqeJZAABV # DWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVTQl0v4q8J/AUmQN5W4n10 # 1cY2L4A7GTQG1h32HHAvfQESWP0xghnXMIIZ0wIBATBuMFcxCzAJBgNVBAYTAlVT # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jv # c29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIdTRnITtcPV0gAAAAAAh0w # DQYJYIZIAWUDBAIBBQCggaAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK # KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIB3QRPKz # YfUm44gzGUhmQ8bXo+vuZBVTQ1GmD4Q5PHazMDQGCisGAQQBgjcCAQwxJjAkoBKA # EABUAGUAcwB0AFMAaQBnAG6hDoAMaHR0cDovL3Rlc3QgMA0GCSqGSIb3DQEBAQUA # BIIBALaxQyxhhwjhrDtVZXB4OsC0zwRTy5724CZtsze18SuW7Q9iiB0YHTEMMZqA # t3FQFuULGDmYp6SUnyePFkOnvGCumf8uJruBjju03T5POpbPpn6RcWpIwDpG32zc # j5tYB+aCntDTJAb1LAXgN4yD+qI48+Sp3FnrG1Nz3wtPuS6vrBrOt5ko9J7PDkeJ # dHsJzMD3S3crMwX/OdK8sypudUdrW0UN3Fr/vraLrDjdiK2c2EdIKuoSw0KKMUUd # Q/EN2mNUAkQbyc3w4cpQBRSYysdwjsXezL2h9kxAsiGseIB8LQy0QeDQ+GumuCt/ # ttYKJt6nzd6XNOskXHBCLAEob92hgheXMIIXkwYKKwYBBAGCNwMDATGCF4Mwghd/ # BgkqhkiG9w0BBwKgghdwMIIXbAIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBUgYLKoZI # hvcNAQkQAQSgggFBBIIBPTCCATkCAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQME # AgEFAAQgmwzqa2iKDC0vjX9Fp9cM5hMX5rACPnwEg+gEWRNAfgkCBmqp+qHR/xgT # MjAyNjEwMDkwMTIwMDkuNTE5WjAEgAIB9KCB0aSBzjCByzELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJp # Y2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjdGMDAtMDVF # MC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIR # 7TCCByAwggUIoAMCAQICEzMAAAIeo6ykbjlvfEkAAQAAAh4wDQYJKoZIhvcNAQEL # BQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE # AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjYwMjE5MTkzOTQ5 # WhcNMjcwNTE3MTkzOTQ5WjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw # b3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEn # MCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjdGMDAtMDVFMC1EOTQ3MSUwIwYDVQQD # ExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEApdE47Ww8LEexXvGnOqJebNc4bU6ndgFqXIUIS6fRuZpk # jNtzeX8kBgkNQ9OqzgNz4Fyhfu+r17zgrNlbC79aMI+JhxMhKoqvBiecgvv0DWEa # WTwPHuzoHpMwzukv+L8v40zGG6d64bhYiigs01jkLXRXBfg9JN+vSO6ZvxNO0sjT # BpLjXeZY+UifdVKhbmX4zAenENsIe+5rYkVFXY+d8o3Tao/hkJfmGs9vQY685+1N # ZZ/iaS5Z29MXRpmaCDymW8AVXFrci+LsoTC+0kk5ojn1l1PoPsjZdAnaCxi/C7Vh # xIvBbLkz3knUqpnjK7y2hJom01U0uL0EGPDT52+riOcuojVfbwRXJvC1P5Q04xk6 # j2u1AU+IHX+SZt8GK3whWeD/4+TKKk9CTjXGudI7eExiPdEooV2gxGKpNt0tCCWd # 1JFKbpA0U4yu9dwSMpH38cgajHkKnztM71n1Mewa5lKboEHMPffg8S5doH/rkBKU # Zp5W61SfXb1vXbOH6hDzdoxtEMBdTwUoJTXFdUqamSorUIARksLv/NgCs7aAh8GE # R0TcM8E1Xv9SjU75qgHeFIHrOMsDh9NoWmoE/MGGPDnVnYyp95NOdsPpJnNFAtBf # olV0xmSDMb6PYgWUKF3oc0bVif1TrSrwskt3LCsze60rVicI0ls+nbTn9JfsrS0C # AwEAAaOCAUkwggFFMB0GA1UdDgQWBBTmChaa6gQdCWZiXBQuHDz5nheCZDAfBgNV # HSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5o # dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBU # aW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwG # CCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRz # L01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNV # HRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIH # gDANBgkqhkiG9w0BAQsFAAOCAgEApKGQeTZyVRW+cCno0aJ5OdfGtkwTWKSnATLX # y+gUtAEWgATjBmC5TzboSNR8JnpT/YV96Kt02hJv3A5JMzUAMw3nT4KESNke/vKa # DUlrx1xALO0mTg5vceyqpQZDWTPXseF2NcjZlTgJlg40a+4yo2okG57X+xAuBjYp # MRhmlVjo32Ld0PV9K/yrPCgZW8w0fc4wP0wnLUeHKNVqVNWUSxawfW5fHUcbG58k # 9qkONRO3U9dkd9HiBlM4hLORjftulf6L1zottHSYjNd4WFr8tTTSQIZCjpSwdTjb # p3en34T3VHB1rLvFfpUdGmpDFeuB6g2y7pmawjcFKH1cd8TJPBeLQmCbUMS08sHN # 9LGQA9UtrAtfefceiosQPqeNRS1JfIOuKB8t232Jx+cXeCTgYEKGqp3Ro3HLca/v # BJJ44Ssq4AM603CiyW1Hs4KMnvG6wiyfsujwKBI6V0ZEmAFPMH0N2FkXJOgC8KFe # 1Ip/Pq6RkEm14RenNXUxWpF5goQpbneCAA2P7eiUZCftOhcy/ow3fCi1fEI++yX4 # rk4jyBuRv8ZZxqGRXF/ssgbQ782ROPHfmPh2FHf3L4R9RSpewB/uQMqLaiUhZrzP # wbmEcdgdtGrFV4pVdpNiWzTtyxgs90PnaRJc8LHya5GtTf4HrZmu31qaMLDb6CGh # EL42nfEwggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3 # DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIw # MAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAx # MDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1l # LVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA # 5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/ # XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1 # hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7 # M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3K # Ni1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy # 1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF80 # 3RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQc # NIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahha # YQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkL # iWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV # 2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIG # CSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUp # zxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBT # MFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jv # c29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYI # KwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGG # MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186a # GMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3Br # aS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsG # AQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcN # AQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1 # OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYA # A7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbz # aN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6L # GYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3m # Sj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0 # SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxko # JLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFm # PWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC482 # 2rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7 # vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDUDCC # AjgCAQEwgfmhgdGkgc4wgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n # dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y # YXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAl # BgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3RjAwLTA1RTAtRDk0NzElMCMGA1UEAxMc # TWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAg/0D # ZCgyFuFSBe496Itqm60dGv+ggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UE # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ # Q0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAO5yHxUwIhgPMjAyNjEwMDgxMzU0Mjla # GA8yMDI2MTAwOTEzNTQyOVowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA7nIfFQIB # ADAKAgEAAgIN1wIB/zAHAgEAAgITxzAKAgUA7nNwlQIBADA2BgorBgEEAYRZCgQC # MSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqG # SIb3DQEBCwUAA4IBAQCWzRWNqywBtPzcyMHtSG/HpVSwv7ZjNtKg+a6zsRUXQAs2 # kGoDKWEHOQlZb9yroIbMyrnlsODIktYEwOIMP8lTJZwTTEcKAw8DjGCYOkQGrUlp # IrnheJgCFwQjhnQwMCzuMjxRDvBYzxZcMlg2FAQ7Nkmb2ptuK1lL+kVU4sCVaZp4 # ZVVd3UXAcVxqDOlJdsMAYLQtsxQ6AvuUcODrE+aI7pRFWAZDN953HTdNDlQtmW90 # OxdtiCjC9OdB8S7ermPpF/d32BiRVnm67UT3kCWh6uXrKMYdrVpwASCeUlfchRrf # bLtPk8YGx7qheb28vaAxlcLRVT+uj5fJ92fMLW8JMYIEDTCCBAkCAQEwgZMwfDEL # MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v # bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWlj # cm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAIeo6ykbjlvfEkAAQAAAh4w # DQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAv # BgkqhkiG9w0BCQQxIgQg1/datc5K0v5eXfwsfQQ17UEHPc8XTg0ZuV/vfM/Hp7Mw # gfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCAvgV1q8/YHjIDPAb5/G6sR44R1 # ydvRAYsyEyMNAfbzgjCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAy # MDEwAhMzAAACHqOspG45b3xJAAEAAAIeMCIEIICyYUh6C0+mkLEED8+OJFeNQvw9 # jSCnwgzbKtyX2Hy/MA0GCSqGSIb3DQEBCwUABIICAETTOoPZTuhS4Sh1on6GU4Kk # tyY3oSWoIZ/Vb78M91epERBnRfngmL+w2z4kelpSP0umbuKec2UgZnwEO3KtKCyQ # 7dHS5uEOidcicW+LcTUM9SiZpjT7ev86B3BZf2WABb6MjLCaRSgRZY9LTJsm+dKS # 8193TJu/NluIc3llqx1fbVccd+hxSsWaL2f2w7hqK/tL/xofHLTxlw2r1kt/T8C5 # q0C3puyev35OfHmhDsBGanmBl+nuaV4f4j+AGEyfMjJgXEDE4AW6dI9W+0xuaal8 # hlxqp4SSS6fmyIz+08x3p/gdY3AMVCTkYdeGD7FLDDmp8VO3hvg2lJGQBwS7wKwS # H7vN7psk6tapvBtFKiH/BrePFSJAk2sJCanJaWAawbJXI6poaKO/0mSOFVRpCzb4 # UuP5teQaNxDlt69+I3SCFWescskPdkTX22fl5/UnLu1ttqBYzwQ8GqHWGi1Iabzp # x7C6QIRgbpexxkWBMz4dxnbDh0NxQ9lgcA/JRFH+qUu8i8khwhSclltofes9yEoQ # c5Wj9EEdJn3RRmHkkVdApRo9x2c3WmU6d2D4ZlcNmRh23wUQzeMMqlQpkPo9Nqgs # vG9mJf6B83xUD+q5w/2sYvE0KmCt2fwe0GYAH2UkxWzPEV01Bo3H2TsURzmxj/1T # EchDsx8JNTSGTb4Ffwdw # SIG # End signature block |