You've already forked setup-dotnet
							
							
				mirror of
				https://github.com/actions/setup-dotnet.git
				synced 2025-10-31 07:16:21 +07:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			cacheupgra
			...
			new-cdn-v3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b238433afb | |||
| 3b55724a43 | |||
| 2984211dcd | |||
| 0126ca49f0 | |||
| 88e040e901 | |||
| 76f538c68f | |||
| 48d4d7f50f | |||
| 8a4bd4c9a8 | 
							
								
								
									
										32
									
								
								.github/workflows/e2e-tests.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								.github/workflows/e2e-tests.yml
									
									
									
									
										vendored
									
									
								
							| @ -17,7 +17,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -40,7 +40,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macos-13] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -69,7 +69,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -94,7 +94,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macos-13] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -114,7 +114,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -138,7 +138,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -159,7 +159,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -183,7 +183,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -209,7 +209,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -234,7 +234,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -256,7 +256,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macos-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macos-latest] | ||||
|     env: | ||||
|       NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages | ||||
|     steps: | ||||
| @ -287,7 +287,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macos-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macos-latest] | ||||
|     env: | ||||
|       NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages | ||||
|     steps: | ||||
| @ -316,7 +316,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -342,7 +342,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
| @ -366,7 +366,7 @@ jobs: | ||||
|           if (-not ($version -eq '${{steps.step2.outputs.dotnet-version}}')) { throw "Unexpected output value" } | ||||
|  | ||||
|   test-proxy: | ||||
|     runs-on: ubuntu-latest | ||||
|     runs-on: ubuntu-22.04 | ||||
|     container: | ||||
|       image: ubuntu:latest | ||||
|       options: --dns 127.0.0.1 | ||||
| @ -406,7 +406,7 @@ jobs: | ||||
|           __tests__/verify-dotnet.ps1 -Patterns "^6.0" -CheckNugetConfig | ||||
|  | ||||
|   test-bypass-proxy: | ||||
|     runs-on: ubuntu-latest | ||||
|     runs-on: ubuntu-22.04 | ||||
|     env: | ||||
|       https_proxy: http://no-such-proxy:3128 | ||||
|       no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/workflows/test-dotnet.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test-dotnet.yml
									
									
									
									
										vendored
									
									
								
							| @ -17,7 +17,7 @@ jobs: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         operating-system: [ubuntu-latest, windows-latest, macOS-latest] | ||||
|         operating-system: [ubuntu-22.04, windows-latest, macOS-latest] | ||||
|         dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0', '8.0'] | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|  | ||||
							
								
								
									
										11
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								dist/setup/index.js
									
									
									
									
										vendored
									
									
								
							| @ -71264,7 +71264,13 @@ class DotnetVersionResolver { | ||||
|                 allowRetries: true, | ||||
|                 maxRetries: 3 | ||||
|             }); | ||||
|             const response = yield httpClient.getJson(DotnetVersionResolver.DotNetCoreIndexUrl); | ||||
|             let response; | ||||
|             try { | ||||
|                 response = yield httpClient.getJson(DotnetVersionResolver.DotNetCoreIndexUrl); | ||||
|             } | ||||
|             catch (error) { | ||||
|                 response = yield httpClient.getJson(DotnetVersionResolver.DotnetCoreIndexFallbackUrl); | ||||
|             } | ||||
|             const result = response.result || {}; | ||||
|             const releasesInfo = result['releases-index']; | ||||
|             const releaseInfo = releasesInfo.find(info => { | ||||
| @ -71279,7 +71285,8 @@ class DotnetVersionResolver { | ||||
|     } | ||||
| } | ||||
| exports.DotnetVersionResolver = DotnetVersionResolver; | ||||
| DotnetVersionResolver.DotNetCoreIndexUrl = 'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json'; | ||||
| DotnetVersionResolver.DotNetCoreIndexUrl = 'https://builds.dotnet.microsoft.com/dotnet/release-metadata/releases-index.json'; | ||||
| DotnetVersionResolver.DotnetCoreIndexFallbackUrl = 'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json'; | ||||
| class DotnetCoreInstaller { | ||||
|     constructor(version, quality) { | ||||
|         this.version = version; | ||||
|  | ||||
							
								
								
									
										649
									
								
								externals/install-dotnet.ps1
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										649
									
								
								externals/install-dotnet.ps1
									
									
									
									
										vendored
									
									
								
							| @ -98,6 +98,16 @@ | ||||
| .PARAMETER DownloadTimeout | ||||
|     Determines timeout duration in seconds for dowloading of the SDK file | ||||
|     Default: 1200 seconds (20 minutes) | ||||
| .PARAMETER KeepZip | ||||
|     If set, downloaded file is kept | ||||
| .PARAMETER ZipPath | ||||
|     Use that path to store installer, generated by default | ||||
| .EXAMPLE | ||||
|     dotnet-install.ps1 -Version 7.0.401 | ||||
|     Installs the .NET SDK version 7.0.401 | ||||
| .EXAMPLE | ||||
|     dotnet-install.ps1 -Channel 8.0 -Quality GA | ||||
|     Installs the latest GA (general availability) version of the .NET 8.0 SDK | ||||
| #> | ||||
| [cmdletbinding()] | ||||
| param( | ||||
| @ -121,7 +131,10 @@ param( | ||||
|     [string[]]$ProxyBypassList = @(), | ||||
|     [switch]$SkipNonVersionedFiles, | ||||
|     [switch]$NoCdn, | ||||
|    [int]$DownloadTimeout=1200 | ||||
|     [int]$DownloadTimeout = 1200, | ||||
|     [switch]$KeepZip, | ||||
|     [string]$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()), | ||||
|     [switch]$Help | ||||
| ) | ||||
|  | ||||
| Set-StrictMode -Version Latest | ||||
| @ -173,7 +186,24 @@ function Say-Verbose($str) { | ||||
| function Measure-Action($name, $block) { | ||||
|     $time = Measure-Command $block | ||||
|     $totalSeconds = $time.TotalSeconds | ||||
|     Say-Verbose "⏱ Action '$name' took $totalSeconds seconds" | ||||
|     Say-Verbose "Action '$name' took $totalSeconds seconds" | ||||
| } | ||||
|  | ||||
| function Get-Remote-File-Size($zipUri) { | ||||
|     try { | ||||
|         $response = Invoke-WebRequest -Uri $zipUri -Method Head | ||||
|         $fileSize = $response.Headers["Content-Length"] | ||||
|         if ((![string]::IsNullOrEmpty($fileSize))) { | ||||
|             Say "Remote file $zipUri size is $fileSize bytes." | ||||
|          | ||||
|             return $fileSize | ||||
|         } | ||||
|     } | ||||
|     catch { | ||||
|         Say-Verbose "Content-Length header was not extracted for $zipUri." | ||||
|     } | ||||
|  | ||||
|     return $null | ||||
| } | ||||
|  | ||||
| function Say-Invocation($Invocation) { | ||||
| @ -219,8 +249,7 @@ function Get-Machine-Architecture() { | ||||
|  | ||||
|     try {         | ||||
|         if ( ((Get-CimInstance -ClassName CIM_OperatingSystem).OSArchitecture) -like "ARM*") { | ||||
|             if( [Environment]::Is64BitOperatingSystem ) | ||||
|             { | ||||
|             if ( [Environment]::Is64BitOperatingSystem ) { | ||||
|                 return "arm64" | ||||
|             }   | ||||
|             return "arm" | ||||
| @ -249,13 +278,13 @@ function Get-CLIArchitecture-From-Architecture([string]$Architecture) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function ValidateFeedCredential([string] $FeedCredential) | ||||
| { | ||||
| function ValidateFeedCredential([string] $FeedCredential) { | ||||
|     if ($Internal -and [string]::IsNullOrWhitespace($FeedCredential)) { | ||||
|         $message = "Provide credentials via -FeedCredential parameter." | ||||
|         if ($DryRun) { | ||||
|             Say-Warning "$message" | ||||
|         } else { | ||||
|         } | ||||
|         else { | ||||
|             throw "$message" | ||||
|         } | ||||
|     } | ||||
| @ -347,8 +376,7 @@ function Load-Assembly([string] $Assembly) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, [bool]$DisableFeedCredential) | ||||
| { | ||||
| function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, [bool]$DisableFeedCredential) { | ||||
|     $cts = New-Object System.Threading.CancellationTokenSource | ||||
|  | ||||
|     $downloadScript = { | ||||
| @ -366,12 +394,14 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, | ||||
|                     if ($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) { | ||||
|                         if ($null -ne $DefaultProxy.GetProxy($Uri)) { | ||||
|                             $ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString | ||||
|                         } else { | ||||
|                         } | ||||
|                         else { | ||||
|                             $ProxyAddress = $null | ||||
|                         } | ||||
|                         $ProxyUseDefaultCredentials = $true | ||||
|                     } | ||||
|                 } catch { | ||||
|                 } | ||||
|                 catch { | ||||
|                     # Eat the exception and move forward as the above code is an attempt | ||||
|                     #    at resolving the DefaultProxy that may not have been a problem. | ||||
|                     $ProxyAddress = $null | ||||
| @ -387,8 +417,7 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, | ||||
|                     BypassList            = $ProxyBypassList; | ||||
|                 } | ||||
|             }        | ||||
|             if ($DisableRedirect) | ||||
|             { | ||||
|             if ($DisableRedirect) { | ||||
|                 $HttpClientHandler.AllowAutoRedirect = $false | ||||
|             } | ||||
|             $HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler | ||||
| @ -422,8 +451,7 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, | ||||
|                     $DownloadException.Data["StatusCode"] = [int] $Response.StatusCode | ||||
|                     $DownloadException.Data["ErrorMessage"] = "Unable to download $Uri. Returned HTTP status code: " + $DownloadException.Data["StatusCode"] | ||||
|  | ||||
|                     if (404 -eq [int] $Response.StatusCode) | ||||
|                     { | ||||
|                     if (404 -eq [int] $Response.StatusCode) { | ||||
|                         $cts.Cancel() | ||||
|                     } | ||||
|                 } | ||||
| @ -462,10 +490,8 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, | ||||
|     try { | ||||
|         return Invoke-With-Retry $downloadScript $cts.Token | ||||
|     } | ||||
|     finally | ||||
|     { | ||||
|         if ($null -ne $cts) | ||||
|         { | ||||
|     finally { | ||||
|         if ($null -ne $cts) { | ||||
|             $cts.Dispose() | ||||
|         } | ||||
|     } | ||||
| @ -583,11 +609,9 @@ function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string | ||||
|     elseif ($Runtime -eq "windowsdesktop") { | ||||
|         # The windows desktop runtime is part of the core runtime layout prior to 5.0 | ||||
|         $PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip" | ||||
|         if ($SpecificVersion -match '^(\d+)\.(.*)$') | ||||
|         { | ||||
|         if ($SpecificVersion -match '^(\d+)\.(.*)$') { | ||||
|             $majorVersion = [int]$Matches[1] | ||||
|             if ($majorVersion -ge 5) | ||||
|             { | ||||
|             if ($majorVersion -ge 5) { | ||||
|                 $PayloadURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip" | ||||
|             } | ||||
|         } | ||||
| @ -637,8 +661,7 @@ function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [stri | ||||
|  | ||||
|             if ($productVersionResponse.StatusCode -eq 200) { | ||||
|                 $productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim() | ||||
|                 if ($productVersion -ne $SpecificVersion) | ||||
|                 { | ||||
|                 if ($productVersion -ne $SpecificVersion) { | ||||
|                     Say "Using alternate version $productVersion found in $ProductVersionTxtURL" | ||||
|                 } | ||||
|                 return $productVersion | ||||
| @ -653,8 +676,7 @@ function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [stri | ||||
|     } | ||||
|  | ||||
|     # Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number. | ||||
|     if ([string]::IsNullOrEmpty($PackageDownloadLink)) | ||||
|     { | ||||
|     if ([string]::IsNullOrEmpty($PackageDownloadLink)) { | ||||
|         Say-Verbose "Using the default value '$SpecificVersion' as the product version." | ||||
|         return $SpecificVersion | ||||
|     } | ||||
| @ -714,16 +736,14 @@ function Get-Product-Version-Url([string]$AzureFeed, [string]$SpecificVersion, [ | ||||
|     return $ProductVersionTxtURL | ||||
| } | ||||
|  | ||||
| function Get-ProductVersionFromDownloadLink([string]$PackageDownloadLink, [string]$SpecificVersion) | ||||
| { | ||||
| function Get-ProductVersionFromDownloadLink([string]$PackageDownloadLink, [string]$SpecificVersion) { | ||||
|     Say-Invocation $MyInvocation | ||||
|  | ||||
|     #product specific version follows the product name | ||||
|     #for filename 'dotnet-sdk-3.1.404-win-x64.zip': the product version is 3.1.400 | ||||
|     $filename = $PackageDownloadLink.Substring($PackageDownloadLink.LastIndexOf("/") + 1) | ||||
|     $filenameParts = $filename.Split('-') | ||||
|     if ($filenameParts.Length -gt 2) | ||||
|     { | ||||
|     if ($filenameParts.Length -gt 2) { | ||||
|         $productVersion = $filenameParts[2] | ||||
|         Say-Verbose "Extracted product version '$productVersion' from download link '$PackageDownloadLink'." | ||||
|     } | ||||
| @ -741,6 +761,9 @@ function Get-User-Share-Path() { | ||||
|     if (!$InstallRoot) { | ||||
|         $InstallRoot = "$env:LocalAppData\Microsoft\dotnet" | ||||
|     } | ||||
|     elseif ($InstallRoot -like "$env:ProgramFiles\dotnet\?*") { | ||||
|         Say-Warning "The install root specified by the environment variable DOTNET_INSTALL_DIR points to the sub folder of $env:ProgramFiles\dotnet which is the default dotnet install root using .NET SDK installer. It is better to keep aligned with .NET SDK installer." | ||||
|     } | ||||
|     return $InstallRoot | ||||
| } | ||||
|  | ||||
| @ -753,6 +776,19 @@ function Resolve-Installation-Path([string]$InstallDir) { | ||||
|     return $InstallDir | ||||
| } | ||||
|  | ||||
| function Test-User-Write-Access([string]$InstallDir) { | ||||
|     try { | ||||
|         $tempFileName = [guid]::NewGuid().ToString() | ||||
|         $tempFilePath = Join-Path -Path $InstallDir -ChildPath $tempFileName | ||||
|         New-Item -Path $tempFilePath -ItemType File -Force | ||||
|         Remove-Item $tempFilePath -Force | ||||
|         return $true | ||||
|     } | ||||
|     catch { | ||||
|         return $false | ||||
|     } | ||||
| } | ||||
|  | ||||
| function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) { | ||||
|     Say-Invocation $MyInvocation | ||||
|  | ||||
| @ -836,8 +872,7 @@ function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     catch | ||||
|     { | ||||
|     catch { | ||||
|         Say-Error "Failed to extract package. Exception: $_" | ||||
|         throw; | ||||
|     } | ||||
| @ -869,6 +904,8 @@ function DownloadFile($Source, [string]$OutPath) { | ||||
|         $File = [System.IO.File]::Create($OutPath) | ||||
|         $Stream.CopyTo($File) | ||||
|         $File.Close() | ||||
|  | ||||
|         ValidateRemoteLocalFileSizes -LocalFileOutPath $OutPath -SourceUri $Source | ||||
|     } | ||||
|     finally { | ||||
|         if ($null -ne $Stream) { | ||||
| @ -877,19 +914,40 @@ function DownloadFile($Source, [string]$OutPath) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function ValidateRemoteLocalFileSizes([string]$LocalFileOutPath, $SourceUri) { | ||||
|     try { | ||||
|         $remoteFileSize = Get-Remote-File-Size -zipUri $SourceUri | ||||
|         $fileSize = [long](Get-Item $LocalFileOutPath).Length | ||||
|         Say "Downloaded file $SourceUri size is $fileSize bytes." | ||||
|      | ||||
|         if ((![string]::IsNullOrEmpty($remoteFileSize)) -and !([string]::IsNullOrEmpty($fileSize)) ) { | ||||
|             if ($remoteFileSize -ne $fileSize) { | ||||
|                 Say "The remote and local file sizes are not equal. Remote file size is $remoteFileSize bytes and local size is $fileSize bytes. The local package may be corrupted." | ||||
|             } | ||||
|             else { | ||||
|                 Say "The remote and local file sizes are equal." | ||||
|             }    | ||||
|         } | ||||
|         else { | ||||
|             Say "Either downloaded or local package size can not be measured. One of them may be corrupted." | ||||
|         } | ||||
|     } | ||||
|     catch { | ||||
|         Say "Either downloaded or local package size can not be measured. One of them may be corrupted." | ||||
|     } | ||||
| } | ||||
|  | ||||
| function SafeRemoveFile($Path) { | ||||
|     try { | ||||
|         if (Test-Path $Path) { | ||||
|             Remove-Item $Path | ||||
|             Say-Verbose "The temporary file `"$Path`" was removed." | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|         else { | ||||
|             Say-Verbose "The temporary file `"$Path`" does not exist, therefore is not removed." | ||||
|         } | ||||
|     } | ||||
|     catch | ||||
|     { | ||||
|     catch { | ||||
|         Say-Warning "Failed to remove the temporary file: `"$Path`", remove it manually." | ||||
|     } | ||||
| } | ||||
| @ -901,7 +959,8 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot) { | ||||
|         if (-Not $env:path.Contains($SuffixedBinPath)) { | ||||
|             Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process." | ||||
|             $env:path = $SuffixedBinPath + $env:path | ||||
|         } else { | ||||
|         } | ||||
|         else { | ||||
|             Say-Verbose "Current process PATH already contains `"$BinPath`"" | ||||
|         } | ||||
|     } | ||||
| @ -910,8 +969,7 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function PrintDryRunOutput($Invocation, $DownloadLinks) | ||||
| { | ||||
| function PrintDryRunOutput($Invocation, $DownloadLinks) { | ||||
|     Say "Payload URLs:" | ||||
|      | ||||
|     for ($linkIndex = 0; $linkIndex -lt $DownloadLinks.count; $linkIndex++) { | ||||
| @ -934,12 +992,37 @@ function PrintDryRunOutput($Invocation, $DownloadLinks) | ||||
|         $RepeatableCommand += " -FeedCredential `"<feedCredential>`"" | ||||
|     } | ||||
|     Say "Repeatable invocation: $RepeatableCommand" | ||||
|     if ($SpecificVersion -ne $EffectiveVersion) | ||||
|     { | ||||
|     if ($SpecificVersion -ne $EffectiveVersion) { | ||||
|         Say "NOTE: Due to finding a version manifest with this runtime, it would actually install with version '$EffectiveVersion'" | ||||
|     } | ||||
| } | ||||
|  | ||||
| # grab the 'stem' of the redirect and check it against all of our configured feeds,  | ||||
| # if it matches, we can be sure that the redirect is valid and we should use it for | ||||
| # subsequent processing | ||||
| function Sanitize-RedirectUrl([string]$url) { | ||||
|     $urlSegments = ([System.Uri]$url).Segments; | ||||
|     $urlStem = $urlSegments[2..($urlSegments.Length - 1)] -join ""; | ||||
|     Write-Verbose "Checking configured feeds for the asset at $urlStem" | ||||
|     foreach ($prospectiveFeed in $feeds) { | ||||
|         $trialUrl = "$prospectiveFeed/$urlStem"; | ||||
|         Write-Verbose "Checking $trialUrl" | ||||
|         try { | ||||
|             $trialResponse = Invoke-WebRequest -Uri $trialUrl -Method HEAD | ||||
|             if ($trialResponse.StatusCode -eq 200) { | ||||
|                 Write-Verbose "Found a match at $trialUrl" | ||||
|                 return $trialUrl; | ||||
|             } | ||||
|             else { | ||||
|                 Write-Verbose "No match at $trialUrl" | ||||
|             } | ||||
|         } | ||||
|         catch { | ||||
|             Write-Verbose "Failed to check $trialUrl" | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) { | ||||
|     Say-Invocation $MyInvocation  | ||||
|  | ||||
| @ -963,8 +1046,7 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern | ||||
|     Say-Verbose  "Constructed aka.ms link: '$akaMsLink'." | ||||
|     $akaMsDownloadLink = $null | ||||
|  | ||||
|     for ($maxRedirections = 9; $maxRedirections -ge 0; $maxRedirections--) | ||||
|     { | ||||
|     for ($maxRedirections = 9; $maxRedirections -ge 0; $maxRedirections--) { | ||||
|         #get HTTP response | ||||
|         #do not pass credentials as a part of the $akaMsLink and do not apply credentials in the GetHTTPResponse function | ||||
|         #otherwise the redirect link would have credentials as well | ||||
| @ -978,8 +1060,7 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern | ||||
|         } | ||||
|  | ||||
|         #if HTTP code is 301 (Moved Permanently), the redirect link exists | ||||
|         if  ($Response.StatusCode -eq 301) | ||||
|         { | ||||
|         if ($Response.StatusCode -eq 301) { | ||||
|             try { | ||||
|                 $akaMsDownloadLink = $Response.Headers.GetValues("Location")[0] | ||||
|  | ||||
| @ -998,9 +1079,13 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern | ||||
|                 return $null | ||||
|             } | ||||
|         } | ||||
|         elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink))) | ||||
|         { | ||||
|         elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink))) { | ||||
|             # Redirections have ended. | ||||
|             $actualRedirectUrl = Sanitize-RedirectUrl $akaMsDownloadLink | ||||
|             if ($null -ne $actualRedirectUrl) { | ||||
|                 $akaMsDownloadLink = $actualRedirectUrl | ||||
|             } | ||||
|  | ||||
|             return $akaMsDownloadLink | ||||
|         } | ||||
|  | ||||
| @ -1049,10 +1134,11 @@ function Get-AkaMsLink-And-Version([string] $NormalizedChannel, [string] $Normal | ||||
|     } | ||||
| } | ||||
|  | ||||
| function Get-Feeds-To-Use() | ||||
| { | ||||
| function Get-Feeds-To-Use() { | ||||
|     $feeds = @( | ||||
|     "https://dotnetcli.azureedge.net/dotnet", | ||||
|         "https://builds.dotnet.microsoft.com/dotnet" | ||||
|         "https://dotnetcli.azureedge.net/dotnet" | ||||
|         "https://ci.dot.net/public" | ||||
|         "https://dotnetbuilds.azureedge.net/public" | ||||
|     ) | ||||
|  | ||||
| @ -1071,6 +1157,8 @@ function Get-Feeds-To-Use() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Write-Verbose "Initialized feeds: $feeds" | ||||
|  | ||||
|     return $feeds | ||||
| } | ||||
|  | ||||
| @ -1100,6 +1188,13 @@ function Resolve-AssetName-And-RelativePath([string] $Runtime) { | ||||
| } | ||||
|  | ||||
| function Prepare-Install-Directory { | ||||
|     $diskSpaceWarning = "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space."; | ||||
|  | ||||
|     if ($PSVersionTable.PSVersion.Major -lt 7) { | ||||
|         Say-Verbose $diskSpaceWarning | ||||
|         return | ||||
|     } | ||||
|  | ||||
|     New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null | ||||
|  | ||||
|     $installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name); | ||||
| @ -1108,14 +1203,20 @@ function Prepare-Install-Directory { | ||||
|         $diskInfo = Get-PSDrive -Name $installDrive | ||||
|     } | ||||
|     catch { | ||||
|         Say-Warning "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space." | ||||
|         Say-Warning $diskSpaceWarning | ||||
|     } | ||||
|  | ||||
|     # The check is relevant for PS version >= 7, the result can be irrelevant for older versions. See https://github.com/PowerShell/PowerShell/issues/12442. | ||||
|     if ( ($null -ne $diskInfo) -and ($diskInfo.Free / 1MB -le 100)) { | ||||
|         throw "There is not enough disk space on drive ${installDrive}:" | ||||
|     } | ||||
| } | ||||
|  | ||||
| if ($Help) { | ||||
|     Get-Help $PSCommandPath -Examples | ||||
|     exit | ||||
| } | ||||
|  | ||||
| Say-Verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:" | ||||
| Say-Verbose "- The SDK needs to be installed without user interaction and without admin rights." | ||||
| Say-Verbose "- The SDK installation doesn't need to persist across multiple CI runs." | ||||
| @ -1139,6 +1240,10 @@ Measure-Action "Product discovery" { | ||||
| } | ||||
|  | ||||
| $InstallRoot = Resolve-Installation-Path $InstallDir | ||||
| if (-not (Test-User-Write-Access $InstallRoot)) { | ||||
|     Say-Error "The current user doesn't have write access to the installation root '$InstallRoot' to install .NET. Please try specifying a different installation directory using the -InstallDir parameter, or ensure the selected directory has the appropriate permissions." | ||||
|     throw | ||||
| } | ||||
| Say-Verbose "InstallRoot: $InstallRoot" | ||||
| $ScriptName = $MyInvocation.MyCommand.Name | ||||
| ($assetName, $dotnetPackageRelativePath) = Resolve-AssetName-And-RelativePath -Runtime $Runtime | ||||
| @ -1160,8 +1265,7 @@ if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) { | ||||
|          | ||||
|         if (-Not $DryRun) { | ||||
|             Say-Verbose "Checking if the version $EffectiveVersion is already installed" | ||||
|             if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) | ||||
|             { | ||||
|             if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) { | ||||
|                 Say "$assetName with version '$EffectiveVersion' is already installed." | ||||
|                 Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot | ||||
|                 return | ||||
| @ -1172,8 +1276,7 @@ if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) { | ||||
|  | ||||
| # Primary and legacy links cannot be used if a quality was specified. | ||||
| # If we already have an aka.ms link, no need to search the blob feeds. | ||||
| if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count) | ||||
| { | ||||
| if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count) { | ||||
|     foreach ($feed in $feeds) { | ||||
|         try { | ||||
|             $SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $feed -Channel $Channel -Version $Version -JSonFile $JSonFile | ||||
| @ -1190,16 +1293,14 @@ if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count) | ||||
|      | ||||
|             if (-Not $DryRun) { | ||||
|                 Say-Verbose "Checking if the version $EffectiveVersion is already installed" | ||||
|                 if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) | ||||
|                 { | ||||
|                 if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) { | ||||
|                     Say "$assetName with version '$EffectiveVersion' is already installed." | ||||
|                     Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot | ||||
|                     return | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         catch | ||||
|         { | ||||
|         catch { | ||||
|             Say-Verbose "Failed to acquire download links from feed $feed. Exception: $_" | ||||
|         } | ||||
|     } | ||||
| @ -1216,15 +1317,13 @@ if ($DryRun) { | ||||
|  | ||||
| Measure-Action "Installation directory preparation" { Prepare-Install-Directory } | ||||
|  | ||||
| $ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) | ||||
| Say-Verbose "Zip path: $ZipPath" | ||||
|  | ||||
| $DownloadSucceeded = $false | ||||
| $DownloadedLink = $null | ||||
| $ErrorMessages = @() | ||||
|  | ||||
| foreach ($link in $DownloadLinks) | ||||
| { | ||||
| foreach ($link in $DownloadLinks) { | ||||
|     Say-Verbose "Downloading `"$($link.type)`" link $($link.downloadLink)" | ||||
|  | ||||
|     try { | ||||
| @ -1244,7 +1343,8 @@ foreach ($link in $DownloadLinks) | ||||
|      | ||||
|         if ($PSItem.Exception.Data.Contains("ErrorMessage")) { | ||||
|             $ErrorMessage = $PSItem.Exception.Data["ErrorMessage"] | ||||
|         } else { | ||||
|         } | ||||
|         else { | ||||
|             $ErrorMessage = $PSItem.Exception.Message | ||||
|         } | ||||
|  | ||||
| @ -1289,226 +1389,231 @@ if (!$isAssetInstalled) { | ||||
|     throw "`"$assetName`" with version = $($DownloadedLink.effectiveVersion) failed to install with an unknown error." | ||||
| } | ||||
|  | ||||
| if (-not $KeepZip) { | ||||
|     SafeRemoveFile -Path $ZipPath | ||||
| } | ||||
|  | ||||
| Measure-Action "Setting up shell environment" { Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot } | ||||
|  | ||||
| Say "Note that the script does not resolve dependencies during installation." | ||||
| Say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install/windows#dependencies" | ||||
| Say "Note that the script does not ensure your Windows version is supported during the installation." | ||||
| Say "To check the list of supported versions, go to https://learn.microsoft.com/dotnet/core/install/windows#supported-versions" | ||||
| Say "Installed version is $($DownloadedLink.effectiveVersion)" | ||||
| Say "Installation finished" | ||||
| # SIG # Begin signature block | ||||
| # MIInvwYJKoZIhvcNAQcCoIInsDCCJ6wCAQExDzANBglghkgBZQMEAgEFADB5Bgor | ||||
| # MIIoVQYJKoZIhvcNAQcCoIIoRjCCKEICAQExDzANBglghkgBZQMEAgEFADB5Bgor | ||||
| # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG | ||||
| # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBhfTi3SRn7+vyy | ||||
| # uCXKPjhiawegWZ493EcaOEycbgkZcKCCDXYwggX0MIID3KADAgECAhMzAAACy7d1 | ||||
| # OfsCcUI2AAAAAALLMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD | ||||
| # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAYvsOYTXPcgaBF | ||||
| # C8M6oYBHzvQKaqKPOJVvd3P0sSBCw6CCDYUwggYDMIID66ADAgECAhMzAAAEA73V | ||||
| # lV0POxitAAAAAAQDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD | ||||
| # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy | ||||
| # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p | ||||
| # bmcgUENBIDIwMTEwHhcNMjIwNTEyMjA0NTU5WhcNMjMwNTExMjA0NTU5WjB0MQsw | ||||
| # bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTEzWhcNMjUwOTExMjAxMTEzWjB0MQsw | ||||
| # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u | ||||
| # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy | ||||
| # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB | ||||
| # AQC3sN0WcdGpGXPZIb5iNfFB0xZ8rnJvYnxD6Uf2BHXglpbTEfoe+mO//oLWkRxA | ||||
| # wppditsSVOD0oglKbtnh9Wp2DARLcxbGaW4YanOWSB1LyLRpHnnQ5POlh2U5trg4 | ||||
| # 3gQjvlNZlQB3lL+zrPtbNvMA7E0Wkmo+Z6YFnsf7aek+KGzaGboAeFO4uKZjQXY5 | ||||
| # RmMzE70Bwaz7hvA05jDURdRKH0i/1yK96TDuP7JyRFLOvA3UXNWz00R9w7ppMDcN | ||||
| # lXtrmbPigv3xE9FfpfmJRtiOZQKd73K72Wujmj6/Su3+DBTpOq7NgdntW2lJfX3X | ||||
| # a6oe4F9Pk9xRhkwHsk7Ju9E/AgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE | ||||
| # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUrg/nt/gj+BBLd1jZWYhok7v5/w4w | ||||
| # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW | ||||
| # MBQGA1UEBRMNMjMwMDEyKzQ3MDUyODAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci | ||||
| # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j | ||||
| # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG | ||||
| # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu | ||||
| # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 | ||||
| # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAJL5t6pVjIRlQ8j4dAFJ | ||||
| # ZnMke3rRHeQDOPFxswM47HRvgQa2E1jea2aYiMk1WmdqWnYw1bal4IzRlSVf4czf | ||||
| # zx2vjOIOiaGllW2ByHkfKApngOzJmAQ8F15xSHPRvNMmvpC3PFLvKMf3y5SyPJxh | ||||
| # 922TTq0q5epJv1SgZDWlUlHL/Ex1nX8kzBRhHvc6D6F5la+oAO4A3o/ZC05OOgm4 | ||||
| # EJxZP9MqUi5iid2dw4Jg/HvtDpCcLj1GLIhCDaebKegajCJlMhhxnDXrGFLJfX8j | ||||
| # 7k7LUvrZDsQniJZ3D66K+3SZTLhvwK7dMGVFuUUJUfDifrlCTjKG9mxsPDllfyck | ||||
| # 4zGnRZv8Jw9RgE1zAghnU14L0vVUNOzi/4bE7wIsiRyIcCcVoXRneBA3n/frLXvd | ||||
| # jDsbb2lpGu78+s1zbO5N0bhHWq4j5WMutrspBxEhqG2PSBjC5Ypi+jhtfu3+x76N | ||||
| # mBvsyKuxx9+Hm/ALnlzKxr4KyMR3/z4IRMzA1QyppNk65Ui+jB14g+w4vole33M1 | ||||
| # pVqVckrmSebUkmjnCshCiH12IFgHZF7gRwE4YZrJ7QjxZeoZqHaKsQLRMp653beB | ||||
| # fHfeva9zJPhBSdVcCW7x9q0c2HVPLJHX9YCUU714I+qtLpDGrdbZxD9mikPqL/To | ||||
| # /1lDZ0ch8FtePhME7houuoPcMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq | ||||
| # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x | ||||
| # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv | ||||
| # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 | ||||
| # IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG | ||||
| # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG | ||||
| # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg | ||||
| # Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC | ||||
| # CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03 | ||||
| # a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr | ||||
| # rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg | ||||
| # OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy | ||||
| # 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9 | ||||
| # sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh | ||||
| # dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k | ||||
| # A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB | ||||
| # w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn | ||||
| # Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90 | ||||
| # lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w | ||||
| # ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o | ||||
| # ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD | ||||
| # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa | ||||
| # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny | ||||
| # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG | ||||
| # AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t | ||||
| # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV | ||||
| # HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3 | ||||
| # dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG | ||||
| # AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl | ||||
| # AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb | ||||
| # C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l | ||||
| # hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6 | ||||
| # I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0 | ||||
| # wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560 | ||||
| # STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam | ||||
| # ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa | ||||
| # J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah | ||||
| # XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA | ||||
| # 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt | ||||
| # Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr | ||||
| # /Xmfwb1tbWrJUnMTDXpQzTGCGZ8wghmbAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw | ||||
| # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN | ||||
| # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp | ||||
| # Z25pbmcgUENBIDIwMTECEzMAAALLt3U5+wJxQjYAAAAAAsswDQYJYIZIAWUDBAIB | ||||
| # BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO | ||||
| # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIFmuaTXYQ37AFvsEol24fdW+ | ||||
| # nRqHcc1fr+VQVdqhXc/vMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A | ||||
| # cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB | ||||
| # BQAEggEAjY5XW5Ly7TJ1OTbeIR98xU+2dmtw7L71ws+ICnQCGhj2xJDUK+5yrTfO | ||||
| # 8C98l/P4ynFi33Dl8z2YElqUCuqEXbiCzz06lIL4NuibC5DV/X80ZmICR/NYd2v1 | ||||
| # ww7IH+7dpsHAowBBindCYpVwQ3Ea3kDWgsjPAinAysFFushSOnNWFvrF6vi2smrs | ||||
| # smbrAAhEhSfLd1Pxxdw73hQ0YjM/D3F3opaybMQ0blpHhOaqtbiyYzvk0doIzBEc | ||||
| # trSH4NDIc3yLNj5VbjSczpexE+hyQNY4xCtwco4bVtXhONUihv08AIKR8+sIaI7A | ||||
| # mM/SWrrwGYSSSxydKqDei7biKG4jDqGCFykwghclBgorBgEEAYI3AwMBMYIXFTCC | ||||
| # FxEGCSqGSIb3DQEHAqCCFwIwghb+AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFZBgsq | ||||
| # hkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl | ||||
| # AwQCAQUABCB6Hzt2gUb/WZK8fvVnOocriE4rYr6mscZi3gZnBCpiigIGZBr2iMZU | ||||
| # GBMyMDIzMDMzMTE1MjEwNi41MTZaMASAAgH0oIHYpIHVMIHSMQswCQYDVQQGEwJV | ||||
| # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE | ||||
| # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl | ||||
| # bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNO | ||||
| # OjA4NDItNEJFNi1DMjlBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBT | ||||
| # ZXJ2aWNloIIReDCCBycwggUPoAMCAQICEzMAAAGybkADf26plJIAAQAAAbIwDQYJ | ||||
| # KoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x | ||||
| # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv | ||||
| # bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjIw | ||||
| # OTIwMjAyMjAxWhcNMjMxMjE0MjAyMjAxWjCB0jELMAkGA1UEBhMCVVMxEzARBgNV | ||||
| # AQCfdGddwIOnbRYUyg03O3iz19XXZPmuhEmW/5uyEN+8mgxl+HJGeLGBR8YButGV | ||||
| # LVK38RxcVcPYyFGQXcKcxgih4w4y4zJi3GvawLYHlsNExQwz+v0jgY/aejBS2EJY | ||||
| # oUhLVE+UzRihV8ooxoftsmKLb2xb7BoFS6UAo3Zz4afnOdqI7FGoi7g4vx/0MIdi | ||||
| # kwTn5N56TdIv3mwfkZCFmrsKpN0zR8HD8WYsvH3xKkG7u/xdqmhPPqMmnI2jOFw/ | ||||
| # /n2aL8W7i1Pasja8PnRXH/QaVH0M1nanL+LI9TsMb/enWfXOW65Gne5cqMN9Uofv | ||||
| # ENtdwwEmJ3bZrcI9u4LZAkujAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE | ||||
| # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU6m4qAkpz4641iK2irF8eWsSBcBkw | ||||
| # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh | ||||
| # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMjkyNjAfBgNVHSMEGDAW | ||||
| # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v | ||||
| # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw | ||||
| # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov | ||||
| # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx | ||||
| # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB | ||||
| # AFFo/6E4LX51IqFuoKvUsi80QytGI5ASQ9zsPpBa0z78hutiJd6w154JkcIx/f7r | ||||
| # EBK4NhD4DIFNfRiVdI7EacEs7OAS6QHF7Nt+eFRNOTtgHb9PExRy4EI/jnMwzQJV | ||||
| # NokTxu2WgHr/fBsWs6G9AcIgvHjWNN3qRSrhsgEdqHc0bRDUf8UILAdEZOMBvKLC | ||||
| # rmf+kJPEvPldgK7hFO/L9kmcVe67BnKejDKO73Sa56AJOhM7CkeATrJFxO9GLXos | ||||
| # oKvrwBvynxAg18W+pagTAkJefzneuWSmniTurPCUE2JnvW7DalvONDOtG01sIVAB | ||||
| # +ahO2wcUPa2Zm9AiDVBWTMz9XUoKMcvngi2oqbsDLhbK+pYrRUgRpNt0y1sxZsXO | ||||
| # raGRF8lM2cWvtEkV5UL+TQM1ppv5unDHkW8JS+QnfPbB8dZVRyRmMQ4aY/tx5x5+ | ||||
| # sX6semJ//FbiclSMxSI+zINu1jYerdUwuCi+P6p7SmQmClhDM+6Q+btE2FtpsU0W | ||||
| # +r6RdYFf/P+nK6j2otl9Nvr3tWLu+WXmz8MGM+18ynJ+lYbSmFWcAj7SYziAfT0s | ||||
| # IwlQRFkyC71tsIZUhBHtxPliGUu362lIO0Lpe0DOrg8lspnEWOkHnCT5JEnWCbzu | ||||
| # iVt8RX1IV07uIveNZuOBWLVCzWJjEGa+HhaEtavjy6i7MIIHejCCBWKgAwIBAgIK | ||||
| # YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV | ||||
| # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv | ||||
| # c29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3Bl | ||||
| # cmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjowODQyLTRC | ||||
| # RTYtQzI5QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCC | ||||
| # AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMqiZTIde/lQ4rC+Bml5f/Wu | ||||
| # q/xKTxrfbG23HofmQ+qZAN4GyO73PF3y9OAfpt7Qf2jcldWOGUB+HzBuwllYyP3f | ||||
| # x4MY8zvuAuB37FvoytnNC2DKnVrVlHOVcGUL9CnmhDNMA2/nskjIf2IoiG9J0qLY | ||||
| # r8duvHdQJ9Li2Pq9guySb9mvUL60ogslCO9gkh6FiEDwMrwUr8Wja6jFpUTny8tg | ||||
| # 0N0cnCN2w4fKkp5qZcbUYFYicLSb/6A7pHCtX6xnjqwhmJoib3vkKJyVxbuFLRhV | ||||
| # XxH95b0LHeNhifn3jvo2j+/4QV10jEpXVW+iC9BsTtR69xvTjU51ZgP7BR4YDEWq | ||||
| # 7JsylSOv5B5THTDXRf184URzFhTyb8OZQKY7mqMh7c8J8w1sEM4XDUF2UZNy829N | ||||
| # VCzG2tfdEXZaHxF8RmxpQYBxyhZwY1rotuIS+gfN2eq+hkAT3ipGn8/KmDwDtzAb | ||||
| # nfuXjApgeZqwgcYJ8pDJ+y/xU6ouzJz1Bve5TTihkiA7wQsQe6R60Zk9dPdNzw0M | ||||
| # K5niRzuQZAt4GI96FhjhlUWcUZOCkv/JXM/OGu/rgSplYwdmPLzzfDtXyuy/GCU5 | ||||
| # I4l08g6iifXypMgoYkkceOAAz4vx1x0BOnZWfI3fSwqNUvoN7ncTT+MB4Vpvf1QB | ||||
| # ppjBAQUuvui6eCG0MCVNAgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUmfIngFzZEZlP | ||||
| # kjDOVluBSDDaanEwHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYD | ||||
| # VR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j | ||||
| # cmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwG | ||||
| # CCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQu | ||||
| # Y29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIw | ||||
| # MjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD | ||||
| # CDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBANxHtu3FzIabaDbW | ||||
| # qswdKBlAhKXRCN+5CSMiv2TYa4i2QuWIm+99piwAhDhADfbqor1zyLi95Y6GQnvI | ||||
| # WUgdeC7oL1ZtZye92zYK+EIfwYZmhS+CH4infAzUvscHZF3wlrJUfPUIDGVP0lCY | ||||
| # Vse9mguvG0dqkY4ayQPEHOvJubgZZaOdg/N8dInd6fGeOc+0DoGzB+LieObJ2Q0A | ||||
| # tEt3XN3iX8Cp6+dZTX8xwE/LvhRwPpb/+nKshO7TVuvenwdTwqB/LT6CNPaElwFe | ||||
| # KxKrqRTPMbHeg+i+KnBLfwmhEXsMg2s1QX7JIxfvT96md0eiMjiMEO22LbOzmLMN | ||||
| # d3LINowAnRBAJtX+3/e390B9sMGMHp+a1V+hgs62AopBl0p/00li30DN5wEQ5If3 | ||||
| # 5Zk7b/T6pEx6rJUDYCti7zCbikjKTanBnOc99zGMlej5X+fC/k5ExUCrOs3/VzGR | ||||
| # CZt5LvVQSdWqq/QMzTEmim4sbzASK9imEkjNtZZyvC1CsUcD1voFktld4mKMjE+u | ||||
| # DEV3IddD+DrRk94nVzNPSuZXewfVOnXHSeqG7xM3V7fl2aL4v1OhL2+JwO1Tx3B0 | ||||
| # irO1O9qbNdJk355bntd1RSVKgM22KFBHnoL7Js7pRhBiaKmVTQGoOb+j1Qa7q+ci | ||||
| # xGo48Vh9k35BDsJS/DLoXFSPDl4mMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJ | ||||
| # mQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT | ||||
| # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m | ||||
| # dCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNh | ||||
| # dGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1 | ||||
| # WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH | ||||
| # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD | ||||
| # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEB | ||||
| # BQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjK | ||||
| # NVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhg | ||||
| # fWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJp | ||||
| # rx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/d | ||||
| # vI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka9 | ||||
| # 7aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKR | ||||
| # Hh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9itu | ||||
| # qBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyO | ||||
| # ArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItb | ||||
| # oKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6 | ||||
| # bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6t | ||||
| # AgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQW | ||||
| # BBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacb | ||||
| # UzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYz | ||||
| # aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnku | ||||
| # aHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIA | ||||
| # QwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2 | ||||
| # VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwu | ||||
| # bWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEw | ||||
| # LTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93 | ||||
| # d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYt | ||||
| # MjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/q | ||||
| # XBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6 | ||||
| # U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVt | ||||
| # I1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis | ||||
| # 9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTp | ||||
| # kbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0 | ||||
| # sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138e | ||||
| # W0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJ | ||||
| # sWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7 | ||||
| # Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0 | ||||
| # dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQ | ||||
| # tB1VM1izoXBm8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB0jELMAkGA1UEBhMCVVMx | ||||
| # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT | ||||
| # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxh | ||||
| # bmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjow | ||||
| # ODQyLTRCRTYtQzI5QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy | ||||
| # dmljZaIjCgEBMAcGBSsOAwIaAxUAjhJ+EeySRfn2KCNsjn9cF9AUSTqggYMwgYCk | ||||
| # fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH | ||||
| # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD | ||||
| # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF | ||||
| # AOfRUdUwIhgPMjAyMzAzMzEyMDM0MjlaGA8yMDIzMDQwMTIwMzQyOVowdDA6Bgor | ||||
| # BgEEAYRZCgQBMSwwKjAKAgUA59FR1QIBADAHAgEAAgIKJDAHAgEAAgIRLzAKAgUA | ||||
| # 59KjVQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID | ||||
| # B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAJlOESCa/uRR1x6GunE8 | ||||
| # K/WgHWTpSE31EITDOfTMvDcF4ptngCS5aOc4gfzmhNNehWfP6EOrgoSQzJYZ4YCh | ||||
| # fYbHNMk56f18sq8t7y2hgR7KixcEo/4HVzeSdaOclHNc4Gn7kCGpMvpT3Xz9Lzc7 | ||||
| # UKWDZ0zkNKnbS8TZLNueVQwfMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMx | ||||
| # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT | ||||
| # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt | ||||
| # U3RhbXAgUENBIDIwMTACEzMAAAGybkADf26plJIAAQAAAbIwDQYJYIZIAWUDBAIB | ||||
| # BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx | ||||
| # IgQgXhJRuHCXk3arJvifIY3DBe9Ce9EmlP1y6U4XkgL31DkwgfoGCyqGSIb3DQEJ | ||||
| # EAIvMYHqMIHnMIHkMIG9BCBTeM485+E+t4PEVieUoFKX7PVyLo/nzu+htJPCG04+ | ||||
| # NTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw | ||||
| # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x | ||||
| # JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABsm5A | ||||
| # A39uqZSSAAEAAAGyMCIEIGGWlnNnYHrB5HguWG0/nJd/WvSrCogze+QCpenu3IM5 | ||||
| # MA0GCSqGSIb3DQEBCwUABIICADVOLTuNxeEnBOfZpb7Nv4uf91W/Ho5i99zenDSJ | ||||
| # x5QHVs+bKXmgc3a7/SSsliAT3zygHc7cH4zARbCZePLTivByKmeG08Ka35eyR+FK | ||||
| # awSNrI/X+eVIC6nw/egCwviBC1NAG8jHGkuScbHeiiGajvS6lp3ORML7UexMuE4w | ||||
| # 9SEumoghljCLZMwCSvw+3WxhQoBEZroR8u+PID2RdD0vi85FjKPWcZZijVLqHeFi | ||||
| # TnuFqwRCLTV0MV+dDCbjwXneIqV+AVlnqb9iDMr3ZhISlRcy9XJNpY5vQBj/wqUW | ||||
| # vefrmpdz0LNkdtXYThPkyl3mha2KsoQi5SA9zSjlAjFgY3ppmXvi3Frbfqk+iL+f | ||||
| # l/Qc4+B71jG4t28lTWKteJiHqo+6AUXK2rlAl0d74yvhO6N8lMMtXhdJc8JABYn1 | ||||
| # v2/KKZn5RvPFF8QP7Ac1saIe1+gUFNcsYOLaMm/xl8E6kefWwZnm5Rhm606g1AC/ | ||||
| # N5Wo08aAs0ymTPH91dEbmOURXLbA3vCyG7kbfgnhCs/j7oQHWaFDzEYuXDIA4ICT | ||||
| # dxPUTltbq3OWdp0PAS8JSEKPQFaOoQEnPa4adrXWxMvOmel8IGqJiQ+BPOaLQG64 | ||||
| # Qu2tMkH/5szb1fsEnCe8SJmy5ESF+kmpnLBtJ17Y9o+9nJHF5ddFmvzy+LUaIqDN | ||||
| # cOfH | ||||
| # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm | ||||
| # aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw | ||||
| # OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE | ||||
| # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD | ||||
| # VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG | ||||
| # 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la | ||||
| # UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc | ||||
| # 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D | ||||
| # dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+ | ||||
| # lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk | ||||
| # kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6 | ||||
| # A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd | ||||
| # X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL | ||||
| # 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd | ||||
| # sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3 | ||||
| # T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS | ||||
| # 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI | ||||
| # bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL | ||||
| # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD | ||||
| # uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv | ||||
| # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf | ||||
| # MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3 | ||||
| # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf | ||||
| # MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF | ||||
| # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h | ||||
| # cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA | ||||
| # YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn | ||||
| # 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7 | ||||
| # v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b | ||||
| # pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/ | ||||
| # KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy | ||||
| # CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp | ||||
| # mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi | ||||
| # hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb | ||||
| # BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS | ||||
| # oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL | ||||
| # gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX | ||||
| # cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGiYwghoiAgEBMIGVMH4x | ||||
| # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt | ||||
| # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p | ||||
| # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAQDvdWVXQ87GK0AAAAA | ||||
| # BAMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw | ||||
| # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEINfL | ||||
| # pWARcSI2v5ypXRaeSwvLuu7hP0XgYbvQaaOIuiKWMEIGCisGAQQBgjcCAQwxNDAy | ||||
| # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j | ||||
| # b20wDQYJKoZIhvcNAQEBBQAEggEADr/V9EQlvMcNLQduKLU/gz5PRRSoE8txgN52 | ||||
| # OuBIJS4+jPp3y82+4/09umeMdQ7+pwRQiuPAvmyZG0zGRoTz3PzpouceetqHnIHn | ||||
| # ij0lT0y4hUQ0DqmZT1AA24GJmoPnM9ab2EcRTfUp7p0t1Fq5ITOEdFvvh6EPkyc/ | ||||
| # spxmI5bTlE0+anj9PmnLyFYnFtrGlmSywrDpIsjqnE8+ODtTabllcpAhLrZxInqu | ||||
| # bHXIrT3cGjATJsRAg+38R5tYP7i6aI5sS9QGmeXhuvrJeFrOIqC2gxbV7iCJIrkE | ||||
| # 5OGFIBZQkxLRZxt3VYdGAjBLj+pCY7OEjXpXvkdg47Xo8aQCKqGCF7AwghesBgor | ||||
| # BgEEAYI3AwMBMYIXnDCCF5gGCSqGSIb3DQEHAqCCF4kwgheFAgEDMQ8wDQYJYIZI | ||||
| # AWUDBAIBBQAwggFaBgsqhkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGE | ||||
| # WQoDATAxMA0GCWCGSAFlAwQCAQUABCBVg4bCpxEOAWWIN2/4kB21BawVRDfKQ35G | ||||
| # xRhhaLpK/AIGZ2KxlnK4GBMyMDI0MTIyMzE2NDIwNy43NDJaMASAAgH0oIHZpIHW | ||||
| # MIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH | ||||
| # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL | ||||
| # EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsT | ||||
| # Hm5TaGllbGQgVFNTIEVTTjo2QjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9z | ||||
| # b2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEf4wggcoMIIFEKADAgECAhMzAAAB9oMv | ||||
| # JmpUXSLBAAEAAAH2MA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYD | ||||
| # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy | ||||
| # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w | ||||
| # IFBDQSAyMDEwMB4XDTI0MDcyNTE4MzEwNFoXDTI1MTAyMjE4MzEwNFowgdMxCzAJ | ||||
| # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k | ||||
| # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jv | ||||
| # c29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVs | ||||
| # ZCBUU1MgRVNOOjZCMDUtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGlt | ||||
| # ZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA | ||||
| # 0UJeLMR/N9WPBZhuKVFF+eWJZ68Wujdj4X6JR05cxO5CepNXo17rVazwWLkm5Aja | ||||
| # Vh19ZVjDChHzimxsoaXxNu8IDggKwpXvpAAItv4Ux50e9S2uVwfKv57p9JKG+Q7V | ||||
| # ONShujl1NCMkcgSrPdmd/8zcsmhzcNobLomrCAIORZ8IwhYy4siVQlf1NKhlyAzm | ||||
| # kWJD0N+60IiogFBzg3yISsvroOx0x1xSi2PiRIQlTXE74MggZDIDKqH/hb9FT2kK | ||||
| # /nV/aXjuo9LMrrRmn44oYYADe/rO95F+SG3uuuhf+H4IriXr0h9ptA6SwHJPS2Vm | ||||
| # bNWCjQWq5G4YkrcqbPMax7vNXUwu7T65E8fFPd1IuE9RsG4TMAV7XkXBopmPNfvL | ||||
| # 0hjxg44kpQn384V46o+zdQqy5K9dDlWm/J6vZtp5yA1PyD3w+HbGubS0niEQ1L6w | ||||
| # GOrPfzIm0FdOn+xFo48ERl+Fxw/3OvXM5CY1EqnzEznPjzJc7OJwhJVR3VQDHjBc | ||||
| # EFTOvS9E0diNu1eocw+ZCkz4Pu/oQv+gqU+bfxL8e7PFktfRDlM6FyOzjP4zuI25 | ||||
| # gD8tO9zJg6g6fRpaZc439mAbkl3zCVzTLDgchv6SxQajJtvvoQaZxQf0tRiPcbr2 | ||||
| # HWfMoqqd9uiQ0hTUEhG44FBSTeUPZeEenRCWadCW4G8CAwEAAaOCAUkwggFFMB0G | ||||
| # A1UdDgQWBBRIwZsJuOcJfScPWcXZuBA4B89K8jAfBgNVHSMEGDAWgBSfpxVdAF5i | ||||
| # XYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jv | ||||
| # c29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENB | ||||
| # JTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRw | ||||
| # Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRp | ||||
| # bWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1Ud | ||||
| # JQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsF | ||||
| # AAOCAgEA13kBirH1cHu1WYR1ysj125omGtQ0PaQkEzwGb70xtqSoI+svQihsgdTY | ||||
| # xaPfp2IVFdgjaMaBi81wB8/nu866FfFKKdhdp3wnMZ91PpP4Ooe7Ncf6qICkgSuw | ||||
| # gdIdQvqE0h8VQ5QW5sDV4Q0Jnj4f7KHYx4NiM8C4jTw8SQtsuxWiTH2Hikf3QYB7 | ||||
| # 1a7dB9zgHOkW0hgUEeWO9mh2wWqYS/Q48ASjOqYw/ha54oVOff22WaoH+/Hxd9NT | ||||
| # EU/4vlvsRIMWT0jsnNI71jVArT4Q9Bt6VShWzyqraE6SKUoZrEwBpVsI0LMg2X3h | ||||
| # OLblC1vxM3+wMyOh97aFOs7sFnuemtI2Mfj8qg16BZTJxXlpPurWrG+OBj4BoTDk | ||||
| # C9AxXYB3yEtuwMs7pRWLyxIxw/wV9THKUGm+x+VE0POLwkrSMgjulSXkpfELHWWi | ||||
| # CVslJbFIIB/4Alv+jQJSKAJuo9CErbm2qeDk/zjJYlYaVGMyKuYZ+uSRVKB2qkEP | ||||
| # cEzG1dO9zIa1Mp32J+zzW3P7suJfjw62s3hDOLk+6lMQOR04x+2o17G3LceLkkxJ | ||||
| # m41ErdiTjAmdClen9yl6HgMpGS4okjFCJX+CpOFX7gBA3PVxQWubisAQbL5HgTFB | ||||
| # tQNEzcCdh1GYw/6nzzNNt+0GQnnobBddfOAiqkzvItqXjvGyK1QwggdxMIIFWaAD | ||||
| # AgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD | ||||
| # VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe | ||||
| # MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3Nv | ||||
| # ZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIy | ||||
| # MjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo | ||||
| # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y | ||||
| # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw | ||||
| # MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5 | ||||
| # vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64 | ||||
| # NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhu | ||||
| # je3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl | ||||
| # 3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPg | ||||
| # yY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I | ||||
| # 5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2 | ||||
| # ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/ | ||||
| # TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy | ||||
| # 16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y | ||||
| # 1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6H | ||||
| # XtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMB | ||||
| # AAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQW | ||||
| # BBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30B | ||||
| # ATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz | ||||
| # L0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYB | ||||
| # BAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMB | ||||
| # Af8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBL | ||||
| # oEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv | ||||
| # TWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggr | ||||
| # BgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNS | ||||
| # b29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1Vffwq | ||||
| # reEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27 | ||||
| # DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pv | ||||
| # vinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9Ak | ||||
| # vUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWK | ||||
| # NsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2 | ||||
| # kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+ | ||||
| # c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep | ||||
| # 8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+Dvk | ||||
| # txW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1Zyvg | ||||
| # DbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/ | ||||
| # 2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDWTCCAkECAQEwggEBoYHZpIHW | ||||
| # MIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH | ||||
| # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL | ||||
| # EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsT | ||||
| # Hm5TaGllbGQgVFNTIEVTTjo2QjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9z | ||||
| # b2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAFU9eSpdxs0a0 | ||||
| # 6JFIuGFHIj/I+36ggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz | ||||
| # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv | ||||
| # cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx | ||||
| # MDANBgkqhkiG9w0BAQsFAAIFAOsTx1MwIhgPMjAyNDEyMjMxMTI2MTFaGA8yMDI0 | ||||
| # MTIyNDExMjYxMVowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA6xPHUwIBADAKAgEA | ||||
| # AgIEpgIB/zAHAgEAAgIULjAKAgUA6xUY0wIBADA2BgorBgEEAYRZCgQCMSgwJjAM | ||||
| # BgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEB | ||||
| # CwUAA4IBAQDkPou5w9O3fL9lm7NIu3mAwCMpezmpCbx9mCUfLb4cXznb4psGEspn | ||||
| # XaDg3PGX1yGC3GR5peByH/hiarlvYv5SZbofvP+iiYFxeLGi+usbC8FQnuWrgyqh | ||||
| # 7RV01Fm2Is7PGF3NXQaXbGkSQUZzrekeRr4zdV2nIKshANlifSPb/wAd6BLcKtYS | ||||
| # 3Kr9xUXgZeHxo6tD88GDxJ5FDsG1RxczsdCO5mVqFZUrQqz6Cs49xt7cq2XlEwMX | ||||
| # 53L40YCUrvYYiTgqvxtOzg58ksUkP1YDfeP9Rel7pGXGyzJF0Fo+FAXiY098HPcW | ||||
| # eRCGaVV55Keop55er/x0vYOQK3WYmR9ZMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UE | ||||
| # BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc | ||||
| # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0 | ||||
| # IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAH2gy8malRdIsEAAQAAAfYwDQYJYIZI | ||||
| # AWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG | ||||
| # 9w0BCQQxIgQgrAY6roZynzJwSUQzsAfof3O6FxHR94SlM3Hdh+QLWTowgfoGCyqG | ||||
| # SIb3DQEJEAIvMYHqMIHnMIHkMIG9BCArYUzxlF6m5USLS4f8NXL/8aoNEVdsCZRm | ||||
| # F+LlQjG2ojCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n | ||||
| # dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y | ||||
| # YXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMz | ||||
| # AAAB9oMvJmpUXSLBAAEAAAH2MCIEIOEmAHxbUTtc2fET28qfaLGRzaIhD4dw4/ak | ||||
| # m6mLo6PCMA0GCSqGSIb3DQEBCwUABIICAH4zqNf+CV7yNKXAQwNuEZwzCHs4eJC4 | ||||
| # mNKMRp9e2W++JJaxtY3kLEBoGDKfz+8RYsjcLtNOg83Hd2gEmAmgvWfs/mZlhi8j | ||||
| # tM5Yj9606ukzuF2797CDwZiXz5JTIs1wIm5+rWuAny0azioafaOZtcaxPqnANbUf | ||||
| # UHnAYoZ0W6AkSnz99XrqRueh8b3Z7h2A5saVS1/MV1fjfImxH673GlexKRYORTFP | ||||
| # A9XH8vCvVTIZobKSWa6y/KG4U5dkWrzJuLbT9Kr3x6yk0bO6epG09yy86HmlnmwQ | ||||
| # bJwBedz4ZpKkvtIJ2U2PYvLti5bztm5WL/hWhDmtXBhoqKy1d/i4LDz7F4vXy9// | ||||
| # 5Wy8zHMLw4ZFwfywP8/P5pZP7nlvIrordtefS2z3Ipea0thJxwyFJSU8c7OGvPof | ||||
| # uHhYKMn+Lg1tj5QcIvT7KG0JGp/XWe/CEB9ruOkYZh9VKBlEU2CkDsWeTXFy5heV | ||||
| # eMPMxRC/GBHPypBHHSrd8BtUsKgehcetdsfQrOI3VLV9gx8SGr8ehSU2Rg0U2UtK | ||||
| # a4S5THXp0PksrjJLmykIsvBmMgl3uK4KJbu6zh3w5ACSS/OZXzrsowysGjn2QBwb | ||||
| # hoIjCDhmNLLq2gupcAhPCgqUX6Ixmg8H0SlqoRp0mZTss7ZS+ErxTQoFBbLkoX5F | ||||
| # 9HjkIOcM6/0F | ||||
| # SIG # End signature block | ||||
							
								
								
									
										267
									
								
								externals/install-dotnet.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										267
									
								
								externals/install-dotnet.sh
									
									
									
									
										vendored
									
									
								
							| @ -298,11 +298,20 @@ get_machine_architecture() { | ||||
|     if command -v uname > /dev/null; then | ||||
|         CPUName=$(uname -m) | ||||
|         case $CPUName in | ||||
|         armv1*|armv2*|armv3*|armv4*|armv5*|armv6*) | ||||
|             echo "armv6-or-below" | ||||
|             return 0 | ||||
|             ;; | ||||
|         armv*l) | ||||
|             echo "arm" | ||||
|             return 0 | ||||
|             ;; | ||||
|         aarch64|arm64) | ||||
|             if [ "$(getconf LONG_BIT)" -lt 64 ]; then | ||||
|                 # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS) | ||||
|                 echo "arm" | ||||
|                 return 0 | ||||
|             fi | ||||
|             echo "arm64" | ||||
|             return 0 | ||||
|             ;; | ||||
| @ -310,6 +319,22 @@ get_machine_architecture() { | ||||
|             echo "s390x" | ||||
|             return 0 | ||||
|             ;; | ||||
|         ppc64le) | ||||
|             echo "ppc64le" | ||||
|             return 0 | ||||
|             ;; | ||||
|         loongarch64) | ||||
|             echo "loongarch64" | ||||
|             return 0 | ||||
|             ;; | ||||
|         riscv64) | ||||
|             echo "riscv64" | ||||
|             return 0 | ||||
|             ;; | ||||
|         powerpc|ppc) | ||||
|             echo "ppc" | ||||
|             return 0 | ||||
|             ;; | ||||
|         esac | ||||
|     fi | ||||
|  | ||||
| @ -326,7 +351,13 @@ get_normalized_architecture_from_architecture() { | ||||
|     local architecture="$(to_lowercase "$1")" | ||||
|  | ||||
|     if [[ $architecture == \<auto\> ]]; then | ||||
|         echo "$(get_machine_architecture)" | ||||
|         machine_architecture="$(get_machine_architecture)" | ||||
|         if [[ "$machine_architecture" == "armv6-or-below" ]]; then | ||||
|             say_err "Architecture \`$machine_architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues" | ||||
|             return 1 | ||||
|         fi | ||||
|  | ||||
|         echo $machine_architecture | ||||
|         return 0 | ||||
|     fi | ||||
|  | ||||
| @ -347,6 +378,14 @@ get_normalized_architecture_from_architecture() { | ||||
|             echo "s390x" | ||||
|             return 0 | ||||
|             ;; | ||||
|         ppc64le) | ||||
|             echo "ppc64le" | ||||
|             return 0 | ||||
|             ;; | ||||
|         loongarch64) | ||||
|             echo "loongarch64" | ||||
|             return 0 | ||||
|             ;; | ||||
|     esac | ||||
|  | ||||
|     say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues" | ||||
| @ -384,11 +423,17 @@ get_normalized_architecture_for_specific_sdk_version() { | ||||
| # args: | ||||
| # version or channel - $1 | ||||
| is_arm64_supported() { | ||||
|     #any channel or version that starts with the specified versions | ||||
|     case "$1" in | ||||
|         ( "1"* | "2"* | "3"*  | "4"* | "5"*)  | ||||
|     # Extract the major version by splitting on the dot | ||||
|     major_version="${1%%.*}" | ||||
|  | ||||
|     # Check if the major version is a valid number and less than 6 | ||||
|     case "$major_version" in | ||||
|         [0-9]*)   | ||||
|             if [ "$major_version" -lt 6 ]; then | ||||
|                 echo false | ||||
|                 return 0 | ||||
|             fi | ||||
|             ;; | ||||
|     esac | ||||
|  | ||||
|     echo true | ||||
| @ -407,8 +452,13 @@ get_normalized_os() { | ||||
|                 echo "$osname" | ||||
|                 return 0 | ||||
|                 ;; | ||||
|             macos) | ||||
|                 osname='osx' | ||||
|                 echo "$osname" | ||||
|                 return 0 | ||||
|                 ;; | ||||
|             *) | ||||
|                 say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." | ||||
|                 say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, macos, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." | ||||
|                 return 1 | ||||
|                 ;; | ||||
|         esac | ||||
| @ -538,6 +588,40 @@ is_dotnet_package_installed() { | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # args: | ||||
| # downloaded file - $1 | ||||
| # remote_file_size - $2 | ||||
| validate_remote_local_file_sizes()  | ||||
| { | ||||
|     eval $invocation | ||||
|  | ||||
|     local downloaded_file="$1" | ||||
|     local remote_file_size="$2" | ||||
|     local file_size='' | ||||
|  | ||||
|     if [[ "$OSTYPE" == "linux-gnu"* ]]; then | ||||
|         file_size="$(stat -c '%s' "$downloaded_file")" | ||||
|     elif [[ "$OSTYPE" == "darwin"* ]]; then | ||||
|         # hardcode in order to avoid conflicts with GNU stat | ||||
|         file_size="$(/usr/bin/stat -f '%z' "$downloaded_file")" | ||||
|     fi   | ||||
|      | ||||
|     if [ -n "$file_size" ]; then | ||||
|         say "Downloaded file size is $file_size bytes." | ||||
|  | ||||
|         if [ -n "$remote_file_size" ] && [ -n "$file_size" ]; then | ||||
|             if [ "$remote_file_size" -ne "$file_size" ]; then | ||||
|                 say "The remote and local file sizes are not equal. The remote file size is $remote_file_size bytes and the local size is $file_size bytes. The local package may be corrupted." | ||||
|             else | ||||
|                 say "The remote and local file sizes are equal." | ||||
|             fi | ||||
|         fi | ||||
|          | ||||
|     else | ||||
|         say "Either downloaded or local package size can not be measured. One of them may be corrupted."       | ||||
|     fi  | ||||
| } | ||||
|  | ||||
| # args: | ||||
| # azure_feed - $1 | ||||
| # channel - $2 | ||||
| @ -872,6 +956,37 @@ get_absolute_path() { | ||||
|     return 0 | ||||
| } | ||||
|  | ||||
| # args: | ||||
| # override - $1 (boolean, true or false) | ||||
| get_cp_options() { | ||||
|     eval $invocation | ||||
|  | ||||
|     local override="$1" | ||||
|     local override_switch="" | ||||
|  | ||||
|     if [ "$override" = false ]; then | ||||
|         override_switch="-n" | ||||
|  | ||||
|         # create temporary files to check if 'cp -u' is supported | ||||
|         tmp_dir="$(mktemp -d)" | ||||
|         tmp_file="$tmp_dir/testfile" | ||||
|         tmp_file2="$tmp_dir/testfile2" | ||||
|  | ||||
|         touch "$tmp_file" | ||||
|  | ||||
|         # use -u instead of -n if it's available | ||||
|         if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then | ||||
|             override_switch="-u" | ||||
|         fi | ||||
|  | ||||
|         # clean up | ||||
|         rm -f "$tmp_file" "$tmp_file2" | ||||
|         rm -rf "$tmp_dir" | ||||
|     fi | ||||
|  | ||||
|     echo "$override_switch" | ||||
| } | ||||
|  | ||||
| # args: | ||||
| # input_files - stdin | ||||
| # root_path - $1 | ||||
| @ -883,15 +998,7 @@ copy_files_or_dirs_from_list() { | ||||
|     local root_path="$(remove_trailing_slash "$1")" | ||||
|     local out_path="$(remove_trailing_slash "$2")" | ||||
|     local override="$3" | ||||
|     local osname="$(get_current_os_name)" | ||||
|     local override_switch=$( | ||||
|         if [ "$override" = false ]; then | ||||
|             if [ "$osname" = "linux-musl" ]; then | ||||
|                 printf -- "-u"; | ||||
|             else | ||||
|                 printf -- "-n"; | ||||
|             fi | ||||
|         fi) | ||||
|     local override_switch="$(get_cp_options "$override")" | ||||
|  | ||||
|     cat | uniq | while read -r file_path; do | ||||
|         local path="$(remove_beginning_slash "${file_path#$root_path}")" | ||||
| @ -906,14 +1013,39 @@ copy_files_or_dirs_from_list() { | ||||
|     done | ||||
| } | ||||
|  | ||||
| # args: | ||||
| # zip_uri - $1 | ||||
| get_remote_file_size() { | ||||
|     local zip_uri="$1" | ||||
|  | ||||
|     if machine_has "curl"; then | ||||
|         file_size=$(curl -sI  "$zip_uri" | grep -i content-length | awk '{ num = $2 + 0; print num }') | ||||
|     elif machine_has "wget"; then | ||||
|         file_size=$(wget --spider --server-response -O /dev/null "$zip_uri" 2>&1 | grep -i 'Content-Length:' | awk '{ num = $2 + 0; print num }') | ||||
|     else | ||||
|         say "Neither curl nor wget is available on this system." | ||||
|         return | ||||
|     fi | ||||
|  | ||||
|     if [ -n "$file_size" ]; then | ||||
|         say "Remote file $zip_uri size is $file_size bytes." | ||||
|         echo "$file_size" | ||||
|     else | ||||
|         say_verbose "Content-Length header was not extracted for $zip_uri." | ||||
|         echo "" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # args: | ||||
| # zip_path - $1 | ||||
| # out_path - $2 | ||||
| # remote_file_size - $3 | ||||
| extract_dotnet_package() { | ||||
|     eval $invocation | ||||
|  | ||||
|     local zip_path="$1" | ||||
|     local out_path="$2" | ||||
|     local remote_file_size="$3" | ||||
|  | ||||
|     local temp_out_path="$(mktemp -d "$temporary_file_template")" | ||||
|  | ||||
| @ -924,8 +1056,12 @@ extract_dotnet_package() { | ||||
|     find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false | ||||
|     find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files" | ||||
|      | ||||
|     validate_remote_local_file_sizes "$zip_path" "$remote_file_size" | ||||
|      | ||||
|     rm -rf "$temp_out_path" | ||||
|     rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed" | ||||
|     if [ -z ${keep_zip+x} ]; then | ||||
|         rm -f "$zip_path" && say_verbose "Temporary archive file $zip_path was removed" | ||||
|     fi | ||||
|  | ||||
|     if [ "$failed" = true ]; then | ||||
|         say_err "Extraction failed" | ||||
| @ -1136,6 +1272,61 @@ downloadwget() { | ||||
|     return 0 | ||||
| } | ||||
|  | ||||
| extract_stem() { | ||||
|     local url="$1" | ||||
|     # extract the protocol | ||||
|     proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')" | ||||
|     # remove the protocol | ||||
|     url="${1/$proto/}" | ||||
|     # extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path | ||||
|     full_path="$(echo $url | grep / | cut -d/ -f2-)" | ||||
|     path="$(echo $full_path | cut -d/ -f2-)" | ||||
|     echo $path | ||||
| } | ||||
|  | ||||
| check_url_exists() { | ||||
|     eval $invocation | ||||
|     local url="$1" | ||||
|  | ||||
|     local code="" | ||||
|     if machine_has "curl" | ||||
|     then | ||||
|         code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url"); | ||||
|     elif machine_has "wget" | ||||
|     then | ||||
|         # get the http response, grab the status code | ||||
|         server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1) | ||||
|         code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}') | ||||
|     fi | ||||
|     if [ $code = "200" ]; then | ||||
|         return 0 | ||||
|     else | ||||
|         return 1 | ||||
|     fi | ||||
| } | ||||
|  | ||||
| sanitize_redirect_url() { | ||||
|     eval $invocation | ||||
|  | ||||
|     local url_stem | ||||
|     url_stem=$(extract_stem "$1") | ||||
|     say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}" | ||||
|  | ||||
|     for feed in "${feeds[@]}" | ||||
|     do | ||||
|         local trial_url="$feed/$url_stem" | ||||
|         say_verbose "Checking ${yellow:-}$trial_url${normal:-}" | ||||
|         if check_url_exists "$trial_url"; then | ||||
|             say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}" | ||||
|             echo "$trial_url" | ||||
|             return 0 | ||||
|         else | ||||
|             say_verbose "No match at ${yellow:-}$trial_url${normal:-}" | ||||
|         fi | ||||
|     done | ||||
|     return 1 | ||||
| } | ||||
|  | ||||
| get_download_link_from_aka_ms() { | ||||
|     eval $invocation | ||||
|  | ||||
| @ -1172,6 +1363,12 @@ get_download_link_from_aka_ms() { | ||||
|     http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' ) | ||||
|     # They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404). | ||||
|     broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' ) | ||||
|     # The response may end without final code 2xx/4xx/5xx somehow, e.g. network restrictions on www.bing.com causes redirecting to bing.com fails with connection refused. | ||||
|     # In this case it should not exclude the last. | ||||
|     last_http_code=$(  echo "$http_codes" | tail -n 1 ) | ||||
|     if ! [[ $last_http_code =~ ^(2|4|5)[0-9][0-9]$ ]]; then | ||||
|         broken_redirects=$( echo "$http_codes" | grep -v '301' ) | ||||
|     fi | ||||
|  | ||||
|     # All HTTP codes are 301 (Moved Permanently), the redirect link exists. | ||||
|     if [[ -z "$broken_redirects" ]]; then | ||||
| @ -1182,6 +1379,11 @@ get_download_link_from_aka_ms() { | ||||
|             return 1 | ||||
|         fi | ||||
|  | ||||
|         sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link") | ||||
|         if [[ -n "$sanitized_redirect_url" ]]; then | ||||
|             aka_ms_download_link="$sanitized_redirect_url" | ||||
|         fi | ||||
|  | ||||
|         say_verbose "The redirect location retrieved: '$aka_ms_download_link'." | ||||
|         return 0 | ||||
|     else | ||||
| @ -1193,7 +1395,9 @@ get_download_link_from_aka_ms() { | ||||
| get_feeds_to_use() | ||||
| { | ||||
|     feeds=( | ||||
|     "https://builds.dotnet.microsoft.com/dotnet" | ||||
|     "https://dotnetcli.azureedge.net/dotnet" | ||||
|     "https://ci.dot.net/public" | ||||
|     "https://dotnetbuilds.azureedge.net/public" | ||||
|     ) | ||||
|  | ||||
| @ -1419,10 +1623,11 @@ install_dotnet() { | ||||
|     eval $invocation | ||||
|     local download_failed=false | ||||
|     local download_completed=false | ||||
|     local remote_file_size=0 | ||||
|  | ||||
|     mkdir -p "$install_root" | ||||
|     zip_path="$(mktemp "$temporary_file_template")" | ||||
|     say_verbose "Zip path: $zip_path" | ||||
|     zip_path="${zip_path:-$(mktemp "$temporary_file_template")}" | ||||
|     say_verbose "Archive path: $zip_path" | ||||
|  | ||||
|     for link_index in "${!download_links[@]}" | ||||
|     do | ||||
| @ -1446,7 +1651,7 @@ install_dotnet() { | ||||
|                 say "Failed to download $link_type link '$download_link': $download_error_msg" | ||||
|                 ;; | ||||
|             esac | ||||
|             rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed" | ||||
|             rm -f "$zip_path" 2>&1 && say_verbose "Temporary archive file $zip_path was removed" | ||||
|         else | ||||
|             download_completed=true | ||||
|             break | ||||
| @ -1459,8 +1664,10 @@ install_dotnet() { | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     say "Extracting zip from $download_link" | ||||
|     extract_dotnet_package "$zip_path" "$install_root" || return 1 | ||||
|     remote_file_size="$(get_remote_file_size "$download_link")" | ||||
|  | ||||
|     say "Extracting archive from $download_link" | ||||
|     extract_dotnet_package "$zip_path" "$install_root" "$remote_file_size" || return 1 | ||||
|  | ||||
|     #  Check if the SDK version is installed; if not, fail the installation. | ||||
|     # if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed. | ||||
| @ -1610,10 +1817,22 @@ do | ||||
|             override_non_versioned_files=false | ||||
|             non_dynamic_parameters+=" $name" | ||||
|             ;; | ||||
|         --keep-zip|-[Kk]eep[Zz]ip) | ||||
|             keep_zip=true | ||||
|             non_dynamic_parameters+=" $name" | ||||
|             ;; | ||||
|         --zip-path|-[Zz]ip[Pp]ath) | ||||
|             shift | ||||
|             zip_path="$1" | ||||
|             ;; | ||||
|         -?|--?|-h|--help|-[Hh]elp) | ||||
|             script_name="$(basename "$0")" | ||||
|             script_name="dotnet-install.sh" | ||||
|             echo ".NET Tools Installer" | ||||
|             echo "Usage: $script_name [-c|--channel <CHANNEL>] [-v|--version <VERSION>] [-p|--prefix <DESTINATION>]" | ||||
|             echo "Usage:" | ||||
|             echo "       # Install a .NET SDK of a given Quality from a given Channel" | ||||
|             echo "       $script_name [-c|--channel <CHANNEL>] [-q|--quality <QUALITY>]" | ||||
|             echo "       # Install a .NET SDK of a specific public version" | ||||
|             echo "       $script_name [-v|--version <VERSION>]" | ||||
|             echo "       $script_name -h|-?|--help" | ||||
|             echo "" | ||||
|             echo "$script_name is a simple command line interface for obtaining dotnet cli." | ||||
| @ -1655,7 +1874,7 @@ do | ||||
|             echo "      -InstallDir" | ||||
|             echo "  --architecture <ARCHITECTURE>      Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`." | ||||
|             echo "      --arch,-Architecture,-Arch" | ||||
|             echo "          Possible values: x64, arm, arm64 and s390x" | ||||
|             echo "          Possible values: x64, arm, arm64, s390x, ppc64le and loongarch64" | ||||
|             echo "  --os <system>                    Specifies operating system to be used when selecting the installer." | ||||
|             echo "          Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6." | ||||
|             echo "          In case any other value is provided, the platform will be determined by the script based on machine configuration." | ||||
| @ -1680,6 +1899,8 @@ do | ||||
|             echo "  --no-cdn,-NoCdn                    Disable downloading from the Azure CDN, and use the uncached feed directly." | ||||
|             echo "  --jsonfile <JSONFILE>              Determines the SDK version from a user specified global.json file." | ||||
|             echo "                                     Note: global.json must have a value for 'SDK:Version'" | ||||
|             echo "  --keep-zip,-KeepZip                If set, downloaded file is kept." | ||||
|             echo "  --zip-path, -ZipPath               If set, downloaded file is stored at the specified path." | ||||
|             echo "  -?,--?,-h,--help,-Help             Shows this help message" | ||||
|             echo "" | ||||
|             echo "Install Location:" | ||||
|  | ||||
| @ -101,9 +101,18 @@ export class DotnetVersionResolver { | ||||
|       allowRetries: true, | ||||
|       maxRetries: 3 | ||||
|     }); | ||||
|     const response = await httpClient.getJson<any>( | ||||
|  | ||||
|     let response; | ||||
|     try { | ||||
|       response = await httpClient.getJson<any>( | ||||
|         DotnetVersionResolver.DotNetCoreIndexUrl | ||||
|       ); | ||||
|     } catch (error) { | ||||
|       response = await httpClient.getJson<any>( | ||||
|         DotnetVersionResolver.DotnetCoreIndexFallbackUrl | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     const result = response.result || {}; | ||||
|     const releasesInfo: any[] = result['releases-index']; | ||||
|  | ||||
| @ -122,6 +131,9 @@ export class DotnetVersionResolver { | ||||
|   } | ||||
|  | ||||
|   static DotNetCoreIndexUrl = | ||||
|     'https://builds.dotnet.microsoft.com/dotnet/release-metadata/releases-index.json'; | ||||
|  | ||||
|   static DotnetCoreIndexFallbackUrl = | ||||
|     'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json'; | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	