##/*****************************************************************************
##Author                :     MohanRaj S
##Purpose               :     Display the list of services and their operations
##Created               :     19/10/2017
##Modified By		    :     Prabaharan.T

$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
$PSDefaultParameterValues = @{'*:Encoding' = 'utf8'}

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$egurkhaPath=($scriptPath.Substring(0,$scriptPath.ToLower().IndexOf('egurkha')+7)).Trim()
$egEncryPath=$scriptPath+"\EGFileEncryption.psm1"
$egDatnKy=$scriptPath+"\GetDatnKeyFiles.psm1"
Import-Module $egEncryPath,$egDatnKy

clear
#<#
$TestInputs=$args
$userName=$TestInputs[0]
$Password=Eg-O365Dcr -EncStr $TestInputs[1]
$proxyserverip=$TestInputs[2]
$proxyUsr=$TestInputs[3]
$proxyPass=Eg-O365Dcr -EncStr $TestInputs[4]
$rpmea=$TestInputs[5]
$topN_DD=$TestInputs[6]

$rpArr=$rpmea.Split('#')
$reportingNam=$rpArr[0]
$meaperiod=$rpArr[1]
$allowLocalUsrAct=$rpArr[2]
$allowLocalUsr=$rpArr[3].Split(',')

$appDetails=$TestInputs[7]
if($appDetails -and $appDetails -ne 'none'){
    $appDetailsArr=($appDetails).ToString() -Split ("~!~")
    $clientId=$appDetailsArr[0]
    $tenantName=$appDetailsArr[1]
    $thumbPrint=$appDetailsArr[2]
}
#>

$azureVal=Eg-GetAzureEnv -UserName $userName
$azureEnvArr=$azureVal.Split(',')
$langPath=$egurkhaPath+'\agent\config\O365_lang.ini'
$encTyp=Eg-GetINIContent -Path $langPath -Subject 'File_Type' -Key 'encoding'

$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $Password -asplaintext -force)
$sessionOption = New-PSSessionOption -SkipRevocationCheck
if(!$proxyserverip.ToString().ToLower().Contains('none')){
    $proxyserver='http://'+$proxyserverip
    [system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($proxyserver)
    if($proxyUsr -ne 'none' -and $proxyPass -ne 'none'){
        $proxyCred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $proxyUsr, $(convertto-securestring $proxyPass -asplaintext -force)
        [system.net.webrequest]::defaultwebproxy.credentials =$proxyCred
        [system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
        $sessionOption = New-PSSessionOption -SkipRevocationCheck -ProxyAccessType WinHttpConfig -ProxyAuthentication basic -ProxyCredential $proxyCred
    }
}
if($appDetails -and $appDetails -ne 'none'){
    Connect-ExchangeOnline -CertificateThumbPrint $thumbPrint -AppID $clientId -Organization $tenantName -PSSessionOption $sessionOption -ShowBanner:$false -WarningAction SilentlyContinue
}else{
    Connect-ExchangeOnline  -ExchangeEnvironmentName $azureEnvArr[4] -ConnectionUri $azureEnvArr[1] -Credential $cred -PSSessionOption $sessionOption -WarningAction SilentlyContinue
}
$rptPath='O365/'+$reportingNam
try{
    #if((Get-PSSession).Availability -eq 'Available' -and (Get-PSSession).State -eq 'Opened'){
        $sysDat=(Get-Date).ToUniversalTime()
        $endDat=$sysDat.AddMinutes(-60)
        $startDat=$endDat.AddMinutes(-$meaperiod)
        $uniqwrkLoad=@{}
        $uniqUserClientIpwrkLoad=@{}
	$uniqClientIp=@{}
        Try{
            $writUsrAct = Eg-WriteFile -ComntRptPath $rptPath -FileName "O365UsrAct" -keyFileName "kO365UsrAct" -EgPath $egurkhaPath
            $curResCnt=0
            while($true){
                $results=Search-UnifiedAuditLog -StartDate $startDat -EndDate $endDat -SessionId ua -SessionCommand ReturnLargeSet -ResultSize 5000 |Select-Object  CreationDate,AuditData
                $results | Export-Csv $writUsrAct[1] -Append -Encoding $encTyp
                $curResCnt=$curResCnt+($results.count)
                if(($curResCnt -eq 50000) -or ($results.count -lt 5000)){
                    break
                }
            }
            $null=Protect-File  $writUsrAct[1] -Algorithm AES -KeyAsPlainText $writUsrAct[0] -RemoveSource
        }Catch{
	          $egurkhaRprtPath=  $egurkhaPath+'\agent\'+$rptPath+'\'
          $fileRead=Get-ChildItem -Path $egurkhaRprtPath |Where-Object {$_.Name -like 'kO365UsrAct*.dat'}| Sort-Object LastWriteTime -Descending | Select Name -First 1
            foreach($file in $fileRead){
                    $fileName=([String]$file.Name).Trim()
                    if([System.IO.File]::Exists(($egurkhaRprtPath+$fileName)) -eq 'True'){
                        Remove-Item $egurkhaRprtPath$fileName -Force
                    }
            }
	    }
        try{
            $readUsrAct=Eg-ReadFile -ComntRptPath $rptPath -FileName "O365UsrAct" -keyFileName "kO365UsrAct" -EgPath $egurkhaPath
            if($readUsrAct -ne $null -and [System.IO.File]::Exists($readUsrAct[1]) -eq 'True'){
                $unProtctUsrAct=$readUsrAct[1] -replace (".csv",".dat") 
                $usrActPath=Unprotect-File $unProtctUsrAct -Algorithm AES -KeyAsPlainText $readUsrAct[0]	
                $a= import-csv $usrActPath -Encoding $encTyp
                Remove-Item $usrActPath
                Eg-DeleteFiles -FilePath $readUsrAct[2] -Pattern 'O365UsrAct' -InputFile $readUsrAct[3]
                Eg-DeleteFiles -FilePath $readUsrAct[2] -Pattern 'kO365UsrAct' -InputFile $readUsrAct[4]
            }
            [System.GC]::GetTotalMemory($true) | out-null
        }
        catch{
            $errmsg=$_.Exception.Message
            Write-Error -Message $errmsg
        }
        $UniqueClientIp=@()
        $UniqueUserId=@()
        $ExcludeActv='FileAccessed','FileCheckedIn','FileCheckedOut','FileCopied','FileDeleted','FileDeletedFirstStageRecycleBin','FileDeletedSecondStageRecycleBin','FileCheckOutDiscarded','FileDownloaded','FileModified','FileMoved','FileRenamed','FileRestored','FileUploaded','PageViewed','Search-Mailbox','UserLoggedIn','UserLoginFailed'        
        foreach($b in $a){
            try{
                $activity = $b.AuditData | ConvertFrom-Json | select Workload,Operation,UserId,ClientIP
                if($activity -match '::1' -or $activity -match '<null>' -or $activity.UserId -eq 'Not Available'){
                   continue
                }
            }catch{
            }
            $entryflag=$true
            if($allowLocalUsrAct -eq $true){
                if($allowLocalUsr -contains($activity.UserId) -and $ExcludeActv -contains($activity.Operation)){
                    $entryflag=$true
                }
            }
            else{
                if($allowLocalUsr -contains($activity.UserId) -and $ExcludeActv -contains($activity.Operation)){
                    $entryflag=$false
                }
            }
            if($entryflag -and $activity -ne "" -and $activity -ne $null -and $activity.ClientIP -ne $null){
	    		if($activity.ClientIP -ne ""){
				    $ClientIp=$activity.ClientIP
			    }else{
				    continue
			    }

           		$charCount=( $ClientIp.ToCharArray() | Where-Object {$_ -eq ':'} | Measure-Object).Count 
			    if($charCount -eq 1){
			        $ClientIp=$activity.ClientIP.Split(':')[0]
			        $ClientIp=$ClientIp.Replace("[","").Replace("]","")
			    }
			    $ClientIp=$ClientIp.Trim()
			    $uniqwrkLoadkey  = $activity.Workload+'~'+$activity.Operation.Replace(" ","_")
			    $uniqClientIpkey = $activity.Workload+'~'+$ClientIp
			    $ClientIpInnerKey= $activity.UserId+'~'+$ClientIp+'~'+$activity.Operation.Replace(" ","_")
			    $uniqUserIdkey   = $activity.Workload+'~'+$activity.UserId
			    $userIdInnerKey  = $ClientIp+'~'+$activity.UserId+'~'+$activity.Operation.Replace(" ","_")
                if(-not $UniqueUserId.Contains($activity.UserId.ToLower())){
                    $UniqueUserId+=$activity.UserId.ToLower()
                }
                if(-not $UniqueClientIp.Contains($ClientIp)){
                    $UniqueClientIp+=$ClientIp
                }
			    # Total Operations
		
			    if($uniqwrkLoad.ContainsKey($uniqwrkLoadkey)){
			        $uniqwrkLoad[$uniqwrkLoadkey]=[int]$uniqwrkLoad[$uniqwrkLoadkey]+1
			    }else{
			        $uniqwrkLoad.Add($uniqwrkLoadkey,1) 
			    }

                if($uniqUserClientIpwrkLoad.ContainsKey($activity.Workload)){
                    $tmpArray=$uniqUserClientIpwrkLoad[$activity.Workload]
                    if(-not $tmpArray[0].Contains($activity.UserId)){
                        $tmpArray[0]+=" "+$activity.UserId
                    }
                    if(-not $tmpArray[1].Contains($ClientIp)){
                        $tmpArray[1]+=" "+$ClientIp
                    }
			    }else{
                    [String[]]$myArray =$activity.UserId,$ClientIp
			        $uniqUserClientIpwrkLoad.Add($activity.Workload,$myArray)
			    }

                

			    # Client Ip

			    if($uniqClientIp.ContainsKey($activity.Workload)){
			        $tmpht=$uniqClientIp[$activity.Workload]
			        if($tmpht.ContainsKey($userIdInnerKey)){
				    $tmpht[$userIdInnerKey]=[int]$tmpht[$userIdInnerKey]+1
			        }else{
				    $tmpht.Add($userIdInnerKey,1)
			        }
			    }
			    else{
			        $tmpuniqClientIp = @{}
			        $tmpuniqClientIp.Add($userIdInnerKey,1)
			        $uniqClientIp.Add($activity.Workload,$tmpuniqClientIp) 
			    }
            }
        }
    $totOpr=0
    foreach($key in $uniqwrkLoad.keys){
        Write-Host 'Audit~' $key '~' $uniqwrkLoad[$key]
        $totOpr+=$uniqwrkLoad[$key]
    }

    foreach($key in $uniqUserClientIpwrkLoad.keys){
        Write-Host 'UsersCount~' $key '~' ($uniqUserClientIpwrkLoad[$key][0].Split(" ").Length)'~' ($uniqUserClientIpwrkLoad[$key][1].Split(" ").Length)
    }

    Write-Host 'Summary~' $totOpr ~ $uniqwrkLoad.Count ~ ($UniqueUserId | select -unique).Count ~ ($UniqueClientIp| select -unique).Count
    foreach($key in $uniqClientIp.keys){
        $uniqInnerht=$uniqClientIp[$key]
        $ipList = New-Object Collections.Generic.List[String]
        $userList = New-Object Collections.Generic.List[String]
		$in =$uniqInnerht.keys | sort { $uniqInnerht.$_ } -des
		foreach($inky in $in) {
            if($ipList.Count -ge [int]$topN_DD -and $userList.Count -ge [int]$topN_DD) {
                break;
            }
            $tokens = $inky.Split('~')
            if($ipList -notcontains $tokens[0]) {
                $ipList.Add($tokens[0])
            }
            if($userList -notcontains $tokens[1]) {
                $userList.Add($tokens[1])
            }
            Write-host 'DDAudit~' $key '#' $inky  '['$uniqInnerht[$inky]']'
        }
    }
#}
$getSession=Get-PSSession -ErrorAction SilentlyContinue
if($getSession -ne $null -and $getSession -ne ''){
	Disconnect-ExchangeOnline -Confirm:$false
}
}catch
{    
	Write-Host 'Exception Occured in O365 UserActivity - ' $_.Exception.Message 
}
[System.GC]::GetTotalMemory($true) | out-null
# SIG # Begin signature block
# MIIlcAYJKoZIhvcNAQcCoIIlYTCCJV0CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBy71Xk+3S8Ylfv
# ckrNHcbQU652bkJtuCSNHNNcS8zspKCCHnIwggUwMIIEGKADAgECAhAECRgbX9W7
# ZnVTQ7VvlVAIMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV
# BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBa
# Fw0yODEwMjIxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy
# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lD
# ZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3
# DQEBAQUAA4IBDwAwggEKAoIBAQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/l
# qJ3bMtdx6nadBS63j/qSQ8Cl+YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fT
# eyOU5JEjlpB3gvmhhCNmElQzUHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqH
# CN8M9eJNYBi+qsSyrnAxZjNxPqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+
# bMt+dDk2DZDv5LVOpKnqagqrhPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLo
# LFH3c7y9hbFig3NBggfkOItqcyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIB
# yTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK
# BggrBgEFBQcDAzB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9v
# Y3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHow
# eDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl
# ZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp
# Z2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwA
# AgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAK
# BghghkgBhv1sAzAdBgNVHQ4EFgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0j
# BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7s
# DVoks/Mi0RXILHwlKXaoHV0cLToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGS
# dQ9RtG6ljlriXiSBThCk7j9xjmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6
# r7VRwo0kriTGxycqoSkoGjpxKAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo
# +MUSaJ/PQMtARKUT8OZkDCUIQjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qz
# sIzV6Q3d9gEgzpkxYz0IGhizgZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHq
# aGxEMrJmoecYpJpkUe8wggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0G
# CSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0
# IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5
# NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNV
# BAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQg
# Um9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvk
# XUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdt
# HauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu
# 34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0
# QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2
# kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM
# 1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmI
# dph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZ
# K37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72
# gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqs
# X40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyh
# HsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8E
# BTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAW
# gBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUH
# AQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYI
# KwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFz
# c3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMu
# ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAE
# CjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX
# 979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offy
# ct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3
# J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0
# d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6ts
# ds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQw
# ggYzMIIFG6ADAgECAhAImnSeuC3D7CfqZerb+DUxMA0GCSqGSIb3DQEBCwUAMHIx
# CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
# dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ
# RCBDb2RlIFNpZ25pbmcgQ0EwHhcNMjEwNTI1MDAwMDAwWhcNMjQwNTI5MjM1OTU5
# WjBxMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEplcnNleTEPMA0GA1UEBxMG
# SXNlbGluMR0wGwYDVQQKExRlRyBJbm5vdmF0aW9ucywgSW5jLjEdMBsGA1UEAxMU
# ZUcgSW5ub3ZhdGlvbnMsIEluYy4wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
# AoICAQDEZQnSmuNt/FyaBkaN3skPE6zuzJIe9pDfAZHYpsPdplqB5IT6QbS0qQSx
# Didrxuc1WJj/MXg9ujRmRi0zMkiTQBlcNMy9ev+YS+YrEJuIkVMKkqSZnixrkFl8
# 7uKAi9w1JrTMgjZrmOJAkXLzmP5/0jgSBOj05x1V4g1eGBDbFnpOMQr6luGqZVe+
# vwMHbolyU5p53QvlWzv4JsbNm4qJ+DEvaLx3kUPOSFlJl90K0a0S8Tmkt6xdJZ+n
# NR128I1GKwg8YHuaD5GWfZe9RnLJpFRG2XHXWlh8n8o1gCRQIvbeueHfz+ZrG1K9
# 16KhgGPjEvK3umhAEb5vS7MKOBEAN7f+TQ22JXAkijRkSxTIMA2nskgiMx4/Ow4x
# jN8w/KLxyUDB8FhzZeFK5RxffIp/iSlEWYKVh8rkuy0ZBE1s42OmwIFMSBm7AR+R
# 05TSuZozLBkVUscSmalhl4/PszdWE35pXnqRH95+jx4PzUTlUNCqYmIZYqr+z2OF
# uRgfuDa6EvYxdv+5GyFUNI6QVG8ggP+X7IMmiAMGlp7fHai/li+NjxmjxEXS1e/J
# LSt+wO8A1nDuam3MefQGWbDmW6DcXYJUmk1vNvUeYAfqTTIUeZZgKhQA1sEHRhH+
# Tgm+BjZvK20XtxA8nKXtQj0K7gpMCDtE6YaTB0uGZeg8IFyjQQIDAQABo4IBxDCC
# AcAwHwYDVR0jBBgwFoAUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYEFPnI
# RJrP2BNJLxoE1rWvfgwwDjZKMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggr
# BgEFBQcDAzB3BgNVHR8EcDBuMDWgM6Axhi9odHRwOi8vY3JsMy5kaWdpY2VydC5j
# b20vc2hhMi1hc3N1cmVkLWNzLWcxLmNybDA1oDOgMYYvaHR0cDovL2NybDQuZGln
# aWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwSwYDVR0gBEQwQjA2Bglg
# hkgBhv1sAwEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20v
# Q1BTMAgGBmeBDAEEATCBhAYIKwYBBQUHAQEEeDB2MCQGCCsGAQUFBzABhhhodHRw
# Oi8vb2NzcC5kaWdpY2VydC5jb20wTgYIKwYBBQUHMAKGQmh0dHA6Ly9jYWNlcnRz
# LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1cmVkSURDb2RlU2lnbmluZ0NB
# LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCUCOdwU+8srLBP
# /gMQIbtsdu2JWX666Z9GPZisW4KGyCS/U+ZCmB/KnELeD4StX3JFXz5ddILA5oon
# e/pEud+mEuETBhzb7RCz82WJvk0DEMa4hzMAh5c5zmRFGm8WxDZdI20ztcvW0sOb
# qn9UbsGhQDKpFeww91ZtOQ3/2d0KYZKypzGMba53w7pWG170nktocFWTeUhkAy0f
# oAJ2jlBOszj2dshTxAa5Fg1dkpEsBS7oiAPpYkoxV9ldaXJ8Px1navd6PpDW4A78
# 1u13f3tP4FVCsNYw4bz4Z5GInCh6/FshaHRJ6dk5SsCr29MlpK8UxK9y2Qmb+jEt
# RxR0QZLfMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0B
# AQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVk
# IFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYD
# VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lD
# ZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIIC
# IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKR
# N6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZz
# lm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1Oco
# LevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH
# 92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRA
# p8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+g
# GkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU
# 8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/
# FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwj
# jVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQ
# EgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUae
# tdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAw
# HQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LS
# cV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEF
# BQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
# Z2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYy
# aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5j
# cmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEB
# CwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftw
# ig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalW
# zxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQm
# h2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScb
# qyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLaf
# zYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbD
# Qc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0K
# XzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm
# 8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9
# gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8a
# pIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBsAwggSo
# oAMCAQICEAxNaXJLlPo8Kko9KQeAPVowDQYJKoZIhvcNAQELBQAwYzELMAkGA1UE
# BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2Vy
# dCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0y
# MjA5MjEwMDAwMDBaFw0zMzExMjEyMzU5NTlaMEYxCzAJBgNVBAYTAlVTMREwDwYD
# VQQKEwhEaWdpQ2VydDEkMCIGA1UEAxMbRGlnaUNlcnQgVGltZXN0YW1wIDIwMjIg
# LSAyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAz+ylJjrGqfJru43B
# DZrboegUhXQzGias0BxVHh42bbySVQxh9J0Jdz0Vlggva2Sk/QaDFteRkjgcMQKW
# +3KxlzpVrzPsYYrppijbkGNcvYlT4DotjIdCriak5Lt4eLl6FuFWxsC6ZFO7Khbn
# UEi7iGkMiMbxvuAvfTuxylONQIMe58tySSgeTIAehVbnhe3yYbyqOgd99qtu5Wbd
# 4lz1L+2N1E2VhGjjgMtqedHSEJFGKes+JvK0jM1MuWbIu6pQOA3ljJRdGVq/9XtA
# bm8WqJqclUeGhXk+DF5mjBoKJL6cqtKctvdPbnjEKD+jHA9QBje6CNk1prUe2nhY
# HTno+EyREJZ+TeHdwq2lfvgtGx/sK0YYoxn2Off1wU9xLokDEaJLu5i/+k/kezbv
# BkTkVf826uV8MefzwlLE5hZ7Wn6lJXPbwGqZIS1j5Vn1TS+QHye30qsU5Thmh1EI
# a/tTQznQZPpWz+D0CuYUbWR4u5j9lMNzIfMvwi4g14Gs0/EH1OG92V1LbjGUKYvm
# QaRllMBY5eUuKZCmt2Fk+tkgbBhRYLqmgQ8JJVPxvzvpqwcOagc5YhnJ1oV/E9mN
# ec9ixezhe7nMZxMHmsF47caIyLBuMnnHC1mDjcbu9Sx8e47LZInxscS451NeX1XS
# fRkpWQNO+l3qRXMchH7XzuLUOncCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIH
# gDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZ
# MBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2
# mi91jGogj57IbzAdBgNVHQ4EFgQUYore0GH8jzEU7ZcLzT0qlBTfUpwwWgYDVR0f
# BFMwUTBPoE2gS4ZJaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1
# c3RlZEc0UlNBNDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUH
# AQEEgYMwgYAwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBY
# BggrBgEFBQcwAoZMaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
# VHJ1c3RlZEc0UlNBNDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG
# 9w0BAQsFAAOCAgEAVaoqGvNG83hXNzD8deNP1oUj8fz5lTmbJeb3coqYw3fUZPwV
# +zbCSVEseIhjVQlGOQD8adTKmyn7oz/AyQCbEx2wmIncePLNfIXNU52vYuJhZqMU
# KkWHSphCK1D8G7WeCDAJ+uQt1wmJefkJ5ojOfRu4aqKbwVNgCeijuJ3XrR8cuOyY
# QfD2DoD75P/fnRCn6wC6X0qPGjpStOq/CUkVNTZZmg9U0rIbf35eCa12VIp0bcrS
# BWcrduv/mLImlTgZiEQU5QpZomvnIj5EIdI/HMCb7XxIstiSDJFPPGaUr10CU+ue
# 4p7k0x+GAWScAMLpWnR1DT3heYi/HAGXyRkjgNc2Wl+WFrFjDMZGQDvOXTXUWT5D
# mhiuw8nLw/ubE19qtcfg8wXDWd8nYiveQclTuf80EGf2JjKYe/5cQpSBlIKdrAqL
# xksVStOYkEVgM4DgI974A6T2RUflzrgDQkfoQTZxd639ouiXdE4u2h4djFrIHprV
# wvDGIqhPm73YHJpRxC+a9l+nJ5e6li6FV8Bg53hWf2rvwpWaSxECyIKcyRoFfLpx
# tU56mWz06J7UWpjIn7+NuxhcQ/XQKujiYu54BNu90ftbCqhwfvCXhHjjCANdRyxj
# qCU4lwHSPzra5eX25pvcfizM/xdMTQCi2NYBDriL7ubgclWJLCcZYfZ3AYwxggZU
# MIIGUAIBATCBhjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j
# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBT
# SEEyIEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBAhAImnSeuC3D7CfqZerb+DUx
# MA0GCWCGSAFlAwQCAQUAoHwwEAYKKwYBBAGCNwIBDDECMAAwGQYJKoZIhvcNAQkD
# MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJ
# KoZIhvcNAQkEMSIEIAxy612aK3ZM5hwq6Mt7zyEvL/gfcfe4Tpo3hdraXmtGMA0G
# CSqGSIb3DQEBAQUABIICACGyEZJJt8JJeA05bfnNiyY/NpGYy88CE/Wc3gXcJIOd
# 7SAXX8QLJJ6qirW775X4FPKA9smBTsAfmh8Fyn+NEuUBzmj+MRfzxyeDz6+9S1kI
# pHosPKzV0YDog4rTdz1RAsh/1/toH7SUnZ29m8MC1rjDMayRtosimM39LnXzabuS
# i66NCe+pxZY7dO2J411M0t4xeIYuSXoaTocjNcn5oYAn/rnV0uGyeM8IBs4xOafx
# McFZXjT6gxYR26CAOQqzRyg/PflUDzGDcBJnSPoDsnfTiubTKAToh6BjdRVJy0BT
# 52RSTHpR7WvJVDBpNsHHt9IvMs3MncZibGQ8uNJueogvn0w8bBxg49giL0jqVszH
# 08Ag3o6H1ExmLJ9hCpN8gf7SmCiIcgXYoTyQGfWlEObW1h2nu5cF8eKoJYEI9Ieg
# MMh4+Ewu4QKASu+zMzH7y4kXIuFT2nBe1O79Shl/YCFeRzCMScwqk00kZ8SMfoW1
# x9DNCYtWMK1WVnvAJ09uDYzSRsFEe2XUuMJ9BQ6NC83qS4biBTt+jGLexwtAREqE
# WRUWe8GJpAzuTvsNa+ElnucUFGhT5gYJ6+TEvlEBmvwHKkK9T1KUYkVbCgFEwWQo
# 3jponG+Ms6KXe7NBsxMkjQPcHEQoa0V+uzxBbfCicQU2mk/fS7perdOlUCTERS2U
# oYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMx
# FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVz
# dGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQDE1pckuU+jwq
# Sj0pB4A9WjANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B
# BwEwHAYJKoZIhvcNAQkFMQ8XDTIzMDgwMzA3MTYwMVowLwYJKoZIhvcNAQkEMSIE
# INQ/CFeM3udZOxe5IECG6KZ0YPYAW/uPdtFac10rNZiBMA0GCSqGSIb3DQEBAQUA
# BIICAI11s3Zi5rqDGh0BxcY57tJyv55QgZTgDlCg+wC+XjjKuSpr5OCiomzuknNr
# CfcG1RtZLynlM5+5pwvkLbD8kkZbd6B+uHAr0ucqLc04PofW+J+jgokhNrgtUy3w
# 0CVbQEUPwLheO6xgQTl5Talu6XowsqPBqnaBEOSfFWlmfGVewehyleYMXQew9fYo
# Im3B0CsQ9VqIgNOQP916MKVd/kAxg1veyxwpFJ9I2NoS4JMCafGSU5Pskt4MTLe4
# zOJs/kc+d3XU9ApJy2CDXDy8rAK45njaOOX6uvHrp6T0mNqkoV08o/irEbVgW2DG
# wOXZMcvEWuvEWI0au4Edv3U+Y0Zo1S9KWQ9bMT+8hbVWlKw6x4Y713//rkn9lm4P
# fCUGFeArdudZ9imOSVZoM/ku8cOHJwjCx14sstKbnSaFMJRXErPqgd4YSldihCSf
# TOf5n9abPUTezKKHq8Y1zDGAvwMLTGi3tggwxgHosvKK07SreFcm3HD/XU/vulhc
# 7VDTjShWnbUFIZh0GOcCALankP82go7x/hs7UmBDgMv9nt835Bf9I6PQ9y7/5B1f
# I+o+KdAfGLVn6Bgoijxjn+vWAltd6WNJr/VKOYhLXKTl+PaKVMV2fObyhIOZksUc
# +jLW1lJEBPzEbwyVeFlmzR5lCpYnHnUWw/3iBVR/x63475Dv
# SIG # End signature block
