keepassxc
/
release-tool.ps1
668 строк · 29.6 Кб
1<#
2.SYNOPSIS
3KeePassXC Release Tool
4
5.DESCRIPTION
6Commands:
7merge Merge release branch into main branch and create release tags
8build Build and package binary release from sources
9sign Sign previously compiled release packages
10
11.NOTES
12The following are descriptions of certain parameters:
13-Vcpkg Specify VCPKG toolchain location (example: C:\vcpkg)
14-Tag Release tag to check out (defaults to version number)
15-Snapshot Build current HEAD without checkout out Tag
16-CMakeGenerator Override the default CMake generator
17-CMakeOptions Additional CMake options for compiling the sources
18-CPackGenerators Set CPack generators (default: WIX;ZIP)
19-Compiler Compiler to use (example: g++, clang, msbuild)
20-MakeOptions Options to pass to the make program
21-SignBuild Perform platform specific App Signing before packaging
22-SignCert Specify the App Signing Certificate
23-TimeStamp Explicitly set the timestamp server to use for appsign
24-SourceBranch Source branch to merge from (default: 'release/$Version')
25-TargetBranch Target branch to merge to (default: master)
26-VSToolChain Specify Visual Studio Toolchain by name if more than one is available
27#>
28
29param(
30[Parameter(ParameterSetName = "merge", Mandatory, Position = 0)]
31[switch] $Merge,
32[Parameter(ParameterSetName = "build", Mandatory, Position = 0)]
33[switch] $Build,
34[Parameter(ParameterSetName = "sign", Mandatory, Position = 0)]
35[switch] $Sign,
36
37[Parameter(ParameterSetName = "merge", Mandatory, Position = 1)]
38[Parameter(ParameterSetName = "build", Mandatory, Position = 1)]
39[Parameter(ParameterSetName = "sign", Mandatory, Position = 1)]
40[string] $Version,
41
42[Parameter(ParameterSetName = "build", Mandatory)]
43[string] $Vcpkg,
44
45[Parameter(ParameterSetName = "sign", Mandatory)]
46[SupportsWildcards()]
47[string[]] $SignFiles,
48
49# [Parameter(ParameterSetName = "build")]
50# [switch] $DryRun,
51[Parameter(ParameterSetName = "build")]
52[switch] $Snapshot,
53[Parameter(ParameterSetName = "build")]
54[switch] $SignBuild,
55
56[Parameter(ParameterSetName = "build")]
57[string] $CMakeGenerator = "Ninja",
58[Parameter(ParameterSetName = "build")]
59[string] $CMakeOptions,
60[Parameter(ParameterSetName = "build")]
61[string] $CPackGenerators = "WIX;ZIP",
62[Parameter(ParameterSetName = "build")]
63[string] $Compiler,
64[Parameter(ParameterSetName = "build")]
65[string] $MakeOptions,
66[Parameter(ParameterSetName = "build")]
67[Parameter(ParameterSetName = "sign")]
68[X509Certificate] $SignCert,
69[Parameter(ParameterSetName = "build")]
70[Parameter(ParameterSetName = "sign")]
71[string] $Timestamp = "http://timestamp.sectigo.com",
72[Parameter(ParameterSetName = "merge")]
73[Parameter(ParameterSetName = "build")]
74[Parameter(ParameterSetName = "sign")]
75[string] $GpgKey = "CFB4C2166397D0D2",
76[Parameter(ParameterSetName = "merge")]
77[Parameter(ParameterSetName = "build")]
78[string] $SourceDir = ".",
79[Parameter(ParameterSetName = "build")]
80[string] $OutDir = ".\release",
81[Parameter(ParameterSetName = "merge")]
82[Parameter(ParameterSetName = "build")]
83[string] $Tag,
84[Parameter(ParameterSetName = "merge")]
85[string] $SourceBranch,
86[Parameter(ParameterSetName = "build")]
87[string] $VSToolChain,
88[Parameter(ParameterSetName = "merge")]
89[Parameter(ParameterSetName = "build")]
90[Parameter(ParameterSetName = "sign")]
91[string] $ExtraPath
92)
93
94# Helper function definitions
95function Test-RequiredPrograms {
96# If any of these fail they will throw an exception terminating the script
97if ($Build) {
98Get-Command git | Out-Null
99Get-Command cmake | Out-Null
100}
101if ($Merge) {
102Get-Command git | Out-Null
103Get-Command tx | Out-Null
104Get-Command lupdate | Out-Null
105}
106if ($Sign) {
107Get-Command gpg | Out-Null
108}
109}
110
111function Test-VersionInFiles {
112# Check CMakeLists.txt
113$Major, $Minor, $Patch = $Version.split(".", 3)
114if (!(Select-String "$SourceDir\CMakeLists.txt" -pattern "KEEPASSXC_VERSION_MAJOR `"$Major`"" -Quiet) `
115-or !(Select-String "$SourceDir\CMakeLists.txt" -pattern "KEEPASSXC_VERSION_MINOR `"$Minor`"" -Quiet) `
116-or !(Select-String "$SourceDir\CMakeLists.txt" -pattern "KEEPASSXC_VERSION_PATCH `"$Patch`"" -Quiet)) {
117throw "CMakeLists.txt has not been updated to $Version."
118}
119
120# Check Changelog
121if (!(Select-String "$SourceDir\CHANGELOG.md" -pattern "^## $Version \(\d{4}-\d{2}-\d{2}\)$" -Quiet)) {
122throw "CHANGELOG.md does not contain a section for $Version."
123}
124
125# Check AppStreamInfo
126if (!(Select-String "$SourceDir\share\linux\org.keepassxc.KeePassXC.appdata.xml" `
127-pattern "<release version=`"$Version`" date=`"\d{4}-\d{2}-\d{2}`">" -Quiet)) {
128throw "share/linux/org.keepassxc.KeePassXC.appdata.xml does not contain a section for $Version."
129}
130}
131
132function Test-WorkingTreeClean {
133& git diff-index --quiet HEAD --
134if ($LASTEXITCODE) {
135throw "Current working tree is not clean! Please commit or unstage any changes."
136}
137}
138
139function Invoke-VSToolchain([String] $Toolchain, [String] $Path, [String] $Arch) {
140# Find Visual Studio installations
141$vs = Get-CimInstance MSFT_VSInstance -Namespace root/cimv2/vs
142
143if ($vs.count -eq 0) {
144$err = "No Visual Studio installations found, download one from https://visualstudio.com/downloads."
145$err = "$err`nIf Visual Studio is installed, you may need to repair the install then restart."
146throw $err
147}
148
149$VSBaseDir = $vs[0].InstallLocation
150if ($Toolchain) {
151# Try to find the specified toolchain by name
152foreach ($_ in $vs) {
153if ($_.Name -eq $Toolchain) {
154$VSBaseDir = $_.InstallLocation
155break
156}
157}
158} elseif ($vs.count -gt 1) {
159# Ask the user which install to use
160$i = 0
161foreach ($_ in $vs) {
162$i = $i + 1
163$i.ToString() + ") " + $_.Name | Write-Host
164}
165$i = Read-Host -Prompt "Which Visual Studio installation do you want to use?"
166$i = [Convert]::ToInt32($i, 10) - 1
167if ($i -lt 0 -or $i -ge $vs.count) {
168throw "Invalid selection made"
169}
170$VSBaseDir = $vs[$i].InstallLocation
171}
172
173# Bootstrap the specified VS Toolchain
174Import-Module "$VSBaseDir\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
175Enter-VsDevShell -VsInstallPath $VSBaseDir -Arch $Arch -StartInPath $Path | Write-Host
176Write-Host # Newline after command output
177}
178
179function Invoke-Cmd([string] $command, [string[]] $options = @(), [switch] $maskargs, [switch] $quiet) {
180$call = ('{0} {1}' -f $command, ($options -Join ' '))
181if ($maskargs) {
182Write-Host "$command <masked>" -ForegroundColor DarkGray
183}
184else {
185Write-Host $call -ForegroundColor DarkGray
186}
187if ($quiet) {
188Invoke-Expression $call > $null
189} else {
190Invoke-Expression $call
191}
192if ($LASTEXITCODE -ne 0) {
193throw "Failed to run command: {0}" -f $command
194}
195Write-Host #insert newline after command output
196}
197
198function Find-SignCert() {
199$certs = Get-ChildItem Cert:\CurrentUser\My -codesign
200if ($certs.Count -eq 0) {
201throw "No code signing certificate found in User certificate store"
202} elseif ($certs.Count -gt 1) {
203# Ask the user which to use
204$i = 0
205foreach ($_ in $certs) {
206$i = $i + 1
207$i.ToString() + ") $($_.Thumbprint) - $($_.NotAfter)" | Write-Host
208}
209$i = Read-Host -Prompt "Which certificate do you want to use?"
210$i = [Convert]::ToInt32($i, 10) - 1
211if ($i -lt 0 -or $i -ge $certs.count) {
212throw "Invalid selection made"
213}
214return $certs[$i]
215} else {
216Write-Host "Found signing certificate: $($certs[0].Subject) ($($certs[0].Thumbprint))" -ForegroundColor Cyan
217Write-Host
218return $certs[0]
219}
220}
221
222function Invoke-SignFiles([string[]] $files, [X509Certificate] $cert, [string] $time) {
223if ($files.Length -eq 0) {
224return
225}
226
227Write-Host "Signing files using $($cert.Subject) ($($cert.Thumbprint))" -ForegroundColor Cyan
228
229foreach ($_ in $files) {
230$sig = Get-AuthenticodeSignature -FilePath "$_" -ErrorAction SilentlyContinue
231if ($sig.Status -ne "Valid") {
232Write-Host "Signing file '$_'"
233$tmp = Set-AuthenticodeSignature -Certificate $cert -FilePath "$_" -TimestampServer "$Timestamp" -HashAlgorithm "SHA256"
234}
235}
236}
237
238function Invoke-GpgSignFiles([string[]] $files, [string] $key) {
239if ($files.Length -eq 0) {
240return
241}
242
243Write-Host "Signing files using GPG key $key" -ForegroundColor Cyan
244
245foreach ($_ in $files) {
246Write-Host "Signing file '$_' and creating DIGEST..."
247if (Test-Path "$_.sig") {
248Remove-Item "$_.sig"
249}
250Invoke-Cmd "gpg" "--output `"$_.sig`" --armor --local-user `"$key`" --detach-sig `"$_`""
251$FileName = (Get-Item $_).Name
252(Get-FileHash "$_" SHA256).Hash + " *$FileName" | Out-File "$_.DIGEST" -NoNewline
253}
254}
255
256
257# Handle errors and restore state
258$OrigDir = (Get-Location).Path
259$OrigBranch = & git rev-parse --abbrev-ref HEAD
260$ErrorActionPreference = 'Stop'
261trap {
262Write-Host "Restoring state..." -ForegroundColor Yellow
263& git checkout $OrigBranch
264Set-Location "$OrigDir"
265}
266
267Write-Host "KeePassXC Release Preparation Helper" -ForegroundColor Green
268Write-Host "Copyright (C) 2022 KeePassXC Team <https://keepassxc.org/>`n" -ForegroundColor Green
269
270# Prepend extra PATH locations as specified
271if ($ExtraPath) {
272$env:Path = "$ExtraPath;$env:Path"
273}
274
275# Resolve absolute directory for paths
276$SourceDir = (Resolve-Path $SourceDir).Path
277
278# Check format of -Version
279if ($Version -notmatch "^\d+\.\d+\.\d+(-Beta\d*)?$") {
280throw "Invalid format for -Version input"
281}
282
283# Check platform
284if (!$IsWindows) {
285throw "The PowerShell release tool is not available for Linux or macOS at this time."
286}
287
288if ($Merge) {
289Test-RequiredPrograms
290
291# Change to SourceDir
292Set-Location "$SourceDir"
293
294Test-VersionInFiles
295Test-WorkingTreeClean
296
297if (!$SourceBranch.Length) {
298$SourceBranch = & git branch --show-current
299}
300
301if ($SourceBranch -notmatch "^release/.*$") {
302throw "Must be on a release/* branch to continue."
303}
304
305# Update translation files
306Write-Host "Updating source translation file..."
307Invoke-Cmd "lupdate" "-no-ui-lines -disable-heuristic similartext -locations none", `
308"-extensions c,cpp,h,js,mm,qrc,ui -no-obsolete ./src -ts share/translations/keepassxc_en.ts"
309
310Write-Host "Pulling updated translations from Transifex..."
311Invoke-Cmd "tx" "pull -af --minimum-perc=60 -r keepassxc.share-translations-keepassxc-en-ts--develop"
312
313# Only commit if there are changes
314$changes = & git status --porcelain
315if ($changes.Length -gt 0) {
316Write-Host "Committing translation updates..."
317Invoke-Cmd "git" "add -A ./share/translations/" -quiet
318Invoke-Cmd "git" "commit -m `"Update translations`"" -quiet
319}
320
321# Read the version release notes from CHANGELOG
322$Changelog = ""
323$ReadLine = $false
324Get-Content "CHANGELOG.md" | ForEach-Object {
325if ($ReadLine) {
326if ($_ -match "^## ") {
327$ReadLine = $false
328} else {
329$Changelog += $_ + "`n"
330}
331} elseif ($_ -match "$Version \(\d{4}-\d{2}-\d{2}\)") {
332$ReadLine = $true
333}
334}
335
336Write-Host "Creating tag for '$Version'..."
337$tmp = New-TemporaryFile
338"Release $Version`n$Changelog" | Out-File $tmp.FullName
339Invoke-Cmd "git" "tag -a `"$Version`" -F `"$tmp`" -s" -quiet
340Remove-Item $tmp.FullName -Force
341
342Write-Host "Moving latest tag..."
343Invoke-Cmd "git" "tag -f -a `"latest`" -m `"Latest stable release`" -s" -quiet
344
345Write-Host "All done!"
346Write-Host "Please merge the release branch back into the develop branch now and then push your changes."
347Write-Host "Don't forget to also push the tags using 'git push --tags'."
348} elseif ($Build) {
349$Vcpkg = (Resolve-Path "$Vcpkg/scripts/buildsystems/vcpkg.cmake").Path
350
351# Find Visual Studio and establish build environment
352Invoke-VSToolchain $VSToolChain $SourceDir -Arch "amd64"
353
354if ($SignBuild && !$SignCert) {
355$SignCert = Find-SignCert
356}
357
358Test-RequiredPrograms
359
360if ($Snapshot) {
361$Tag = "HEAD"
362$SourceBranch = & git rev-parse --abbrev-ref HEAD
363$ReleaseName = "$Version-snapshot"
364$CMakeOptions = "-DKEEPASSXC_BUILD_TYPE=Snapshot -DOVERRIDE_VERSION=`"$ReleaseName`" $CMakeOptions"
365Write-Host "Using current branch '$SourceBranch' to build." -ForegroundColor Cyan
366} else {
367Test-WorkingTreeClean
368
369# Clear output directory
370if (Test-Path $OutDir) {
371Remove-Item $OutDir -Recurse
372}
373
374if ($Version -match "-beta\d*$") {
375$CMakeOptions = "-DKEEPASSXC_BUILD_TYPE=PreRelease $CMakeOptions"
376} else {
377$CMakeOptions = "-DKEEPASSXC_BUILD_TYPE=Release $CMakeOptions"
378}
379
380# Setup Tag if not defined then checkout tag
381if ($Tag -eq "" -or $Tag -eq $null) {
382$Tag = $Version
383}
384Write-Host "Checking out tag 'tags/$Tag' to build." -ForegroundColor Cyan
385Invoke-Cmd "git" "checkout `"tags/$Tag`""
386}
387
388# Create directories
389New-Item "$OutDir" -ItemType Directory -Force | Out-Null
390$OutDir = (Resolve-Path $OutDir).Path
391
392$BuildDir = "$OutDir\build-release"
393New-Item "$BuildDir" -ItemType Directory -Force | Out-Null
394
395# Enter build directory
396Set-Location "$BuildDir"
397
398# Setup CMake options
399$CMakeOptions = "-DWITH_XC_ALL=ON -DWITH_TESTS=OFF -DCMAKE_BUILD_TYPE=Release $CMakeOptions"
400$CMakeOptions = "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=`"$Vcpkg`" -DX_VCPKG_APPLOCAL_DEPS_INSTALL=ON $CMakeOptions"
401
402Write-Host "Configuring build..." -ForegroundColor Cyan
403Invoke-Cmd "cmake" "-G `"$CMakeGenerator`" $CMakeOptions `"$SourceDir`""
404
405Write-Host "Compiling sources..." -ForegroundColor Cyan
406Invoke-Cmd "cmake" "--build . --config Release -- $MakeOptions"
407
408if ($SignBuild) {
409$VcpkgDir = $BuildDir + "\vcpkg_installed\"
410if (Test-Path $VcpkgDir) {
411$files = Get-ChildItem $VcpkgDir -Filter "*.dll" -Recurse -File |
412Where-Object {$_.FullName -notlike "$VcpkgDir*debug\*" -and $_.FullName -notlike "$VcpkgDir*tools\*"} |
413ForEach-Object {$_.FullName}
414}
415$files += Get-ChildItem "$BuildDir\src" -Include "*keepassxc*.exe", "*keepassxc*.dll" -Recurse -File | ForEach-Object { $_.FullName }
416Invoke-SignFiles $files $SignCert $Timestamp
417}
418
419Write-Host "Create deployment packages..." -ForegroundColor Cyan
420Invoke-Cmd "cpack" "-G `"$CPackGenerators`""
421Move-Item "$BuildDir\keepassxc-*" -Destination "$OutDir" -Force
422
423if ($SignBuild) {
424# Enter output directory
425Set-Location -Path "$OutDir"
426
427# Sign MSI files using AppSign key
428$files = Get-ChildItem $OutDir -Include "*.msi" -Name
429Invoke-SignFiles $files $SignCert $Timestamp
430
431# Sign all output files using the GPG key then hash them
432$files = Get-ChildItem $OutDir -Include "*.msi", "*.zip" -Name
433Invoke-GpgSignFiles $files $GpgKey
434}
435
436# Restore state
437Invoke-Command {git checkout $OrigBranch}
438Set-Location "$OrigDir"
439} elseif ($Sign) {
440Test-RequiredPrograms
441
442if (!$SignCert) {
443$SignCert = Find-SignCert
444}
445
446# Resolve wildcard paths
447$ResolvedFiles = @()
448foreach ($_ in $SignFiles) {
449$ResolvedFiles += (Get-ChildItem $_ -File | ForEach-Object { $_.FullName })
450}
451
452$AppSignFiles = $ResolvedFiles.Where({ $_ -match "\.(msi|exe|dll)$" })
453Invoke-SignFiles $AppSignFiles $SignCert $Timestamp
454
455$GpgSignFiles = $ResolvedFiles.Where({ $_ -match "\.(msi|zip|gz|xz|dmg|appimage)$" })
456Invoke-GpgSignFiles $GpgSignFiles $GpgKey
457}
458
459# SIG # Begin signature block
460# MIIm2gYJKoZIhvcNAQcCoIImyzCCJscCAQExDzANBglghkgBZQMEAgEFADB5Bgor
461# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
462# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDuejql+mhHrYzE
463# MGUrjGMbUzkTkzwhj8dkNuT2x9j8+KCCH8cwggVvMIIEV6ADAgECAhBI/JO0YFWU
464# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
465# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
466# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
467# dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG
468# EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv
469# IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA
470# A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s
471# hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD
472# J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7
473# P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme
474# me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz
475# T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q
476# RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz
477# mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc
478# QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T
479# OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/
480# AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID
481# AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD
482# VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV
483# HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE
484# VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v
485# ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE
486# KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI
487# hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF
488# OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC
489# J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ
490# pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl
491# d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH
492# +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M
493# UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD
494# VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv
495# ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5
496# NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp
497# BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G
498# CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI
499# ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV
500# DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3
501# 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw
502# mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm
503# +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe
504# dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4
505# 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM
506# dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY
507# MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU
508# pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV
509# HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG
510# A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1
511# YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG
512# AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl
513# U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0
514# aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh
515# w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd
516# OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj
517# cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc
518# WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO
519# hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs
520# zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7
521# 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J
522# KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH
523# j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2
524# Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/
525# L9Uo2bC5a4CH2RwwggZJMIIEsaADAgECAhAGQz/MzOQzqJLMF7dGpYxlMA0GCSqG
526# SIb3DQEBDAUAMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
527# ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYw
528# HhcNMjQwMjIzMDAwMDAwWhcNMjcwMjIyMjM1OTU5WjBgMQswCQYDVQQGEwJVUzER
529# MA8GA1UECAwIVmlyZ2luaWExHjAcBgNVBAoMFURyb2lkTW9ua2V5IEFwcHMsIExM
530# QzEeMBwGA1UEAwwVRHJvaWRNb25rZXkgQXBwcywgTExDMIICIjANBgkqhkiG9w0B
531# AQEFAAOCAg8AMIICCgKCAgEAuJtEjRyetghx6Abi1cpMT88uT6nIcTe3AyUvdSkj
532# CtUM8Gat0YJfqTxokb9dBzJa7j8YWOUU1Yc4EDXoYYtVRE+1UkdPAcXNMf2hNXGI
533# 45iZVwhBPQZBU4QfKltzYqrjAZgDvxeYd68qImjzUfrCY3uZHwEIuCewmNMPpEgb
534# djuSXDyBAKKBtaO2iqyaJpqcC39QnDKlXMicDPqqH5fI7wK7Lg9f4BwOsaO4P68I
535# 3pOv7L/6E5GR9+hTj6txhxFz/yCbDxN1PUvDsGaXjMmVeP2M95fkwOFwut5yBESD
536# IwAGEWUFsTJ32hSmE74+xG6rVqtueayV7U9cGURznSk9ZlTUqQOW9Z4K+pu29gTZ
537# 9zVWlONIsQR7QXfGKZWF+Xik6rTujSRTTsK7QNMYzBI6b9v0nD2pEWuGZDXIO5o5
538# N2HzXEFlwxCFY483yWSObHNBp9PFtiDueqv+8vrN+lsirZlDFCxI6hW+F8oYp3Xx
539# HdSqxsMRTqbO6dUjH2Tyd0G5fbyT8Rid7DbP6p/apzIrdFOM0kdcKLmppYBp7BIn
540# TdjbWJYhtuORIUZQbUOSM71vYCUHj7xkckiYYmkUf0XH8xx8jqgVWseBW63gCEow
541# hCEYxaWt0QGyXJ6UrlV4WTUCWzxm45I5OQoofymUvdutKgr9bR3nJ5yS/c+E3Knq
542# JhkCAwEAAaOCAYkwggGFMB8GA1UdIwQYMBaAFA8qyyCHKLjsb0iuK1SmKaoXpM0M
543# MB0GA1UdDgQWBBQta729krTac3CUndU0S0DdDscjHTAOBgNVHQ8BAf8EBAMCB4Aw
544# DAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAzBKBgNVHSAEQzBBMDUG
545# DCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29t
546# L0NQUzAIBgZngQwBBAEwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5zZWN0
547# aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcmwweQYIKwYB
548# BQUHAQEEbTBrMEQGCCsGAQUFBzAChjhodHRwOi8vY3J0LnNlY3RpZ28uY29tL1Nl
549# Y3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNydDAjBggrBgEFBQcwAYYXaHR0
550# cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggGBAJSy5YPCbh9Z
551# suDCKgDuzOWZzNza4/FrA+kT7EitDezYN3S/P0EVc0tPbgYAKfNqY+ihAMyjZHdg
552# ybfBWhGzUTDo+HEipcnZ2pgwPadsw23jJ8MN1tdms9iKDakIQ2MVsB7cGFRU8QjL
553# ovkPdZkyLcjuYbkiZRoNoKlhmrOOf6n1oCwXVJ9ONJijc+Lr3+4EIqZ39ET2+uI9
554# Wg9Bfd9XrDZfYFEcRJjNzRpCtHb26aIzV/XiMWasHRPaII34SzD0BmaPbsLeGW1U
555# GvW3tQcgVNdT/uajegmShVb+c5J5ktRSJ0cqyxmTAYaeMuA6IxG1f6kui1SAFQs2
556# lzlGyEgxgiNGo7cHHN2KidhrBL3U2bGr9Tkdp3gmV+Gj3esCdQzJE4aqmUZvIvHp
557# krair4qbLFZRNozAZJn2SIeQa5u2U0ZmvcAr1C7S3JVLP3t9LKE0mlFkV9pbIU97
558# ND3iH3tO0Zb3SvCK/XjO1PZVb8EXsi67wbfMSWAwi2CETDonb7+gBjCCBuwwggTU
559# oAMCAQICEDAPb6zdZph0fKlGNqd4LbkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNV
560# BAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0
561# eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VS
562# VHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE5MDUwMjAwMDAw
563# MFoXDTM4MDExODIzNTk1OVowfTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0
564# ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGln
565# byBMaW1pdGVkMSUwIwYDVQQDExxTZWN0aWdvIFJTQSBUaW1lIFN0YW1waW5nIENB
566# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyBsBr9ksfoiZfQGYPyCQ
567# vZyAIVSTuc+gPlPvs1rAdtYaBKXOR4O168TMSTTL80VlufmnZBYmCfvVMlJ5Lslj
568# whObtoY/AQWSZm8hq9VxEHmH9EYqzcRaydvXXUlNclYP3MnjU5g6Kh78zlhJ07/z
569# Obu5pCNCrNAVw3+eolzXOPEWsnDTo8Tfs8VyrC4Kd/wNlFK3/B+VcyQ9ASi8Dw1P
570# s5EBjm6dJ3VV0Rc7NCF7lwGUr3+Az9ERCleEyX9W4L1GnIK+lJ2/tCCwYH64TfUN
571# P9vQ6oWMilZx0S2UTMiMPNMUopy9Jv/TUyDHYGmbWApU9AXn/TGs+ciFF8e4KRmk
572# KS9G493bkV+fPzY+DjBnK0a3Na+WvtpMYMyou58NFNQYxDCYdIIhz2JWtSFzEh79
573# qsoIWId3pBXrGVX/0DlULSbuRRo6b83XhPDX8CjFT2SDAtT74t7xvAIo9G3aJ4oG
574# 0paH3uhrDvBbfel2aZMgHEqXLHcZK5OVmJyXnuuOwXhWxkQl3wYSmgYtnwNe/YOi
575# U2fKsfqNoWTJiJJZy6hGwMnypv99V9sSdvqKQSTUG/xypRSi1K1DHKRJi0E5FAMe
576# KfobpSKupcNNgtCN2mu32/cYQFdz8HGj+0p9RTbB942C+rnJDVOAffq2OVgy728Y
577# UInXT50zvRq1naHelUF6p4MCAwEAAaOCAVowggFWMB8GA1UdIwQYMBaAFFN5v1qq
578# K0rPVIDh2JvAnfKyA2bLMB0GA1UdDgQWBBQaofhhGSAPw0F3RSiO0TVfBhIEVTAO
579# BgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggr
580# BgEFBQcDCDARBgNVHSAECjAIMAYGBFUdIAAwUAYDVR0fBEkwRzBFoEOgQYY/aHR0
581# cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdFJTQUNlcnRpZmljYXRpb25B
582# dXRob3JpdHkuY3JsMHYGCCsGAQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0cDov
583# L2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdFJTQUFkZFRydXN0Q0EuY3J0MCUG
584# CCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEB
585# DAUAA4ICAQBtVIGlM10W4bVTgZF13wN6MgstJYQRsrDbKn0qBfW8Oyf0WqC5SVmQ
586# KWxhy7VQ2+J9+Z8A70DDrdPi5Fb5WEHP8ULlEH3/sHQfj8ZcCfkzXuqgHCZYXPO0
587# EQ/V1cPivNVYeL9IduFEZ22PsEMQD43k+ThivxMBxYWjTMXMslMwlaTW9JZWCLjN
588# XH8Blr5yUmo7Qjd8Fng5k5OUm7Hcsm1BbWfNyW+QPX9FcsEbI9bCVYRm5LPFZgb2
589# 89ZLXq2jK0KKIZL+qG9aJXBigXNjXqC72NzXStM9r4MGOBIdJIct5PwC1j53BLwE
590# NrXnd8ucLo0jGLmjwkcd8F3WoXNXBWiap8k3ZR2+6rzYQoNDBaWLpgn/0aGUpk6q
591# PQn1BWy30mRa2Coiwkud8TleTN5IPZs0lpoJX47997FSkc4/ifYcobWpdR9xv1tD
592# XWU9UIFuq/DQ0/yysx+2mZYm9Dx5i1xkzM3uJ5rloMAMcofBbk1a0x7q8ETmMm8c
593# 6xdOlMN4ZSA7D0GqH+mhQZ3+sbigZSo04N6o+TzmwTC7wKBjLPxcFgCo0MR/6hGd
594# HgbGpm0yXbQ4CStJB6r97DDa8acvz7f9+tCjhNknnvsBZne5VhDhIG7GrrH5trrI
595# NV0zdo7xfCAMKneutaIChrop7rRaALGMq+P5CslUXdS5anSevUiumDCCBvUwggTd
596# oAMCAQICEDlMJeF8oG0nqGXiO9kdItQwDQYJKoZIhvcNAQEMBQAwfTELMAkGA1UE
597# BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2Fs
598# Zm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSUwIwYDVQQDExxTZWN0aWdv
599# IFJTQSBUaW1lIFN0YW1waW5nIENBMB4XDTIzMDUwMzAwMDAwMFoXDTM0MDgwMjIz
600# NTk1OVowajELMAkGA1UEBhMCR0IxEzARBgNVBAgTCk1hbmNoZXN0ZXIxGDAWBgNV
601# BAoTD1NlY3RpZ28gTGltaXRlZDEsMCoGA1UEAwwjU2VjdGlnbyBSU0EgVGltZSBT
602# dGFtcGluZyBTaWduZXIgIzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
603# AQCkkyhSS88nh3akKRyZOMDnDtTRHOxoywFk5IrNd7BxZYK8n/yLu7uVmPslEY5a
604# iAlmERRYsroiW+b2MvFdLcB6og7g4FZk7aHlgSByIGRBbMfDCPrzfV3vIZrCftcs
605# w7oRmB780yAIQrNfv3+IWDKrMLPYjHqWShkTXKz856vpHBYusLA4lUrPhVCrZwMl
606# obs46Q9vqVqakSgTNbkf8z3hJMhrsZnoDe+7TeU9jFQDkdD8Lc9VMzh6CRwH0SLg
607# Y4anvv3Sg3MSFJuaTAlGvTS84UtQe3LgW/0Zux88ahl7brstRCq+PEzMrIoEk8ZX
608# hqBzNiuBl/obm36Ih9hSeYn+bnc317tQn/oYJU8T8l58qbEgWimro0KHd+D0TAJI
609# 3VilU6ajoO0ZlmUVKcXtMzAl5paDgZr2YGaQWAeAzUJ1rPu0kdDF3QFAaraoEO72
610# jXq3nnWv06VLGKEMn1ewXiVHkXTNdRLRnG/kXg2b7HUm7v7T9ZIvUoXo2kRRKqLM
611# AMqHZkOjGwDvorWWnWKtJwvyG0rJw5RCN4gghKiHrsO6I3J7+FTv+GsnsIX1p0OF
612# 2Cs5dNtadwLRpPr1zZw9zB+uUdB7bNgdLRFCU3F0wuU1qi1SEtklz/DT0JFDEtcy
613# fZhs43dByP8fJFTvbq3GPlV78VyHOmTxYEsFT++5L+wJEwIDAQABo4IBgjCCAX4w
614# HwYDVR0jBBgwFoAUGqH4YRkgD8NBd0UojtE1XwYSBFUwHQYDVR0OBBYEFAMPMciR
615# KpO9Y/PRXU2kNA/SlQEYMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMBYG
616# A1UdJQEB/wQMMAoGCCsGAQUFBwMIMEoGA1UdIARDMEEwNQYMKwYBBAGyMQECAQMI
617# MCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAEE
618# AjBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vY3JsLnNlY3RpZ28uY29tL1NlY3Rp
619# Z29SU0FUaW1lU3RhbXBpbmdDQS5jcmwwdAYIKwYBBQUHAQEEaDBmMD8GCCsGAQUF
620# BzAChjNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29SU0FUaW1lU3RhbXBp
621# bmdDQS5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMA0G
622# CSqGSIb3DQEBDAUAA4ICAQBMm2VY+uB5z+8VwzJt3jOR63dY4uu9y0o8dd5+lG3D
623# IscEld9laWETDPYMnvWJIF7Bh8cDJMrHpfAm3/j4MWUN4OttUVemjIRSCEYcKsLe
624# 8tqKRfO+9/YuxH7t+O1ov3pWSOlh5Zo5d7y+upFkiHX/XYUWNCfSKcv/7S3a/76T
625# DOxtog3Mw/FuvSGRGiMAUq2X1GJ4KoR5qNc9rCGPcMMkeTqX8Q2jo1tT2KsAulj7
626# NYBPXyhxbBlewoNykK7gxtjymfvqtJJlfAd8NUQdrVgYa2L73mzECqls0yFGcNwv
627# jXVMI8JB0HqWO8NL3c2SJnR2XDegmiSeTl9O048P5RNPWURlS0Nkz0j4Z2e5Tb/M
628# DbE6MNChPUitemXk7N/gAfCzKko5rMGk+al9NdAyQKCxGSoYIbLIfQVxGksnNqrg
629# mByDdefHfkuEQ81D+5CXdioSrEDBcFuZCkD6gG2UYXvIbrnIZ2ckXFCNASDeB/cB
630# 1PguEc2dg+X4yiUcRD0n5bCGRyoLG4R2fXtoT4239xO07aAt7nMP2RC6nZksfNd1
631# H48QxJTmfiTllUqIjCfWhWYd+a5kdpHoSP7IVQrtKcMf3jimwBT7Mj34qYNiNsjD
632# vgCHHKv6SkIciQPc9Vx8cNldeE7un14g5glqfCsIo0j1FfwET9/NIRx65fWOGtS5
633# QDGCBmkwggZlAgEBMGgwVDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28g
634# TGltaXRlZDErMCkGA1UEAxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENB
635# IFIzNgIQBkM/zMzkM6iSzBe3RqWMZTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEE
636# AYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwG
637# CisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCCn5BDd
638# F+7Q6LMoJuJxenFHgWAZjm1CET9oBKnlZKClzjANBgkqhkiG9w0BAQEFAASCAgAS
639# ypiTBQb39I43fGdH6t2OYAl53TSbJfPG99/11OYS+6nMTKhy7dHtzzgMFxBQmL/L
640# P4eJJMqh1yIYEjrjhNLLddRhVP2lfsuQ1OkLVx5lS8M32I3SzpskOe+SywMLDYJy
641# sYHEcZkyQX0Q2J/RGzF8/tDcltZodYEdZrQdaAKo7bGv1JcYpW7B6JZnNjquE90d
642# WVNAsQ6Mc3kzkjbs2qDaRAdkOmX5uENWbNf1GgTRpud7Ic5hMyb4v9qfWAptlFuO
643# pLHyuINNsBuTfzD/cGVR9qecDPIE90UnHQHZWws9U+m84CzAmqpptp4VhrAWc7Hc
644# bHsbmg4tGA41ythKyERpW9YlwID6fJYMigEVmJihXdM/qRGO2XdfbPAr0C0AMPIV
645# re8r86BJw1lxJJYL2gsS/ttgrnW2C8aFq+IxxXWnv/7maPG69K/jmRLQGZuLIZCl
646# 7rT6hob37zZMsdnqDZ0DjJb/FGonJr7GpyeMEWPy8eVwZydMbC9hBl8HNgQ04sp7
647# ouskM1nCco9DV+d1Y6Oyje6IylZjD+xgX7VfsDa2O3Lw27cfyxJBW359meYHytkJ
648# oYqh4Y4fC9YlYTD3913ryqTbPaWtWjvFV+GR8biHxDoTmTRuNaeN6RDyyZJkdON7
649# CnR/8X8y4C9BXdesvjfIdhHZsGwLJcZ87cnYGb7oYqGCA0swggNHBgkqhkiG9w0B
650# CQYxggM4MIIDNAIBATCBkTB9MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRl
651# ciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdv
652# IExpbWl0ZWQxJTAjBgNVBAMTHFNlY3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgQ0EC
653# EDlMJeF8oG0nqGXiO9kdItQwDQYJYIZIAWUDBAICBQCgeTAYBgkqhkiG9w0BCQMx
654# CwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yNDA0MjgyMjE0MzdaMD8GCSqG
655# SIb3DQEJBDEyBDARWlO4ZY7Qij7x/efLB7SJrHgfXJwezYW7sskwZhfhnoQ8JQ8Q
656# HfefvIk4nF1+1PkwDQYJKoZIhvcNAQEBBQAEggIAWpBgtEaYVRayRmCTjyOoKg0b
657# 2vXn3dqpcpckspX4t58xHLbhapGm3Akg9N6C0xZWm9qQ9vhjoOeuLZ0Z+017JRUe
658# YExYYIYcyNGlxyt/uXiBst8KiAFFzn6RwIjycQcsnOsGRBAz2E9/k7wGtdg8kqBI
659# Q71cDl+seRjWVcTR4JgthphZuRTKS1Jxn3tjDNJuK+LFo4jL38ojxhhdOnb3xzZ0
660# M1AQ+l2YuDxBX4H9aZsbiTfdI1mxvmPgmZbq4fjV28TUCiBhD1UYuHUPN3Ff9Fwo
661# 9BMbTLvKqED8Mm9A25S4M8kVZsGt8j3EAt0AJaWbdHLpLC0l0ykDAcSiwZNYsdMu
662# vN0q6z5knfhKv4M8FXQ2wu8pbPww7/4kBqqy9L8VMI8UIazG9Z/R7yhkZjEz3jgc
663# a/VZMcsDn41B79/9eSx4wED7NYtc0T6DB8WFH1a2CqlORSHnRolnms+VjWerfmZP
664# a9lV7Sk1gGZ+MePsWwXj7liURI/ubTtPtxWElWuYookkQMmrOJYj+IZCW4RvV3I3
665# utzHUwfbBaON3Mq46ADayLxKP2SE9j3JXpl4mZeWXdYUrywt2TgQktCXT7iZOinl
666# dbx1tso5uDAj1DQDiTm4Nps+UWjyo2bZB/g1ONMqxPDIuY75HryfmJDlvCMp80Tk
667# cJchA5s/dVwNSWKti4Q=
668# SIG # End signature block
669