diff --git a/connection/connection.go b/connection/connection.go index 984b7ba4..65731327 100644 --- a/connection/connection.go +++ b/connection/connection.go @@ -50,7 +50,7 @@ func (c *Connection) Serve(ctx context.Context) error { } // Connect is used to establish connections with cloudflare's edge network -func (c *Connection) Connect(ctx context.Context, parameters *tunnelpogs.ConnectParameters, logger *logrus.Entry) (*pogs.ConnectResult, error) { +func (c *Connection) Connect(ctx context.Context, parameters *tunnelpogs.ConnectParameters, logger *logrus.Entry) (pogs.ConnectResult, error) { openStreamCtx, cancel := context.WithTimeout(ctx, openStreamTimeout) defer cancel() diff --git a/connection/manager.go b/connection/manager.go index b998c0e0..b59d6ee8 100644 --- a/connection/manager.go +++ b/connection/manager.go @@ -17,8 +17,9 @@ import ( ) const ( - quickStartLink = "https://developers.cloudflare.com/argo-tunnel/quickstart/" - faqLink = "https://developers.cloudflare.com/argo-tunnel/faq/" + quickStartLink = "https://developers.cloudflare.com/argo-tunnel/quickstart/" + faqLink = "https://developers.cloudflare.com/argo-tunnel/faq/" + defaultRetryAfter = time.Second * 5 ) // EdgeManager manages connections with the edge @@ -87,8 +88,12 @@ func (em *EdgeManager) Run(ctx context.Context) error { // Create/delete connection one at a time, so we don't need to adjust for connections that are being created/deleted // in shouldCreateConnection or shouldReduceConnection calculation if em.state.shouldCreateConnection(em.serviceDiscoverer.AvailableAddrs()) { - if err := em.newConnection(ctx); err != nil { - em.logger.WithError(err).Error("cannot create new connection") + if connErr := em.newConnection(ctx); connErr != nil { + if !connErr.ShouldRetry { + em.logger.WithError(connErr).Error(em.noRetryMessage()) + return connErr + } + em.logger.WithError(connErr).Error("cannot create new connection") } } else if em.state.shouldReduceConnection() { if err := em.closeConnection(ctx); err != nil { @@ -103,11 +108,11 @@ func (em *EdgeManager) UpdateConfigurable(newConfigurable *EdgeManagerConfigurab em.state.updateConfigurable(newConfigurable) } -func (em *EdgeManager) newConnection(ctx context.Context) error { +func (em *EdgeManager) newConnection(ctx context.Context) *pogs.ConnectError { edgeIP := em.serviceDiscoverer.Addr() edgeConn, err := em.dialEdge(ctx, edgeIP) if err != nil { - return errors.Wrap(err, "dial edge error") + return retryConnection(fmt.Sprintf("dial edge error: %v", err)) } configurable := em.state.getConfigurable() // Establish a muxed connection with the edge @@ -121,12 +126,12 @@ func (em *EdgeManager) newConnection(ctx context.Context) error { Logger: em.logger.WithField("subsystem", "muxer"), }) if err != nil { - return errors.Wrap(err, "couldn't perform handshake with edge") + retryConnection(fmt.Sprintf("couldn't perform handshake with edge: %v", err)) } h2muxConn, err := newConnection(muxer, edgeIP) if err != nil { - return errors.Wrap(err, "couldn't create h2mux connection") + return retryConnection(fmt.Sprintf("couldn't create h2mux connection: %v", err)) } go em.serveConn(ctx, h2muxConn) @@ -141,18 +146,15 @@ func (em *EdgeManager) newConnection(ctx context.Context) error { }, em.logger) if err != nil { h2muxConn.Shutdown() - return errors.Wrap(err, "couldn't connect to edge") + return retryConnection(fmt.Sprintf("couldn't connect to edge: %v", err)) } - if connErr := connResult.Err; connErr != nil { - if !connErr.ShouldRetry { - return errors.Wrap(connErr, em.noRetryMessage()) - } - return errors.Wrapf(connErr, "edge responded with RetryAfter=%v", connErr.RetryAfter) + if connErr := connResult.ConnectError(); connErr != nil { + return connErr } em.state.newConnection(h2muxConn) - em.logger.Infof("connected to %s", connResult.ServerInfo.LocationName) + em.logger.Infof("connected to %s", connResult.ConnectedTo()) return nil } @@ -282,3 +284,11 @@ func (ems *edgeManagerState) getUserCredential() []byte { defer ems.RUnlock() return ems.userCredential } + +func retryConnection(cause string) *pogs.ConnectError { + return &pogs.ConnectError{ + Cause: cause, + RetryAfter: defaultRetryAfter, + ShouldRetry: true, + } +} diff --git a/tunnelrpc/pogs/tunnelrpc.go b/tunnelrpc/pogs/tunnelrpc.go index 079c7945..981d5299 100644 --- a/tunnelrpc/pogs/tunnelrpc.go +++ b/tunnelrpc/pogs/tunnelrpc.go @@ -2,10 +2,12 @@ package pogs import ( "context" + "fmt" "time" "github.com/cloudflare/cloudflared/tunnelrpc" "github.com/google/uuid" + "github.com/pkg/errors" log "github.com/sirupsen/logrus" capnp "zombiezen.com/go/capnproto2" @@ -73,28 +75,129 @@ func UnmarshalRegistrationOptions(s tunnelrpc.RegistrationOptions) (*Registratio return p, err } -type ConnectResult struct { - Err *ConnectError - ServerInfo ServerInfo - ClientConfig ClientConfig +// ConnectResult models the result of Connect RPC, implemented by ConnectError and ConnectSuccess. +type ConnectResult interface { + ConnectError() *ConnectError + ConnectedTo() string + ClientConfig() *ClientConfig + Marshal(s tunnelrpc.ConnectResult) error } -func MarshalConnectResult(s tunnelrpc.ConnectResult, p *ConnectResult) error { - return pogs.Insert(tunnelrpc.ConnectResult_TypeID, s.Struct, p) +func MarshalConnectResult(s tunnelrpc.ConnectResult, p ConnectResult) error { + return p.Marshal(s) } -func UnmarshalConnectResult(s tunnelrpc.ConnectResult) (*ConnectResult, error) { - p := new(ConnectResult) - err := pogs.Extract(p, tunnelrpc.ConnectResult_TypeID, s.Struct) - return p, err +func UnmarshalConnectResult(s tunnelrpc.ConnectResult) (ConnectResult, error) { + switch s.Result().Which() { + case tunnelrpc.ConnectResult_result_Which_err: + capnpConnectError, err := s.Result().Err() + if err != nil { + return nil, err + } + return UnmarshalConnectError(capnpConnectError) + case tunnelrpc.ConnectResult_result_Which_success: + capnpConnectSuccess, err := s.Result().Success() + if err != nil { + return nil, err + } + return UnmarshalConnectSuccess(capnpConnectSuccess) + default: + return nil, fmt.Errorf("Unmarshal %v not implemented yet", s.Result().Which().String()) + } } +// ConnectSuccess is the concrete returned type when Connect RPC succeed +type ConnectSuccess struct { + ServerLocationName string + Config *ClientConfig +} + +func (*ConnectSuccess) ConnectError() *ConnectError { + return nil +} + +func (cs *ConnectSuccess) ConnectedTo() string { + return cs.ServerLocationName +} + +func (cs *ConnectSuccess) ClientConfig() *ClientConfig { + return cs.Config +} + +func (cs *ConnectSuccess) Marshal(s tunnelrpc.ConnectResult) error { + capnpConnectSuccess, err := s.Result().NewSuccess() + if err != nil { + return err + } + + err = capnpConnectSuccess.SetServerLocationName(cs.ServerLocationName) + if err != nil { + return errors.Wrap(err, "failed to set ConnectSuccess.ServerLocationName") + } + + if cs.Config != nil { + capnpClientConfig, err := capnpConnectSuccess.NewClientConfig() + if err != nil { + return errors.Wrap(err, "failed to initialize ConnectSuccess.ClientConfig") + } + if err := MarshalClientConfig(capnpClientConfig, cs.Config); err != nil { + return errors.Wrap(err, "failed to marshal ClientConfig") + } + } + + return nil +} + +func UnmarshalConnectSuccess(s tunnelrpc.ConnectSuccess) (*ConnectSuccess, error) { + p := new(ConnectSuccess) + + serverLocationName, err := s.ServerLocationName() + if err != nil { + return nil, errors.Wrap(err, "failed to get tunnelrpc.ConnectSuccess.ServerLocationName") + } + p.ServerLocationName = serverLocationName + + if s.HasClientConfig() { + capnpClientConfig, err := s.ClientConfig() + if err != nil { + return nil, errors.Wrap(err, "failed to get tunnelrpc.ConnectSuccess.ClientConfig") + } + p.Config, err = UnmarshalClientConfig(capnpClientConfig) + if err != nil { + return nil, errors.Wrap(err, "failed to get unmarshal ClientConfig") + } + } + + return p, nil +} + +// ConnectError is the concrete returned type when Connect RPC encounters some error type ConnectError struct { Cause string RetryAfter time.Duration ShouldRetry bool } +func (ce *ConnectError) ConnectError() *ConnectError { + return ce +} + +func (*ConnectError) ConnectedTo() string { + return "" +} + +func (*ConnectError) ClientConfig() *ClientConfig { + return nil +} + +func (ce *ConnectError) Marshal(s tunnelrpc.ConnectResult) error { + capnpConnectError, err := s.Result().NewErr() + if err != nil { + return err + } + return MarshalConnectError(capnpConnectError, ce) +} + func MarshalConnectError(s tunnelrpc.ConnectError, p *ConnectError) error { return pogs.Insert(tunnelrpc.ConnectError_TypeID, s.Struct, p) } @@ -223,7 +326,7 @@ type TunnelServer interface { RegisterTunnel(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) (*TunnelRegistration, error) GetServerInfo(ctx context.Context) (*ServerInfo, error) UnregisterTunnel(ctx context.Context, gracePeriodNanoSec int64) error - Connect(ctx context.Context, paramaters *ConnectParameters) (*ConnectResult, error) + Connect(ctx context.Context, parameters *ConnectParameters) (ConnectResult, error) } func TunnelServer_ServerToClient(s TunnelServer) tunnelrpc.TunnelServer { @@ -284,11 +387,11 @@ func (i TunnelServer_PogsImpl) UnregisterTunnel(p tunnelrpc.TunnelServer_unregis } func (i TunnelServer_PogsImpl) Connect(p tunnelrpc.TunnelServer_connect) error { - paramaters, err := p.Params.Parameters() + parameters, err := p.Params.Parameters() if err != nil { return err } - pogsParameters, err := UnmarshalConnectParameters(paramaters) + pogsParameters, err := UnmarshalConnectParameters(parameters) if err != nil { return err } @@ -301,7 +404,7 @@ func (i TunnelServer_PogsImpl) Connect(p tunnelrpc.TunnelServer_connect) error { if err != nil { return err } - return MarshalConnectResult(result, connectResult) + return connectResult.Marshal(result) } type TunnelServer_PogsClient struct { @@ -365,7 +468,7 @@ func (c TunnelServer_PogsClient) UnregisterTunnel(ctx context.Context, gracePeri func (c TunnelServer_PogsClient) Connect(ctx context.Context, parameters *ConnectParameters, -) (*ConnectResult, error) { +) (ConnectResult, error) { client := tunnelrpc.TunnelServer{Client: c.Client} promise := client.Connect(ctx, func(p tunnelrpc.TunnelServer_connect_Params) error { connectParameters, err := p.NewParameters() diff --git a/tunnelrpc/pogs/tunnelrpc_test.go b/tunnelrpc/pogs/tunnelrpc_test.go index c4aad592..3a5ff7a4 100644 --- a/tunnelrpc/pogs/tunnelrpc_test.go +++ b/tunnelrpc/pogs/tunnelrpc_test.go @@ -11,21 +11,21 @@ import ( capnp "zombiezen.com/go/capnproto2" ) -func sampleTestConnectResult() *ConnectResult { - return &ConnectResult{ - Err: &ConnectError{ +func TestConnectResult(t *testing.T) { + testCases := []ConnectResult{ + &ConnectError{ Cause: "it broke", ShouldRetry: false, RetryAfter: 2 * time.Second, }, - ServerInfo: ServerInfo{LocationName: "computer"}, - ClientConfig: *sampleClientConfig(), - } -} - -func TestConnectResult(t *testing.T) { - testCases := []*ConnectResult{ - sampleTestConnectResult(), + &ConnectSuccess{ + ServerLocationName: "SFO", + Config: sampleClientConfig(), + }, + &ConnectSuccess{ + ServerLocationName: "", + Config: nil, + }, } for i, testCase := range testCases { _, seg, err := capnp.NewMessage(capnp.SingleSegment(nil)) diff --git a/tunnelrpc/tunnelrpc.capnp b/tunnelrpc/tunnelrpc.capnp index fb7b9121..5664dcc3 100644 --- a/tunnelrpc/tunnelrpc.capnp +++ b/tunnelrpc/tunnelrpc.capnp @@ -62,11 +62,10 @@ struct CapnpConnectParameters { } struct ConnectResult { - err @0 :ConnectError; - # Information about the server this connection is established with - serverInfo @1 :ServerInfo; - # How this cloudflared instance should be configured - clientConfig @2 :ClientConfig; + result :union { + err @0 :ConnectError; + success @1 :ConnectSuccess; + } } struct ConnectError { @@ -76,6 +75,13 @@ struct ConnectError { shouldRetry @2 :Bool; } +struct ConnectSuccess { + # Information about the server this connection is established with + serverLocationName @0 :Text; + # How this cloudflared instance should be configured. This can be null if there isn't an intent for this origin yet + clientConfig @1 :ClientConfig; +} + struct ClientConfig { # Version of this configuration. This value is opaque, but is guaranteed # to monotonically increase in value. Any configuration supplied to diff --git a/tunnelrpc/tunnelrpc.capnp.go b/tunnelrpc/tunnelrpc.capnp.go index 649dddce..34e07f10 100644 --- a/tunnelrpc/tunnelrpc.capnp.go +++ b/tunnelrpc/tunnelrpc.capnp.go @@ -653,17 +653,36 @@ func (p CapnpConnectParameters_Promise) Struct() (CapnpConnectParameters, error) } type ConnectResult struct{ capnp.Struct } +type ConnectResult_result ConnectResult +type ConnectResult_result_Which uint16 + +const ( + ConnectResult_result_Which_err ConnectResult_result_Which = 0 + ConnectResult_result_Which_success ConnectResult_result_Which = 1 +) + +func (w ConnectResult_result_Which) String() string { + const s = "errsuccess" + switch w { + case ConnectResult_result_Which_err: + return s[0:3] + case ConnectResult_result_Which_success: + return s[3:10] + + } + return "ConnectResult_result_Which(" + strconv.FormatUint(uint64(w), 10) + ")" +} // ConnectResult_TypeID is the unique identifier for the type ConnectResult. const ConnectResult_TypeID = 0xff8d9848747c956a func NewConnectResult(s *capnp.Segment) (ConnectResult, error) { - st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}) + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) return ConnectResult{st}, err } func NewRootConnectResult(s *capnp.Segment) (ConnectResult, error) { - st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}) + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}) return ConnectResult{st}, err } @@ -677,23 +696,36 @@ func (s ConnectResult) String() string { return str } -func (s ConnectResult) Err() (ConnectError, error) { +func (s ConnectResult) Result() ConnectResult_result { return ConnectResult_result(s) } + +func (s ConnectResult_result) Which() ConnectResult_result_Which { + return ConnectResult_result_Which(s.Struct.Uint16(0)) +} +func (s ConnectResult_result) Err() (ConnectError, error) { + if s.Struct.Uint16(0) != 0 { + panic("Which() != err") + } p, err := s.Struct.Ptr(0) return ConnectError{Struct: p.Struct()}, err } -func (s ConnectResult) HasErr() bool { +func (s ConnectResult_result) HasErr() bool { + if s.Struct.Uint16(0) != 0 { + return false + } p, err := s.Struct.Ptr(0) return p.IsValid() || err != nil } -func (s ConnectResult) SetErr(v ConnectError) error { +func (s ConnectResult_result) SetErr(v ConnectError) error { + s.Struct.SetUint16(0, 0) return s.Struct.SetPtr(0, v.Struct.ToPtr()) } // NewErr sets the err field to a newly // allocated ConnectError struct, preferring placement in s's segment. -func (s ConnectResult) NewErr() (ConnectError, error) { +func (s ConnectResult_result) NewErr() (ConnectError, error) { + s.Struct.SetUint16(0, 0) ss, err := NewConnectError(s.Struct.Segment()) if err != nil { return ConnectError{}, err @@ -702,53 +734,36 @@ func (s ConnectResult) NewErr() (ConnectError, error) { return ss, err } -func (s ConnectResult) ServerInfo() (ServerInfo, error) { - p, err := s.Struct.Ptr(1) - return ServerInfo{Struct: p.Struct()}, err +func (s ConnectResult_result) Success() (ConnectSuccess, error) { + if s.Struct.Uint16(0) != 1 { + panic("Which() != success") + } + p, err := s.Struct.Ptr(0) + return ConnectSuccess{Struct: p.Struct()}, err } -func (s ConnectResult) HasServerInfo() bool { - p, err := s.Struct.Ptr(1) +func (s ConnectResult_result) HasSuccess() bool { + if s.Struct.Uint16(0) != 1 { + return false + } + p, err := s.Struct.Ptr(0) return p.IsValid() || err != nil } -func (s ConnectResult) SetServerInfo(v ServerInfo) error { - return s.Struct.SetPtr(1, v.Struct.ToPtr()) +func (s ConnectResult_result) SetSuccess(v ConnectSuccess) error { + s.Struct.SetUint16(0, 1) + return s.Struct.SetPtr(0, v.Struct.ToPtr()) } -// NewServerInfo sets the serverInfo field to a newly -// allocated ServerInfo struct, preferring placement in s's segment. -func (s ConnectResult) NewServerInfo() (ServerInfo, error) { - ss, err := NewServerInfo(s.Struct.Segment()) +// NewSuccess sets the success field to a newly +// allocated ConnectSuccess struct, preferring placement in s's segment. +func (s ConnectResult_result) NewSuccess() (ConnectSuccess, error) { + s.Struct.SetUint16(0, 1) + ss, err := NewConnectSuccess(s.Struct.Segment()) if err != nil { - return ServerInfo{}, err + return ConnectSuccess{}, err } - err = s.Struct.SetPtr(1, ss.Struct.ToPtr()) - return ss, err -} - -func (s ConnectResult) ClientConfig() (ClientConfig, error) { - p, err := s.Struct.Ptr(2) - return ClientConfig{Struct: p.Struct()}, err -} - -func (s ConnectResult) HasClientConfig() bool { - p, err := s.Struct.Ptr(2) - return p.IsValid() || err != nil -} - -func (s ConnectResult) SetClientConfig(v ClientConfig) error { - return s.Struct.SetPtr(2, v.Struct.ToPtr()) -} - -// NewClientConfig sets the clientConfig field to a newly -// allocated ClientConfig struct, preferring placement in s's segment. -func (s ConnectResult) NewClientConfig() (ClientConfig, error) { - ss, err := NewClientConfig(s.Struct.Segment()) - if err != nil { - return ClientConfig{}, err - } - err = s.Struct.SetPtr(2, ss.Struct.ToPtr()) + err = s.Struct.SetPtr(0, ss.Struct.ToPtr()) return ss, err } @@ -757,7 +772,7 @@ type ConnectResult_List struct{ capnp.List } // NewConnectResult creates a new list of ConnectResult. func NewConnectResult_List(s *capnp.Segment, sz int32) (ConnectResult_List, error) { - l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}, sz) + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz) return ConnectResult_List{l}, err } @@ -778,16 +793,24 @@ func (p ConnectResult_Promise) Struct() (ConnectResult, error) { return ConnectResult{s}, err } -func (p ConnectResult_Promise) Err() ConnectError_Promise { +func (p ConnectResult_Promise) Result() ConnectResult_result_Promise { + return ConnectResult_result_Promise{p.Pipeline} +} + +// ConnectResult_result_Promise is a wrapper for a ConnectResult_result promised by a client call. +type ConnectResult_result_Promise struct{ *capnp.Pipeline } + +func (p ConnectResult_result_Promise) Struct() (ConnectResult_result, error) { + s, err := p.Pipeline.Struct() + return ConnectResult_result{s}, err +} + +func (p ConnectResult_result_Promise) Err() ConnectError_Promise { return ConnectError_Promise{Pipeline: p.Pipeline.GetPipeline(0)} } -func (p ConnectResult_Promise) ServerInfo() ServerInfo_Promise { - return ServerInfo_Promise{Pipeline: p.Pipeline.GetPipeline(1)} -} - -func (p ConnectResult_Promise) ClientConfig() ClientConfig_Promise { - return ClientConfig_Promise{Pipeline: p.Pipeline.GetPipeline(2)} +func (p ConnectResult_result_Promise) Success() ConnectSuccess_Promise { + return ConnectSuccess_Promise{Pipeline: p.Pipeline.GetPipeline(0)} } type ConnectError struct{ capnp.Struct } @@ -876,6 +899,105 @@ func (p ConnectError_Promise) Struct() (ConnectError, error) { return ConnectError{s}, err } +type ConnectSuccess struct{ capnp.Struct } + +// ConnectSuccess_TypeID is the unique identifier for the type ConnectSuccess. +const ConnectSuccess_TypeID = 0x8407e070e0d52605 + +func NewConnectSuccess(s *capnp.Segment) (ConnectSuccess, error) { + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) + return ConnectSuccess{st}, err +} + +func NewRootConnectSuccess(s *capnp.Segment) (ConnectSuccess, error) { + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) + return ConnectSuccess{st}, err +} + +func ReadRootConnectSuccess(msg *capnp.Message) (ConnectSuccess, error) { + root, err := msg.RootPtr() + return ConnectSuccess{root.Struct()}, err +} + +func (s ConnectSuccess) String() string { + str, _ := text.Marshal(0x8407e070e0d52605, s.Struct) + return str +} + +func (s ConnectSuccess) ServerLocationName() (string, error) { + p, err := s.Struct.Ptr(0) + return p.Text(), err +} + +func (s ConnectSuccess) HasServerLocationName() bool { + p, err := s.Struct.Ptr(0) + return p.IsValid() || err != nil +} + +func (s ConnectSuccess) ServerLocationNameBytes() ([]byte, error) { + p, err := s.Struct.Ptr(0) + return p.TextBytes(), err +} + +func (s ConnectSuccess) SetServerLocationName(v string) error { + return s.Struct.SetText(0, v) +} + +func (s ConnectSuccess) ClientConfig() (ClientConfig, error) { + p, err := s.Struct.Ptr(1) + return ClientConfig{Struct: p.Struct()}, err +} + +func (s ConnectSuccess) HasClientConfig() bool { + p, err := s.Struct.Ptr(1) + return p.IsValid() || err != nil +} + +func (s ConnectSuccess) SetClientConfig(v ClientConfig) error { + return s.Struct.SetPtr(1, v.Struct.ToPtr()) +} + +// NewClientConfig sets the clientConfig field to a newly +// allocated ClientConfig struct, preferring placement in s's segment. +func (s ConnectSuccess) NewClientConfig() (ClientConfig, error) { + ss, err := NewClientConfig(s.Struct.Segment()) + if err != nil { + return ClientConfig{}, err + } + err = s.Struct.SetPtr(1, ss.Struct.ToPtr()) + return ss, err +} + +// ConnectSuccess_List is a list of ConnectSuccess. +type ConnectSuccess_List struct{ capnp.List } + +// NewConnectSuccess creates a new list of ConnectSuccess. +func NewConnectSuccess_List(s *capnp.Segment, sz int32) (ConnectSuccess_List, error) { + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz) + return ConnectSuccess_List{l}, err +} + +func (s ConnectSuccess_List) At(i int) ConnectSuccess { return ConnectSuccess{s.List.Struct(i)} } + +func (s ConnectSuccess_List) Set(i int, v ConnectSuccess) error { return s.List.SetStruct(i, v.Struct) } + +func (s ConnectSuccess_List) String() string { + str, _ := text.MarshalList(0x8407e070e0d52605, s.List) + return str +} + +// ConnectSuccess_Promise is a wrapper for a ConnectSuccess promised by a client call. +type ConnectSuccess_Promise struct{ *capnp.Pipeline } + +func (p ConnectSuccess_Promise) Struct() (ConnectSuccess, error) { + s, err := p.Pipeline.Struct() + return ConnectSuccess{s}, err +} + +func (p ConnectSuccess_Promise) ClientConfig() ClientConfig_Promise { + return ClientConfig_Promise{Pipeline: p.Pipeline.GetPipeline(1)} +} + type ClientConfig struct{ capnp.Struct } // ClientConfig_TypeID is the unique identifier for the type ClientConfig. @@ -3559,225 +3681,232 @@ func (p ClientService_useConfiguration_Results_Promise) Result() UseConfiguratio return UseConfigurationResult_Promise{Pipeline: p.Pipeline.GetPipeline(0)} } -const schema_db8274f9144abc7e = "x\xda\xacY\x7f\x8c\x1c\xf5u\x7fo\xbe\xbb;>s" + - "\xe7\xdd\xf1\x1c\xe0;\x8c\xb6\xb2\x88\x12\x13L!.m" + - "\xb8VY\xdf\x9d\xcf\xb9u\xfcc\xe7\xf6\xce\x801\x92" + - "\xc7\xbb\xdf\xdb\x9b\xf3\xec\xccz~\x98;\xcb\xc4`\xd9" + - "\x05_q\xb0\x09\x960\xc1\x11\xb8q\xc1\xc8\x14L\x8c" + - "Z(I\x93\xaa-\xa1IE\xdaB\x95\xb4\xf9\xa3\x0d" + - "\xa0*\xa8\x115I\x85R\x05\xa6z\xf3\xfb\xf66g" + - "\xbb\xea?\xf6\xe8\xed\xf7\xc7\xfb~\xde{\x9f\xf7\xe3n" + - "y}\xc9:\xe1\xd6\xec_v\x03(\x8fes\xde\x1f" + - "4\xdf<\xfd\xbb'\xbe\x7f\x08\xa4~\xc1\xfb\xf2k\x1b" + - "{\x7f\xe5\x1c\xfcW\x00\\;\x92\xdb\x87\xf2]9\x11" + - "@\x9e\xc8m\x05\xf4\xfe\xe9\x96\xfd\xef\xee\xfc\xc5\xf1\x87" + - "@\xea\xc7deF\x04X\xdb\xcc\xcd\xa1|8'\x02" + - "\xf3N\xdd\xdd\xfbw\xf8\xd4G\xc7A\xfa\x0c\x02d\x91" + - "~VsK\x05@y6W\x02\xf4\xde\xbc\xe9\xb5W" + - "\x8f}\xf3\xc1\xaf\x81\xf2iD\x08\xf6\x9f\xcc\xfd\x0f\x02" + - "\xca\xcf\xfb\x0b.~\xe3\xb3\x99\xe7\xdf\\\xfeu\x7f\x81" + - "w\xe6\x1f\xeex\xe9\xd87\x7f\xeb}\x98\x10D\xcc\x00" + - "\xac};g\xd1\xda\x7f\xcf\xfd\x07\xa0\xf7\xd8\x8f\xbe\xb5" + - "\xa5y\xfc\x89\xd3 }::\xeb\xbb\xa2 @\xc6\xbb" + - "\xed_\xde\xdb\xba\xf9\xa5\xc9g\x82_\x02=^\x16_" + - "\xa2\xad\x7f#\xd25\xdf\xbb\xb7\xf0\xf0\xe0\xef=\xf2\x0c" + - "(\xfd\x98zO6K+\x7f&\xce\xa1\x8cK\xe8\xf3" + - "c\xf1\x0e\x04\xf4\xe6n\xff\xd6\xb6_\xfc\xa1\xfd\x1c(" + - "k0\xe3\xfd\xf5\x91w\xf6\xae>;\xf9\xba\xaf\x15\x03" + - "X\xebv\xfd#\x1d}\xa4\xeb\x05@\xaf\xe7/n\xdc" + - "\xf2\xc8\xbb\x9b\xce\xd3\xd1)P\x03%V/\x1d@\xf9" + - "\xf6\xa5\x84\xebmKi\xf5\x0fo\xda\xf6\xedo\xbf\xd8" + - "8\xdf\xae\x88@\xab\xdf^\xba\x11\xe5\x9f\xf9\xab\xdf\xf3" + - "W_]\xc6\x9f|\xe7\xd6\xcc\x9f\x85\xefb>|W" + - "\xbd\xef\xc3w\x15-\xb8\xfb\xd7/\xff\xd5\xc8\x07o\xbd" + - "\x926\xc0\xe6n\x81\x0c\xa0v\xd3\xc3\xaf\xff\xf9P\x8f" + - "\xf1\xc1\xc1\xef\xcc\xb7cp\xd2\x91\xee\x8d(\x9f\xea\xa6" + - "\xebNv\xbf\x00\xf8\xd1s\x0f\x1e+\xbf\xb3\xfeu\xa5" + - "\x1f3\xed\x0f\xb9\xadg\x1f\xca\xe5\x1e\xfa\x1c\xe9)\x12" + - "F1*m\xcb\xfd\x97\xb8\xcb\xa6Q>\xb2\x8c>\x0f" + - "/\xf3\x97o\xbc\xfb\xab\x8ff\xdf\xfb\xea\xeb\xed0\x89" + - "\xb4\xe6x\xdeB\xf9L\x9e>\x9f\xce?#\x00z\xfd" + - "/\xfe\xfe\x9f\x0e\xd5\x7f\xfc\xfd6\xbd\xe9p\xf9\xe8\xf2" + - "\x0f\xe5\x93\xcb\xe9\xeb\xc4\xf2{\x01\xbd\x07?;\xbbo" + - "\xcb\xa7\xe6\xden\xc7\xd4W\xfc\xe2\xf29\x94\xbbdZ" + - "\x9d\x95i\xb5\xf0\x9e\xdaw\xff?\x7f\xe1')/r" + - "\xe5\x9f\"d\xbc-\xdb\xee\x9e\xee\xba\xef\x9dw\xd2^" + - "\xa4\xc9>\xda\xf7\xc9\x04\xe6\x05\xe9Q\xf9\xb5\xa7\xff\xe4" + - "]\xbaHlG\xf3\x94\xbc\x1d\xe5\xf3t\xd1\xda\xe7e" + - "\xff\x0d\xb17w\xb2\xf5\xd9k\x06P~\xe5\x1a\xd2\xeb" + - "\xe5kH\xaf\xdbv\x0e\xf2\x1d\x9f\xbf\xf3}\x90\xfa\xd9" + - "\xbc\xd8\xfcoZ\x99\xbd\x966\xe1\xb5\"\xca\xe7\xe9\xd3" + - "\xfbJc\xfb\x1b\x17\x87\x9f\xfe\xaf\xf6\xc3\x83\x10\xbbv" + - "\x00\xe5\xb3\xfe\x963\xd7\xfa\xf0\xaf\xbd\xf5\x8f~~\xe2" + - "\x8f\x87/.8\xfd\xe2\x8a!\x94\xb1\x8f\xf4\xf8x\xc5" + - "\x17\xe55}\xfe\xe1_^\xbf\xf5\xf6U\xdf\xfd0\x8d" + - "\xc4\xd5}\x1f\x12\x12\xab\xfb\x08\x89\xc9\xcf\xff\xe7\x17?" + - "\xf5\x95\xbf\xfd\xb0\xcd<\xfe\xc2r\xdf\x8d(\xdf\xe5\x9f" + - "8A\x8b?\xd8\xf0\xf5\xb7\xfa\xf3\xfd\xbf\xec\xa4\xe8l" + - "\xdf4\xcaG\xfb|o\xec\xf3\x15\xbd\xf3\xa7O\xdc[" + - "\xfa\xda/?\xa2w\xb16\xe6y\xa5\x7f;\xca\x7f\xdf" + - "O'\xbf\xd1O\xee\xbf\xe9\xdc\x8f\xbf0u\xe2{\xbf" + - "j\x07\xc17\x88{\xddA\x94\x8f\\G\xab\x0f_G" + - "\xfc\xb1\xff\x83\x93\xa3\x8f\xec8\xf7I\xfaU\xcd\x95\xaf" + - "\xfa\xf6]I\xaf\x9a>\xb1\xdf\x19}\xfc\xa8\xd7)X" + - "N\xad\x1cB\xf9\xf9\x95t\xda\xd9\x95/\xc0\x1a\xcfq" + - "\x0d\x83\xebV+S\xfb\xed\xe8\xb3vsMm\x19\xad" + - "\x81\x91\x19\xcdv4\xa31\xee\xcbK\x15S\xd7j\xb3" + - "\x15D\xa5\x1b\x05\x00\xe9\xfa\x01\x00D\xe9\xea\xed\x00(" + - "H\xd2\x10@Ik\x18\xa6\xc5\xbd\xbaf\xd7L\xc3\xe0" + - "\xc0j\xce\x81]\xaa\xae\x1a5\x1e_\x94]x\xd1(" + - "\xd7u\xf3\x0e\xd3\xd2\xeb[-\xad\xa1\x19\xc3\xa61\xa9" + - "5\x00*\x88\xf16q\xe1\xb6a]\xe3\x86S\xe5\xd6" + - "^\xad\xc6ovm\x1e\xecs-\xd5\xd1L\xe3\x861" + - "n\xbb\xbac\x03(\x19\x96\x01\xc8 \x80\xd43\x00\xa0" + - ",a\xa8\xf4\x0aX\xb2\xfc\x05XH\"\x0f\x10\x0b\x90" + - "\xdc\x99[xg\x80\x05\xdd\xc9\xad\x9b]\xc3\xe2\x0d\xcd" + - "v\xb8\x15\x88o(UTKm\xda\xe9\x0b\x9f\x00P" + - "\x0a\x0c\x95\x95\x02z\x0dK\xad\xf1\x0a\xb7P3\xeb[" + - "T\xc3\xac2^\xc3,\x08\x98M]\xda\xc1\x10\x1bT" + - "M\xe7\xf5\xe0u7\xd7\x8a\xfe\xffJ\x81e\xba=\xcf" + - "\xbfD\xdd\x0e\xa0\xecd\xa8\xe8\x02\xf6\xe0'^/%" + - ")I\xdb\x07\xa0L1T\x1c\x01{\x84\x8f\xbd^\xdf" + - "j{V\x01(:CeF\xc0\x1e\xf6k\xaf\x97R" + - "\x81\xe4N\x03(\x0eC\xe5~\x01=\xdbm\x11\xa66" + - "0\xd3\xc2B\xe2\xca!:\xbc\xde \xa4\x0d(\xf1\x1a" + - "\x01\x8d\x85\x88q\x83\x05b\xdd\x9c\xc2B\x92\"\xc2m" + - "\x16\xdf\xcb-\x9bW o\x993\xb3XH\x98\xb7\x0d" + - "\xf5\x9e+E=2t\xbck\xf1\xfd\xbek\xd6\x9c\x1b" + - "*\xc5\x05\xc6\"\x1c\xbb\x19*+\x04\xf4Z\xf4+w" + - "80\xcb\xc6B\x92z\xdb\xb4\xed\xe0\xce\xc3\xf4\xefp" + - "pK%<\xc5\xb2}wVV\xc4\x97\x9d\xa4\xcb\x1e" + - "g\xa8|C@\x091\xb0\xd9\xd3\x16\x80\xf2\x14C\xe5" + - "\x9c\x80(\x04\x16;{\x1a@9\xc7P\xf9s\x01%" + - "&\x04\x06{\xf9F\x00\xe5E\x86\xca\x0f\x04\x942\xac" + - "\x97\xca\x0c\xe9\x0dr\xb6\x1f0T~$\xa0\x94\xcd\xf4" + - "b\x16@z{\x17\x80\xf2\x16C\xe5\xdf\x04\xf4\xcc " + - "\xbe\xe8Q\x0e\xf6\x80\x80=\x80^M7\xdd\xfa\xa4\xae" + - "B\xd1\xe2\xf5\xf2\xfaXn\xb8\xcd\x8a\xc5\xf7jh\xba" + - "\xf6\xa0\xe3\xf0\xa6\xd8rl\xcc\x81\x809\xc0\xbc\xa36" + - "l\\\x06Xa\x88\x85$\xd1\x01\x920>\x13-^" + - "\xdf\xc6-[c\xa6\x81\xdd `7\xa0\xa7\x19\x0e7" + - "\x9cM*\x88\xbb\xb8\x1eK\x17\x89\xba\xb1\xd0w\xc8s" + - "\xc200\x13\xa6\xc0\x86\xd2\xcd2+=/\x04q\x84" + - "\xb0Y\xc7P\xd9$\xe0\xf5\xf8\x09\x89\x09\xc7\xf2\x18\x80" + - "2\xcaP\x19\x17\xf0z\xe1c\x12\x13\x92\x0a\xd9\xa1\xc2" + - "P\xd9!`~\xcaqZXH2dh\xec{\xf9" + - ".\xdb\xac\xed\xe6\x80D\x171]\x87\xbfN\x85\xf4\x05" + - "L\xafc!\xa99\xdb<\x85u\xf0\x14\xdfIJ\xce" + - "\x88e\x99\x96\xcf\xac\xb1{\x8c|.yD\xe4\x1d\xe5" + - "\xed\xc9\x0b$a]\xf0,eW\xa2\x7f\xb1\xa6\xba6" + - "\x8f\x11\xb5\xb8c\xcd\x0eN:\xc0\xb8\x15\xf3\x8c=e" + - "\xbaz}\x8c\x83\xe8X\xb3\x88 .\xce>\xeb\xcd" + - "\xd1\x14\xf0\x81\x1b\xa7\xf4$\x9d\xd63T*\x89\x9e\x9b" + - "I\xb6\x89\xa1r'\xe9\x19\xc2?A\xf0\x8f3TZ" + - "\x02z:\xc5\xaf1j\x02\xb3\x9dX\xdd@X1}" + - "\xe7\x14A@\x11\xd0s[\xb6cq\xb5\x09\x18{\x1b" + - "\xad_v\x054\xddF\x17\x155\xef\xc7}\xe77\xc4" + - "\xa1\xb8yc\xfa\x11a,N\x0c%`w\x0e\xa6)" + - "\xd3v\x0c\xb5\xc9\x01 z\xd8\x01\xb3El\x1a\xe2\xa4\xd6\xc0BRo\xb5" + - ")\xd0\xc1\xee\x83\xae3\xc5\x0dG\xab\xf9\x17.\xb0\xfb" + - "\xaa\xc4?c\xcc\xca\x9fK\x01\x19a\xb6yW\x02\xa4" + - "\xb8\x9b\xcfF\xb0\x14yS\xd5\x92\xf0\x0f\xd1\x1c\x04\xf1" + - "K\xc9\x9aE\xcb\x930\x0f\x05Y\xa8\x14\xc0CJ\xf6" + - "\xc6J\xde7\x07\xa0\xdc\xcfPy8\xa5\xe4\x91G\x01" + - "\x94\x87\x19*\x8f\xa7\x94\x1a\xec\x12U\xc7\xc6.\x10\xb0\x8b" + - "B\xc0\xe6\xd6\xb0\xc5\xebH\xd6P\xf5\x8a\xca\x9c\xa9\xcb" + - "\x01h>k\xe6;\xc0C\x15\xc2~\x86\xcaC\x14\xbb" + - "\x98j\x18\xa5\xc3\xd3 \xf8\xa1Ko\xde3\x94\xd4\x0c" + - "~\x06\xa2\xbc\xe2\x12\x8c3\x0c\x95Ca\x06\xca\x01H" + - "\x0f\x10:\x87\x18*\xc7\x84H\xb5Q\x13JAH\xb4" + - "\x9b\xda\x04_\xa7\x03DS\x1aO\xde\x1b&h\x0dM" + - "c\xdc\x07\x0a\x13\xa4jf\xb3eq\xdbF\xcd4\x14" + - "W\xd55\xe6\xcc\xc6\x1b\x17\xc5\x828 \x88\x9d\xad\xad" + - "\xa2o,\x02\xe3\x96\x08\x0cy\x107\x02T\xd7!\xc3" + - "\xea&L\xdcE.\xe3\x10@u=\xc9+\x98x\x8c" + - "\xbc\x19\xfb\x01\xaa\xa3$\x1fG\x011\xf0\x19Y\xc1\xe7" + - "\x00\xaa\xe3$\xde\x89In\x96\xef\xf1\x8f\xdfA\xf2)" + - "L\xd2\xb3\xcc\xf1F\x80\xeaN\x92\xef'yN\xf0\x91" + - "\x94gq\x1a\xa0:C\xf2C$\x17\xb3\xbdT\xe9\xcb" + - "\x0f\xa0\x05P\xbd\x9f\xe4\x0f\x93|\xc9\x8a^\\\x02 " + - "\x1f\xf1\xe5\x0f\x91\xfc1\x92w\xf5\xf5b\x17\x80|\x1c" + - "\x0f\x02T\x8f\x91\xfcI\x92/\xc5^\\J\xad2>" + - "\x01P}\x92\xe4\xcf\x92\xfc\xaa\\/^\x05 \x9f\xf1" + - "\xf5y\x8a\xe4\xe70&\x92r=\xcdg\xe4VZ\x92" + - "\xcf\x99i\xc7\xa6\xe5a\xcf\x80\x01\xd9V\xcc<5\x0d" + - "\x98Of6\x80\x98\x07\xf4Z\xa6\xa9o\x99\xcf\x93\x97" + - "*)B\xb7\x80\xbci\x94\xebq\x9c\x05\xce\xb4\xc9\x84" + - "bM\xd5\xcb\xad\xa4\xc8\xb0\x07]\xc7t[P\xac\xab" + - "\x0e\xaf\xc7\x99\xcer\x8d\x0d\x96\xd9\x1cGn55C" + - "\xd5!\xfee1\xdf\xca\xbb\xaeV_\x10tB\xbb\xa3" + - "\x15[\x03\xe3\xaa\x1feK\xe2([M\xe5\xc8\x0d\x0c" + - "\x95[R$\xb4\x86\x98\xf23\x0c\x95\xdf\x110\x9f\x0e" + - "\x8e\xe2^Uw\xf9\x82\x9b:\x94\x99\x13m)!(" + - "\x83\x03\x9eN\xdd>\x94\xdc\x1e_NU\xe6M\x0c\x95" + - "Q\x01\x0f\xd8n\xadF\x8f\x8eP\x98\x0c\x9b\x0d(\xd2" + - "\xd9){\xc4s\x80\xd0\x1e\x97\x9b~\x1b\xdc\x09\xbe\xca" + - "\xc6\xa4IyKT\x9b\xf6\xffq\xf7\x18\xb7\xf3T\xeb" + - "_\xb2\xa5\x8b;\xfbK\xe7\xb9\xd1\xf1\xf1J\xd2w\xb2" + - "\x80$\xd3\xbc0\x96\xe6\x85\x84\x16\xa6\xd3\xe1\x1f\x95c" + - "\xb2\xe2\xc7a\x85\xe4;0)\xd8\xe5\xbb\xf0\xf4\xbc\xf8" + - "\xcf\x0c\x06\xbc\xc0\xfd\xe3\xeb$o\xf9\xbc\x80\x01/4" + - "\xfd\xf3u\x92\xcf\xa4y\xc1\xc5\xb9\xf9\xbc\xc0\"^\xa0" + - "x>D\xf2c>/d\x02^8\x8a/\xcd\x8b\xff" + - "\xael\xc0\x0b'\xf1\xd5y\xf1\xbf4\x17\xf0\xc2\x19\x7f" + - "\xfd\xb3$\xbf\xe0\xf3\xc2P\xc0\x0b\xe7}\x1ey\x91\xe4" + - "\xaf\x11/\xb8\x96^u,\xcd\x00l$\xceZk}" + - "\x89\xf3\xd6 \xe4um/\x8f9\xbb\xae\xa9\xfazW" + - "\xd5\xa1Xu\xd4\xda\xee\xa4\xe6\xd4\xedQ\xd5\xa8\xdb8" + - "\xa5\xee\xe6\xc4\xf4b:':\xba\xbd\x8d[\xda$`" + - "R\xa5\xc65B\xbeb\x9a\xed\xa5\x83_\xecp+ " + - "\x95\xf8\xb7\xa6:S\xae\xeb|\x18\xa3J\x81\x19I\xa6" + - "\xd1\xe8\x17\xd300H\xdf\xe3Zq~^n\x85u" + - "o\x94\xdf\xc7Km\x89\x9b\xcf\xb4x\xcd\x196\xd1p" + - "4\xc3\xe5\x0b\x0e\xa8M\xb9\xc6n^\x1fA\xa3f\xd6" + - "5\xa3\x01\x0b\x0an\xf6\x9b\xda\xfdTA\xe3G3\xa6" + - "\xa6\xcc\xd2\xea\x01\x10|.\xa1\xf4,\x0d$mk\xa9" + - "\xe6\xef*Y\\\xb5S\x1d\xd7\"\xb7\x85\xd3\x9d \xc8" + - "\xe8\xb6\x02\xcb\x02\xc43[\x8c\x86h\xd2\x9e} H" + - "\x9a\x88\xc9\xec\x11\xa3Q\xa3t\x8f\x05\x824!\xa2\x10" + - "\x8f\xca1\x1asK\xe59\x10\xa4\x11\x11Y<\xdf\xc6" + - "h\x84%\xdd>\x04\x82\xb4F\xf4\xa2\x12\x1dJ\x81:" + - "\xeb\xd0\x8b\x02\x1f\x8a~\xe8\xafC/j\xfc1*\xe5" + - "\x01\xd6\xe1\x810-\xac\xc3\xf4\xb4\x88\xfd\xa6z\xbas" + - "\x998\x94\x942\x11G>0\x97T2q\x0fs\xf4" + - "\xb9t\x95\x18\xb6\xe2'\x0f\x86\x8d\xfc\x85T+~\x9e" + - "J\xc7\x0b\x0c\x95\x1f\x0aI\xbe\x8c\xdc.\x1a\xb0\xa0i" + - "EM\xd5\"s\x96\xd09\xc3\x0a\xae}\xda\xe2\xd5\xcd" + - ")\xbf\xc2\xc3\xe0(\x1b\x12\xc6N\x8f`\x96\xa5F0" + - "\x18\xb5s\xe2<\x82O\x0fd\x96-\xce\x99\xf3\x9a\x13" + - "?\xe3d|\xaf\x89\x06\xf9\x18\xfdIE\x92\xc8\xfa=" + - "\xa2\x1750\x18\xa5+2^\xdadW\xd8\xc5\x8d\xf1" + - "\xa2}9\x99 \x1a\xdb^\xba\x19\x0f\xee\xc9\x93\xb3\x05" + - "\x0f\x8a\xcf\x9dN\x8d\x85t3\xec\x87\xf2[\xd2%\xed" + - "\"X\x05\x0aG\x05h\x9e6\xb7\xb9\xdf\xaaT%\x1d" + - "\xfb\xdf\xaa\xa46\x8f\xbb\x94\xc3\x1bC\xa7|*.8" + - "\xa5Ss\xc9\xc8(v\xbf\xb3\x1b\x93.E\xe4\x96\x15" + - "\xe9)\xbaVB\x9b\xba\xd9\xd8\xa4\x19\xdc\xa6\x12\xac\xad" + - "\xb5nq\xab\xa9\x1a\xdc@\x87\xc8\xc8\xb5\x88Q\xe73" + - "Wy}\xaar[\xec\xf9\xd5\xd0\xd9\x03_\x0f\xd3k" + - "\xaa\x8f<\x9d\x9aiD\x8fW^\x0dg\x05;S\x8f" + - "\xbf\x87\xfa\xc8\x1d\x0c\x95)\x01=\xd5u\xcc\x89V]" + - "E\x87o\xb0\xf8\x1e\x97\x8bFm6\xe9\xa7\xa8\xa3\xa8" + - "\xd9\x13\xd8\xa2\xdao\x83\xc5K{\\\x9e^\x10Mb" + - "A\xd4\xcc\xfa\x82\x11l\x87b\xeb\x0e\xbe\xabj\xd6v" + - "sg\xde\x84:\xa0\xcb\xe8)\xeaX2\x86\x8d^\xa2" + - "\x8d%C\xd8\x98F\xf6\x90C\xb5\x18*\xfbS42" + - ";\x97\x18\xbcsv\xfd\xffI\x88\x8b<\xb2\xe3\x98t" + - "\xac\xc4/+\xd0\x92?;\\\xba\xe4\x0a\xdb\xf6\xb0b" + - "\xbd\x9c\xc1\xc2\xbc\xc9W\xe8\x10\xcat2\x8c\xf1\x9d\xbc" + - "\x90\xfc\x153\xd4\xc1\x0eKG`\x93f\x87\xaa0h" + - "n\xa2Ft\xe1x\xe4\x7f\x03\x00\x00\xff\xffYM," + - "\\" +const schema_db8274f9144abc7e = "x\xda\xacY{\x8c\\\xe5u?\xe7~\xb3{\xd7\x8f" + + "\xf1\xcc\xed\x1d\x843\xf5j+\x0b\x1a\xec`\x17\xe3\xd0" + + "\xe2m\xc9\xec\xc3vv7k{\xee\xce\xae\x01c$" + + "_\xcf|\xbb{\xd7w\xee\x1d\xdf\x87\xd9\xb5L\x8c-" + + "S`\x0b\xc1&\xb1\x84\x89\x89\xc0\x8d\xcbCv\x83\x89" + + "Q\x0b\x05\x14\xaa\xa6\x84&\x11q\x8b\xab\xd0\x12\x09\x02" + + "V\x15TDM\"!\xaa\x84[\x9d\xfb\xde\xd9e\x8d" + + "\xab\xfc\xb3;:s\xbe\xef;\xcf\xdfy\xccu\x99\x05" + + "]\xc2\x9a\x163\x0b\xa0\x1coi\xf5Z\xfe\xf8\xfc\xdb" + + "\x8d\xb7\xc5C \x15\xd1\xfb\xfa\x8b\x03\x85O\x9c\x83\xff" + + "\x09-\x82\x08\xb0\xf6\xd1\xd6\x01\x94\xcf\xb4\x8a\x00\xf2\xe9" + + "\xd6;\x00\xbd\xbf\xa8\xbf~\xe2O\x8f\xfe\x98\x98\x85\x84" + + "\x19p\xed\x15\xe2^\x94W\x88\xc4y\xb5\xb8\x05\xd0\xfb" + + "\xb7\xeb\xf6\xbd\xb7\xe3\xd7G\xee\x9dym\x86n\xbdI" + + "\x9cFyD\x14\x81y\x8f\xdeV\xf8\x17|\xec\xe3#" + + " ]\x83\x00-H_\xaf\x11\x17\x0a\x80r\xbfX\x02" + + "\xf4^\xbf\xf6\xc5\x17\x0e\x7f\xff\x9eo\x83\xf2ED\x08" + + "\xcek\xe2\xff\"\xa0|\xa7\xcfp\xf1\xbb_\xca\x9c~" + + "\xfd\x0f\xbe\xe33x'\xcf\xdd\xfc\xec\xe1\xef\xff\xd1\xfb" + + "0\"\x88\x98\x01X{R\xb4\x88\xf7\x8c\xf8_\x80\xde" + + "\xb7~\xfe\xd2\xe6\xfa\x91GN\x80\xf4\xc5\xe8\xae#m" + + "\x82\x00\x19\xef\x86\xff\xb8\xb0e\xd3\xb3\xa3O\x04\xdf\x04" + + "r\xdc\xdd\xf6,\x1d=\xdaF\xcf\xfc\xe8\x8e\xfc\xfd\xdd" + + "\x7f\xf6\xe0\x13\xa0\x141m\xa6\x16\xe2|\xbem\x1a\xe5" + + "sm\xf4\xf1\xa7m7#\xa07\xbd\xee\xa5\xad\xbf\xfe" + + "K\xfbiPVa\xc6\xfb\xa7\xfb\xde\xdd\xb3\xe2\xa9\xd1" + + "W}\xa9\x18\xc0\xda\x0d\x0b\xff\x95\xae\xbeu\xe1\xf7\x00" + + "\xbd\xec?\xac\xdc\xfc\xe0{\x83g\xe8\xea\x94Q\x03!" + + ">Y\xd8\x89\xf2\x82Ed\xd7\x96E\xc4\xfd\xb3k\xb7" + + "\xbe\xfc\xf23cg\x9a\x05\xf1\xfdur\xd1\x00\xca\xcf" + + "\xfb\xdc\xcf\xf9\xdcW\xf4\xe3[?X\x93\xf9\xbbP/" + + "\xe6\x9bo\xf1\xfb\xbe\xf9\x16\x13\xc3m\xbf}\xee\x1f7" + + "|\xf8\xc6\xf3i\x07\xb4g\x05r\xc0\x9a,)\xbem" + + "\x1a\xebouv\xbd\x0c\xca5\x88\xde\xc4\xd1}N\xdf" + + "\xc3\x0fx0\x82\"\x0a\x00ko\xcd\xee\xa5\xcbx\x96" + + "\xa2\xa3\xfd\x83\x9e\xac\xf1\xe1\xc1\x1f4\x85\x92\xff\xea+" + + "\xd9\x01\x94\xcfgI\xb4s\xd9\xef\x01~\xfc\xf4=\x87" + + "\xfb\xdf]\xff\xaaR\xc4L\xb3\xd2\xf5%{Q>\xb0" + + "\x84>\xde\xb9\xa4\x83\xec\x19[\xb0\x89\xdd\xd7\xfatn" + + "\x02\xe5Wr\xf4\xf1\xa5\x9c\xcf>p\xdb7\x1fj\xb9" + + "\xf0\xcdW\x9bMJ\xf1\xb9\xf6\xb5\xbc\x85\xf2/\xf2\xf4" + + "\xf1\xcd\xfc\x13\x02\xa0W|\xe6\xcf\xff\xb6\xa7\xf6\xe6\x8f" + + "\xe7H\x01\xf9\x87\xf2G\xf29\x99>\xfdT&\x1d\xef" + + "\xf9\xd2\xd4\xde\xcdWO\x9fo\xb6\xbf/\xf8\x8a\xc24" + + "\xca\xdd\x05\xe2\xbe\xa9@\xdc\xc2\x05\xf5\x0bw\xfd\xfbW" + + "\xdeJE\xdc\xe9\xc2/\x112\xde\xe6\xad\xb7M,\xb8" + + "\xf3\xddw\xd3\x11\xf7x\xc1\xf7\xccs\x052\xfcY\xe9" + + "!\xf9\xc5\xc7\xff\xe6=zHl\xb6\xe6\xf9\xc26\x94" + + "\x7fE\x0f\xad\xbdP\xf0u\x88#\x7f\xae\xb8x\xe7\xca" + + "N\x94/^Ir}p%\xc9u\xc3\x8en\xbe\xfd" + + "\xc6[\xde\x07\xa9\xc8f\xe4\xf1\xaa\xa5\x9d(\xdf\xb4\x94" + + "\x0e\xad[*\xa2\xfc+\xfa\xe8}cl\xdbk\x17{" + + "\x1f\xff\x9f\xe6\xcb}\x85\xce\xd1\x91w\xfc#\xbfX\xea" + + "\x9b\x7f\xed\x9a\xbf\xfa\xe0\xe8_\xf7^\x9cu\xfb\x8ab" + + "\x0f\xca\xeb\x8a$\xc7\x0d\xc5\xaf\xca\xbc\xe8_\xfe\xf5\xf5" + + "[\xd6-\x7f\xe5\xa3\xb4%6\x15?\"K\xa8E\xb2" + + "\xc4\xe8\x8d\xff\xfd\xd5\xab\xbf\xf1\xcf\x1f5\xb9\xc7g<" + + "P\\\x89\xf2\x11\xff\xc6\x07\x88\xf9\xc3\x8d\xdfy\xa3\x98" + + "+\xfef.A\xcf\x14'P\xfea\xd1\x8f\xc6\xa2/" + + "\xe8-\xbf|\xe4\x8e\xd2\xb7\x7f\xf31\xe9\xc5\x9aP\xea" + + "\xe2\x1fnC\xb9e\x19\xdd\x8c\xcb(U\x06O\xbd\xf9" + + "\x95\xf1\xa3?\xfa\xa4\xd9\x08\xbeCN/;\x88\xf2+" + + ">\xf7K\xcb\x08k\xf6}x\xac\xef\xc1\xed\xa7>M" + + "ku\xb2\xfd\x05\xdf\xbf\xed\xa4U\x9cJs\x05\xd2\xf9" + + "\xf6\x1e\x94/\xb4\xd3u\xef\xb4\x97`\x95\xe7\xb8\x86\xc1" + + "u\xab\x91\xa9\xfeI\xf4\xb1\xba\xba\xaa6\x8cFg\xaf" + + "i\x18\xbc\xeaT\xdcj\x95\xdb6@\x19Qic\x19" + + "\x80\x0c\x02H+\x1e\x01P\xaee\xa8\xdc(\xa0\x84X" + + " \x14\x95n\x98\x00P\xbe\xccP\xe9\x12\xd0\xb3\xb9\xb5" + + "\x87[\x83&VUG3\x8d\xcd*\xabs\\\x0c\x02" + + ".\x06\xf4\xaa\xba\xc6\x0d\xa7\xd7\x84\x9c1\xaa\x8da>" + + "\x09\x05@\xcc\x03\xce'\xd8\x86I\xcdv4cl\xd8" + + "\xa7\x97\xca\xa6\xaeU\xa7H\xba\xc5\x04\x1dR{'\xdd" + + "!]\xb1\x0d\x00\x05I\xea\x01(ic\x86iq\xaf" + + "\xa6\xd9UR\x0aX\xd5\xd9\xbfS\xd5U\xa3\xca\xe3\x87" + + "Zf?\xd4\xc7u\xdd\xbc\xd9\xb4\xf4\xda\x16K\x1b\xd3" + + "\x8c^\x93\x84\xf5-\x11\x1f\x13\xe70\x9c\xaf[\x85[" + + "{\xb4*_\xed\xda<8\xe7Z\xbe\x1d\xae\x1a\xe2\xb6" + + "\xab;6\x80\x92\x89\xad\x99\xed\x04P\xda\x18*\x05\x01" + + "K\x96\xcf\x80\xf9\x04\x13\x9al\xd2:\xfb\xcd\xc0\x16\x15" + + "\xdf\xe4\xab]\xc3\xe2c\x9a\xedp+ _U*\xab" + + "\x96Z\xb7\xd3\x0f\x92\xfb\xf2\x0c\x95e\x02zc\x96Z" + + "\xe5en\xa1f\xd66\xab\x86Ya\xbc\x8a- `" + + "\xcb\xfc\x8e\xd8\xa8j:\xaf\x05\xda\xad\xaev\xf8\xff\x95" + + "<\xcb,\xf6<\xff\x11u\x1b\x80\xb2\x83\xa1\xa2\x0b\x98" + + "\xc5O\xbd H\xb4\xbd\x00\xca8C\xc5\x110+\xfc" + + "\xce+\xf8^\xdb\xbd\x1c@\xd1\x19*\x93\x02f\xd9o" + + "\xbd\x02\x154\xc9\xa5\x80r\x18*wQ@\xb9\x0d\xb2" + + "\xa9\x0d\xcc\xb40\x9f$Yh\x1d^\x1b#K\x1bP" + + "\xe2U24\xe6\xa3Z\x100\x885s\x1c\xf3I\xa1" + + "\x0b\x8fY|\x0f\xb7l^\x86\x9ceNNa>\xa9" + + "\x09MV\xcf^\xae\xd5#G\xc7\xa7\xe6?_\x0d\xf2" + + "\xed\xaar\xc7,g\x91\x1d\x173T\x96\x0a\xe85\xe8" + + "[\xeep`\x96\x8d\xf9\xa4\x81h\x92v\x8ep\xee\xa5" + + "\xbfaV\x97\xc3[\xac0\xb1\x97\xc6\x8f\x1d\xa3\xc7\x1e" + + "f\xa8|7\x95\xd8\x8f[\x00\xcac\x0c\x95S\x02\xa2" + + "\x10x\xec\xa9\x13\x00\xca)\x86\xca\xdf\x0b(1!p" + + "\xd8s+\x01\x94g\x18*?\x11P\xca\xb0\x025K" + + "\xd2k\x14l?a\xa8\xfc\\@\xa9%S\xc0\x16\x00" + + "\xe9\xfcN\x00\xe5\x0d\x86\xca\xdb\x02zf\x90_\xa4\x94" + + "\x83Y\x100\xebc\x84\xe9\xd6Fu\x15:,^\xeb" + + "_\x1f\xd3\x0d\xb7^\xb6\xf8\x1e\x0dM\xd7\xeev\x1c^" + + "\x17\x1b\x8e\x8d\xad `+`\xceQ\xc7l\\\x02X" + + "f\x88\xf9\xa4\x04\x03\x121\xbe\x13-^\xdb\xca-[" + + "c\xa6\x11\x83\x92f8\xdcp\x06U\x10wr=\xa6" + + "\xce\x93uCa\xecP\xe4\x84i`&H\x81c\xca" + + "b\x96Y\xe6y\xa1\x117\x90m\xba\x18*\x83\x02\xb6" + + "\xe3\xa7D&;\xf6\x0f\x01(}\x0c\x95a\x01\xdb\x85" + + "\xdf\x11\x99,\xa9\x90\x1f\xca\x0c\x95\xed\x02\xe6\xc6\x1d\xa7" + + "\x81\xf9\xa4v\x87\xce\xbe\x83\xef\xb4\xcd\xea.\x0eHp" + + "\x11\x17\x92\xf0\xdb\xf1\x10\xbe\x80\xe95\xcc'\x9dsS" + + "\xa4\xb0\xcf\x82\xfe\x92\xb3\xc1\xb2L\xcbG\xd68<6" + + "\\\x9f(\x11EG\xff\xb6D\x03I\xe8\x0a\xd4Rv" + + "&\xf2wTU\xd7N\xc0\xdf\xe2\x8e5\xd5=\xea\x00" + + "\xe3V\x8c3\xf6\xb8\xe9\xea\xb5!\x0e\xa2cM!\x82" + + "\x808?\xfa\xac7\xfbR\x86\x0f\xc28%'\xc9\xb4" + + "\x9e\xa1RN\xe4\xdcD\xb4A\x86\xca-$gh\xfe" + + "\x112\xff0C\xa5!\xa0\xa7S\xfe\x1a}&0\xdb" + + "\x89\xc5\x0d\x88e\xd3\x0fN\x11\x04\x14\x01=\xb7a;" + + "\x16W\xeb\x80q\xb4\x11\xff\x92\xcb\x80\xe9&\xb8(\xab" + + "9?\xef\xe7\xd6!N\xc5M\x03i%\xc2\\\x1c\xe9" + + "I\x8c=w2\x8d\x9b\xb6c\xa8u\x0e\x00\x91b\xfb" + + "\xcd\x06\xe1$\xa1H\xdc\xd86\xc5\xc6\xe5W\xb7\xa0\xd2" + + "\xcc\xa8m'R\xa5\xa6\x1a\x9eF\xffx\xafi\x88\x97" + + "]\xfeC\x04\x0b\xd0uuX-\xa93\x89\xca\xce\x0a" + + "*%W1T\xaeK\x97\x9dUd\xa2k\x18*_" + + "\x16P\xe4\x16U\x90xB\x0a\x1e\xddo\x07\xad\x0e\xe6" + + "\x93\xe1\xf5\xd2\xe2t\xbb\xce87\x1c-\xe8rf\x85" + + "\xe1\xf2$]b\x17\xf6_\x9f\xf2k\xe4\xc2M;\x13" + + "\xbf\x8a\xbb\xf8T\xe4\xa5\x0e^W\xb5\x04\x8dB\xe7v" + + "\x83\xf8\xb5\x84g\xden),\x8bAQ,\x05\xde\"" + + "!\x0b\xb1\x90wN\x03(w1T\xeeO\x09y\xdf" + + "C\x00\xca\xfd\x0c\x95\x87SB\x1e%#\x1ef\xa8\x1c" + + "'\xccg\x01R\x1d#\x07\x1fg\xa8<) f\x02" + + "\xc8?I\x90\xff$C\xe5\xac\xe0\x03v_w\xafi" + + "`(\x84\x0d\x10\xc1\xb57\xceU\xcb\xd9\xc9Ut\xfa" + + "\x0d\x87[{T\xd4#H\xd8\xefhun\xbaN\x0c" + + "\x11uu\xd2o9\xb0\xd6\x17\x9c\x12U\xc7\xc6\x05 " + + "\xe0\x02\xcaH\x9b[\xbd\x16\xaf!yC\xd5\xcb*s" + + "\xc6?\x8f\x81f\x82xn\x0e\xf3P\xc3\xb2\x8f\xa1r" + + "/A\x09\xa6\xa6p\xe9\xee\x09\x10|$!\x9dw\xf7" + + "$-\x8c_\x10\xa9\xcc\xb9d\xc6I\x86\xca\xa1\xb0 " + + "\xb6\x02H\x07\xc8:\x87\x18*\x87\x85H\xb4>\x13J" + + "A\x866\xbb:\xec\x91\xf7\x13jj<\xd17\xec\x17" + + "44\x8da\xdfP\x98X\xaaj\xd6\x1b\x16\x85\xb2f" + + "\x1a\x8a\xab\xea\x1as\xa6\xe2\x83\xf3\xda\x82 )H\xe5" + + "-\x8d\x0e\xdfYd\x8c\xeb\"c\xc8\xdd8\x00P\xe9" + + "B\x86\x95AL\xc2E\xee\xc7\x1e\x80\xcaz\xa2\x971" + + "\x89\x18y\x13\x16\x01*}D\x1fF\x011\x88\x19Y" + + "\xc1\xa7\x01*\xc3D\xde\x81I\xab \xdf\xee_\xbf\x9d" + + "\xe8\xe3\x98t\x0b2\xc7\x95\x00\x95\x1dD\xdfG\xf4V" + + "\xc1\xb7\xa4<\x85\x13\x00\x95I\xa2\x1f\"\xba\xd8R\xa0" + + "AG>\x80\x16@\xe5.\xa2\xdfO\xf4\xb6\xa5\x05l" + + "\x03\x90\xef\xf3\xe9\xf7\x12\xfd[D_\xf0\x85\x02.\x00" + + "\x90\x8f\xe0A\x80\xcaa\xa2\x1f'\xfaB,\xe0B\x00" + + "\xf9\x18>\x02P9N\xf4'\x89\xbe\xa8\xb5\x80\x8b\x00" + + "\xe4\x93\xbe<\x8f\x11\xfd\x14\xc6\xb8\xd6_K\xc3+\x85" + + "\x95\x96\xb4\x17\xcc\xb4c\xd7\xf2p\x84\xc1\x00\xfb\xcbf" + + "\x8ef\x18\xcc%\x8b0@\xcc\x01z\x0d\xd3\xd47\xcf" + + "\x84\xedKu8aX@\xce4\xfakq\x9e\x05\xc1" + + "4hBGU\xd5\xfb\x1bI\xcfcw\xbb\x8e\xe96" + + "\xa0\xa3\xa6:\xbc\x16\x17^\xcb56Zf}\x18\xb9" + + "U\xd7\x0cU\x87\xf8\x9b\xf9b+\xe7\xbaZmV\xd2" + + "\x09\xcd\x81\xd6\xd1\xe8\x1cV\xc7\x9a\x06\xca\x95\x09j\xc7" + + " \xb4\xea\xfa\x04\xb4s\xe9\xe4\xe8\xd8\xa3\xea.\x9f\xf5" + + "\xd2\x1c]\xefHS\x85\x0a\xea\xc6\xacq\xb6'y=" + + "~\xdc\x0aG\xdc>!\xa9\x0d\x91\x15F\xc3\xd9\x07:" + + "\xe8\xee\x94?\xe2\x85I\xe8\x8f\xcf\xdb\x0d\x8cq'\xf8" + + "\xd4o\x8c\x9aTFE\xb5n\xff?O\x0fq;G" + + "\xa3\xc7%'\xccx\x05r\xe9:\xd77<\\N\xc6" + + "`\x16\x80d\x1a\x17\x86\xd2\xb8\x90\xc0\xc2D:\xfd\xa3" + + "\xeePV\xfc<,\x13};&\xf3\x83|+\x9e\x98" + + "\x91\xff\x99\xee\x00\x17\xb8\x7f}\x8d\xe8\x0d\x1f\x170\xc0" + + "\x85\xba\x7f\xbfN\xf4\xc94.\xb88=\x13\x17X\x84" + + "\x0b\x94\xcf\x87\x88~\xd8\xc7\x85L\x80\x0b\x0f\xe0\xb33" + + "\xf2\x7fAK\x80\x0b\xc7\xf0\x85\x19\xf9\xbf\xb05\xc0\x85" + + "\x93>\xff\x93D?\xeb\xe3BO\x80\x0bg|\x1cy" + + "\x86\xe8/\x12.\xb8\x96^q,\xcd\x00\x1cK\x82\xb5" + + "\xda\xf8\x1a\xe7\x8dn\xc8\xe9\xda\x1e\x1ecvMS\xf5" + + "\xf5\xae\xaaCG\xc5Q\xab\xbb\x92\x16X\xb7\xfbT\xa3" + + "f\xe3\xb8\xba\x8b\x13\xd2\x8b\xe9\x9a\xe8\xe8\xf6Vni" + + "\xa3\x80I\xd3\x1c\xf7\x08\xb9\xb2i6\xb7\x0e~\xef\xc5" + + "\xad\x00T\xe2\xef\xea\xead\x7fM\xe7\xbd\x18u\x0a\xcc" + + "H*\x8dF\xdf\x98\x86\x81A\xf9\x1e\xd6:f\xd6\xe5" + + "F\xd8\x86G\xf5}\xb8\xd4T\xb8\xf9d\x83W\x9d^" + + "\x13\x0dG3\\>\xeb\x82\xea\xb8k\xec\xe2\xb5\x0dh" + + "T\xcd\x9af\x8c\xc1\xac\xfe\x9f}\xd6\xf6!\xd5\xd0\xf8" + + "\xd9\x8c\xa9\xd5\xbd\xb4\xa2\x13\x04\x1fK\xa8" + + "\xab\xbd\x9f\xbbM\xecIZ\x99\x08#\x0fL'\x9dL" + + "\xbd\x1fZr\x89" + + "Q%=+\xf9\x15'\xe3GM\xf4\xeb\x08F\xbfS" + + "I\x12y?+z\xd1<\x85Q\xb9\"\xe7\xa5]v" + + "\x99C\xe5\x10\xef\xb0?O%\x88\xf6\xdb\x97\xde\x0d\x04" + + "\xef\xe4(\xd8\x02\x85\xe2{'R[*\xdd\x0c\xe7\xa1" + + "\xdc\xe6tK;\x8f\xad\x02\x81\xa3\x064G\x87\x9b\xc2" + + "oy\xaa\x93\x8e\xe3oy\xd2\x9b\xc7S\xca\xdd\x03a" + + "P>\x167\x9c\xd2\xa3\xd3\xc9\x06+\x0e\xbf\xa7\x06\x92" + + ")\xc5\x9f\x09C9E\xd7J`S7\xc7\x065\x83" + + "\xdb\xd4\x825M\xfa\x0dn\xd5U\x83\x1b\xe8\x10\x18\xb9" + + "\x16!\xeaL\xe4\xea_\x9f\xea\xdc\xe6S\xbf\x12\x06{" + + "\x10\xebayM\xcd\x91'R+\x96Hy\xe5\x85p" + + "u\xb1#\xa5\xfc\xed4Gng\xa8\x8c\x0b\xe8\xa9\xae" + + "c\x8e4j*:|\xa3\xc5w\xbb\\4\xaaS\xc9" + + "