Public/SEPPmailAPI-Statistics.ps1
|
<#
.SYNOPSIS Gets usage statistics of your SEPPmail appliance. .DESCRIPTION Queries the SEPPmail API endpoint /statistics and returns what the appliance has processed over time. The result can be limited to user or domain statistics and - in MSP / multi-customer environments - calculated on a per-customer basis. .PARAMETER customerStatistics If $true, statistics are calculated on a per-customer basis. Can be narrowed down with the -customer parameter. Default: $false .PARAMETER customer Filters the statistics type that is returned. Valid values: 'user', 'domain', 'all'. Default: '[default]' .PARAMETER SMAHost SEPPmail API hostname. Defaults to the configured value. .PARAMETER SMAPort SEPPmail API port. Defaults to the configured value. .PARAMETER SMAVersion SEPPmail API version. Defaults to the configured value. .PARAMETER SMACred API credentials (PSCredential). Defaults to the configured value. .PARAMETER SMASkipCertCheck Skip SSL certificate validation. Use only in test environments. .OUTPUTS System.Management.Automation.PSCustomObject Returns the user statistics or domain statistics object. .NOTES - Requires an active SEPPmail API session (New-SMAConfiguration). - Alias: Get-SMAStat .LINK Get-SMALicense .LINK Get-SMALftStatistics .EXAMPLE PS C:\> Get-SMAStatistics Returns all available statistics (default). .EXAMPLE PS C:\> Get-SMAStatistics -customer user Filters the statistics to user data. .EXAMPLE PS C:\> Get-SMAStatistics -customer domain Filters the statistics to domain data. .EXAMPLE PS C:\> Get-SMAStatistics -customerStatistics $true Calculates the statistics on a per-customer basis. #> function Get-SMAStatistics { [CmdletBinding()] param ( #region API parameters [Parameter( Mandatory = $false, HelpMessage = 'Calculate statistics on a per-customer basis. Can be limited via the customer parameter' )] [bool]$customerStatistics = $false, [Parameter( Mandatory = $false, HelpMessage = 'Filter to a specific customer type' )] [ValidateSet('user', 'domain', 'all')] [String]$customer = '[default]', #endregion API parameters #region Config parameters block [Parameter(Mandatory = $false)] [String]$SMAHost = $Script:activeCfg.SMAHost, [Parameter(Mandatory = $false)] [int]$SMAPort = $Script:activeCfg.SMAPort, [Parameter(Mandatory = $false)] [String]$SMAVersion = $Script:activeCfg.SMAPIVersion, [Parameter( Mandatory=$false )] [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred, [Parameter( Mandatory=$false )] [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck #endregion ) begin { if (! (verifyVars -VarList $Script:requiredVarList)) { Throw($missingVarsMessage); }; # end if $smaParams = @{ Host = $SMAHost Port = $SMAPort Version = $SMAVersion } # end smaParams Write-Verbose "Creating URL path" $uriPath = "{0}" -f 'statistics' } process { Write-Verbose "Building full request uri" $uri = $null $boundParam = @{ customerStatistics = $customerstatistics customer = $customer } $uri = New-SMAQueryString -uriPath $uriPath -qParam $boundParam @smaParams Write-verbose "Crafting InvokeParam for Invoke-SMARestMethod" $invokeParam = @{ Uri = $uri Method = 'GET' Cred = $SMACred SkipCertCheck = $SMASkipCertCheck } Write-Verbose "Replace wrong '%40' value with '@'" $invokeparam.Uri = ($invokeParam.Uri).Replace('%40','@') Write-Verbose "Call Invoke-SMARestMethod $uri" $statsInfo = Invoke-SMARestMethod @invokeParam #Write-Verbose 'Converting Umlauts from ISO-8859-1' #Encinfo = ConvertFrom-SMAPIFormat -inputObject $encInfoRaw # Userobject if ($statsInfo) { if ($StatsInfo.User) { return $statsInfo.User } if ($StatsInfo.Domain) { return $statsInfo.Domain } } } end { } } <# .SYNOPSIS Retrieves license statistics from your SEPPmail appliance. .DESCRIPTION The Get-SMALicense CmdLet queries the SEPPmail API endpoint /statistics/license for license information. It has 2 outputs. Either License information or customer license statistics information (for MSPs or multi-customer environments) .PARAMETER Customer Returns license information for a specific customer (tenant). .PARAMETER CustomerStatistics Returns usage statistics per appliance-customer instead of the plain license object. Alias: stats .PARAMETER showGlobal Returns the global license usage statistics of the appliance. Alias: global .PARAMETER SMAVersion SEPPmail API version. Defaults to the configured value. .PARAMETER SMAHost SEPPmail API hostname. Defaults to the configured value. .PARAMETER SMAPort SEPPmail API port. Defaults to the configured value. .PARAMETER SMACred API credentials (PSCredential). Defaults to the configured value. .PARAMETER SMASkipCertCheck Skip SSL certificate validation. Use only in test environments. .OUTPUTS System.Management.Automation.PSCustomObject Without parameters: the license object. With -showGlobal: the global usage statistics. With -CustomerStatistics: an array of per-customer usage statistics. With -Customer: the usage statistics of the specified customer. .EXAMPLE PS C:\> Get-SMALicense Emits the appliance license information. .EXAMPLE PS C:\> Get-SMALicense -CustomerStatistics Emits the usage statistics per appliance-customer. .EXAMPLE PS C:\> Get-SMALicense -showGlobal Emits the usage statistics of the appliance globally. .EXAMPLE PS C:\> Get-SMALicense -Customer "Contoso" Emits the usage statistics for a particular customer. .LINK Get-SMAStatistics .LINK Get-SMALftStatistics .NOTES Available parameters may vary depending on appliance and API version. Alias: Get-SMALic #> function Get-SMALicense { [CmdletBinding()] param ( #api Params [Parameter( Mandatory = $false, HelpMessage = 'Returns license information for a specific customer (tenant).' )] [string]$Customer, [Parameter( Mandatory = $false, HelpMessage = 'Returns license information for a specific customer (tenant).' )] [Alias("stats")] [switch]$CustomerStatistics, [Parameter( Mandatory = $false, HelpMessage = 'Returns global license statistics.' )] [Alias("global")] [switch]$showGlobal, #endregion API parameters #region SMA Config Params [Parameter( Mandatory = $false, HelpMessage = 'API version to use.' )] [string]$SMAVersion = $Script:activeCfg.SMAPIVersion, [Parameter( Mandatory = $false, HelpMessage = 'Hostname or IP of the SEPPmail appliance.' )] [string]$SMAHost = $Script:activeCfg.SMAHost, [Parameter( Mandatory = $false, HelpMessage = 'Port for the SEPPmail API.' )] [int]$SMAPort = $Script:activeCfg.SMAPort, [Parameter(Mandatory = $false)] [System.Management.Automation.PSCredential]$SMACred = $Script:activeCfg.SMACred, [Parameter(Mandatory = $false)] [switch]$SMASkipCertCheck = $Script:activeCfg.SMAskipCertCheck #endregion ) begin { if (! (verifyVars -VarList $Script:requiredVarList)) { Throw($missingVarsMessage); } Write-Verbose "Creating URL path for license statistics" $uriPath = "statistics/license" $smaParams = @{ Host = $SMAHost Port = $SMAPort Version = $SMAVersion } } process { Write-Verbose "Building full request uri" if ($customer) {$CustomerStatistics = $true} $boundParam = @{ customerStatistics = $customerStatistics } if ($Customer) { $boundParam.customer = $Customer } $uri = New-SMAQueryString -uriPath $uriPath -qParam $boundParam @smaParams Write-Verbose "Crafting InvokeParam for Invoke-SMARestMethod" $invokeParam = @{ Uri = $uri Method = 'GET' Cred = $SMACred SkipCertCheck = $SMASkipCertCheck } Write-Verbose "Replace wrong '%40' value with '@'" $invokeParam.Uri = ($invokeParam.Uri).Replace('%40','@') Write-Verbose "Call Invoke-SMARestMethod $($invokeParam.Uri)" $licenseInfo = Invoke-SMARestMethod @invokeParam if ($licenseInfo) { # Keine Parameter gesetzt ==> OK if ((!($customer)) -and (!($customerStatistics)) -and (!($showGlobal))) { Write-Output $licenseInfo.License } # Global statistics if ((!($customer)) -and (!($customerStatistics)) -and ($showGlobal)) { Write-Output $licenseInfo.statistics.global } # Customerusage if ((!($customer)) -and ($customerStatistics)) { $outPutObj = $licenseInfo.statistics.customers.PSObject.Properties | ForEach-Object { $obj = [PSCustomObject]@{ customerName = $_.Name } # Alle Properties aus dem Originalobjekt hinzufügen $_.Value.PSObject.Properties | ForEach-Object { $obj | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_.Value } $obj } Write-Output $outPutObj } # specific customer if (($customer) -and (!($showGlobal))) { Write-Output $licenseInfo.statistics.customers.$customer } } else { Write-Information 'No license information found, nothing to return' } } end { # Cleanup or final actions can be added here if needed } } <# .SYNOPSIS Gets LFT (Large File Transfer) statistics from your SEPPmail appliance. .DESCRIPTION Queries the SEPPmail API endpoints under /statistics/lft and returns Large File Transfer usage statistics. You must select exactly one scope via the mutually exclusive switches -CustomerStats, -UserStats, -DomainStats or -GroupStats. Within each scope you can optionally narrow down to a single entity and define a date or date range. .PARAMETER CustomerStats Selects the customer scope (parameter set 'Customer'). Returns LFT statistics for all customers or, with -customer, a single customer. .PARAMETER UserStats Selects the user scope (parameter set 'User'). Returns LFT statistics for all users or, with -user, a single user. .PARAMETER DomainStats Selects the domain scope (parameter set 'Domain'). Returns LFT statistics for all domains or, with -domain, a single domain. .PARAMETER GroupStats Selects the group scope (parameter set 'Group'). Returns LFT statistics for all groups or, with -group, a single group. .PARAMETER customer Specific customer name. Omit to return statistics for all customers. ('Customer' parameter set.) .PARAMETER user Specific user e-mail. Omit to return statistics for all users. ('User' parameter set.) .PARAMETER domain Specific domain name. Omit to return statistics for all domains. ('Domain' parameter set.) .PARAMETER group Specific group name. Omit to return statistics for all groups. ('Group' parameter set.) .PARAMETER date A specific date for the statistics (format: YYYY-MM-DD). .PARAMETER startdate Start date of a statistics range (format: YYYY-MM-DD). .PARAMETER enddate End date of a statistics range (format: YYYY-MM-DD). .PARAMETER split Splits the statistics by a sub-dimension. Valid values depend on the scope: - Customer: 'domain', 'group', 'user' - Domain: 'group', 'user' - Group: 'user' - User: not allowed .PARAMETER SMAHost SEPPmail API hostname. Defaults to the configured value. .PARAMETER SMAPort SEPPmail API port. Defaults to the configured value. .PARAMETER SMAVersion SEPPmail API version. Defaults to the configured value. .PARAMETER SMACred API credentials (PSCredential). Defaults to the configured value. .PARAMETER SMASkipCertCheck Skip SSL certificate validation. Use only in test environments. .OUTPUTS System.Management.Automation.PSCustomObject Returns the LFT statistics (with umlaut/unicode conversion applied). .NOTES - Requires an active SEPPmail API session (New-SMAConfiguration). - Exactly one of -CustomerStats/-UserStats/-DomainStats/-GroupStats must be specified. - Alias: Get-SMALftStat .LINK Get-SMAStatistics .LINK Get-SMALicense .EXAMPLE PS C:\> Get-SMALftStatistics -CustomerStats Returns LFT statistics for all customers. .EXAMPLE PS C:\> Get-SMALftStatistics -DomainStats -domain 'contoso.com' -split user Returns LFT statistics for 'contoso.com', split by user. .EXAMPLE PS C:\> Get-SMALftStatistics -UserStats -user 'alice@contoso.com' -startdate 2026-01-01 -enddate 2026-01-31 Returns LFT statistics for a single user over a date range. #> function Get-SMALftStatistics { [CmdletBinding()] param ( #region API parameters # Parameter set switches - user MUST choose one [Parameter( Mandatory = $true, ParameterSetName = 'Customer', HelpMessage = 'Get customer statistics (all or specific customer)' )] [switch]$CustomerStats, [Parameter( Mandatory = $true, ParameterSetName = 'User', HelpMessage = 'Get user statistics (all or specific user)' )] [switch]$UserStats, [Parameter( Mandatory = $true, ParameterSetName = 'Domain', HelpMessage = 'Get domain statistics (all or specific domain)' )] [switch]$DomainStats, [Parameter( Mandatory = $true, ParameterSetName = 'Group', HelpMessage = 'Get group statistics (all or specific group)' )] [switch]$GroupStats, # Optional detail parameters for each set [Parameter( Mandatory = $false, ParameterSetName = 'Customer', ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specific customer name (optional - omit for all customers)' )] [string]$customer, [Parameter( Mandatory = $false, ParameterSetName = 'User', ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specific user email (optional - omit for all users)' )] [string]$user, [Parameter( Mandatory = $false, ParameterSetName = 'Domain', ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specific domain name (optional - omit for all domains)' )] [string]$domain, [Parameter( Mandatory = $false, ParameterSetName = 'Group', ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specific group name (optional - omit for all groups)' )] [string]$group, # Common parameters for all parameter sets [Parameter( Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specific date for statistics (format: YYYY-MM-DD)' )] [datetime]$date, [Parameter( Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Start date for statistics range (format: YYYY-MM-DD)' )] [datetime]$startdate, [Parameter( Mandatory = $false, ValueFromPipelineByPropertyName = $true, HelpMessage = 'End date for statistics range (format: YYYY-MM-DD)' )] [datetime]$enddate, # Split parameter - validation depends on parameter set (validated in begin block) [Parameter( Mandatory = $false, ParameterSetName = 'Customer', ValueFromPipelineByPropertyName = $true, HelpMessage = 'Split statistics by domain, group or user (depending on context)' )] [Parameter( Mandatory = $false, ParameterSetName = 'Domain', ValueFromPipelineByPropertyName = $true, HelpMessage = 'Split statistics by group or user' )] [Parameter( Mandatory = $false, ParameterSetName = 'Group', ValueFromPipelineByPropertyName = $true, HelpMessage = 'Split statistics by user' )] [string]$split, #endregion API parameters #region Config parameters block [Parameter(Mandatory = $false)] [String]$SMAHost = $Script:activeCfg.SMAHost, [Parameter(Mandatory = $false)] [int]$SMAPort = $Script:activeCfg.SMAPort, [Parameter(Mandatory = $false)] [String]$SMAVersion = $Script:activeCfg.SMAPIVersion, [Parameter( Mandatory=$false )] [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred, [Parameter( Mandatory=$false )] [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck #endregion ) begin { if (! (verifyVars -VarList $Script:requiredVarList)) { Throw($missingVarsMessage); } $smaParams = @{ Host = $SMAHost Port = $SMAPort Version = $SMAVersion } # end smaParams Write-Verbose "Creating URL path" $basicUriPath = "{0}/{1}" -f 'statistics','lft' } process { Write-Verbose "Convert Dates to correct formats" if ($date) { [string]$dateString = "{0:s}" -f (Get-Date $date) } if ($startDate) { [string]$startDateString = "{0:s}" -f (Get-Date $startDate) } if ($endDate) { [string]$endDateString = "{0:s}" -f (Get-Date $endDate) } Write-verbose "Validate $split parameter based on parameter set" if ($split) { $validSplitValues = switch ($PSCmdlet.ParameterSetName) { 'Customer' { @('domain', 'group', 'user') } 'Domain' { @('group', 'user') } 'Group' { @('user') } 'User' { @() } # No split allowed for User } if ($validSplitValues.Count -eq 0) { throw "The -split parameter is not valid for parameter set '$($PSCmdlet.ParameterSetName)'" } if ($split -notin $validSplitValues) { throw "Invalid value '$split' for -split parameter in parameter set '$($PSCmdlet.ParameterSetName)'. Valid values are: $($validSplitValues -join ', ')" } } Write-Verbose "Building URI path based on parameter set" $boundParam = @{} if ($dateString) {$boundParam.date = $dateString} if ($startdateString) {$boundParam.startdate = $startdateString} if ($enddateString) {$boundParam.enddate = $enddateString} if ($split) {$boundParam.split = $split} # Switch statement to build the correct URI path for each parameter set switch ($PSCmdlet.ParameterSetName) { 'Customer' { if ($customer) { $uriPath = "{0}/{1}" -f $basicUriPath, "customer/$customer" Write-Verbose "Using customer-specific path: $uriPath" } else { $uriPath = "{0}/{1}" -f $basicUriPath, 'customer' Write-Verbose "Using general customer path: $uriPath" } } 'User' { if ($user) { $uriPath = "{0}/{1}" -f $basicUriPath, "user/$user" Write-Verbose "Using user-specific path: $uriPath" } else { $uriPath = "{0}/{1}" -f $basicUriPath, 'user' Write-Verbose "Using general user path: $uriPath" } } 'Domain' { if ($domain) { $uriPath = "{0}/{1}" -f $basicUriPath, "domain/$domain" Write-Verbose "Using domain-specific path: $uriPath" } else { $uriPath = "{0}/{1}" -f $basicUriPath, 'domain' Write-Verbose "Using general domain path: $uriPath" } } 'Group' { if ($group) { $uriPath = "{0}/{1}" -f $basicUriPath, "group/$group" Write-Verbose "Using group-specific path: $uriPath" } else { $uriPath = "{0}/{1}" -f $basicUriPath, 'group' Write-Verbose "Using general group path: $uriPath" } } } Write-Verbose "Building full request uri" $uri = $null $uri = New-SMAQueryString -uriPath $uriPath -qParam $boundParam @smaParams Write-verbose "Crafting InvokeParam for Invoke-SMARestMethod" $invokeParam = @{ Uri = $uri Method = 'GET' Cred = $SMACred SkipCertCheck = $SMASkipCertCheck } Write-Verbose "Replace wrong '%40' value with '@'" $invokeparam.Uri = ($invokeParam.Uri).Replace('%40','@') Write-Verbose "Call Invoke-SMARestMethod $uri" $lftStatsInfoRaw = Invoke-SMARestMethod @invokeParam Write-Verbose 'Converting Umlauts from ISO-8859-1' # Userobject if ($lftStatsInfoRaw) { $lftStatsinfo = ConvertFrom-SMAPIFormat -inputObject $lftStatsInfoRaw return $lftStatsinfo } else { Write-Information 'No LFT statistics information found, nothing to return' } } end { } } New-Alias -Name Get-SMAStat -Value Get-SMAStatistics New-Alias -Name Get-SMALic -Value Get-SMALicense New-Alias -Name Get-SMALftStat -Value Get-SMALftStatistics # SIG # Begin signature block # MIIVyAYJKoZIhvcNAQcCoIIVuTCCFbUCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCA3bpJwWY8GKwYN # 3kEHS6EL+t9oyefr5jYDKAB7hrdZ8KCCEgQwggVvMIIEV6ADAgECAhBI/JO0YFWU # jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI # DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM # EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy # dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG # EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv # IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s # hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD # J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7 # P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme # me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz # T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q # RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz # mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc # QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T # OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/ # AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID # AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD # VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV # HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE # VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v # ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE # KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI # hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF # OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC # J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ # pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl # d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH # +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M # UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv # ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5 # NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp # BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G # CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI # ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV # DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3 # 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw # mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm # +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe # dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4 # 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM # dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY # MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU # pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV # HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG # A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1 # YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG # AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl # U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0 # aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh # w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd # OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj # cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc # WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO # hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs # zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7 # 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J # KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH # j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2 # Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/ # L9Uo2bC5a4CH2RwwggZvMIIE16ADAgECAhBIqMP3CCLHOHtOKuaWNyeFMA0GCSqG # SIb3DQEBDAUAMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0 # ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYw # HhcNMjYwNDE1MDAwMDAwWhcNMjcwNzE0MjM1OTU5WjBmMQswCQYDVQQGEwJERTEP # MA0GA1UECAwGQmF5ZXJuMSIwIAYDVQQKDBlTRVBQbWFpbCBEZXV0c2NobGFuZCBH # bWJIMSIwIAYDVQQDDBlTRVBQbWFpbCBEZXV0c2NobGFuZCBHbWJIMIICIjANBgkq # hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvAFzE8MbJpvQt+IdIh1M+bKYsJBFDk4b # 9ySe25IrCi00B9o5XmQtIw42MqyIKbUq1tDARtp9KTQedEP9W+rflAF2l+0Z046J # kiqumU9/enbqWLDyln1aS/p7HOgwZFMhnsR9zH0MfFckiklUmkzJO+vmzYAK7ZmD # xajNLJs0gkGRU2/BecAx/TSvLXMaKONsKZCyMKQCnwo1mCY/tFl5EgUz7YQFrPOR # BQGfQke/hkdBfQDqNRsi/J6+KhJWc6LvgQihdRg/INQbQsTxlow18NWvyFsjjueH # 7kG6HR4YKfbv07xgrsIh8xvq9ZJ1SBhLXmkg4SdoQGASjqR6o3keAX+bDRFf+hml # WWJp/FqVHR5QomF3vbK2/bbz4jAclYSPx/sPasNJ0YnKFkgmowZ7Ysa0KA0/egBg # tI4gJ+8V7zrqIVEG3rMQh9KCdMnJqP2aM9o4gUzQvE1M4x606liX9EWwdLLS+fe7 # 9o+Fzo5oH4wBE/En6hQQkzseHHu+TXCDd6zUUZ/PlTK0gTaDIRXt6UzPNqJ4RiRC # W2pNFcPt078qqVTuwKUXoE4ufxGgXKFrZlCYST/9eG1TnW2oq19nz8A333GCsL3g # poNIKvfmDyGMMNzvx2aeqn2v6e75z8kH19iGSNZ51xT+WgS9F1aIvjz08/T7XAv7 # iDPF1/gPIp8CAwEAAaOCAakwggGlMB8GA1UdIwQYMBaAFA8qyyCHKLjsb0iuK1Sm # KaoXpM0MMB0GA1UdDgQWBBS30/Tq+alF3j2BY5up8n5zpAU23DAOBgNVHQ8BAf8E # BAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAzBKBgNVHSAE # QzBBMDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3Rp # Z28uY29tL0NQUzAIBgZngQwBBAEwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2Ny # bC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcmww # eQYIKwYBBQUHAQEEbTBrMEQGCCsGAQUFBzAChjhodHRwOi8vY3J0LnNlY3RpZ28u # Y29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNydDAjBggrBgEFBQcw # AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wHgYDVR0RBBcwFYETc3VwcG9ydEBz # ZXBwbWFpbC5jaDANBgkqhkiG9w0BAQwFAAOCAYEAi7fmb5UYoemWG3CC4K2UZWVr # R6GOfi8gbJKgjPbKO4zrCrU/x6cOdyp6scKZfUEGFDf8KH6pP4pAQv1Hsbi49gU2 # kxoUWLlCiipn05qJY663DHx9hlStej/ZdEatou0wyCDiG5xD7kmG+1t6iLyyCBgE # B88tJpzTjI61qXmBTS/FGEOAsB4SDEW1ngA7bc5FOv4IUKA43hp8M+N3GeYFzDqw # JELYEfVVYheBW3o7q4VrCdfFEuaQihOtvfDfYpP6ANgekNn8HdsMT8rx9D1I50Rl # i/qQFo2BOuPyb2SIQPzJvCs5wgi5qgp1nHiN6igumu2Cz7BmGjOazGUgCSUY5Qwy # E8+F+R2tVM+2O15rfX01+e56ZfojBEiEjMwfPHs3fa3V3gokWWNwUMkton/v0R/n # l2zjmOr2okohOINZEDh9frg21zUCN5ZD8Y4zQWuiJLCvvvBZs0JR4c9xl2k2wtw/ # QLPhGU69zM3smGpRoLE8M6zvUvSU7jXjvefazUniMYIDGjCCAxYCAQEwaDBUMQsw # CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJT # ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2AhBIqMP3CCLHOHtOKuaW # NyeFMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAw # GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG # AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIM6ZNQRGdrQa9/tCPorVYdLRGm/jW6HR # xq2hNyoAJcFjMA0GCSqGSIb3DQEBAQUABIICAE9xddS0lTUxzKS/eX+QJ00h0A7K # nVVFoocuJMxKBx/es7JPEEVRg1w7NHiuUPt5rkemDcGApopzQuAU+jRj8zvamMsj # aNTGY+kSdB01/20bjeauSSiMo8HbvyQJYBHm5kYuBRPEK11/bmGmY+3K1UJ4fsXV # tyi4l9+zPZFm+mvxtPCn49NSSdUUigUo/sYXncCsb5sh/fEu8+QHBNtd7rDdNkuC # +EpZQcT0JJPoLvz6K0zZElhpvVDBqj86HBRCDlpQHL9/FBf8PxCohNph3YBmyABW # 3U2+Nj7TZxo9T/EAGRVWy7iwh4Ntr4WvCSyBEWIQDD5A73iqvpReXLZFowTvS9kf # ZxKinL79bXCWl2a5g5ypv+S3MavJsAv6RyPfYvtx+9xE7rvBkfTj8KHTZmSrjnVE # xSj4G7CYIRtkmErMQNhE64OYqiTJjLHeabR3dALhVIo5UPX7DGKIx1h2VzSQGiE0 # FBtyEjGG6cvWC57brY3u3LlcHu37uV0ou9mEiZUc8IblwFk5jo78gyi/YqtyTsw7 # wdhk0+uIyFGwmgL6HZZj+XxTO/qNdDMlhWPe9EldT+tgarT/1+N3HLLN1WoH8zK/ # tK+rgncalI4ffKcEv369NSHnIfw29LJIHKxp28HqxmcZSedkjaduBXlIuSV5aclM # BksUw3kF3AcHh5II # SIG # End signature block |