# 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):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0)
        inParentNamespace = InParentNamespace()
        inParentNamespace.Init(buf, pos+n)
        return cls.InitFromObj(inParentNamespace)

    @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):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, 0)
        monster = Monster()
        monster.Init(buf, pos+n)
        return cls.InitFromObj(monster)

    @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):
        self.a = 0  # type: int
        self.b = 0  # type: int

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

    @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):
        self.color = 2  # type: int

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

    @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):
        self.x = 0.0  # type: float
        self.y = 0.0  # type: float
        self.z = 0.0  # type: float
        self.test1 = 0.0  # type: float
        self.test2 = 0  # type: int
        self.test3 = None  # type: Optional[TestT]

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

    @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):
        self.id = 0  # type: int
        self.distance = 0  # type: int

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

    @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):
        self.a = None  # type: Optional[AbilityT]
        self.b = None  # type: Optional[TestT]
        self.c = None  # type: Optional[AbilityT]

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

    @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):
        self.a = None  # type: Optional[StructOfStructsT]

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

    @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):
        self.id = None  # type: str
        self.val = 0  # type: int
        self.count = 0  # type: int

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

    @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):
        self.id = 0  # type: int

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

    @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.GetRootAsMonster(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.GetRootAsMonster(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

def MonsterStart(builder): builder.StartObject(54)
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 MonsterEnd(builder): return builder.EndObject()

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

class MonsterT(object):

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

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

    @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()

    # 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)
        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 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 TypeAliasesEnd(builder): return builder.EndObject()

try:
    from typing import List
except:
    pass

class TypeAliasesT(object):

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

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

    @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


