func moduleDisplayAddr(addr addrs.ModuleInstance) string {
	switch {
	case addr.IsRoot():
		return "the root module"
	default:
		return addr.String()
	}
}
moduleDisplayAddr returns a string describing the given module instance
address that is appropriate for returning to users in situations where the
root module is possible. Specifically, it returns "the root module" if the
root module instance is given, or a string representation of the module
address otherwise.
package terraform
import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"sync"
	"github.com/agext/levenshtein"
	"github.com/hashicorp/hcl/v2"
	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/convert"
	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/configs"
	"github.com/hashicorp/terraform/configs/configschema"
	"github.com/hashicorp/terraform/lang"
	"github.com/hashicorp/terraform/plans"
	"github.com/hashicorp/terraform/states"
	"github.com/hashicorp/terraform/tfdiags"
)
type Evaluator struct {
	Operation walkOperation
	Meta *ContextMeta
	Config *configs.Config
	VariableValues     map[string]map[string]cty.Value
	VariableValuesLock *sync.Mutex
	Schemas *Schemas
	State *states.SyncState
	Changes *plans.ChangesSync
}
func (e *Evaluator) Scope(data lang.Data, self addrs.Referenceable) *lang.Scope {
	return &lang.Scope{
		Data:     data,
		SelfAddr: self,
		PureOnly: e.Operation != walkApply && e.Operation != walkDestroy,
		BaseDir:  ".",  
	}
}
type evaluationStateData struct {
	Evaluator *Evaluator
	ModulePath addrs.ModuleInstance
	InstanceKeyData InstanceKeyEvalData
	Operation walkOperation
}
type InstanceKeyEvalData struct {
	CountIndex cty.Value
	EachKey, EachValue cty.Value
}
func EvalDataForInstanceKey(key addrs.InstanceKey, forEachMap map[string]cty.Value) InstanceKeyEvalData {
	var countIdx cty.Value
	var eachKey cty.Value
	var eachVal cty.Value
	if intKey, ok := key.(addrs.IntKey); ok {
		countIdx = cty.NumberIntVal(int64(intKey))
	}
	if stringKey, ok := key.(addrs.StringKey); ok {
		eachKey = cty.StringVal(string(stringKey))
		eachVal = forEachMap[string(stringKey)]
	}
	return InstanceKeyEvalData{
		CountIndex: countIdx,
		EachKey:    eachKey,
		EachValue:  eachVal,
	}
}
var EvalDataForNoInstanceKey = InstanceKeyEvalData{}
var _ lang.Data = (*evaluationStateData)(nil)
func (d *evaluationStateData) GetCountAttr(addr addrs.CountAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	switch addr.Name {
	case "index":
		idxVal := d.InstanceKeyData.CountIndex
		if idxVal == cty.NilVal {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  `Reference to "count" in non-counted context`,
				Detail:   fmt.Sprintf(`The "count" object can be used only in "resource" and "data" blocks, and only when the "count" argument is set.`),
				Subject:  rng.ToHCL().Ptr(),
			})
			return cty.UnknownVal(cty.Number), diags
		}
		return idxVal, diags
	default:
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Invalid "count" attribute`,
			Detail:   fmt.Sprintf(`The "count" object does not have an attribute named %q. The only supported attribute is count.index, which is the index of each instance of a resource block that has the "count" argument set.`, addr.Name),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
}
func (d *evaluationStateData) GetForEachAttr(addr addrs.ForEachAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	var returnVal cty.Value
	switch addr.Name {
	case "key":
		returnVal = d.InstanceKeyData.EachKey
	case "value":
		returnVal = d.InstanceKeyData.EachValue
		if returnVal == cty.NilVal {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  `each.value cannot be used in this context`,
				Detail:   fmt.Sprintf(`A reference to "each.value" has been used in a context in which it unavailable, such as when the configuration no longer contains the value in its "for_each" expression. Remove this reference to each.value in your configuration to work around this error.`),
				Subject:  rng.ToHCL().Ptr(),
			})
			return cty.UnknownVal(cty.DynamicPseudoType), diags
		}
	default:
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Invalid "each" attribute`,
			Detail:   fmt.Sprintf(`The "each" object does not have an attribute named %q. The supported attributes are each.key and each.value, the current key and value pair of the "for_each" attribute set.`, addr.Name),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
	if returnVal == cty.NilVal {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Reference to "each" in context without for_each`,
			Detail:   fmt.Sprintf(`The "each" object can be used only in "resource" blocks, and only when the "for_each" argument is set.`),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.UnknownVal(cty.DynamicPseudoType), diags
	}
	return returnVal, diags
}
func (d *evaluationStateData) GetInputVariable(addr addrs.InputVariable, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	moduleConfig := d.Evaluator.Config.DescendentForInstance(d.ModulePath)
	if moduleConfig == nil {
		panic(fmt.Sprintf("input variable read from %s, which has no configuration", d.ModulePath))
	}
	config := moduleConfig.Module.Variables[addr.Name]
	if config == nil {
		var suggestions []string
		for k := range moduleConfig.Module.Variables {
			suggestions = append(suggestions, k)
		}
		suggestion := nameSuggestion(addr.Name, suggestions)
		if suggestion != "" {
			suggestion = fmt.Sprintf(" Did you mean %q?", suggestion)
		} else {
			suggestion = fmt.Sprintf(" This variable can be declared with a variable %q {} block.", addr.Name)
		}
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Reference to undeclared input variable`,
			Detail:   fmt.Sprintf(`An input variable with the name %q has not been declared.%s`, addr.Name, suggestion),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
	wantType := cty.DynamicPseudoType
	if config.Type != cty.NilType {
		wantType = config.Type
	}
	d.Evaluator.VariableValuesLock.Lock()
	defer d.Evaluator.VariableValuesLock.Unlock()
	if d.Operation == walkValidate {
		return cty.UnknownVal(wantType), diags
	}
	moduleAddrStr := d.ModulePath.String()
	vals := d.Evaluator.VariableValues[moduleAddrStr]
	if vals == nil {
		return cty.UnknownVal(wantType), diags
	}
	val, isSet := vals[addr.Name]
	if !isSet {
		if config.Default != cty.NilVal {
			return config.Default, diags
		}
		return cty.UnknownVal(wantType), diags
	}
	var err error
	val, err = convert.Convert(val, wantType)
	if err != nil {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Incorrect variable type`,
			Detail:   fmt.Sprintf(`The resolved value of variable %q is not appropriate: %s.`, addr.Name, err),
			Subject:  &config.DeclRange,
		})
		val = cty.UnknownVal(wantType)
	}
	return val, diags
}
func (d *evaluationStateData) GetLocalValue(addr addrs.LocalValue, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	moduleConfig := d.Evaluator.Config.DescendentForInstance(d.ModulePath)
	if moduleConfig == nil {
		panic(fmt.Sprintf("local value read from %s, which has no configuration", d.ModulePath))
	}
	config := moduleConfig.Module.Locals[addr.Name]
	if config == nil {
		var suggestions []string
		for k := range moduleConfig.Module.Locals {
			suggestions = append(suggestions, k)
		}
		suggestion := nameSuggestion(addr.Name, suggestions)
		if suggestion != "" {
			suggestion = fmt.Sprintf(" Did you mean %q?", suggestion)
		}
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Reference to undeclared local value`,
			Detail:   fmt.Sprintf(`A local value with the name %q has not been declared.%s`, addr.Name, suggestion),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
	val := d.Evaluator.State.LocalValue(addr.Absolute(d.ModulePath))
	if val == cty.NilVal {
		val = cty.DynamicVal
	}
	return val, diags
}
func (d *evaluationStateData) GetModuleInstance(addr addrs.ModuleCallInstance, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	moduleAddr := addr.ModuleInstance(d.ModulePath)
	moduleConfig := d.Evaluator.Config.DescendentForInstance(moduleAddr)
	if moduleConfig == nil {
		panic(fmt.Sprintf("output value read from %s, which has no configuration", moduleAddr))
	}
	outputConfigs := moduleConfig.Module.Outputs
	vals := map[string]cty.Value{}
	for n := range outputConfigs {
		addr := addrs.OutputValue{Name: n}.Absolute(moduleAddr)
		if changeSrc := d.Evaluator.Changes.GetOutputChange(addr); changeSrc != nil {
			change, err := changeSrc.Decode()
			if err != nil {
				diags = diags.Append(fmt.Errorf("planned change for %s could not be decoded: %s", addr, err))
				vals[n] = cty.DynamicVal
				continue
			}
			vals[n] = change.After
		} else {
			os := d.Evaluator.State.OutputValue(addr)
			if os == nil {
				vals[n] = cty.DynamicVal
				continue
			}
			vals[n] = os.Value
		}
	}
	return cty.ObjectVal(vals), diags
}
func (d *evaluationStateData) GetModuleInstanceOutput(addr addrs.ModuleCallOutput, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	absAddr := addr.AbsOutputValue(d.ModulePath)
	moduleAddr := absAddr.Module
	moduleConfig := d.Evaluator.Config.DescendentForInstance(moduleAddr)
	if moduleConfig == nil {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Reference to undeclared module`,
			Detail:   fmt.Sprintf(`The configuration contains no %s.`, moduleAddr),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
	config := moduleConfig.Module.Outputs[addr.Name]
	if config == nil {
		var suggestions []string
		for k := range moduleConfig.Module.Outputs {
			suggestions = append(suggestions, k)
		}
		suggestion := nameSuggestion(addr.Name, suggestions)
		if suggestion != "" {
			suggestion = fmt.Sprintf(" Did you mean %q?", suggestion)
		}
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Reference to undeclared output value`,
			Detail:   fmt.Sprintf(`An output value with the name %q has not been declared in %s.%s`, addr.Name, moduleDisplayAddr(moduleAddr), suggestion),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
	if changeSrc := d.Evaluator.Changes.GetOutputChange(absAddr); changeSrc != nil {
		change, err := changeSrc.Decode()
		if err != nil {
			diags = diags.Append(fmt.Errorf("planned change for %s could not be decoded: %s", absAddr, err))
			return cty.DynamicVal, diags
		}
		return change.After, diags
	}
	os := d.Evaluator.State.OutputValue(absAddr)
	if os == nil {
		return cty.DynamicVal, diags
	}
	return os.Value, diags
}
func (d *evaluationStateData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	switch addr.Name {
	case "cwd":
		wd, err := os.Getwd()
		if err != nil {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  `Failed to get working directory`,
				Detail:   fmt.Sprintf(`The value for path.cwd cannot be determined due to a system error: %s`, err),
				Subject:  rng.ToHCL().Ptr(),
			})
			return cty.DynamicVal, diags
		}
		return cty.StringVal(filepath.ToSlash(wd)), diags
	case "module":
		moduleConfig := d.Evaluator.Config.DescendentForInstance(d.ModulePath)
		if moduleConfig == nil {
			panic(fmt.Sprintf("module.path read from module %s, which has no configuration", d.ModulePath))
		}
		sourceDir := moduleConfig.Module.SourceDir
		return cty.StringVal(filepath.ToSlash(sourceDir)), diags
	case "root":
		sourceDir := d.Evaluator.Config.Module.SourceDir
		return cty.StringVal(filepath.ToSlash(sourceDir)), diags
	default:
		suggestion := nameSuggestion(addr.Name, []string{"cwd", "module", "root"})
		if suggestion != "" {
			suggestion = fmt.Sprintf(" Did you mean %q?", suggestion)
		}
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Invalid "path" attribute`,
			Detail:   fmt.Sprintf(`The "path" object does not have an attribute named %q.%s`, addr.Name, suggestion),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
}
func (d *evaluationStateData) GetResource(addr addrs.Resource, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	moduleAddr := d.ModulePath
	moduleConfig := d.Evaluator.Config.DescendentForInstance(moduleAddr)
	if moduleConfig == nil {
		panic(fmt.Sprintf("resource value read from %s, which has no configuration", moduleAddr))
	}
	config := moduleConfig.Module.ResourceByAddr(addr)
	if config == nil {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Reference to undeclared resource`,
			Detail:   fmt.Sprintf(`A resource %q %q has not been declared in %s`, addr.Type, addr.Name, moduleDisplayAddr(moduleAddr)),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
	rs := d.Evaluator.State.Resource(addr.Absolute(d.ModulePath))
	if rs == nil {
		return cty.DynamicVal, diags
	}
	if d.Operation == walkValidate {
		return cty.DynamicVal, diags
	}
	return d.getResourceInstancesAll(addr, rng, config, rs, rs.ProviderConfig)
}
func (d *evaluationStateData) getResourceInstancesAll(addr addrs.Resource, rng tfdiags.SourceRange, config *configs.Resource, rs *states.Resource, providerAddr addrs.AbsProviderConfig) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	instAddr := addrs.ResourceInstance{Resource: addr, Key: addrs.NoKey}
	schema := d.getResourceSchema(addr, providerAddr)
	if schema == nil {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Missing resource type schema`,
			Detail:   fmt.Sprintf("No schema is available for %s in %s. This is a bug in Terraform and should be reported.", addr, providerAddr),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
	switch rs.EachMode {
	case states.NoEach:
		ty := schema.ImpliedType()
		is := rs.Instances[addrs.NoKey]
		if is == nil || is.Current == nil {
			return cty.UnknownVal(ty), diags
		}
		if is.Current.Status == states.ObjectPlanned {
			if change := d.Evaluator.Changes.GetResourceInstanceChange(instAddr.Absolute(d.ModulePath), states.CurrentGen); change != nil {
				val, err := change.After.Decode(ty)
				if err != nil {
					diags = diags.Append(&hcl.Diagnostic{
						Severity: hcl.DiagError,
						Summary:  "Invalid resource instance data in plan",
						Detail:   fmt.Sprintf("Instance %s data could not be decoded from the plan: %s.", addr.Absolute(d.ModulePath), err),
						Subject:  &config.DeclRange,
					})
					return cty.UnknownVal(ty), diags
				}
				return val, diags
			} else {
				diags = diags.Append(&hcl.Diagnostic{
					Severity: hcl.DiagError,
					Summary:  "Missing pending object in plan",
					Detail:   fmt.Sprintf("Instance %s is marked as having a change pending but that change is not recorded in the plan. This is a bug in Terraform; please report it.", addr),
					Subject:  &config.DeclRange,
				})
				return cty.UnknownVal(ty), diags
			}
		}
		ios, err := is.Current.Decode(ty)
		if err != nil {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Invalid resource instance data in state",
				Detail:   fmt.Sprintf("Instance %s data could not be decoded from the state: %s.", addr.Absolute(d.ModulePath), err),
				Subject:  &config.DeclRange,
			})
			return cty.UnknownVal(ty), diags
		}
		return ios.Value, diags
	case states.EachList:
		length := 0
		for k := range rs.Instances {
			if ik, ok := k.(addrs.IntKey); ok {
				if int(ik) >= length {
					length = int(ik) + 1
				}
			}
		}
		vals := make([]cty.Value, length)
		for i := 0; i < length; i++ {
			ty := schema.ImpliedType()
			key := addrs.IntKey(i)
			is := rs.Instances[key]
			if is == nil || is.Current == nil {
				vals[i] = cty.UnknownVal(schema.ImpliedType())
				continue
			}
			instAddr := addr.Instance(key).Absolute(d.ModulePath)
			if is.Current.Status == states.ObjectPlanned {
				if change := d.Evaluator.Changes.GetResourceInstanceChange(instAddr, states.CurrentGen); change != nil {
					val, err := change.After.Decode(ty)
					if err != nil {
						diags = diags.Append(&hcl.Diagnostic{
							Severity: hcl.DiagError,
							Summary:  "Invalid resource instance data in plan",
							Detail:   fmt.Sprintf("Instance %s data could not be decoded from the plan: %s.", instAddr, err),
							Subject:  &config.DeclRange,
						})
						continue
					}
					vals[i] = val
					continue
				} else {
					diags = diags.Append(&hcl.Diagnostic{
						Severity: hcl.DiagError,
						Summary:  "Missing pending object in plan",
						Detail:   fmt.Sprintf("Instance %s is marked as having a change pending but that change is not recorded in the plan. This is a bug in Terraform; please report it.", instAddr),
						Subject:  &config.DeclRange,
					})
					continue
				}
			}
			ios, err := is.Current.Decode(ty)
			if err != nil {
				diags = diags.Append(&hcl.Diagnostic{
					Severity: hcl.DiagError,
					Summary:  "Invalid resource instance data in state",
					Detail:   fmt.Sprintf("Instance %s data could not be decoded from the state: %s.", instAddr, err),
					Subject:  &config.DeclRange,
				})
				continue
			}
			vals[i] = ios.Value
		}
		return cty.TupleVal(vals), diags
	case states.EachMap:
		ty := schema.ImpliedType()
		vals := make(map[string]cty.Value, len(rs.Instances))
		for k, is := range rs.Instances {
			if sk, ok := k.(addrs.StringKey); ok {
				if is == nil || is.Current == nil {
					vals[string(sk)] = cty.UnknownVal(schema.ImpliedType())
					continue
				}
				instAddr := addr.Instance(k).Absolute(d.ModulePath)
				if is.Current.Status == states.ObjectPlanned {
					if change := d.Evaluator.Changes.GetResourceInstanceChange(instAddr, states.CurrentGen); change != nil {
						val, err := change.After.Decode(ty)
						if err != nil {
							diags = diags.Append(&hcl.Diagnostic{
								Severity: hcl.DiagError,
								Summary:  "Invalid resource instance data in plan",
								Detail:   fmt.Sprintf("Instance %s data could not be decoded from the plan: %s.", instAddr, err),
								Subject:  &config.DeclRange,
							})
							continue
						}
						vals[string(sk)] = val
						continue
					} else {
						diags = diags.Append(&hcl.Diagnostic{
							Severity: hcl.DiagError,
							Summary:  "Missing pending object in plan",
							Detail:   fmt.Sprintf("Instance %s is marked as having a change pending but that change is not recorded in the plan. This is a bug in Terraform; please report it.", instAddr),
							Subject:  &config.DeclRange,
						})
						continue
					}
				}
				ios, err := is.Current.Decode(ty)
				if err != nil {
					diags = diags.Append(&hcl.Diagnostic{
						Severity: hcl.DiagError,
						Summary:  "Invalid resource instance data in state",
						Detail:   fmt.Sprintf("Instance %s data could not be decoded from the state: %s.", instAddr, err),
						Subject:  &config.DeclRange,
					})
					continue
				}
				vals[string(sk)] = ios.Value
			}
		}
		return cty.ObjectVal(vals), diags
	default:
		panic(fmt.Sprintf("unsupported EachMode %s", rs.EachMode))
	}
}
func (d *evaluationStateData) getResourceSchema(addr addrs.Resource, providerAddr addrs.AbsProviderConfig) *configschema.Block {
	providerType := providerAddr.ProviderConfig.Type.LegacyString()
	schemas := d.Evaluator.Schemas
	schema, _ := schemas.ResourceTypeConfig(providerType, addr.Mode, addr.Type)
	return schema
}
func (d *evaluationStateData) coerceInstanceKey(key addrs.InstanceKey, mode states.EachMode) addrs.InstanceKey {
	if key == addrs.NoKey {
		return key
	}
	switch mode {
	case states.NoEach:
		return key
	case states.EachMap:
		if intKey, isInt := key.(addrs.IntKey); isInt {
			return addrs.StringKey(strconv.Itoa(int(intKey)))
		}
		return key
	case states.EachList:
		if strKey, isStr := key.(addrs.StringKey); isStr {
			i, err := strconv.Atoi(string(strKey))
			if err != nil {
				return key
			}
			return addrs.IntKey(i)
		}
		return key
	default:
		return key
	}
}
func (d *evaluationStateData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	switch addr.Name {
	case "workspace":
		workspaceName := d.Evaluator.Meta.Env
		return cty.StringVal(workspaceName), diags
	case "env":
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Invalid "terraform" attribute`,
			Detail:   `The terraform.env attribute was deprecated in v0.10 and removed in v0.12. The "state environment" concept was rename to "workspace" in v0.12, and so the workspace name can now be accessed using the terraform.workspace attribute.`,
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	default:
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  `Invalid "terraform" attribute`,
			Detail:   fmt.Sprintf(`The "terraform" object does not have an attribute named %q. The only supported attribute is terraform.workspace, the name of the currently-selected workspace.`, addr.Name),
			Subject:  rng.ToHCL().Ptr(),
		})
		return cty.DynamicVal, diags
	}
}
func nameSuggestion(given string, suggestions []string) string {
	for _, suggestion := range suggestions {
		dist := levenshtein.Distance(given, suggestion, nil)
		if dist < 3 {  
			return suggestion
		}
	}
	return ""
}