|
|
|
@ -79,12 +79,12 @@ func TestProvisionerPrepare_Defaults(t *testing.T) {
|
|
|
|
|
t.Error("expected elevated_password to be empty")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if p.config.ExecuteCommand != `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode` {
|
|
|
|
|
t.Fatalf(`Default command should be "if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode", but got %s`, p.config.ExecuteCommand)
|
|
|
|
|
if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` {
|
|
|
|
|
t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if p.config.ElevatedExecuteCommand != `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'}; . {{.Vars}}; &'{{.Path}}'; exit $LastExitCode` {
|
|
|
|
|
t.Fatalf(`Default command should be "if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'}; . {{.Vars}}; &'{{.Path}}'; exit $LastExitCode", but got %s`, p.config.ElevatedExecuteCommand)
|
|
|
|
|
if p.config.ElevatedExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"` {
|
|
|
|
|
t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"', but got '%s'`, p.config.ElevatedExecuteCommand)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if p.config.ValidExitCodes == nil {
|
|
|
|
@ -413,23 +413,9 @@ func TestProvisionerProvision_Inline(t *testing.T) {
|
|
|
|
|
t.Fatal("should not have error")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode`
|
|
|
|
|
expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiAGkAcwBvACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiAHYAbQB3AGEAcgBlACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAGkAbgBsAGkAbgBlAFMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
|
|
|
|
|
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
|
|
|
|
|
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
|
|
|
|
|
|
|
|
|
|
actualCommandWithoutPrefix := strings.Replace(comm.StartCmd.Command, expectedCommandPrefix, "", -1)
|
|
|
|
|
actualCommandDecoded, err := powershellDecode(actualCommandWithoutPrefix)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal("should not have error when base64 decoding")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if actualCommandDecoded != expectedCommand {
|
|
|
|
|
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if comm.StartCmd.Command != expectedCommandEncoded {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, comm.StartCmd.Command)
|
|
|
|
|
expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"`
|
|
|
|
|
if comm.StartCmd.Command != expectedCommand {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
envVars := make([]string, 2)
|
|
|
|
@ -444,23 +430,9 @@ func TestProvisionerProvision_Inline(t *testing.T) {
|
|
|
|
|
t.Fatal("should not have error")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expectedCommand = `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR="BAZ"; $env:FOO="BAR"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode`
|
|
|
|
|
expectedCommandBase64Encoded = `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AEIAQQBSAD0AIgBCAEEAWgAiADsAIAAkAGUAbgB2ADoARgBPAE8APQAiAEIAQQBSACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABFAFIAXwBUAFkAUABFAD0AIgBpAHMAbwAiADsAIAAkAGUAbgB2ADoAUABBAEMASwBFAFIAXwBCAFUASQBMAEQAXwBOAEEATQBFAD0AIgB2AG0AdwBhAHIAZQAiADsAIAAmACcAYwA6AC8AVwBpAG4AZABvAHcAcwAvAFQAZQBtAHAALwBpAG4AbABpAG4AZQBTAGMAcgBpAHAAdAAuAHAAcwAxACcAOwBlAHgAaQB0ACAAJABMAGEAcwB0AEUAeABpAHQAQwBvAGQAZQA=`
|
|
|
|
|
expectedCommandPrefix = `powershell -executionpolicy bypass -encodedCommand `
|
|
|
|
|
expectedCommandEncoded = expectedCommandPrefix + expectedCommandBase64Encoded
|
|
|
|
|
|
|
|
|
|
actualCommandWithoutPrefix = strings.Replace(comm.StartCmd.Command, expectedCommandPrefix, "", -1)
|
|
|
|
|
actualCommandDecoded, err = powershellDecode(actualCommandWithoutPrefix)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal("should not have error when base64 decoding")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if actualCommandDecoded != expectedCommand {
|
|
|
|
|
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if comm.StartCmd.Command != expectedCommandEncoded {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, comm.StartCmd.Command)
|
|
|
|
|
expectedCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"`
|
|
|
|
|
if comm.StartCmd.Command != expectedCommand {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -483,24 +455,11 @@ func TestProvisionerProvision_Scripts(t *testing.T) {
|
|
|
|
|
t.Fatal("should not have error")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
|
|
|
|
|
expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiAGYAbwBvAHQAeQBwAGUAIgA7ACAAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAF8ATgBBAE0ARQA9ACIAZgBvAG8AYgB1AGkAbABkACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAHMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
|
|
|
|
|
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
|
|
|
|
|
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
|
|
|
|
|
|
|
|
|
|
actualCommandWithoutPrefix := strings.Replace(comm.StartCmd.Command, expectedCommandPrefix, "", -1)
|
|
|
|
|
actualCommandDecoded, err := powershellDecode(actualCommandWithoutPrefix)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal("should not have error when base64 decoding")
|
|
|
|
|
expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"`
|
|
|
|
|
if comm.StartCmd.Command != expectedCommand {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if actualCommandDecoded != expectedCommand {
|
|
|
|
|
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if comm.StartCmd.Command != expectedCommandEncoded {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, comm.StartCmd.Command)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) {
|
|
|
|
@ -529,23 +488,9 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) {
|
|
|
|
|
t.Fatal("should not have error")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR="BAZ"; $env:FOO="BAR"; $env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
|
|
|
|
|
expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AEIAQQBSAD0AIgBCAEEAWgAiADsAIAAkAGUAbgB2ADoARgBPAE8APQAiAEIAQQBSACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABFAFIAXwBUAFkAUABFAD0AIgBmAG8AbwB0AHkAcABlACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiAGYAbwBvAGIAdQBpAGwAZAAiADsAIAAmACcAYwA6AC8AVwBpAG4AZABvAHcAcwAvAFQAZQBtAHAALwBzAGMAcgBpAHAAdAAuAHAAcwAxACcAOwBlAHgAaQB0ACAAJABMAGEAcwB0AEUAeABpAHQAQwBvAGQAZQA=`
|
|
|
|
|
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
|
|
|
|
|
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
|
|
|
|
|
|
|
|
|
|
actualCommandWithoutPrefix := strings.Replace(comm.StartCmd.Command, expectedCommandPrefix, "", -1)
|
|
|
|
|
actualCommandDecoded, err := powershellDecode(actualCommandWithoutPrefix)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal("should not have error when base64 decoding")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if actualCommandDecoded != expectedCommand {
|
|
|
|
|
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if comm.StartCmd.Command != expectedCommandEncoded {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, comm.StartCmd.Command)
|
|
|
|
|
expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"`
|
|
|
|
|
if comm.StartCmd.Command != expectedCommand {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -588,7 +533,6 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) {
|
|
|
|
|
t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) {
|
|
|
|
@ -603,11 +547,11 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) {
|
|
|
|
|
{"FOO==bar"}, // User env var with value starting with equals
|
|
|
|
|
}
|
|
|
|
|
expected := []string{
|
|
|
|
|
`$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
|
|
|
|
`$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
|
|
|
|
`$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
|
|
|
|
`$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
|
|
|
|
`$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
|
|
|
|
|
`$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
|
|
|
|
|
`$env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
|
|
|
|
|
`$env:BAZ=\"qux\"; $env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
|
|
|
|
|
`$env:FOO=\"bar=baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
|
|
|
|
|
`$env:FOO=\"=bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p := new(Provisioner)
|
|
|
|
@ -635,27 +579,17 @@ func TestProvision_createCommandText(t *testing.T) {
|
|
|
|
|
p.communicator = comm
|
|
|
|
|
_ = p.Prepare(config)
|
|
|
|
|
|
|
|
|
|
// Defaults provided by Packer
|
|
|
|
|
p.config.PackerBuildName = "vmware"
|
|
|
|
|
p.config.PackerBuilderType = "iso"
|
|
|
|
|
|
|
|
|
|
// Non-elevated
|
|
|
|
|
cmd, _ := p.createCommandText()
|
|
|
|
|
|
|
|
|
|
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=""; $env:PACKER_BUILD_NAME=""; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
|
|
|
|
|
expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAHMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
|
|
|
|
|
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
|
|
|
|
|
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
|
|
|
|
|
expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"`
|
|
|
|
|
|
|
|
|
|
actualCommandWithoutPrefix := strings.Replace(cmd, expectedCommandPrefix, "", -1)
|
|
|
|
|
|
|
|
|
|
actualCommandDecoded, err := powershellDecode(actualCommandWithoutPrefix)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal("should not have error when base64 decoding")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if actualCommandDecoded != expectedCommand {
|
|
|
|
|
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if cmd != expectedCommandEncoded {
|
|
|
|
|
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, cmd)
|
|
|
|
|
if cmd != expectedCommand {
|
|
|
|
|
t.Fatalf("Expected Non-elevated command: %s, got %s", expectedCommand, cmd)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Elevated
|
|
|
|
|