package  jsonimport  (	"bytes" 	"cmp" 	"encoding" 	"encoding/base64" 	"fmt" 	"math" 	"reflect" 	"slices" 	"strconv" 	"strings" 	"sync" 	"unicode" 	"unicode/utf8" 	_  "unsafe" )func  Marshal v  any ) ([]byte , error ) {	e  := newEncodeState ()	defer  encodeStatePool .Put (e )	err  := e .marshal (v , encOpts {escapeHTML : true })	if  err  != nil  {		return  nil , err 	}	buf  := append ([]byte (nil ), e .Bytes ()...)	return  buf , nil }func  MarshalIndent v  any , prefix , indent  string ) ([]byte , error ) {	b , err  := Marshal (v )	if  err  != nil  {		return  nil , err 	}	b2  := make ([]byte , 0 , indentGrowthFactor *len (b ))	b2 , err  = appendIndent (b2 , b , prefix , indent )	if  err  != nil  {		return  nil , err 	}	return  b2 , nil }type  Marshaler  interface  {	MarshalJSON () ([]byte , error )}type  UnsupportedTypeError  struct  {	Type  reflect .Type }func  (e  *UnsupportedTypeError ) Error string  {	return  "json: unsupported type: "  + e .Type .String ()}type  UnsupportedValueError  struct  {	Value  reflect .Value 	Str    string }func  (e  *UnsupportedValueError ) Error string  {	return  "json: unsupported value: "  + e .Str }type  InvalidUTF8Error  struct  {	S  string  }func  (e  *InvalidUTF8Error ) Error string  {	return  "json: invalid UTF-8 in string: "  + strconv .Quote (e .S )}type  MarshalerError  struct  {	Type        reflect .Type 	Err         error 	sourceFunc  string }func  (e  *MarshalerError ) Error string  {	srcFunc  := e .sourceFunc 	if  srcFunc  == ""  {		srcFunc  = "MarshalJSON" 	}	return  "json: error calling "  + srcFunc  +		" for type "  + e .Type .String () +		": "  + e .Err .Error()}func  (e  *MarshalerError ) Unwrap error  { return  e .Err  }const  hex  = "0123456789abcdef" type  encodeState  struct  {	bytes .Buffer  		ptrLevel  uint 	ptrSeen   map [any ]struct {}}const  startDetectingCyclesAfter  = 1000 var  encodeStatePool  sync .Pool func  newEncodeState encodeState  {	if  v  := encodeStatePool .Get (); v  != nil  {		e  := v .(*encodeState )		e .Reset ()		if  len (e .ptrSeen ) > 0  {			panic ("ptrEncoder.encode should have emptied ptrSeen via defers" )		}		e .ptrLevel  = 0 		return  e 	}	return  &encodeState {ptrSeen : make (map [any ]struct {})}}type  jsonError  struct { error  }func  (e  *encodeState ) marshal v  any , opts  encOpts ) (err  error ) {	defer  func () {		if  r  := recover (); r  != nil  {			if  je , ok  := r .(jsonError ); ok  {				err  = je .error 			} else  {				panic (r )			}		}	}()	e .reflectValue (reflect .ValueOf (v ), opts )	return  nil }func  (e  *encodeState ) error err  error ) {	panic (jsonError {err })}func  isEmptyValue v  reflect .Value ) bool  {	switch  v .Kind () {	case  reflect .Array , reflect .Map , reflect .Slice , reflect .String :		return  v .Len () == 0 	case  reflect .Bool ,		reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 ,		reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr ,		reflect .Float32 , reflect .Float64 ,		reflect .Interface , reflect .Pointer :		return  v .IsZero ()	}	return  false }func  (e  *encodeState ) reflectValue v  reflect .Value , opts  encOpts ) {	valueEncoder (v )(e , v , opts )}type  encOpts  struct  {		quoted  bool 		escapeHTML  bool }type  encoderFunc  func (e *encodeState , v reflect .Value , opts encOpts )var  encoderCache  sync .Map  func  valueEncoder v  reflect .Value ) encoderFunc  {	if  !v .IsValid () {		return  invalidValueEncoder 	}	return  typeEncoder (v .Type ())}func  typeEncoder t  reflect .Type ) encoderFunc  {	if  fi , ok  := encoderCache .Load (t ); ok  {		return  fi .(encoderFunc )	}		var  (		wg  sync .WaitGroup 		f   encoderFunc 	)	wg .Add (1 )	fi , loaded  := encoderCache .LoadOrStore (t , encoderFunc (func (e  *encodeState , v  reflect .Value , opts  encOpts ) {		wg .Wait ()		f (e , v , opts )	}))	if  loaded  {		return  fi .(encoderFunc )	}		f  = newTypeEncoder (t , true )	wg .Done ()	encoderCache .Store (t , f )	return  f }var  (	marshalerType      = reflect .TypeFor [Marshaler ]()	textMarshalerType  = reflect .TypeFor [encoding .TextMarshaler ]())func  newTypeEncoder t  reflect .Type , allowAddr  bool ) encoderFunc  {		if  t .Kind () != reflect .Pointer  && allowAddr  && reflect .PointerTo (t ).Implements (marshalerType ) {		return  newCondAddrEncoder (addrMarshalerEncoder , newTypeEncoder (t , false ))	}	if  t .Implements (marshalerType ) {		return  marshalerEncoder 	}	if  t .Kind () != reflect .Pointer  && allowAddr  && reflect .PointerTo (t ).Implements (textMarshalerType ) {		return  newCondAddrEncoder (addrTextMarshalerEncoder , newTypeEncoder (t , false ))	}	if  t .Implements (textMarshalerType ) {		return  textMarshalerEncoder 	}	switch  t .Kind () {	case  reflect .Bool :		return  boolEncoder 	case  reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :		return  intEncoder 	case  reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr :		return  uintEncoder 	case  reflect .Float32 :		return  float32Encoder 	case  reflect .Float64 :		return  float64Encoder 	case  reflect .String :		return  stringEncoder 	case  reflect .Interface :		return  interfaceEncoder 	case  reflect .Struct :		return  newStructEncoder (t )	case  reflect .Map :		return  newMapEncoder (t )	case  reflect .Slice :		return  newSliceEncoder (t )	case  reflect .Array :		return  newArrayEncoder (t )	case  reflect .Pointer :		return  newPtrEncoder (t )	default :		return  unsupportedTypeEncoder 	}}func  invalidValueEncoder e  *encodeState , v  reflect .Value , _  encOpts ) {	e .WriteString ("null" )}func  marshalerEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	if  v .Kind () == reflect .Pointer  && v .IsNil () {		e .WriteString ("null" )		return 	}	m , ok  := v .Interface ().(Marshaler )	if  !ok  {		e .WriteString ("null" )		return 	}	b , err  := m .MarshalJSON ()	if  err  == nil  {		e .Grow (len (b ))		out  := e .AvailableBuffer ()		out , err  = appendCompact (out , b , opts .escapeHTML )		e .Buffer .Write (out )	}	if  err  != nil  {		e .error (&MarshalerError {v .Type (), err , "MarshalJSON" })	}}func  addrMarshalerEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	va  := v .Addr ()	if  va .IsNil () {		e .WriteString ("null" )		return 	}	m  := va .Interface ().(Marshaler )	b , err  := m .MarshalJSON ()	if  err  == nil  {		e .Grow (len (b ))		out  := e .AvailableBuffer ()		out , err  = appendCompact (out , b , opts .escapeHTML )		e .Buffer .Write (out )	}	if  err  != nil  {		e .error (&MarshalerError {v .Type (), err , "MarshalJSON" })	}}func  textMarshalerEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	if  v .Kind () == reflect .Pointer  && v .IsNil () {		e .WriteString ("null" )		return 	}	m , ok  := v .Interface ().(encoding .TextMarshaler )	if  !ok  {		e .WriteString ("null" )		return 	}	b , err  := m .MarshalText ()	if  err  != nil  {		e .error (&MarshalerError {v .Type (), err , "MarshalText" })	}	e .Write (appendString (e .AvailableBuffer (), b , opts .escapeHTML ))}func  addrTextMarshalerEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	va  := v .Addr ()	if  va .IsNil () {		e .WriteString ("null" )		return 	}	m  := va .Interface ().(encoding .TextMarshaler )	b , err  := m .MarshalText ()	if  err  != nil  {		e .error (&MarshalerError {v .Type (), err , "MarshalText" })	}	e .Write (appendString (e .AvailableBuffer (), b , opts .escapeHTML ))}func  boolEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	b  := e .AvailableBuffer ()	b  = mayAppendQuote (b , opts .quoted )	b  = strconv .AppendBool (b , v .Bool ())	b  = mayAppendQuote (b , opts .quoted )	e .Write (b )}func  intEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	b  := e .AvailableBuffer ()	b  = mayAppendQuote (b , opts .quoted )	b  = strconv .AppendInt (b , v .Int (), 10 )	b  = mayAppendQuote (b , opts .quoted )	e .Write (b )}func  uintEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	b  := e .AvailableBuffer ()	b  = mayAppendQuote (b , opts .quoted )	b  = strconv .AppendUint (b , v .Uint (), 10 )	b  = mayAppendQuote (b , opts .quoted )	e .Write (b )}type  floatEncoder  int  func  (bits  floatEncoder ) encode e  *encodeState , v  reflect .Value , opts  encOpts ) {	f  := v .Float ()	if  math .IsInf (f , 0 ) || math .IsNaN (f ) {		e .error (&UnsupportedValueError {v , strconv .FormatFloat (f , 'g' , -1 , int (bits ))})	}		b  := e .AvailableBuffer ()	b  = mayAppendQuote (b , opts .quoted )	abs  := math .Abs (f )	fmt  := byte ('f' )		if  abs  != 0  {		if  bits  == 64  && (abs  < 1e-6  || abs  >= 1e21 ) || bits  == 32  && (float32 (abs ) < 1e-6  || float32 (abs ) >= 1e21 ) {			fmt  = 'e' 		}	}	b  = strconv .AppendFloat (b , f , fmt , -1 , int (bits ))	if  fmt  == 'e'  {				n  := len (b )		if  n  >= 4  && b [n -4 ] == 'e'  && b [n -3 ] == '-'  && b [n -2 ] == '0'  {			b [n -2 ] = b [n -1 ]			b  = b [:n -1 ]		}	}	b  = mayAppendQuote (b , opts .quoted )	e .Write (b )}var  (	float32Encoder  = (floatEncoder (32 )).encode 	float64Encoder  = (floatEncoder (64 )).encode )func  stringEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	if  v .Type () == numberType  {		numStr  := v .String ()				if  numStr  == ""  {			numStr  = "0"  		}		if  !isValidNumber (numStr ) {			e .error (fmt .Errorf ("json: invalid number literal %q" , numStr ))		}		b  := e .AvailableBuffer ()		b  = mayAppendQuote (b , opts .quoted )		b  = append (b , numStr ...)		b  = mayAppendQuote (b , opts .quoted )		e .Write (b )		return 	}	if  opts .quoted  {		b  := appendString (nil , v .String (), opts .escapeHTML )		e .Write (appendString (e .AvailableBuffer (), b , false )) 	} else  {		e .Write (appendString (e .AvailableBuffer (), v .String (), opts .escapeHTML ))	}}func  isValidNumber s  string ) bool  {		if  s  == ""  {		return  false 	}		if  s [0 ] == '-'  {		s  = s [1 :]		if  s  == ""  {			return  false 		}	}		switch  {	default :		return  false 	case  s [0 ] == '0' :		s  = s [1 :]	case  '1'  <= s [0 ] && s [0 ] <= '9' :		s  = s [1 :]		for  len (s ) > 0  && '0'  <= s [0 ] && s [0 ] <= '9'  {			s  = s [1 :]		}	}		if  len (s ) >= 2  && s [0 ] == '.'  && '0'  <= s [1 ] && s [1 ] <= '9'  {		s  = s [2 :]		for  len (s ) > 0  && '0'  <= s [0 ] && s [0 ] <= '9'  {			s  = s [1 :]		}	}		if  len (s ) >= 2  && (s [0 ] == 'e'  || s [0 ] == 'E' ) {		s  = s [1 :]		if  s [0 ] == '+'  || s [0 ] == '-'  {			s  = s [1 :]			if  s  == ""  {				return  false 			}		}		for  len (s ) > 0  && '0'  <= s [0 ] && s [0 ] <= '9'  {			s  = s [1 :]		}	}		return  s  == "" }func  interfaceEncoder e  *encodeState , v  reflect .Value , opts  encOpts ) {	if  v .IsNil () {		e .WriteString ("null" )		return 	}	e .reflectValue (v .Elem (), opts )}func  unsupportedTypeEncoder e  *encodeState , v  reflect .Value , _  encOpts ) {	e .error (&UnsupportedTypeError {v .Type ()})}type  structEncoder  struct  {	fields  structFields }type  structFields  struct  {	list          []field 	byExactName   map [string ]*field 	byFoldedName  map [string ]*field }func  (se  structEncoder ) encode e  *encodeState , v  reflect .Value , opts  encOpts ) {	next  := byte ('{' )FieldLoop :	for  i  := range  se .fields .list  {		f  := &se .fields .list [i ]				fv  := v 		for  _ , i  := range  f .index  {			if  fv .Kind () == reflect .Pointer  {				if  fv .IsNil () {					continue  FieldLoop 				}				fv  = fv .Elem ()			}			fv  = fv .Field (i )		}		if  f .omitEmpty  && isEmptyValue (fv ) {			continue 		}		e .WriteByte (next )		next  = ',' 		if  opts .escapeHTML  {			e .WriteString (f .nameEscHTML )		} else  {			e .WriteString (f .nameNonEsc )		}		opts .quoted  = f .quoted 		f .encoder (e , fv , opts )	}	if  next  == '{'  {		e .WriteString ("{}" )	} else  {		e .WriteByte ('}' )	}}func  newStructEncoder t  reflect .Type ) encoderFunc  {	se  := structEncoder {fields : cachedTypeFields (t )}	return  se .encode }type  mapEncoder  struct  {	elemEnc  encoderFunc }func  (me  mapEncoder ) encode e  *encodeState , v  reflect .Value , opts  encOpts ) {	if  v .IsNil () {		e .WriteString ("null" )		return 	}	if  e .ptrLevel ++; e .ptrLevel  > startDetectingCyclesAfter  {				ptr  := v .UnsafePointer ()		if  _ , ok  := e .ptrSeen [ptr ]; ok  {			e .error (&UnsupportedValueError {v , fmt .Sprintf ("encountered a cycle via %s" , v .Type ())})		}		e .ptrSeen [ptr ] = struct {}{}		defer  delete (e .ptrSeen , ptr )	}	e .WriteByte ('{' )		var  (		sv   = make ([]reflectWithString , v .Len ())		mi   = v .MapRange ()		err  error 	)	for  i  := 0 ; mi .Next (); i ++ {		if  sv [i ].ks , err  = resolveKeyName (mi .Key ()); err  != nil  {			e .error (fmt .Errorf ("json: encoding error for type %q: %q" , v .Type ().String (), err .Error()))		}		sv [i ].v  = mi .Value ()	}	slices .SortFunc (sv , func (i , j  reflectWithString ) int  {		return  strings .Compare (i .ks , j .ks )	})	for  i , kv  := range  sv  {		if  i  > 0  {			e .WriteByte (',' )		}		e .Write (appendString (e .AvailableBuffer (), kv .ks , opts .escapeHTML ))		e .WriteByte (':' )		me .elemEnc (e , kv .v , opts )	}	e .WriteByte ('}' )	e .ptrLevel --}func  newMapEncoder t  reflect .Type ) encoderFunc  {	switch  t .Key ().Kind () {	case  reflect .String ,		reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 ,		reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr :	default :		if  !t .Key ().Implements (textMarshalerType ) {			return  unsupportedTypeEncoder 		}	}	me  := mapEncoder {typeEncoder (t .Elem ())}	return  me .encode }func  encodeByteSlice e  *encodeState , v  reflect .Value , _  encOpts ) {	if  v .IsNil () {		e .WriteString ("null" )		return 	}	s  := v .Bytes ()	b  := e .AvailableBuffer ()	b  = append (b , '"' )	b  = base64 .StdEncoding .AppendEncode (b , s )	b  = append (b , '"' )	e .Write (b )}type  sliceEncoder  struct  {	arrayEnc  encoderFunc }func  (se  sliceEncoder ) encode e  *encodeState , v  reflect .Value , opts  encOpts ) {	if  v .IsNil () {		e .WriteString ("null" )		return 	}	if  e .ptrLevel ++; e .ptrLevel  > startDetectingCyclesAfter  {				ptr  := struct  {			ptr  interface {} 			len  int 		}{v .UnsafePointer (), v .Len ()}		if  _ , ok  := e .ptrSeen [ptr ]; ok  {			e .error (&UnsupportedValueError {v , fmt .Sprintf ("encountered a cycle via %s" , v .Type ())})		}		e .ptrSeen [ptr ] = struct {}{}		defer  delete (e .ptrSeen , ptr )	}	se .arrayEnc (e , v , opts )	e .ptrLevel --}func  newSliceEncoder t  reflect .Type ) encoderFunc  {		if  t .Elem ().Kind () == reflect .Uint8  {		p  := reflect .PointerTo (t .Elem ())		if  !p .Implements (marshalerType ) && !p .Implements (textMarshalerType ) {			return  encodeByteSlice 		}	}	enc  := sliceEncoder {newArrayEncoder (t )}	return  enc .encode }type  arrayEncoder  struct  {	elemEnc  encoderFunc }func  (ae  arrayEncoder ) encode e  *encodeState , v  reflect .Value , opts  encOpts ) {	e .WriteByte ('[' )	n  := v .Len ()	for  i  := 0 ; i  < n ; i ++ {		if  i  > 0  {			e .WriteByte (',' )		}		ae .elemEnc (e , v .Index (i ), opts )	}	e .WriteByte (']' )}func  newArrayEncoder t  reflect .Type ) encoderFunc  {	enc  := arrayEncoder {typeEncoder (t .Elem ())}	return  enc .encode }type  ptrEncoder  struct  {	elemEnc  encoderFunc }func  (pe  ptrEncoder ) encode e  *encodeState , v  reflect .Value , opts  encOpts ) {	if  v .IsNil () {		e .WriteString ("null" )		return 	}	if  e .ptrLevel ++; e .ptrLevel  > startDetectingCyclesAfter  {				ptr  := v .Interface ()		if  _ , ok  := e .ptrSeen [ptr ]; ok  {			e .error (&UnsupportedValueError {v , fmt .Sprintf ("encountered a cycle via %s" , v .Type ())})		}		e .ptrSeen [ptr ] = struct {}{}		defer  delete (e .ptrSeen , ptr )	}	pe .elemEnc (e , v .Elem (), opts )	e .ptrLevel --}func  newPtrEncoder t  reflect .Type ) encoderFunc  {	enc  := ptrEncoder {typeEncoder (t .Elem ())}	return  enc .encode }type  condAddrEncoder  struct  {	canAddrEnc , elseEnc  encoderFunc }func  (ce  condAddrEncoder ) encode e  *encodeState , v  reflect .Value , opts  encOpts ) {	if  v .CanAddr () {		ce .canAddrEnc (e , v , opts )	} else  {		ce .elseEnc (e , v , opts )	}}func  newCondAddrEncoder canAddrEnc , elseEnc  encoderFunc ) encoderFunc  {	enc  := condAddrEncoder {canAddrEnc : canAddrEnc , elseEnc : elseEnc }	return  enc .encode }func  isValidTag s  string ) bool  {	if  s  == ""  {		return  false 	}	for  _ , c  := range  s  {		switch  {		case  strings .ContainsRune ("!#$%&()*+-./:;<=>?@[]^_{|}~ " , c ):					case  !unicode .IsLetter (c ) && !unicode .IsDigit (c ):			return  false 		}	}	return  true }func  typeByIndex t  reflect .Type , index  []int ) reflect .Type  {	for  _ , i  := range  index  {		if  t .Kind () == reflect .Pointer  {			t  = t .Elem ()		}		t  = t .Field (i ).Type 	}	return  t }type  reflectWithString  struct  {	v   reflect .Value 	ks  string }func  resolveKeyName k  reflect .Value ) (string , error ) {	if  k .Kind () == reflect .String  {		return  k .String (), nil 	}	if  tm , ok  := k .Interface ().(encoding .TextMarshaler ); ok  {		if  k .Kind () == reflect .Pointer  && k .IsNil () {			return  "" , nil 		}		buf , err  := tm .MarshalText ()		return  string (buf ), err 	}	switch  k .Kind () {	case  reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :		return  strconv .FormatInt (k .Int (), 10 ), nil 	case  reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr :		return  strconv .FormatUint (k .Uint (), 10 ), nil 	}	panic ("unexpected map key type" )}func  appendString Bytes  []byte  | string ](dst  []byte , src  Bytes , escapeHTML  bool ) []byte  {	dst  = append (dst , '"' )	start  := 0 	for  i  := 0 ; i  < len (src ); {		if  b  := src [i ]; b  < utf8 .RuneSelf  {			if  htmlSafeSet [b ] || (!escapeHTML  && safeSet [b ]) {				i ++				continue 			}			dst  = append (dst , src [start :i ]...)			switch  b  {			case  '\\' , '"' :				dst  = append (dst , '\\' , b )			case  '\b' :				dst  = append (dst , '\\' , 'b' )			case  '\f' :				dst  = append (dst , '\\' , 'f' )			case  '\n' :				dst  = append (dst , '\\' , 'n' )			case  '\r' :				dst  = append (dst , '\\' , 'r' )			case  '\t' :				dst  = append (dst , '\\' , 't' )			default :								dst  = append (dst , '\\' , 'u' , '0' , '0' , hex [b >>4 ], hex [b &0xF ])			}			i ++			start  = i 			continue 		}				n  := len (src ) - i 		if  n  > utf8 .UTFMax  {			n  = utf8 .UTFMax 		}		c , size  := utf8 .DecodeRuneInString (string (src [i  : i +n ]))		if  c  == utf8 .RuneError  && size  == 1  {			dst  = append (dst , src [start :i ]...)			dst  = append (dst , `\ufffd` ...)			i  += size 			start  = i 			continue 		}				if  c  == '\u2028'  || c  == '\u2029'  {			dst  = append (dst , src [start :i ]...)			dst  = append (dst , '\\' , 'u' , '2' , '0' , '2' , hex [c &0xF ])			i  += size 			start  = i 			continue 		}		i  += size 	}	dst  = append (dst , src [start :]...)	dst  = append (dst , '"' )	return  dst }type  field  struct  {	name       string 	nameBytes  []byte  	nameNonEsc   string  	nameEscHTML  string  	tag        bool 	index      []int 	typ        reflect .Type 	omitEmpty  bool 	quoted     bool 	encoder  encoderFunc }func  typeFields t  reflect .Type ) structFields  {		current  := []field {}	next  := []field {{typ : t }}		var  count , nextCount  map [reflect .Type ]int 		visited  := map [reflect .Type ]bool {}		var  fields  []field 		var  nameEscBuf  []byte 	for  len (next ) > 0  {		current , next  = next , current [:0 ]		count , nextCount  = nextCount , map [reflect .Type ]int {}		for  _ , f  := range  current  {			if  visited [f .typ ] {				continue 			}			visited [f .typ ] = true 						for  i  := 0 ; i  < f .typ .NumField (); i ++ {				sf  := f .typ .Field (i )				if  sf .Anonymous  {					t  := sf .Type 					if  t .Kind () == reflect .Pointer  {						t  = t .Elem ()					}					if  !sf .IsExported () && t .Kind () != reflect .Struct  {												continue 					}									} else  if  !sf .IsExported () {										continue 				}				tag  := sf .Tag .Get ("json" )				if  tag  == "-"  {					continue 				}				name , opts  := parseTag (tag )				if  !isValidTag (name ) {					name  = "" 				}				index  := make ([]int , len (f .index )+1 )				copy (index , f .index )				index [len (f .index )] = i 				ft  := sf .Type 				if  ft .Name () == ""  && ft .Kind () == reflect .Pointer  {										ft  = ft .Elem ()				}								quoted  := false 				if  opts .Contains ("string" ) {					switch  ft .Kind () {					case  reflect .Bool ,						reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 ,						reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr ,						reflect .Float32 , reflect .Float64 ,						reflect .String :						quoted  = true 					}				}								if  name  != ""  || !sf .Anonymous  || ft .Kind () != reflect .Struct  {					tagged  := name  != "" 					if  name  == ""  {						name  = sf .Name 					}					field  := field {						name :      name ,						tag :       tagged ,						index :     index ,						typ :       ft ,						omitEmpty : opts .Contains ("omitempty" ),						quoted :    quoted ,					}					field .nameBytes  = []byte (field .name )										nameEscBuf  = appendHTMLEscape (nameEscBuf [:0 ], field .nameBytes )					field .nameEscHTML  = `"`  + string (nameEscBuf ) + `":` 					field .nameNonEsc  = `"`  + field .name  + `":` 					fields  = append (fields , field )					if  count [f .typ ] > 1  {												fields  = append (fields , fields [len (fields )-1 ])					}					continue 				}								nextCount [ft ]++				if  nextCount [ft ] == 1  {					next  = append (next , field {name : ft .Name (), index : index , typ : ft })				}			}		}	}	slices .SortFunc (fields , func (a , b  field ) int  {				if  c  := strings .Compare (a .name , b .name ); c  != 0  {			return  c 		}		if  c  := cmp .Compare (len (a .index ), len (b .index )); c  != 0  {			return  c 		}		if  a .tag  != b .tag  {			if  a .tag  {				return  -1 			}			return  +1 		}		return  slices .Compare (a .index , b .index )	})			out  := fields [:0 ]	for  advance , i  := 0 , 0 ; i  < len (fields ); i  += advance  {				fi  := fields [i ]		name  := fi .name 		for  advance  = 1 ; i +advance  < len (fields ); advance ++ {			fj  := fields [i +advance ]			if  fj .name  != name  {				break 			}		}		if  advance  == 1  { 			out  = append (out , fi )			continue 		}		dominant , ok  := dominantField (fields [i  : i +advance ])		if  ok  {			out  = append (out , dominant )		}	}	fields  = out 	slices .SortFunc (fields , func (i , j  field ) int  {		return  slices .Compare (i .index , j .index )	})	for  i  := range  fields  {		f  := &fields [i ]		f .encoder  = typeEncoder (typeByIndex (t , f .index ))	}	exactNameIndex  := make (map [string ]*field , len (fields ))	foldedNameIndex  := make (map [string ]*field , len (fields ))	for  i , field  := range  fields  {		exactNameIndex [field .name ] = &fields [i ]				if  _ , ok  := foldedNameIndex [string (foldName (field .nameBytes ))]; !ok  {			foldedNameIndex [string (foldName (field .nameBytes ))] = &fields [i ]		}	}	return  structFields {fields , exactNameIndex , foldedNameIndex }}func  dominantField fields  []field ) (field , bool ) {		if  len (fields ) > 1  && len (fields [0 ].index ) == len (fields [1 ].index ) && fields [0 ].tag  == fields [1 ].tag  {		return  field {}, false 	}	return  fields [0 ], true }var  fieldCache  sync .Map  func  cachedTypeFields t  reflect .Type ) structFields  {	if  f , ok  := fieldCache .Load (t ); ok  {		return  f .(structFields )	}	f , _  := fieldCache .LoadOrStore (t , typeFields (t ))	return  f .(structFields )}func  mayAppendQuote b  []byte , quoted  bool ) []byte  {	if  quoted  {		b  = append (b , '"' )	}	return  b } The pages are generated with Golds v0.7.6 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .