From 219fb73cd923bdbc6ebe47a1b67b97578a1536e9 Mon Sep 17 00:00:00 2001
From: Wei Gao <gaowei66@huawei.com>
Date: Wed, 15 Jul 2020 22:19:37 -0400
Subject: [PATCH] kata-runtime: add support of new sandbox quantvisor.

Signed-off-by: Wei Gao <gaowei66@huawei.com>
---
 pkg/katautils/config.go                            |   4 +
 .../agent/protocols/grpc/agent.pb.go               | 853 +++++++++++++++------
 virtcontainers/agent.go                            |   8 +
 virtcontainers/hypervisor.go                       |   9 +
 virtcontainers/kata_agent.go                       |  29 +
 virtcontainers/noop_agent.go                       |   9 +
 virtcontainers/quantvisor.go                       | 687 +++++++++++++++++
 virtcontainers/sandbox.go                          |  14 +
 virtcontainers/types/capabilities.go               |  11 +
 virtcontainers/vm.go                               |  11 +
 10 files changed, 1401 insertions(+), 234 deletions(-)
 create mode 100644 virtcontainers/quantvisor.go

diff --git a/pkg/katautils/config.go b/pkg/katautils/config.go
index 9105bc6..f98b3cb 100644
--- a/pkg/katautils/config.go
+++ b/pkg/katautils/config.go
@@ -51,6 +51,7 @@ const (
 	// supported hypervisor component types
 	firecrackerHypervisorTableType = "firecracker"
 	qemuHypervisorTableType        = "qemu"
+	quantvisorHypervisorTableType        = "quantvisor"
 
 	// supported proxy component types
 	kataProxyTableType = "kata"
@@ -717,6 +718,9 @@ func updateRuntimeConfigHypervisor(configPath string, tomlConf tomlConfig, confi
 		case qemuHypervisorTableType:
 			config.HypervisorType = vc.QemuHypervisor
 			hConfig, err = newQemuHypervisorConfig(hypervisor)
+		case quantvisorHypervisorTableType:
+			config.HypervisorType = vc.QuantvisorHypervisor
+			hConfig, err = newQemuHypervisorConfig(hypervisor)
 		}
 
 		if err != nil {
diff --git a/vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go b/vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go
index d1cf285..2c2523d 100644
--- a/vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go
+++ b/vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go
@@ -52,10 +52,12 @@
 		Interfaces
 		Routes
 		UpdateInterfaceRequest
+		UpdateInterfaceHwAddrByNameRequest
 		UpdateRoutesRequest
 		ListInterfacesRequest
 		ListRoutesRequest
 		OnlineCPUMemRequest
+		OfflineCPURequest
 		ReseedRandomDevRequest
 		AgentDetails
 		GuestDetailsRequest
@@ -1539,6 +1541,24 @@ func (m *UpdateInterfaceRequest) GetInterface() *types.Interface {
 	return nil
 }
 
+type UpdateInterfaceHwAddrByNameRequest struct {
+	Interface *types.Interface `protobuf:"bytes,1,opt,name=interface" json:"interface,omitempty"`
+}
+
+func (m *UpdateInterfaceHwAddrByNameRequest) Reset()         { *m = UpdateInterfaceHwAddrByNameRequest{} }
+func (m *UpdateInterfaceHwAddrByNameRequest) String() string { return proto.CompactTextString(m) }
+func (*UpdateInterfaceHwAddrByNameRequest) ProtoMessage()    {}
+func (*UpdateInterfaceHwAddrByNameRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptorAgent, []int{42}
+}
+
+func (m *UpdateInterfaceHwAddrByNameRequest) GetInterface() *types.Interface {
+	if m != nil {
+		return m.Interface
+	}
+	return nil
+}
+
 type UpdateRoutesRequest struct {
 	Routes    *Routes `protobuf:"bytes,1,opt,name=routes" json:"routes,omitempty"`
 	Increment bool    `protobuf:"varint,2,opt,name=increment,proto3" json:"increment,omitempty"`
@@ -1547,7 +1567,7 @@ type UpdateRoutesRequest struct {
 func (m *UpdateRoutesRequest) Reset()                    { *m = UpdateRoutesRequest{} }
 func (m *UpdateRoutesRequest) String() string            { return proto.CompactTextString(m) }
 func (*UpdateRoutesRequest) ProtoMessage()               {}
-func (*UpdateRoutesRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{42} }
+func (*UpdateRoutesRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{43} }
 
 func (m *UpdateRoutesRequest) GetRoutes() *Routes {
 	if m != nil {
@@ -1569,7 +1589,7 @@ type ListInterfacesRequest struct {
 func (m *ListInterfacesRequest) Reset()                    { *m = ListInterfacesRequest{} }
 func (m *ListInterfacesRequest) String() string            { return proto.CompactTextString(m) }
 func (*ListInterfacesRequest) ProtoMessage()               {}
-func (*ListInterfacesRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{43} }
+func (*ListInterfacesRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{44} }
 
 type ListRoutesRequest struct {
 }
@@ -1577,10 +1597,10 @@ type ListRoutesRequest struct {
 func (m *ListRoutesRequest) Reset()                    { *m = ListRoutesRequest{} }
 func (m *ListRoutesRequest) String() string            { return proto.CompactTextString(m) }
 func (*ListRoutesRequest) ProtoMessage()               {}
-func (*ListRoutesRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{44} }
+func (*ListRoutesRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{45} }
 
 type OnlineCPUMemRequest struct {
-	// Wait specifies if the caller waits for the agent to online all resources.
+	// Wait specifies if the caller waits for the agent to offline all resources.
 	// If true the agent returns once all resources have been connected, otherwise all
 	// resources are connected asynchronously and the agent returns immediately.
 	Wait bool `protobuf:"varint,1,opt,name=wait,proto3" json:"wait,omitempty"`
@@ -1593,7 +1613,7 @@ type OnlineCPUMemRequest struct {
 func (m *OnlineCPUMemRequest) Reset()                    { *m = OnlineCPUMemRequest{} }
 func (m *OnlineCPUMemRequest) String() string            { return proto.CompactTextString(m) }
 func (*OnlineCPUMemRequest) ProtoMessage()               {}
-func (*OnlineCPUMemRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{45} }
+func (*OnlineCPUMemRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{46} }
 
 func (m *OnlineCPUMemRequest) GetWait() bool {
 	if m != nil {
@@ -1616,6 +1636,34 @@ func (m *OnlineCPUMemRequest) GetCpuOnly() bool {
 	return false
 }
 
+type OfflineCPURequest struct {
+	// Wait specifies if the caller waits for the agent to offline all resources.
+	// If true the agent returns once all resources have been connected, otherwise all
+	// resources are disconnected asynchronously and the agent returns immediately.
+	Wait bool `protobuf:"varint,1,opt,name=wait,proto3" json:"wait,omitempty"`
+	// NbCpus specifies the number of CPUs that were added and the agent has to offline.
+	NbCpus uint32 `protobuf:"varint,2,opt,name=nb_cpus,json=nbCpus,proto3" json:"nb_cpus,omitempty"`
+}
+
+func (m *OfflineCPURequest) Reset()                    { *m = OfflineCPURequest{} }
+func (m *OfflineCPURequest) String() string            { return proto.CompactTextString(m) }
+func (*OfflineCPURequest) ProtoMessage()               {}
+func (*OfflineCPURequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{47} }
+
+func (m *OfflineCPURequest) GetWait() bool {
+	if m != nil {
+		return m.Wait
+	}
+	return false
+}
+
+func (m *OfflineCPURequest) GetNbCpus() uint32 {
+	if m != nil {
+		return m.NbCpus
+	}
+	return 0
+}
+
 type ReseedRandomDevRequest struct {
 	// Data specifies the random data used to reseed the guest crng.
 	Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
@@ -1624,7 +1672,7 @@ type ReseedRandomDevRequest struct {
 func (m *ReseedRandomDevRequest) Reset()                    { *m = ReseedRandomDevRequest{} }
 func (m *ReseedRandomDevRequest) String() string            { return proto.CompactTextString(m) }
 func (*ReseedRandomDevRequest) ProtoMessage()               {}
-func (*ReseedRandomDevRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{46} }
+func (*ReseedRandomDevRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{48} }
 
 func (m *ReseedRandomDevRequest) GetData() []byte {
 	if m != nil {
@@ -1651,7 +1699,7 @@ type AgentDetails struct {
 func (m *AgentDetails) Reset()                    { *m = AgentDetails{} }
 func (m *AgentDetails) String() string            { return proto.CompactTextString(m) }
 func (*AgentDetails) ProtoMessage()               {}
-func (*AgentDetails) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{47} }
+func (*AgentDetails) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{49} }
 
 func (m *AgentDetails) GetVersion() string {
 	if m != nil {
@@ -1702,7 +1750,7 @@ type GuestDetailsRequest struct {
 func (m *GuestDetailsRequest) Reset()                    { *m = GuestDetailsRequest{} }
 func (m *GuestDetailsRequest) String() string            { return proto.CompactTextString(m) }
 func (*GuestDetailsRequest) ProtoMessage()               {}
-func (*GuestDetailsRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{48} }
+func (*GuestDetailsRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{50} }
 
 func (m *GuestDetailsRequest) GetMemBlockSize() bool {
 	if m != nil {
@@ -1728,7 +1776,7 @@ type GuestDetailsResponse struct {
 func (m *GuestDetailsResponse) Reset()                    { *m = GuestDetailsResponse{} }
 func (m *GuestDetailsResponse) String() string            { return proto.CompactTextString(m) }
 func (*GuestDetailsResponse) ProtoMessage()               {}
-func (*GuestDetailsResponse) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{49} }
+func (*GuestDetailsResponse) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{51} }
 
 func (m *GuestDetailsResponse) GetMemBlockSizeBytes() uint64 {
 	if m != nil {
@@ -1760,7 +1808,7 @@ type MemHotplugByProbeRequest struct {
 func (m *MemHotplugByProbeRequest) Reset()                    { *m = MemHotplugByProbeRequest{} }
 func (m *MemHotplugByProbeRequest) String() string            { return proto.CompactTextString(m) }
 func (*MemHotplugByProbeRequest) ProtoMessage()               {}
-func (*MemHotplugByProbeRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{50} }
+func (*MemHotplugByProbeRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{52} }
 
 func (m *MemHotplugByProbeRequest) GetMemHotplugProbeAddr() []uint64 {
 	if m != nil {
@@ -1779,7 +1827,7 @@ type SetGuestDateTimeRequest struct {
 func (m *SetGuestDateTimeRequest) Reset()                    { *m = SetGuestDateTimeRequest{} }
 func (m *SetGuestDateTimeRequest) String() string            { return proto.CompactTextString(m) }
 func (*SetGuestDateTimeRequest) ProtoMessage()               {}
-func (*SetGuestDateTimeRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{51} }
+func (*SetGuestDateTimeRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{53} }
 
 func (m *SetGuestDateTimeRequest) GetSec() int64 {
 	if m != nil {
@@ -1828,7 +1876,7 @@ type Storage struct {
 func (m *Storage) Reset()                    { *m = Storage{} }
 func (m *Storage) String() string            { return proto.CompactTextString(m) }
 func (*Storage) ProtoMessage()               {}
-func (*Storage) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{52} }
+func (*Storage) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{54} }
 
 func (m *Storage) GetDriver() string {
 	if m != nil {
@@ -1911,7 +1959,7 @@ type Device struct {
 func (m *Device) Reset()                    { *m = Device{} }
 func (m *Device) String() string            { return proto.CompactTextString(m) }
 func (*Device) ProtoMessage()               {}
-func (*Device) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{53} }
+func (*Device) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{55} }
 
 func (m *Device) GetId() string {
 	if m != nil {
@@ -1957,7 +2005,7 @@ type StringUser struct {
 func (m *StringUser) Reset()                    { *m = StringUser{} }
 func (m *StringUser) String() string            { return proto.CompactTextString(m) }
 func (*StringUser) ProtoMessage()               {}
-func (*StringUser) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{54} }
+func (*StringUser) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{56} }
 
 func (m *StringUser) GetUid() string {
 	if m != nil {
@@ -2005,7 +2053,7 @@ type CopyFileRequest struct {
 func (m *CopyFileRequest) Reset()                    { *m = CopyFileRequest{} }
 func (m *CopyFileRequest) String() string            { return proto.CompactTextString(m) }
 func (*CopyFileRequest) ProtoMessage()               {}
-func (*CopyFileRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{55} }
+func (*CopyFileRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{57} }
 
 func (m *CopyFileRequest) GetPath() string {
 	if m != nil {
@@ -2070,7 +2118,7 @@ type InstallDeviceDriverRequest struct {
 func (m *InstallDeviceDriverRequest) Reset()                    { *m = InstallDeviceDriverRequest{} }
 func (m *InstallDeviceDriverRequest) String() string            { return proto.CompactTextString(m) }
 func (*InstallDeviceDriverRequest) ProtoMessage()               {}
-func (*InstallDeviceDriverRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{56} }
+func (*InstallDeviceDriverRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{58} }
 
 func (m *InstallDeviceDriverRequest) GetDeviceType() string {
 	if m != nil {
@@ -2085,7 +2133,7 @@ type StartTracingRequest struct {
 func (m *StartTracingRequest) Reset()                    { *m = StartTracingRequest{} }
 func (m *StartTracingRequest) String() string            { return proto.CompactTextString(m) }
 func (*StartTracingRequest) ProtoMessage()               {}
-func (*StartTracingRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{57} }
+func (*StartTracingRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{59} }
 
 type StopTracingRequest struct {
 }
@@ -2093,7 +2141,7 @@ type StopTracingRequest struct {
 func (m *StopTracingRequest) Reset()                    { *m = StopTracingRequest{} }
 func (m *StopTracingRequest) String() string            { return proto.CompactTextString(m) }
 func (*StopTracingRequest) ProtoMessage()               {}
-func (*StopTracingRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{58} }
+func (*StopTracingRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{60} }
 
 type Ipvs struct {
 	Rule string `protobuf:"bytes,1,opt,name=Rule,proto3" json:"Rule,omitempty"`
@@ -2102,7 +2150,7 @@ type Ipvs struct {
 func (m *Ipvs) Reset()                    { *m = Ipvs{} }
 func (m *Ipvs) String() string            { return proto.CompactTextString(m) }
 func (*Ipvs) ProtoMessage()               {}
-func (*Ipvs) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{59} }
+func (*Ipvs) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{61} }
 
 func (m *Ipvs) GetRule() string {
 	if m != nil {
@@ -2118,7 +2166,7 @@ type UpdateIpvsRequest struct {
 func (m *UpdateIpvsRequest) Reset()                    { *m = UpdateIpvsRequest{} }
 func (m *UpdateIpvsRequest) String() string            { return proto.CompactTextString(m) }
 func (*UpdateIpvsRequest) ProtoMessage()               {}
-func (*UpdateIpvsRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{60} }
+func (*UpdateIpvsRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{62} }
 
 func (m *UpdateIpvsRequest) GetIpvss() *Ipvs {
 	if m != nil {
@@ -2134,7 +2182,7 @@ type IpvsResponse struct {
 func (m *IpvsResponse) Reset()                    { *m = IpvsResponse{} }
 func (m *IpvsResponse) String() string            { return proto.CompactTextString(m) }
 func (*IpvsResponse) ProtoMessage()               {}
-func (*IpvsResponse) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{61} }
+func (*IpvsResponse) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{63} }
 
 func (m *IpvsResponse) GetIpvsRes() string {
 	if m != nil {
@@ -2186,10 +2234,12 @@ func init() {
 	proto.RegisterType((*Interfaces)(nil), "grpc.Interfaces")
 	proto.RegisterType((*Routes)(nil), "grpc.Routes")
 	proto.RegisterType((*UpdateInterfaceRequest)(nil), "grpc.UpdateInterfaceRequest")
+	proto.RegisterType((*UpdateInterfaceHwAddrByNameRequest)(nil), "grpc.UpdateInterfaceHwAddrByNameRequest")
 	proto.RegisterType((*UpdateRoutesRequest)(nil), "grpc.UpdateRoutesRequest")
 	proto.RegisterType((*ListInterfacesRequest)(nil), "grpc.ListInterfacesRequest")
 	proto.RegisterType((*ListRoutesRequest)(nil), "grpc.ListRoutesRequest")
 	proto.RegisterType((*OnlineCPUMemRequest)(nil), "grpc.OnlineCPUMemRequest")
+	proto.RegisterType((*OfflineCPURequest)(nil), "grpc.OfflineCPURequest")
 	proto.RegisterType((*ReseedRandomDevRequest)(nil), "grpc.ReseedRandomDevRequest")
 	proto.RegisterType((*AgentDetails)(nil), "grpc.AgentDetails")
 	proto.RegisterType((*GuestDetailsRequest)(nil), "grpc.GuestDetailsRequest")
@@ -2246,6 +2296,7 @@ type AgentServiceClient interface {
 	TtyWinResize(ctx context.Context, in *TtyWinResizeRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error)
 	// networking
 	UpdateInterface(ctx context.Context, in *UpdateInterfaceRequest, opts ...grpc1.CallOption) (*types.Interface, error)
+	UpdateInterfaceHwAddrByName(ctx context.Context, in *UpdateInterfaceHwAddrByNameRequest, opts ...grpc1.CallOption) (*types.Interface, error)
 	UpdateRoutes(ctx context.Context, in *UpdateRoutesRequest, opts ...grpc1.CallOption) (*Routes, error)
 	ListInterfaces(ctx context.Context, in *ListInterfacesRequest, opts ...grpc1.CallOption) (*Interfaces, error)
 	ListRoutes(ctx context.Context, in *ListRoutesRequest, opts ...grpc1.CallOption) (*Routes, error)
@@ -2256,6 +2307,7 @@ type AgentServiceClient interface {
 	CreateSandbox(ctx context.Context, in *CreateSandboxRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error)
 	DestroySandbox(ctx context.Context, in *DestroySandboxRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error)
 	OnlineCPUMem(ctx context.Context, in *OnlineCPUMemRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error)
+	OfflineCPU(ctx context.Context, in *OfflineCPURequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error)
 	ReseedRandomDev(ctx context.Context, in *ReseedRandomDevRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error)
 	GetGuestDetails(ctx context.Context, in *GuestDetailsRequest, opts ...grpc1.CallOption) (*GuestDetailsResponse, error)
 	MemHotplugByProbe(ctx context.Context, in *MemHotplugByProbeRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error)
@@ -2435,6 +2487,15 @@ func (c *agentServiceClient) UpdateInterface(ctx context.Context, in *UpdateInte
 	return out, nil
 }
 
+func (c *agentServiceClient) UpdateInterfaceHwAddrByName(ctx context.Context, in *UpdateInterfaceHwAddrByNameRequest, opts ...grpc1.CallOption) (*types.Interface, error) {
+	out := new(types.Interface)
+	err := grpc1.Invoke(ctx, "/grpc.AgentService/UpdateInterfaceHwAddrByName", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 func (c *agentServiceClient) UpdateRoutes(ctx context.Context, in *UpdateRoutesRequest, opts ...grpc1.CallOption) (*Routes, error) {
 	out := new(Routes)
 	err := grpc1.Invoke(ctx, "/grpc.AgentService/UpdateRoutes", in, out, c.cc, opts...)
@@ -2507,6 +2568,15 @@ func (c *agentServiceClient) OnlineCPUMem(ctx context.Context, in *OnlineCPUMemR
 	return out, nil
 }
 
+func (c *agentServiceClient) OfflineCPU(ctx context.Context, in *OfflineCPURequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) {
+	out := new(google_protobuf2.Empty)
+	err := grpc1.Invoke(ctx, "/grpc.AgentService/OfflineCPU", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 func (c *agentServiceClient) ReseedRandomDev(ctx context.Context, in *ReseedRandomDevRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) {
 	out := new(google_protobuf2.Empty)
 	err := grpc1.Invoke(ctx, "/grpc.AgentService/ReseedRandomDev", in, out, c.cc, opts...)
@@ -2600,6 +2670,7 @@ type AgentServiceServer interface {
 	TtyWinResize(context.Context, *TtyWinResizeRequest) (*google_protobuf2.Empty, error)
 	// networking
 	UpdateInterface(context.Context, *UpdateInterfaceRequest) (*types.Interface, error)
+	UpdateInterfaceHwAddrByName(context.Context, *UpdateInterfaceHwAddrByNameRequest) (*types.Interface, error)
 	UpdateRoutes(context.Context, *UpdateRoutesRequest) (*Routes, error)
 	ListInterfaces(context.Context, *ListInterfacesRequest) (*Interfaces, error)
 	ListRoutes(context.Context, *ListRoutesRequest) (*Routes, error)
@@ -2610,6 +2681,7 @@ type AgentServiceServer interface {
 	CreateSandbox(context.Context, *CreateSandboxRequest) (*google_protobuf2.Empty, error)
 	DestroySandbox(context.Context, *DestroySandboxRequest) (*google_protobuf2.Empty, error)
 	OnlineCPUMem(context.Context, *OnlineCPUMemRequest) (*google_protobuf2.Empty, error)
+	OfflineCPU(context.Context, *OfflineCPURequest) (*google_protobuf2.Empty, error)
 	ReseedRandomDev(context.Context, *ReseedRandomDevRequest) (*google_protobuf2.Empty, error)
 	GetGuestDetails(context.Context, *GuestDetailsRequest) (*GuestDetailsResponse, error)
 	MemHotplugByProbe(context.Context, *MemHotplugByProbeRequest) (*google_protobuf2.Empty, error)
@@ -2947,6 +3019,24 @@ func _AgentService_UpdateInterface_Handler(srv interface{}, ctx context.Context,
 	return interceptor(ctx, in, info, handler)
 }
 
+func _AgentService_UpdateInterfaceHwAddrByName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc1.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UpdateInterfaceHwAddrByNameRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AgentServiceServer).UpdateInterfaceHwAddrByName(ctx, in)
+	}
+	info := &grpc1.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/grpc.AgentService/UpdateInterfaceHwAddrByName",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AgentServiceServer).UpdateInterfaceHwAddrByName(ctx, req.(*UpdateInterfaceHwAddrByNameRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 func _AgentService_UpdateRoutes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc1.UnaryServerInterceptor) (interface{}, error) {
 	in := new(UpdateRoutesRequest)
 	if err := dec(in); err != nil {
@@ -3091,6 +3181,24 @@ func _AgentService_OnlineCPUMem_Handler(srv interface{}, ctx context.Context, de
 	return interceptor(ctx, in, info, handler)
 }
 
+func _AgentService_OfflineCPU_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc1.UnaryServerInterceptor) (interface{}, error) {
+	in := new(OfflineCPURequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AgentServiceServer).OfflineCPU(ctx, in)
+	}
+	info := &grpc1.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/grpc.AgentService/OfflineCPU",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AgentServiceServer).OfflineCPU(ctx, req.(*OfflineCPURequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 func _AgentService_ReseedRandomDev_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc1.UnaryServerInterceptor) (interface{}, error) {
 	in := new(ReseedRandomDevRequest)
 	if err := dec(in); err != nil {
@@ -3294,6 +3402,10 @@ var _AgentService_serviceDesc = grpc1.ServiceDesc{
 			Handler:    _AgentService_UpdateInterface_Handler,
 		},
 		{
+			MethodName: "UpdateInterfaceHwAddrByName",
+			Handler:    _AgentService_UpdateInterfaceHwAddrByName_Handler,
+		},
+		{
 			MethodName: "UpdateRoutes",
 			Handler:    _AgentService_UpdateRoutes_Handler,
 		},
@@ -3326,6 +3438,10 @@ var _AgentService_serviceDesc = grpc1.ServiceDesc{
 			Handler:    _AgentService_OnlineCPUMem_Handler,
 		},
 		{
+			MethodName: "OfflineCPU",
+			Handler:    _AgentService_OfflineCPU_Handler,
+		},
+		{
 			MethodName: "ReseedRandomDev",
 			Handler:    _AgentService_ReseedRandomDev_Handler,
 		},
@@ -5095,6 +5211,34 @@ func (m *UpdateInterfaceRequest) MarshalTo(dAtA []byte) (int, error) {
 	return i, nil
 }
 
+func (m *UpdateInterfaceHwAddrByNameRequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *UpdateInterfaceHwAddrByNameRequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Interface != nil {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintAgent(dAtA, i, uint64(m.Interface.Size()))
+		n25, err := m.Interface.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n25
+	}
+	return i, nil
+}
+
 func (m *UpdateRoutesRequest) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -5114,11 +5258,11 @@ func (m *UpdateRoutesRequest) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintAgent(dAtA, i, uint64(m.Routes.Size()))
-		n25, err := m.Routes.MarshalTo(dAtA[i:])
+		n26, err := m.Routes.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n25
+		i += n26
 	}
 	if m.Increment {
 		dAtA[i] = 0x10
@@ -5212,6 +5356,39 @@ func (m *OnlineCPUMemRequest) MarshalTo(dAtA []byte) (int, error) {
 	return i, nil
 }
 
+func (m *OfflineCPURequest) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *OfflineCPURequest) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if m.Wait {
+		dAtA[i] = 0x8
+		i++
+		if m.Wait {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i++
+	}
+	if m.NbCpus != 0 {
+		dAtA[i] = 0x10
+		i++
+		i = encodeVarintAgent(dAtA, i, uint64(m.NbCpus))
+	}
+	return i, nil
+}
+
 func (m *ReseedRandomDevRequest) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -5372,11 +5549,11 @@ func (m *GuestDetailsResponse) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0x12
 		i++
 		i = encodeVarintAgent(dAtA, i, uint64(m.AgentDetails.Size()))
-		n26, err := m.AgentDetails.MarshalTo(dAtA[i:])
+		n27, err := m.AgentDetails.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n26
+		i += n27
 	}
 	if m.SupportMemHotplugProbe {
 		dAtA[i] = 0x18
@@ -5407,21 +5584,21 @@ func (m *MemHotplugByProbeRequest) MarshalTo(dAtA []byte) (int, error) {
 	var l int
 	_ = l
 	if len(m.MemHotplugProbeAddr) > 0 {
-		dAtA28 := make([]byte, len(m.MemHotplugProbeAddr)*10)
-		var j27 int
+		dAtA29 := make([]byte, len(m.MemHotplugProbeAddr)*10)
+		var j28 int
 		for _, num := range m.MemHotplugProbeAddr {
 			for num >= 1<<7 {
-				dAtA28[j27] = uint8(uint64(num)&0x7f | 0x80)
+				dAtA29[j28] = uint8(uint64(num)&0x7f | 0x80)
 				num >>= 7
-				j27++
+				j28++
 			}
-			dAtA28[j27] = uint8(num)
-			j27++
+			dAtA29[j28] = uint8(num)
+			j28++
 		}
 		dAtA[i] = 0xa
 		i++
-		i = encodeVarintAgent(dAtA, i, uint64(j27))
-		i += copy(dAtA[i:], dAtA28[:j27])
+		i = encodeVarintAgent(dAtA, i, uint64(j28))
+		i += copy(dAtA[i:], dAtA29[:j28])
 	}
 	return i, nil
 }
@@ -5791,11 +5968,11 @@ func (m *UpdateIpvsRequest) MarshalTo(dAtA []byte) (int, error) {
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintAgent(dAtA, i, uint64(m.Ipvss.Size()))
-		n29, err := m.Ipvss.MarshalTo(dAtA[i:])
+		n30, err := m.Ipvss.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n29
+		i += n30
 	}
 	return i, nil
 }
@@ -6604,6 +6781,16 @@ func (m *UpdateInterfaceRequest) Size() (n int) {
 	return n
 }
 
+func (m *UpdateInterfaceHwAddrByNameRequest) Size() (n int) {
+	var l int
+	_ = l
+	if m.Interface != nil {
+		l = m.Interface.Size()
+		n += 1 + l + sovAgent(uint64(l))
+	}
+	return n
+}
+
 func (m *UpdateRoutesRequest) Size() (n int) {
 	var l int
 	_ = l
@@ -6644,6 +6831,18 @@ func (m *OnlineCPUMemRequest) Size() (n int) {
 	return n
 }
 
+func (m *OfflineCPURequest) Size() (n int) {
+	var l int
+	_ = l
+	if m.Wait {
+		n += 2
+	}
+	if m.NbCpus != 0 {
+		n += 1 + sovAgent(uint64(m.NbCpus))
+	}
+	return n
+}
+
 func (m *ReseedRandomDevRequest) Size() (n int) {
 	var l int
 	_ = l
@@ -12591,6 +12790,89 @@ func (m *UpdateInterfaceRequest) Unmarshal(dAtA []byte) error {
 	}
 	return nil
 }
+func (m *UpdateInterfaceHwAddrByNameRequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowAgent
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: UpdateInterfaceHwAddrByNameRequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: UpdateInterfaceHwAddrByNameRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Interface", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowAgent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthAgent
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.Interface == nil {
+				m.Interface = &types.Interface{}
+			}
+			if err := m.Interface.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipAgent(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthAgent
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
 func (m *UpdateRoutesRequest) Unmarshal(dAtA []byte) error {
 	l := len(dAtA)
 	iNdEx := 0
@@ -12903,6 +13185,95 @@ func (m *OnlineCPUMemRequest) Unmarshal(dAtA []byte) error {
 	}
 	return nil
 }
+func (m *OfflineCPURequest) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowAgent
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: OfflineCPURequest: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: OfflineCPURequest: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Wait", wireType)
+			}
+			var v int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowAgent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				v |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			m.Wait = bool(v != 0)
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field NbCpus", wireType)
+			}
+			m.NbCpus = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowAgent
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.NbCpus |= (uint32(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		default:
+			iNdEx = preIndex
+			skippy, err := skipAgent(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthAgent
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
 func (m *ReseedRandomDevRequest) Unmarshal(dAtA []byte) error {
 	l := len(dAtA)
 	iNdEx := 0
@@ -14881,203 +15252,217 @@ var (
 func init() { proto.RegisterFile("agent.proto", fileDescriptorAgent) }
 
 var fileDescriptorAgent = []byte{
-	// 3153 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x39, 0xdb, 0x6e, 0x1c, 0xc7,
-	0x95, 0x98, 0x0b, 0x39, 0x33, 0x67, 0x6e, 0x9c, 0x22, 0x45, 0x8d, 0x46, 0xb2, 0x4c, 0xb7, 0x6d,
-	0x99, 0x5e, 0xaf, 0x49, 0x8b, 0xf6, 0xfa, 0x0a, 0xaf, 0x20, 0x51, 0x5a, 0x91, 0x6b, 0x69, 0xc5,
-	0x6d, 0x8a, 0xf0, 0x2e, 0x16, 0x8b, 0x46, 0xb3, 0xbb, 0x38, 0x2c, 0x73, 0xba, 0xab, 0x5d, 0x55,
-	0x4d, 0x71, 0xbc, 0xc0, 0x3e, 0x26, 0xaf, 0xf9, 0x81, 0xfc, 0x40, 0x90, 0xb7, 0xbc, 0x25, 0xaf,
-	0x79, 0x30, 0x82, 0x3c, 0x04, 0x79, 0x0d, 0x10, 0x04, 0xfe, 0x84, 0x7c, 0x41, 0x50, 0xb7, 0xbe,
-	0xcc, 0x0c, 0x69, 0x44, 0x10, 0x90, 0x97, 0x46, 0x9f, 0x4b, 0x9d, 0x5b, 0x55, 0x9d, 0x3a, 0xa7,
-	0x0a, 0xda, 0xfe, 0x18, 0xc7, 0x62, 0x2b, 0x61, 0x54, 0x50, 0x54, 0x1f, 0xb3, 0x24, 0x18, 0xb5,
-	0x68, 0x40, 0x34, 0x62, 0xf4, 0xf1, 0x98, 0x88, 0xd3, 0xf4, 0x78, 0x2b, 0xa0, 0xd1, 0xf6, 0x99,
-	0x2f, 0xfc, 0xf7, 0x03, 0x1a, 0x0b, 0x9f, 0xc4, 0x98, 0xf1, 0x6d, 0x35, 0x70, 0x3b, 0x39, 0x1b,
-	0x6f, 0x8b, 0x69, 0x82, 0xb9, 0xfe, 0x9a, 0x71, 0x37, 0xc7, 0x94, 0x8e, 0x27, 0x78, 0x5b, 0x41,
-	0xc7, 0xe9, 0xc9, 0x36, 0x8e, 0x12, 0x31, 0xd5, 0x44, 0xe7, 0xe7, 0x55, 0x58, 0xdf, 0x65, 0xd8,
-	0x17, 0x78, 0xd7, 0x4a, 0x73, 0xf1, 0xb7, 0x29, 0xe6, 0x02, 0xbd, 0x01, 0x9d, 0x4c, 0x83, 0x47,
-	0xc2, 0x61, 0x65, 0xa3, 0xb2, 0xd9, 0x72, 0xdb, 0x19, 0x6e, 0x3f, 0x44, 0xd7, 0xa1, 0x81, 0x2f,
-	0x70, 0x20, 0xa9, 0x55, 0x45, 0x5d, 0x96, 0xe0, 0x7e, 0x88, 0xee, 0x42, 0x9b, 0x0b, 0x46, 0xe2,
-	0xb1, 0x97, 0x72, 0xcc, 0x86, 0xb5, 0x8d, 0xca, 0x66, 0x7b, 0x67, 0x65, 0x4b, 0xba, 0xb4, 0x75,
-	0xa8, 0x08, 0x47, 0x1c, 0x33, 0x17, 0x78, 0xf6, 0x8f, 0xee, 0x40, 0x23, 0xc4, 0xe7, 0x24, 0xc0,
-	0x7c, 0x58, 0xdf, 0xa8, 0x6d, 0xb6, 0x77, 0x3a, 0x9a, 0xfd, 0xa1, 0x42, 0xba, 0x96, 0x88, 0xde,
-	0x85, 0x26, 0x17, 0x94, 0xf9, 0x63, 0xcc, 0x87, 0x4b, 0x8a, 0xb1, 0x6b, 0xe5, 0x2a, 0xac, 0x9b,
-	0x91, 0xd1, 0x2d, 0xa8, 0x3d, 0xdb, 0xdd, 0x1f, 0x2e, 0x2b, 0xed, 0x60, 0xb8, 0x12, 0x1c, 0xb8,
-	0x12, 0x8d, 0xde, 0x84, 0x2e, 0xf7, 0xe3, 0xf0, 0x98, 0x5e, 0x78, 0x09, 0x09, 0x63, 0x3e, 0x6c,
-	0x6c, 0x54, 0x36, 0x9b, 0x6e, 0xc7, 0x20, 0x0f, 0x24, 0xce, 0xf9, 0x1c, 0xae, 0x1d, 0x0a, 0x9f,
-	0x89, 0x97, 0x88, 0x8e, 0x73, 0x04, 0xeb, 0x2e, 0x8e, 0xe8, 0xf9, 0x4b, 0x85, 0x76, 0x08, 0x0d,
-	0x41, 0x22, 0x4c, 0x53, 0xa1, 0x42, 0xdb, 0x75, 0x2d, 0xe8, 0xfc, 0xb2, 0x02, 0xe8, 0xd1, 0x05,
-	0x0e, 0x0e, 0x18, 0x0d, 0x30, 0xe7, 0xff, 0xa0, 0xe9, 0x7a, 0x07, 0x1a, 0x89, 0x36, 0x60, 0x58,
-	0x57, 0xec, 0x66, 0x16, 0xac, 0x55, 0x96, 0xea, 0x7c, 0x03, 0x6b, 0x87, 0x64, 0x1c, 0xfb, 0x93,
-	0x57, 0x68, 0xef, 0x3a, 0x2c, 0x73, 0x25, 0x53, 0x99, 0xda, 0x75, 0x0d, 0xe4, 0x1c, 0x00, 0xfa,
-	0xda, 0x27, 0xe2, 0xd5, 0x69, 0x72, 0xde, 0x87, 0xd5, 0x92, 0x44, 0x9e, 0xd0, 0x98, 0x63, 0x65,
-	0x80, 0xf0, 0x45, 0xca, 0x95, 0xb0, 0x25, 0xd7, 0x40, 0x0e, 0x86, 0xb5, 0x27, 0x84, 0x5b, 0x76,
-	0xfc, 0xf7, 0x98, 0xb0, 0x0e, 0xcb, 0x27, 0x94, 0x45, 0xbe, 0xb0, 0x16, 0x68, 0x08, 0x21, 0xa8,
-	0xfb, 0x6c, 0xcc, 0x87, 0xb5, 0x8d, 0xda, 0x66, 0xcb, 0x55, 0xff, 0x72, 0x55, 0xce, 0xa8, 0x31,
-	0x76, 0xbd, 0x01, 0x1d, 0x13, 0x77, 0x6f, 0x42, 0xb8, 0x50, 0x7a, 0x3a, 0x6e, 0xdb, 0xe0, 0xe4,
-	0x18, 0x87, 0xc2, 0xfa, 0x51, 0x12, 0xbe, 0xe4, 0x86, 0xdf, 0x81, 0x16, 0xc3, 0x9c, 0xa6, 0x4c,
-	0x6e, 0xd3, 0xaa, 0x9a, 0xf7, 0x35, 0x3d, 0xef, 0x4f, 0x48, 0x9c, 0x5e, 0xb8, 0x96, 0xe6, 0xe6,
-	0x6c, 0x66, 0x0b, 0x09, 0xfe, 0x32, 0x5b, 0xe8, 0x73, 0xb8, 0x76, 0xe0, 0xa7, 0xfc, 0x65, 0x6c,
-	0x75, 0xbe, 0x90, 0xdb, 0x8f, 0xa7, 0xd1, 0x4b, 0x0d, 0xfe, 0x45, 0x05, 0x9a, 0xbb, 0x49, 0x7a,
-	0xc4, 0xfd, 0x31, 0x46, 0xaf, 0x43, 0x5b, 0x50, 0xe1, 0x4f, 0xbc, 0x54, 0x82, 0x8a, 0xbd, 0xee,
-	0x82, 0x42, 0x69, 0x06, 0x19, 0x76, 0xcc, 0x82, 0x24, 0x35, 0x1c, 0xd5, 0x8d, 0xda, 0x66, 0xdd,
-	0x6d, 0x6b, 0x9c, 0x66, 0xd9, 0x82, 0x55, 0x45, 0xf3, 0x48, 0xec, 0x9d, 0x61, 0x16, 0xe3, 0x49,
-	0x44, 0x43, 0xac, 0xd6, 0x6f, 0xdd, 0x1d, 0x28, 0xd2, 0x7e, 0xfc, 0x55, 0x46, 0x40, 0xff, 0x04,
-	0x83, 0x8c, 0x5f, 0x6e, 0x4a, 0xc5, 0x5d, 0x57, 0xdc, 0x7d, 0xc3, 0x7d, 0x64, 0xd0, 0xce, 0xff,
-	0x43, 0xef, 0xf9, 0x29, 0xa3, 0x42, 0x4c, 0x48, 0x3c, 0x7e, 0xe8, 0x0b, 0x5f, 0x66, 0x8f, 0x04,
-	0x33, 0x42, 0x43, 0x6e, 0xac, 0xb5, 0x20, 0x7a, 0x0f, 0x06, 0x42, 0xf3, 0xe2, 0xd0, 0xb3, 0x3c,
-	0x55, 0xc5, 0xb3, 0x92, 0x11, 0x0e, 0x0c, 0xf3, 0xdb, 0xd0, 0xcb, 0x99, 0x65, 0xfe, 0x31, 0xf6,
-	0x76, 0x33, 0xec, 0x73, 0x12, 0x61, 0xe7, 0x5c, 0xc5, 0x4a, 0x4d, 0x32, 0x7a, 0x0f, 0x5a, 0x79,
-	0x1c, 0x2a, 0x6a, 0x85, 0xf4, 0xf4, 0x0a, 0xb1, 0xe1, 0x74, 0x9b, 0x59, 0x50, 0xbe, 0x84, 0xbe,
-	0xc8, 0x0c, 0xf7, 0x42, 0x5f, 0xf8, 0xe5, 0x45, 0x55, 0xf6, 0xca, 0xed, 0x89, 0x12, 0xec, 0x7c,
-	0x01, 0xad, 0x03, 0x12, 0x72, 0xad, 0x78, 0x08, 0x8d, 0x20, 0x65, 0x0c, 0xc7, 0xc2, 0xba, 0x6c,
-	0x40, 0xb4, 0x06, 0x4b, 0x13, 0x12, 0x11, 0x61, 0xdc, 0xd4, 0x80, 0x43, 0x01, 0x9e, 0xe2, 0x88,
-	0xb2, 0xa9, 0x0a, 0xd8, 0x1a, 0x2c, 0x15, 0x27, 0x57, 0x03, 0xe8, 0x26, 0xb4, 0x22, 0xff, 0x22,
-	0x9b, 0x54, 0x49, 0x69, 0x46, 0xfe, 0x85, 0x36, 0x7e, 0x08, 0x8d, 0x13, 0x9f, 0x4c, 0x82, 0x58,
-	0x98, 0xa8, 0x58, 0x30, 0x57, 0x58, 0x2f, 0x2a, 0xfc, 0x6d, 0x15, 0xda, 0x5a, 0xa3, 0x36, 0x78,
-	0x0d, 0x96, 0x02, 0x3f, 0x38, 0xcd, 0x54, 0x2a, 0x00, 0xdd, 0xb1, 0x86, 0x54, 0x8b, 0x49, 0x38,
-	0xb7, 0xd4, 0x9a, 0xb6, 0x0d, 0xc0, 0x5f, 0xf8, 0x89, 0xb1, 0xad, 0x76, 0x09, 0x73, 0x4b, 0xf2,
-	0x68, 0x73, 0x3f, 0x84, 0x8e, 0x5e, 0x77, 0x66, 0x48, 0xfd, 0x92, 0x21, 0x6d, 0xcd, 0xa5, 0x07,
-	0xbd, 0x09, 0xdd, 0x94, 0x63, 0xef, 0x94, 0x60, 0xe6, 0xb3, 0xe0, 0x74, 0x3a, 0x5c, 0xd2, 0x67,
-	0x64, 0xca, 0xf1, 0x9e, 0xc5, 0xa1, 0x1d, 0x58, 0x92, 0xe9, 0x8f, 0x0f, 0x97, 0xd5, 0x71, 0x7c,
-	0xab, 0x28, 0x52, 0xb9, 0xba, 0xa5, 0xbe, 0x8f, 0x62, 0xc1, 0xa6, 0xae, 0x66, 0x1d, 0x7d, 0x0a,
-	0x90, 0x23, 0xd1, 0x0a, 0xd4, 0xce, 0xf0, 0xd4, 0xec, 0x43, 0xf9, 0x2b, 0x83, 0x73, 0xee, 0x4f,
-	0x52, 0x1b, 0x75, 0x0d, 0x7c, 0x5e, 0xfd, 0xb4, 0xe2, 0x04, 0xd0, 0x7f, 0x30, 0x39, 0x23, 0xb4,
-	0x30, 0x7c, 0x0d, 0x96, 0x22, 0xff, 0x1b, 0xca, 0x6c, 0x24, 0x15, 0xa0, 0xb0, 0x24, 0xa6, 0xcc,
-	0x8a, 0x50, 0x00, 0xea, 0x41, 0x95, 0x26, 0x2a, 0x5e, 0x2d, 0xb7, 0x4a, 0x93, 0x5c, 0x51, 0xbd,
-	0xa0, 0xc8, 0xf9, 0x73, 0x1d, 0x20, 0xd7, 0x82, 0x5c, 0x18, 0x11, 0xea, 0x71, 0xcc, 0x64, 0x09,
-	0xe2, 0x1d, 0x4f, 0x05, 0xe6, 0x1e, 0xc3, 0x41, 0xca, 0x38, 0x39, 0x97, 0xf3, 0x27, 0xdd, 0xbe,
-	0xa6, 0xdd, 0x9e, 0xb1, 0xcd, 0xbd, 0x4e, 0xe8, 0xa1, 0x1e, 0xf7, 0x40, 0x0e, 0x73, 0xed, 0x28,
-	0xb4, 0x0f, 0xd7, 0x72, 0x99, 0x61, 0x41, 0x5c, 0xf5, 0x2a, 0x71, 0xab, 0x99, 0xb8, 0x30, 0x17,
-	0xf5, 0x08, 0x56, 0x09, 0xf5, 0xbe, 0x4d, 0x71, 0x5a, 0x12, 0x54, 0xbb, 0x4a, 0xd0, 0x80, 0xd0,
-	0xff, 0x54, 0x03, 0x72, 0x31, 0x07, 0x70, 0xa3, 0xe0, 0xa5, 0xdc, 0xee, 0x05, 0x61, 0xf5, 0xab,
-	0x84, 0xad, 0x67, 0x56, 0xc9, 0x7c, 0x90, 0x4b, 0xfc, 0x77, 0x58, 0x27, 0xd4, 0x7b, 0xe1, 0x13,
-	0x31, 0x2b, 0x6e, 0xe9, 0x47, 0x9c, 0x94, 0x87, 0x6e, 0x59, 0x96, 0x76, 0x32, 0xc2, 0x6c, 0x5c,
-	0x72, 0x72, 0xf9, 0x47, 0x9c, 0x7c, 0xaa, 0x06, 0xe4, 0x62, 0xee, 0xc3, 0x80, 0xd0, 0x59, 0x6b,
-	0x1a, 0x57, 0x09, 0xe9, 0x13, 0x5a, 0xb6, 0xe4, 0x01, 0x0c, 0x38, 0x0e, 0x04, 0x65, 0xc5, 0x45,
-	0xd0, 0xbc, 0x4a, 0xc4, 0x8a, 0xe1, 0xcf, 0x64, 0x38, 0xff, 0x03, 0x9d, 0xbd, 0x74, 0x8c, 0xc5,
-	0xe4, 0x38, 0x4b, 0x06, 0xaf, 0x2c, 0xff, 0x38, 0x7f, 0xad, 0x42, 0x7b, 0x77, 0xcc, 0x68, 0x9a,
-	0x94, 0x72, 0xb2, 0xde, 0xa4, 0xb3, 0x39, 0x59, 0xb1, 0xa8, 0x9c, 0xac, 0x99, 0x3f, 0x82, 0x4e,
-	0xa4, 0xb6, 0xae, 0xe1, 0xd7, 0x79, 0x68, 0x30, 0xb7, 0xa9, 0xdd, 0x76, 0x54, 0x48, 0x66, 0x5b,
-	0x00, 0x09, 0x09, 0xb9, 0x19, 0xa3, 0xd3, 0x51, 0xdf, 0x54, 0x84, 0x36, 0x45, 0xbb, 0xad, 0x24,
-	0xcb, 0xd6, 0x77, 0xa1, 0x7d, 0x2c, 0x83, 0x64, 0x06, 0x94, 0x92, 0x51, 0x1e, 0x3d, 0x17, 0x8e,
-	0xf3, 0x4d, 0xb8, 0x07, 0xdd, 0x53, 0x1d, 0x32, 0x33, 0x48, 0xaf, 0xa1, 0x37, 0x8d, 0x27, 0xb9,
-	0xbf, 0x5b, 0xc5, 0xc8, 0xea, 0x09, 0xe8, 0x9c, 0x16, 0x50, 0xa3, 0x43, 0x18, 0xcc, 0xb1, 0x2c,
-	0xc8, 0x41, 0x9b, 0xc5, 0x1c, 0xd4, 0xde, 0x41, 0x5a, 0x51, 0x71, 0x64, 0x31, 0x2f, 0xfd, 0xac,
-	0x0a, 0xbd, 0xfd, 0x58, 0x60, 0x76, 0xe2, 0x07, 0x58, 0x5b, 0x8c, 0xa0, 0x1e, 0xfb, 0x11, 0x36,
-	0x32, 0xd5, 0x3f, 0xba, 0x01, 0x4d, 0x76, 0xa1, 0x53, 0x88, 0x99, 0xd1, 0x06, 0xbb, 0x50, 0xa9,
-	0x01, 0xbd, 0x06, 0xc0, 0x2e, 0xbc, 0xc4, 0x0f, 0xce, 0xb0, 0x89, 0x61, 0xdd, 0x6d, 0xb1, 0x8b,
-	0x03, 0x8d, 0x90, 0x8b, 0x81, 0x5d, 0x78, 0x98, 0x31, 0xca, 0xb8, 0xc9, 0x56, 0x4d, 0x76, 0xf1,
-	0x48, 0xc1, 0x66, 0x6c, 0xc8, 0x68, 0x92, 0xe0, 0x50, 0x65, 0x69, 0x35, 0xf6, 0xa1, 0x46, 0x48,
-	0xad, 0xc2, 0x6a, 0x5d, 0xd6, 0x5a, 0x45, 0xae, 0x55, 0xe4, 0x5a, 0x1b, 0x7a, 0xa4, 0x28, 0x6a,
-	0x15, 0x99, 0xd6, 0xa6, 0xd6, 0x2a, 0x0a, 0x5a, 0x45, 0xae, 0xb5, 0x65, 0xc7, 0x1a, 0xad, 0xce,
-	0xaf, 0xab, 0xd0, 0x78, 0x1e, 0xa8, 0x49, 0x41, 0x1b, 0xd0, 0xc6, 0x5c, 0xf8, 0xc7, 0x13, 0xc2,
-	0x4f, 0x71, 0x68, 0x96, 0x79, 0x11, 0x25, 0x6d, 0xe4, 0xd3, 0xd8, 0xe3, 0xf2, 0x04, 0x37, 0x91,
-	0xe1, 0xd3, 0xf8, 0x50, 0x9e, 0xe0, 0x86, 0xc4, 0x70, 0x70, 0x6e, 0xd7, 0x3a, 0x9f, 0xc6, 0x2e,
-	0x0e, 0xce, 0xa5, 0x7d, 0x27, 0x24, 0x56, 0x39, 0xe6, 0xae, 0x8d, 0xca, 0x09, 0x89, 0x65, 0xfe,
-	0xb8, 0x5b, 0x24, 0xee, 0x98, 0xa0, 0x58, 0xe2, 0x8e, 0xf2, 0x4c, 0xa6, 0x01, 0x49, 0x35, 0x41,
-	0x69, 0x4a, 0x84, 0xa4, 0xaa, 0xc3, 0x79, 0x42, 0x39, 0x36, 0x01, 0xd1, 0x80, 0xf4, 0x57, 0xfd,
-	0xe8, 0x31, 0x3a, 0x1a, 0x2d, 0x85, 0x51, 0x83, 0x6e, 0x40, 0x73, 0xe2, 0x73, 0xe1, 0xf9, 0xc1,
-	0x99, 0x09, 0x46, 0x43, 0xc2, 0xf7, 0x83, 0x33, 0x59, 0xdd, 0xcb, 0x82, 0x1c, 0xc7, 0x43, 0x50,
-	0x04, 0x03, 0xa9, 0xaa, 0x65, 0x42, 0x39, 0x89, 0xc7, 0xc3, 0xb6, 0xa9, 0x5a, 0x34, 0xe8, 0xa4,
-	0xd0, 0x38, 0x0a, 0x75, 0xec, 0xf2, 0xc1, 0x95, 0xd9, 0xc1, 0x36, 0xf6, 0x26, 0x60, 0x06, 0x34,
-	0x6b, 0x45, 0x9f, 0x08, 0x26, 0x62, 0x4d, 0x76, 0xa1, 0x13, 0xbe, 0x99, 0x52, 0x43, 0xac, 0xdb,
-	0x29, 0xd5, 0x44, 0xe7, 0xf7, 0x15, 0xe8, 0xfc, 0x07, 0x16, 0x2f, 0x28, 0x3b, 0xb3, 0xf9, 0x00,
-	0x88, 0x5d, 0xd6, 0xdc, 0x9c, 0x75, 0xa6, 0x3c, 0x2b, 0x2f, 0x77, 0xb7, 0xc0, 0x87, 0x5e, 0x87,
-	0x9a, 0x08, 0x12, 0xb3, 0x73, 0x4c, 0x6b, 0x68, 0x96, 0x82, 0x2b, 0x29, 0xe8, 0x0d, 0xa8, 0x8b,
-	0x20, 0xf9, 0xd8, 0xa4, 0x8a, 0x19, 0x0e, 0x45, 0x92, 0x32, 0xd2, 0x30, 0x29, 0xb7, 0x97, 0x26,
-	0x24, 0xae, 0xa4, 0x48, 0x19, 0x69, 0x98, 0x7c, 0xac, 0x66, 0x76, 0x8e, 0x43, 0x91, 0x9c, 0x9f,
-	0x56, 0x60, 0x7d, 0xb6, 0xfb, 0x30, 0xbd, 0xd2, 0x47, 0xd0, 0x09, 0x54, 0xd2, 0x28, 0x25, 0xc6,
-	0xc1, 0x5c, 0x3a, 0x71, 0xdb, 0x41, 0x21, 0x97, 0x7e, 0x02, 0xdd, 0x58, 0x87, 0xa7, 0x94, 0x1f,
-	0x4d, 0x72, 0x28, 0x46, 0xce, 0xed, 0xc4, 0x05, 0xc8, 0x09, 0x01, 0x7d, 0xcd, 0x88, 0xc0, 0x87,
-	0x82, 0x61, 0x3f, 0x7a, 0x15, 0x5d, 0x30, 0x82, 0xba, 0x2a, 0x99, 0x6b, 0xaa, 0xc9, 0x53, 0xff,
-	0xce, 0x3b, 0xb0, 0x5a, 0xd2, 0x62, 0x7c, 0x5d, 0x81, 0xda, 0xc4, 0x2c, 0x9f, 0xae, 0x2b, 0x7f,
-	0x1d, 0x1f, 0x06, 0x2e, 0xf6, 0xc3, 0x57, 0x67, 0x8d, 0x51, 0x51, 0xcb, 0x55, 0x6c, 0x02, 0x2a,
-	0xaa, 0x30, 0xa6, 0x58, 0xab, 0x2b, 0x05, 0xab, 0x9f, 0xc1, 0x60, 0x57, 0xee, 0xa2, 0x43, 0x11,
-	0x92, 0xf8, 0x55, 0xb4, 0xed, 0xff, 0x07, 0xab, 0xcf, 0xc5, 0xf4, 0x6b, 0x29, 0x8c, 0x93, 0xef,
-	0xf0, 0x2b, 0xf2, 0x8f, 0xd1, 0x17, 0xd6, 0x3f, 0x46, 0x5f, 0xc8, 0x6d, 0x19, 0xd0, 0x49, 0x1a,
-	0xc5, 0x6a, 0x89, 0x76, 0x5d, 0x03, 0x39, 0x7f, 0xaa, 0xc0, 0x9a, 0xbe, 0x53, 0x3b, 0xd4, 0x57,
-	0x49, 0x56, 0xfd, 0x08, 0x9a, 0xa7, 0x94, 0x8b, 0xc2, 0x99, 0x90, 0xc1, 0x52, 0x7c, 0x18, 0x73,
-	0x55, 0xfc, 0xb5, 0x5c, 0xf9, 0x5b, 0xba, 0xe8, 0xaa, 0x5d, 0x7d, 0xd1, 0x35, 0x77, 0x95, 0x55,
-	0x9f, 0xbf, 0xca, 0x92, 0xc9, 0xcb, 0x32, 0x11, 0x7d, 0x44, 0xb4, 0xdc, 0x96, 0xc1, 0xec, 0x87,
-	0xe8, 0x0e, 0xf4, 0xc7, 0xd2, 0x4a, 0xef, 0x94, 0xd2, 0x33, 0x2f, 0xf1, 0xc5, 0xa9, 0x4a, 0x8a,
-	0x2d, 0xb7, 0xab, 0xd0, 0x7b, 0x94, 0x9e, 0x1d, 0xf8, 0xe2, 0xd4, 0xb9, 0x0e, 0xd7, 0x1e, 0x62,
-	0x2e, 0x18, 0x9d, 0x96, 0xbd, 0x73, 0xfe, 0x15, 0x60, 0x3f, 0x4f, 0x00, 0x1f, 0x14, 0x21, 0x93,
-	0x36, 0x56, 0xb6, 0xf4, 0xbd, 0x64, 0x46, 0x70, 0x0b, 0x3c, 0xce, 0x16, 0x2c, 0xbb, 0x34, 0x95,
-	0x47, 0xd2, 0x5b, 0xf6, 0xcf, 0x8c, 0xeb, 0x98, 0x71, 0x0a, 0xe9, 0x1a, 0x9a, 0xb3, 0x67, 0x2f,
-	0x32, 0x72, 0x71, 0x26, 0xce, 0x5b, 0xd0, 0xca, 0x52, 0x91, 0xd9, 0xd6, 0xf3, 0xaa, 0x73, 0x16,
-	0xe7, 0xbf, 0x61, 0x55, 0x4b, 0xd2, 0x92, 0xad, 0x98, 0xb7, 0x60, 0x99, 0x59, 0x33, 0x2a, 0xf9,
-	0x85, 0xa4, 0x61, 0x32, 0x34, 0x74, 0x4b, 0x2a, 0x0b, 0x18, 0x8e, 0xec, 0xb9, 0xd5, 0x74, 0x73,
-	0x84, 0x8c, 0xd6, 0x13, 0xc2, 0x45, 0xee, 0xa6, 0x8d, 0xd6, 0x2a, 0x0c, 0x24, 0xa1, 0xa4, 0xd1,
-	0xf9, 0x5f, 0x58, 0x7d, 0x16, 0x4f, 0x48, 0x8c, 0x77, 0x0f, 0x8e, 0x9e, 0xe2, 0x6c, 0x5b, 0x22,
-	0xa8, 0xab, 0x03, 0xa7, 0xa2, 0xa4, 0xab, 0x7f, 0xb9, 0x4e, 0xe3, 0x63, 0x2f, 0x48, 0x52, 0x6e,
-	0xee, 0x07, 0x97, 0xe3, 0xe3, 0xdd, 0x24, 0xe5, 0xf2, 0x10, 0x92, 0xc5, 0x1e, 0x8d, 0x27, 0x53,
-	0xb5, 0x58, 0x9b, 0x6e, 0x23, 0x48, 0xd2, 0x67, 0xf1, 0x64, 0xea, 0xfc, 0xb3, 0xba, 0x11, 0xc1,
-	0x38, 0x74, 0xfd, 0x38, 0xa4, 0xd1, 0x43, 0x7c, 0x5e, 0xd0, 0x90, 0x75, 0xdf, 0x76, 0x53, 0x7e,
-	0x5f, 0x81, 0xce, 0xfd, 0x31, 0x8e, 0xc5, 0x43, 0x2c, 0x7c, 0x32, 0x51, 0x1d, 0xf6, 0x39, 0x66,
-	0x9c, 0xd0, 0xd8, 0xac, 0x5e, 0x0b, 0xa2, 0xd7, 0xa1, 0x4d, 0x62, 0x22, 0xbc, 0xd0, 0xc7, 0x11,
-	0x8d, 0x4d, 0x14, 0x40, 0xa2, 0x1e, 0x2a, 0x0c, 0x7a, 0x07, 0xfa, 0xfa, 0xfe, 0xd6, 0x3b, 0xf5,
-	0xe3, 0x70, 0x82, 0x99, 0xbd, 0xcf, 0xea, 0x69, 0xf4, 0x9e, 0xc1, 0xa2, 0x77, 0x61, 0xc5, 0xac,
-	0xea, 0x9c, 0xb3, 0xae, 0x38, 0xfb, 0x06, 0x5f, 0x62, 0x4d, 0x93, 0x84, 0x32, 0xc1, 0x3d, 0x8e,
-	0x83, 0x80, 0x46, 0x89, 0x69, 0x4f, 0xfb, 0x16, 0x7f, 0xa8, 0xd1, 0xce, 0x18, 0x56, 0x1f, 0x4b,
-	0x3f, 0x8d, 0x27, 0xf9, 0x04, 0xf7, 0x22, 0x1c, 0x79, 0xc7, 0x13, 0x1a, 0x9c, 0x79, 0x32, 0x4f,
-	0x98, 0x08, 0xcb, 0x02, 0xf8, 0x81, 0x44, 0x1e, 0x92, 0xef, 0xd4, 0x4d, 0x8c, 0xe4, 0x3a, 0xa5,
-	0x22, 0x99, 0xa4, 0x63, 0x2f, 0x61, 0xf4, 0x18, 0x1b, 0x17, 0xfb, 0x11, 0x8e, 0xf6, 0x34, 0xfe,
-	0x40, 0xa2, 0x9d, 0xdf, 0x54, 0x60, 0xad, 0xac, 0xc9, 0x64, 0xbd, 0x6d, 0x58, 0x2b, 0xab, 0x32,
-	0xc5, 0x98, 0x3e, 0xd0, 0x07, 0x45, 0x85, 0xba, 0x2c, 0xfb, 0x04, 0xba, 0xea, 0x52, 0xdf, 0x0b,
-	0xb5, 0xa4, 0xf2, 0x39, 0x53, 0x9c, 0x17, 0xb7, 0xe3, 0x17, 0x67, 0xe9, 0x33, 0xb8, 0x61, 0xdc,
-	0xf7, 0xe6, 0xcd, 0xd6, 0x0b, 0x62, 0xdd, 0x30, 0x3c, 0x9d, 0xb1, 0xfe, 0x09, 0x0c, 0x73, 0xd4,
-	0x83, 0xa9, 0x42, 0xda, 0x58, 0x7d, 0x00, 0xab, 0x33, 0xce, 0xde, 0x0f, 0x43, 0xa6, 0x36, 0x68,
-	0xdd, 0x5d, 0x44, 0x72, 0xee, 0xc1, 0xf5, 0x43, 0x2c, 0x74, 0x34, 0x7c, 0x61, 0x3a, 0x43, 0x2d,
-	0x6c, 0x05, 0x6a, 0x87, 0x38, 0x50, 0xce, 0xd7, 0x5c, 0xf9, 0x2b, 0x17, 0xe0, 0x11, 0xc7, 0x81,
-	0xf2, 0xb2, 0xe6, 0xaa, 0x7f, 0xe7, 0x57, 0x15, 0x68, 0x98, 0x5c, 0x27, 0x73, 0x6d, 0xc8, 0xc8,
-	0x39, 0x66, 0x66, 0xe9, 0x19, 0x08, 0xbd, 0x0d, 0x3d, 0xfd, 0xe7, 0xd1, 0x44, 0x10, 0x9a, 0x65,
-	0xd0, 0xae, 0xc6, 0x3e, 0xd3, 0x48, 0x75, 0x5f, 0xab, 0xae, 0x23, 0x4d, 0xe7, 0x6f, 0x20, 0x75,
-	0xe9, 0xca, 0x65, 0x66, 0x50, 0x19, 0xb3, 0xe5, 0x1a, 0x48, 0x2e, 0x75, 0x2b, 0x6f, 0x49, 0xc9,
-	0xb3, 0xa0, 0x5c, 0xea, 0x11, 0x4d, 0x63, 0xe1, 0x25, 0x94, 0xc4, 0xc2, 0xa4, 0x48, 0x50, 0xa8,
-	0x03, 0x89, 0x71, 0x7e, 0x52, 0x81, 0x65, 0xfd, 0x66, 0x81, 0x7a, 0x50, 0xcd, 0x0e, 0x99, 0x2a,
-	0x51, 0x07, 0xb6, 0xd2, 0xa5, 0x0f, 0x16, 0xf5, 0x2f, 0xf7, 0xf1, 0x79, 0xa4, 0xd3, 0xad, 0x31,
-	0xed, 0x3c, 0x92, 0x79, 0x56, 0x7a, 0x96, 0x9f, 0x55, 0x8a, 0xae, 0x4d, 0xec, 0x66, 0x58, 0xc5,
-	0x76, 0xa9, 0xa5, 0xce, 0x7f, 0x01, 0xe4, 0x77, 0xf7, 0x32, 0xe4, 0x69, 0x66, 0x8c, 0xfc, 0x95,
-	0x98, 0x71, 0x76, 0xca, 0xc9, 0x5f, 0x74, 0x07, 0x7a, 0x7e, 0x18, 0x12, 0x39, 0xdc, 0x9f, 0x3c,
-	0x26, 0x61, 0xb6, 0x49, 0xcb, 0x58, 0xe7, 0x77, 0x15, 0xe8, 0xef, 0xd2, 0x64, 0xfa, 0x6f, 0x64,
-	0x82, 0x0b, 0x19, 0x44, 0x19, 0x69, 0x7a, 0x1d, 0xf9, 0xaf, 0xcb, 0xef, 0x09, 0xd6, 0x5b, 0x4b,
-	0xcf, 0x6c, 0x53, 0x22, 0xd4, 0xb6, 0xb2, 0xc4, 0xec, 0x1a, 0xb4, 0xab, 0x89, 0x4f, 0x69, 0xa8,
-	0xba, 0xa4, 0x90, 0x30, 0x2f, 0xbb, 0xf4, 0xec, 0xba, 0x8d, 0x90, 0x30, 0x45, 0x32, 0x8e, 0x2c,
-	0xa9, 0x7b, 0xf7, 0xa2, 0x23, 0xcb, 0x1a, 0x23, 0x1d, 0x59, 0x87, 0x65, 0x7a, 0x72, 0xc2, 0xb1,
-	0x50, 0xe5, 0x7b, 0xcd, 0x35, 0x50, 0x96, 0xe6, 0x9a, 0x85, 0x34, 0x77, 0x0d, 0x56, 0xd5, 0x0b,
-	0xcf, 0x73, 0xe6, 0x07, 0x24, 0x1e, 0xdb, 0x54, 0xbc, 0x06, 0xe8, 0x50, 0xd0, 0x64, 0x06, 0x3b,
-	0x82, 0xfa, 0x7e, 0x72, 0xae, 0x3a, 0x3b, 0x37, 0x9d, 0x64, 0x9d, 0x9d, 0xfc, 0x77, 0xfe, 0x05,
-	0x06, 0xe6, 0x3c, 0x4a, 0xce, 0xb3, 0x14, 0xb3, 0x01, 0x4b, 0x12, 0xb4, 0x47, 0x88, 0x79, 0x84,
-	0x52, 0x1c, 0x9a, 0xe0, 0x6c, 0x42, 0x47, 0x0f, 0x30, 0x99, 0x62, 0x08, 0x0d, 0x03, 0xdb, 0x2c,
-	0x6b, 0xc0, 0x9d, 0x3f, 0xae, 0x98, 0x84, 0x6c, 0xee, 0x5a, 0xd0, 0x63, 0xe8, 0xcf, 0xbc, 0xdd,
-	0x21, 0x73, 0xf9, 0xb6, 0xf8, 0x49, 0x6f, 0xb4, 0xbe, 0xa5, 0xdf, 0x02, 0xb7, 0xec, 0x5b, 0xe0,
-	0xd6, 0xa3, 0x28, 0x11, 0x53, 0xf4, 0x08, 0x7a, 0xe5, 0x57, 0x2e, 0x74, 0xd3, 0x96, 0x1a, 0x0b,
-	0xde, 0xbe, 0x2e, 0x15, 0xf3, 0x18, 0xfa, 0x33, 0x0f, 0x5e, 0xd6, 0x9e, 0xc5, 0xef, 0x60, 0x97,
-	0x0a, 0xba, 0x07, 0xed, 0xc2, 0x0b, 0x17, 0x1a, 0x6a, 0x21, 0xf3, 0x8f, 0x5e, 0x97, 0x0a, 0xd8,
-	0x85, 0x6e, 0xe9, 0xd1, 0x09, 0x8d, 0x8c, 0x3f, 0x0b, 0x5e, 0xa2, 0x2e, 0x15, 0xf2, 0x00, 0xda,
-	0x85, 0xb7, 0x1f, 0x6b, 0xc5, 0xfc, 0x03, 0xd3, 0xe8, 0xc6, 0x02, 0x8a, 0x99, 0xcd, 0x3d, 0xe8,
-	0x96, 0x5e, 0x6a, 0xac, 0x21, 0x8b, 0x5e, 0x89, 0x46, 0x37, 0x17, 0xd2, 0x8c, 0xa4, 0xc7, 0xd0,
-	0x9f, 0x79, 0xb7, 0xb1, 0xc1, 0x5d, 0xfc, 0x9c, 0x73, 0xa9, 0x5b, 0x5f, 0xa9, 0xc9, 0x2e, 0x74,
-	0x44, 0x85, 0xc9, 0x9e, 0x7f, 0xa5, 0x19, 0xdd, 0x5a, 0x4c, 0x34, 0x56, 0x3d, 0x82, 0x5e, 0xf9,
-	0x81, 0xc6, 0x0a, 0x5b, 0xf8, 0x6c, 0x73, 0xf5, 0xca, 0x29, 0xbd, 0xd5, 0xe4, 0x2b, 0x67, 0xd1,
-	0x13, 0xce, 0xa5, 0x82, 0xee, 0x03, 0x98, 0xfe, 0x27, 0x24, 0x71, 0x36, 0x65, 0x73, 0x7d, 0x57,
-	0x36, 0x65, 0x0b, 0x7a, 0xa5, 0x7b, 0x00, 0xba, 0x6d, 0x09, 0x69, 0x2a, 0xd0, 0x75, 0x6b, 0xc6,
-	0x4c, 0xaf, 0x34, 0x1a, 0xce, 0x13, 0xe6, 0x04, 0x60, 0xc6, 0x5e, 0x46, 0xc0, 0x97, 0x00, 0x79,
-	0x3b, 0x64, 0x05, 0xcc, 0x35, 0x48, 0x57, 0xc4, 0xa0, 0x53, 0x6c, 0x7e, 0x90, 0xf1, 0x75, 0x41,
-	0x43, 0x74, 0x85, 0x88, 0xfe, 0x4c, 0x6d, 0x5d, 0x5e, 0x6c, 0xb3, 0x25, 0xf7, 0x68, 0xae, 0xbe,
-	0x46, 0x9f, 0x40, 0xa7, 0x58, 0x54, 0x5b, 0x2b, 0x16, 0x14, 0xda, 0xa3, 0x52, 0x61, 0x8d, 0xee,
-	0x41, 0xaf, 0x5c, 0x32, 0xa3, 0xc2, 0xbe, 0x98, 0x2b, 0xa4, 0x47, 0x2b, 0x33, 0x77, 0x11, 0x1c,
-	0x7d, 0x08, 0x90, 0x97, 0xd6, 0x36, 0x7c, 0x73, 0xc5, 0xf6, 0x8c, 0xd6, 0xfb, 0xd0, 0x29, 0x1e,
-	0x03, 0xd6, 0xdc, 0x05, 0x47, 0xc3, 0x55, 0x59, 0xab, 0x70, 0x64, 0xd8, 0xc5, 0x37, 0x7f, 0x8a,
-	0x5c, 0x95, 0xb5, 0x4a, 0x7d, 0xa3, 0x4d, 0x16, 0x8b, 0x9a, 0xc9, 0xab, 0x72, 0x79, 0xb9, 0x3f,
-	0xb3, 0xe1, 0x5b, 0xd8, 0xb5, 0x5d, 0xb5, 0x88, 0x8a, 0xad, 0x88, 0x8d, 0xc7, 0x82, 0xf6, 0xe4,
-	0x47, 0x36, 0x75, 0xb1, 0xdd, 0x28, 0x6c, 0xea, 0x05, 0x5d, 0xc8, 0xa5, 0x82, 0xf6, 0xa0, 0xff,
-	0xd8, 0x56, 0x92, 0xa6, 0xca, 0x35, 0xe6, 0x2c, 0xa8, 0xea, 0x47, 0xa3, 0x45, 0x24, 0xb3, 0xb3,
-	0xbe, 0x82, 0xc1, 0x5c, 0x85, 0x8b, 0x6e, 0x67, 0x77, 0xdb, 0x0b, 0x4b, 0xdf, 0x4b, 0xcd, 0xda,
-	0x87, 0x95, 0xd9, 0x02, 0x17, 0xbd, 0x66, 0x26, 0x7d, 0x71, 0xe1, 0x7b, 0xa9, 0xa8, 0xcf, 0xa0,
-	0x69, 0x0b, 0x2a, 0x64, 0xde, 0x10, 0x66, 0x0a, 0xac, 0x4b, 0x87, 0x7e, 0x09, 0xbd, 0x42, 0xd9,
-	0x91, 0x4e, 0xb0, 0x5d, 0xf1, 0x73, 0xc5, 0xc8, 0x08, 0x15, 0xaa, 0x0f, 0x13, 0x91, 0x07, 0x9d,
-	0xef, 0x7f, 0xb8, 0x5d, 0xf9, 0xc3, 0x0f, 0xb7, 0x2b, 0x7f, 0xf9, 0xe1, 0x76, 0xe5, 0x78, 0x59,
-	0x09, 0xff, 0xf0, 0x6f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x56, 0x4f, 0xcc, 0x5d, 0x8a, 0x24, 0x00,
-	0x00,
+	// 3378 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x39, 0x4b, 0x6f, 0x1c, 0xc7,
+	0x99, 0x98, 0x07, 0x39, 0x33, 0xdf, 0xcc, 0x70, 0x38, 0x4d, 0x8a, 0x1a, 0x8d, 0x64, 0x89, 0x6e,
+	0xdb, 0x32, 0xbd, 0x5e, 0x93, 0x16, 0xed, 0xf5, 0x73, 0xb5, 0x5a, 0x91, 0xd4, 0x92, 0x5c, 0x4b,
+	0x16, 0xb7, 0x49, 0xc2, 0x6b, 0x04, 0x41, 0xa3, 0xd9, 0x5d, 0x1c, 0x96, 0xd9, 0xd3, 0xd5, 0xae,
+	0xaa, 0xa6, 0x38, 0x0e, 0x90, 0x63, 0x72, 0x0d, 0x90, 0x73, 0x8e, 0xb9, 0x04, 0xb9, 0xe5, 0x96,
+	0x5c, 0x73, 0x30, 0x82, 0x1c, 0x72, 0x0f, 0x10, 0x04, 0xfe, 0x09, 0xf9, 0x05, 0x41, 0xbd, 0xfa,
+	0x31, 0x0f, 0x1a, 0x26, 0x04, 0xe4, 0xd2, 0xe8, 0xef, 0x51, 0xdf, 0xab, 0xbe, 0xfa, 0xaa, 0xbe,
+	0x2a, 0x68, 0x7a, 0x03, 0x14, 0xf1, 0xf5, 0x98, 0x12, 0x4e, 0xac, 0xea, 0x80, 0xc6, 0x7e, 0xbf,
+	0x41, 0x7c, 0xac, 0x10, 0xfd, 0x0f, 0x06, 0x98, 0x9f, 0x25, 0x27, 0xeb, 0x3e, 0x19, 0x6e, 0x9c,
+	0x7b, 0xdc, 0x7b, 0xc7, 0x27, 0x11, 0xf7, 0x70, 0x84, 0x28, 0xdb, 0x90, 0x03, 0x37, 0xe2, 0xf3,
+	0xc1, 0x06, 0x1f, 0xc5, 0x88, 0xa9, 0xaf, 0x1e, 0x77, 0x7b, 0x40, 0xc8, 0x20, 0x44, 0x1b, 0x12,
+	0x3a, 0x49, 0x4e, 0x37, 0xd0, 0x30, 0xe6, 0x23, 0x45, 0xb4, 0x7f, 0x55, 0x86, 0x95, 0x6d, 0x8a,
+	0x3c, 0x8e, 0xb6, 0x8d, 0x34, 0x07, 0x7d, 0x9d, 0x20, 0xc6, 0xad, 0x57, 0xa1, 0x95, 0x6a, 0x70,
+	0x71, 0xd0, 0x2b, 0xad, 0x96, 0xd6, 0x1a, 0x4e, 0x33, 0xc5, 0xed, 0x07, 0xd6, 0x4d, 0xa8, 0xa1,
+	0x4b, 0xe4, 0x0b, 0x6a, 0x59, 0x52, 0xe7, 0x05, 0xb8, 0x1f, 0x58, 0x0f, 0xa0, 0xc9, 0x38, 0xc5,
+	0xd1, 0xc0, 0x4d, 0x18, 0xa2, 0xbd, 0xca, 0x6a, 0x69, 0xad, 0xb9, 0xb9, 0xb8, 0x2e, 0x5c, 0x5a,
+	0x3f, 0x94, 0x84, 0x63, 0x86, 0xa8, 0x03, 0x2c, 0xfd, 0xb7, 0xee, 0x43, 0x2d, 0x40, 0x17, 0xd8,
+	0x47, 0xac, 0x57, 0x5d, 0xad, 0xac, 0x35, 0x37, 0x5b, 0x8a, 0x7d, 0x47, 0x22, 0x1d, 0x43, 0xb4,
+	0xde, 0x82, 0x3a, 0xe3, 0x84, 0x7a, 0x03, 0xc4, 0x7a, 0x73, 0x92, 0xb1, 0x6d, 0xe4, 0x4a, 0xac,
+	0x93, 0x92, 0xad, 0x3b, 0x50, 0x79, 0xbe, 0xbd, 0xdf, 0x9b, 0x97, 0xda, 0x41, 0x73, 0xc5, 0xc8,
+	0x77, 0x04, 0xda, 0x7a, 0x0d, 0xda, 0xcc, 0x8b, 0x82, 0x13, 0x72, 0xe9, 0xc6, 0x38, 0x88, 0x58,
+	0xaf, 0xb6, 0x5a, 0x5a, 0xab, 0x3b, 0x2d, 0x8d, 0x3c, 0x10, 0x38, 0xfb, 0x13, 0xb8, 0x71, 0xc8,
+	0x3d, 0xca, 0xaf, 0x11, 0x1d, 0xfb, 0x18, 0x56, 0x1c, 0x34, 0x24, 0x17, 0xd7, 0x0a, 0x6d, 0x0f,
+	0x6a, 0x1c, 0x0f, 0x11, 0x49, 0xb8, 0x0c, 0x6d, 0xdb, 0x31, 0xa0, 0xfd, 0xdb, 0x12, 0x58, 0x4f,
+	0x2e, 0x91, 0x7f, 0x40, 0x89, 0x8f, 0x18, 0xfb, 0x17, 0x4d, 0xd7, 0x9b, 0x50, 0x8b, 0x95, 0x01,
+	0xbd, 0xaa, 0x64, 0xd7, 0xb3, 0x60, 0xac, 0x32, 0x54, 0xfb, 0x2b, 0x58, 0x3e, 0xc4, 0x83, 0xc8,
+	0x0b, 0x5f, 0xa2, 0xbd, 0x2b, 0x30, 0xcf, 0xa4, 0x4c, 0x69, 0x6a, 0xdb, 0xd1, 0x90, 0x7d, 0x00,
+	0xd6, 0x17, 0x1e, 0xe6, 0x2f, 0x4f, 0x93, 0xfd, 0x0e, 0x2c, 0x15, 0x24, 0xb2, 0x98, 0x44, 0x0c,
+	0x49, 0x03, 0xb8, 0xc7, 0x13, 0x26, 0x85, 0xcd, 0x39, 0x1a, 0xb2, 0x11, 0x2c, 0x3f, 0xc5, 0xcc,
+	0xb0, 0xa3, 0x1f, 0x62, 0xc2, 0x0a, 0xcc, 0x9f, 0x12, 0x3a, 0xf4, 0xb8, 0xb1, 0x40, 0x41, 0x96,
+	0x05, 0x55, 0x8f, 0x0e, 0x58, 0xaf, 0xb2, 0x5a, 0x59, 0x6b, 0x38, 0xf2, 0x5f, 0x64, 0xe5, 0x98,
+	0x1a, 0x6d, 0xd7, 0xab, 0xd0, 0xd2, 0x71, 0x77, 0x43, 0xcc, 0xb8, 0xd4, 0xd3, 0x72, 0x9a, 0x1a,
+	0x27, 0xc6, 0xd8, 0x04, 0x56, 0x8e, 0xe3, 0xe0, 0x9a, 0x0b, 0x7e, 0x13, 0x1a, 0x14, 0x31, 0x92,
+	0x50, 0xb1, 0x4c, 0xcb, 0x72, 0xde, 0x97, 0xd5, 0xbc, 0x3f, 0xc5, 0x51, 0x72, 0xe9, 0x18, 0x9a,
+	0x93, 0xb1, 0xd9, 0x0f, 0xa1, 0x77, 0xc8, 0x3d, 0xce, 0x52, 0x7d, 0xbb, 0x71, 0xf2, 0x03, 0x56,
+	0x91, 0x5a, 0x81, 0xb9, 0xe1, 0x3f, 0x6c, 0xec, 0x81, 0x97, 0xb0, 0xeb, 0xb8, 0x6a, 0x7f, 0x2a,
+	0x56, 0x2f, 0x4b, 0x86, 0xd7, 0x1a, 0xfc, 0x9b, 0x12, 0xd4, 0xb7, 0xe3, 0xe4, 0x98, 0x79, 0x03,
+	0x64, 0xdd, 0x83, 0x26, 0x27, 0xdc, 0x0b, 0xdd, 0x44, 0x80, 0x92, 0xbd, 0xea, 0x80, 0x44, 0x29,
+	0x06, 0x31, 0x6b, 0x88, 0xfa, 0x71, 0xa2, 0x39, 0xca, 0xab, 0x95, 0xb5, 0xaa, 0xd3, 0x54, 0x38,
+	0xc5, 0xb2, 0x0e, 0x4b, 0x92, 0xe6, 0xe2, 0xc8, 0x3d, 0x47, 0x34, 0x42, 0xe1, 0x90, 0x04, 0x48,
+	0xa6, 0x7f, 0xd5, 0xe9, 0x4a, 0xd2, 0x7e, 0xf4, 0x59, 0x4a, 0xb0, 0xfe, 0x0d, 0xba, 0x29, 0xbf,
+	0x58, 0xd3, 0x92, 0xbb, 0x2a, 0xb9, 0x3b, 0x9a, 0xfb, 0x58, 0xa3, 0xed, 0x9f, 0xc2, 0xc2, 0xd1,
+	0x19, 0x25, 0x9c, 0x87, 0x38, 0x1a, 0xec, 0x78, 0xdc, 0x13, 0xc5, 0x27, 0x46, 0x14, 0x93, 0x80,
+	0x69, 0x6b, 0x0d, 0x68, 0xbd, 0x0d, 0x5d, 0xae, 0x78, 0x51, 0xe0, 0x1a, 0x9e, 0xb2, 0xe4, 0x59,
+	0x4c, 0x09, 0x07, 0x9a, 0xf9, 0x0d, 0x58, 0xc8, 0x98, 0x45, 0xf9, 0xd2, 0xf6, 0xb6, 0x53, 0xec,
+	0x11, 0x1e, 0x22, 0xfb, 0x42, 0xc6, 0x4a, 0x4e, 0xb2, 0xf5, 0x36, 0x34, 0xb2, 0x38, 0x94, 0x64,
+	0x82, 0x2d, 0xa8, 0x04, 0x33, 0xe1, 0x74, 0xea, 0x69, 0x50, 0x1e, 0x42, 0x87, 0xa7, 0x86, 0xbb,
+	0x81, 0xc7, 0xbd, 0x62, 0x4e, 0x16, 0xbd, 0x72, 0x16, 0x78, 0x01, 0xb6, 0x3f, 0x85, 0xc6, 0x01,
+	0x0e, 0x98, 0x52, 0xdc, 0x83, 0x9a, 0x9f, 0x50, 0x8a, 0x22, 0x6e, 0x5c, 0xd6, 0xa0, 0xb5, 0x0c,
+	0x73, 0x21, 0x1e, 0x62, 0xae, 0xdd, 0x54, 0x80, 0x4d, 0x00, 0x9e, 0xa1, 0x21, 0xa1, 0x23, 0x19,
+	0xb0, 0x65, 0x98, 0xcb, 0x4f, 0xae, 0x02, 0xac, 0xdb, 0xd0, 0x18, 0x7a, 0x97, 0xe9, 0xa4, 0x0a,
+	0x4a, 0x7d, 0xe8, 0x5d, 0x2a, 0xe3, 0x7b, 0x50, 0x3b, 0xf5, 0x70, 0xe8, 0x47, 0x5c, 0x47, 0xc5,
+	0x80, 0x99, 0xc2, 0x6a, 0x5e, 0xe1, 0x1f, 0xcb, 0xd0, 0x54, 0x1a, 0x95, 0xc1, 0xcb, 0x30, 0xe7,
+	0x7b, 0xfe, 0x59, 0xaa, 0x52, 0x02, 0xd6, 0x7d, 0x63, 0x48, 0x39, 0x5f, 0xc3, 0x33, 0x4b, 0x8d,
+	0x69, 0x1b, 0x00, 0xec, 0x85, 0x17, 0x6b, 0xdb, 0x2a, 0x33, 0x98, 0x1b, 0x82, 0x47, 0x99, 0xfb,
+	0x1e, 0xb4, 0x54, 0xde, 0xe9, 0x21, 0xd5, 0x19, 0x43, 0x9a, 0x8a, 0x4b, 0x0d, 0x7a, 0x0d, 0xda,
+	0x09, 0x43, 0xee, 0x19, 0x46, 0xd4, 0xa3, 0xfe, 0xd9, 0xa8, 0x37, 0xa7, 0xb6, 0xd8, 0x84, 0xa1,
+	0x3d, 0x83, 0xb3, 0x36, 0x61, 0x4e, 0x54, 0x4f, 0xd6, 0x9b, 0x97, 0xbb, 0xf9, 0x9d, 0xbc, 0x48,
+	0xe9, 0xea, 0xba, 0xfc, 0x3e, 0x89, 0x38, 0x1d, 0x39, 0x8a, 0xb5, 0xff, 0x11, 0x40, 0x86, 0xb4,
+	0x16, 0xa1, 0x72, 0x8e, 0x46, 0x7a, 0x1d, 0x8a, 0x5f, 0x11, 0x9c, 0x0b, 0x2f, 0x4c, 0x4c, 0xd4,
+	0x15, 0xf0, 0x49, 0xf9, 0xa3, 0x92, 0xed, 0x43, 0x67, 0x2b, 0x3c, 0xc7, 0x24, 0x37, 0x7c, 0x19,
+	0xe6, 0x86, 0xde, 0x57, 0x84, 0x9a, 0x48, 0x4a, 0x40, 0x62, 0x71, 0x44, 0xa8, 0x11, 0x21, 0x01,
+	0x6b, 0x01, 0xca, 0x24, 0x96, 0xf1, 0x6a, 0x38, 0x65, 0x12, 0x67, 0x8a, 0xaa, 0x39, 0x45, 0xf6,
+	0xdf, 0xaa, 0x00, 0x99, 0x16, 0xcb, 0x81, 0x3e, 0x26, 0x2e, 0x43, 0x54, 0x9c, 0x60, 0xdc, 0x93,
+	0x11, 0x47, 0xcc, 0xa5, 0xc8, 0x4f, 0x28, 0xc3, 0x17, 0x62, 0xfe, 0x84, 0xdb, 0x37, 0x94, 0xdb,
+	0x63, 0xb6, 0x39, 0x37, 0x31, 0x39, 0x54, 0xe3, 0xb6, 0xc4, 0x30, 0xc7, 0x8c, 0xb2, 0xf6, 0xe1,
+	0x46, 0x26, 0x33, 0xc8, 0x89, 0x2b, 0x5f, 0x25, 0x6e, 0x29, 0x15, 0x17, 0x64, 0xa2, 0x9e, 0xc0,
+	0x12, 0x26, 0xee, 0xd7, 0x09, 0x4a, 0x0a, 0x82, 0x2a, 0x57, 0x09, 0xea, 0x62, 0xf2, 0x7f, 0x72,
+	0x40, 0x26, 0xe6, 0x00, 0x6e, 0xe5, 0xbc, 0x14, 0xcb, 0x3d, 0x27, 0xac, 0x7a, 0x95, 0xb0, 0x95,
+	0xd4, 0x2a, 0x51, 0x0f, 0x32, 0x89, 0xff, 0x0b, 0x2b, 0x98, 0xb8, 0x2f, 0x3c, 0xcc, 0xc7, 0xc5,
+	0xcd, 0x7d, 0x8f, 0x93, 0x62, 0xcf, 0x2e, 0xca, 0x52, 0x4e, 0x0e, 0x11, 0x1d, 0x14, 0x9c, 0x9c,
+	0xff, 0x1e, 0x27, 0x9f, 0xc9, 0x01, 0x99, 0x98, 0xc7, 0xd0, 0xc5, 0x64, 0xdc, 0x9a, 0xda, 0x55,
+	0x42, 0x3a, 0x98, 0x14, 0x2d, 0xd9, 0x82, 0x2e, 0x43, 0x3e, 0x27, 0x34, 0x9f, 0x04, 0xf5, 0xab,
+	0x44, 0x2c, 0x6a, 0xfe, 0x54, 0x86, 0xfd, 0x23, 0x68, 0xed, 0x25, 0x03, 0xc4, 0xc3, 0x93, 0xb4,
+	0x18, 0xbc, 0xb4, 0xfa, 0x63, 0xff, 0xba, 0x04, 0xf5, 0x5d, 0x53, 0x90, 0xef, 0x41, 0x53, 0x9d,
+	0xbc, 0xdd, 0xc8, 0x1b, 0x22, 0xbd, 0xc6, 0x40, 0xa1, 0x3e, 0xf7, 0x86, 0x48, 0x9c, 0x4f, 0x92,
+	0x24, 0x3d, 0x37, 0xc9, 0x7f, 0xb1, 0xa1, 0x0d, 0xe5, 0xfa, 0x75, 0xe5, 0x2e, 0xa7, 0x15, 0x34,
+	0x15, 0xee, 0x48, 0xa0, 0x84, 0x5c, 0xcd, 0x92, 0x30, 0x14, 0xe8, 0xe5, 0x03, 0x0a, 0x75, 0xcc,
+	0x50, 0x60, 0xad, 0x42, 0x33, 0xe1, 0x38, 0xc4, 0xdf, 0x78, 0x1c, 0x93, 0x48, 0x56, 0x8e, 0xaa,
+	0x93, 0x47, 0xd9, 0x9f, 0xc3, 0xad, 0x29, 0x07, 0x0b, 0x7d, 0x12, 0x7a, 0x00, 0x2d, 0x2f, 0x0c,
+	0x07, 0x71, 0xe2, 0xaa, 0xe2, 0xa2, 0x56, 0x99, 0xde, 0x4b, 0x8c, 0x77, 0x4e, 0x53, 0xf1, 0x48,
+	0xc0, 0xfe, 0x47, 0x19, 0x9a, 0xdb, 0x03, 0x4a, 0x92, 0xb8, 0xb0, 0x17, 0x99, 0xf1, 0xc5, 0xbd,
+	0x48, 0x8d, 0x17, 0x7b, 0x91, 0x62, 0x7e, 0x3f, 0x75, 0x59, 0xf1, 0xab, 0xfa, 0xdb, 0x9d, 0x28,
+	0x66, 0x26, 0x0a, 0x6a, 0xd4, 0x3a, 0x40, 0x8c, 0x03, 0xa6, 0xc7, 0xa8, 0x32, 0xdc, 0xd1, 0x07,
+	0x69, 0xb3, 0x35, 0x39, 0x8d, 0x38, 0xdd, 0xa5, 0x1e, 0x40, 0xf3, 0x44, 0x24, 0x87, 0x1e, 0x50,
+	0x28, 0xc2, 0x59, 0xd6, 0x38, 0x70, 0x92, 0x15, 0x9f, 0x3d, 0x68, 0x9f, 0xa9, 0x54, 0xd1, 0x83,
+	0xd4, 0xda, 0x79, 0x4d, 0x7b, 0x92, 0xf9, 0xbb, 0x9e, 0xcf, 0x28, 0x95, 0x78, 0xad, 0xb3, 0x1c,
+	0xaa, 0x7f, 0x08, 0xdd, 0x09, 0x96, 0x29, 0xb5, 0x77, 0x2d, 0x5f, 0x7b, 0x9b, 0x9b, 0x96, 0x52,
+	0x94, 0x1f, 0x99, 0xaf, 0xc7, 0xbf, 0x28, 0xc3, 0xc2, 0x7e, 0xc4, 0x11, 0x3d, 0xf5, 0x7c, 0xa4,
+	0x2c, 0xb6, 0xa0, 0x9a, 0xcb, 0x35, 0xf9, 0x6f, 0xdd, 0x82, 0x3a, 0xbd, 0x54, 0xa5, 0x53, 0x67,
+	0x72, 0x8d, 0x5e, 0xca, 0x92, 0x68, 0xbd, 0x02, 0x40, 0x2f, 0xdd, 0xd8, 0xf3, 0xcf, 0x91, 0x8e,
+	0x61, 0xd5, 0x69, 0xd0, 0xcb, 0x03, 0x85, 0x10, 0x8b, 0x80, 0x5e, 0xba, 0x88, 0x52, 0x42, 0x99,
+	0x4e, 0xb3, 0x3a, 0xbd, 0x7c, 0x22, 0x61, 0x3d, 0x36, 0xa0, 0x24, 0x8e, 0x51, 0xa0, 0x73, 0xac,
+	0x41, 0x2f, 0x77, 0x14, 0x42, 0x68, 0xe5, 0x46, 0xeb, 0xbc, 0xd2, 0xca, 0x33, 0xad, 0x3c, 0xd3,
+	0x5a, 0x53, 0x23, 0x79, 0x5e, 0x2b, 0x4f, 0xb5, 0xd6, 0x95, 0x56, 0x9e, 0xd3, 0xca, 0x33, 0xad,
+	0x0d, 0x33, 0x56, 0x6b, 0xb5, 0x7f, 0x5f, 0x86, 0xda, 0x91, 0x2f, 0x27, 0x45, 0xac, 0x02, 0xc4,
+	0xb8, 0x77, 0x12, 0x62, 0x76, 0x86, 0x02, 0xbd, 0xbc, 0xf3, 0x28, 0x61, 0x23, 0x1b, 0x45, 0x2e,
+	0x13, 0x27, 0x17, 0x1d, 0x19, 0x36, 0x8a, 0x0e, 0xc5, 0xc9, 0x45, 0x93, 0x28, 0xf2, 0x2f, 0xcc,
+	0x1a, 0x67, 0xa3, 0xc8, 0x41, 0xfe, 0x85, 0xb0, 0xef, 0x14, 0x47, 0xb2, 0xb6, 0x3e, 0x30, 0x51,
+	0x39, 0xc5, 0x91, 0xa8, 0x9b, 0x0f, 0xf2, 0xc4, 0x4d, 0x1d, 0x14, 0x43, 0xdc, 0x94, 0x9e, 0x89,
+	0xf2, 0x27, 0xa8, 0x3a, 0x28, 0x75, 0x81, 0x10, 0x54, 0x79, 0x28, 0x09, 0x09, 0x43, 0x3a, 0x20,
+	0x0a, 0x10, 0xfe, 0xca, 0x1f, 0x35, 0x46, 0x45, 0xa3, 0x21, 0x31, 0x72, 0xd0, 0x2d, 0xa8, 0x87,
+	0x1e, 0xe3, 0xae, 0xe7, 0x9f, 0xeb, 0x60, 0xd4, 0x04, 0xfc, 0xd8, 0x3f, 0x17, 0x4d, 0x91, 0xe8,
+	0x63, 0x50, 0xd4, 0x03, 0x49, 0xd0, 0x90, 0x3c, 0xad, 0x85, 0x84, 0xe1, 0x68, 0xd0, 0x6b, 0xea,
+	0xd3, 0x9a, 0x02, 0xed, 0x04, 0x6a, 0xc7, 0x81, 0x8a, 0x5d, 0x36, 0xb8, 0x34, 0x3e, 0xd8, 0xc4,
+	0x5e, 0x07, 0x4c, 0x83, 0x3a, 0x57, 0xd4, 0x4e, 0xa8, 0x23, 0x56, 0xa7, 0x97, 0x6a, 0xa3, 0xd3,
+	0x53, 0xaa, 0x89, 0x55, 0x33, 0xa5, 0x8a, 0x68, 0xff, 0xb9, 0x04, 0xad, 0xcf, 0x11, 0x7f, 0x41,
+	0xe8, 0xb9, 0xa9, 0x07, 0x80, 0x4d, 0x5a, 0x9b, 0xea, 0xa3, 0x8f, 0xa5, 0xc5, 0x74, 0x77, 0x72,
+	0x7c, 0xd6, 0x3d, 0xa8, 0x70, 0x3f, 0xd6, 0x2b, 0x47, 0x77, 0xd4, 0x3a, 0x15, 0x1c, 0x41, 0xb1,
+	0x5e, 0x85, 0x2a, 0xf7, 0xe3, 0x0f, 0x74, 0xa9, 0x18, 0xe3, 0x90, 0x24, 0x21, 0x23, 0x09, 0xe2,
+	0x62, 0x57, 0xae, 0x43, 0xe2, 0x08, 0x8a, 0x90, 0x91, 0x04, 0xf1, 0x07, 0x72, 0x66, 0x27, 0x38,
+	0x24, 0xc9, 0xfe, 0x79, 0x09, 0x56, 0xc6, 0xbb, 0x2e, 0x5d, 0x58, 0xdf, 0x87, 0x96, 0x2f, 0x8b,
+	0x46, 0xa1, 0x30, 0x76, 0x27, 0xca, 0x89, 0xd3, 0xf4, 0x73, 0xb5, 0xf4, 0x43, 0x68, 0x47, 0x2a,
+	0x3c, 0x85, 0xfa, 0xa8, 0x8b, 0x43, 0x3e, 0x72, 0x4e, 0x2b, 0xca, 0x41, 0x76, 0x00, 0xd6, 0x17,
+	0x14, 0x73, 0x74, 0xc8, 0x29, 0xf2, 0x86, 0x2f, 0xe3, 0xf2, 0xc0, 0x82, 0xaa, 0x6c, 0x15, 0x2a,
+	0xb2, 0x37, 0x96, 0xff, 0xf6, 0x9b, 0xb0, 0x54, 0xd0, 0xa2, 0x7d, 0x5d, 0x84, 0x4a, 0xa8, 0xd3,
+	0xa7, 0xed, 0x88, 0x5f, 0xdb, 0x83, 0xae, 0x83, 0xbc, 0xe0, 0xe5, 0x59, 0xa3, 0x55, 0x54, 0x32,
+	0x15, 0x6b, 0x60, 0xe5, 0x55, 0x68, 0x53, 0x8c, 0xd5, 0xa5, 0x9c, 0xd5, 0xcf, 0xa1, 0xbb, 0x2d,
+	0x56, 0xd1, 0x21, 0x0f, 0x70, 0xf4, 0x32, 0x6e, 0x3b, 0x7e, 0x02, 0x4b, 0x47, 0x7c, 0xf4, 0x85,
+	0x10, 0xc6, 0xf0, 0x37, 0xe8, 0x25, 0xf9, 0x47, 0xc9, 0x0b, 0xe3, 0x1f, 0x25, 0x2f, 0xc4, 0xb2,
+	0xf4, 0x49, 0x98, 0x0c, 0x23, 0x99, 0xa2, 0x6d, 0x47, 0x43, 0xf6, 0x5f, 0x4b, 0xb0, 0xac, 0xae,
+	0x22, 0x0f, 0xd5, 0x0d, 0x9c, 0x51, 0xdf, 0x87, 0xfa, 0x19, 0x61, 0x3c, 0xb7, 0x27, 0xa4, 0xb0,
+	0x10, 0x1f, 0x44, 0x4c, 0x1e, 0x7a, 0x1b, 0x8e, 0xf8, 0x2d, 0xdc, 0x0f, 0x56, 0xae, 0xbe, 0x1f,
+	0x9c, 0xb8, 0x01, 0xac, 0x4e, 0xde, 0x00, 0x8a, 0xe2, 0x65, 0x98, 0xb0, 0xda, 0x22, 0x1a, 0x4e,
+	0x43, 0x63, 0xf6, 0x03, 0xeb, 0x3e, 0x74, 0x06, 0xc2, 0x4a, 0xf7, 0x8c, 0x90, 0x73, 0x37, 0xf6,
+	0xf8, 0x99, 0x2c, 0x8a, 0x0d, 0xa7, 0x2d, 0xd1, 0x7b, 0x84, 0x9c, 0x1f, 0x78, 0xfc, 0xcc, 0xbe,
+	0x09, 0x37, 0x76, 0x10, 0xe3, 0x94, 0x8c, 0x8a, 0xde, 0xd9, 0xff, 0x05, 0xb0, 0x9f, 0x15, 0x80,
+	0x77, 0xf3, 0x90, 0x2e, 0x1b, 0x8b, 0xeb, 0xea, 0x3a, 0x37, 0x25, 0x38, 0x39, 0x1e, 0x7b, 0x1d,
+	0xe6, 0x1d, 0x92, 0x88, 0x2d, 0xe9, 0x75, 0xf3, 0xa7, 0xc7, 0xb5, 0xf4, 0x38, 0x89, 0x74, 0x34,
+	0xcd, 0xde, 0x33, 0xf7, 0x3f, 0x99, 0x38, 0x1d, 0xe7, 0x75, 0x68, 0xa4, 0xa5, 0x48, 0x2f, 0xeb,
+	0x49, 0xd5, 0x19, 0x8b, 0x7d, 0x04, 0xf6, 0x98, 0xa4, 0xbd, 0x17, 0x8f, 0x83, 0x80, 0x6e, 0x8d,
+	0xc4, 0xc1, 0xf0, 0xba, 0x52, 0xbf, 0x84, 0x25, 0x25, 0x55, 0xd9, 0x6b, 0xc4, 0xbc, 0x0e, 0xf3,
+	0xd4, 0x38, 0x57, 0xca, 0x6e, 0x87, 0x35, 0x93, 0xa6, 0x59, 0x77, 0x84, 0x32, 0x9f, 0xa2, 0xa1,
+	0xd9, 0x0d, 0xeb, 0x4e, 0x86, 0x10, 0x73, 0xf0, 0x14, 0x33, 0x9e, 0x05, 0xcf, 0xcc, 0xc1, 0x12,
+	0x74, 0x05, 0xa1, 0xa0, 0xd1, 0xfe, 0x31, 0x2c, 0x3d, 0x8f, 0x42, 0x1c, 0xa1, 0xed, 0x83, 0xe3,
+	0x67, 0x28, 0x5d, 0xec, 0x16, 0x54, 0xe5, 0x36, 0x56, 0x92, 0xd2, 0xe5, 0xbf, 0xc8, 0xfe, 0xe8,
+	0xc4, 0xf5, 0xe3, 0x84, 0xe9, 0xcb, 0xda, 0xf9, 0xe8, 0x64, 0x3b, 0x4e, 0x98, 0xd8, 0xda, 0xc4,
+	0x11, 0x92, 0x44, 0xe1, 0x48, 0x2e, 0x81, 0xba, 0x53, 0xf3, 0xe3, 0xe4, 0x79, 0x14, 0x8e, 0xec,
+	0xff, 0x86, 0xee, 0xf3, 0xd3, 0x53, 0x2d, 0xff, 0x3a, 0xc2, 0xed, 0x7f, 0x97, 0x37, 0x54, 0x08,
+	0x05, 0x8e, 0x17, 0x05, 0x64, 0xb8, 0x83, 0x2e, 0x72, 0x62, 0xd2, 0xdb, 0x10, 0x53, 0x2c, 0xbe,
+	0x2d, 0x41, 0xeb, 0xf1, 0x00, 0x45, 0x7c, 0x07, 0x71, 0x0f, 0x87, 0xf2, 0xc6, 0xe3, 0x02, 0x51,
+	0x26, 0x0e, 0xd7, 0x6a, 0x55, 0x19, 0x50, 0x9c, 0xcd, 0x71, 0x84, 0xb9, 0x1b, 0x78, 0x68, 0x48,
+	0x22, 0x1d, 0x47, 0x10, 0xa8, 0x1d, 0x89, 0xb1, 0xde, 0x84, 0x8e, 0x6e, 0x0a, 0xce, 0xbc, 0x28,
+	0x08, 0x11, 0x35, 0xd7, 0x93, 0x0b, 0x0a, 0xbd, 0xa7, 0xb1, 0xd6, 0x5b, 0xb0, 0xa8, 0x57, 0x5b,
+	0xc6, 0x59, 0x95, 0x9c, 0x1d, 0x8d, 0x2f, 0xb0, 0x26, 0x71, 0x4c, 0x28, 0x67, 0x2e, 0x43, 0xbe,
+	0x4f, 0x86, 0xb1, 0xbe, 0x2e, 0xe8, 0x18, 0xfc, 0xa1, 0x42, 0xdb, 0x03, 0x58, 0xda, 0x15, 0x7e,
+	0x6a, 0x4f, 0xb2, 0x14, 0x59, 0x18, 0xa2, 0xa1, 0x7b, 0x12, 0x12, 0xff, 0xdc, 0x15, 0xf5, 0x4b,
+	0x87, 0x51, 0x1c, 0xcc, 0xb7, 0x04, 0xf2, 0x10, 0x7f, 0x23, 0x6f, 0xc6, 0x04, 0xd7, 0x19, 0xe1,
+	0x71, 0x98, 0x0c, 0xdc, 0x98, 0x92, 0x13, 0xa4, 0x5d, 0xec, 0x0c, 0xd1, 0x70, 0x4f, 0xe1, 0x0f,
+	0x04, 0xda, 0xfe, 0x43, 0x09, 0x96, 0x8b, 0x9a, 0x74, 0x35, 0xde, 0x80, 0xe5, 0xa2, 0x2a, 0x7d,
+	0x48, 0x54, 0x07, 0x8d, 0x6e, 0x5e, 0xa1, 0x3a, 0x2e, 0x7e, 0x08, 0x6d, 0xf9, 0x46, 0xe3, 0x06,
+	0x4a, 0x52, 0x71, 0xff, 0xcb, 0xcf, 0x8b, 0xd3, 0xf2, 0xf2, 0xb3, 0xf4, 0x31, 0xdc, 0xd2, 0xee,
+	0xbb, 0x93, 0x66, 0xab, 0x94, 0x5a, 0xd1, 0x0c, 0xcf, 0xc6, 0xac, 0x7f, 0x0a, 0xbd, 0x0c, 0xb5,
+	0x35, 0x92, 0x48, 0x13, 0xab, 0x77, 0x61, 0x69, 0xcc, 0x59, 0xb1, 0x72, 0x65, 0xe1, 0xa8, 0x3a,
+	0xd3, 0x48, 0xf6, 0x23, 0xb8, 0x79, 0x88, 0xb8, 0x8a, 0x86, 0xc7, 0x75, 0xa7, 0xae, 0x84, 0x2d,
+	0x42, 0xe5, 0x10, 0xf9, 0xd2, 0xf9, 0x8a, 0x23, 0x7e, 0x45, 0x02, 0x1e, 0x33, 0xe4, 0x4b, 0x2f,
+	0x2b, 0x8e, 0xfc, 0xb7, 0x7f, 0x57, 0x82, 0x9a, 0xae, 0xc1, 0x62, 0x0f, 0x08, 0x28, 0xbe, 0x40,
+	0x54, 0xa7, 0x9e, 0x86, 0xac, 0x37, 0x60, 0x41, 0xfd, 0xb9, 0x24, 0x16, 0x3d, 0x9e, 0xa9, 0xec,
+	0x6d, 0x85, 0x7d, 0xae, 0x90, 0xf2, 0xfa, 0x5d, 0xde, 0x2e, 0xeb, 0x9b, 0x18, 0x0d, 0xc9, 0x3b,
+	0x74, 0x26, 0x6a, 0x8b, 0xac, 0xe4, 0x0d, 0x47, 0x43, 0x22, 0xd5, 0x8d, 0xbc, 0x39, 0x29, 0xcf,
+	0x80, 0xb2, 0x0d, 0x25, 0x49, 0xc4, 0xdd, 0x98, 0xe0, 0x88, 0xeb, 0xd2, 0x0d, 0x12, 0x75, 0x20,
+	0x30, 0xf6, 0xcf, 0x4a, 0x30, 0xaf, 0x9e, 0xa0, 0xac, 0x05, 0x28, 0xa7, 0x9b, 0x5f, 0x19, 0xcb,
+	0x83, 0x84, 0xd4, 0xa5, 0x3b, 0x5f, 0xa9, 0xe9, 0x26, 0xd4, 0x2e, 0x86, 0x6a, 0x1b, 0xd0, 0xa6,
+	0x5d, 0x0c, 0x45, 0xfd, 0x17, 0x9e, 0x65, 0x7b, 0xa8, 0xa4, 0x2b, 0x13, 0xdb, 0x29, 0x56, 0xb2,
+	0xcd, 0xb4, 0xd4, 0xfe, 0x7f, 0x80, 0xec, 0x29, 0x46, 0x84, 0x3c, 0x49, 0x8d, 0x11, 0xbf, 0x02,
+	0x33, 0x48, 0x77, 0x5f, 0xf1, 0x6b, 0xdd, 0x87, 0x05, 0x2f, 0x08, 0xb0, 0x18, 0xee, 0x85, 0xbb,
+	0x38, 0x48, 0x17, 0x69, 0x11, 0x6b, 0xff, 0xa9, 0x04, 0x9d, 0x6d, 0x12, 0x8f, 0xfe, 0x07, 0x87,
+	0x28, 0x57, 0x41, 0xa4, 0x91, 0xba, 0x07, 0x13, 0xff, 0xaa, 0x2d, 0x08, 0x91, 0x5a, 0x5a, 0x6a,
+	0x66, 0xeb, 0x02, 0x21, 0x97, 0x95, 0x21, 0xa6, 0xd7, 0xd2, 0x6d, 0x45, 0x7c, 0x46, 0x02, 0xd9,
+	0xbd, 0x05, 0x98, 0xba, 0xe9, 0x25, 0x74, 0xdb, 0xa9, 0x05, 0x98, 0x4a, 0x92, 0x76, 0x64, 0x4e,
+	0x3e, 0xa3, 0xe4, 0x1d, 0x99, 0x57, 0x18, 0xe1, 0xc8, 0x0a, 0xcc, 0x93, 0xd3, 0x53, 0x86, 0xb8,
+	0x6c, 0x2b, 0x2a, 0x8e, 0x86, 0xd2, 0x32, 0x57, 0xcf, 0x95, 0xb9, 0xff, 0x84, 0xfe, 0x7e, 0xc4,
+	0xb8, 0x17, 0x86, 0x6a, 0xd6, 0x76, 0x64, 0xe2, 0x18, 0xb7, 0xee, 0x82, 0xbe, 0xba, 0x38, 0x12,
+	0x13, 0x57, 0xb8, 0xcc, 0x10, 0x18, 0xfb, 0x06, 0x2c, 0xc9, 0xe7, 0xbe, 0x23, 0xea, 0xf9, 0x38,
+	0x1a, 0x98, 0xad, 0x60, 0x19, 0xac, 0x43, 0x4e, 0xe2, 0x31, 0x6c, 0x1f, 0xaa, 0xfb, 0xf1, 0x85,
+	0xec, 0x57, 0x9d, 0x24, 0x4c, 0xfb, 0x55, 0xf1, 0x6f, 0xff, 0x07, 0x74, 0xf5, 0xde, 0x18, 0x5f,
+	0xa4, 0x05, 0x6a, 0x15, 0xe6, 0x04, 0x68, 0xb6, 0x30, 0xfd, 0x22, 0x29, 0x39, 0x14, 0xc1, 0x5e,
+	0x83, 0x96, 0x1a, 0xa0, 0xeb, 0x4c, 0x0f, 0x6a, 0x1a, 0x36, 0x35, 0x5a, 0x83, 0x9b, 0xbf, 0x5c,
+	0xd2, 0xe5, 0x5c, 0xdf, 0x9c, 0x59, 0xbb, 0xd0, 0x19, 0x7b, 0xc8, 0xb5, 0xf4, 0x55, 0xea, 0xf4,
+	0xf7, 0xdd, 0xfe, 0xca, 0xba, 0x7a, 0x18, 0x5e, 0x37, 0x0f, 0xc3, 0xeb, 0x4f, 0x86, 0x31, 0x1f,
+	0x59, 0x4f, 0x60, 0xa1, 0xf8, 0xe4, 0x69, 0xdd, 0x36, 0x07, 0xa8, 0x29, 0x0f, 0xa1, 0x33, 0xc5,
+	0xec, 0x42, 0x67, 0xec, 0xf5, 0xd3, 0xd8, 0x33, 0xfd, 0x51, 0x74, 0xa6, 0xa0, 0x47, 0xd0, 0xcc,
+	0x3d, 0x77, 0x5a, 0x3d, 0x25, 0x64, 0xf2, 0x05, 0x74, 0xa6, 0x80, 0x6d, 0x68, 0x17, 0x5e, 0x20,
+	0xad, 0xbe, 0xf6, 0x67, 0xca, 0xb3, 0xe4, 0x4c, 0x21, 0x5b, 0xd0, 0xcc, 0x3d, 0x04, 0x1a, 0x2b,
+	0x26, 0x5f, 0x1b, 0xfb, 0xb7, 0xa6, 0x50, 0xf4, 0x6c, 0xee, 0x41, 0xbb, 0xf0, 0x6c, 0x67, 0x0c,
+	0x99, 0xf6, 0x64, 0xd8, 0xbf, 0x3d, 0x95, 0xa6, 0x25, 0xed, 0x42, 0x67, 0xec, 0x11, 0xcf, 0x04,
+	0x77, 0xfa, 0xdb, 0xde, 0x4c, 0xb7, 0x8e, 0xa0, 0x3b, 0x71, 0x87, 0x66, 0xdd, 0x4d, 0xe7, 0x7b,
+	0xea, 0xab, 0x5d, 0xff, 0xde, 0x4c, 0xba, 0x36, 0xef, 0x33, 0x99, 0x42, 0x39, 0x62, 0x2e, 0x85,
+	0x26, 0x5f, 0xf2, 0xfa, 0x77, 0xa6, 0x13, 0xb5, 0xb0, 0x27, 0xb0, 0x50, 0x7c, 0xc4, 0x33, 0xc2,
+	0xa6, 0x3e, 0xed, 0x5d, 0x9d, 0x8f, 0x85, 0xf7, 0xbc, 0x2c, 0x1f, 0xa7, 0x3d, 0xf3, 0xcd, 0x14,
+	0xf4, 0x18, 0x40, 0xf7, 0x8a, 0x01, 0x8e, 0xd2, 0x44, 0x98, 0xe8, 0x51, 0xd3, 0x44, 0x98, 0xd2,
+	0x57, 0x3e, 0x02, 0x50, 0x2d, 0x5e, 0x40, 0x12, 0x6e, 0xdd, 0x34, 0x66, 0x8c, 0xf5, 0x95, 0xfd,
+	0xde, 0x24, 0x61, 0x42, 0x00, 0xa2, 0xf4, 0x3a, 0x02, 0x1e, 0x02, 0x64, 0xad, 0xa3, 0x11, 0x30,
+	0xd1, 0x4c, 0x5e, 0x11, 0x83, 0x56, 0xbe, 0x51, 0xb4, 0xb4, 0xaf, 0x53, 0x9a, 0xc7, 0x2b, 0x44,
+	0x74, 0xc6, 0xba, 0x87, 0x62, 0x0a, 0x8f, 0xb7, 0x27, 0xfd, 0x89, 0xae, 0xc1, 0xfa, 0x12, 0x6e,
+	0x5f, 0xd1, 0x80, 0x58, 0x6b, 0x53, 0xc5, 0x4d, 0xe9, 0x51, 0xa6, 0x88, 0xfe, 0x10, 0x5a, 0xf9,
+	0x2e, 0xc4, 0x38, 0x38, 0xa5, 0x33, 0xe9, 0x17, 0x3a, 0x11, 0xeb, 0x11, 0x2c, 0x14, 0x7b, 0x0c,
+	0x2b, 0xb7, 0x90, 0x27, 0x3a, 0x8f, 0xfe, 0xe2, 0xd8, 0x95, 0x10, 0xb3, 0xde, 0x03, 0xc8, 0x7a,
+	0x11, 0x33, 0x33, 0x13, 0xdd, 0xc9, 0x98, 0xd6, 0xc7, 0xd0, 0xca, 0xef, 0x5b, 0xc6, 0xdc, 0x29,
+	0x7b, 0xd9, 0x55, 0x65, 0x36, 0xb7, 0xc7, 0x99, 0xbc, 0x9e, 0xdc, 0xf6, 0xae, 0x2a, 0xb3, 0x85,
+	0xf6, 0xdd, 0x54, 0xb7, 0x69, 0x3d, 0xfd, 0x55, 0x9b, 0x4f, 0xb1, 0x4d, 0x36, 0xe1, 0x9b, 0xda,
+	0x3c, 0x5f, 0x95, 0x9f, 0xf9, 0xde, 0xcd, 0xc4, 0x63, 0x4a, 0x3f, 0x37, 0x53, 0xc4, 0x43, 0x80,
+	0xac, 0x3f, 0x33, 0xf3, 0x30, 0xd1, 0xb1, 0x7d, 0x4f, 0xb9, 0xc9, 0x37, 0x67, 0xb9, 0x72, 0x33,
+	0xa5, 0x67, 0x9b, 0x29, 0x68, 0x0f, 0x3a, 0xbb, 0xe6, 0xdc, 0xad, 0x7b, 0x02, 0xed, 0xcd, 0x94,
+	0x1e, 0xa8, 0xdf, 0x9f, 0x46, 0x4a, 0xab, 0x72, 0x77, 0xa2, 0x1f, 0x30, 0xb5, 0x7e, 0x56, 0xa3,
+	0x30, 0xd3, 0xac, 0x7d, 0x58, 0x1c, 0x6f, 0x07, 0xac, 0x57, 0x74, 0xce, 0x4c, 0x6f, 0x13, 0x66,
+	0x8a, 0xfa, 0x18, 0xea, 0xe6, 0xf8, 0x69, 0xe9, 0x17, 0xb0, 0xb1, 0xe3, 0xe8, 0x15, 0x93, 0xb4,
+	0x90, 0x3b, 0x66, 0x25, 0x21, 0x32, 0x13, 0x35, 0x71, 0xf8, 0xea, 0x5b, 0xb9, 0xd3, 0x96, 0x89,
+	0xc8, 0x73, 0x58, 0x9a, 0x72, 0x58, 0xb4, 0x56, 0xcd, 0xa2, 0x9c, 0x75, 0x8e, 0x9c, 0x65, 0xcf,
+	0x56, 0xeb, 0xdb, 0xef, 0xee, 0x96, 0xfe, 0xf2, 0xdd, 0xdd, 0xd2, 0xdf, 0xbf, 0xbb, 0x5b, 0x3a,
+	0x99, 0x97, 0xd4, 0xf7, 0xfe, 0x19, 0x00, 0x00, 0xff, 0xff, 0xa4, 0x82, 0xa7, 0x81, 0xd8, 0x27,
+	0x00, 0x00,
 }
diff --git a/virtcontainers/agent.go b/virtcontainers/agent.go
index f8651be..9053757 100644
--- a/virtcontainers/agent.go
+++ b/virtcontainers/agent.go
@@ -204,6 +204,12 @@ type agent interface {
 	// wait specifies that onlineCPUMem is done sync or async
 	onlineCPUMem(cpus uint32, cpuOnly bool, wait bool) error
 
+	// offlineCPU will offline CPUs and Memory inside the Sandbox.
+	// This function should be called after hot unpluging vCPUs.
+	// cpus specifies the number of CPUs that were added and the agent should offline
+	// wait specifies that offlineCPU is done sync or async
+	offlineCPU(cpus uint32, wait bool) error
+
 	// statsContainerGpu will tell the agent to get GPU stats from a container related to a Sandbox
 	statsContainerGpu(sandbox *Sandbox, c Container) (*pb.StatsContainerGpuResponse, error)
 
@@ -240,6 +246,8 @@ type agent interface {
 	// updateInterface will tell the agent to update a nic for an existed Sandbox.
 	updateInterface(inf *vcTypes.Interface) (*vcTypes.Interface, error)
 
+	updateInterfaceHwAddrByName(inf *vcTypes.Interface) (*vcTypes.Interface, error)
+
 	// listInterfaces will tell the agent to list interfaces of an existed Sandbox
 	listInterfaces() ([]*vcTypes.Interface, error)
 
diff --git a/virtcontainers/hypervisor.go b/virtcontainers/hypervisor.go
index 3590f1a..698a5da 100644
--- a/virtcontainers/hypervisor.go
+++ b/virtcontainers/hypervisor.go
@@ -33,6 +33,8 @@ const (
 
 	// MockHypervisor is a mock hypervisor for testing purposes
 	MockHypervisor HypervisorType = "mock"
+
+	QuantvisorHypervisor HypervisorType = "quantvisor"
 )
 
 const (
@@ -115,6 +117,9 @@ func (hType *HypervisorType) Set(value string) error {
 	case "mock":
 		*hType = MockHypervisor
 		return nil
+	case "quantvisor":
+		*hType = QuantvisorHypervisor
+		return nil
 	default:
 		return fmt.Errorf("Unknown hypervisor type %s", value)
 	}
@@ -129,6 +134,8 @@ func (hType *HypervisorType) String() string {
 		return string(FirecrackerHypervisor)
 	case MockHypervisor:
 		return string(MockHypervisor)
+	case QuantvisorHypervisor:
+		return string(QuantvisorHypervisor)
 	default:
 		return ""
 	}
@@ -143,6 +150,8 @@ func newHypervisor(hType HypervisorType) (hypervisor, error) {
 		return &firecracker{}, nil
 	case MockHypervisor:
 		return &mockHypervisor{}, nil
+	case QuantvisorHypervisor:
+		return &quantvisor{}, nil
 	default:
 		return nil, fmt.Errorf("Unknown hypervisor type %s", hType)
 	}
diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go
index 83fe1b0..02ef437 100644
--- a/virtcontainers/kata_agent.go
+++ b/virtcontainers/kata_agent.go
@@ -542,6 +542,15 @@ func (k *kataAgent) updateInterface(ifc *vcTypes.Interface) (*vcTypes.Interface,
 	return nil, err
 }
 
+func (k *kataAgent) updateInterfaceHwAddrByName(ifc *vcTypes.Interface) (*vcTypes.Interface, error) {
+	ifcReq := &grpc.UpdateInterfaceHwAddrByNameRequest{
+		Interface: k.convertToKataAgentInterface(ifc),
+	}
+	_, err := k.sendReq(ifcReq)
+
+	return nil, err
+}
+
 func (k *kataAgent) updateInterfaces(interfaces []*vcTypes.Interface) error {
 	for _, ifc := range interfaces {
 		if _, err := k.updateInterface(ifc); err != nil {
@@ -1619,6 +1628,16 @@ func (k *kataAgent) onlineCPUMem(cpus uint32, cpuOnly bool, wait bool) error {
 	return err
 }
 
+func (k *kataAgent) offlineCPU(cpus uint32, wait bool) error {
+	req := &grpc.OfflineCPURequest{
+		Wait: wait,
+		NbCpus: cpus,
+	}
+
+	_, err := k.sendReq(req)
+	return err
+}
+
 func (k *kataAgent) statsContainerGpu(sandbox *Sandbox, c Container) (*pb.StatsContainerGpuResponse, error) {
 	req := &grpc.StatsContainerGpuRequest{
 		ContainerId: c.id,
@@ -1842,6 +1861,11 @@ func (k *kataAgent) installReqFunc(c *kataclient.AgentClient) {
 		defer cancel()
 		return k.client.UpdateInterface(ctx, req.(*grpc.UpdateInterfaceRequest), opts...)
 	}
+	k.reqHandlers["grpc.UpdateInterfaceHwAddrByNameRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
+		ctx, cancel := context.WithTimeout(ctx, defaultGrpcTimeout)
+		defer cancel()
+		return k.client.UpdateInterfaceHwAddrByName(ctx, req.(*grpc.UpdateInterfaceHwAddrByNameRequest), opts...)
+	}
 	k.reqHandlers["grpc.ListInterfacesRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
 		ctx, cancel := context.WithTimeout(ctx, defaultGrpcTimeout)
 		defer cancel()
@@ -1857,6 +1881,11 @@ func (k *kataAgent) installReqFunc(c *kataclient.AgentClient) {
 		defer cancel()
 		return k.client.OnlineCPUMem(ctx, req.(*grpc.OnlineCPUMemRequest), opts...)
 	}
+	k.reqHandlers["grpc.OfflineCPURequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
+		ctx, cancel := context.WithTimeout(ctx, defaultGrpcTimeout)
+		defer cancel()
+		return k.client.OfflineCPU(ctx, req.(*grpc.OfflineCPURequest), opts...)
+	}
 	k.reqHandlers["grpc.ListProcessesRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
 		ctx, cancel := context.WithTimeout(ctx, defaultGrpcTimeout)
 		defer cancel()
diff --git a/virtcontainers/noop_agent.go b/virtcontainers/noop_agent.go
index ad14efe..41034bc 100644
--- a/virtcontainers/noop_agent.go
+++ b/virtcontainers/noop_agent.go
@@ -102,11 +102,20 @@ func (n *noopAgent) onlineCPUMem(cpus uint32, cpuOnly bool, wait bool) error {
 	return nil
 }
 
+// offlineCPU is the Noop agent Container offline CPU implementation. It does nothing.
+func (n *noopAgent) offlineCPU(cpus uint32, wait bool) error {
+	return nil
+}
+
 // updateInterface is the Noop agent Interface update implementation. It does nothing.
 func (n *noopAgent) updateInterface(inf *vcTypes.Interface) (*vcTypes.Interface, error) {
 	return nil, nil
 }
 
+func (n *noopAgent) updateInterfaceHwAddrByName(inf *vcTypes.Interface) (*vcTypes.Interface, error) {
+	return nil, nil
+}
+
 // listInterfaces is the Noop agent Interfaces list implementation. It does nothing.
 func (n *noopAgent) listInterfaces() ([]*vcTypes.Interface, error) {
 	return nil, nil
diff --git a/virtcontainers/quantvisor.go b/virtcontainers/quantvisor.go
new file mode 100644
index 0000000..c818e17
--- /dev/null
+++ b/virtcontainers/quantvisor.go
@@ -0,0 +1,687 @@
+package virtcontainers
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"os/exec"
+	"io/ioutil"
+	"time"
+	"strconv"
+	"strings"
+	"syscall"
+	"path/filepath"
+
+	govmmQemu "github.com/intel/govmm/qemu"
+	"github.com/opentracing/opentracing-go"
+	"github.com/sirupsen/logrus"
+
+	"github.com/kata-containers/runtime/virtcontainers/device/config"
+	"github.com/kata-containers/runtime/virtcontainers/store"
+	"github.com/kata-containers/runtime/virtcontainers/types"
+	vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
+)
+
+const defaultDummyMac = "22:33:44:aa:bb:"
+const mmioBlkCount = 6
+const mmioNetCount = 2
+
+type quantvisorDev struct {
+	dev     interface{}
+	devType deviceType
+}
+
+type quantvisor struct {
+	id string
+	ctx context.Context
+	sandbox *Sandbox
+	store *store.VCStore
+	config HypervisorConfig
+	socketPath string
+	consolePath string
+	pidFilePath string
+	qmpMonitorCh qmpChannel
+	devices []quantvisorDev
+	HotpluggedVCPUs []CPUDevice
+	mmioBlkSlots [mmioBlkCount]bool
+	mmioNetSlots [mmioNetCount]bool
+}
+
+func (q *quantvisor) Logger() *logrus.Entry {
+	return virtLog.WithField("subsystem", "quantvisor")
+}
+
+func (q *quantvisor) trace(name string) (opentracing.Span, context.Context) {
+	span, ctx := opentracing.StartSpanFromContext(q.ctx, name)
+
+	span.SetTag("subsystem", "hypervisor")
+	span.SetTag("type", "quantvisor")
+
+	return span, ctx
+}
+
+func (q *quantvisor) getKernelCmdLine() string {
+	var params []string
+
+	params = append(params, "pci=off")
+	params = append(params, "reboot=k")
+	params = append(params, "panic=1")
+	params = append(params, "iommu=off")
+	params = append(params, "acpi=off")
+	params = append(params, "quiet")
+	params = append(params, "agent.use_vsock=" + strconv.FormatBool(q.config.UseVSock))
+	params = append(params, SerializeParams(q.config.KernelParams, "=")...)
+
+	return strings.Join(params, " ")
+}
+
+func (q *quantvisor) hypervisorConfig() HypervisorConfig {
+	return q.config
+}
+
+func (q *quantvisor) createSandbox(ctx context.Context, id string, hypervisorConfig *HypervisorConfig, vcstore *store.VCStore) error {
+	q.ctx = ctx
+
+	span, _ := q.trace("createSandbox")
+	defer span.Finish()
+
+	sandbox, err := globalSandboxList.lookupSandbox(id)
+	if err != nil {
+		q.Logger().Error("createSandbox: get sandbox failed")
+		return err
+	}
+
+	q.id = id
+	q.sandbox = sandbox
+	q.store = vcstore
+	q.config = *hypervisorConfig
+	q.socketPath = filepath.Join(store.RunVMStoragePath, id, "qmp.sock")
+	q.consolePath = filepath.Join(store.RunVMStoragePath, id, "console.sock")
+	q.pidFilePath = filepath.Join(store.RunVMStoragePath, id, "pid")
+	q.qmpMonitorCh = qmpChannel{
+		ctx:  q.ctx,
+		path: q.socketPath,
+	}
+
+	return err
+}
+
+func (q *quantvisor) waitSandBoxStarted(timeout int) error {
+	timeStart := time.Now()
+	for {
+		err := q.qmpSetup()
+		if err == nil {
+			break
+		}
+
+		if int(time.Since(timeStart).Seconds()) > timeout {
+			return fmt.Errorf("Failed to connect to QuantVisor instance (timeout %ds): %v", timeout, err)
+		}
+
+		time.Sleep(time.Duration(50) * time.Millisecond)
+	}
+
+	if err := q.qmpMonitorCh.qmp.ExecuteQMPCapabilities(q.qmpMonitorCh.ctx); err != nil {
+		q.Logger().WithError(err).Error(qmpCapErrMsg)
+		return err
+	}
+
+	return nil
+}
+
+func (q *quantvisor) startSandbox(timeout int) error {
+	span, _ := q.trace("startSandbox")
+	defer span.Finish()
+
+	var params []string
+	params = append(params, "-name " + fmt.Sprintf("sandbox-%s", q.id))
+	params = append(params, "-api-channel unix:" + q.socketPath)
+	params = append(params, "-pidfile " + q.pidFilePath)
+
+	if kernelPath, err := q.config.KernelAssetPath(); err == nil {
+		params = append(params, "-kernel " + kernelPath)
+	}
+
+	if initrdPath, err := q.config.InitrdAssetPath(); err == nil {
+		params = append(params, "-initrd " + initrdPath)
+	}
+
+	params = append(params, "-append " + q.getKernelCmdLine())
+	params = append(params, fmt.Sprintf("-smp %d,maxcpus=%d", q.config.NumVCPUs, q.config.DefaultMaxVCPUs))
+	params = append(params, fmt.Sprintf("-m %d", q.config.MemorySize * 1024 * 1024))
+	params = append(params, fmt.Sprintf("-chardev id=charconsole0,path=%s", q.consolePath))
+
+	// add devices to cmdline
+	for _, d := range q.devices {
+		switch v := d.dev.(type) {
+		case Endpoint:
+			name := v.Name()
+			mac := v.HardwareAddr()
+			tapName := v.NetworkPair().TapInterface.TAPIface.Name
+			params = append(params, fmt.Sprintf("-net id=%s,mac=%s,host_dev_name=%s", name, mac, tapName))
+		case config.BlockDrive:
+			id := v.ID
+			path := v.File
+			params = append(params, fmt.Sprintf("-drive id=%s,file=%s", id, path))
+		case kataVSOCK:
+			guestCid := v.contextID
+			v.vhostFd.Close()
+			params = append(params, fmt.Sprintf("-device vsock,id=vsock-id,guest-cid=%d", guestCid))
+		default:
+			q.Logger().Error("Adding device: un-support device type")
+		}
+	}
+
+	// daemonize and logfile
+	params = append(params, "-daemonize")
+
+	q.Logger().Info("VM start with params: ", strings.Join(params, " "))
+
+	dir := filepath.Join(store.RunVMStoragePath, q.id)
+	err := os.MkdirAll(dir, store.DirMode)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if err != nil {
+			if err := os.RemoveAll(dir); err != nil {
+				q.Logger().WithError(err).Error("Fail to clean up vm dir %s", dir)
+			}
+		}
+	}()
+
+	binPath, err := q.config.HypervisorAssetPath()
+	if err != nil {
+		q.Logger().WithField("Fail to get hypervisor bin path", err).Error()
+		return err
+	}
+
+	cmd := exec.CommandContext(q.ctx, binPath, params...)
+	if err := cmd.Run(); err != nil {
+		q.Logger().WithField("Error starting hypervisor, check the params", err).Error()
+		return err
+	}
+
+	if err = q.waitSandBoxStarted(timeout); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (q *quantvisor) stopSandbox(force bool) error {
+	span, _ := q.trace("stopSandbox")
+	defer span.Finish()
+
+	defer func () {
+		dir := filepath.Join(store.RunVMStoragePath, q.id)
+		link, _ := filepath.EvalSymlinks(dir)
+
+		if err := os.RemoveAll(dir); err != nil {
+			q.Logger().WithError(err).Warnf("failed to remove vm path %s", dir)
+		}
+
+		if link != dir && link != "" {
+			if err := os.RemoveAll(link); err != nil {
+				q.Logger().WithError(err).WithField("link", link).Warn("failed to remove vm path link %s", link)
+			}
+		}
+	}()
+
+	if !force {
+		err := q.qmpSetup()
+		if err != nil {
+			return err
+		}
+
+		err = q.qmpMonitorCh.qmp.ExecuteQuit(q.qmpMonitorCh.ctx)
+		if err != nil {
+			q.Logger().WithError(err).Error("Fail to execute qmp QUIT")
+			return err
+		}
+	} else {
+		if q.pid() > 0 {
+			syscall.Kill(q.pid(), syscall.SIGKILL)
+		}
+	}
+	return nil
+}
+
+func (q *quantvisor) pauseSandbox() error {
+	return nil
+}
+
+func (q *quantvisor) saveSandbox() error {
+	return nil
+}
+
+func (q *quantvisor) resumeSandbox() error {
+	return nil
+}
+
+func (q *quantvisor) addDevice(devInfo interface{}, devType deviceType) error {
+	dev := quantvisorDev {
+		dev:     devInfo,
+		devType: devType,
+	}
+	q.devices = append(q.devices, dev)
+
+	return nil
+}
+
+func (q *quantvisor) updateVMInterfaceHwAddr(Name string, HwAddr string) {
+	inf := &vcTypes.Interface{
+		Name: Name,
+		HwAddr: HwAddr,
+		IPAddresses: []*vcTypes.IPAddress{},
+		PciAddr: "",
+	}
+
+	_, err := q.sandbox.agent.updateInterfaceHwAddrByName(inf)
+	if err != nil {
+		q.Logger().WithError(err).Error("updateInterfaceHwAddrByName failed")
+	}
+}
+
+func (q *quantvisor) getDevSlot(Name string, isPut bool) (slot int, err error){
+	Name = filepath.Base(strings.ToLower(Name))
+
+	if strings.HasPrefix(Name, "eth") {
+		idxStr := strings.TrimPrefix(Name, "eth")
+		if idxStr == Name {
+			return 0, fmt.Errorf("Could not get idx from Name %q", Name)
+		}
+
+		idx, err := strconv.Atoi(idxStr)
+		if err != nil {
+			return 0, fmt.Errorf("Could not convert to index from Str %q", idxStr)
+		}
+
+		if !isPut && q.mmioNetSlots[idx] {
+			return 0, fmt.Errorf("getDevSlot failed, the slot is being used %q", idxStr)
+		}
+		q.mmioNetSlots[idx] = !isPut
+
+		return idx, nil
+	} else if strings.HasPrefix(Name, "vd") {
+		charStr := strings.TrimPrefix(Name, "vd")
+		if charStr == Name {
+			return 0, fmt.Errorf("Could not get idx from Name %q", Name)
+		}
+
+		char := []rune(charStr)
+		idx := int(char[0] - 'a')
+
+		if !isPut && q.mmioBlkSlots[idx] {
+			return 0, fmt.Errorf("getDevSlot failed, the slot is being used %q", charStr)
+		}
+		q.mmioBlkSlots[idx] = !isPut
+
+		return idx, nil
+	}
+
+	return 0, fmt.Errorf("getDevSlot failed, Name is invalid %q", Name)
+}
+
+func (q *quantvisor) hotplugNet(endpoint Endpoint, op operation) (err error) {
+	err = q.qmpSetup()
+	if err != nil {
+		return err
+	}
+	var tap TapInterface
+
+	switch endpoint.Type() {
+	case VethEndpointType:
+		drive := endpoint.(*VethEndpoint)
+		tap = drive.NetPair.TapInterface
+	case TapEndpointType:
+		drive := endpoint.(*TapEndpoint)
+		tap = drive.TapInterface
+	default:
+		return fmt.Errorf("this endpoint is not supported")
+	}
+
+	switch op {
+	case addDevice:
+		var (
+			VMFdNames    []string
+			VhostFdNames []string
+		)
+		for i, VMFd := range tap.VMFds {
+			fdName := fmt.Sprintf("fd%d", i)
+			if err := q.qmpMonitorCh.qmp.ExecuteGetFD(q.qmpMonitorCh.ctx, fdName, VMFd); err != nil {
+				return err
+			}
+			VMFdNames = append(VMFdNames, fdName)
+		}
+		for i, VhostFd := range tap.VhostFds {
+			fdName := fmt.Sprintf("vhostfd%d", i)
+			if err := q.qmpMonitorCh.qmp.ExecuteGetFD(q.qmpMonitorCh.ctx, fdName, VhostFd); err != nil {
+				return err
+			}
+			VhostFd.Close()
+			VhostFdNames = append(VhostFdNames, fdName)
+		}
+
+		slot, err := q.getDevSlot(endpoint.Name(), false)
+		if err != nil {
+			return fmt.Errorf("Could not get unused slot for %q", endpoint.Name())
+		}
+
+		if len(VMFdNames) != 0 || len(VhostFdNames) != 0 {
+			q.qmpMonitorCh.qmp.ExecuteNetdevAddByFds(q.qmpMonitorCh.ctx, "tap", tap.ID, VMFdNames, VhostFdNames)
+		} else {
+			q.qmpMonitorCh.qmp.ExecuteNetdevAdd(q.qmpMonitorCh.ctx, "tap", tap.ID, tap.TAPIface.Name, "no", "no", "on", 0)
+		}
+		q.qmpMonitorCh.qmp.ExecuteNetPCIDeviceAdd(q.qmpMonitorCh.ctx, tap.Name, tap.ID, endpoint.HardwareAddr(), fmt.Sprintf("%d", slot), "", "", 0, false)
+
+		// update vm interface
+		q.updateVMInterfaceHwAddr(endpoint.Name(), endpoint.HardwareAddr())
+		return nil
+	default:
+		if err := q.qmpMonitorCh.qmp.ExecuteDeviceDel(q.qmpMonitorCh.ctx, tap.ID); err != nil {
+			return err
+		}
+		if err := q.qmpMonitorCh.qmp.ExecuteNetdevDel(q.qmpMonitorCh.ctx, tap.ID); err != nil {
+			return err
+		}
+
+		slot, err := q.getDevSlot(endpoint.Name(), true)
+		if err != nil {
+			slot = 0
+		}
+
+		// clear vm interface
+		q.updateVMInterfaceHwAddr(endpoint.Name(), defaultDummyMac + fmt.Sprintf("%02x", slot))
+		return nil
+	}
+}
+
+func (q *quantvisor) hotplugBlk(drive *config.BlockDrive, op operation) (err error) {
+	err = q.qmpSetup()
+	if err != nil {
+		return err
+	}
+
+	switch op {
+	case addDevice:
+		driver := "virtio-blk-pci"
+		slot, err := q.getDevSlot(drive.VirtPath, false)
+		if err != nil {
+			return fmt.Errorf("Could not get unused slot for %q", drive.VirtPath)
+		}
+
+		q.qmpMonitorCh.qmp.ExecuteBlockdevAdd(q.qmpMonitorCh.ctx, drive.File, drive.ID)
+		q.qmpMonitorCh.qmp.ExecutePCIDeviceAdd(q.qmpMonitorCh.ctx, drive.ID, drive.ID, driver, fmt.Sprintf("%d", slot), "", "", true, false)
+		return nil
+	default:
+		if err := q.qmpMonitorCh.qmp.ExecuteDeviceDel(q.qmpMonitorCh.ctx, drive.ID); err != nil {
+			return err
+		}
+
+		if err := q.qmpMonitorCh.qmp.ExecuteBlockdevDel(q.qmpMonitorCh.ctx, drive.ID); err != nil {
+			return err
+		}
+
+		q.getDevSlot(drive.VirtPath, true)
+		return nil
+	}
+}
+
+func (q *quantvisor) hotplugCPUs(vcpus uint32, op operation) (uint32, error) {
+	if vcpus == 0 {
+		q.Logger().Warnf("cannot hotplug 0 vCPUs")
+		return 0, nil
+	}
+
+	err := q.qmpSetup()
+	if err != nil {
+		return 0, err
+	}
+
+	if op == addDevice {
+		currentVCPUs := q.config.NumVCPUs + uint32(len(q.HotpluggedVCPUs))
+
+		if currentVCPUs + vcpus > q.config.DefaultMaxVCPUs {
+			q.Logger().Warnf("Cannot hotlug %d CPUs, currently this SB has %d CPUs and the maximum amount of CPUs is %d",
+				vcpus, currentVCPUs, q.config.DefaultMaxVCPUs)
+			vcpus = q.config.DefaultMaxVCPUs - currentVCPUs
+		}
+
+		if vcpus == 0 {
+			q.Logger().Warnf("maximum number of vCPUs '%d' has been reached", q.config.DefaultMaxVCPUs)
+			return 0, nil
+		}
+
+		// get the list of hotpluggable CPUs
+		hotpluggableVCPUs, err := q.qmpMonitorCh.qmp.ExecuteQueryHotpluggableCPUs(q.qmpMonitorCh.ctx)
+		if err != nil {
+			return 0, fmt.Errorf("failed to query hotpluggable CPUs: %v", err)
+		}
+
+		var hotpluggedVCPUs uint32
+		for _, hc := range hotpluggableVCPUs {
+			if hc.QOMPath != "" {
+				continue
+			}
+
+			driver := hc.Type
+			cpuID := fmt.Sprintf("cpu-%d", uint32(len(q.HotpluggedVCPUs))+q.config.NumVCPUs)
+			socketID := fmt.Sprintf("%d", hc.Properties.Socket)
+			coreID := fmt.Sprintf("%d", hc.Properties.Core)
+			threadID := fmt.Sprintf("%d", hc.Properties.Thread)
+
+			if err := q.qmpMonitorCh.qmp.ExecuteCPUDeviceAdd(q.qmpMonitorCh.ctx, driver, cpuID, socketID, coreID, threadID, romFile); err != nil {
+				continue
+			}
+
+			q.HotpluggedVCPUs = append(q.HotpluggedVCPUs, CPUDevice{cpuID})
+
+			hotpluggedVCPUs++
+			if hotpluggedVCPUs == vcpus {
+				return vcpus, nil
+			}
+		}
+		return hotpluggedVCPUs, fmt.Errorf("failed to hot add vCPUs: only %d vCPUs of %d were added", hotpluggedVCPUs, vcpus)
+	}
+
+	hotpluggedVCPUs := uint32(len(q.HotpluggedVCPUs))
+
+	if vcpus > hotpluggedVCPUs {
+		return 0, fmt.Errorf("Unable to remove %d CPUs, currently there are only %d hotpluggabled CPUs", vcpus, hotpluggedVCPUs)
+	}
+
+	for i := uint32(0); i < vcpus; i++ {
+		cpu := q.HotpluggedVCPUs[len(q.HotpluggedVCPUs)-1]
+		if err := q.qmpMonitorCh.qmp.ExecuteDeviceDel(q.qmpMonitorCh.ctx, cpu.ID); err != nil {
+			return i, fmt.Errorf("failed to hotunplug CPUs, only %d CPUs were hotunplugged: %v", i, err)
+		}
+
+		q.HotpluggedVCPUs = q.HotpluggedVCPUs[:len(q.HotpluggedVCPUs)-1]
+	}
+
+	return vcpus, nil
+}
+
+func (q *quantvisor) hotplugAddDevice(devInfo interface{}, devType deviceType) (interface{}, error) {
+	span, _ := q.trace("hotplugAddDevice")
+	defer span.Finish()
+
+	switch devType {
+	case netDev:
+		q.hotplugNet(devInfo.(Endpoint), addDevice)
+	case blockDev:
+		q.hotplugBlk(devInfo.(*config.BlockDrive), addDevice)
+	case cpuDev:
+		return q.hotplugCPUs(devInfo.(uint32), addDevice)
+	default:
+		return nil, fmt.Errorf("cannot hotplug device: unsupported device type '%v'", devType)
+	}
+
+	return nil, nil
+}
+
+func (q *quantvisor) hotplugRemoveDevice(devInfo interface{}, devType deviceType) (interface{}, error) {
+	span, _ := q.trace("hotplugRemoveDevice")
+	defer span.Finish()
+
+	switch devType {
+	case netDev:
+		q.hotplugNet(devInfo.(Endpoint), removeDevice)
+	case blockDev:
+		q.hotplugBlk(devInfo.(*config.BlockDrive), removeDevice)
+	case cpuDev:
+		return q.hotplugCPUs(devInfo.(uint32), removeDevice)
+	default:
+		return nil, fmt.Errorf("cannot hotplug device: unsupported device type '%v'", devType)
+	}
+
+	return nil, nil
+}
+
+func (q *quantvisor) resizeMemory(reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
+	return 0, memoryDevice{}, nil
+}
+
+func (q *quantvisor) resizeVCPUs(reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
+	currentVCPUs = q.config.NumVCPUs + uint32(len(q.HotpluggedVCPUs))
+	newVCPUs = currentVCPUs
+	switch {
+	case currentVCPUs < reqVCPUs:
+		addCPUs := reqVCPUs - currentVCPUs
+		data, err := q.hotplugAddDevice(addCPUs, cpuDev)
+		if err != nil {
+			return currentVCPUs, newVCPUs, err
+		}
+		vCPUsAdded, ok := data.(uint32)
+		if !ok {
+			return currentVCPUs, newVCPUs, fmt.Errorf("Could not get the vCPUs added, got %+v", data)
+		}
+		newVCPUs += vCPUsAdded
+	case currentVCPUs > reqVCPUs:
+		removeCPUs := currentVCPUs - reqVCPUs
+		data, err := q.hotplugRemoveDevice(removeCPUs, cpuDev)
+		if err != nil {
+			return currentVCPUs, newVCPUs, err
+		}
+		VCPUsRemoved, ok := data.(uint32)
+		if !ok {
+			return currentVCPUs, newVCPUs, fmt.Errorf("Could not get the vCPUs removed, got %+v", data)
+		}
+		newVCPUs -= VCPUsRemoved
+	}
+	return currentVCPUs, newVCPUs, nil
+}
+
+func (q *quantvisor) getSandboxConsole(id string) (string, error) {
+	return q.consolePath, nil
+}
+
+func (q *quantvisor) getMemorySize() uint32 {
+	return 0
+}
+
+func (q *quantvisor) disconnect() {
+	span, _ := q.trace("disconnect")
+	defer span.Finish()
+
+	q.qmpTeardown()
+}
+
+func (q *quantvisor) capabilities() types.Capabilities {
+	span, _ := q.trace("capabilities")
+	defer span.Finish()
+
+	var caps types.Capabilities
+	caps.SetFsSharingUnsupported()
+	caps.SetBlockDeviceHotplugSupport()
+	caps.SetCpuOfflineSupported()
+
+	return caps
+}
+
+func (q *quantvisor) qmpTeardown() {
+	if q.qmpMonitorCh.qmp != nil {
+		q.qmpMonitorCh.qmp.Shutdown()
+		<-q.qmpMonitorCh.disconn
+		q.qmpMonitorCh.qmp = nil
+		q.qmpMonitorCh.disconn = nil
+	}
+}
+
+func (q *quantvisor) qmpSetup() error {
+	q.qmpTeardown()
+
+	cfg := govmmQemu.QMPConfig{Logger: newQMPLogger()}
+
+	// Auto-closed by QMPStart().
+	disconnectCh := make(chan struct{})
+
+	qmp, _, err := govmmQemu.QMPStart(q.qmpMonitorCh.ctx, q.qmpMonitorCh.path, cfg, disconnectCh)
+	if err != nil {
+		q.Logger().WithError(err).Error("Failed to connect to QuantVisor instance")
+		return err
+	}
+
+	q.qmpMonitorCh.qmp = qmp
+	q.qmpMonitorCh.disconn = disconnectCh
+
+	return nil
+}
+
+func (q *quantvisor) getThreadIDs() (vcpuThreadIDs, error) {
+	span, _ := q.trace("getThreadIDs")
+	defer span.Finish()
+
+	tid := vcpuThreadIDs{}
+	if err := q.qmpSetup(); err != nil {
+		return tid, err
+	}
+
+	cpuInfos, err := q.qmpMonitorCh.qmp.ExecQueryCpus(q.qmpMonitorCh.ctx)
+	if err != nil {
+		q.Logger().WithError(err).Error("Failed to query cpu infos")
+		return tid, err
+	}
+
+	tid.vcpus = make(map[int]int, len(cpuInfos))
+	for _, i := range cpuInfos {
+		if i.ThreadID > 0 {
+			tid.vcpus[i.CPU] = i.ThreadID
+		}
+	}
+	return tid, nil
+}
+
+func (q *quantvisor) cleanup() error {
+	span, _ := q.trace("cleanup")
+	defer span.Finish()
+
+	q.qmpTeardown()
+
+	return nil
+}
+
+func (q *quantvisor) pid() int {
+	data, err := ioutil.ReadFile(q.pidFilePath)
+	if err != nil {
+		q.Logger().WithError(err).Error("Could not read qemu pid file")
+		return 0
+	}
+
+	pid, err := strconv.Atoi(strings.Trim(string(data), "\n\t "))
+	if err != nil {
+		q.Logger().WithError(err).Error("Could not convert pid string to int")
+		return 0
+	}
+
+	return pid
+}
+
+func (q *quantvisor) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, store *store.VCStore, j []byte) error {
+	return nil
+}
+
+func (q *quantvisor) toGrpc() ([]byte, error) {
+	return nil, nil
+}
diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go
index 465e8ea..e6e466d 100644
--- a/virtcontainers/sandbox.go
+++ b/virtcontainers/sandbox.go
@@ -2247,6 +2247,20 @@ func (s *Sandbox) updateResources() error {
 	}
 	s.Logger().Debugf("Sandbox CPUs: %d", newCPUs)
 
+	caps := s.hypervisor.capabilities()
+	if caps.IsCpuOfflineSupprorted() {
+		// The CPUs were decreased, ask agent to offline them
+		if oldCPUs > newCPUs {
+			vcpusDeled := oldCPUs - newCPUs
+			if err := s.agent.offlineCPU(vcpusDeled, false); err != nil {
+				return err
+			}
+		}
+
+		// Unsupported memory update, return directly
+		return nil
+	}
+
 	// Update Memory
 	s.Logger().WithField("memory-sandbox-size-byte", sandboxMemoryByte).Debugf("Request to hypervisor to update memory")
 
diff --git a/virtcontainers/types/capabilities.go b/virtcontainers/types/capabilities.go
index fbd86a6..4470861 100644
--- a/virtcontainers/types/capabilities.go
+++ b/virtcontainers/types/capabilities.go
@@ -10,6 +10,7 @@ const (
 	blockDeviceHotplugSupport
 	multiQueueSupport
 	fsSharingUnsupported
+	cpuOfflineSupported
 )
 
 // Capabilities describe a virtcontainers hypervisor capabilities
@@ -57,3 +58,13 @@ func (caps *Capabilities) IsFsSharingSupported() bool {
 func (caps *Capabilities) SetFsSharingUnsupported() {
 	caps.flags |= fsSharingUnsupported
 }
+
+// IsCpuOfflineSupported tells if an hypervisor supports offline cpu by agent.
+func (caps *Capabilities) IsCpuOfflineSupprorted() bool {
+	return caps.flags&cpuOfflineSupported != 0
+}
+
+// SetCpuOfflineSupported sets the cpu offline after hot-unplug capability to true.
+func (caps *Capabilities) SetCpuOfflineSupported() {
+	caps.flags |= cpuOfflineSupported
+}
diff --git a/virtcontainers/vm.go b/virtcontainers/vm.go
index 08100a7..5b8bb70 100644
--- a/virtcontainers/vm.go
+++ b/virtcontainers/vm.go
@@ -380,6 +380,17 @@ func (v *VM) OnlineCPUMemory() error {
 	return err
 }
 
+// OfflineCPU puts the hotplugged CPU offline.
+func (v *VM) OfflineCPU() error {
+	v.logger().Infof("offline CPU %d", v.cpuDelta)
+	err := v.agent.offlineCPU(v.cpuDelta, false)
+	if err == nil {
+		v.cpuDelta = 0
+	}
+
+	return err
+}
+
 // ReseedRNG adds random entropy to guest random number generator
 // and reseeds it.
 func (v *VM) ReseedRNG() error {
-- 
2.9.3

