PackageManagementDscUtilities.psm1 (24136B)
1 # 2 # Copyright (c) Microsoft Corporation. 3 # 4 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 5 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 6 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 7 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 8 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 9 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 10 # THE SOFTWARE. 11 # 12 #Helper functions for PackageManagement DSC Resouces 13 14 Import-LocalizedData -BindingVariable LocalizedData -filename PackageManagementDscUtilities.strings.psd1 15 16 17 Function ExtractArguments 18 { 19 <# 20 .SYNOPSIS 21 22 This is a helper function that extract the parameters from a given table. 23 24 .PARAMETER FunctionBoundParameters 25 Specifies the hashtable containing a set of parameters to be extracted 26 27 .PARAMETER ArgumentNames 28 Specifies A list of arguments you want to extract 29 #> 30 31 Param 32 ( 33 [parameter(Mandatory = $true)] 34 [System.Collections.Hashtable] 35 $FunctionBoundParameters, 36 37 #A list of arguments you want to extract 38 [parameter(Mandatory = $true)] 39 [System.String[]]$ArgumentNames 40 ) 41 42 Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand)) 43 44 $returnValue=@{} 45 46 foreach ($arg in $ArgumentNames) 47 { 48 if($FunctionBoundParameters.ContainsKey($arg)) 49 { 50 #Found an argument we are looking for, so we add it to return collection 51 $returnValue.Add($arg,$FunctionBoundParameters[$arg]) 52 } 53 } 54 55 return $returnValue 56 } 57 58 function ThrowError 59 { 60 <# 61 .SYNOPSIS 62 63 This is a helper function that throws an error. 64 65 .PARAMETER ExceptionName 66 Specifies the type of errors, e.g. System.ArgumentException 67 68 .PARAMETER ExceptionMessage 69 Specifies the exception message 70 71 .PARAMETER ErrorId 72 Specifies an identifier of the error 73 74 .PARAMETER ErrorCategory 75 Specifies the error category, e.g., InvalidArgument defined in System.Management.Automation. 76 77 #> 78 79 param 80 ( 81 [parameter(Mandatory = $true)] 82 [ValidateNotNullOrEmpty()] 83 [System.String] 84 $ExceptionName, 85 86 [parameter(Mandatory = $true)] 87 [ValidateNotNullOrEmpty()] 88 [System.String] 89 $ExceptionMessage, 90 91 [parameter(Mandatory = $true)] 92 [ValidateNotNullOrEmpty()] 93 [System.String] 94 $ErrorId, 95 96 [parameter(Mandatory = $true)] 97 [ValidateNotNull()] 98 [System.Management.Automation.ErrorCategory] 99 $ErrorCategory 100 ) 101 102 Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand)) 103 104 $exception = New-Object -TypeName $ExceptionName -ArgumentList $ExceptionMessage; 105 $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord -ArgumentList ($exception, $ErrorId, $ErrorCategory, $null) 106 throw $errorRecord 107 } 108 109 Function ValidateArgument 110 { 111 <# 112 .SYNOPSIS 113 114 This is a helper function that validates the arguments. 115 116 .PARAMETER Argument 117 Specifies the argument to be validated. 118 119 .PARAMETER Type 120 Specifies the type of argument. 121 #> 122 123 [CmdletBinding()] 124 param 125 ( 126 [parameter(Mandatory = $true)] 127 [ValidateNotNullOrEmpty()] 128 [string]$Argument, 129 130 [parameter(Mandatory = $true)] 131 [ValidateNotNullOrEmpty()] 132 [String]$Type, 133 134 [parameter(Mandatory = $true)] 135 [ValidateNotNullOrEmpty()] 136 [String]$ProviderName 137 ) 138 139 Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand)) 140 141 switch ($Type) 142 { 143 144 "SourceUri" 145 { 146 # Checks whether given URI represents specific scheme 147 # Most common schemes: file, http, https, ftp 148 $scheme =@('http', 'https', 'file', 'ftp') 149 150 $newUri = $Argument -as [System.URI] 151 $returnValue = ($newUri -and $newUri.AbsoluteURI -and ($scheme -icontains $newuri.Scheme)) 152 153 if ($returnValue -eq $false) 154 { 155 ThrowError -ExceptionName "System.ArgumentException" ` 156 -ExceptionMessage ($LocalizedData.InValidUri -f $Argument)` 157 -ErrorId "InValidUri" ` 158 -ErrorCategory InvalidArgument 159 } 160 161 #Check whether it's a valid uri. Wait for the response within 2mins. 162 <#$result = Invoke-WebRequest $newUri -TimeoutSec 120 -UseBasicParsing -ErrorAction SilentlyContinue 163 164 if ($null -eq (([xml]$result.Content).service )) 165 { 166 ThrowError -ExceptionName "System.ArgumentException" ` 167 -ExceptionMessage ($LocalizedData.InValidUri -f $Argument)` 168 -ErrorId "InValidUri" ` 169 -ErrorCategory InvalidArgument 170 }#> 171 172 } 173 "DestinationPath" 174 { 175 $returnValue = Test-Path -Path $Argument 176 if ($returnValue -eq $false) 177 { 178 ThrowError -ExceptionName "System.ArgumentException" ` 179 -ExceptionMessage ($LocalizedData.PathDoesNotExist -f $Argument)` 180 -ErrorId "PathDoesNotExist" ` 181 -ErrorCategory InvalidArgument 182 } 183 } 184 "PackageSource" 185 { 186 #Argument can be either the package source Name or source Uri. 187 188 #Check if the source is a uri 189 $uri = $Argument -as [System.URI] 190 191 if($uri -and $uri.AbsoluteURI) 192 { 193 # Check if it's a valid Uri 194 ValidateArgument -Argument $Argument -Type "SourceUri" -ProviderName $ProviderName 195 } 196 else 197 { 198 #Check if it's a registered package source name 199 $source = PackageManagement\Get-PackageSource -Name $Argument -ProviderName $ProviderName -verbose -ErrorVariable ev 200 if ((-not $source) -or $ev) 201 { 202 #We do not need to throw error here as Get-PackageSource does already 203 Write-Verbose -Message ($LocalizedData.SourceNotFound -f $source) 204 } 205 } 206 } 207 default 208 { 209 ThrowError -ExceptionName "System.ArgumentException" ` 210 -ExceptionMessage ($LocalizedData.UnexpectedArgument -f $Type)` 211 -ErrorId "UnexpectedArgument" ` 212 -ErrorCategory InvalidArgument 213 } 214 } 215 } 216 217 Function ValidateVersionArgument 218 { 219 <# 220 .SYNOPSIS 221 222 This is a helper function that does the version validation. 223 224 .PARAMETER RequiredVersion 225 Provides the required version. 226 227 .PARAMETER MaximumVersion 228 Provides the maximum version. 229 230 .PARAMETER MinimumVersion 231 Provides the minimum version. 232 #> 233 234 [CmdletBinding()] 235 param 236 ( 237 [string]$RequiredVersion, 238 [string]$MinimumVersion, 239 [string]$MaximumVersion 240 241 ) 242 243 Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand)) 244 245 $isValid = $false 246 247 #Case 1: No further check required if a user provides either none or one of these: minimumVersion, maximumVersion, and requiredVersion 248 if ($PSBoundParameters.Count -le 1) 249 { 250 return $true 251 } 252 253 #Case 2: #If no RequiredVersion is provided 254 if (-not $PSBoundParameters.ContainsKey('RequiredVersion')) 255 { 256 #If no RequiredVersion, both MinimumVersion and MaximumVersion are provided. Otherwise fall into the Case #1 257 $isValid = $PSBoundParameters['MinimumVersion'] -le $PSBoundParameters['MaximumVersion'] 258 } 259 260 #Case 3: RequiredVersion is provided. 261 # In this case MinimumVersion and/or MaximumVersion also are provided. Otherwise fall in to Case #1. 262 # This is an invalid case. When RequiredVersion is provided, others are not allowed. so $isValid is false, which is already set in the init 263 264 if ($isValid -eq $false) 265 { 266 ThrowError -ExceptionName "System.ArgumentException" ` 267 -ExceptionMessage ($LocalizedData.VersionError)` 268 -ErrorId "VersionError" ` 269 -ErrorCategory InvalidArgument 270 } 271 } 272 273 Function Get-InstallationPolicy 274 { 275 <# 276 .SYNOPSIS 277 278 This is a helper function that retrives the InstallationPolicy from the given repository. 279 280 .PARAMETER RepositoryName 281 Provides the repository Name. 282 283 #> 284 285 Param 286 ( 287 [parameter(Mandatory = $true)] 288 [ValidateNotNullOrEmpty()] 289 [System.String]$RepositoryName 290 ) 291 292 Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand)) 293 294 $repositoryobj = PackageManagement\Get-PackageSource -Name $RepositoryName -ErrorAction SilentlyContinue -WarningAction SilentlyContinue 295 296 if ($repositoryobj) 297 { 298 return $repositoryobj.IsTrusted 299 } 300 } 301 302 # SIG # Begin signature block 303 # MIInoQYJKoZIhvcNAQcCoIInkjCCJ44CAQExDzANBglghkgBZQMEAgEFADB5Bgor 304 # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG 305 # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD+xe8u4YoS6UEO 306 # jtW70wceL89huvuluOvdcbeefpOXLqCCDYEwggX/MIID56ADAgECAhMzAAACUosz 307 # qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD 308 # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy 309 # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p 310 # bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw 311 # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u 312 # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy 313 # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB 314 # AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I 315 # sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O 316 # L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA 317 # v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o 318 # RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8 319 # q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE 320 # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw 321 # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 322 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu 323 # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu 324 # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w 325 # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 326 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx 327 # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFkk3 328 # uSxkTEBh1NtAl7BivIEsAWdgX1qZ+EdZMYbQKasY6IhSLXRMxF1B3OKdR9K/kccp 329 # kvNcGl8D7YyYS4mhCUMBR+VLrg3f8PUj38A9V5aiY2/Jok7WZFOAmjPRNNGnyeg7 330 # l0lTiThFqE+2aOs6+heegqAdelGgNJKRHLWRuhGKuLIw5lkgx9Ky+QvZrn/Ddi8u 331 # TIgWKp+MGG8xY6PBvvjgt9jQShlnPrZ3UY8Bvwy6rynhXBaV0V0TTL0gEx7eh/K1 332 # o8Miaru6s/7FyqOLeUS4vTHh9TgBL5DtxCYurXbSBVtL1Fj44+Od/6cmC9mmvrti 333 # yG709Y3Rd3YdJj2f3GJq7Y7KdWq0QYhatKhBeg4fxjhg0yut2g6aM1mxjNPrE48z 334 # 6HWCNGu9gMK5ZudldRw4a45Z06Aoktof0CqOyTErvq0YjoE4Xpa0+87T/PVUXNqf 335 # 7Y+qSU7+9LtLQuMYR4w3cSPjuNusvLf9gBnch5RqM7kaDtYWDgLyB42EfsxeMqwK 336 # WwA+TVi0HrWRqfSx2olbE56hJcEkMjOSKz3sRuupFCX3UroyYf52L+2iVTrda8XW 337 # esPG62Mnn3T8AuLfzeJFuAbfOSERx7IFZO92UPoXE1uEjL5skl1yTZB3MubgOA4F 338 # 8KoRNhviFAEST+nG8c8uIsbZeb08SeYQMqjVEmkwggd6MIIFYqADAgECAgphDpDS 339 # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK 340 # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 341 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 342 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla 343 # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS 344 # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT 345 # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB 346 # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG 347 # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S 348 # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz 349 # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 350 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u 351 # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 352 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl 353 # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP 354 # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB 355 # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF 356 # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM 357 # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ 358 # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud 359 # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO 360 # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 361 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y 362 # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p 363 # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y 364 # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB 365 # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw 366 # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA 367 # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY 368 # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj 369 # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd 370 # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ 371 # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf 372 # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ 373 # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j 374 # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B 375 # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 376 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 377 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I 378 # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIZdjCCGXICAQEwgZUwfjELMAkG 379 # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx 380 # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z 381 # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN 382 # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor 383 # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgCZ2K5xbK 384 # 27tyibqtMV5AHpyNN7lNy3nCNEZ+gshCPtAwQgYKKwYBBAGCNwIBDDE0MDKgFIAS 385 # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN 386 # BgkqhkiG9w0BAQEFAASCAQCyqH1a6wilw9tLp1PBwdpHqB1Ami+jaRaJh0DD1pMa 387 # 0Wv61B/88vYVxgOsFfBcBqZvVoQsYtlAjEcx/dg5Vamacy+LfO+8cm8uRq1uSXOq 388 # gn3FDJ6Xy0j3pcU44/X1uzh8KoUaQJzNpcjLn8WpqABD0w7WfIA7A+o1yMZUcUsP 389 # XejK8HpbV8Qrtz9okvl/hsK0zQuajckvm/odt+IgmwBr4yomlRFJ1AAqyKYp//4H 390 # 7gPo5CBjh3H7wHn0mXMkES24T37LXmxxSncAShECTMvJMhiuM01TN6PziqI6ER0S 391 # XFvKYHyfqwXvsfn71rcKAIWWjtWXz4a1mIZjkXJfUcf7oYIXADCCFvwGCisGAQQB 392 # gjcDAwExghbsMIIW6AYJKoZIhvcNAQcCoIIW2TCCFtUCAQMxDzANBglghkgBZQME 393 # AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB 394 # MDEwDQYJYIZIAWUDBAIBBQAEIB/6Ll6BcpT6c9557ujfliR3kAn4lZRikouo1ahJ 395 # /NiIAgZitNXDgmUYEzIwMjIwNzAxMjEwMDAwLjQ0OVowBIACAfSggdCkgc0wgcox 396 # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt 397 # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p 398 # Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg 399 # RVNOOjhBODItRTM0Ri05RERBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt 400 # cCBTZXJ2aWNloIIRVzCCBwwwggT0oAMCAQICEzMAAAGZyI+vrbZ9vosAAQAAAZkw 401 # DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0 402 # b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh 403 # dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN 404 # MjExMjAyMTkwNTE2WhcNMjMwMjI4MTkwNTE2WjCByjELMAkGA1UEBhMCVVMxEzAR 405 # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p 406 # Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg 407 # T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046OEE4Mi1FMzRGLTlE 408 # REExJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0G 409 # CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4E/lXXKMsy9rVa2a8bRb0Ar/Pj4+b 410 # KiAgMgKayvCMFn3ddGof8eWFgJWp5JdKjWjrnmW1r9tHpcP2kFpjXp2Udrj55jt5 411 # NYi1MERcoIo+E29XuCwFAMJftGdvsWea/OTQPIFsZEWqEteXdRncyVwct5xFzBIC 412 # 1JWCdmfc7R59RMIyvgWjIz8356mweowkOstN1fe53KIJ8flrYILIQWsNRMOT3znA 413 # GwIb9kyL54C6jZjFxOSusGYmVQ+Gr/qZQELw1ipx9s5jNP1LSpOpfTEBFu+y9KLN 414 # BmMBARkSPpTFkGEyGSwGGgSdOi6BU6FPK+6urZ830jrRemK4JkIJ9tQhlGcIhAjh 415 # cqZStn+38lRjVvrfbBI5EpI2NwlVIK2ibGW7sWeTAz/yNPNISUbQhGAJse/OgGj/ 416 # 1qz/Ha9mqfYZ8BHchNxn08nWkqyrjrKicQyxuD8mCatTrVSbOJYfQyZdHR9a4vgy 417 # GeZEXBYQNAlIuB37QCOAgs/VeDU8M4dc/IlrTyC0uV1SS4Gk8zV+5X5eRu+XORN8 418 # FWqzI6k/9y6cWwOWMK6aUN1XqLcaF/sm9rX84eKW2lhDc3C31WLjp8UOfOHZfPuy 419 # y54xfilnhhCPy4QKJ9jggoqqeeEhCEfgDYjy+PByV/e5HDB2xHdtlL93wltAkI3a 420 # Cxo84kVPBCa0OwIDAQABo4IBNjCCATIwHQYDVR0OBBYEFI26Vrg+nGWvrvIh0dQP 421 # EonENR0QMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRY 422 # MFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01p 423 # Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEF 424 # BQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w 425 # a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAo 426 # MSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI 427 # hvcNAQELBQADggIBAHGzWh29ibBNro3ns8E3EOHGsLB1Gzk90SFYUKBilIu4jDbR 428 # 7qbvXNd8nnl/z5D9LKgw3T81jqy5tMiWp+p4jYBBk3PRx1ySqLUfhF5ZMWolRzW+ 429 # cQZGXV38iSmdAUG0CpR5x1rMdPIrTczVUFsOYGqmkoUQ/dRiVL4iAXJLCNTj4x3Y 430 # wIQcCPt0ijJVinPIMAYzA8f99BbeiskyI0BHGAd0kGUX2I2/puYnlyS8toBnANjh 431 # 21xgvEuaZ2dvRqvWk/i1XIlO67au/XCeMTvXhPOIUmq80U32Tifw3SSiBKTyir7m 432 # oWH1i7H2q5QAnrBxuyy//ZsDfARDV/Atmj5jr6ATfRHDdUanQpeoBS+iylNU6RAR 433 # u8g+TMCu/ZndZmrs9w+8galUIGg+GmlNk07fXJ58Oc+qFqgNAsNkMi+dSzKkWGA4 434 # /klJFn0XichXL8+t7KOayXKGzQja6CdtCjisnyS8hbv4PKhaeMtf68wJWKKOs0tt 435 # 2AJfYC5vSbH9ck8BGj2e/yQXEZEu88L5/fHK5XUk/IKXx3zaLkxXTSZ43Ea/WKXV 436 # BzMasHZ3Pmny0moEekAXx1UhLNNYv4Vum33VirxSB6r/GKQxFSHu7yFfrWQpYyyD 437 # H119TmhAedS8T1VabqdtO5ZP2E14TK82Vyxy3xEPelOo4dRIlhm7XY6k9B68MIIH 438 # cTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCB 439 # iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl 440 # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMp 441 # TWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEw 442 # OTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UE 443 # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z 444 # b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ 445 # Q0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIh 446 # C3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNx 447 # WuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFc 448 # UTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAc 449 # nVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUo 450 # veO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyzi 451 # YrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9 452 # fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdH 453 # GO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7X 454 # KHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiE 455 # R9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/ 456 # eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3 457 # FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAd 458 # BgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEE 459 # AYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29t 460 # L3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMI 461 # MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMB 462 # Af8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1Ud 463 # HwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By 464 # b2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQRO 465 # MEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2Vy 466 # dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4IC 467 # AQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pk 468 # bHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gng 469 # ugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3 470 # lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHC 471 # gRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6 472 # MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEU 473 # BHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvsh 474 # VGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+ 475 # fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrp 476 # NPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHI 477 # qzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAs4wggI3AgEBMIH4 478 # oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G 479 # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUw 480 # IwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1U 481 # aGFsZXMgVFNTIEVTTjo4QTgyLUUzNEYtOUREQTElMCMGA1UEAxMcTWljcm9zb2Z0 482 # IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAku/zYujnqapN6BJ9 483 # MJ5jtgDrlOuggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu 484 # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv 485 # cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN 486 # BgkqhkiG9w0BAQUFAAIFAOZpNz0wIhgPMjAyMjA3MDExNzA1MDFaGA8yMDIyMDcw 487 # MjE3MDUwMVowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA5mk3PQIBADAKAgEAAgIR 488 # FQIB/zAHAgEAAgIRszAKAgUA5mqIvQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgor 489 # BgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUA 490 # A4GBAFPnj5aYeiMxAJhCBC3XyLLyNYf/OubzwI5EX68hNX+TC87/MMvxocAgfMk1 491 # zLkJek8rPLlWGWf2oeGQYwyOQ0OMjD5YU4LnkVjN0l027+vwT2Rafc6RIWFiQbIG 492 # RRBFfXDFgyuM97dVEf8ICSKsRlCCgFAV8JMNdND7JtN+xEb6MYIEDTCCBAkCAQEw 493 # gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT 494 # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE 495 # AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGZyI+vrbZ9vosA 496 # AQAAAZkwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B 497 # CRABBDAvBgkqhkiG9w0BCQQxIgQgkB6lWYhfhU1/DxjvSurvGL3RL89ss6hg4476 498 # tkRKHTwwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBmfWn58qKN7WWpBTYO 499 # rUO1BSCSnKPLC/G7wCOIc2JsfjCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD 500 # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy 501 # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w 502 # IFBDQSAyMDEwAhMzAAABmciPr622fb6LAAEAAAGZMCIEILRj7rb7JnV73e8wLbPq 503 # CULQreKtMxdbry8TgOxho5edMA0GCSqGSIb3DQEBCwUABIICAKDNJpuPLp51vjon 504 # QG0U01L3EGiaTgFCweFx7+x4vL5mVQ8JQBPaYJoy+34wnXF2U+0FwXW0SiTzzIHb 505 # 0lFXKRkSMqCPnpW/1Oz474m9w95SvR86JgRC/kuJWtyD+TZg++zCafJeaLAXnuj3 506 # LbpJlbNp7P6jW5Kz05J8xrz/Q+5g16VQ7RqqHImBKubLqAHEWrRcZiOXZZuIyDT4 507 # 2L1vyDMMVHjGZfghQO5on6LsAmBmS2Ne7VteWUQxVWI/0yl1e81xjLzPFmiU0PrL 508 # oWwI+fYVuKCYo5bwYQEhlVb5iVhNYYeNo0Voyh5Nnl75ClP/Xp/jeRb4hI9w6cdf 509 # rlHWIhrKmNDb2Hmu7fVOF+A4O2j32EXG7sJPMNmboMFOeQf8eTcohw0LImS/eay/ 510 # 6vAcPeJw7jhHpJG20zDfusn4HDR1nD4oKTENvK7EIMSheRvsxAR1KS90sQLoPkyc 511 # k5rkNTr8MHhvE4Nz5eeNfO7FIw2xPxwRST4p/hLes9xUw4H59TdSe9H0N92q118J 512 # NNo/xo7e5d6lSLoonrL/TIYbvuoqM5PGw8HPS8ve09kV00MXTAGcnxpr2j1CzMAv 513 # Y4i7KMGesQfOB5ounL187ZV/e+bhhHfLA0mgSnehHjXtQP/MNOvQ9/EXIK3/xcXg 514 # mr4TmGPRZkuxUnXFoqN0pPOr9NOY 515 # SIG # End signature block