BWDynamicParameter.psm1
<# .SYNOPSIS Helper function to simplify creating dynamic parameters .DESCRIPTION Helper function to simplify creating dynamic parameters Example use cases: Include parameters only if your environment dictates it Include parameters depending on the value of a user-specified parameter Provide tab completion and intellisense for parameters, depending on the environment Please keep in mind that all dynamic parameters you create will not have corresponding variables created. One of the examples illustrates a generic method for populating appropriate variables from dynamic parameters Alternatively, manually reference $PSBoundParameters for the dynamic parameter value .NOTES Credit to http://jrich523.wordpress.com/2013/05/30/powershell-simple-way-to-add-dynamic-parameters-to-advanced-function/ Added logic to make option set optional Added logic to add RuntimeDefinedParameter to existing DPDictionary Added a little comment based help Credit to BM for alias and type parameters and their handling .PARAMETER Name The Name of the dynamic parameter. Note: If -DPDictionary is not specified you must use this same name when adding the parameter to the dictionary. .PARAMETER Mandatory Make the parameter mandatory. .PARAMETER Position The Position of the parameter. .PARAMETER ParameterSetName The ParameterSet the attribute belongs to. .PARAMETER Type Type for the parameter. Default is [string]. .PARAMETER Alias One or more aliases to assign to the parameter. .PARAMETER ValidateLength Length validation for this parameter. Takes two arguments: Min, Max .PARAMETER ValidateRange Range validation for this parameter. Takes two arguments: Min, Max .PARAMETER ValidatePattern Regex pattern validation for this parameter. .PARAMETER ValidateScript Script validation for this parameter. .PARAMETER ValidateCount Count validation for this parameter. Takes two arguments: Min, Max .PARAMETER ValidateSet Validate that arguments belong to a set. Takes at least one argument. .PARAMETER ValidateTrustedData Validate that the variable has not been manipulated outside of the local scope in ConstrainedLanguageMode. See: https://github.com/MicrosoftDocs/PowerShell-Docs/issues/3288 .PARAMETER ValidateDrive Validate that the path provided in the parameter is in one of the specified drive letters. .PARAMETER ValidateNotNull Validate that the parameter value is not null. .PARAMETER ValidateNotNullOrEmpty Validate that the parameter value is not null or empty. .PARAMETER ValueFromPipeline Allow the parameter to be populated by values from the pipeline. .PARAMETER ValueFromPipelineByPropertyName Allow the parameter to be populated by object property names from the pipeline. .PARAMETER ValueFromRemainingArguments Allow the parameter to be populated by the remaining arguments. .PARAMETER ArgumentCompleter Argument completer script block. See: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/register-argumentcompleter?view=powershell-7 .PARAMETER DontShow Hide the parameter from auto-complete. .PARAMETER HelpMessage Show a short help message. .PARAMETER HelpMessageBaseName The base type name where the help message should be populated from. Requires -HelpMessageResourceId be set. .PARAMETER HelpMessageResourceId The resource in the -HelpMessageBaseName to use. .PARAMETER DPDictionary Optionally append the parameter to a DPDictionary object. .EXAMPLE PS C:\ > $Param1 = New-DynamicParameter -Name Param1 -ValidateSet 1,2 -Mandatory .FUNCTIONALITY PowerShell Language #> function New-DynamicParameter { [CmdletBinding(DefaultParameterSetName='Default')] [OutputType([System.Management.Automation.RuntimeDefinedParameter], ParameterSetName='Default')] [OutputType([void], ParameterSetName='AppendToDictionary')] param( [Parameter(Mandatory=$true, Position=1)] [string] $Name, [switch] $Mandatory, [ValidateNotNullOrEmpty()] [int] $Position, [ValidateNotNullOrEmpty()] [string] $ParameterSetName = '__AllParameterSets', [System.Type] $Type = [string], [ValidateCount( 1, 4096 )] [ValidateNotNullOrEmpty()] [string[]] $Alias, [ValidateCount( 2, 2 )] [int[]] $ValidateLength, [ValidateCount( 2, 2 )] [int[]] $ValidateRange, [ValidateNotNullOrEmpty()] [regex] $ValidatePattern, [ValidateNotNullOrEmpty()] [scriptblock] $ValidateScript, [ValidateCount( 2, 2 )] [int[]] $ValidateCount, [ValidateCount( 1, 4096 )] [ValidateNotNullOrEmpty()] [string[]] $ValidateSet, [switch] $ValidateTrustedData, [ValidateCount( 1, 4096 )] [ValidateNotNullOrEmpty()] [string[]] $ValidateDrive, [switch] $ValidateNotNull, [switch] $ValidateNotNullOrEmpty, [switch] $ValueFromPipeline, [switch] $ValueFromPipelineByPropertyName, [switch] $ValueFromRemainingArguments, [scriptblock] $ArgumentCompleter, [switch] $DontShow, [ValidateNotNullOrEmpty()] [string] $HelpMessage, [ValidateNotNullOrEmpty()] [string] $HelpMessageBaseName, [ValidateNotNullOrEmpty()] [string] $HelpMessageResourceId, [Parameter(Mandatory=$true, ParameterSetName='AppendToDictionary')] [System.Management.Automation.RuntimeDefinedParameterDictionary] $DPDictionary ) # the collection of parameter attributes $AttributeCollection = New-Object 'Collections.ObjectModel.Collection[System.Attribute]' # primary parameter configuration $ParameterAttribute = New-Object -TypeName System.Management.Automation.ParameterAttribute $ParameterAttribute.ParameterSetName = $ParameterSetName $ParameterAttribute.Mandatory = $Mandatory.IsPresent $ParameterAttribute.ValueFromPipeline = $ValueFromPipeline.IsPresent $ParameterAttribute.ValueFromPipelineByPropertyName = $ValueFromPipelineByPropertyName.IsPresent $ParameterAttribute.ValueFromRemainingArguments = $ValueFromRemainingArguments.IsPresent $ParameterAttribute.DontShow = $DontShow.IsPresent if ( $Position ) { $ParameterAttribute.Position = $Position } if ( $HelpMessage ) { $ParameterAttribute.HelpMessage = $HelpMessage } if ( $HelpMessageBaseName ) { $ParameterAttribute.HelpMessageBaseName = $HelpMessageBaseName } if ( $HelpMessageResourceId ) { $ParameterAttribute.HelpMessageResourceId = $HelpMessageResourceId } $AttributeCollection.Add( $ParameterAttribute ) # create a lenth validation if ( $ValidateLength -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateLengthAttribute').Type ) { $ParameterValidateLength = New-Object -TypeName System.Management.Automation.ValidateLengthAttribute -ArgumentList $ValidateLength $AttributeCollection.Add( $ParameterValidateLength ) } # create a range validation if ( $ValidateRange -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateRangeAttribute').Type ) { $ParameterValidateRange = New-Object -TypeName System.Management.Automation.ValidateRangeAttribute -ArgumentList $ValidateRange $AttributeCollection.Add( $ParameterValidateRange ) } # create a pattern validation if ( $ValidatePattern -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidatePatternAttribute').Type ) { $ParameterValidatePattern = New-Object -TypeName System.Management.Automation.ValidatePatternAttribute -ArgumentList $ValidatePattern $AttributeCollection.Add( $ParameterValidatePattern ) } # create a script validation if ( $ValidateScript -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateScriptAttribute').Type ) { $ParameterValidateScript = New-Object -TypeName System.Management.Automation.ValidateScriptAttribute -ArgumentList $ValidateScript $AttributeCollection.Add( $ParameterValidateScript ) } # create a count validation if ( $ValidateCount -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateCountAttribute').Type ) { $ParameterValidateCount = New-Object -TypeName System.Management.Automation.ValidateCountAttribute -ArgumentList $ValidateCount $AttributeCollection.Add( $ParameterValidateCount ) } # create a validation set if ( $ValidateSet -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateSetAttribute').Type ) { $ParameterValidateSet = New-Object -TypeName System.Management.Automation.ValidateSetAttribute -ArgumentList $ValidateSet $AttributeCollection.Add( $ParameterValidateSet ) } # create a trusted data validation if ( $ValidateTrustedData.IsPresent -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateTrustedDataAttribute').Type ) { $ParameterValidateTrustedData = New-Object -TypeName System.Management.Automation.ValidateTrustedDataAttribute $AttributeCollection.Add( $ParameterValidateTrustedData ) } # create a drive validation if ( $ValidateDrive -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateDriveAttribute').Type ) { $ParameterValidateDrive = New-Object -TypeName System.Management.Automation.ValidateDriveAttribute -ArgumentList $ValidateDrive $AttributeCollection.Add( $ParameterValidateDrive ) } # create a not null validation if ( $ValidateNotNull.IsPresent -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateNotNullAttribute').Type ) { $ParameterValidateNotNull = New-Object -TypeName System.Management.Automation.ValidateNotNullAttribute $AttributeCollection.Add( $ParameterValidateNotNull ) } # create a not null or empty validation if ( $ValidateNotNullOrEmpty.IsPresent -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ValidateNotNullOrEmptyAttribute').Type ) { $ParameterValidateNotNullOrEmpty = New-Object -TypeName System.Management.Automation.ValidateNotNullOrEmptyAttribute $AttributeCollection.Add( $ParameterValidateNotNullOrEmpty ) } # create aliases if specified if( $Alias ) { $ParameterAlias = New-Object -TypeName System.Management.Automation.AliasAttribute -ArgumentList $Alias $AttributeCollection.Add( $ParameterAlias ) } # create argument completer if specified if ( $ArgumentCompleter -and [bool]([System.Management.Automation.PSTypeName]'System.Management.Automation.ArgumentCompleterAttribute').Type ) { $ParameterArgumentCompleter = New-Object -TypeName System.Management.Automation.ArgumentCompleterAttribute ( $ArgumentCompleter ) $AttributeCollection.Add( $ParameterArgumentCompleter ) } # create the parameter object $Parameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter -ArgumentList @( $Name, $Type, $AttributeCollection ) #Add the dynamic parameter to an existing dynamic parameter dictionary, or create the dictionary and add it if( $DPDictionary ) { $DPDictionary.Add( $Name, $Parameter ) } else { Write-Output $Parameter } } <# .SYNOPSIS Creates a dictionary of dynamic parameters. .DESCRIPTION Creates a RuntimeDefinedParameterDictionary of 0 or more DynamicParameters. .PARAMETER DynamicParameters Dynamic parameters to be included. .PARAMETER ScriptBlock Script block to execute to generate the Dynamic Parameters. .EXAMPLE DynamicParameterDictionary { DynamicParameter -Name Param1 -Mandatory DynamicParameter -Name Param2 -ValidateSet 'Item1', 'Item2' } .EXAMPLE $Param1 = DynamicParameter -Name Param1 -Mandatory $Param2 = DynamicParameter -Name Param2 -ValidateSet 'Item1', 'Item2' DynamicParameterDictionary $Param1, $Param2 #> function New-DynamicParameterDictionary { [CmdletBinding(DefaultParameterSetName='Default')] [OutputType([System.Management.Automation.RuntimeDefinedParameterDictionary])] param( [Parameter(Mandatory=$false, Position=0, ParameterSetName='Default')] [System.Management.Automation.RuntimeDefinedParameter[]] $DynamicParameters, [Parameter(Mandatory=$true, Position=0, ParameterSetName='ScriptBlock')] [scriptblock] $ScriptBlock ) begin { $DynamicParameterDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary if ( $PSCmdlet.ParameterSetName -eq 'ScriptBlock' ) { $DynamicParameters = $ScriptBlock.Invoke() } } process { foreach ( $DynamicParameterItem in $DynamicParameters ) { $DynamicParameterDictionary.Add( $DynamicParameterItem.Name, $DynamicParameterItem) > $null } } end { Write-Output $DynamicParameterDictionary } } New-Alias -Name DynamicParameter -Value New-DynamicParameter New-Alias -Name DynamicParameterDictionary -Value New-DynamicParameterDictionary # SIG # Begin signature block # MIIesgYJKoZIhvcNAQcCoIIeozCCHp8CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQULCiRiCXRl54uY0fW8u2koZrk # awqgghm9MIIEhDCCA2ygAwIBAgIQQhrylAmEGR9SCkvGJCanSzANBgkqhkiG9w0B # AQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNV # BAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRU # cnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTA1MDYwNzA4MDkxMFoXDTIwMDUzMDEw # NDgzOFowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2Fs # dCBMYWtlIENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8G # A1UECxMYaHR0cDovL3d3dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNF # UkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6q # gT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x # 2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ # w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbH # d2pBnqcP1/vulBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh # 2JU022R5KP+6LhHC5ehbkkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzT # bafc8H9vg2XiaquHhnUCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rE # JlTvA73gJMtUGjAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwDgYDVR0P # AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQG # A1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVz # dEV4dGVybmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGG # GWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEFBQADggEBAE1C # L6bBiusHgJBYRoz4GTlmKjxaLG3P1NmHVY15CxKIe0CP1cf4S41VFmOtt1fcOyu9 # 08FPHgOHS0Sb4+JARSbzJkkraoTxVHrUQtr802q7Zn7Knurpu9wHx8OSToM8gUmf # ktUyCepJLqERcZo20sVOaLbLDhslFq9s3l122B9ysZMmhhfbGN6vRenf+5ivFBjt # pF72iZRF8FUESt3/J90GSkD2tLzx5A+ZArv9XQ4uKMG+O18aP5cQhLwWPtijnGMd # ZstcX9o+8w8KCTUi29vAPwD55g1dZ9H9oB4DK9lA977Mh2ZUgKajuPUZYtXSJrGY # Ju6ay0SnRVqBlRUa9VEwggTmMIIDzqADAgECAhBiXE2QjNVC+6supXM/8VQZMA0G # CSqGSIb3DQEBBQUAMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNV # BAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdv # cmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEdMBsGA1UEAxMU # VVROLVVTRVJGaXJzdC1PYmplY3QwHhcNMTEwNDI3MDAwMDAwWhcNMjAwNTMwMTA0 # ODM4WjB6MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVy # MRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEg # MB4GA1UEAxMXQ09NT0RPIFRpbWUgU3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3DQEB # AQUAA4IBDwAwggEKAoIBAQCqgvGEqVvYcbXSXSvt9BMgDPmb6dGPdF5u7uspSNjI # vizrCmFgzL2SjXzddLsKnmhOqnUkcyeuN/MagqVtuMgJRkx+oYPp4gNgpCEQJ0Ca # WeFtrz6CryFpWW1jzM6x9haaeYOXOh0Mr8l90U7Yw0ahpZiqYM5V1BIR8zsLbMaI # upUu76BGRTl8rOnjrehXl1/++8IJjf6OmqU/WUb8xy1dhIfwb1gmw/BC/FXeZb5n # OGOzEbGhJe2pm75I30x3wKoZC7b9So8seVWx/llaWm1VixxD9rFVcimJTUA/vn9J # AV08m1wI+8ridRUFk50IYv+6Dduq+LW/EDLKcuoIJs0ZAgMBAAGjggFKMIIBRjAf # BgNVHSMEGDAWgBTa7WR0FJwUPKvdmam9WyhNizzJ2DAdBgNVHQ4EFgQUZCKGtkqJ # yQQP0ARYkiuzbj0eJ2wwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C # AQAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAAMEIGA1Ud # HwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZp # cnN0LU9iamVjdC5jcmwwdAYIKwYBBQUHAQEEaDBmMD0GCCsGAQUFBzAChjFodHRw # Oi8vY3J0LnVzZXJ0cnVzdC5jb20vVVROQWRkVHJ1c3RPYmplY3RfQ0EuY3J0MCUG # CCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEB # BQUAA4IBAQARyT3hBeg7ZazJdDEDt9qDOMaSuv3N+Ntjm30ekKSYyNlYaDS18Ash # U55ZRv1jhd/+R6pw5D9eCJUoXxTx/SKucOS38bC2Vp+xZ7hog16oYNuYOfbcSV4T # p5BnS+Nu5+vwQ8fQL33/llqnA9abVKAj06XCoI75T9GyBiH+IV0njKCv2bBS7vzI # 7bec8ckmONalMu1Il5RePeA9NbSwyVivx1j/YnQWkmRB2sqo64sDvcFOrh+RMrjh # JDt77RRoCYaWKMk7yWwowiVp9UphreAn+FOndRWwUTGw8UH/PlomHmB+4uNqOZrE # 6u4/5rITP1UDBE0LkHLU6/u8h5BRsjgZMIIE/jCCA+agAwIBAgIQK3PbdGMRTFpb # MkryMFdySTANBgkqhkiG9w0BAQUFADB6MQswCQYDVQQGEwJHQjEbMBkGA1UECBMS # R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD # T01PRE8gQ0EgTGltaXRlZDEgMB4GA1UEAxMXQ09NT0RPIFRpbWUgU3RhbXBpbmcg # Q0EwHhcNMTkwNTAyMDAwMDAwWhcNMjAwNTMwMTA0ODM4WjCBgzELMAkGA1UEBhMC # R0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9y # ZDEYMBYGA1UECgwPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDDCJTZWN0aWdvIFNI # QS0xIFRpbWUgU3RhbXBpbmcgU2lnbmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A # MIIBCgKCAQEAv1I2gjrcdDcNeNV/FlAZZu26GpnRYziaDGayQNungFC/aS42Lwpn # P0ChSopjNZvQGcx0qhcZkSu1VSAZ+8AaOm3KOZuC8rqVoRrYNMe4iXtwiHBRZmns # d/7GlHJ6zyWB7TSCmt8IFTcxtG2uHL8Y1Q3P/rXhxPuxR3Hp+u5jkezx7M5ZBBF8 # rgtgU+oq874vAg/QTF0xEy8eaQ+Fm0WWwo0Si2euH69pqwaWgQDfkXyVHOaeGWTf # dshgRC9J449/YGpFORNEIaW6+5H6QUDtTQK0S3/f4uA9uKrzGthBg49/M+1BBuJ9 # nj9ThI0o2t12xr33jh44zcDLYCQD3npMqwIDAQABo4IBdDCCAXAwHwYDVR0jBBgw # FoAUZCKGtkqJyQQP0ARYkiuzbj0eJ2wwHQYDVR0OBBYEFK7u2WC6XvUsARL9jo2y # VXI1Rm/xMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQM # MAoGCCsGAQUFBwMIMEAGA1UdIAQ5MDcwNQYMKwYBBAGyMQECAQMIMCUwIwYIKwYB # BQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMEIGA1UdHwQ7MDkwN6A1oDOG # MWh0dHA6Ly9jcmwuc2VjdGlnby5jb20vQ09NT0RPVGltZVN0YW1waW5nQ0FfMi5j # cmwwcgYIKwYBBQUHAQEEZjBkMD0GCCsGAQUFBzAChjFodHRwOi8vY3J0LnNlY3Rp # Z28uY29tL0NPTU9ET1RpbWVTdGFtcGluZ0NBXzIuY3J0MCMGCCsGAQUFBzABhhdo # dHRwOi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAen+pStKw # pBwdDZ0tXMauWt2PRR3wnlyQ9l6scP7T2c3kGaQKQ3VgaoOkw5mEIDG61v5MzxP4 # EPdUCX7q3NIuedcHTFS3tcmdsvDyHiQU0JzHyGeqC2K3tPEG5OfkIUsZMpk0uRlh # dwozkGdswIhKkvWhQwHzrqJvyZW9ljj3g/etfCgf8zjfjiHIcWhTLcuuquIwF4Mi # KRi14YyJ6274fji7kE+5Xwc0EmuX1eY7kb4AFyFu4m38UnnvgSW6zxPQ+90rzYG2 # V4lO8N3zC0o0yoX/CLmWX+sRE+DhxQOtVxzhXZIGvhvIPD+lIJ9p0GnBxcLJPufF # cvfqG5bilK+GLjCCBUwwggQ0oAMCAQICEQCV7K1bRdp1yZPPBYrFbG8VMA0GCSqG # SIb3DQEBCwUAMHwxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNo # ZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRl # ZDEkMCIGA1UEAxMbU2VjdGlnbyBSU0EgQ29kZSBTaWduaW5nIENBMB4XDTE5MTAx # NTAwMDAwMFoXDTIwMTAwNzIzNTk1OVowgZQxCzAJBgNVBAYTAlVTMQ4wDAYDVQQR # DAU2MDEyMDERMA8GA1UECAwISWxsaW5vaXMxDjAMBgNVBAcMBUVsZ2luMRowGAYD # VQQJDBExMjg3IEJsYWNraGF3ayBEcjEaMBgGA1UECgwRU2hhbm5vbiBHcmF5YnJv # b2sxGjAYBgNVBAMMEVNoYW5ub24gR3JheWJyb29rMIIBIjANBgkqhkiG9w0BAQEF # AAOCAQ8AMIIBCgKCAQEA1A3wiJRalXGleCYOLaKdlD5iZrswpu4ChSnCx8XvkWeL # R/XBQSvebJXpF99sdVwwUeouEk1i5EA2AIU88DoEw0+1XxC6DAUwYAVXmo3M+dkv # OwNXHrWwSRqNwmhABHVejGOInKsi1jYa3DPI2dFBL19Trg0ez0oXkMVwbKGDpwt9 # U7WbbjveLcAPnpvR65dk3Jhb9bmCMirCnALjaOOnFzlCUiagx9nDszzw7fYRAlf6 # EJNnicwwBujOmA59q9urwAuEA7/VXTAMpE2wmhVsM4xqscbzAPs7PSVgkOTrZR6a # 51r1HSCzrULISVZKxF0mD4/6qOElqM/X/nd7q7dmSQIDAQABo4IBrjCCAaowHwYD # VR0jBBgwFoAUDuE6qFM6MdWKvsG7rWcaA4WtNA4wHQYDVR0OBBYEFJHiTLW7XSJv # Xn/hpQzh7bxSIUZ2MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMGA1Ud # JQQMMAoGCCsGAQUFBwMDMBEGCWCGSAGG+EIBAQQEAwIEEDBABgNVHSAEOTA3MDUG # DCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29t # L0NQUzBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLnNlY3RpZ28uY29tL1Nl # Y3RpZ29SU0FDb2RlU2lnbmluZ0NBLmNybDBzBggrBgEFBQcBAQRnMGUwPgYIKwYB # BQUHMAKGMmh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1JTQUNvZGVTaWdu # aW5nQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAm # BgNVHREEHzAdgRtzaGFubm9uLmdyYXlicm9va0BnbWFpbC5jb20wDQYJKoZIhvcN # AQELBQADggEBACNm23H5GuT8THomfaxBDdgN/4g4FgsClLsxhAyRyWxqnE4udxre # x1Dq3FQtdXoeXFPaaFYVH/zvmEFuh+oz65Ejomo2WPSOVKiF6NbLpxScHW2c1+yO # NHDqn/TGtx0+RrfUgOFgao/AzuRqxei90CotgUe73cpmG0JPdmV1+hnMAhojoO4g # bhfdb69y8fCaDzLoTmybz1JOfcinR12TLntNV+Def2CXaNoOV2VNKpauAiIh2BkK # 7LoabyBtMNQbMNCY33dyNq9V7tvVxdYOlPRoANB3SfATPtKQCrix7T85qrFoRHBC # SxTfYFHsyGQVno6lmMfQstJ6q+TQJz1gFcUwggX1MIID3aADAgECAhAdokgwb5sm # GNCC4JZ9M9NqMA0GCSqGSIb3DQEBDAUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE # CBMKTmV3IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRo # ZSBVU0VSVFJVU1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0 # aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xODExMDIwMDAwMDBaFw0zMDEyMzEyMzU5 # NTlaMHwxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIx # EDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEkMCIG # A1UEAxMbU2VjdGlnbyBSU0EgQ29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEAhiKNMoV6GJ9J8JYvYwgeLdx8nxTP4ya2JWYpQIZU # RnQxYsUQ7bKHJ6aZy5UwwFb1pHXGqQ5QYqVRkRBq4Etirv3w+Bisp//uLjMg+gwZ # iahse60Aw2Gh3GllbR9uJ5bXl1GGpvQn5Xxqi5UeW2DVftcWkpwAL2j3l+1qcr44 # O2Pej79uTEFdEiAIWeg5zY/S1s8GtFcFtk6hPldrH5i8xGLWGwuNx2YbSp+dgcRy # QLXiX+8LRf+jzhemLVWwt7C8VGqdvI1WU8bwunlQSSz3A7n+L2U18iLqLAevRtn5 # RhzcjHxxKPP+p8YU3VWRbooRDd8GJJV9D6ehfDrahjVh0wIDAQABo4IBZDCCAWAw # HwYDVR0jBBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFA7hOqhT # OjHVir7Bu61nGgOFrTQOMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/ # AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMDBggrBgEFBQcDCDARBgNVHSAECjAIMAYG # BFUdIAAwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2VydHJ1c3QuY29t # L1VTRVJUcnVzdFJTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHYGCCsGAQUF # BwEBBGowaDA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VT # RVJUcnVzdFJTQUFkZFRydXN0Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2Nz # cC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBDAUAA4ICAQBNY1DtRzRKYaTb3moq # jJvxAAAeHWJ7Otcywvaz4GOz+2EAiJobbRAHBE++uOqJeCLrD0bs80ZeQEaJEvQL # d1qcKkE6/Nb06+f3FZUzw6GDKLfeL+SU94Uzgy1KQEi/msJPSrGPJPSzgTfTt2Sw # piNqWWhSQl//BOvhdGV5CPWpk95rcUCZlrp48bnI4sMIFrGrY1rIFYBtdF5KdX6l # uMNstc/fSnmHXMdATWM19jDTz7UKDgsEf6BLrrujpdCEAJM+U100pQA1aWy+nyAl # EA0Z+1CQYb45j3qOTfafDh7+B1ESZoMmGUiVzkrJwX/zOgWb+W/fiH/AI57SHkN6 # RTHBnE2p8FmyWRnoao0pBAJ3fEtLzXC+OrJVWng+vLtvAxAldxU0ivk2zEOS5LpP # 8WKTKCVXKftRGcehJUBqhFfGsp2xvBwK2nxnfn0u6ShMGH7EezFBcZpLKewLPVdQ # 0srd/Z4FUeVEeN0B3rF1mA1UJP3wTuPi+IO9crrLPTru8F4XkmhtyGH5pvEqCgul # ufSe7pgyBYWe6/mDKdPGLH29OncuizdCoGqC7TtKqpQQpOEN+BfFtlp5MxiS47V1 # +KHpjgolHuQe8Z9ahyP/n6RRnvs5gBHN27XEp6iAb+VT1ODjosLSWxr6MiYtaldw # HDykWC6j81tLB9wyWfOHpxptWDGCBF8wggRbAgEBMIGRMHwxCzAJBgNVBAYTAkdC # MRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQx # GDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEkMCIGA1UEAxMbU2VjdGlnbyBSU0Eg # Q29kZSBTaWduaW5nIENBAhEAleytW0XadcmTzwWKxWxvFTAJBgUrDgMCGgUAoHgw # GAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGC # NwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQx # FgQU4oTPa2PvI1rt56LIk9LYQSCVt1AwDQYJKoZIhvcNAQEBBQAEggEALxqMgP3Z # C6rk7cCzdv2qf36W/Gdf1WUp+kTwycI8+HLYEktjCl7HL8AlwY0A8u4Zrq45Bl+t # siToLA0yDtGLlwsltTc1T0z+r2ROL7yQcTv6+Sa6yjwdnbGfsyL/dpKWckmJ49NX # W31NsY1FcQcxy/ckA+S2BiAfX1q87H6fHez6R/KrhpYWMHcOPGdcJ9UNFdXiDlJ/ # 64G+TBo+Rute/x+ED0U5XyJBVX3wUrU9fo8X9ZQqUqAheMaNVy2Z8z6QdFaUeEw/ # IRKQCTs2y/tkgw8ZlFe6utvj1z3SWr38gQ5v0dbBhiapMexhOS1pBqkqaHL+BYdf # eT9PlrzytMo8lKGCAigwggIkBgkqhkiG9w0BCQYxggIVMIICEQIBATCBjjB6MQsw # CQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQH # EwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEgMB4GA1UEAxMX # Q09NT0RPIFRpbWUgU3RhbXBpbmcgQ0ECECtz23RjEUxaWzJK8jBXckkwCQYFKw4D # AhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8X # DTIwMDEyMzIwMTMwOVowIwYJKoZIhvcNAQkEMRYEFH7r/B4CobLsa4kbYO3Vyhwn # Oqn4MA0GCSqGSIb3DQEBAQUABIIBAAab9Tt/pV9bYVFQABulKAicU/W9LFnfHe7j # LH4aPqN3SB/wBcL1/XWp5JF1Mgw/8trpU3wC8lpsdUEJRG3MLRJn/vP9+YgfUiod # DLqr5a4IZcW1UG0sVAo7citWRl1bwNq6gsqEGOAQrxdKOP3kdVIre71/W1oqqIg2 # K0XgFQCn0UrHqV8rFs+273r4UmJUn7uqDO1dC9c5voeiiO0YstXlNTSPEoBo5vss # Bc4vto7xJJOrbupcp7t+qtleG9BNNp/jmxc/xqk85JYwrkN9n+OxLT70Q1+snVtE # qjeQbfYXLlgn9MkjRF2tzuih3YvOO2+MeMrtBVqoNK9vGVOxpUA= # SIG # End signature block |