package goja

import (
	
	
)

type destructKeyedSource struct {
	r        *Runtime
	wrapped  Value
	usedKeys map[Value]struct{}
}

func newDestructKeyedSource( *Runtime,  Value) *destructKeyedSource {
	return &destructKeyedSource{
		r:       ,
		wrapped: ,
	}
}

func ( *Runtime) ( Value) *Object {
	return &Object{
		runtime: ,
		self:    newDestructKeyedSource(, ),
	}
}

func ( *destructKeyedSource) () objectImpl {
	return .wrapped.ToObject(.r).self
}

func ( *destructKeyedSource) ( Value) {
	if .usedKeys == nil {
		.usedKeys = make(map[Value]struct{})
	}
	.usedKeys[] = struct{}{}
}

func ( *destructKeyedSource) () int {
	return .w().sortLen()
}

func ( *destructKeyedSource) ( int) Value {
	return .w().sortGet()
}

func ( *destructKeyedSource) ( int,  int) {
	.w().swap(, )
}

func ( *destructKeyedSource) () string {
	return .w().className()
}

func ( *destructKeyedSource) () String {
	return .w().typeOf()
}

func ( *destructKeyedSource) ( unistring.String,  Value) Value {
	.recordKey(stringValueFromRaw())
	return .w().getStr(, )
}

func ( *destructKeyedSource) ( valueInt,  Value) Value {
	.recordKey(.toString())
	return .w().getIdx(, )
}

func ( *destructKeyedSource) ( *Symbol,  Value) Value {
	.recordKey()
	return .w().getSym(, )
}

func ( *destructKeyedSource) ( unistring.String) Value {
	.recordKey(stringValueFromRaw())
	return .w().getOwnPropStr()
}

func ( *destructKeyedSource) ( valueInt) Value {
	.recordKey(.toString())
	return .w().getOwnPropIdx()
}

func ( *destructKeyedSource) ( *Symbol) Value {
	.recordKey()
	return .w().getOwnPropSym()
}

func ( *destructKeyedSource) ( unistring.String,  Value,  bool) bool {
	return .w().setOwnStr(, , )
}

func ( *destructKeyedSource) ( valueInt,  Value,  bool) bool {
	return .w().setOwnIdx(, , )
}

func ( *destructKeyedSource) ( *Symbol,  Value,  bool) bool {
	return .w().setOwnSym(, , )
}

func ( *destructKeyedSource) ( unistring.String, ,  Value,  bool) ( bool,  bool) {
	return .w().setForeignStr(, , , )
}

func ( *destructKeyedSource) ( valueInt, ,  Value,  bool) ( bool,  bool) {
	return .w().setForeignIdx(, , , )
}

func ( *destructKeyedSource) ( *Symbol, ,  Value,  bool) ( bool,  bool) {
	return .w().setForeignSym(, , , )
}

func ( *destructKeyedSource) ( unistring.String) bool {
	return .w().hasPropertyStr()
}

func ( *destructKeyedSource) ( valueInt) bool {
	return .w().hasPropertyIdx()
}

func ( *destructKeyedSource) ( *Symbol) bool {
	return .w().hasPropertySym()
}

func ( *destructKeyedSource) ( unistring.String) bool {
	return .w().hasOwnPropertyStr()
}

func ( *destructKeyedSource) ( valueInt) bool {
	return .w().hasOwnPropertyIdx()
}

func ( *destructKeyedSource) ( *Symbol) bool {
	return .w().hasOwnPropertySym()
}

func ( *destructKeyedSource) ( unistring.String,  PropertyDescriptor,  bool) bool {
	return .w().defineOwnPropertyStr(, , )
}

func ( *destructKeyedSource) ( valueInt,  PropertyDescriptor,  bool) bool {
	return .w().defineOwnPropertyIdx(, , )
}

func ( *destructKeyedSource) ( *Symbol,  PropertyDescriptor,  bool) bool {
	return .w().defineOwnPropertySym(, , )
}

func ( *destructKeyedSource) ( unistring.String,  bool) bool {
	return .w().deleteStr(, )
}

func ( *destructKeyedSource) ( valueInt,  bool) bool {
	return .w().deleteIdx(, )
}

func ( *destructKeyedSource) ( *Symbol,  bool) bool {
	return .w().deleteSym(, )
}

func ( *destructKeyedSource) () ( func(FunctionCall) Value,  bool) {
	return .w().assertCallable()
}

func ( *destructKeyedSource) ( *vm,  int) {
	.w().vmCall(, )
}

func ( *destructKeyedSource) () func( []Value,  *Object) *Object {
	return .w().assertConstructor()
}

func ( *destructKeyedSource) () *Object {
	return .w().proto()
}

func ( *destructKeyedSource) ( *Object,  bool) bool {
	return .w().setProto(, )
}

func ( *destructKeyedSource) ( Value) bool {
	return .w().hasInstance()
}

func ( *destructKeyedSource) () bool {
	return .w().isExtensible()
}

func ( *destructKeyedSource) ( bool) bool {
	return .w().preventExtensions()
}

type destructKeyedSourceIter struct {
	d       *destructKeyedSource
	wrapped iterNextFunc
}

func ( *destructKeyedSourceIter) () (propIterItem, iterNextFunc) {
	for {
		,  := .wrapped()
		if  == nil {
			return , nil
		}
		.wrapped = 
		if ,  := .d.usedKeys[.name]; ! {
			return , .
		}
	}
}

func ( *destructKeyedSource) () iterNextFunc {
	return (&destructKeyedSourceIter{
		d:       ,
		wrapped: .w().iterateStringKeys(),
	}).next
}

func ( *destructKeyedSource) () iterNextFunc {
	return (&destructKeyedSourceIter{
		d:       ,
		wrapped: .w().iterateSymbols(),
	}).next
}

func ( *destructKeyedSource) () iterNextFunc {
	return (&destructKeyedSourceIter{
		d:       ,
		wrapped: .w().iterateKeys(),
	}).next
}

func ( *destructKeyedSource) ( *objectExportCtx) interface{} {
	return .w().export()
}

func ( *destructKeyedSource) () reflect.Type {
	return .w().exportType()
}

func ( *destructKeyedSource) ( reflect.Value,  reflect.Type,  *objectExportCtx) error {
	return .w().exportToMap(, , )
}

func ( *destructKeyedSource) ( reflect.Value,  reflect.Type,  *objectExportCtx) error {
	return .w().exportToArrayOrSlice(, , )
}

func ( *destructKeyedSource) ( objectImpl) bool {
	return .w().equal()
}

func ( *destructKeyedSource) ( bool,  []Value) []Value {
	var  iterNextFunc
	if  {
		 = .iterateStringKeys()
	} else {
		 = (&enumerableIter{
			o:       .wrapped.ToObject(.r),
			wrapped: .iterateStringKeys(),
		}).next
	}
	for ,  := ();  != nil; ,  = () {
		 = append(, .name)
	}
	return 
}

func ( *destructKeyedSource) ( []Value) []Value {
	 := 0
	for ,  := range  {
		if ,  := .usedKeys[];  {
			continue
		}
		if  !=  {
			[] = 
		}
		++
	}
	return [:]
}

func ( *destructKeyedSource) ( bool,  []Value) []Value {
	return .filterUsedKeys(.w().symbols(, ))
}

func ( *destructKeyedSource) ( bool,  []Value) []Value {
	return .filterUsedKeys(.w().keys(, ))
}

func ( *destructKeyedSource) ( unistring.String,  Value, , ,  bool) Value {
	return .w()._putProp(, , , , )
}

func ( *destructKeyedSource) ( *Symbol,  Value) {
	.w()._putSym(, )
}

func ( *destructKeyedSource) ( *privateEnvType,  bool) *privateElements {
	return .w().getPrivateEnv(, )
}