package dagro

import (
	
	
	
	
)

func jsTruthyNumber( float64) bool {
	return  != 0 && !math.IsNaN()
}

// mathMinJS and mathMaxJS model JavaScript's Math.min and Math.max. Unlike
// Lodash's extrema helpers, Math propagates NaN if any argument is NaN.
func mathMinJS( ...float64) float64 {
	if len() == 0 {
		return math.Inf(1)
	}
	 := [0]
	for ,  := range [1:] {
		if math.IsNaN() || math.IsNaN() {
			return math.NaN()
		}
		 = math.Min(, )
	}
	return 
}

func mathMaxJS( ...float64) float64 {
	if len() == 0 {
		return math.Inf(-1)
	}
	 := [0]
	for ,  := range [1:] {
		if math.IsNaN() || math.IsNaN() {
			return math.NaN()
		}
		 = math.Max(, )
	}
	return 
}

// lodashMinJS and lodashMaxJS model the Lodash 4 extrema helpers used by
// Dagre. Lodash skips undefined and NaN values rather than propagating NaN.
// A NaN return represents Lodash's undefined result when no numeric value is
// present.
func lodashMinJS( ...float64) float64 {
	 := math.NaN()
	 := false
	for ,  := range  {
		if math.IsNaN() {
			continue
		}
		if ! ||  <  {
			 = 
			 = true
		}
	}
	return 
}

func lodashMaxJS( ...float64) float64 {
	 := math.NaN()
	 := false
	for ,  := range  {
		if math.IsNaN() {
			continue
		}
		if ! ||  >  {
			 = 
			 = true
		}
	}
	return 
}

// jsConcatString covers the primitive values Dagre concatenates into debug
// identifiers. In particular, JavaScript distinguishes an absent property
// (handled by the caller as "undefined") from an explicit null value.
func jsConcatString( any) string {
	switch value := .(type) {
	case nil:
		return "null"
	case string:
		return 
	case bool:
		return strconv.FormatBool()
	case float64:
		return jsNumberString()
	case float32:
		return jsNumberString(float64())
	case int:
		return strconv.Itoa()
	case int8:
		return strconv.FormatInt(int64(), 10)
	case int16:
		return strconv.FormatInt(int64(), 10)
	case int32:
		return strconv.FormatInt(int64(), 10)
	case int64:
		return strconv.FormatInt(, 10)
	case uint:
		return strconv.FormatUint(uint64(), 10)
	case uint8:
		return strconv.FormatUint(uint64(), 10)
	case uint16:
		return strconv.FormatUint(uint64(), 10)
	case uint32:
		return strconv.FormatUint(uint64(), 10)
	case uint64:
		return strconv.FormatUint(, 10)
	default:
		return fmt.Sprint()
	}
}

func jsNumberString( float64) string {
	switch {
	case math.IsNaN():
		return "NaN"
	case math.IsInf(, 1):
		return "Infinity"
	case math.IsInf(, -1):
		return "-Infinity"
	case  == 0:
		return "0"
	}

	 := math.Abs()
	if  >= 1e-6 &&  < 1e21 {
		return strconv.FormatFloat(, 'f', -1, 64)
	}

	 := strconv.FormatFloat(, 'e', -1, 64)
	, ,  := strings.Cut(, "e")
	if ! {
		return 
	}
	 := ""
	if strings.HasPrefix(, "+") || strings.HasPrefix(, "-") {
		,  = [:1], [1:]
	}
	 = strings.TrimLeft(, "0")
	if  == "" {
		 = "0"
	}
	return  + "e" +  + 
}