diff --git a/tunnelrpc/pogs/config.go b/tunnelrpc/pogs/config.go index 76d079a0..1125d1d9 100644 --- a/tunnelrpc/pogs/config.go +++ b/tunnelrpc/pogs/config.go @@ -32,7 +32,7 @@ type ClientConfig struct { Version Version `json:"version"` SupervisorConfig *SupervisorConfig `json:"supervisor_config"` EdgeConnectionConfig *EdgeConnectionConfig `json:"edge_connection_config"` - DoHProxyConfigs []*DoHProxyConfig `json:"doh_proxy_configs"` + DoHProxyConfigs []*DoHProxyConfig `json:"doh_proxy_configs" capnp:"dohProxyConfigs"` ReverseProxyConfigs []*ReverseProxyConfig `json:"reverse_proxy_configs"` } diff --git a/tunnelrpc/pogs/config_test.go b/tunnelrpc/pogs/config_test.go index d74fa62c..ccc51d66 100644 --- a/tunnelrpc/pogs/config_test.go +++ b/tunnelrpc/pogs/config_test.go @@ -29,7 +29,27 @@ func TestVersion(t *testing.T) { assert.True(t, secondVersion.IsNewerOrEqual(secondVersion)) } -func TestClientConfig(t *testing.T) { +func TestClientConfigCapnp(t *testing.T) { + for i, testCase := range ClientConfigTestCases() { + _, seg, err := capnp.NewMessage(capnp.SingleSegment(nil)) + capnpEntity, err := tunnelrpc.NewClientConfig(seg) + if !assert.NoError(t, err) { + t.Fatal("Couldn't initialize a new message") + } + err = MarshalClientConfig(capnpEntity, testCase) + if !assert.NoError(t, err, "testCase index %v failed to marshal", i) { + continue + } + result, err := UnmarshalClientConfig(capnpEntity) + if !assert.NoError(t, err, "testCase index %v failed to unmarshal", i) { + continue + } + assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i) + } +} + +func ClientConfigTestCases() []*ClientConfig { + addDoHProxyConfigs := func(c *ClientConfig) { c.DoHProxyConfigs = []*DoHProxyConfig{ sampleDoHProxyConfig(), @@ -58,7 +78,12 @@ func TestClientConfig(t *testing.T) { sampleClientConfig(addReverseProxyConfigs), sampleClientConfig(addDoHProxyConfigs, addReverseProxyConfigs), } - for i, testCase := range testCases { + + return testCases +} + +func TestClientConfig(t *testing.T) { + for i, testCase := range ClientConfigTestCases() { _, seg, err := capnp.NewMessage(capnp.SingleSegment(nil)) capnpEntity, err := tunnelrpc.NewClientConfig(seg) if !assert.NoError(t, err) { diff --git a/tunnelrpc/pogs/tunnelrpc.go b/tunnelrpc/pogs/tunnelrpc.go index 94bc87c2..8d41b63a 100644 --- a/tunnelrpc/pogs/tunnelrpc.go +++ b/tunnelrpc/pogs/tunnelrpc.go @@ -75,8 +75,9 @@ func UnmarshalRegistrationOptions(s tunnelrpc.RegistrationOptions) (*Registratio } type ConnectResult struct { - Err *ConnectError - ServerInfo ServerInfo + Err *ConnectError + ServerInfo ServerInfo + ClientConfig ClientConfig } func MarshalConnectResult(s tunnelrpc.ConnectResult, p *ConnectResult) error { @@ -146,7 +147,7 @@ func NewSystemName(systemName string) *SystemName { func (s *SystemName) Value() string { return s.systemName } func (_ *SystemName) PostgresType() string { return "system_name" } -func (_ *SystemName) GraphQLType() string { return "SYSTEM_NAME" } +func (_ *SystemName) GraphQLType() string { return "SYSTEM_NAME" } func (_ *SystemName) isScope() {} @@ -160,7 +161,7 @@ func NewGroup(group string) *Group { func (g *Group) Value() string { return g.group } func (_ *Group) PostgresType() string { return "group" } -func (_ *Group) GraphQLType() string { return "GROUP" } +func (_ *Group) GraphQLType() string { return "GROUP" } func (_ *Group) isScope() {} diff --git a/tunnelrpc/pogs/tunnelrpc_test.go b/tunnelrpc/pogs/tunnelrpc_test.go index cad0b0dc..b2f2e71e 100644 --- a/tunnelrpc/pogs/tunnelrpc_test.go +++ b/tunnelrpc/pogs/tunnelrpc_test.go @@ -3,6 +3,7 @@ package pogs import ( "reflect" "testing" + "time" "github.com/cloudflare/cloudflared/tunnelrpc" "github.com/google/uuid" @@ -39,6 +40,40 @@ func TestScope(t *testing.T) { } } +func sampleTestConnectResult() *ConnectResult { + return &ConnectResult{ + Err: &ConnectError{ + Cause: "it broke", + ShouldRetry: false, + RetryAfter: 2 * time.Second, + }, + ServerInfo: ServerInfo{LocationName: "computer"}, + ClientConfig: *sampleClientConfig(), + } +} + +func TestConnectResult(t *testing.T) { + testCases := []*ConnectResult{ + sampleTestConnectResult(), + } + for i, testCase := range testCases { + _, seg, err := capnp.NewMessage(capnp.SingleSegment(nil)) + capnpEntity, err := tunnelrpc.NewConnectResult(seg) + if !assert.NoError(t, err) { + t.Fatal("Couldn't initialize a new message") + } + err = MarshalConnectResult(capnpEntity, testCase) + if !assert.NoError(t, err, "testCase #%v failed to marshal", i) { + continue + } + result, err := UnmarshalConnectResult(capnpEntity) + if !assert.NoError(t, err, "testCase #%v failed to unmarshal", i) { + continue + } + assert.Equal(t, testCase, result, "testCase index %v didn't preserve struct through marshalling and unmarshalling", i) + } +} + func TestConnectParameters(t *testing.T) { testCases := []*ConnectParameters{ sampleConnectParameters(), diff --git a/tunnelrpc/tunnelrpc.capnp b/tunnelrpc/tunnelrpc.capnp index 1f3b20ee..5beecc18 100644 --- a/tunnelrpc/tunnelrpc.capnp +++ b/tunnelrpc/tunnelrpc.capnp @@ -74,6 +74,8 @@ 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; } struct ConnectError { diff --git a/tunnelrpc/tunnelrpc.capnp.go b/tunnelrpc/tunnelrpc.capnp.go index f1f01575..0dd6ab0e 100644 --- a/tunnelrpc/tunnelrpc.capnp.go +++ b/tunnelrpc/tunnelrpc.capnp.go @@ -805,12 +805,12 @@ type ConnectResult struct{ capnp.Struct } const ConnectResult_TypeID = 0xff8d9848747c956a func NewConnectResult(s *capnp.Segment) (ConnectResult, error) { - st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) + st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}) return ConnectResult{st}, err } func NewRootConnectResult(s *capnp.Segment) (ConnectResult, error) { - st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}) + st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}) return ConnectResult{st}, err } @@ -874,12 +874,37 @@ func (s ConnectResult) NewServerInfo() (ServerInfo, error) { 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()) + return ss, err +} + // ConnectResult_List is a list of ConnectResult. 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: 2}, sz) + l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}, sz) return ConnectResult_List{l}, err } @@ -908,6 +933,10 @@ 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)} +} + type ConnectError struct{ capnp.Struct } // ConnectError_TypeID is the unique identifier for the type ConnectError. @@ -3675,228 +3704,229 @@ func (p ClientService_useConfiguration_Results_Promise) Result() UseConfiguratio return UseConfigurationResult_Promise{Pipeline: p.Pipeline.GetPipeline(0)} } -const schema_db8274f9144abc7e = "x\xda\xacY}l\x1cez\x7f\x9ey\xd7\x1e;\xf1" + - "f=\xcc\"b\x13\xcb\xa7\x08t\x17\x8e\xa4\x107-" + - "q\xdb\xdb\xd8Nr\xb6/\x1f;\xfe\x08\x10\x12)\x93" + - "\xdd\xd7\xebIfg6\xf3\x91\xd8Q\xee\x02i(\xe0" + - "\x92#\xe1.\x15\xc9\x85\x13\xa4\x97\xf2\xa1\\K\xb8\xa0" + - "\xf6(\x9c\x8e\xaa\x14\xd2;\x09P\xa1\x82\x96\xfe\xd1\x83" + - "\xa8\x025\xa2p'!N\x17\xa6z\xe6\xdb\xeb\xc5!" + - "U\xffIV\xcf<\xef\xfb>\x9f\xbf\xe7\xc3\xb7\\n" + - "Y#\xdc\xdadf\x01\x94SM\xcd\xde\x1fW_;" + - "\xfd\x07\xc7\x7fq\x18\xa4N\xc1\xfb\xce\x0b\xc3\xf9\xcf\x9c" + - "C\xff\x0e\x80=\x8f6\xefG\xf9\\\xb3\x08 \xff\xb8" + - "y3\xa0\xf7/\xb7\x1cx\x7f\xc7\xaf\x8f\xdd\x0fR'" + - "&\x9c\x19\x11\xa0\xe7\xe5\xe6\x19\x94\xff\xa3Y\x04\xe6=" + - "zW\xfe\x9f\xf1\xb1O\x8f\x81\xf45\x04hB\xfa\xfc" + - "\xd3\xe6\x05\x02\xa0\xfcFs\x01\xd0{\xed\xe6\x17\x9e?" + - "\xfa\x93\xfb~\x00\xcaW\x11!8\xffq\xf3o\x11P" + - "n\x12\x89\xe1\xe3\x1f}=\xf3\xe3\xd7\xae\xf9\xa1\xcf\xe0" + - "\x9dy\xe3\xf6g\x8f\xfe\xe4+\x1f\xc2\xb8 b\x06\xa0" + - "g\xb9h\x11\xefj\xf1\xbf\x00\xbd\xef\xbf\xfd\xe2\xa6\xea" + - "\xb1\x93\xa7A\xfajtWG\x8b @\xc6[\xf5o" + - "\x177o|v\xe2\x89\xe0K G\xb6\xe5Y:\xda" + - "\xd5B\xcf\xbc\xba\xaf\xfd\xc1\xbe?|\xe8\x09P:1" + - "\xa5OS\x13q\xf6\xb5\xcc\xa0|g\x0b\xfd\x1co\xb9" + - "\x1d\x01\xbd\x99\xd5/n\xf9\xf5\x9f\xd9O\x83\xb2\x1c3" + - "\xde?>\xf0\xde\xdeeOM\xbc\xe2K\xc5\x00z." + - "\xb4\x9e\xa6\xab\xdfi\xfd\x1b@/\xfb\xf77mz\xe8" + - "\xfd\x0d\xe7\xe8\xea\x94Q\x03!\xa6\x17\xf4\xa2\xfc\xc0\x02" + - "\xb2\xeb\xbd\x0b\x88\xfb\xf5\x9b\xb7\xfc\xecg\xcfT\xce\xd5" + - "\x0b\"\x10\xf7\x8d\x0b\x87Q^\xbd\x90\xb8W-$\xee" + - "k\x87\xf0\xdd\x9f\xdf\x9a\xf9\xdbP/FL\x1f,\xfc" + - "\x90\x1e\xbf\xec3\xdc\xf5\xbb\xe7\xfea\xddGo\xfe4" + - "\xed\x80G\xdb\x04r\xc0\xb96R\xbc\xebR\x7f\xd6\xf8" + - "\xe8\xd0\xcfg\xfb1\xb8\xe9\x9d\xb6a\x94/\xb5\xd1s" + - "\x1f\xb4\xd1m\x7f\xe1\xbe\xfd\xa69<\xfcr\xbdp\xfe" + - "\xb5\xf7f\x05\x94\x8fe\x89\xfbH\xb6\x00\xf8\xe9\xd3\xf7" + - "\x1d\x1dzo\xed+J'f\xeay\x8fe\xf7\xa3|" + - "\x86x{\x1e\xcfv\x93Ec\x1b\xd6\xb1\xfbz\xbf\xb1" + - "h\x17\xca\x17\x17\xd1\xcf\xff\\\xe4\xb3\x0f\xdf\xf5\xbd\x87" + - "\x9b.~\xef\x95z\xa3\x8a\xbe\x05r\x16\xca\x97s\xf4" + - "\xf3\xb3\xdc\x13\x02\xa0\xf7\xdb\xb3\x7f\xca/\xaex\xf5\x02" + - "(_\xc1\x94\x1a\xe3(\xa2\x00\xd0s\xf1\x9a\x95d\xb2" + - "K\xd7\xec\x03\xf4:\x9f\xf9\xa3\xbf\xee/\xbf\xf3\x8b:" + - "\x8b\x90 \xf2F\xf9\x13\xf9N\x99~\x8d\xcb\xc4{\xdf" + - "\xd7\xa7\xf7o\xbaq\xe6\xad\x86\x069'\xcf\xa0|\xc1" + - "\xe7~\xd9\xe7\x16.\xaa\x1dw\xff\xeb7\xdeM\xc5\xe7" + - "\xaa\xfc\xaf\x102\xde\xa6-w\xedj\xfd\xf6{\xef\xa5" + - "\xe3sY\xde\xf7\xe3\x9f\xe4\xc9M\xe7\xa5\x87\xe5\x17\x1e" + - "\xff\xab\xf7\xe9!\xb1\xdeO\xdb\xf3[Q\xde\x93\xa7\x9f" + - "\xd5\xbc\xafo\x9c'\x8d\xa2H\xbb\xae\x17\xe5\xe9\xebH" + - ".\xf7:\x92k\xd5\x8e>\xbe\xed\xb6;>\x04\xa9\x93" + - "\xcd\xca\xfa\xe7\x88\xf3e\xe2\xecy\xe9:\x11\xe5=\x8b" + - "E\x00\xef\xbb\x95\xad\x17>\x1ex\xfc\x7f\xea/\xf7\x15" + - "\xbasq/\xca\x1a\xf1\xf5\xf0\xc5\xbe\xabzn\xfd\xf3" + - "K\xc7\xffr\xe0\xe39\xb7\x9f\xeb\xe8G\xf9\xa5\x0e\x92" + - "\xe3\xc5\x8eo\xca\x97:\xfc\xcb\xbf\xb3v\xf3\xea\xa5/" + - "}\x92\xb6\xc4[\x1d\x9f\x90%>\xe8 KL\xdc\xf6" + - "\xdf\xdf\xbc\xf1\xbb\xff\xf4I\x9d{|\xc6\xd6\xce\x9bP" + - "\xee\xe8\xa4\x1b\xaf\xed,\x00~\xb4\xfe\x87ov\xe6:" + - "\x7f\xd3H\xd0\xd5\x9d\xbbP\xdeH\xbc=C\x9d\xbe\xa0" + - "w\xfc\xea\xe4\xbe\xc2\x0f~\xf3)\xe9\xc5\xea0m\xfa" + - "\xfa\xad(\x1f\xb9\x9en~\xe0zJ\x85\x0dg\xdf\xf9" + - "\xc6\xe4\xf1W?\xab7\x82\xef\x90UK\x0e\xa1<\xb4" + - "\x84\xb8\xd7-!d:\xf0\xd1\x89\xc1\x87\xb6\x9d\xfd<" + - "\xad\xd5\xf2\xae\xe7}\xffv\x91V\xbb\x8e\x1fp\x06\x1f" + - "9\xe25\x08\xba\x9e\xed]\xfd(W\xbb\xe86\xadk" + - "\x1f,\xf7\x1c\xd70\xb8n\xd52\xa5\xdf\x8b~\x96V" + - "\x94\xd4\x9aQ\xeb]7\xa5\xd9\x8efT\xc6|z\xa1" + - "h\xeaZi\xba\x88\xa8\xb4Q\xa0K]\xbd\x00\x88\xd2" + - "\xb5[\x01P\x90\xa4~\x80\x82V1L\x8b{e\xcd" + - ".\x99\x86\xc1\x81\x95\x9c\x83;U]5J<~\xa8" + - "i\xeeC\x83\\\xd7\xcd\xdbMK/o\xb6\xb4\x8af" + - "\x0c\x98\xc6\x84V\x01(\"\xc6\xc7\xc4\xb9\xc7\x06t\x8d" + - "\x1b\xce(\xb7\xf6j%\xbe\xc2\xb5yp\xce\xb5TG" + - "3\x8d\x1bF\xb8\xed\xea\x8e\x0d\xa0dX\x06 \x83\x00" + - "R\xb6\x17@ia\xa8\xe4\x05,X>\x03\xb6'\x99" + - "\x07\x88\xed\x90\xbc\xd9<\xf7\xcd\xc0\x16\xf4&\xb7V\xb8" + - "\x86\xc5+\x9a\xedp+ \xdfP(\xaa\x96Z\xb5\xd3" + - "\x0f\x9e\x04P\xda\x19*K\x04\xf4*\x96Z\xe2En" + - "\xa1f\x967\xa9\x869\xcax\x09\x9b@\xc0\xa6\xd4\xa3" + - "\x0d\x1c\xb1^\xd5t^\x0e\xb4[Q\xea\xf6\xffW\xda" + - "Y\xa6\xcd\xf3\xfcG\xd4\xad\x00\xca\x0e\x86\x8a.`\x16" + - "?\xf7\xf2T\xfe$m?\x802\xc9Pq\x04\xcc\x0a" + - "\x97\xbd\xbc\xef\xb5=K\x01\x14\x9d\xa12%`\x96\xfd" + - "\xce\xcbS\x91\x91\xdc]\x00\x8a\xc3P\xb9[@\xcfv" + - "kdS\x1b\x98ia{\x12\xca\xa1ux\xb9B\x96" + - "6\xa0\xc0Kdhl\x8f\xd09`\x10\xcb\xe6$\xb6" + - "'\xc5'\xfd~\xa2\x7f\x9f\xe8\xad\x1dy" + - "l\x05\x90\x8f\xe1!\x80\xd1\xa3D?E\xf4\x05\x98\xc7" + - "\x05\x00\xf2\x09<\x090z\x8a\xe8O\x12}as\x1e" + - "\x17\x02\xc8g|y\x1e#\xfaY\x8c!h\xa8\x9cF" + - "B\x0a'-\xe9\x02\x98i\xc7a\xc8\xc3I\x03\x03\x98" + - ".\x9a9\x1a50\x97\xec\x90\x001\x07\xe8\xd5LS" + - "\xdf4\x1ba\xaf\xd4\x88\x84a\x019\xd3\x18*\xc7\xf9" + - "\x15\x04\xd1\x06\x13\xbaK\xaa>T\x8b%\xd1\xec>\xd7" + - "1\xdd\x1at\x97U\x87\x97\xe3\x1ai\xb9\xc6z\xcb\xac" + - "\x8e!\xb7\xaa\x9a\xa1\xea\x10\x7f\x99/\xb6r\xae\xab\x95" + - "\xbf4\x9e\xad\x08PKiI:\xfbeT\x9d\xbe\xc6" + - "P\xf9\xfdtg\x7f+A\xed\xcd\x0c\x95\xdb\xa8[\x9f" + - "\xb6\x1d^\xdd\xa4\x02Kr\xa4\xbbb\x99nm\xce\xc3" + - "B\xfd\xc3\xdd\xb5\xde1\xd5O\xeb\x968\xad\x97Q\x07" + - "u\x03C\xe5\x96\x14\xea-_\x99\xc8\x91Kgc " + - "\xf2\x9c\x97\x1atp\xe3uU,\xe8\xda\x83\xd2\x92z" + - "\xbd?y=~\xdc\x0a\xd5\x1d\x14\xf0\xa0\xed\x96Jd" + - "\xed\xc8\xfc\x13\xe1l\x04\xddtw*\x10\xe2\xb5E\x18" + - "\x08_\xb6c\xa8p'\xf85dL\x98TjE\xb5" + - "j\xff\x1fO\x8fp;G\xa3\xc9\x15'\xd0x\x11q" + - "\xe5\xd2<86VL\xc6d\x16\xa0r\x1a\x90F\xd2" + - "\x80\x94\xe0\xd1\xae4\xeeD\x1d\xa4\xac\xf8\x00P$\xfa" + - "6L\xe6\x0b\xf9N<=\x0bx2}\x01 q\xff" + - "\xfa2\xd1k> a\x00HU\xff~\x9d\xe8Si" + - "@rqf6 \xb1\x08\x90\x08H\x0e\x13\xfd\xa8\x0f" + - "H\x99\x00\x90\x8e\xe0\xb3\xb3\x80\xa7\xb5)\x00\xa4\x13\xf8" + - "\xfc,\xe0Y\xd0\x1c\x00\xd2\x19\x9f\xffI\xa2\x9f\xf7\x01" + - "\xa9?\x00\xa4s>\x80=C\xf4\x17\x08\x90\\K\x1f" + - "u,\xcd\x00\xac$\xc1Z\xaa}\x8b\xf3Z\x1f\xe4t" + - "m/\x8f\x8bEYS\xf5\xb5\xae\xaaC\xf7\xa8\xa3\x96" + - "v'm\xb2n\x0f\xaaF\xd9\xc6Iu7\xa7\x12#" + - "\xa6\x8b\xb0\xa3\xdb[\xb8\xa5M\x00&\x8du\xdc\xd6\xe4" + - "\x8a\xa6Y\xdf\xed\xf8\xfd\x19\xb7\x024\x8b\xbfU\xd5\xa9" + - "\xa1\xb2\xce\x070jM\x98\x91\x948\x8d\xbe\x98\x86\x81" + - "A\xbf0\xa6u\xcfn\x04ja\xab\x1e5\x14c\x85" + - "\xbaN\x81O\xd5x\xc9\x190\xd1p4\xc3\xe5s." + - "(M\xba\xc6n^^\x87F\xc9,kF\x05\xe6\xcc" + - "\x08\xec\x8b\xb6\x13\xa9\x0e\xaa%l\xc9\xe2u\xbb\xb4\x8c" + - "\xfa\x01\x0c\xfb\x01\xa97\x99\xb2\x0b%\xffT\xc1\xe2\xaa" + - "\x9d\x94\x86\xf9^\x0b\x97QA\x92\xd1k\xed\xac\x09 " + - "^^c\xb4\xf3\x93\xf6\xec\x07A\xd2DLV\xa5\x18" + - "mF\xa5\xed\x16\x08\xd2\xb8\x88B\xfc7\x03\x8c\xf6\xfd" + - "\xd2\xd0\x0c\x08\xd2:\x11Y\xbc\xe8\xc7h\xe3&\xad\xee" + - "\x07AZ.z\xd1T\x01\x85@\x9c5\xe8E\x89\x0f" + - "\xdd~\xea\xafA/\xdaS`4}\x00\xac\xc1\x83a" + - "=Z\x83\xe9\xe5\x16\xfb\xa2\x11\xa0q_J\x189\xc5" + - "P9\x9c`\xe4=\xd4\xab\x1ef\xa8\x1cM\x8d]G" + - "\x9eN\xb7\xa5\xe1\xe6\xe0\xc4\xa1p\xefp>\xb598" + - "G\xbd\xeay\x86\xca\xebBR\xa8\xa3\xb0\x8b\xf6Ah" + - "Z\xd1\x1c8\xcfZ(\x0c\xce\xb0e\xac_\x0eye" + - "s\xd2o)1\xb8\xca\x86\x04\xb1\xd3\x1b\xa3E\xa9\x8d" + - "\x11F\x13\xa88\x0b\xe0\xd3\xfb\xa3E\xf3c\xe6\xacy" + - "*\x1c\x1b(j\xa2\xbfh`\xf4\xb7%I\"\xefg" + - "E/\x9a\xb90*W\xe4\xbc\xb4\xcb\xaer\xf0\x1c\xe1" + - "\xdd\xf6\x97\xa9\x04\xd1\x96\xf9\xca\xfb\x83\xe0\x9d\x1c\x05[" + - "<\x07\x05\xf7\xeeJm\xb1t3\x1c\xe1r\x9bRU" + - "{>[\x05\x02G\x9do\x8e\x0e\xd7\x85\xdf\xd2$\xfc" + - "\xe2\x06\xe1\x9e\xa5\xc90\x10\x8fE\xf7\x0e\x87A\xf9X" + - "\xdc\xe9J\x8f\xce$\x1b\xae8\xfc\x9e\x1aN\xc6\"\x91" + - "[V$\xa7\xe8Z\x09l\xeafe\x83fp\x9bz" + - "\xbf\xbam@\x8d[U\xd5\xe0\x06:\x04F\xaeE\x88" + - ":\x1b\xb9\x86\xd6\xa6Z\xc6\xf9\xd4\x1f\x0d\x83=\x88\xf5" + - "\xb0\xbc\xa6F\xdf\xd3\xa95L\xa4\xbc\xf2|\xb8\xde\xd8" + - "\x91R~;\x8d\xbe\xdb\x18*\x93\x02z\xaa\xeb\x98\xe3" + - "\xb5\xb2\x8a\x0e_o\xf1=.\x17\x8d\xd2t2\xc0\xd1" + - "(S\xb2\xc7\xb1FM\xe7z\x8b\x17\xf6\xb8<\xcd\x10" + - "-\x8eA\xd4\xcc\xf2\x9c\x8dq\x83f\xebv\xbes\xd4" + - ",\xed\xe6\xce\xac\x85z\x00\x97\x91*\xeaH\xb25\x8e" + - "4\xd1FR\xb3Z\x04#{(\xa0j\x0c\x95\x03)" + - "\x18\x99\x9eI\x1c\xde\xb8\xba\xfe\xff\x14\xc4y\x94l\xb8" + - "\xd5\x1d)\xf0/\x95h\xc9_I\xae\xdcr\x85{\x82" + - "\xb0c\xadkX\x976j\x97\xb7&\x0d\xba\x1f\xcf\xed" + - "\xc9_n\xc3\xe7\xec\xb0K\x046a\xcem\x00\xff7" + - "\x00\x00\xff\xff\xfd\xa0l\x0d" +const schema_db8274f9144abc7e = "x\xda\xacY}l]\xe5y\x7f\x9e\xf3^\xfb\xd8\x89" + + "o\xae\x0f\xe7\"b\x13\xcbU\x04jCI\x06\xf1\xb2" + + "\x11o\xeb\x8d\xed$\xb5\xdd|\xdc\xe3\x8f\x00!\x91r" + + "r\xef\xeb\xeb\xe3\x9c{\xce\xcd\xf9\x08v\x946\x90\x85" + + "\x01\x1e)\x09m&\x92\x86\x0a\xb2f|(]\x09\x0d" + + "\xda\xca\xa0*\xd3\x18d\xad\x04h0\xc1\xc6\xfeX!" + + "\x9a@\x8b\x18\xb4\x12\xa2*\x9c\xe99\xdf\xbe\xbeu\xc2" + + "\xd4\x7f\x92\xab\xe7<\xef\xfb>\x9f\xbf\xe7\xc37e[" + + "\xd7\x0977\x99Y\x00\xe5TS\xb3\xf7\xa7\xd5WO" + + "\xff\xd1\xf1\x9f\x1f\x06\xa9S\xf0\xbe\xf5\xfcp\xfeS\xe7" + + "\xd0\x7f\x00`\xcf#\xcd\xfbQ>\xd7,\x02\xc8?l" + + "\xde\x0a\xe8\xfd\xebM\x07\xde\xdb\xf5\xabc\xf7\x81\xd4\x89" + + "\x09gF\x04\xe8y\xa9y\x16\xe5\xffl\x16\x81y\x8f" + + "\xdc\x91\xff\x17|\xf4\x93c }\x05\x01\x9a\x90>\xff" + + "\xa4y\x91\x00(\xbf\xde\\\x00\xf4^\xbd\xf1\xf9\xe7\x8e" + + "\xfe\xf8\xde\xef\x81\xf2eD\x08\xce\x7f\xd4\xfc\x1b\x04\x94" + + "\x9bDb\xf8\xe8\x07_\xcd\xfc\xf0\xd5\xab\xbe\xef3x" + + "g^\xbf\xf5\x99\xa3?\xfe\xd2\x070.\x88\x98\x01\xe8" + + "Y)Z\xc4\xbbV\xfco@\xef\xbbo\xbd\xb0\xa5z" + + "\xec\xe4i\x90\xbe\x1c\xdd\xd5\xd1\"\x08\x90\xf1\xd6\xfc\xfb" + + "\xc5\xad\x9b\x9f\x99x<\xf8\x12\xc8\x91my\x86\x8ev" + + "\xb5\xd03\xaf\xdc\xd9\xfe@\xdf\x1f?\xf88(\x9d\x98" + + "\xd2\xa7\xa9\x898\xfbZfQ\xbe\xbd\x85~\x8e\xb7\xdc" + + "\x8a\x80\xde\xec\xda\x17\xb6\xfd\xea/\xec\xa7@Y\x89\x19" + + "\xef\x9f\xee\x7fw\xdf\x8a''^\xf6\xa5b\x00=\x17" + + "ZO\xd3\xd5o\xb7\xfe\x08\xd0\xcb\xfe\xc3\x0d[\x1e|" + + "o\xd39\xba:e\xd4@\x88\x99E\xbd(\xdf\xbf\x88" + + "\xecz\xcf\"\xe2~\xed\xc6m?\xfd\xe9\xd3\x95s\xf5" + + "\x82\x08\xc4}\xfd\xe2a\x94\xd7.&\xee5\x8b\x89\xfb" + + "\xea!|\xe7g7g\xfe.\xd4\x8b\x11\xd3\xfb\x8b?" + + "\xa0\xc7?\xf3\x19\xee\xf8\xed\xb3\xff\xb8\xe1\xc37~\x92" + + "v\xc0#m\x029\xe0\\\x1b)\xdeu\xa9?k|" + + "x\xe8gs\xfd\x18\xdc\xf4v\xdb0\xca\x97\xda\xe8\xb9" + + "\xf7\xdb\xe8\xb6\xbfr\xdfz\xc3\x1c\x1e~\xa9^8\xff" + + "\xda{\xb2\x02\xca\xc7\xb2\xc4}$[\x00\xfc\xe4\xa9{" + + "\x8f\x0e\xbd\xbb\xfee\xa5\x133\xf5\xbc\xc7\xb2\xfbQ>" + + "C\xbc=\x8fe\xbb\xc9\xa2\xb1\x0d\xeb\xd8}\xbd__" + + "2\x85\xf2\xc5%\xf4\xf3\xbf\x96\xf8\xec\xc3w|\xe7\xa1" + + "\xa6\x8b\xdfy\xb9\xde\xa8\xa2o\x81\x9c\x85\xf2g9\xfa" + + "\xf9i\xeeq\x01\xd0\xfb\xcd\xd9?\xe7\x17W\xbdr\x01" + + "\x94/aJ\x8dq\x14Q\x00\xe8\xb9x\xd5j2\xd9" + + "\xa5\xab\xee\x04\xf4:\x9f\xfe\x93\xbf\xed/\xbf\xfd\xf3:" + + "\x8b\x90 \xf2f\xf9c\xf9v\x99~\x8d\xcb\xc4{\xef" + + "Wg\xf6o\xb9~\xf6\xcd\x86\x069'\xcf\xa2|\xc1" + + "\xe7~\xc9\xe7\x16.\xaa\x1dw\xfd\xdb\xd7\xdeI\xc5\xe7" + + "\x9a\xfc/\x112\xde\x96mwL\xb5~\xf3\xddw\xd3" + + "\xf1\xb9\"\xef\xfb\xf1\xcf\xf2\xe4\xa6\xf3\xd2C\xf2\xf3\x8f" + + "\xfd\xcd{\xf4\x90X\xef\xa7\x9d\xf9\xed(\xef\xcd\xd3\xcf" + + "j\xde\xd77\xce\x93FQ\xa4]\xd3\x8b\xf2\xcc5$" + + "\x97{\x0d\xc9\xb5fW\x1f\xdfq\xcbm\x1f\x80\xd4\xc9" + + "\xe6d\xfd\xb3\xc4\xf9\x12q\xf6\xbcx\x8d\x88\xf2\xde\xa5" + + "\"\x80\xf7\xed\xca\xf6\x0b\x1f\x0d<\xf6\xbf\xf5\x97\xfb\x0a" + + "\xdd\xbe\xb4\x17e\x8d\xf8z\xf8R\xdfU=7\xff\xe5" + + "\xa5\xe3\x7f=\xf0\xd1\xbc\xdb\xcfu\xf4\xa3\xfcb\x07\xc9" + + "\xf1B\xc7\xd7\xe5K\x1d\xfe\xe5\xdfZ\xbfu\xed\xf2\x17" + + "?N[\xe2\xcd\x8e\x8f\xc9\x12\xefw\x90%&n\xf9" + + "\x9f\xaf_\xff\xed\x7f\xfe\xb8\xce=>ck\xe7\x0d(" + + "wt\xd2\x8dWw\x16\x00?\xdc\xf8\xfd7:s\x9d" + + "\xbfn$\xe8\xda\xce)\x947\x13o\xcfP\xa7/\xe8" + + "m\xbf\x03\xb6'\x99\x07" + + "\x88\xed\x90\xbc\xd9<\xff\xcd\xc0\x16\xf4&\xb7V\xb9\x86" + + "\xc5+\x9a\xedp+ _W(\xaa\x96Z\xb5\xd3\x0f" + + "\x9e\x04P\xda\x19*\xcb\x04\xf4*\x96Z\xe2En\xa1" + + "f\x96\xb7\xa8\x869\xcax\x09\x9b@\xc0\xa6\xd4\xa3\x0d" + + "\x1c\xb1Q\xd5t^\x0e\xb4[U\xea\xf6\xffW\xdaY" + + "\xa6\xcd\xf3\xfcG\xd4\xed\x00\xca.\x86\x8a.`\x16?" + + "\xf7\xf2T\xfe$m?\x802\xc9Pq\x04\xcc\x0a\x9f" + + "yy\xdfk{\x97\x03(:CeZ\xc0,\xfb\xad" + + "\x97\xa7\"#\xb9S\x00\x8a\xc3P\xb9K@\xcfvk" + + "dS\x1b\x98ia{\x12\xca\xa1ux\xb9B\x966" + + "\xa0\xc0Kdhl\x8f\xd09`\x10\xcb\xe6$\xb6'" + + "\xc5'\xb5\xf0y?" + + "4K\xceu\xc5\xeey\xce\";\xb61T\x96\x0a\xe8" + + "\xd5\xe8+w80\xcb\xc6\xf6\xa4\xa8\xd7I\xdb \x9c" + + "\x07\xe8\xdf\x81\xe0\x95bx\x8be\xfb\xe1\xac,\x8d\x1f" + + ";A\x8f=\xccP\xf9\x81\x80\x12b\xe0\xb3\xc7,\x00" + + "\xe5Q\x86\xcaY\x01Q\x08<\xf6\xe4i\x00\xe5,C" + + "\xe5\xef\x05\x94\x98\x108\xec\xd9\x1b\x00\x94\xa7\x19*\xbf" + + "\x10P\xca\xb0<50\xd2\x05\x0a\xb6_0T\xde\x12" + + "Pj\xca\xe4\xb1\x09@zs5\x80\xf2\x1aC\xe5\x1d" + + "\x01=3\xc8/R\xca\xc1,\x08\x98\x05\xf4J\xba\xe9" + + "\x96't\x15\xba-^\x1eZ\x1f\xd3\x0d\xb7Z\xb4\xf8" + + ">\x0dM\xd7\xees\x1c^\x15k\x8e\x8d\xcd `3" + + "`\xceQ+6.\x01,2\xc4\xf6\xa4\xd0\x01\x121" + + "\xbe\x13-^\xde\xc6-[c\xa6\x81m `\x1b`" + + "\xb7]2k\x1c\xdb\x93\xdayy\x9b\x8e\x84\xd1C\xb1" + + "\x13&\x82iibE3\x946\x96Y\xe6y\xa1\x01" + + "7\x90]\xd61T6\x09\xd8\x85\x9f\x13\x99l84" + + "\x02\xa0\x0c2T\xc6\x04\xec\x12>#2YQ!\x1f" + + "\x14\x19*;\x04\xccM:N\x0d\xdb\x93\xea\x18\x0au" + + "'\xdfm\x9b\xa5=\x1c\x90\xa0\"\x86\xea\xf0\xebd\x08" + + "]\xc0\xf42\xb6'\x9dl\x9dF\xacA\x94\xf8\x01R" + + "p6X\x96i\xf9\xa8\x1a\x87\xc6\x86\xd5\x89\x12Qd" + + "\x0cmO4\x90\x84u\x81Z\xca\xeeD\xfe\xee\x92\xea" + + "\xda<\xb2\xb1gq\xc7\x9a\xe9\x9bp\x80q+\xc6\x18" + + "{\xd2t\xf5\xf2\x08\x07\xd1\xb1f\x10A@\\\x18y" + + "\xd6\x9b\x83)\x93\x07!\x9c\x92\x93dZ\xcfP)&" + + "rn&\xda&\x86\xcam$gh\xfeq2\xff\x18" + + "C\xa5&\xa0\xa7S\xee\x1a\x83&0\xdb\x89\xc5\x0d\x88" + + "E\xd3\x0fL\x11\x04\x14\x01=\xb7f;\x16W\xab\x80" + + "q\xa4\x11\xff\x92/\x00\xd1uPQTs~\xce7" + + "\xd6!N\xc3\xcd\xc3i%\xc2<\x1c\xefO\x8c\xdd8" + + "\x91&M\xdb1\xd4*\x07\x80H\xb1\x83f\x8d0\x92" + + "\x10$n3\xebb\xe3\x8bW\xb6\xa0\xca\xcc\xa9k\xa7" + + "Se\xa6\x14\x9eF\xff\xf8\x80i\x88\x13Z\x05\xdb\x93" + + "^\xabN\x80\x06~\xefs\x9dIn8Z\xc9\x7fp" + + "\x9e\xdf\x97'\xf1\x19\xdblhu\xca\x90\x91\xcd6\xef" + + "N\x0c)\xee\xe131\x04\xf0\xaa\xaa\xe9\xb1\xf7Ck" + + "\xf6\x81\xf8\x8d\x84g\xa1\xe4\x19%\x04\xf1\xa5\xf2m\x80" + + "\xa9\xae\\\xca\xae\x06\xa1{\x9f\xaa\xbb|\xc1\xe6&\xac" + + "bA\x0d+\x04\x06\xa6\x0b\xf3\xb1\x9a\xdf\x9c\x05P\xee" + + "b\xa8<\x90R\xf3\xfe\x87\x00\x94\x07\x18*\x0f\xa7\xd4" + + "\xff\x13D?\xef\x03R" + + "\x7f\x00H\xe7|\x00{\x9a\xe8\xcf\x13 \xb9\x96>\xea" + + "X\x9a\x01XI\x82\xb5T\xfb\x06\xe7\xb5>\xc8\xe9\xda" + + ">\x1e\x17\x8b\xb2\xa6\xea\xeb]U\x87\xeeQG-\xed" + + "I\xdad\xdd\x1eT\x8d\xb2\x8d\x93\xea\x1eN%FL" + + "\x17aG\xb7\xb7qK\x9b\x00L\x1a\xeb\xb8\xad\xc9\x15" + + "M\xb3\xbe\xdb\xf1\xfb3n\x05h\x16\x7f\xab\xaa\xd3C" + + "e\x9d\x0f`\xd4\x9a0#)q\x1a}1\x0d\x03\x83" + + "~aL\xeb\x9e\xdb\x08\xd4\xc2V=j(\xc6\x0au" + + "\x9d\x02\x9f\xae\xf1\x923`\xa2\xe1h\x86\xcb\xe7]P" + + "\x9at\x8d=\xbc\xbc\x01\x8d\x92Y\xd6\x8c\x0a\xcc\x9b\x11" + + "\xd8\xef\xdaN\xa4:\xa8\x96\xb0%\x8b\xd7\xed\xd2\x0a\xea" + + "\x070\xec\x07\xa4\xded\xca.\x94\xfcS\x05\x8b\xabv" + + "R\x1a\x16z-\\F\x05IF\xaf\xb5\xb3&\x80x" + + "y\x8d\xd1\xceO\xda\xbb\x1f\x04I\x131Y\x95b\xb4" + + "\x19\x95vZ H\xe3\"\x0a\xf1\xdf\x0c0\xda\xf7K" + + "C\xb3 H\x1bDd\xf1\xa2\x1f\xa3\x8d\x9b\xb4\xb6\x1f" + + "\x04i\xa5\xe8ES\x05\x14\x02q\xd6\xa1\x17%>t" + + "\xfb\xa9\xbf\x0e\xbdhO\x81\xd1\xf4\x01\xb0\x0e\x0f\x86\xf5" + + "h\x1d\xa6\x97[\xecw\x8d\x00\x8d\xfbR\xc2\xc8i\x86" + + "\xca\xe1\x04#\xef\xa6^\xf50C\xe5hj\xec:\xf2" + + "T\xba-\x0d7\x07'\x0e\x85{\x87\xf3\xa9\xcd\xc19" + + "\xeaU\xcf3T^\x13\x92B\x1d\x85]\xb4\x0fB\xd3" + + "\x8a\xe6\xc0\x05\xd6Bap\x86-c\xfdr\xc8+\x9b" + + "\x93~K\x89\xc1U6$\x88\x9d\xde\x18-Im\x8c" + + "0\x9a@\xc59\x00\x9f\xde\x1f-Y\x183\xe7\xccS" + + "\xe1\xd8@Q\x13\xfdE\x03\xa3\xbf-I\x12y?+" + + "z\xd1\xcc\x85Q\xb9\"\xe7\xa5]\xf6\x05\x07\xcf\x11\xde" + + "m_I%\x88\xb6\xcc\x97\xdf\x1f\x04\xef\xe4(\xd8\xe2" + + "9(\xb8w*\xb5\xc5\xd2\xcdp\x84\xcbmIU\xed" + + "\x85l\x15\x08\x1cu\xbe9:\\\x17~\xcb\x93\xf0\x8b" + + "\x1b\x84\xbb\x97'\xc3@<\x16\xdd3\x1c\x06\xe5\xa3q" + + "\xa7+=2\x9bl\xb8\xe2\xf0{r8\x19\x8bDn" + + "Y\x91\x9c\xa2k%\xb0\xa9\x9b\x95M\x9a\xc1m\xea\xfd" + + "\xea\xb6\x015nUU\x83\x1b\xe8\x10\x18\xb9\x16!\xea" + + "\\\xe4\x1aZ\x9fj\x19\x17R\x7f4\x0c\xf6 \xd6\xc3" + + "\xf2\x9a\x1a}O\xa7\xd60\x91\xf2\xcas\xe1zcW" + + "J\xf9\x9d4\xfa\xee`\xa8L\x0a\xe8\xa9\xaec\x8e\xd7" + + "\xca*:|\xa3\xc5\xf7\xba\\4J3\xc9\x00G\xa3" + + "L\xc9\x1e\xc7\x1a5\x9d\x1b-^\xd8\xeb\xf24C\xb4" + + "8\x06Q3\xcb\xf36\xc6\x0d\x9a\xad[\xf9\xeeQ\xb3" + + "\xb4\x87;s\x16\xea\x01\\F\xaa\xa8#\xc9\xd68\xd2" + + "D\x1bI\xcdj\x11\x8c\xec\xa5\x80\xaa1T\x0e\xa4`" + + "df6qx\xe3\xea\xfa\xfb)\x88\x0b(\xd9p\xab" + + ";R\xe0W\x94h\xc9_I.\xdfr\x85{\x82\xb0" + + "c\xbd\x92]\xc8\x9ce]\x18\x10\xcaT\xb2?\xf2\x83" + + "\xbc=\xf9sn(\x83\x1d\xb6\x8e\xc0&\xcc\x06]a" + + "0U\x0d\x98\x10Bk\xfdF\xe7\xff\x02\x00\x00\xff\xff" + + "\xd4\xcdz3" func init() { schemas.Register(schema_db8274f9144abc7e,