AppHandling/Copy-AlSourceFiles.ps1
|
<#
.Synopsis Copy AL Source Files .Description This function will copy all .al and .xlf files from Path to Destination. Information about each file will be sent to the alFileStructure function to determine the relative location of the file. .Parameter Path Source Path from where you want to copy all AL source files .Parameter Destination Destination Path .Parameter Recurse Copy source in subfolders .Parameter alFileStructure Specify a function, which will determine the location of the individual al source files .Example Copy-AlSourceFiles -Path "$sourceFolder\*" -Destination $destinationFolder -Recurse -alFileStructure $TypeFolders #> function Copy-AlSourceFiles { Param ( [string] $Path, [string] $Destination, [switch] $Recurse, [ScriptBlock] $alFileStructure ) $telemetryScope = InitTelemetryScope -name $MyInvocation.InvocationName -parameterValues $PSBoundParameters -includeParameters @() try { Write-Host "Copying Al Source Files from $Path to $Destination" if ($alFileStructure) { $types = @('enum', 'page', 'table', 'codeunit', 'report', 'query', 'xmlport', 'profile', 'dotnet', 'enumextension', 'pageextension', 'tableextension', 'interface', 'entitlement', 'permissionset', 'permissionsetextension', 'pagecustomization', 'reportextension', 'profileextension') $noidtypes = @('profile','profileextension','interface','entitlement','pagecustomization') $extensions = @(".al",".xlf",".lcl") $files = Get-ChildItem -Path $Path -Recurse:$Recurse $files | Where-Object { ($extensions.Contains($_.Extension.ToLowerInvariant())) -and !($_.Attributes.HasFlag([System.IO.FileAttributes]::Directory)) } | ForEach-Object { $filename = $_.Name $directoryname = $_.DirectoryName $content = [System.IO.File]::ReadAllLines($_.FullName) try { if ($_.Extension -ne ".al") { $type = $_.Extension $id = '' $name = $_.BaseName $found = $true } else { $found = $false foreach($Line in $content) { if (-not $found) { $line = $Line.Trim() if ($line -notlike '//*') { $idx = $line.IndexOf(' ') if ($idx -lt 0) { $type = $line } else { $type = $line.SubString(0,$idx).ToLowerInvariant() } if ($types.Contains($type)) { $found = $true break } } } } if ($type -eq "dotnet") { $id = '' $name = $_.BaseName } else { $line = $line.SubString($type.Length).TrimStart() if ($noidTypes.Contains($type)) { $id = '' } else { $id = $line.SubString(0,$line.IndexOf(' ')) $line = $line.SubString($id.Length).Trim() } if ($line.StartsWith('"')) { $nameendidx = $line.IndexOf('"',1) $name = $line.SubString(1,$nameendidx-1) } else { $name = $line } } } $newFilename = "" if ($found) { if ($alFileStructure.Ast.ParamBlock.Parameters.Count -eq 3) { $newFilename = "$($alFileStructure.Invoke($type, $id, $name))" } else { $newFilename = "$($alFileStructure.Invoke($type, $id, $name, [ref] $content))" } } if ($newFilename) { $newFilename = $newFilename -replace '[~#%&*{}|:<>?/"]', '' $destFilename = Join-Path $Destination $newFilename $destPath = [System.IO.Path]::GetDirectoryName($destFilename) $destName = [System.IO.Path]::GetFileName($destFilename) if (-not (Test-Path $destPath)) { New-Item $destPath -ItemType Directory | Out-Null } if (Test-Path -Path $destFilename) { Write-Warning "$destFilename already exists, adding sequence number" $seq = 1 $dotIdx = $destName.IndexOf('.') if ($dotIdx -lt 0) { throw "Cannot add sequence number to $destName" } while (Test-Path -Path $destFilename) { $seq++ $destFilename = Join-Path $destPath $destName.Insert($dotIdx,"$seq") } } if ($type -eq "report") { 0..($content.Count-1) | % { $line = $content[$_] if ($line.Trim() -like "RDLCLayout = '*';" -or $line.Trim() -like "WordLayout = '*';" -or $line.Trim() -like "LayoutFile = '*';") { $startIdx = $line.IndexOf("'")+1 $endIdx = $line.LastIndexOf("'") $layoutFilename = $line.SubString($startIdx, $endIdx-$startIdx) $layoutFilename = $layoutFilename.SubString($layoutFilename.LastIndexOfAny(@('\','/'))+1) $layoutFile = $Files | Where-Object { ($_.name -eq $layoutFilename) -and ($_.DirectoryName -eq $DirectoryName)} if (!($layoutFile)){ $layoutFile = $Files | Where-Object { $_.name -eq $layoutFilename } } if ($layoutFile) { $layoutcontent = [System.IO.File]::ReadAllBytes($layoutFile.FullName) if ($alFileStructure.Ast.ParamBlock.Parameters.Count -eq 3) { $layoutNewFilename = "$($alFileStructure.Invoke($layoutFile.Extension, $id, $name))" } else { $layoutNewFilename = "$($alFileStructure.Invoke($layoutFile.Extension, $id, $name, [ref] $content))" } if ($layoutNewFilename) { if ($layoutNewFilename.StartsWith('*\')) { $layoutDestFilename = Join-Path $DestPath $layoutNewFilename.Substring(2) $layoutDestPath = [System.IO.Path]::GetDirectoryName($layoutDestFilename) $layoutDestName = [System.IO.Path]::GetFileName($layoutDestFilename) if ($layoutDestName.StartsWith('*.')) { $layoutDestName = [System.IO.Path]::GetFileNameWithoutExtension($destFileName) + $layoutDestName.Substring(1) $layoutDestFileName = Join-Path $layoutDestPath $layoutDestName } } elseif ($layoutNewFilename.StartsWith('*.')) { $layoutDestPath = $destPath $layoutDestName = [System.IO.Path]::GetFileNameWithoutExtension($destFileName) + $layoutNewFilename.Substring(1) $layoutDestFilename = Join-Path $layoutDestPath $layoutDestName } else { $layoutNewFilename = $layoutNewFilename -replace '[~#%&*{}|:<>?/"]', '' $layoutDestFilename = Join-Path $Destination $layoutNewFilename $layoutDestPath = [System.IO.Path]::GetDirectoryName($layoutDestFilename) $layoutDestName = [System.IO.Path]::GetFileName($layoutDestFilename) } if (-not (Test-Path $layoutDestPath)) { New-Item $layoutDestPath -ItemType Directory | Out-Null } if (Test-Path -Path $layoutDestFilename) { Write-Warning "$layoutDestFilename already exists, adding sequence number" $seq = 1 $dotIdx = $layoutDestName.IndexOf('.') if ($dotIdx -lt 0) { throw "Cannot add sequence number to $layoutDestName" } while (Test-Path -Path $layoutDestFilename) { $seq++ $layoutDestFilename = Join-Path $layoutDestPath $layoutDestName.Insert($dotIdx,"$seq") } } [System.IO.File]::WriteAllBytes($layoutDestFilename, $layoutcontent) $filename = (get-item $layoutDestFilename).FullName if ($filename.StartsWith($Destination,"InvariantCultureIgnoreCase")) { $layoutDestFilename = $filename } $content[$_] = $line.SubString(0,$startIdx) + $layoutDestFilename.Substring($destination.Length+1).Replace('\','/') + $line.SubString($endIdx) } } else { Write-Warning "Unable to find $layoutFilename" } } } } [System.IO.File]::WriteAllLines($destFileName, $content) } } catch { Write-Warning "Unexpected error while handling $filename" throw } } } else { Copy-Item -Path $Path -Destination $Destination -Recurse:$Recurse -Force | Out-Null } } catch { TrackException -telemetryScope $telemetryScope -errorRecord $_ throw } finally { TrackTrace -telemetryScope $telemetryScope } } Export-ModuleMember -Function Copy-AlSourceFiles # SIG # Begin signature block # MIIncAYJKoZIhvcNAQcCoIInYTCCJ10CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD6onw4XaH+e8gG # hzozyTPfWgTDNZ42RqIKascC5R/jWKCCDMkwggYEMIID7KADAgECAhMzAAACHPrN # xZvoL37EAAAAAAIcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQxWhcNMjcwNDE1MTg1 # OTQxWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDVsZfgOKmM31HPfoWOoNEiw0SlCiIxUMC0I9NMWbucKOw/e9lP # oAoehQVu6SG65V4EPzrYsnBnFPNoi4/HoOdjhz1qkrEt4I6tEcxXU6oOeY9zGveC # /3iBeuhLYxM3M/PkcUoebF+Nednm8OkdSPoDu8imViHPQq/8CQUu0WRR4rE+dMRf # rpVqfmNi2qWCX94T4MsepijGVkwE//tJg0ryAiYdHT34LSnlG/RSBZmQRGWZ5g8j # qnKjRParSqMft1gvjuUTVgtWNZfgcLFSK5Wa0myrq8OPcgTGGsRgun+tnSS+IxDT # xVsAPH1OzvPjwomguByhUe/OcvUN0D5Wmp7xAgMBAAGjggGqMIIBpjAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFNoH7a2YDjOSwpkp6DHcmUS7J+0yMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQL # EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxFjAUBgNVBAUT # DTIzMDAxMis1MDc1NjkwHwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEw # YAYDVR0fBFkwVzBVoFOgUYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w # cy9jcmwvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # bDBtBggrBgEFBQcBAQRhMF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9z # b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmcl # MjBQQ0ElMjAyMDI0LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC # AQAUnEqhaRXe0T3hIJjvdQErEkrA/7bByjn6t5IArODkkRjzkYwtKMc2yYj2quaN # rLutWw2YZcngKPy1b71YyDJQTy4NDRwaSh9Tw5thrk3NmcPrAHia5vtcBJ1CgtKK # 7mQbIcQ22d/N3813ayCDDFewu1+jsZmX+r/aTEqaOM4TVxVtRSkuCy8nAXKuChOK # Li/zA4XuH8iEYqIsj2YoNaeSxVmeGiERXpKdo3dDmYi0kO5w2D8VS4c3+9h6gElY # BaAAg/dYErBg27qT3vv0zRDJhJufvCNylA8S7/+8H5E/PV5cng6na9VV/w9OV3qu # uND6zdGa2EX38Glp50F9AIQk3p2xXmcvorDeM4XJ7UlWYBi6g80J1SSOQnInCYFE # msfUNn3+1AaTJKSJL83quKArTac2pKhu0Yzzzrzo6HrsRiQKzpnRBb1/dMa6P3hz # 75XbMRBctNsFhZC07WCmjExdLg2eHW5uV0TY8D5+6wozJf7vF3+WHkYPO85Z+BC6 # U4FkNbYNycZ9cE4j1tXRdyDCfml6c0HWPHjNVDObrv9lKt3qUqFpX38VCqVCyNOO # 1UcXfQiVjJw32U2WUKZjt/neJKHEBsm9kFsLuWzkQ53+qcaSaytmsCnk2gOglrlD # 5d3kKyvvAw+rzm0lT8K38P6PLxfZQHhu4W8dV7Av8N2ZmDCCBr0wggSloAMCAQIC # EzMAAAA5O7Y3Gb8GHWcAAAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS # b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoX # DTM2MDMyMjIyMTMwNFowVzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQ # Q0EgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeq # lRYHNa265v4IY9fH8TKhemHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo # 0dtS/EW6I/yEL/bLSY8hKpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATv # QVL4tcf03aTycsz8QeCdM0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a # 1uv1zerOYMnsneRRwCbpyW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1 # FyQfK0fVkaya8SmVHQ/tOf23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfO # GSWHIIV4YrTJTT6PNty5REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7 # ttOu1bVnXfHaqPYl2rPs20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJ # uz2MXMCt7iw7lFPG9LXKGjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxS # CwyoGIq0PhaA7Y+VPct5pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOm # VQop36wUVUYklUy++vDWeEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3 # SkE/xIkgpfl22MM1itkZ35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8E # BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPX # LQaUEggxMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMB # Af8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBP # oE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAw # TgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOC # AgEAFJQfOChP7onn6fLIMKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D # 5W4wMwYeLystcEqfkjz4NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBY # nbu0+THSuVHTe0VTTPVhily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSI # vgn0JksVBVMYVI5QFu/qhnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6 # aR9y34aiM1qmxaxBi6OUnyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4w # PKC5OmHm1DQIt/MNokbbH3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7 # RTX8AdBPo0I6OEojf39zuFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK # /fg8B2qjW88MT/WF5V5uvZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSK # YBv0VisCzfxgeU+dquXW9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkw # YTu/9dLeH2pDqeJZAABVDWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVT # Ql0v4q8J/AUmQN5W4n101cY2L4A7GTQG1h32HHAvfQESWP0xghn9MIIZ+QIBATBu # MFcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIc # +s3Fm+gvfsQAAAAAAhwwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwG # CisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZI # hvcNAQkEMSIEIP1shGTVUeWf/AElFE48DTOBxOBPlpYzSqwHspU0L2OQMEIGCisG # AQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEAUVSycQUFBbwbS8giMrec # PkvBEy11KjApX/HhfyXdbkxd+LFT1MwpNSx0qp1RogHhO4ADLpyE0qnx6syev+6Y # 65sBn9RnxpKnw+Dr4Ud3+73BAmBcqgc0vh4ONjtrCsIQi7KKOOxjrpYPw7r24hNh # ntpDYWExb+dKp/uIsaTozfEpcm+DH0SLp9C/h3oPWGleW5Z6JLKGjRmnv91CIQ0T # 1pUoT1B0bXA/fmUb+MwH/7VENv1qHUOqU4imOMAMhZ+wclCgYTes8tncASo8atjU # IIa7LsH3zg+SQtpiWE11djjDYdq2DfMjocyfh2IhvKwDehqR0zsBJJmIsKpxEgqp # 4KGCF68wgherBgorBgEEAYI3AwMBMYIXmzCCF5cGCSqGSIb3DQEHAqCCF4gwgheE # AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIB # QAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCDB0/YU5nhrx7RFoUcf # VrOzWuyYtIHBo2oNQJtPAVJkiAIGaq0pIfHiGBIyMDI2MDkzMDEyMjE0NS42OFow # BIACAfSggdmkgdYwgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRl # ZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjZCMDUtMDVFMC1EOTQ3MSUwIwYD # VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIR/jCCBygwggUQoAMC # AQICEzMAAAIRRRg5m0PP/GwAAQAAAhEwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE # BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0 # IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjUwODE0MTg0ODEzWhcNMjYxMTEzMTg0 # ODEzWjCB0zELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsG # A1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMScwJQYD # VQQLEx5uU2hpZWxkIFRTUyBFU046NkIwNS0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1p # Y3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQDPubszEB0vlVrKuTuOwyjcaeE3zmS0cJkS8RyPgEhxwcp380oL # u4++lfl2E7rdbpUzmILGSUbypB5VWs9oq+Px1hgkLsM23g03deVV0L++i94m48+F # Mn+7tf6liZXap6FNU844HX+Gma3nVLODFlzMx2cWX5fZ7U+C61IDkICH39fPk1bQ # LGdhXPyDRWnGD4GrfZqaS1FevybcFISBSzyOBZE9XM8cRzOluGWgYYR8dpE6YeFU # oio34mEzB4SNTY1czZbqGbfaP9Af8j8pao019hyEdobTEmWNVNihQo+lxAO6Ef11 # AoSC8bGPZTn/cWrV6bh07oiHTibpH623GvpjyhEkf1mFnexyIUEi9mHsTZgVc6M/ # gwbJtLKVBM8MQUC0ceCmSyR4RSGw8NH1W9ZaF6SFDHepdoAqH4CQubP+GkTd7TL5 # Ego7YBESNQskAqB/5H1Cc2+ox4yTP08auOyKOpYbMHaTYk3JpRgqVuZDB45puwKK # iJjZ8luKaNXIUAaTkB5h11QXG8kaBFUIfsF4E8oCrsww6ZIJM4xnRLDrPI3HhSGH # ljS4nRk6hMqcHcp9039tr94ocV4SGLdaoB/NPGLLSsy+Gx+xdkrvOhyWppG9WXxD # jwnXvj57KuLKlj0eFT6iGCJiLi5AYMNV1MN4oO2gL+EPYKf4BHPATWsV8QIDAQAB # o4IBSTCCAUUwHQYDVR0OBBYEFGJ9RQPA6eohy99vnf7JXQRmfs5wMB8GA1UdIwQY # MBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6 # Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUt # U3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYB # BQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj # cm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB # /wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0G # CSqGSIb3DQEBCwUAA4ICAQCkQp2cx4ghSJTo9q1n+puvCIPNhQwpFzMLgGn9djVL # 02Ycj7Zzd1ynAfZI6YN928giq3uZGuC8E9g68n0K1lLl54iuw5sLRvSCApO/bCtO # BYb6qS2o0USFB6Kl1RE0s3ry4cCbl53AHK13WTDLmvoH3eSXEOyV06ZVa3D+eCPu # Sc3T2a4KbCvXsmewwVygg38fn2z7VFg3tWJ3j7uePwVy9jL2ttk4yd0HOxOKiwXU # z5owglfaTcRUVWy4Mvv9Hmmkj1ODt5ZA5Yoxkc92wDdmpbMO6EmpPOgVJBKGdl6c # L7Gr/P0GEc8UVtS1+MCgboQM+NJAlheaiCNrw4RrX3HCeHfBW594/5yT7/SDE2Lu # D6Q7pZo6bTnYXiyIPzGLpS/vkvvv3yUe89OFzEceyBeoxjn3Z3XBSh/e0v94NpDR # SGdgJTzIaRTZcmdy042cEoC9REC9/aqIhYOPgulybTMDtW6h+4lHVOm7JzmnWNrn # Zs1kEFWoA7DIOECapawlcCNheeywL98mR57fXgWH4YjIyC8A9FJyCpFmpXXp1MFi # +h77DWf/Baz/JJNSzEPDhP8AhNy7k8CwucJWkCsOsUtFMXK6354dSgbpRhl+Pz9G # y5DjYg2x7Wlv9w+bsbaVwsm2QgpPzTG8HUuJo289MFURyY1K8VQzTGtdldxhzFVe # JjCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL # BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV # BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X # DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh # bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM # 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm # 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB # RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb # fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO # Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw # XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW # /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w # EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK # Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2 # BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH # CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB # BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v # BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM # KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF # BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW # BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH # AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF # AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx # Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+ # iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2 # pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw # C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7 # T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO # Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL # mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L # wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5 # m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE # 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNZMIICQQIB # ATCCAQGhgdmkgdYwgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRl # ZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjZCMDUtMDVFMC1EOTQ3MSUwIwYD # VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoD # FQArKnyrZV2ACrVUaTN3s9nBXrM1zaCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA7md4XTAiGA8yMDI2MDkzMDEy # MDAyOVoYDzIwMjYxMDAxMTIwMDI5WjB3MD0GCisGAQQBhFkKBAExLzAtMAoCBQDu # Z3hdAgEAMAoCAQACAgDCAgH/MAcCAQACAhJJMAoCBQDuaMndAgEAMDYGCisGAQQB # hFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAw # DQYJKoZIhvcNAQELBQADggEBAHD0yrI+3x2x6SRz/XxeLs/2bi+jXgCWF+MhiXzi # rXDk2fyZK7XLLxQnBDzHOdR0d0NqdcJ7qewzvI6gOXmDd8TcyTihkbKOXQfT1F40 # 4xOpISloSN3eN2EZbBaA09dykuUOViRnfU+xX3p3BMfoI0T4YOd7fXY8q3QFalha # bjBTeUxLxH5mZUNR0wDJtBNcX9clMJJGvIONLhUqBJikZIs18XVs2vY/aKttAxU4 # ZPVkAZL1SrLByfVt8zM4eCVAzSHpIhfndBNlmJPlrgpwRRwZVUTIM3oEnRHEqpmM # Cyis5Xh/IfppGsVlthFT5vMR38EE2BGVfjCCaR8senWNwPUxggQNMIIECQIBATCB # kzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAhFFGDmbQ8/8bAAB # AAACETANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJ # EAEEMC8GCSqGSIb3DQEJBDEiBCA5SCqg60eZ+oShTathSsxO8nC1hmvRN4rZkHF0 # 1G131jCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EICytM6ma74dOrVpcXC+W # GMXynadQI00IRf85Ysc0Mya3MIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg # UENBIDIwMTACEzMAAAIRRRg5m0PP/GwAAQAAAhEwIgQgc0RCXdpewkcJdSwdEE3y # syS+PgVVTESWmzFNxsXQXBIwDQYJKoZIhvcNAQELBQAEggIAWIekehA2skMv2fHA # PF5EbhmWfXBLdQrZMjdKHqGIblyuXkrsORm52P371N8mUXAVra9Q5K2924aYcw+I # gY74yoBeExQSV3gR67hjBfMZWQ6IQdbbjMm7ie5Zp4Q5TondZ9h3fO7uDtrb3Bq0 # CCNajrlAfi3aucVTtyZMj+CTBuzxCnPLU8rqQMz6s+HIjivAP10a6cxQN4k946Oc # CMO/TM/buXKCdaX9yONmr9BxDp4d8TTpKpTsY1fz4++7gVjrNGAGiaz8dN3jbD1w # 7wFtBT44c8Y/bOyZrqspdjGePd8UB8+bgJmfu9YqoBJiiIFB/tmDhrun/L8YffAX # mB/Kw9seLVPoLFfMe+GITjiIAJY3prWxPMQsjQ/GK64yZK2oKsu0P8qHWHMNgrQx # IydCbJKc1R7KlUad+2zSAxrxE+DbaHsniBdhwMdjr55tbSyTq0DUZBTMHh9ggBJ+ # H/S1U95h6OZe801rkZMDnYwZRlzeg0V95h4KZIKfLa/fohWKoWBQvC13d8DTKVBY # jGtCRwwEYIMQCw6+aUEwVPeFo1Jd9SKH3hJSwhTYoKQA3on+y+YmvEQ8VNrc0Dmd # BF+90NiegbcsZx42PntoFpyix/uu8CUse1Vi+0cRlnE3rksDojbWYr7lKs3u0cTp # 3AqXOEhJQlCafc5rZjiMVYduhJ4= # SIG # End signature block |