# automatically generated by the FlatBuffers compiler, do not modify

# namespace: Example

import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()

# Composite components of Monster color.
class Color(object):
    Red = 1
    # \brief color Green
    # Green is bit_flag with value (1u << 1)
    Green = 2
    # \brief color Blue (1u << 3)
    Blue = 8


class Race(object):
    None_ = -1
    Human = 0
    Dwarf = 1
    Elf = 2


class LongEnum(object):
    LongOne = 2
    LongTwo = 4
    LongBig = 1099511627776


class Any(object):
    NONE = 0
    Monster = 1
    TestSimpleTableWithEnum = 2
    MyGame_Example2_Monster = 3

def AnyCreator(unionType, table):
    from flatbuffers.table import Table
    if not isinstance(table, Table):
        return None
    if unionType == Any.Monster:
        return MonsterT.InitFromBuf(table.Bytes, table.Pos)
    if unionType == Any.TestSimpleTableWithEnum:
        return TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
    if unionType == Any.MyGame_Example2_Monster:
        return MonsterT.InitFromBuf(table.Bytes, table.Pos)
    return None


class AnyUniqueAliases(object):
    NONE = 0
    M = 1
    TS = 2
    M2 = 3

def AnyUniqueAliasesCreator(unionType, table):
    from flatbuffers.table import Table
    if not isinstance(table, Table):
        return None
    if unionType == AnyUniqueAliases.M:
        return MonsterT.InitFromBuf(table.Bytes, table.Pos)
    if unionType == AnyUniqueAliases.TS:
        return TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
    if unionType == AnyUniqueAliases.M2:
        return MonsterT.InitFromBuf(table.Bytes, table.Pos)
    return None


class AnyAmbiguousAliases(object):
    NONE = 0
    M1 = 1
    M2 = 2
    M3 = 3

def AnyAmbiguousAliasesCreator(unionType, table):
    from flatbuffers.table import Table
    if not isinstance(table, Table):
        return None
    if unionType == AnyAmbiguousAliases.M1:
        return MonsterT.InitFromBuf(table.Bytes, table.Pos)
    if unionType == AnyAmbiguousAliases.M2:
        return MonsterT.InitFromBuf(table.Bytes, table.Pos)
    if unionType == AnyAmbiguousAliases.M3:
        return MonsterT.InitFromBuf(table.Bytes, table.Pos)
    return None


class InParentNamespace(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = InParentNamespace()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsInParentNamespace(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def InParentNamespaceBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # InParentNamespace
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

def InParentNamespaceStart(builder):
    builder.StartObject(0)

def InParentNamespaceEnd(builder):
    return builder.EndObject()



class InParentNamespaceT(object):

    # InParentNamespaceT
    def __init__(
        self,
    ):
        pass

    @classmethod
    def InitFromBuf(cls, buf, pos):
        inParentNamespace = InParentNamespace()
        inParentNamespace.Init(buf, pos)
        return cls.InitFromObj(inParentNamespace)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, inParentNamespace):
        x = InParentNamespaceT()
        x._UnPack(inParentNamespace)
        return x

    # InParentNamespaceT
    def _UnPack(self, inParentNamespace):
        if inParentNamespace is None:
            return

    # InParentNamespaceT
    def Pack(self, builder):
        InParentNamespaceStart(builder)
        inParentNamespace = InParentNamespaceEnd(builder)
        return inParentNamespace


class Monster(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = Monster()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsMonster(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # Monster
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

def MonsterStart(builder):
    builder.StartObject(0)

def MonsterEnd(builder):
    return builder.EndObject()



class MonsterT(object):

    # MonsterT
    def __init__(
        self,
    ):
        pass

    @classmethod
    def InitFromBuf(cls, buf, pos):
        monster = Monster()
        monster.Init(buf, pos)
        return cls.InitFromObj(monster)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, monster):
        x = MonsterT()
        x._UnPack(monster)
        return x

    # MonsterT
    def _UnPack(self, monster):
        if monster is None:
            return

    # MonsterT
    def Pack(self, builder):
        MonsterStart(builder)
        monster = MonsterEnd(builder)
        return monster


class Test(object):
    __slots__ = ['_tab']

    @classmethod
    def SizeOf(cls):
        return 4

    # Test
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # Test
    def A(self): return self._tab.Get(flatbuffers.number_types.Int16Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
    # Test
    def B(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(2))

def CreateTest(builder, a, b):
    builder.Prep(2, 4)
    builder.Pad(1)
    builder.PrependInt8(b)
    builder.PrependInt16(a)
    return builder.Offset()


class TestT(object):

    # TestT
    def __init__(
        self,
        a = 0,
        b = 0,
    ):
        self.a = a  # type: int
        self.b = b  # type: int

    @classmethod
    def InitFromBuf(cls, buf, pos):
        test = Test()
        test.Init(buf, pos)
        return cls.InitFromObj(test)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, test):
        x = TestT()
        x._UnPack(test)
        return x

    # TestT
    def _UnPack(self, test):
        if test is None:
            return
        self.a = test.A()
        self.b = test.B()

    # TestT
    def Pack(self, builder):
        return CreateTest(builder, self.a, self.b)


class TestSimpleTableWithEnum(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = TestSimpleTableWithEnum()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsTestSimpleTableWithEnum(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def TestSimpleTableWithEnumBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # TestSimpleTableWithEnum
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # TestSimpleTableWithEnum
    def Color(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 2

def TestSimpleTableWithEnumStart(builder):
    builder.StartObject(1)

def TestSimpleTableWithEnumAddColor(builder, color):
    builder.PrependUint8Slot(0, color, 2)

def TestSimpleTableWithEnumEnd(builder):
    return builder.EndObject()



class TestSimpleTableWithEnumT(object):

    # TestSimpleTableWithEnumT
    def __init__(
        self,
        color = 2,
    ):
        self.color = color  # type: int

    @classmethod
    def InitFromBuf(cls, buf, pos):
        testSimpleTableWithEnum = TestSimpleTableWithEnum()
        testSimpleTableWithEnum.Init(buf, pos)
        return cls.InitFromObj(testSimpleTableWithEnum)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, testSimpleTableWithEnum):
        x = TestSimpleTableWithEnumT()
        x._UnPack(testSimpleTableWithEnum)
        return x

    # TestSimpleTableWithEnumT
    def _UnPack(self, testSimpleTableWithEnum):
        if testSimpleTableWithEnum is None:
            return
        self.color = testSimpleTableWithEnum.Color()

    # TestSimpleTableWithEnumT
    def Pack(self, builder):
        TestSimpleTableWithEnumStart(builder)
        TestSimpleTableWithEnumAddColor(builder, self.color)
        testSimpleTableWithEnum = TestSimpleTableWithEnumEnd(builder)
        return testSimpleTableWithEnum


class Vec3(object):
    __slots__ = ['_tab']

    @classmethod
    def SizeOf(cls):
        return 32

    # Vec3
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # Vec3
    def X(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
    # Vec3
    def Y(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))
    # Vec3
    def Z(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(8))
    # Vec3
    def Test1(self): return self._tab.Get(flatbuffers.number_types.Float64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(16))
    # Vec3
    def Test2(self): return self._tab.Get(flatbuffers.number_types.Uint8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(24))
    # Vec3
    def Test3(self, obj):
        obj.Init(self._tab.Bytes, self._tab.Pos + 26)
        return obj


def CreateVec3(builder, x, y, z, test1, test2, test3_a, test3_b):
    builder.Prep(8, 32)
    builder.Pad(2)
    builder.Prep(2, 4)
    builder.Pad(1)
    builder.PrependInt8(test3_b)
    builder.PrependInt16(test3_a)
    builder.Pad(1)
    builder.PrependUint8(test2)
    builder.PrependFloat64(test1)
    builder.Pad(4)
    builder.PrependFloat32(z)
    builder.PrependFloat32(y)
    builder.PrependFloat32(x)
    return builder.Offset()

try:
    from typing import Optional
except:
    pass

class Vec3T(object):

    # Vec3T
    def __init__(
        self,
        x = 0.0,
        y = 0.0,
        z = 0.0,
        test1 = 0.0,
        test2 = 0,
        test3 = None,
    ):
        self.x = x  # type: float
        self.y = y  # type: float
        self.z = z  # type: float
        self.test1 = test1  # type: float
        self.test2 = test2  # type: int
        self.test3 = test3  # type: Optional[TestT]

    @classmethod
    def InitFromBuf(cls, buf, pos):
        vec3 = Vec3()
        vec3.Init(buf, pos)
        return cls.InitFromObj(vec3)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, vec3):
        x = Vec3T()
        x._UnPack(vec3)
        return x

    # Vec3T
    def _UnPack(self, vec3):
        if vec3 is None:
            return
        self.x = vec3.X()
        self.y = vec3.Y()
        self.z = vec3.Z()
        self.test1 = vec3.Test1()
        self.test2 = vec3.Test2()
        if vec3.Test3(Test()) is not None:
            self.test3 = TestT.InitFromObj(vec3.Test3(Test()))

    # Vec3T
    def Pack(self, builder):
        return CreateVec3(builder, self.x, self.y, self.z, self.test1, self.test2, self.test3.a, self.test3.b)


class Ability(object):
    __slots__ = ['_tab']

    @classmethod
    def SizeOf(cls):
        return 8

    # Ability
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # Ability
    def Id(self): return self._tab.Get(flatbuffers.number_types.Uint32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
    # Ability
    def Distance(self): return self._tab.Get(flatbuffers.number_types.Uint32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4))

def CreateAbility(builder, id, distance):
    builder.Prep(4, 8)
    builder.PrependUint32(distance)
    builder.PrependUint32(id)
    return builder.Offset()


class AbilityT(object):

    # AbilityT
    def __init__(
        self,
        id = 0,
        distance = 0,
    ):
        self.id = id  # type: int
        self.distance = distance  # type: int

    @classmethod
    def InitFromBuf(cls, buf, pos):
        ability = Ability()
        ability.Init(buf, pos)
        return cls.InitFromObj(ability)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, ability):
        x = AbilityT()
        x._UnPack(ability)
        return x

    # AbilityT
    def _UnPack(self, ability):
        if ability is None:
            return
        self.id = ability.Id()
        self.distance = ability.Distance()

    # AbilityT
    def Pack(self, builder):
        return CreateAbility(builder, self.id, self.distance)


class StructOfStructs(object):
    __slots__ = ['_tab']

    @classmethod
    def SizeOf(cls):
        return 20

    # StructOfStructs
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # StructOfStructs
    def A(self, obj):
        obj.Init(self._tab.Bytes, self._tab.Pos + 0)
        return obj

    # StructOfStructs
    def B(self, obj):
        obj.Init(self._tab.Bytes, self._tab.Pos + 8)
        return obj

    # StructOfStructs
    def C(self, obj):
        obj.Init(self._tab.Bytes, self._tab.Pos + 12)
        return obj


def CreateStructOfStructs(builder, a_id, a_distance, b_a, b_b, c_id, c_distance):
    builder.Prep(4, 20)
    builder.Prep(4, 8)
    builder.PrependUint32(c_distance)
    builder.PrependUint32(c_id)
    builder.Prep(2, 4)
    builder.Pad(1)
    builder.PrependInt8(b_b)
    builder.PrependInt16(b_a)
    builder.Prep(4, 8)
    builder.PrependUint32(a_distance)
    builder.PrependUint32(a_id)
    return builder.Offset()

try:
    from typing import Optional
except:
    pass

class StructOfStructsT(object):

    # StructOfStructsT
    def __init__(
        self,
        a = None,
        b = None,
        c = None,
    ):
        self.a = a  # type: Optional[AbilityT]
        self.b = b  # type: Optional[TestT]
        self.c = c  # type: Optional[AbilityT]

    @classmethod
    def InitFromBuf(cls, buf, pos):
        structOfStructs = StructOfStructs()
        structOfStructs.Init(buf, pos)
        return cls.InitFromObj(structOfStructs)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, structOfStructs):
        x = StructOfStructsT()
        x._UnPack(structOfStructs)
        return x

    # StructOfStructsT
    def _UnPack(self, structOfStructs):
        if structOfStructs is None:
            return
        if structOfStructs.A(Ability()) is not None:
            self.a = AbilityT.InitFromObj(structOfStructs.A(Ability()))
        if structOfStructs.B(Test()) is not None:
            self.b = TestT.InitFromObj(structOfStructs.B(Test()))
        if structOfStructs.C(Ability()) is not None:
            self.c = AbilityT.InitFromObj(structOfStructs.C(Ability()))

    # StructOfStructsT
    def Pack(self, builder):
        return CreateStructOfStructs(builder, self.a.id, self.a.distance, self.b.a, self.b.b, self.c.id, self.c.distance)


class StructOfStructsOfStructs(object):
    __slots__ = ['_tab']

    @classmethod
    def SizeOf(cls):
        return 20

    # StructOfStructsOfStructs
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # StructOfStructsOfStructs
    def A(self, obj):
        obj.Init(self._tab.Bytes, self._tab.Pos + 0)
        return obj


def CreateStructOfStructsOfStructs(builder, a_a_id, a_a_distance, a_b_a, a_b_b, a_c_id, a_c_distance):
    builder.Prep(4, 20)
    builder.Prep(4, 20)
    builder.Prep(4, 8)
    builder.PrependUint32(a_c_distance)
    builder.PrependUint32(a_c_id)
    builder.Prep(2, 4)
    builder.Pad(1)
    builder.PrependInt8(a_b_b)
    builder.PrependInt16(a_b_a)
    builder.Prep(4, 8)
    builder.PrependUint32(a_a_distance)
    builder.PrependUint32(a_a_id)
    return builder.Offset()

try:
    from typing import Optional
except:
    pass

class StructOfStructsOfStructsT(object):

    # StructOfStructsOfStructsT
    def __init__(
        self,
        a = None,
    ):
        self.a = a  # type: Optional[StructOfStructsT]

    @classmethod
    def InitFromBuf(cls, buf, pos):
        structOfStructsOfStructs = StructOfStructsOfStructs()
        structOfStructsOfStructs.Init(buf, pos)
        return cls.InitFromObj(structOfStructsOfStructs)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, structOfStructsOfStructs):
        x = StructOfStructsOfStructsT()
        x._UnPack(structOfStructsOfStructs)
        return x

    # StructOfStructsOfStructsT
    def _UnPack(self, structOfStructsOfStructs):
        if structOfStructsOfStructs is None:
            return
        if structOfStructsOfStructs.A(StructOfStructs()) is not None:
            self.a = StructOfStructsT.InitFromObj(structOfStructsOfStructs.A(StructOfStructs()))

    # StructOfStructsOfStructsT
    def Pack(self, builder):
        return CreateStructOfStructsOfStructs(builder, self.a.a.id, self.a.a.distance, self.a.b.a, self.a.b.b, self.a.c.id, self.a.c.distance)


class Stat(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = Stat()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsStat(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def StatBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # Stat
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # Stat
    def Id(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.String(o + self._tab.Pos)
        return None

    # Stat
    def Val(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
        return 0

    # Stat
    def Count(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
        return 0

def StatStart(builder):
    builder.StartObject(3)

def StatAddId(builder, id):
    builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(id), 0)

def StatAddVal(builder, val):
    builder.PrependInt64Slot(1, val, 0)

def StatAddCount(builder, count):
    builder.PrependUint16Slot(2, count, 0)

def StatEnd(builder):
    return builder.EndObject()



class StatT(object):

    # StatT
    def __init__(
        self,
        id = None,
        val = 0,
        count = 0,
    ):
        self.id = id  # type: Optional[str]
        self.val = val  # type: int
        self.count = count  # type: int

    @classmethod
    def InitFromBuf(cls, buf, pos):
        stat = Stat()
        stat.Init(buf, pos)
        return cls.InitFromObj(stat)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, stat):
        x = StatT()
        x._UnPack(stat)
        return x

    # StatT
    def _UnPack(self, stat):
        if stat is None:
            return
        self.id = stat.Id()
        self.val = stat.Val()
        self.count = stat.Count()

    # StatT
    def Pack(self, builder):
        if self.id is not None:
            id = builder.CreateString(self.id)
        StatStart(builder)
        if self.id is not None:
            StatAddId(builder, id)
        StatAddVal(builder, self.val)
        StatAddCount(builder, self.count)
        stat = StatEnd(builder)
        return stat


class Referrable(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = Referrable()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsReferrable(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def ReferrableBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # Referrable
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # Referrable
    def Id(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

def ReferrableStart(builder):
    builder.StartObject(1)

def ReferrableAddId(builder, id):
    builder.PrependUint64Slot(0, id, 0)

def ReferrableEnd(builder):
    return builder.EndObject()



class ReferrableT(object):

    # ReferrableT
    def __init__(
        self,
        id = 0,
    ):
        self.id = id  # type: int

    @classmethod
    def InitFromBuf(cls, buf, pos):
        referrable = Referrable()
        referrable.Init(buf, pos)
        return cls.InitFromObj(referrable)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, referrable):
        x = ReferrableT()
        x._UnPack(referrable)
        return x

    # ReferrableT
    def _UnPack(self, referrable):
        if referrable is None:
            return
        self.id = referrable.Id()

    # ReferrableT
    def Pack(self, builder):
        ReferrableStart(builder)
        ReferrableAddId(builder, self.id)
        referrable = ReferrableEnd(builder)
        return referrable


# an example documentation comment: "monster object"
class Monster(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = Monster()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsMonster(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # Monster
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # Monster
    def Pos(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            x = o + self._tab.Pos
            obj = Vec3()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Mana(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
        return 150

    # Monster
    def Hp(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
        return 100

    # Monster
    def Name(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
        if o != 0:
            return self._tab.String(o + self._tab.Pos)
        return None

    # Monster
    def Inventory(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def InventoryAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def InventoryLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def InventoryIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        return o == 0

    # Monster
    def Color(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 8

    # Monster
    def TestType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Test(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def Test4(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Test4Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Test4IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        return o == 0

    # Monster
    def Testarrayofstring(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return ""

    # Monster
    def TestarrayofstringLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofstringIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        return o == 0

    # an example documentation comment: this will end up in the generated code
    # multiline too
    # Monster
    def Testarrayoftables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            obj = Monster()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def TestarrayoftablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayoftablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        return o == 0

    # Monster
    def Enemy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            obj = Monster()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Testnestedflatbuffer(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestnestedflatbufferAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def TestnestedflatbufferNestedRoot(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            from MyGame.Example.Monster import Monster
            return Monster.GetRootAs(self._tab.Bytes, self._tab.Vector(o))
        return 0

    # Monster
    def TestnestedflatbufferLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestnestedflatbufferIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
        return o == 0

    # Monster
    def Testempty(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            obj = Stat()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Testbool(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
        if o != 0:
            return bool(self._tab.Get(flatbuffers.number_types.BoolFlags, o + self._tab.Pos))
        return False

    # Monster
    def Testhashs32Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(36))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu32Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(38))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs64Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(40))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu64Fnv1(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(42))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs32Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(44))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu32Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(46))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashs64Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(48))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testhashu64Fnv1a(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(50))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def Testarrayofbools(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.BoolFlags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestarrayofboolsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.BoolFlags, o)
        return 0

    # Monster
    def TestarrayofboolsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofboolsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
        return o == 0

    # Monster
    def Testf(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(54))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 3.14159

    # Monster
    def Testf2(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(56))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 3.0

    # Monster
    def Testf3(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(58))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 0.0

    # Monster
    def Testarrayofstring2(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.String(a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
        return ""

    # Monster
    def Testarrayofstring2Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Testarrayofstring2IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
        return o == 0

    # Monster
    def Testarrayofsortedstruct(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 8
            obj = Ability()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def TestarrayofsortedstructLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestarrayofsortedstructIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
        return o == 0

    # Monster
    def Flex(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def FlexAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def FlexLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def FlexIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
        return o == 0

    # Monster
    def Test5(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def Test5Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def Test5IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
        return o == 0

    # Monster
    def VectorOfLongs(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Int64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfLongsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int64Flags, o)
        return 0

    # Monster
    def VectorOfLongsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfLongsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
        return o == 0

    # Monster
    def VectorOfDoubles(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfDoublesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
        return 0

    # Monster
    def VectorOfDoublesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfDoublesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
        return o == 0

    # Monster
    def ParentNamespaceTest(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
        if o != 0:
            x = self._tab.Indirect(o + self._tab.Pos)
            obj = InParentNamespace()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfReferrables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            obj = Referrable()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfReferrablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfReferrablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
        return o == 0

    # Monster
    def SingleWeakReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(76))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfWeakReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfWeakReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfWeakReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfWeakReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
        return o == 0

    # Monster
    def VectorOfStrongReferrables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            obj = Referrable()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def VectorOfStrongReferrablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfStrongReferrablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
        return o == 0

    # Monster
    def CoOwningReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(82))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfCoOwningReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfCoOwningReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfCoOwningReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfCoOwningReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
        return o == 0

    # Monster
    def NonOwningReference(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(86))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def VectorOfNonOwningReferences(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # Monster
    def VectorOfNonOwningReferencesAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint64Flags, o)
        return 0

    # Monster
    def VectorOfNonOwningReferencesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfNonOwningReferencesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
        return o == 0

    # Monster
    def AnyUniqueType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(90))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def AnyUnique(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(92))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def AnyAmbiguousType(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(94))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # Monster
    def AnyAmbiguous(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(96))
        if o != 0:
            from flatbuffers.table import Table
            obj = Table(bytearray(), 0)
            self._tab.Union(obj, o)
            return obj
        return None

    # Monster
    def VectorOfEnums(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def VectorOfEnumsAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def VectorOfEnumsLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def VectorOfEnumsIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
        return o == 0

    # Monster
    def SignedEnum(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(100))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
        return -1

    # Monster
    def Testrequirednestedflatbuffer(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # Monster
    def TestrequirednestedflatbufferAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # Monster
    def TestrequirednestedflatbufferNestedRoot(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            from MyGame.Example.Monster import Monster
            return Monster.GetRootAs(self._tab.Bytes, self._tab.Vector(o))
        return 0

    # Monster
    def TestrequirednestedflatbufferLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def TestrequirednestedflatbufferIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(102))
        return o == 0

    # Monster
    def ScalarKeySortedTables(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        if o != 0:
            x = self._tab.Vector(o)
            x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
            x = self._tab.Indirect(x)
            obj = Stat()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def ScalarKeySortedTablesLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # Monster
    def ScalarKeySortedTablesIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(104))
        return o == 0

    # Monster
    def NativeInline(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(106))
        if o != 0:
            x = o + self._tab.Pos
            obj = Test()
            obj.Init(self._tab.Bytes, x)
            return obj
        return None

    # Monster
    def LongEnumNonEnumDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(108))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # Monster
    def LongEnumNormalDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(110))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 2

    # Monster
    def NanDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(112))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('nan')

    # Monster
    def InfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(114))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def PositiveInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(116))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def InfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(118))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def PositiveInfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(120))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('inf')

    # Monster
    def NegativeInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(122))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('-inf')

    # Monster
    def NegativeInfinityDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(124))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return float('-inf')

    # Monster
    def DoubleInfDefault(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(126))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
        return float('inf')

def MonsterStart(builder):
    builder.StartObject(62)

def MonsterAddPos(builder, pos):
    builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pos), 0)

def MonsterAddMana(builder, mana):
    builder.PrependInt16Slot(1, mana, 150)

def MonsterAddHp(builder, hp):
    builder.PrependInt16Slot(2, hp, 100)

def MonsterAddName(builder, name):
    builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)

def MonsterAddInventory(builder, inventory):
    builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(inventory), 0)

def MonsterStartInventoryVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def MonsterCreateInventoryVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def MonsterAddColor(builder, color):
    builder.PrependUint8Slot(6, color, 8)

def MonsterAddTestType(builder, testType):
    builder.PrependUint8Slot(7, testType, 0)

def MonsterAddTest(builder, test):
    builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(test), 0)

def MonsterAddTest4(builder, test4):
    builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(test4), 0)

def MonsterStartTest4Vector(builder, numElems):
    return builder.StartVector(4, numElems, 2)

def MonsterCreateTest4Vector(builder, data):
    data = list(data)
    builder.StartVector(4, len(data), 2)
    for item in reversed(data):
        item.Pack(builder)
    return builder.EndVector()

def MonsterAddTestarrayofstring(builder, testarrayofstring):
    builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring), 0)

def MonsterStartTestarrayofstringVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def MonsterCreateTestarrayofstringVector(builder, data):
    return builder.CreateVectorOfTables(data)

def MonsterAddTestarrayoftables(builder, testarrayoftables):
    builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayoftables), 0)

def MonsterStartTestarrayoftablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def MonsterCreateTestarrayoftablesVector(builder, data):
    return builder.CreateVectorOfTables(data)

def MonsterAddEnemy(builder, enemy):
    builder.PrependUOffsetTRelativeSlot(12, flatbuffers.number_types.UOffsetTFlags.py_type(enemy), 0)

def MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer):
    builder.PrependUOffsetTRelativeSlot(13, flatbuffers.number_types.UOffsetTFlags.py_type(testnestedflatbuffer), 0)

def MonsterStartTestnestedflatbufferVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def MonsterCreateTestnestedflatbufferVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def MonsterMakeTestnestedflatbufferVectorFromBytes(builder, bytes):
    builder.StartVector(1, len(bytes), 1)
    builder.head = builder.head - len(bytes)
    builder.Bytes[builder.head : builder.head + len(bytes)] = bytes
    return builder.EndVector()
def MonsterAddTestempty(builder, testempty):
    builder.PrependUOffsetTRelativeSlot(14, flatbuffers.number_types.UOffsetTFlags.py_type(testempty), 0)

def MonsterAddTestbool(builder, testbool):
    builder.PrependBoolSlot(15, testbool, 0)

def MonsterAddTesthashs32Fnv1(builder, testhashs32Fnv1):
    builder.PrependInt32Slot(16, testhashs32Fnv1, 0)

def MonsterAddTesthashu32Fnv1(builder, testhashu32Fnv1):
    builder.PrependUint32Slot(17, testhashu32Fnv1, 0)

def MonsterAddTesthashs64Fnv1(builder, testhashs64Fnv1):
    builder.PrependInt64Slot(18, testhashs64Fnv1, 0)

def MonsterAddTesthashu64Fnv1(builder, testhashu64Fnv1):
    builder.PrependUint64Slot(19, testhashu64Fnv1, 0)

def MonsterAddTesthashs32Fnv1a(builder, testhashs32Fnv1a):
    builder.PrependInt32Slot(20, testhashs32Fnv1a, 0)

def MonsterAddTesthashu32Fnv1a(builder, testhashu32Fnv1a):
    builder.PrependUint32Slot(21, testhashu32Fnv1a, 0)

def MonsterAddTesthashs64Fnv1a(builder, testhashs64Fnv1a):
    builder.PrependInt64Slot(22, testhashs64Fnv1a, 0)

def MonsterAddTesthashu64Fnv1a(builder, testhashu64Fnv1a):
    builder.PrependUint64Slot(23, testhashu64Fnv1a, 0)

def MonsterAddTestarrayofbools(builder, testarrayofbools):
    builder.PrependUOffsetTRelativeSlot(24, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofbools), 0)

def MonsterStartTestarrayofboolsVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def MonsterCreateTestarrayofboolsVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependBool(item)
    return builder.EndVector()

def MonsterAddTestf(builder, testf):
    builder.PrependFloat32Slot(25, testf, 3.14159)

def MonsterAddTestf2(builder, testf2):
    builder.PrependFloat32Slot(26, testf2, 3.0)

def MonsterAddTestf3(builder, testf3):
    builder.PrependFloat32Slot(27, testf3, 0.0)

def MonsterAddTestarrayofstring2(builder, testarrayofstring2):
    builder.PrependUOffsetTRelativeSlot(28, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofstring2), 0)

def MonsterStartTestarrayofstring2Vector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def MonsterCreateTestarrayofstring2Vector(builder, data):
    return builder.CreateVectorOfTables(data)

def MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct):
    builder.PrependUOffsetTRelativeSlot(29, flatbuffers.number_types.UOffsetTFlags.py_type(testarrayofsortedstruct), 0)

def MonsterStartTestarrayofsortedstructVector(builder, numElems):
    return builder.StartVector(8, numElems, 4)

def MonsterCreateTestarrayofsortedstructVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 4)
    for item in reversed(data):
        item.Pack(builder)
    return builder.EndVector()

def MonsterAddFlex(builder, flex):
    builder.PrependUOffsetTRelativeSlot(30, flatbuffers.number_types.UOffsetTFlags.py_type(flex), 0)

def MonsterStartFlexVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def MonsterCreateFlexVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def MonsterAddTest5(builder, test5):
    builder.PrependUOffsetTRelativeSlot(31, flatbuffers.number_types.UOffsetTFlags.py_type(test5), 0)

def MonsterStartTest5Vector(builder, numElems):
    return builder.StartVector(4, numElems, 2)

def MonsterCreateTest5Vector(builder, data):
    data = list(data)
    builder.StartVector(4, len(data), 2)
    for item in reversed(data):
        item.Pack(builder)
    return builder.EndVector()

def MonsterAddVectorOfLongs(builder, vectorOfLongs):
    builder.PrependUOffsetTRelativeSlot(32, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfLongs), 0)

def MonsterStartVectorOfLongsVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def MonsterCreateVectorOfLongsVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependInt64(item)
    return builder.EndVector()

def MonsterAddVectorOfDoubles(builder, vectorOfDoubles):
    builder.PrependUOffsetTRelativeSlot(33, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfDoubles), 0)

def MonsterStartVectorOfDoublesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def MonsterCreateVectorOfDoublesVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependFloat64(item)
    return builder.EndVector()

def MonsterAddParentNamespaceTest(builder, parentNamespaceTest):
    builder.PrependUOffsetTRelativeSlot(34, flatbuffers.number_types.UOffsetTFlags.py_type(parentNamespaceTest), 0)

def MonsterAddVectorOfReferrables(builder, vectorOfReferrables):
    builder.PrependUOffsetTRelativeSlot(35, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfReferrables), 0)

def MonsterStartVectorOfReferrablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def MonsterCreateVectorOfReferrablesVector(builder, data):
    return builder.CreateVectorOfTables(data)

def MonsterAddSingleWeakReference(builder, singleWeakReference):
    builder.PrependUint64Slot(36, singleWeakReference, 0)

def MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences):
    builder.PrependUOffsetTRelativeSlot(37, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfWeakReferences), 0)

def MonsterStartVectorOfWeakReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def MonsterCreateVectorOfWeakReferencesVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependUint64(item)
    return builder.EndVector()

def MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables):
    builder.PrependUOffsetTRelativeSlot(38, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfStrongReferrables), 0)

def MonsterStartVectorOfStrongReferrablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def MonsterCreateVectorOfStrongReferrablesVector(builder, data):
    return builder.CreateVectorOfTables(data)

def MonsterAddCoOwningReference(builder, coOwningReference):
    builder.PrependUint64Slot(39, coOwningReference, 0)

def MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences):
    builder.PrependUOffsetTRelativeSlot(40, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfCoOwningReferences), 0)

def MonsterStartVectorOfCoOwningReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def MonsterCreateVectorOfCoOwningReferencesVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependUint64(item)
    return builder.EndVector()

def MonsterAddNonOwningReference(builder, nonOwningReference):
    builder.PrependUint64Slot(41, nonOwningReference, 0)

def MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences):
    builder.PrependUOffsetTRelativeSlot(42, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfNonOwningReferences), 0)

def MonsterStartVectorOfNonOwningReferencesVector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def MonsterCreateVectorOfNonOwningReferencesVector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependUint64(item)
    return builder.EndVector()

def MonsterAddAnyUniqueType(builder, anyUniqueType):
    builder.PrependUint8Slot(43, anyUniqueType, 0)

def MonsterAddAnyUnique(builder, anyUnique):
    builder.PrependUOffsetTRelativeSlot(44, flatbuffers.number_types.UOffsetTFlags.py_type(anyUnique), 0)

def MonsterAddAnyAmbiguousType(builder, anyAmbiguousType):
    builder.PrependUint8Slot(45, anyAmbiguousType, 0)

def MonsterAddAnyAmbiguous(builder, anyAmbiguous):
    builder.PrependUOffsetTRelativeSlot(46, flatbuffers.number_types.UOffsetTFlags.py_type(anyAmbiguous), 0)

def MonsterAddVectorOfEnums(builder, vectorOfEnums):
    builder.PrependUOffsetTRelativeSlot(47, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfEnums), 0)

def MonsterStartVectorOfEnumsVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def MonsterCreateVectorOfEnumsVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def MonsterAddSignedEnum(builder, signedEnum):
    builder.PrependInt8Slot(48, signedEnum, -1)

def MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer):
    builder.PrependUOffsetTRelativeSlot(49, flatbuffers.number_types.UOffsetTFlags.py_type(testrequirednestedflatbuffer), 0)

def MonsterStartTestrequirednestedflatbufferVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def MonsterCreateTestrequirednestedflatbufferVector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependUint8(item)
    return builder.EndVector()

def MonsterMakeTestrequirednestedflatbufferVectorFromBytes(builder, bytes):
    builder.StartVector(1, len(bytes), 1)
    builder.head = builder.head - len(bytes)
    builder.Bytes[builder.head : builder.head + len(bytes)] = bytes
    return builder.EndVector()
def MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables):
    builder.PrependUOffsetTRelativeSlot(50, flatbuffers.number_types.UOffsetTFlags.py_type(scalarKeySortedTables), 0)

def MonsterStartScalarKeySortedTablesVector(builder, numElems):
    return builder.StartVector(4, numElems, 4)

def MonsterCreateScalarKeySortedTablesVector(builder, data):
    return builder.CreateVectorOfTables(data)

def MonsterAddNativeInline(builder, nativeInline):
    builder.PrependStructSlot(51, flatbuffers.number_types.UOffsetTFlags.py_type(nativeInline), 0)

def MonsterAddLongEnumNonEnumDefault(builder, longEnumNonEnumDefault):
    builder.PrependUint64Slot(52, longEnumNonEnumDefault, 0)

def MonsterAddLongEnumNormalDefault(builder, longEnumNormalDefault):
    builder.PrependUint64Slot(53, longEnumNormalDefault, 2)

def MonsterAddNanDefault(builder, nanDefault):
    builder.PrependFloat32Slot(54, nanDefault, float('nan'))

def MonsterAddInfDefault(builder, infDefault):
    builder.PrependFloat32Slot(55, infDefault, float('inf'))

def MonsterAddPositiveInfDefault(builder, positiveInfDefault):
    builder.PrependFloat32Slot(56, positiveInfDefault, float('inf'))

def MonsterAddInfinityDefault(builder, infinityDefault):
    builder.PrependFloat32Slot(57, infinityDefault, float('inf'))

def MonsterAddPositiveInfinityDefault(builder, positiveInfinityDefault):
    builder.PrependFloat32Slot(58, positiveInfinityDefault, float('inf'))

def MonsterAddNegativeInfDefault(builder, negativeInfDefault):
    builder.PrependFloat32Slot(59, negativeInfDefault, float('-inf'))

def MonsterAddNegativeInfinityDefault(builder, negativeInfinityDefault):
    builder.PrependFloat32Slot(60, negativeInfinityDefault, float('-inf'))

def MonsterAddDoubleInfDefault(builder, doubleInfDefault):
    builder.PrependFloat64Slot(61, doubleInfDefault, float('inf'))

def MonsterEnd(builder):
    return builder.EndObject()


try:
    from typing import List, Optional, Union
except:
    pass

class MonsterT(object):

    # MonsterT
    def __init__(
        self,
        pos = None,
        mana = 150,
        hp = 100,
        name = None,
        inventory = None,
        color = 8,
        testType = 0,
        test = None,
        test4 = None,
        testarrayofstring = None,
        testarrayoftables = None,
        enemy = None,
        testnestedflatbuffer = None,
        testempty = None,
        testbool = False,
        testhashs32Fnv1 = 0,
        testhashu32Fnv1 = 0,
        testhashs64Fnv1 = 0,
        testhashu64Fnv1 = 0,
        testhashs32Fnv1a = 0,
        testhashu32Fnv1a = 0,
        testhashs64Fnv1a = 0,
        testhashu64Fnv1a = 0,
        testarrayofbools = None,
        testf = 3.14159,
        testf2 = 3.0,
        testf3 = 0.0,
        testarrayofstring2 = None,
        testarrayofsortedstruct = None,
        flex = None,
        test5 = None,
        vectorOfLongs = None,
        vectorOfDoubles = None,
        parentNamespaceTest = None,
        vectorOfReferrables = None,
        singleWeakReference = 0,
        vectorOfWeakReferences = None,
        vectorOfStrongReferrables = None,
        coOwningReference = 0,
        vectorOfCoOwningReferences = None,
        nonOwningReference = 0,
        vectorOfNonOwningReferences = None,
        anyUniqueType = 0,
        anyUnique = None,
        anyAmbiguousType = 0,
        anyAmbiguous = None,
        vectorOfEnums = None,
        signedEnum = -1,
        testrequirednestedflatbuffer = None,
        scalarKeySortedTables = None,
        nativeInline = None,
        longEnumNonEnumDefault = 0,
        longEnumNormalDefault = 2,
        nanDefault = float('nan'),
        infDefault = float('inf'),
        positiveInfDefault = float('inf'),
        infinityDefault = float('inf'),
        positiveInfinityDefault = float('inf'),
        negativeInfDefault = float('-inf'),
        negativeInfinityDefault = float('-inf'),
        doubleInfDefault = float('inf'),
    ):
        self.pos = pos  # type: Optional[Vec3T]
        self.mana = mana  # type: int
        self.hp = hp  # type: int
        self.name = name  # type: Optional[str]
        self.inventory = inventory  # type: Optional[List[int]]
        self.color = color  # type: int
        self.testType = testType  # type: int
        self.test = test  # type: Union[None, 'MonsterT', 'TestSimpleTableWithEnumT', 'MonsterT']
        self.test4 = test4  # type: Optional[List[TestT]]
        self.testarrayofstring = testarrayofstring  # type: Optional[List[Optional[str]]]
        self.testarrayoftables = testarrayoftables  # type: Optional[List[MonsterT]]
        self.enemy = enemy  # type: Optional[MonsterT]
        self.testnestedflatbuffer = testnestedflatbuffer  # type: Optional[List[int]]
        self.testempty = testempty  # type: Optional[StatT]
        self.testbool = testbool  # type: bool
        self.testhashs32Fnv1 = testhashs32Fnv1  # type: int
        self.testhashu32Fnv1 = testhashu32Fnv1  # type: int
        self.testhashs64Fnv1 = testhashs64Fnv1  # type: int
        self.testhashu64Fnv1 = testhashu64Fnv1  # type: int
        self.testhashs32Fnv1a = testhashs32Fnv1a  # type: int
        self.testhashu32Fnv1a = testhashu32Fnv1a  # type: int
        self.testhashs64Fnv1a = testhashs64Fnv1a  # type: int
        self.testhashu64Fnv1a = testhashu64Fnv1a  # type: int
        self.testarrayofbools = testarrayofbools  # type: Optional[List[bool]]
        self.testf = testf  # type: float
        self.testf2 = testf2  # type: float
        self.testf3 = testf3  # type: float
        self.testarrayofstring2 = testarrayofstring2  # type: Optional[List[Optional[str]]]
        self.testarrayofsortedstruct = testarrayofsortedstruct  # type: Optional[List[AbilityT]]
        self.flex = flex  # type: Optional[List[int]]
        self.test5 = test5  # type: Optional[List[TestT]]
        self.vectorOfLongs = vectorOfLongs  # type: Optional[List[int]]
        self.vectorOfDoubles = vectorOfDoubles  # type: Optional[List[float]]
        self.parentNamespaceTest = parentNamespaceTest  # type: Optional[InParentNamespaceT]
        self.vectorOfReferrables = vectorOfReferrables  # type: Optional[List[ReferrableT]]
        self.singleWeakReference = singleWeakReference  # type: int
        self.vectorOfWeakReferences = vectorOfWeakReferences  # type: Optional[List[int]]
        self.vectorOfStrongReferrables = vectorOfStrongReferrables  # type: Optional[List[ReferrableT]]
        self.coOwningReference = coOwningReference  # type: int
        self.vectorOfCoOwningReferences = vectorOfCoOwningReferences  # type: Optional[List[int]]
        self.nonOwningReference = nonOwningReference  # type: int
        self.vectorOfNonOwningReferences = vectorOfNonOwningReferences  # type: Optional[List[int]]
        self.anyUniqueType = anyUniqueType  # type: int
        self.anyUnique = anyUnique  # type: Union[None, 'MonsterT', 'TestSimpleTableWithEnumT', 'MonsterT']
        self.anyAmbiguousType = anyAmbiguousType  # type: int
        self.anyAmbiguous = anyAmbiguous  # type: Union[None, 'MonsterT', 'MonsterT', 'MonsterT']
        self.vectorOfEnums = vectorOfEnums  # type: Optional[List[int]]
        self.signedEnum = signedEnum  # type: int
        self.testrequirednestedflatbuffer = testrequirednestedflatbuffer  # type: Optional[List[int]]
        self.scalarKeySortedTables = scalarKeySortedTables  # type: Optional[List[StatT]]
        self.nativeInline = nativeInline  # type: Optional[TestT]
        self.longEnumNonEnumDefault = longEnumNonEnumDefault  # type: int
        self.longEnumNormalDefault = longEnumNormalDefault  # type: int
        self.nanDefault = nanDefault  # type: float
        self.infDefault = infDefault  # type: float
        self.positiveInfDefault = positiveInfDefault  # type: float
        self.infinityDefault = infinityDefault  # type: float
        self.positiveInfinityDefault = positiveInfinityDefault  # type: float
        self.negativeInfDefault = negativeInfDefault  # type: float
        self.negativeInfinityDefault = negativeInfinityDefault  # type: float
        self.doubleInfDefault = doubleInfDefault  # type: float

    @classmethod
    def InitFromBuf(cls, buf, pos):
        monster = Monster()
        monster.Init(buf, pos)
        return cls.InitFromObj(monster)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, monster):
        x = MonsterT()
        x._UnPack(monster)
        return x

    # MonsterT
    def _UnPack(self, monster):
        if monster is None:
            return
        if monster.Pos() is not None:
            self.pos = Vec3T.InitFromObj(monster.Pos())
        self.mana = monster.Mana()
        self.hp = monster.Hp()
        self.name = monster.Name()
        if not monster.InventoryIsNone():
            if np is None:
                self.inventory = []
                for i in range(monster.InventoryLength()):
                    self.inventory.append(monster.Inventory(i))
            else:
                self.inventory = monster.InventoryAsNumpy()
        self.color = monster.Color()
        self.testType = monster.TestType()
        self.test = AnyCreator(self.testType, monster.Test())
        if not monster.Test4IsNone():
            self.test4 = []
            for i in range(monster.Test4Length()):
                if monster.Test4(i) is None:
                    self.test4.append(None)
                else:
                    test_ = TestT.InitFromObj(monster.Test4(i))
                    self.test4.append(test_)
        if not monster.TestarrayofstringIsNone():
            self.testarrayofstring = []
            for i in range(monster.TestarrayofstringLength()):
                self.testarrayofstring.append(monster.Testarrayofstring(i))
        if not monster.TestarrayoftablesIsNone():
            self.testarrayoftables = []
            for i in range(monster.TestarrayoftablesLength()):
                if monster.Testarrayoftables(i) is None:
                    self.testarrayoftables.append(None)
                else:
                    monster_ = MonsterT.InitFromObj(monster.Testarrayoftables(i))
                    self.testarrayoftables.append(monster_)
        if monster.Enemy() is not None:
            self.enemy = MonsterT.InitFromObj(monster.Enemy())
        if not monster.TestnestedflatbufferIsNone():
            if np is None:
                self.testnestedflatbuffer = []
                for i in range(monster.TestnestedflatbufferLength()):
                    self.testnestedflatbuffer.append(monster.Testnestedflatbuffer(i))
            else:
                self.testnestedflatbuffer = monster.TestnestedflatbufferAsNumpy()
        if monster.Testempty() is not None:
            self.testempty = StatT.InitFromObj(monster.Testempty())
        self.testbool = monster.Testbool()
        self.testhashs32Fnv1 = monster.Testhashs32Fnv1()
        self.testhashu32Fnv1 = monster.Testhashu32Fnv1()
        self.testhashs64Fnv1 = monster.Testhashs64Fnv1()
        self.testhashu64Fnv1 = monster.Testhashu64Fnv1()
        self.testhashs32Fnv1a = monster.Testhashs32Fnv1a()
        self.testhashu32Fnv1a = monster.Testhashu32Fnv1a()
        self.testhashs64Fnv1a = monster.Testhashs64Fnv1a()
        self.testhashu64Fnv1a = monster.Testhashu64Fnv1a()
        if not monster.TestarrayofboolsIsNone():
            if np is None:
                self.testarrayofbools = []
                for i in range(monster.TestarrayofboolsLength()):
                    self.testarrayofbools.append(monster.Testarrayofbools(i))
            else:
                self.testarrayofbools = monster.TestarrayofboolsAsNumpy()
        self.testf = monster.Testf()
        self.testf2 = monster.Testf2()
        self.testf3 = monster.Testf3()
        if not monster.Testarrayofstring2IsNone():
            self.testarrayofstring2 = []
            for i in range(monster.Testarrayofstring2Length()):
                self.testarrayofstring2.append(monster.Testarrayofstring2(i))
        if not monster.TestarrayofsortedstructIsNone():
            self.testarrayofsortedstruct = []
            for i in range(monster.TestarrayofsortedstructLength()):
                if monster.Testarrayofsortedstruct(i) is None:
                    self.testarrayofsortedstruct.append(None)
                else:
                    ability_ = AbilityT.InitFromObj(monster.Testarrayofsortedstruct(i))
                    self.testarrayofsortedstruct.append(ability_)
        if not monster.FlexIsNone():
            if np is None:
                self.flex = []
                for i in range(monster.FlexLength()):
                    self.flex.append(monster.Flex(i))
            else:
                self.flex = monster.FlexAsNumpy()
        if not monster.Test5IsNone():
            self.test5 = []
            for i in range(monster.Test5Length()):
                if monster.Test5(i) is None:
                    self.test5.append(None)
                else:
                    test_ = TestT.InitFromObj(monster.Test5(i))
                    self.test5.append(test_)
        if not monster.VectorOfLongsIsNone():
            if np is None:
                self.vectorOfLongs = []
                for i in range(monster.VectorOfLongsLength()):
                    self.vectorOfLongs.append(monster.VectorOfLongs(i))
            else:
                self.vectorOfLongs = monster.VectorOfLongsAsNumpy()
        if not monster.VectorOfDoublesIsNone():
            if np is None:
                self.vectorOfDoubles = []
                for i in range(monster.VectorOfDoublesLength()):
                    self.vectorOfDoubles.append(monster.VectorOfDoubles(i))
            else:
                self.vectorOfDoubles = monster.VectorOfDoublesAsNumpy()
        if monster.ParentNamespaceTest() is not None:
            self.parentNamespaceTest = InParentNamespaceT.InitFromObj(monster.ParentNamespaceTest())
        if not monster.VectorOfReferrablesIsNone():
            self.vectorOfReferrables = []
            for i in range(monster.VectorOfReferrablesLength()):
                if monster.VectorOfReferrables(i) is None:
                    self.vectorOfReferrables.append(None)
                else:
                    referrable_ = ReferrableT.InitFromObj(monster.VectorOfReferrables(i))
                    self.vectorOfReferrables.append(referrable_)
        self.singleWeakReference = monster.SingleWeakReference()
        if not monster.VectorOfWeakReferencesIsNone():
            if np is None:
                self.vectorOfWeakReferences = []
                for i in range(monster.VectorOfWeakReferencesLength()):
                    self.vectorOfWeakReferences.append(monster.VectorOfWeakReferences(i))
            else:
                self.vectorOfWeakReferences = monster.VectorOfWeakReferencesAsNumpy()
        if not monster.VectorOfStrongReferrablesIsNone():
            self.vectorOfStrongReferrables = []
            for i in range(monster.VectorOfStrongReferrablesLength()):
                if monster.VectorOfStrongReferrables(i) is None:
                    self.vectorOfStrongReferrables.append(None)
                else:
                    referrable_ = ReferrableT.InitFromObj(monster.VectorOfStrongReferrables(i))
                    self.vectorOfStrongReferrables.append(referrable_)
        self.coOwningReference = monster.CoOwningReference()
        if not monster.VectorOfCoOwningReferencesIsNone():
            if np is None:
                self.vectorOfCoOwningReferences = []
                for i in range(monster.VectorOfCoOwningReferencesLength()):
                    self.vectorOfCoOwningReferences.append(monster.VectorOfCoOwningReferences(i))
            else:
                self.vectorOfCoOwningReferences = monster.VectorOfCoOwningReferencesAsNumpy()
        self.nonOwningReference = monster.NonOwningReference()
        if not monster.VectorOfNonOwningReferencesIsNone():
            if np is None:
                self.vectorOfNonOwningReferences = []
                for i in range(monster.VectorOfNonOwningReferencesLength()):
                    self.vectorOfNonOwningReferences.append(monster.VectorOfNonOwningReferences(i))
            else:
                self.vectorOfNonOwningReferences = monster.VectorOfNonOwningReferencesAsNumpy()
        self.anyUniqueType = monster.AnyUniqueType()
        self.anyUnique = AnyUniqueAliasesCreator(self.anyUniqueType, monster.AnyUnique())
        self.anyAmbiguousType = monster.AnyAmbiguousType()
        self.anyAmbiguous = AnyAmbiguousAliasesCreator(self.anyAmbiguousType, monster.AnyAmbiguous())
        if not monster.VectorOfEnumsIsNone():
            if np is None:
                self.vectorOfEnums = []
                for i in range(monster.VectorOfEnumsLength()):
                    self.vectorOfEnums.append(monster.VectorOfEnums(i))
            else:
                self.vectorOfEnums = monster.VectorOfEnumsAsNumpy()
        self.signedEnum = monster.SignedEnum()
        if not monster.TestrequirednestedflatbufferIsNone():
            if np is None:
                self.testrequirednestedflatbuffer = []
                for i in range(monster.TestrequirednestedflatbufferLength()):
                    self.testrequirednestedflatbuffer.append(monster.Testrequirednestedflatbuffer(i))
            else:
                self.testrequirednestedflatbuffer = monster.TestrequirednestedflatbufferAsNumpy()
        if not monster.ScalarKeySortedTablesIsNone():
            self.scalarKeySortedTables = []
            for i in range(monster.ScalarKeySortedTablesLength()):
                if monster.ScalarKeySortedTables(i) is None:
                    self.scalarKeySortedTables.append(None)
                else:
                    stat_ = StatT.InitFromObj(monster.ScalarKeySortedTables(i))
                    self.scalarKeySortedTables.append(stat_)
        if monster.NativeInline() is not None:
            self.nativeInline = TestT.InitFromObj(monster.NativeInline())
        self.longEnumNonEnumDefault = monster.LongEnumNonEnumDefault()
        self.longEnumNormalDefault = monster.LongEnumNormalDefault()
        self.nanDefault = monster.NanDefault()
        self.infDefault = monster.InfDefault()
        self.positiveInfDefault = monster.PositiveInfDefault()
        self.infinityDefault = monster.InfinityDefault()
        self.positiveInfinityDefault = monster.PositiveInfinityDefault()
        self.negativeInfDefault = monster.NegativeInfDefault()
        self.negativeInfinityDefault = monster.NegativeInfinityDefault()
        self.doubleInfDefault = monster.DoubleInfDefault()

    # MonsterT
    def Pack(self, builder):
        if self.name is not None:
            name = builder.CreateString(self.name)
        if self.inventory is not None:
            if np is not None and type(self.inventory) is np.ndarray:
                inventory = builder.CreateNumpyVector(self.inventory)
            else:
                MonsterStartInventoryVector(builder, len(self.inventory))
                for i in reversed(range(len(self.inventory))):
                    builder.PrependUint8(self.inventory[i])
                inventory = builder.EndVector()
        if self.test is not None:
            test = self.test.Pack(builder)
        if self.test4 is not None:
            MonsterStartTest4Vector(builder, len(self.test4))
            for i in reversed(range(len(self.test4))):
                self.test4[i].Pack(builder)
            test4 = builder.EndVector()
        if self.testarrayofstring is not None:
            testarrayofstringlist = []
            for i in range(len(self.testarrayofstring)):
                testarrayofstringlist.append(builder.CreateString(self.testarrayofstring[i]))
            MonsterStartTestarrayofstringVector(builder, len(self.testarrayofstring))
            for i in reversed(range(len(self.testarrayofstring))):
                builder.PrependUOffsetTRelative(testarrayofstringlist[i])
            testarrayofstring = builder.EndVector()
        if self.testarrayoftables is not None:
            testarrayoftableslist = []
            for i in range(len(self.testarrayoftables)):
                testarrayoftableslist.append(self.testarrayoftables[i].Pack(builder))
            MonsterStartTestarrayoftablesVector(builder, len(self.testarrayoftables))
            for i in reversed(range(len(self.testarrayoftables))):
                builder.PrependUOffsetTRelative(testarrayoftableslist[i])
            testarrayoftables = builder.EndVector()
        if self.enemy is not None:
            enemy = self.enemy.Pack(builder)
        if self.testnestedflatbuffer is not None:
            if np is not None and type(self.testnestedflatbuffer) is np.ndarray:
                testnestedflatbuffer = builder.CreateNumpyVector(self.testnestedflatbuffer)
            else:
                MonsterStartTestnestedflatbufferVector(builder, len(self.testnestedflatbuffer))
                for i in reversed(range(len(self.testnestedflatbuffer))):
                    builder.PrependUint8(self.testnestedflatbuffer[i])
                testnestedflatbuffer = builder.EndVector()
        if self.testempty is not None:
            testempty = self.testempty.Pack(builder)
        if self.testarrayofbools is not None:
            if np is not None and type(self.testarrayofbools) is np.ndarray:
                testarrayofbools = builder.CreateNumpyVector(self.testarrayofbools)
            else:
                MonsterStartTestarrayofboolsVector(builder, len(self.testarrayofbools))
                for i in reversed(range(len(self.testarrayofbools))):
                    builder.PrependBool(self.testarrayofbools[i])
                testarrayofbools = builder.EndVector()
        if self.testarrayofstring2 is not None:
            testarrayofstring2list = []
            for i in range(len(self.testarrayofstring2)):
                testarrayofstring2list.append(builder.CreateString(self.testarrayofstring2[i]))
            MonsterStartTestarrayofstring2Vector(builder, len(self.testarrayofstring2))
            for i in reversed(range(len(self.testarrayofstring2))):
                builder.PrependUOffsetTRelative(testarrayofstring2list[i])
            testarrayofstring2 = builder.EndVector()
        if self.testarrayofsortedstruct is not None:
            MonsterStartTestarrayofsortedstructVector(builder, len(self.testarrayofsortedstruct))
            for i in reversed(range(len(self.testarrayofsortedstruct))):
                self.testarrayofsortedstruct[i].Pack(builder)
            testarrayofsortedstruct = builder.EndVector()
        if self.flex is not None:
            if np is not None and type(self.flex) is np.ndarray:
                flex = builder.CreateNumpyVector(self.flex)
            else:
                MonsterStartFlexVector(builder, len(self.flex))
                for i in reversed(range(len(self.flex))):
                    builder.PrependUint8(self.flex[i])
                flex = builder.EndVector()
        if self.test5 is not None:
            MonsterStartTest5Vector(builder, len(self.test5))
            for i in reversed(range(len(self.test5))):
                self.test5[i].Pack(builder)
            test5 = builder.EndVector()
        if self.vectorOfLongs is not None:
            if np is not None and type(self.vectorOfLongs) is np.ndarray:
                vectorOfLongs = builder.CreateNumpyVector(self.vectorOfLongs)
            else:
                MonsterStartVectorOfLongsVector(builder, len(self.vectorOfLongs))
                for i in reversed(range(len(self.vectorOfLongs))):
                    builder.PrependInt64(self.vectorOfLongs[i])
                vectorOfLongs = builder.EndVector()
        if self.vectorOfDoubles is not None:
            if np is not None and type(self.vectorOfDoubles) is np.ndarray:
                vectorOfDoubles = builder.CreateNumpyVector(self.vectorOfDoubles)
            else:
                MonsterStartVectorOfDoublesVector(builder, len(self.vectorOfDoubles))
                for i in reversed(range(len(self.vectorOfDoubles))):
                    builder.PrependFloat64(self.vectorOfDoubles[i])
                vectorOfDoubles = builder.EndVector()
        if self.parentNamespaceTest is not None:
            parentNamespaceTest = self.parentNamespaceTest.Pack(builder)
        if self.vectorOfReferrables is not None:
            vectorOfReferrableslist = []
            for i in range(len(self.vectorOfReferrables)):
                vectorOfReferrableslist.append(self.vectorOfReferrables[i].Pack(builder))
            MonsterStartVectorOfReferrablesVector(builder, len(self.vectorOfReferrables))
            for i in reversed(range(len(self.vectorOfReferrables))):
                builder.PrependUOffsetTRelative(vectorOfReferrableslist[i])
            vectorOfReferrables = builder.EndVector()
        if self.vectorOfWeakReferences is not None:
            if np is not None and type(self.vectorOfWeakReferences) is np.ndarray:
                vectorOfWeakReferences = builder.CreateNumpyVector(self.vectorOfWeakReferences)
            else:
                MonsterStartVectorOfWeakReferencesVector(builder, len(self.vectorOfWeakReferences))
                for i in reversed(range(len(self.vectorOfWeakReferences))):
                    builder.PrependUint64(self.vectorOfWeakReferences[i])
                vectorOfWeakReferences = builder.EndVector()
        if self.vectorOfStrongReferrables is not None:
            vectorOfStrongReferrableslist = []
            for i in range(len(self.vectorOfStrongReferrables)):
                vectorOfStrongReferrableslist.append(self.vectorOfStrongReferrables[i].Pack(builder))
            MonsterStartVectorOfStrongReferrablesVector(builder, len(self.vectorOfStrongReferrables))
            for i in reversed(range(len(self.vectorOfStrongReferrables))):
                builder.PrependUOffsetTRelative(vectorOfStrongReferrableslist[i])
            vectorOfStrongReferrables = builder.EndVector()
        if self.vectorOfCoOwningReferences is not None:
            if np is not None and type(self.vectorOfCoOwningReferences) is np.ndarray:
                vectorOfCoOwningReferences = builder.CreateNumpyVector(self.vectorOfCoOwningReferences)
            else:
                MonsterStartVectorOfCoOwningReferencesVector(builder, len(self.vectorOfCoOwningReferences))
                for i in reversed(range(len(self.vectorOfCoOwningReferences))):
                    builder.PrependUint64(self.vectorOfCoOwningReferences[i])
                vectorOfCoOwningReferences = builder.EndVector()
        if self.vectorOfNonOwningReferences is not None:
            if np is not None and type(self.vectorOfNonOwningReferences) is np.ndarray:
                vectorOfNonOwningReferences = builder.CreateNumpyVector(self.vectorOfNonOwningReferences)
            else:
                MonsterStartVectorOfNonOwningReferencesVector(builder, len(self.vectorOfNonOwningReferences))
                for i in reversed(range(len(self.vectorOfNonOwningReferences))):
                    builder.PrependUint64(self.vectorOfNonOwningReferences[i])
                vectorOfNonOwningReferences = builder.EndVector()
        if self.anyUnique is not None:
            anyUnique = self.anyUnique.Pack(builder)
        if self.anyAmbiguous is not None:
            anyAmbiguous = self.anyAmbiguous.Pack(builder)
        if self.vectorOfEnums is not None:
            if np is not None and type(self.vectorOfEnums) is np.ndarray:
                vectorOfEnums = builder.CreateNumpyVector(self.vectorOfEnums)
            else:
                MonsterStartVectorOfEnumsVector(builder, len(self.vectorOfEnums))
                for i in reversed(range(len(self.vectorOfEnums))):
                    builder.PrependUint8(self.vectorOfEnums[i])
                vectorOfEnums = builder.EndVector()
        if self.testrequirednestedflatbuffer is not None:
            if np is not None and type(self.testrequirednestedflatbuffer) is np.ndarray:
                testrequirednestedflatbuffer = builder.CreateNumpyVector(self.testrequirednestedflatbuffer)
            else:
                MonsterStartTestrequirednestedflatbufferVector(builder, len(self.testrequirednestedflatbuffer))
                for i in reversed(range(len(self.testrequirednestedflatbuffer))):
                    builder.PrependUint8(self.testrequirednestedflatbuffer[i])
                testrequirednestedflatbuffer = builder.EndVector()
        if self.scalarKeySortedTables is not None:
            scalarKeySortedTableslist = []
            for i in range(len(self.scalarKeySortedTables)):
                scalarKeySortedTableslist.append(self.scalarKeySortedTables[i].Pack(builder))
            MonsterStartScalarKeySortedTablesVector(builder, len(self.scalarKeySortedTables))
            for i in reversed(range(len(self.scalarKeySortedTables))):
                builder.PrependUOffsetTRelative(scalarKeySortedTableslist[i])
            scalarKeySortedTables = builder.EndVector()
        MonsterStart(builder)
        if self.pos is not None:
            pos = self.pos.Pack(builder)
            MonsterAddPos(builder, pos)
        MonsterAddMana(builder, self.mana)
        MonsterAddHp(builder, self.hp)
        if self.name is not None:
            MonsterAddName(builder, name)
        if self.inventory is not None:
            MonsterAddInventory(builder, inventory)
        MonsterAddColor(builder, self.color)
        MonsterAddTestType(builder, self.testType)
        if self.test is not None:
            MonsterAddTest(builder, test)
        if self.test4 is not None:
            MonsterAddTest4(builder, test4)
        if self.testarrayofstring is not None:
            MonsterAddTestarrayofstring(builder, testarrayofstring)
        if self.testarrayoftables is not None:
            MonsterAddTestarrayoftables(builder, testarrayoftables)
        if self.enemy is not None:
            MonsterAddEnemy(builder, enemy)
        if self.testnestedflatbuffer is not None:
            MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer)
        if self.testempty is not None:
            MonsterAddTestempty(builder, testempty)
        MonsterAddTestbool(builder, self.testbool)
        MonsterAddTesthashs32Fnv1(builder, self.testhashs32Fnv1)
        MonsterAddTesthashu32Fnv1(builder, self.testhashu32Fnv1)
        MonsterAddTesthashs64Fnv1(builder, self.testhashs64Fnv1)
        MonsterAddTesthashu64Fnv1(builder, self.testhashu64Fnv1)
        MonsterAddTesthashs32Fnv1a(builder, self.testhashs32Fnv1a)
        MonsterAddTesthashu32Fnv1a(builder, self.testhashu32Fnv1a)
        MonsterAddTesthashs64Fnv1a(builder, self.testhashs64Fnv1a)
        MonsterAddTesthashu64Fnv1a(builder, self.testhashu64Fnv1a)
        if self.testarrayofbools is not None:
            MonsterAddTestarrayofbools(builder, testarrayofbools)
        MonsterAddTestf(builder, self.testf)
        MonsterAddTestf2(builder, self.testf2)
        MonsterAddTestf3(builder, self.testf3)
        if self.testarrayofstring2 is not None:
            MonsterAddTestarrayofstring2(builder, testarrayofstring2)
        if self.testarrayofsortedstruct is not None:
            MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct)
        if self.flex is not None:
            MonsterAddFlex(builder, flex)
        if self.test5 is not None:
            MonsterAddTest5(builder, test5)
        if self.vectorOfLongs is not None:
            MonsterAddVectorOfLongs(builder, vectorOfLongs)
        if self.vectorOfDoubles is not None:
            MonsterAddVectorOfDoubles(builder, vectorOfDoubles)
        if self.parentNamespaceTest is not None:
            MonsterAddParentNamespaceTest(builder, parentNamespaceTest)
        if self.vectorOfReferrables is not None:
            MonsterAddVectorOfReferrables(builder, vectorOfReferrables)
        MonsterAddSingleWeakReference(builder, self.singleWeakReference)
        if self.vectorOfWeakReferences is not None:
            MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences)
        if self.vectorOfStrongReferrables is not None:
            MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables)
        MonsterAddCoOwningReference(builder, self.coOwningReference)
        if self.vectorOfCoOwningReferences is not None:
            MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences)
        MonsterAddNonOwningReference(builder, self.nonOwningReference)
        if self.vectorOfNonOwningReferences is not None:
            MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences)
        MonsterAddAnyUniqueType(builder, self.anyUniqueType)
        if self.anyUnique is not None:
            MonsterAddAnyUnique(builder, anyUnique)
        MonsterAddAnyAmbiguousType(builder, self.anyAmbiguousType)
        if self.anyAmbiguous is not None:
            MonsterAddAnyAmbiguous(builder, anyAmbiguous)
        if self.vectorOfEnums is not None:
            MonsterAddVectorOfEnums(builder, vectorOfEnums)
        MonsterAddSignedEnum(builder, self.signedEnum)
        if self.testrequirednestedflatbuffer is not None:
            MonsterAddTestrequirednestedflatbuffer(builder, testrequirednestedflatbuffer)
        if self.scalarKeySortedTables is not None:
            MonsterAddScalarKeySortedTables(builder, scalarKeySortedTables)
        if self.nativeInline is not None:
            nativeInline = self.nativeInline.Pack(builder)
            MonsterAddNativeInline(builder, nativeInline)
        MonsterAddLongEnumNonEnumDefault(builder, self.longEnumNonEnumDefault)
        MonsterAddLongEnumNormalDefault(builder, self.longEnumNormalDefault)
        MonsterAddNanDefault(builder, self.nanDefault)
        MonsterAddInfDefault(builder, self.infDefault)
        MonsterAddPositiveInfDefault(builder, self.positiveInfDefault)
        MonsterAddInfinityDefault(builder, self.infinityDefault)
        MonsterAddPositiveInfinityDefault(builder, self.positiveInfinityDefault)
        MonsterAddNegativeInfDefault(builder, self.negativeInfDefault)
        MonsterAddNegativeInfinityDefault(builder, self.negativeInfinityDefault)
        MonsterAddDoubleInfDefault(builder, self.doubleInfDefault)
        monster = MonsterEnd(builder)
        return monster


class TypeAliases(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = TypeAliases()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsTypeAliases(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def TypeAliasesBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)

    # TypeAliases
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # TypeAliases
    def I8(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
        return 0

    # TypeAliases
    def U8(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
        return 0

    # TypeAliases
    def I16(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int16Flags, o + self._tab.Pos)
        return 0

    # TypeAliases
    def U16(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint16Flags, o + self._tab.Pos)
        return 0

    # TypeAliases
    def I32(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
        return 0

    # TypeAliases
    def U32(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint32Flags, o + self._tab.Pos)
        return 0

    # TypeAliases
    def I64(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
        return 0

    # TypeAliases
    def U64(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Uint64Flags, o + self._tab.Pos)
        return 0

    # TypeAliases
    def F32(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
        return 0.0

    # TypeAliases
    def F64(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
        if o != 0:
            return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
        return 0.0

    # TypeAliases
    def V8(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Int8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # TypeAliases
    def V8AsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int8Flags, o)
        return 0

    # TypeAliases
    def V8Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # TypeAliases
    def V8IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
        return o == 0

    # TypeAliases
    def Vf64(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
        return 0

    # TypeAliases
    def Vf64AsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
        return 0

    # TypeAliases
    def Vf64Length(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # TypeAliases
    def Vf64IsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
        return o == 0

def TypeAliasesStart(builder):
    builder.StartObject(12)

def TypeAliasesAddI8(builder, i8):
    builder.PrependInt8Slot(0, i8, 0)

def TypeAliasesAddU8(builder, u8):
    builder.PrependUint8Slot(1, u8, 0)

def TypeAliasesAddI16(builder, i16):
    builder.PrependInt16Slot(2, i16, 0)

def TypeAliasesAddU16(builder, u16):
    builder.PrependUint16Slot(3, u16, 0)

def TypeAliasesAddI32(builder, i32):
    builder.PrependInt32Slot(4, i32, 0)

def TypeAliasesAddU32(builder, u32):
    builder.PrependUint32Slot(5, u32, 0)

def TypeAliasesAddI64(builder, i64):
    builder.PrependInt64Slot(6, i64, 0)

def TypeAliasesAddU64(builder, u64):
    builder.PrependUint64Slot(7, u64, 0)

def TypeAliasesAddF32(builder, f32):
    builder.PrependFloat32Slot(8, f32, 0.0)

def TypeAliasesAddF64(builder, f64):
    builder.PrependFloat64Slot(9, f64, 0.0)

def TypeAliasesAddV8(builder, v8):
    builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(v8), 0)

def TypeAliasesStartV8Vector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def TypeAliasesCreateV8Vector(builder, data):
    data = list(data)
    builder.StartVector(1, len(data), 1)
    for item in reversed(data):
        builder.PrependInt8(item)
    return builder.EndVector()

def TypeAliasesAddVf64(builder, vf64):
    builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(vf64), 0)

def TypeAliasesStartVf64Vector(builder, numElems):
    return builder.StartVector(8, numElems, 8)

def TypeAliasesCreateVf64Vector(builder, data):
    data = list(data)
    builder.StartVector(8, len(data), 8)
    for item in reversed(data):
        builder.PrependFloat64(item)
    return builder.EndVector()

def TypeAliasesEnd(builder):
    return builder.EndObject()


try:
    from typing import List
except:
    pass

class TypeAliasesT(object):

    # TypeAliasesT
    def __init__(
        self,
        i8 = 0,
        u8 = 0,
        i16 = 0,
        u16 = 0,
        i32 = 0,
        u32 = 0,
        i64 = 0,
        u64 = 0,
        f32 = 0.0,
        f64 = 0.0,
        v8 = None,
        vf64 = None,
    ):
        self.i8 = i8  # type: int
        self.u8 = u8  # type: int
        self.i16 = i16  # type: int
        self.u16 = u16  # type: int
        self.i32 = i32  # type: int
        self.u32 = u32  # type: int
        self.i64 = i64  # type: int
        self.u64 = u64  # type: int
        self.f32 = f32  # type: float
        self.f64 = f64  # type: float
        self.v8 = v8  # type: Optional[List[int]]
        self.vf64 = vf64  # type: Optional[List[float]]

    @classmethod
    def InitFromBuf(cls, buf, pos):
        typeAliases = TypeAliases()
        typeAliases.Init(buf, pos)
        return cls.InitFromObj(typeAliases)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, typeAliases):
        x = TypeAliasesT()
        x._UnPack(typeAliases)
        return x

    # TypeAliasesT
    def _UnPack(self, typeAliases):
        if typeAliases is None:
            return
        self.i8 = typeAliases.I8()
        self.u8 = typeAliases.U8()
        self.i16 = typeAliases.I16()
        self.u16 = typeAliases.U16()
        self.i32 = typeAliases.I32()
        self.u32 = typeAliases.U32()
        self.i64 = typeAliases.I64()
        self.u64 = typeAliases.U64()
        self.f32 = typeAliases.F32()
        self.f64 = typeAliases.F64()
        if not typeAliases.V8IsNone():
            if np is None:
                self.v8 = []
                for i in range(typeAliases.V8Length()):
                    self.v8.append(typeAliases.V8(i))
            else:
                self.v8 = typeAliases.V8AsNumpy()
        if not typeAliases.Vf64IsNone():
            if np is None:
                self.vf64 = []
                for i in range(typeAliases.Vf64Length()):
                    self.vf64.append(typeAliases.Vf64(i))
            else:
                self.vf64 = typeAliases.Vf64AsNumpy()

    # TypeAliasesT
    def Pack(self, builder):
        if self.v8 is not None:
            if np is not None and type(self.v8) is np.ndarray:
                v8 = builder.CreateNumpyVector(self.v8)
            else:
                TypeAliasesStartV8Vector(builder, len(self.v8))
                for i in reversed(range(len(self.v8))):
                    builder.PrependByte(self.v8[i])
                v8 = builder.EndVector()
        if self.vf64 is not None:
            if np is not None and type(self.vf64) is np.ndarray:
                vf64 = builder.CreateNumpyVector(self.vf64)
            else:
                TypeAliasesStartVf64Vector(builder, len(self.vf64))
                for i in reversed(range(len(self.vf64))):
                    builder.PrependFloat64(self.vf64[i])
                vf64 = builder.EndVector()
        TypeAliasesStart(builder)
        TypeAliasesAddI8(builder, self.i8)
        TypeAliasesAddU8(builder, self.u8)
        TypeAliasesAddI16(builder, self.i16)
        TypeAliasesAddU16(builder, self.u16)
        TypeAliasesAddI32(builder, self.i32)
        TypeAliasesAddU32(builder, self.u32)
        TypeAliasesAddI64(builder, self.i64)
        TypeAliasesAddU64(builder, self.u64)
        TypeAliasesAddF32(builder, self.f32)
        TypeAliasesAddF64(builder, self.f64)
        if self.v8 is not None:
            TypeAliasesAddV8(builder, v8)
        if self.vf64 is not None:
            TypeAliasesAddVf64(builder, vf64)
        typeAliases = TypeAliasesEnd(builder)
        return typeAliases


