Private/Deploy-Accelerator-Helpers/Request-AcceleratorConfigurationInput.ps1
|
function Request-AcceleratorConfigurationInput { <# .SYNOPSIS Prompts the user for accelerator configuration input and creates the folder structure. .DESCRIPTION This function interactively prompts the user for the inputs needed to set up the accelerator folder structure, calls New-AcceleratorFolderStructure to create the folders and configuration files, and returns the paths needed for Deploy-Accelerator to continue. .PARAMETER Destroy When set, only prompts for the target folder path and validates the existing folder structure exists. .OUTPUTS Returns a hashtable with the following keys: - Continue: Boolean indicating whether to continue with deployment - InputConfigFilePaths: Array of input configuration file paths - StarterAdditionalFiles: Array of additional files/folders for the starter module - OutputFolderPath: Path to the output folder #> [CmdletBinding(SupportsShouldProcess = $true)] param( [Parameter(Mandatory = $false)] [switch] $Destroy ) if ($PSCmdlet.ShouldProcess("Accelerator folder structure setup", "prompt and create")) { # Display appropriate header message if ($Destroy.IsPresent) { Write-InformationColored "Running in destroy mode. Please provide the path to your existing accelerator folder." -ForegroundColor Yellow -NewLineBefore -InformationAction Continue } else { Write-InformationColored "No input configuration files provided. Let's set up the accelerator folder structure first..." -ForegroundColor Green -NewLineBefore -InformationAction Continue Write-InformationColored "For more information, see: https://aka.ms/alz/acc/phase2" -ForegroundColor Cyan -InformationAction Continue } # Prompt for target folder path (first prompt for both modes) Write-InformationColored "`nEnter the target folder path for the accelerator files (default: ~/accelerator):" -ForegroundColor Yellow -InformationAction Continue $targetFolderPathInput = Read-Host "Target folder path" if ([string]::IsNullOrWhiteSpace($targetFolderPathInput)) { $targetFolderPathInput = "~/accelerator" } # Normalize the path $normalizedTargetPath = Get-NormalizedPath -Path $targetFolderPathInput # Analyze existing folder configuration $folderConfig = Get-AcceleratorFolderConfiguration -FolderPath $normalizedTargetPath $useExistingFolder = $false $forceFlag = $false # If folder exists, ask about overwriting before other prompts if ($folderConfig.FolderExists) { # Ask about overwriting the folder Write-InformationColored "`nTarget folder '$normalizedTargetPath' already exists." -ForegroundColor Yellow -InformationAction Continue $forceResponse = Read-Host "Do you want to overwrite it? (y/N)" if ($forceResponse -eq "y" -or $forceResponse -eq "Y") { $forceFlag = $true } else { # User wants to keep existing folder $useExistingFolder = $true # Validate config files exist if (-not $folderConfig.IsValid) { if (-not (Test-Path -Path $folderConfig.ConfigFolderPath)) { Write-InformationColored "ERROR: Config folder not found at '$($folderConfig.ConfigFolderPath)'" -ForegroundColor Red -InformationAction Continue } elseif (-not (Test-Path -Path $folderConfig.InputsYamlPath)) { Write-InformationColored "ERROR: Required configuration file not found: inputs.yaml" -ForegroundColor Red -InformationAction Continue } Write-InformationColored "Please overwrite the folder structure by choosing 'y', or run New-AcceleratorFolderStructure manually." -ForegroundColor Yellow -InformationAction Continue return ConvertTo-AcceleratorResult -Continue $false } } } # Handle destroy mode - validate existing folder and return early if ($Destroy.IsPresent) { if (-not $folderConfig.FolderExists) { Write-InformationColored "ERROR: Target folder '$normalizedTargetPath' does not exist." -ForegroundColor Red -InformationAction Continue Write-InformationColored "Cannot destroy a deployment that doesn't exist. Please check the path and try again." -ForegroundColor Yellow -InformationAction Continue return ConvertTo-AcceleratorResult -Continue $false } if (-not (Test-Path -Path $folderConfig.ConfigFolderPath)) { Write-InformationColored "ERROR: Config folder not found at '$($folderConfig.ConfigFolderPath)'" -ForegroundColor Red -InformationAction Continue Write-InformationColored "Cannot destroy a deployment without configuration files." -ForegroundColor Yellow -InformationAction Continue return ConvertTo-AcceleratorResult -Continue $false } if (-not (Test-Path -Path $folderConfig.InputsYamlPath)) { Write-InformationColored "ERROR: Required configuration file not found: inputs.yaml" -ForegroundColor Red -InformationAction Continue Write-InformationColored "Cannot destroy a deployment without inputs.yaml." -ForegroundColor Yellow -InformationAction Continue return ConvertTo-AcceleratorResult -Continue $false } # Build input config file paths based on detected IaC type $configPaths = Get-AcceleratorConfigPath -IacType $folderConfig.IacType -ConfigFolderPath $folderConfig.ConfigFolderPath $resolvedTargetPath = (Resolve-Path -Path $normalizedTargetPath).Path Write-InformationColored "Using existing folder: $resolvedTargetPath" -ForegroundColor Green -InformationAction Continue Write-InformationColored "`nProceeding with destroy..." -ForegroundColor Yellow -InformationAction Continue return ConvertTo-AcceleratorResult -Continue $true ` -InputConfigFilePaths $configPaths.InputConfigFilePaths ` -StarterAdditionalFiles $configPaths.StarterAdditionalFiles ` -OutputFolderPath "$resolvedTargetPath/output" } # Set selected values from detected values (for use existing folder case) $selectedIacType = $folderConfig.IacType $selectedVersionControl = $folderConfig.VersionControl $selectedScenarioNumber = 1 # Only prompt for IaC type, version control, and scenario if creating new folder or overwriting if (-not $useExistingFolder) { # Prompt for IaC type with detected value as default $iacTypeOptions = @("terraform", "bicep") $defaultIacTypeIndex = if ($null -ne $folderConfig.IacType) { [Math]::Max(0, $iacTypeOptions.IndexOf($folderConfig.IacType)) } else { 0 } $selectedIacType = Read-MenuSelection ` -Title "`nSelect the Infrastructure as Code (IaC) type:" ` -Options $iacTypeOptions ` -DefaultIndex $defaultIacTypeIndex # Prompt for version control with detected value as default $versionControlOptions = @("github", "azure-devops", "local") $defaultVcsIndex = if ($null -ne $folderConfig.VersionControl) { [Math]::Max(0, $versionControlOptions.IndexOf($folderConfig.VersionControl)) } else { 0 } $selectedVersionControl = Read-MenuSelection ` -Title "`nSelect the Version Control System:" ` -Options $versionControlOptions ` -DefaultIndex $defaultVcsIndex # Prompt for scenario number (Terraform only) if ($selectedIacType -eq "terraform") { $scenarioDescriptions = @( "Full Multi-Region - Hub and Spoke VNet", "Full Multi-Region - Virtual WAN", "Full Multi-Region NVA - Hub and Spoke VNet", "Full Multi-Region NVA - Virtual WAN", "Management Only", "Full Single-Region - Hub and Spoke VNet", "Full Single-Region - Virtual WAN", "Full Single-Region NVA - Hub and Spoke VNet", "Full Single-Region NVA - Virtual WAN" ) $scenarioNumbers = 1..$scenarioDescriptions.Count $selectedScenarioNumber = Read-MenuSelection ` -Title "`nSelect the Terraform scenario (see https://aka.ms/alz/acc/scenarios):" ` -Options $scenarioNumbers ` -OptionDescriptions $scenarioDescriptions ` -DefaultIndex 0 } } # Create folder structure if needed if (-not $folderConfig.FolderExists -or $forceFlag) { New-AcceleratorFolderStructure ` -iacType $selectedIacType ` -versionControl $selectedVersionControl ` -scenarioNumber $selectedScenarioNumber ` -targetFolderPath $targetFolderPathInput ` -force:$forceFlag Write-InformationColored "`nFolder structure created at: $normalizedTargetPath" -ForegroundColor Green -InformationAction Continue } # Resolve the path after folder creation or validation $resolvedTargetPath = (Resolve-Path -Path $normalizedTargetPath).Path $configFolderPath = if ($useExistingFolder) { $folderConfig.ConfigFolderPath } else { Join-Path $resolvedTargetPath "config" } if ($useExistingFolder) { Write-InformationColored "`nUsing existing folder structure at: $resolvedTargetPath" -ForegroundColor Green -InformationAction Continue } Write-InformationColored "Config folder: $configFolderPath" -ForegroundColor Cyan -InformationAction Continue # Offer to configure inputs interactively (default is Yes) $configureNowResponse = Read-Host "`nWould you like to configure the input values interactively now? (Y/n)" if ($configureNowResponse -ne "n" -and $configureNowResponse -ne "N") { $azureContext = Get-AzureContext Request-ALZConfigurationValue ` -ConfigFolderPath $configFolderPath ` -IacType $selectedIacType ` -VersionControl $selectedVersionControl ` -AzureContext $azureContext } # Check for VS Code or VS Code Insiders and offer to open the config folder $vsCodeCommand = $null $vsCodeName = $null if (Get-Command "code-insiders" -ErrorAction SilentlyContinue) { $vsCodeCommand = "code-insiders" $vsCodeName = "VS Code Insiders" } elseif (Get-Command "code" -ErrorAction SilentlyContinue) { $vsCodeCommand = "code" $vsCodeName = "VS Code" } if ($null -ne $vsCodeCommand) { $openInVsCodeResponse = Read-Host "`nWould you like to open the config folder in $($vsCodeName)? (Y/n)" if ($openInVsCodeResponse -ne "n" -and $openInVsCodeResponse -ne "N") { Write-InformationColored "Opening config folder in $vsCodeName..." -ForegroundColor Green -InformationAction Continue & $vsCodeCommand $configFolderPath } } Write-InformationColored "`nPlease check and update the configuration files in the config folder before continuing:" -ForegroundColor Yellow -InformationAction Continue Write-InformationColored " - inputs.yaml: Bootstrap configuration (required)" -ForegroundColor White -InformationAction Continue if ($selectedIacType -eq "terraform") { Write-InformationColored " - platform-landing-zone.tfvars: Platform configuration (required)" -ForegroundColor White -InformationAction Continue Write-InformationColored " - starter_locations: Enter the regions for you platform landing zone (required)" -ForegroundColor White -InformationAction Continue Write-InformationColored " - defender_email_security_contact: Enter the email security contact for Microsoft Defender for Cloud (required)" -ForegroundColor White -InformationAction Continue Write-InformationColored " - lib/: Library customizations (optional)" -ForegroundColor White -InformationAction Continue } elseif ($selectedIacType -eq "bicep") { Write-InformationColored " - platform-landing-zone.yaml: Platform configuration (required)" -ForegroundColor White -InformationAction Continue Write-InformationColored " - starter_locations: Enter the regions for you platform landing zone (required)" -ForegroundColor White -InformationAction Continue } Write-InformationColored "`nFor more details, see: https://azure.github.io/Azure-Landing-Zones/accelerator/configuration-files/" -ForegroundColor Cyan -InformationAction Continue # Prompt to continue or exit $continueResponse = Read-Host "`nHave you checked and updated the configuration files? Enter 'yes' to continue with deployment, or 'no' to exit and configure later" if ($continueResponse -ne "yes") { Write-InformationColored "`nTo continue later, run Deploy-Accelerator with the following parameters:" -ForegroundColor Green -InformationAction Continue if ($selectedIacType -eq "terraform") { Write-InformationColored @" Deploy-Accelerator `` -inputs "$configFolderPath/inputs.yaml", "$configFolderPath/platform-landing-zone.tfvars" `` -starterAdditionalFiles "$configFolderPath/lib" `` -output "$resolvedTargetPath/output" "@ -ForegroundColor Cyan -InformationAction Continue } elseif ($selectedIacType -eq "bicep") { Write-InformationColored @" Deploy-Accelerator `` -inputs "$configFolderPath/inputs.yaml", "$configFolderPath/platform-landing-zone.yaml" `` -output "$resolvedTargetPath/output" "@ -ForegroundColor Cyan -InformationAction Continue } else { Write-InformationColored @" Deploy-Accelerator `` -inputs "$configFolderPath/inputs.yaml" `` -output "$resolvedTargetPath/output" "@ -ForegroundColor Cyan -InformationAction Continue } return ConvertTo-AcceleratorResult -Continue $false } # Build the result for continuing with deployment $configPaths = Get-AcceleratorConfigPath -IacType $selectedIacType -ConfigFolderPath $configFolderPath Write-InformationColored "`nContinuing with deployment..." -ForegroundColor Green -InformationAction Continue return ConvertTo-AcceleratorResult -Continue $true ` -InputConfigFilePaths $configPaths.InputConfigFilePaths ` -StarterAdditionalFiles $configPaths.StarterAdditionalFiles ` -OutputFolderPath "$resolvedTargetPath/output" } } # SIG # Begin signature block # MIIoLwYJKoZIhvcNAQcCoIIoIDCCKBwCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBlf50yWfExbXab # VvUsR0RA2I4nW1nObD8HQzJbBuIACKCCDXYwggX0MIID3KADAgECAhMzAAAEhV6Z # 7A5ZL83XAAAAAASFMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjUwNjE5MTgyMTM3WhcNMjYwNjE3MTgyMTM3WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDASkh1cpvuUqfbqxele7LCSHEamVNBfFE4uY1FkGsAdUF/vnjpE1dnAD9vMOqy # 5ZO49ILhP4jiP/P2Pn9ao+5TDtKmcQ+pZdzbG7t43yRXJC3nXvTGQroodPi9USQi # 9rI+0gwuXRKBII7L+k3kMkKLmFrsWUjzgXVCLYa6ZH7BCALAcJWZTwWPoiT4HpqQ # hJcYLB7pfetAVCeBEVZD8itKQ6QA5/LQR+9X6dlSj4Vxta4JnpxvgSrkjXCz+tlJ # 67ABZ551lw23RWU1uyfgCfEFhBfiyPR2WSjskPl9ap6qrf8fNQ1sGYun2p4JdXxe # UAKf1hVa/3TQXjvPTiRXCnJPAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUuCZyGiCuLYE0aU7j5TFqY05kko0w # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwNTM1OTAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBACjmqAp2Ci4sTHZci+qk # tEAKsFk5HNVGKyWR2rFGXsd7cggZ04H5U4SV0fAL6fOE9dLvt4I7HBHLhpGdE5Uj # Ly4NxLTG2bDAkeAVmxmd2uKWVGKym1aarDxXfv3GCN4mRX+Pn4c+py3S/6Kkt5eS # DAIIsrzKw3Kh2SW1hCwXX/k1v4b+NH1Fjl+i/xPJspXCFuZB4aC5FLT5fgbRKqns # WeAdn8DsrYQhT3QXLt6Nv3/dMzv7G/Cdpbdcoul8FYl+t3dmXM+SIClC3l2ae0wO # lNrQ42yQEycuPU5OoqLT85jsZ7+4CaScfFINlO7l7Y7r/xauqHbSPQ1r3oIC+e71 # 5s2G3ClZa3y99aYx2lnXYe1srcrIx8NAXTViiypXVn9ZGmEkfNcfDiqGQwkml5z9 # nm3pWiBZ69adaBBbAFEjyJG4y0a76bel/4sDCVvaZzLM3TFbxVO9BQrjZRtbJZbk # C3XArpLqZSfx53SuYdddxPX8pvcqFuEu8wcUeD05t9xNbJ4TtdAECJlEi0vvBxlm # M5tzFXy2qZeqPMXHSQYqPgZ9jvScZ6NwznFD0+33kbzyhOSz/WuGbAu4cHZG8gKn # lQVT4uA2Diex9DMs2WHiokNknYlLoUeWXW1QrJLpqO82TLyKTbBM/oZHAdIc0kzo # STro9b3+vjn2809D0+SOOCVZMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # 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 # /Xmfwb1tbWrJUnMTDXpQzTGCGg8wghoLAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAASFXpnsDlkvzdcAAAAABIUwDQYJYIZIAWUDBAIB # BQCggbAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIGu3gHDLU5k7HjdRq8d2DeDG # 5bhIPaCzA8Qr1DDZCSh3MEQGCisGAQQBgjcCAQwxNjA0oBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEcgBpodHRwczovL3d3dy5taWNyb3NvZnQuY29tIDANBgkqhkiG9w0B # AQEFAASCAQCr0sQUGYdaradTfE27mxwqL+ogBHy2bf/EkRt9W3cBiRF5Q+eN+7hr # ou+uJ2xrKjdGquY+Z7iu4pLLJytXlhrKbWEJSDLgMljtyOnghuVFJ5sfUlDsx+6g # 63r9F6x8NqQ29anme3O557Yw63cOMsNo7zdtolNkVYSNarL8UL9eVWQyVjKor0ZX # 1RyJMiXKRWyjpE0XOOGmAsYDviPS2j7JwQGbEeZ9NsXm1xALuZ4J+CW5Ri0LMTr6 # ZgwVx8NTPMvl7Ey+rNjnDmEiZC4faWohVx27EKn1i1PrUj8JRpl4QKu3yNEweFn7 # Ob3+gx1nCcgiHEj4rE5EBqx44uGdaDWfoYIXlzCCF5MGCisGAQQBgjcDAwExgheD # MIIXfwYJKoZIhvcNAQcCoIIXcDCCF2wCAQMxDzANBglghkgBZQMEAgEFADCCAVIG # CyqGSIb3DQEJEAEEoIIBQQSCAT0wggE5AgEBBgorBgEEAYRZCgMBMDEwDQYJYIZI # AWUDBAIBBQAEIJdkW006I92BdTShD/RQxlM0VbcucPExyDudY0+RBiUdAgZpO0mX # H30YEzIwMjYwMTA5MTIyNzE2LjMwMVowBIACAfSggdGkgc4wgcsxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBB # bWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo5NjAw # LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj # ZaCCEe0wggcgMIIFCKADAgECAhMzAAACBNjgDgeXMliYAAEAAAIEMA0GCSqGSIb3 # DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAk # BgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI1MDEzMDE5 # NDI0N1oXDTI2MDQyMjE5NDI0N1owgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlv # bnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo5NjAwLTA1RTAtRDk0NzElMCMG # A1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBAPDdJtx57Z3rq+RYZMheF8aqqBAbFBdOerjheVS8 # 3MVK3sQu07gH3f2PBkVfsOtG3/h+nMY2QV0alzsQvlLzqopi/frR5eNb58i/WUCo # MPfV3+nwCL38BnPwz3nOjSsOkrZyzP1YDJH0W1QPHnZU6z2o/f+mCke+BS8Pyzr/ # co0hPOazxALW0ndMzDVxGf0JmBUhjPDaIP9m85bSxsX8NF2AzxR23GMUgpNdNoj9 # smGxCB7dPBrIpDaPzlFp8UVUJHn8KFqmSsFBYbA0Vo/OmZg3jqY+I69TGuIhIL2d # D8asNdQlbMsOZyGuavZtoAEl6+/DfVRiVOUtljrNSaOSBpF+mjN34aWr1NjYTcOC # Wvo+1MQqA+7aEzq/w2JTmdO/GEOfF2Zx/xQ3uCh5WUQtds6buPzLDXEz0jLJC5Qx # aSisFo3/mv2DiW9iQyiFFcRgHS0xo4+3QWZmZAwsEWk1FWdcFNriFpe+fVp0qu9P # PxWV+cfGQfquID+HYCWphaG/RhQuwRwedoNaCoDb2vL6MfT3sykn8UcYfGT532Qf # Yvlok+kBi42Yw08HsUNM9YDHsCmOv8nkyFTHSLTuBXZusBn0n1EeL58w9tL5CbgC # icLmI5OP50oK21VGz6Moq47rcIvCqWWO+dQKa5Jq85fnghc60pwVmR8N05ntwTgO # Kg/VAgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUGnV2S0Bwalb8qbqqb6+7gzUZol8w # HwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKg # UIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0 # JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAw # XjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j # ZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQw # DAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8E # BAMCB4AwDQYJKoZIhvcNAQELBQADggIBAF5y/qxHDYdMszJQLVYkn4VH4OAD0mS/ # SUawi3jLr0KY6PxHregVuFKZx2lqTGo1uvy/13JNvhEPI2q2iGKJdu2teZArlfvL # 9D74XTMyi1O1OlM+8bd6W3JX8u87Xmasug1DtbhUfnxou3TfS05HGzxWcBBAXkGZ # BAw65r4RCAfh/UXi4XquXcQLXskFInTCMdJ5r+fRZiIc9HSqTP81EB/yVJRRXSBs # gxrAYiOfv5ErIKv7yXXF02Qr8XRRi5feEbScT71ZzQvgD96eW5Q3s9r285XpWLcE # 4lJPRFj9rHuJnjmV4zySoLDsEU9xMiRbPGmOvacK2KueTDs4FDoU2DAi4C9g1NTu # vrRbjbVgU4vmlOwxlw0M46wDTXG/vKYIXrOScwalEe7DRFvYEAkL2q5TsJdZsxsA # kt1npcg0pquJKYJff8wt3Nxblc7JwrRCGhE1F/hapdGyEQFpjbKYm8c7jyhJJj+S # m5i8FLeWMAC4s3tGnyNZLu33XqloZ4Tumuas/0UmyjLUsUqYWdb6+DjcA2EHK4AR # er0JrLmjsrYfk0WdHnCP9ItErArWLJRf3bqLVMS+ISICH89XIlsAPiSiKmKDbyn/ # ocO6Jg5nTBSSb9rlbyisiOg51TdewniLTwJ82nkjvcKy8HlA9gxwukX007/Uu+hA # DDdQ90vnkzkdMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg # VGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+ # F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU # 88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqY # O7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzp # cGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0Xn # Rm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1 # zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZN # N3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLR # vWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTY # uVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUX # k8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB # 2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKR # PEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0g # BFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5t # aWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQM # MAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQE # AwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQ # W9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNv # bS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBa # BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqG # SIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOX # PTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6c # qYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/z # jj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz # /AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyR # gNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdU # bZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo # 3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4K # u+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10Cga # iQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9 # vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGC # A1AwggI4AgEBMIH5oYHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25z # MScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046OTYwMC0wNUUwLUQ5NDcxJTAjBgNV # BAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMV # ALo9gdHD371If7WnDLqrNUbeT2VuoIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh # bXAgUENBIDIwMTAwDQYJKoZIhvcNAQELBQACBQDtC1fcMCIYDzIwMjYwMTA5MTAz # MzAwWhgPMjAyNjAxMTAxMDMzMDBaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAO0L # V9wCAQAwCgIBAAICJbgCAf8wBwIBAAICEjswCgIFAO0MqVwCAQAwNgYKKwYBBAGE # WQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDAN # BgkqhkiG9w0BAQsFAAOCAQEABzeiX5shc7zo8FtJCPqoQZQZtDQdjxcfjmLj4pu/ # RvkxU7H9Uz6o08blLZFV3VvNZQPiDqwJOM8jdlY5OJwqF3U5Po9q7Ookuml9KJ/y # mQOE0BFr2CD35Rteo6xtmS4/x32BCqm26uzDXIw+2S7Z5NbSOqDit1ZKzWbWiFDP # gVgWqG4obuzUnbEXfWHjLe63gwPed/JfjGbgJxVBcLvGKt8KZNxdK3/z64GZnYPG # fKZ/fD6vmyU4RU6TmGQ+gJ7e9bBVlnxWnf3vLEctBBxS1efF4O+Vq6yz+7NhtQnR # QYmzxdommGsgHHrPbgZv9qW/LgzU28leUnBlUEt/85F3wDGCBA0wggQJAgEBMIGT # MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT # HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAACBNjgDgeXMliYAAEA # AAIEMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQ # AQQwLwYJKoZIhvcNAQkEMSIEIMZIOqmVzkimWMSIrE3tNIF79xN0tn3E4PmzCPnp # xh/EMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQg+e14Zf1bCrxV0kzqaN/H # UYQmy7v/qRTqXRJLmtx5uf4wgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UE # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ # Q0EgMjAxMAITMwAAAgTY4A4HlzJYmAABAAACBDAiBCADLMbtFvFX+kxJ6s/3k7qm # UDphPWCw74qwtbsFW05/vjANBgkqhkiG9w0BAQsFAASCAgC1hVFNdSIqi0qOiMjG # vY6v39U4DJun6DWcJkhujDaFQNRY9QSBTz7UeJ0gSu2t4Og1N0J6GpYRNtdfmvRM # 9WCI+KCYHRiAShSn4dMI8bnn8wWED8zCVLHgotNofcoxmOHIQntt3pQOGEjhxRw9 # 4SLfliOticwPS2CqSrF/63lumDgRpzjP8LNGI/WW+QCkr8lsTUMNvrLetrotONuC # hMAc6DWv/PwbPAQdKffRYuBV8TLJnEUw6PS1QjKrW9xUYsAFxHJdc8rm3J0fO9MM # eVF7+/vRwQTbfYDPCLQjmyE9y46P1IHfOg7r76d9t+J2/zoZolaYauYj/mtdr1An # Z7OUMTLJfKAaiDBrY+yw4cAH7vx1/UNILVaRNz/p4J6qQtp2q7UTPj2LYG5Cx4t3 # 4Tu2okki7f+P50FksgePehfOMR5TNZ9hZ4xgaD+NcTewjnyXGpFcg0TRG9JDDx5w # AtWaEThz9IaQ22fbPR9B4EknxghRpCmBeXKlOyRMXfIs5R9KSrkGRDdJUGDAHmAI # FydeCIHBzP7U6mnY9ubqxyQVvTPmV4KWtR1ojnxjBH6FbIyoHhjgI40a3nxnM5cD # hG4Gj3+0vv+qacCfnP6hM6pNkYY0E8hfHOzNtPo68qxJStPgLOb4acNxzGwXpneR # mS5s254jUYTtz/IqgzuapTdb/g== # SIG # End signature block |