TUN-2755: ReconnectTunnel RPC now transmits ConnectionDigest

This commit is contained in:
Adam Chalmers 2020-03-06 14:48:16 -06:00
parent d50fee4fa0
commit 1b2a96f96b
7 changed files with 310 additions and 268 deletions

View File

@ -984,6 +984,12 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
EnvVars: []string{"TUNNEL_USE_RECONNECT_TOKEN"},
Hidden: true,
}),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "use-quick-reconnects",
Usage: "Test reestablishing connections with the new 'connection digest' flow.",
EnvVars: []string{"TUNNEL_USE_QUICK_RECONNECTS"},
Hidden: true,
}),
altsrc.NewDurationFlag(&cli.DurationFlag{
Name: "dial-edge-timeout",
Usage: "Maximum wait time to set up a connection with the edge",

View File

@ -276,6 +276,7 @@ func prepareTunnelConfig(
TransportLogger: transportLogger,
UseDeclarativeTunnel: c.Bool("use-declarative-tunnels"),
UseReconnectToken: c.Bool("use-reconnect-token"),
UseQuickReconnects: c.Bool("use-quick-reconnects"),
}, nil
}

View File

@ -85,6 +85,8 @@ type TunnelConfig struct {
// feature-flag to use new edge reconnect tokens
UseReconnectToken bool
// feature-flag for using ConnectionDigest
UseQuickReconnects bool
}
// ReconnectTunnelCredentialManager is invoked by functions in this file to
@ -280,7 +282,15 @@ func ServeTunnel(
eventDigest, eventDigestErr := credentialManager.EventDigest()
// if we have both credentials, we can reconnect
if tokenErr == nil && eventDigestErr == nil {
return ReconnectTunnel(serveCtx, token, eventDigest, handler.muxer, config, logger, connectionID, originLocalIP, u)
var connDigest []byte
// check if we can use Quick Reconnects
if config.UseQuickReconnects {
if digest, connDigestErr := credentialManager.ConnDigest(); connDigestErr == nil {
connDigest = digest
}
}
return ReconnectTunnel(serveCtx, token, eventDigest, connDigest, handler.muxer, config, logger, connectionID, originLocalIP, u)
}
// log errors and proceed to RegisterTunnel
if tokenErr != nil {
@ -389,7 +399,7 @@ func RegisterTunnel(
func ReconnectTunnel(
ctx context.Context,
token []byte,
eventDigest []byte,
eventDigest, connDigest []byte,
muxer *h2mux.Muxer,
config *TunnelConfig,
logger *log.Entry,
@ -413,6 +423,7 @@ func ReconnectTunnel(
ctx,
token,
eventDigest,
connDigest,
config.Hostname,
config.RegistrationOptions(connectionID, originLocalIP, uuid),
)

View File

@ -16,6 +16,10 @@ func (i TunnelServer_PogsImpl) ReconnectTunnel(p tunnelrpc.TunnelServer_reconnec
if err != nil {
return err
}
connDigest, err := p.Params.ConnDigest()
if err != nil {
return err
}
hostname, err := p.Params.Hostname()
if err != nil {
return err
@ -29,7 +33,7 @@ func (i TunnelServer_PogsImpl) ReconnectTunnel(p tunnelrpc.TunnelServer_reconnec
return err
}
server.Ack(p.Options)
registration, err := i.impl.ReconnectTunnel(p.Ctx, jwt, eventDigest, hostname, pogsOptions)
registration, err := i.impl.ReconnectTunnel(p.Ctx, jwt, eventDigest, connDigest, hostname, pogsOptions)
if err != nil {
return err
}
@ -44,6 +48,7 @@ func (c TunnelServer_PogsClient) ReconnectTunnel(
ctx context.Context,
jwt,
eventDigest []byte,
connDigest []byte,
hostname string,
options *RegistrationOptions,
) *TunnelRegistration {
@ -57,6 +62,10 @@ func (c TunnelServer_PogsClient) ReconnectTunnel(
if err != nil {
return err
}
err = p.SetConnDigest(connDigest)
if err != nil {
return err
}
err = p.SetHostname(hostname)
if err != nil {
return err

View File

@ -437,7 +437,7 @@ type TunnelServer interface {
UnregisterTunnel(ctx context.Context, gracePeriodNanoSec int64) error
Connect(ctx context.Context, parameters *ConnectParameters) (ConnectResult, error)
Authenticate(ctx context.Context, originCert []byte, hostname string, options *RegistrationOptions) (*AuthenticateResponse, error)
ReconnectTunnel(ctx context.Context, jwt, eventDigest []byte, hostname string, options *RegistrationOptions) (*TunnelRegistration, error)
ReconnectTunnel(ctx context.Context, jwt, eventDigest, connDigest []byte, hostname string, options *RegistrationOptions) (*TunnelRegistration, error)
}
func TunnelServer_ServerToClient(s TunnelServer) tunnelrpc.TunnelServer {

View File

@ -297,7 +297,7 @@ interface TunnelServer {
unregisterTunnel @2 (gracePeriodNanoSec :Int64) -> ();
connect @3 (parameters :CapnpConnectParameters) -> (result :ConnectResult);
authenticate @4 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :AuthenticateResponse);
reconnectTunnel @5 (jwt :Data, eventDigest :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
reconnectTunnel @5 (jwt :Data, eventDigest :Data, connDigest :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);
}
interface ClientService {

View File

@ -2929,7 +2929,7 @@ func (c TunnelServer) ReconnectTunnel(ctx context.Context, params func(TunnelSer
Options: capnp.NewCallOptions(opts),
}
if params != nil {
call.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 4}
call.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 5}
call.ParamsFunc = func(s capnp.Struct) error { return params(TunnelServer_reconnectTunnel_Params{Struct: s}) }
}
return TunnelServer_reconnectTunnel_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}
@ -3927,12 +3927,12 @@ type TunnelServer_reconnectTunnel_Params struct{ capnp.Struct }
const TunnelServer_reconnectTunnel_Params_TypeID = 0xa353a3556df74984
func NewTunnelServer_reconnectTunnel_Params(s *capnp.Segment) (TunnelServer_reconnectTunnel_Params, error) {
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 4})
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 5})
return TunnelServer_reconnectTunnel_Params{st}, err
}
func NewRootTunnelServer_reconnectTunnel_Params(s *capnp.Segment) (TunnelServer_reconnectTunnel_Params, error) {
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 4})
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 5})
return TunnelServer_reconnectTunnel_Params{st}, err
}
@ -3974,37 +3974,51 @@ func (s TunnelServer_reconnectTunnel_Params) SetEventDigest(v []byte) error {
return s.Struct.SetData(1, v)
}
func (s TunnelServer_reconnectTunnel_Params) Hostname() (string, error) {
func (s TunnelServer_reconnectTunnel_Params) ConnDigest() ([]byte, error) {
p, err := s.Struct.Ptr(2)
return []byte(p.Data()), err
}
func (s TunnelServer_reconnectTunnel_Params) HasConnDigest() bool {
p, err := s.Struct.Ptr(2)
return p.IsValid() || err != nil
}
func (s TunnelServer_reconnectTunnel_Params) SetConnDigest(v []byte) error {
return s.Struct.SetData(2, v)
}
func (s TunnelServer_reconnectTunnel_Params) Hostname() (string, error) {
p, err := s.Struct.Ptr(3)
return p.Text(), err
}
func (s TunnelServer_reconnectTunnel_Params) HasHostname() bool {
p, err := s.Struct.Ptr(2)
p, err := s.Struct.Ptr(3)
return p.IsValid() || err != nil
}
func (s TunnelServer_reconnectTunnel_Params) HostnameBytes() ([]byte, error) {
p, err := s.Struct.Ptr(2)
p, err := s.Struct.Ptr(3)
return p.TextBytes(), err
}
func (s TunnelServer_reconnectTunnel_Params) SetHostname(v string) error {
return s.Struct.SetText(2, v)
return s.Struct.SetText(3, v)
}
func (s TunnelServer_reconnectTunnel_Params) Options() (RegistrationOptions, error) {
p, err := s.Struct.Ptr(3)
p, err := s.Struct.Ptr(4)
return RegistrationOptions{Struct: p.Struct()}, err
}
func (s TunnelServer_reconnectTunnel_Params) HasOptions() bool {
p, err := s.Struct.Ptr(3)
p, err := s.Struct.Ptr(4)
return p.IsValid() || err != nil
}
func (s TunnelServer_reconnectTunnel_Params) SetOptions(v RegistrationOptions) error {
return s.Struct.SetPtr(3, v.Struct.ToPtr())
return s.Struct.SetPtr(4, v.Struct.ToPtr())
}
// NewOptions sets the options field to a newly
@ -4014,7 +4028,7 @@ func (s TunnelServer_reconnectTunnel_Params) NewOptions() (RegistrationOptions,
if err != nil {
return RegistrationOptions{}, err
}
err = s.Struct.SetPtr(3, ss.Struct.ToPtr())
err = s.Struct.SetPtr(4, ss.Struct.ToPtr())
return ss, err
}
@ -4023,7 +4037,7 @@ type TunnelServer_reconnectTunnel_Params_List struct{ capnp.List }
// NewTunnelServer_reconnectTunnel_Params creates a new list of TunnelServer_reconnectTunnel_Params.
func NewTunnelServer_reconnectTunnel_Params_List(s *capnp.Segment, sz int32) (TunnelServer_reconnectTunnel_Params_List, error) {
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 4}, sz)
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 5}, sz)
return TunnelServer_reconnectTunnel_Params_List{l}, err
}
@ -4049,7 +4063,7 @@ func (p TunnelServer_reconnectTunnel_Params_Promise) Struct() (TunnelServer_reco
}
func (p TunnelServer_reconnectTunnel_Params_Promise) Options() RegistrationOptions_Promise {
return RegistrationOptions_Promise{Pipeline: p.Pipeline.GetPipeline(3)}
return RegistrationOptions_Promise{Pipeline: p.Pipeline.GetPipeline(4)}
}
type TunnelServer_reconnectTunnel_Results struct{ capnp.Struct }
@ -4369,256 +4383,257 @@ func (p ClientService_useConfiguration_Results_Promise) Result() UseConfiguratio
return UseConfigurationResult_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
}
const schema_db8274f9144abc7e = "x\xda\xccZ{\x90Tev?\xe7\xde\x1e\xee\x0c\xcc" +
"\xd0}s\x9br\xa0\x80^^QX!\xe2,\x89;" +
"I\xb6\xe7\xc1\xb03,\x8f\xb9\xd33\xa8#\x9b\xf2N" +
"\xf773w\xe8\xbe\xb7\xb9\x0f`\x08,\x8f\xc2(\x13" +
"X\xd1\x95\x14\xb8h)\xae\xf1\x11\x93\x15\x17+\xabQ" +
"K\x93\xad\xa8Y\x89\xba\x81\x94l\xb4\xa2\x82\x95Zk" +
"-\xc5GY\xa4\xd4\x9b:\xf7==\xc3\x00&\xa9\xda" +
"\x7f\xa0\xeb\xdc\xf3=\xce\xebw\x1e\xdf\\s\xef\xe4&" +
"ni\xd5\x95I\x00\xf9\xf1\xaaI\x0e[\xf4\xab\xad\xf7" +
"-\xf8\xa7\xdd \xcf@t~\xf0\xcc\xca\xf4yk\xf7" +
"\x7f@\x15/\x004\x0c\x0b[Q\xda/\x08\x00\xd2^" +
"\xe1\xbf\x00\x9d\xaa\xdf?\xf5v\xf9ma\x0f\x883\xe2" +
"\xcc\x1c1\x97\xaaW\xa2\xb4\xab\x9a\x98\xb7Wo\x06t" +
"\xfe\xa4\xf4\xea\xd1?<\xf8Kb\xe6\"f\xc0\x86\xf7" +
"\xaa\xb7\xa2t\xde\xe5\xfc\xacz-\xa0\xf3\xc9]\xf5\x7f" +
"s\xff\xbf\xbet\x0b\x88W\"\xf8g\xd7\xd5\xfc\x1a\x01" +
"\xa595?\x05t\xfe\xed\x9amgo\xfe\xe4\x8e\xdb" +
"F\x9f\x9b \xbe\x17jFP:]#\x00\xef\xdcs" +
"S\xfa_\xf0\xbe\xcf\xef\x00\xf1*\xda\x06\xe9\xf3\x935" +
"\x939@\xe9DM\x16\xd0y\xf5\xeag\x9e>\xf0\xb3" +
"[\x7f\x0c\xf2\x95\x88\xe0\xad\xff\xa0\xe6\xbf\xe9\x1c\x9cL" +
"\x0c\xe7~\xf2\xcd\xc4\xdf\xbe\xfa{\xf7\xba\x0c\xce\x83\xaf" +
"_\xff\xc4\x81\x9f}\xe3}\xe8\xe1\x04L\x004,\x9c" +
"l\x10\xef\xb2\xc9\xa4\x8b\xbb\xdexvM\xe9\x8e\xbb\x8f" +
"z\x97v\xf7\x9a6\x85\xe3 \xe1\xec\xe9\xf8\xbc\xd4\xf3" +
"@\xee\x01_\x1c\xf7S\xcd\x94\x8fi\xe9\xac)\xb4t" +
"\xd9\xaf\xdf[\xbb\xfa\x89\xfe\x87|\x06\xf7\xa2\xe7\xa7<" +
"A\x0c5\xb5t\x8f\x976\xa7\xf65\xff\xd1\xed\x0fU" +
"Z\xa5\x8a8\x17\xd7\x8e\xa0\xd4VK?\x9bk\xafG" +
"@g\xe4\xdb\xcf\xae\xfb\xe4/\xccGA^\x8c\x09\xe7" +
"\x17{\xcflZ\xf8H\xff\x8b\xee\xb5y\x80\x86\xa7\xea" +
"~E[\x9f\xa8#U\xd6\xfd\xc3\xa25\xb7\x9f]u" +
"\x8c\xb6\x8e\x99\xc5\xbbDij#J\xdb\xa7\x92e\x86" +
"\xa7\x12\xf7kW\xaf{\xee\xb9\xc7\x07\x8eU^\xc4\xb5" +
"\xf8\xf4\xe4J\x94\x16'\x89{a\x92\xb8\xa7u\xe0\x9b" +
"\xcf/M\xfc}\xdc\x8eo%\xdf\xa7\xc3\xcf\xb9\x0c7" +
"}\xf1\xe4?\xb6}x\xf2\xa9\xb8\x85\xeeHqd\xa1" +
"\x07S$x\xef\x08\x96\xdellz\x0e\xe4\xab\x10\x9d" +
"\xa1\x83\xdb\xac\xf6C\xfb\x1d\xe8A\x019\x80\x86\x13\xa9" +
"\xad\xb4\xd9\xe9\x14\xf9\xd7\xac\x0fZ\xea\xb4\x0fw?_" +
"\xe1\x8c\xee\xa9\xcb\xc4\x95(u\x88t\xb56\xf1\xa7\x80" +
"\x9f?z\xeb\x81\x8e3\xcb_\x94g`\xa2R\xe8w" +
"\xc4\xad(}F\xbc\x0d\xe7\xc4\x0c\xe93\xd4`\x05\xbb" +
"+\xf5\x1ci\x08\xa5e\x12\xfd\\*\xb9\xec+o\xfa" +
"\xd1\x9dU\xef\xfd\xe8\xc5J\x95\x92\x877\xfci\xda@" +
"IN\xd3\xcf\xd5\xe9+x@g\xc6\xe3\x7f\xfcw-" +
"\x85\xd3\xbf\x1c'\x88\xa4\x13W|,\x9d\xbe\x82~\x9d" +
"\xba\x82d<\xb3\xf8\xd8\x9f\xfff\xff\xeb'\xe3\x9e\xb2" +
"\xb4\xde\xf5\xd8\xb6zR\xd8\xad\xdf\x1c\xde\xbaf\xc1\xc8" +
"\xa9J\x03\xb9\x9c\xac~\x04\xa5\xed\xf5\xae9\xebi;" +
"\xee=e\xfa\xce\x7f\xff\xce\x9b1\x9f\xfdM\xfd\xbb\x08" +
"\x09g\xcd\xba\x9b\x86j\xb6\x9f9\x13?\xe8\xadz\xcf" +
"t\xeeA\xc7\xc5;\xa5g\xee\xff\xeb\xb3t\x90P\xa9" +
"nqz/J\x0b\xa6\xbb\xea\x99\xfe\x10\x07\xb1\xd8\x19" +
"\xcfqf\xcdlDi\xf1L\xd7qf\xd2\xbd\x96\xdd" +
"\xdc\xcc\xd6_w\xc3\xfb \xce\xe0GA\x85J\x9c\xc3" +
"\xc4\xd9`\xcf\xbc\x15\xa5\xed\xb3\x04\x00\xe7\x87\x03\xbd/" +
"\x9fk\xbd\xff\xa3\xca\xcd]\x81\xd8\xacF\x94l\xe2k" +
"\xd88\xcb\xb5O\xc3\xd2\xbf\xfc\xe0\xe0\x03\xad\xe7\xc6\xec" +
"\xfe\xec\xec\x16\x94N\xcc\xa6{\xbc<\xfb\xbb\xd2\xf9\xd9" +
"\xee\xe6?X\xbe\xf6\xdbs_\xf88\xae\x89wf\xbb" +
"\xd1\xfb\xd9l\xd2D\xffu\xbf\xfd\xee\x82\x1f\xfe\xf3\xc7" +
"\x15\xf6s\x19\xa7e\x16\xa1\xb4 C;\xce\xc9d\x01" +
"?\\q\xef\xc9\x19\xc9\x19\x9fV\\t\x12\xf1\xb6e" +
"\x86P\xba\x91x\x1bz2/\xd2Eox\xf7\xee\xcd" +
"\xd9\x1f\x7f\xfa9\xc9\xc5W\xe0\\\xc7\x9c^\x94\xbe?" +
"\x87v\xbeq\x0e\xc5\xd2\xaa\xc7N\x7fg\xf0\xe0K\xe7" +
"\xc7E\xee\xaa\xb9\xbbQ\x9a>\x97\xb8\xa7\xcd%\xc8\xf9" +
"+\xe1\xc8\x99\x9d\xff\xf9g_\xc4\xa5\xfar\xee\xbb$" +
"\x958\x8f\xa4\xda\xf6\xe1\xe1\xf6\xdb\xd7?\xf6\xd5(O" +
"\x9b\xf7414\xbb\x0ca0\x8e\xe7i\xca\xbc\x16\x94" +
"6\xce\xa3\xf3J\xf3\xb2\xb0\xd8\xb1lMcE\xa3\x9c" +
"\xc8\xffA\xf03\xbf$\xaf\x94\xb5rc\xb3m\x0d2" +
"\xcdR\xf3\x8a\xc5\xbaX\xd6,\xeb\x9a\xc9:\x11\xe5\x14" +
"\x9f\x00H \x80\xa8\x0c\x01\xc87\xf3(\x179\x14\x11" +
"\xd3\x84\xd6\xa2J\xc4A\x1ee\x8bC\x91\xe3\xd2\x84\x08" +
"\xe2\xc6\xb9\x00r\x91Gy\x0b\x87\xc8\xa7\x09\xefD\xfb" +
"N\x00y\x0b\x8f\xf2\x1e\x0e\x9d23J\x8a\xc64H" +
"Zm\x86\x81\xb5\xc0a-\xa0c0\xcb\x18V\xfa\x8a" +
"\x90d1\xb20\xb4\xd9\xc2:\xe0\xb0\x0e\xd0\x19\xd4m" +
"\xc3\xec\xd1,T\x8b]\xac\xdf`&\x0e\xe2$\xe0p" +
"\x12\xe0D\xe2\xb5\xea\x9a\xc6\xf2V\xce\xce\xe7\x99i\x02" +
"\x90d\xd5\xa1d\x0b\xef\x06\x90\xaf\xe6Q\xbe.&\xd9" +
"2\x92\xec[<\xcaM\x1c:&361c\x95\x8e" +
"y\xc5Rum\x8d\xc2\x97Xx\xed|Qe\x9a\xd5" +
"\xaaCR\xebW\x070\x15\x85\x02 \xa6&\xbeX\xdb" +
"\x16\xd5\xb4Tm\xa0\xdb\xa5g;\xf5\xa2\x9a\x1f\xa6\xdb" +
"\xd5\xba\x9a\x9c\xd5H{\x88\xd3z\x01\x90\x13\xc5\x16\x80" +
"\xac:\xa0\xe9\x06s\x0a\xaa\x99'\xa1\x80\xcf[;\xfa" +
"\x94\xa2\xa2\xe5Yx\xd0\xa4\xb1\x07y\x07\xe4\\9\x96" +
"(1k\xcf\xefT\x0c\x85/\x99rm\xa8\x8f\xb6^" +
"\x00y9\x8frgL\x1f\xabW\x02\xc8\xabx\x94o" +
"\x88Y\xba\xa7\x05@\xee\xe4Q^\xcf\xa1\xa3\x1b\xea\x80" +
"\xaa\xb52\xe0\x8d\xb8\xc1LKSJ\x0c\x00\x02\x85\xed" +
"\xd0\xcb\xa4D\x13S\x11JWh\xaaj\xac\x00\xed\xac" +
"X\xd4\xaf\xd7\x8dba\xadw\x8eN\xdavM\x19." +
"\x13\xc6\xb1\xbck\x1c\x92[\xcd\xb3%\xb6\xc9\xbcu\xb6" +
"\xe1\x1ar~\x173\xed\xa2e\x02\xc8\x89P\xfc\xbaF" +
"\x00\xb9\x9aG9\xcda\xd6p\x190\x15\x81z\xc5U" +
"/\xa6k[3\xd8\x80jZ\xcc\xf0\xc8\xf3\xb3\xa4\xf0" +
"\x92\x19?\x90\xfc/\xc5\xa3<\x93Cg\xc0P\xf2\xac" +
"\x93\x19\xa8\xea\x855\x8a\xa6\xe7x\x96\xc7*\xe0\xb0j" +
"bOZ\xa1\xa8EV\xf0\xa4[\x92\xcf\xb8\xffS\xf4" +
"\xd6:\x8e\x17\xbe\xbdQ\xf8\xd6\xe1W\x8e\x1f\xbf[\xa3" +
"\xf8\xad\xe3\xbet\xc6\x06p\x1d\xff\x85\xe3\x870E\x84" +
"\xc5\xa3\xbc\x93\"\xc2.\x93NM\xe0u\x03S\x11J" +
"\xfa\xdaa\x85\x01\xd2\xb4\x06Y\x96'Ec*\xc8\xf6" +
"\x1e\x83P\xd0\x071\x15\x952\xfe2\x83mb\x86\xc9" +
":!i\xe8[\x861\x15e\xfd\x0a\xadO\xbd\\\xad" +
"\x07\x86\x0eWM\xbc\xde`y\x0f2\xfc\xe5\x9d\x19\xcf" +
"h18$\x1d\xad\xe7Q\x1e\x8c\x05\x09\xeb\x03\x90\x0b" +
"<\xca\xe5X\x90\x94VF\xda\x14\xf9\x00\x0f)r\xca" +
"<\xca\xdb\xb8\xd1\x08\xc761\xcdZ\xae\x0e\x80\xc0\xcc" +
"\xff\x870\x1a%\xa5/c(]\xcc%\xc9[jy" +
"\x94\xeb\x09\xae\xe9+\xb3(\xb0\xe9\xb4\xb0\x10\xbe\xf8i" +
"\xad\xf4\xaf\x0f\xbe\x9d\xfe.\x86\x8f\xbf\xf5\xe1a\x87\xe9" +
"\xb0C<\xca?\x89\xa9\xf2~\x03@\xbe\x8fG\xf91" +
"\x0e\xd1\xd7\xe4#G\x01\xe4\xc7x\x94\x7fN\x9a\xe4<" +
"M>\xb9\x88\xda&\x1e\xe5W8\x14\x13|\x9a\xba\x02" +
"\xf1e\x0a\xa9Wx\x94\xdf\xe0P\xacJ\xa4\xb1\x0a@" +
"<E\xd69\xc9\xa3\xfc\xf6\x85\xd0*_\xd4\xedB\x7f" +
"Q\x81\x8c\xc1\x0a\x1d\xcbC\xbaf\x97:\x0d\xb6IE" +
"\xdd6\x9b-\x8b\x95\x84\xb2e\x06\x89'i)\x03&" +
"N\x05\xec\xe4\x11SQ)\x09H\xc4pO4Xa" +
"\x1d3L\x95\xd7\xb50w\xa8\x9a\xc54k\x95\x02B" +
"\x1f+\x86\xd4\x09\xb0\xa5\xcb\x8f\x10\x8a\x0f?\xd8\xf5\x08" +
"\x0fq\x80`|\xa6\xe3\xf8Jl#\xdd4\xf1(\xaf" +
"\xe2p\x16~Ed\xd2cG\x17\x80\xdc\xce\xa3\xdc\xcd" +
"\xe1,\xeeK\"\x93&\xe5\xde\x08\xcd\x93\x83\x96U\xc6" +
"TTb\xfa\xc6\xde\xcc\xfaL=\xbf\x81\x01\x12(\x86" +
"\xf5\x8e\xffu\xd0\x07i\xe0\x8b\x05LE-b\x85\xa7" +
"\xf0\x17\xca\xd0Y\xaa\x07t\xc3M\x80Q:\xba6\x12" +
"\"\xf0\x8e\x8e\xdeH\x02\x91k\xf2\xc4\x92\xfb\xa2\xfbg" +
"\xf2\x8am\xb2\xd1\xa5Es\xbf\x05<3B45\x07" +
"u\xbbX\xe8b X\xc60\"p\x88\x13c\xecr" +
"\xbd=\xa6x\xcf\x8d\xc7O\x9ba\xd6\xec\x8dgM_" +
"\xfd=\xa4\xfen\x0f%\x9c\"\xa1\x94\xd6\xae\x03oZ" +
"\xe1u=b\xa7\xee:\xa7\x00\x1c\x0a\x80\x8e]6-" +
"\x83)%\xc0\xd0\xdb\x88\x7f\xeae$\xa3\x0aP\xecT" +
"\x92n\xdc\xff.\xa5\xfe\xcb\xcf\xe1^>\x1d\x95\xc1\x8f" +
"\xc6\x12j\xde_\x8d\xee\xf2V]\x13.\xbbJ\xf3\x11" +
"\xcc\xcb!K\xfc\x9a\x80\x0a\xc8 \xb9.\xa4d0\x9f" +
"G\xf9\x9axr]L*\xba\x8aG\xf9[\x1c\x0a\xcc" +
"\xa0<\x19v\xfa\xde\xa1;L\xaf\"\xc5T4\xc6\xb9" +
"\xf8ub\xc5\xba\xaakc\xdcpn\x14.\xa1\x09;" +
"\xae\x8d\xd950\xe1\xea\xbe\xc8\xae\xc2\x066\x1cX)" +
"\xc3J\x8a\x1a\xa1\x91o\xdcf\x10\xbe\x17\xf1LX\xd4" +
"\xfa\xc9\xdfK\xfdY\xcfZt\xc9tx\xc9\xed#\x00" +
"\xf2N\x1e\xe5}\xb1K\xee\xa5\x1ea\x1f\x8f\xf2\xa1\xd8" +
"%\x0f\x92\x12\x0f\xf0(\x1f\x89e\xcf\xc3d\xe0#<" +
"\xca\x0fs\x88\x09\x0f\xf2\x1f$\xc8\x7f\x98G\xf98\xe7" +
"\x02v{s\xab\xae\xa1\x7f\x09\x13 \xec\x13\x06\x99b" +
"X}LA\xabC\xb3\x98\xb1I\xc1b\x00\x09;," +
"\xb5\xc4t\xdb\x0a!\xa2\xa4lq\x0b+,\xb4{\xab" +
"\x04\xc52\xb1\x068\xac\xa1\x884\x99\xd1j\xb0\x02\x92" +
"5\x94b\xa7\xc2[\x83\x97\xa2\xa0\xd1 \x9e\x1cG=" +
"T\x96m\xe3Q\xbe\x8d\xa0\x04c\xd3$\xf1\x96!\xe0" +
"\\$!\x997\xb6\xc4K\x0b\xceKs\xf1V\xcbM" +
"\x88\x93\x00\xc4]\xa4\x9d=<\xca\x07\xb8\xe0j\xed:" +
"d\xbd\x08\xad4\xb5\xdf\xca\xec \xd4TY$\xaf_" +
"/\xa8\xa8k\xdd\xae\xa20\xd2T^/\x95\x0dre" +
"U\xd7d[)\xaa\xbc5\x1c.\x9cP\x17\x04I^" +
"(\xaf-g\\c\x912\xae\x0b\x94!\x0d\xe3J\x80" +
"\xdc\x16\xe41\xb7\x07#w\x91va\x0b@n\x1b\xd1" +
"o\xc3\xc8c\xa4[p\x06@n'\xd1\xf7a\xd8\x81" +
"J{\xf1Q\x80\xdc>\"\x1f\xc2\xa8T\x90\x0e\xba\xdb" +
"\xdfE\xf4\xfb0\xaa\x16\xa4{p\x11@\xee\x10\xd1\x8f" +
"\x13}\x12\xe7jR:\x86C\x00\xb9\xc7\x89\xfe\x0c\xd1" +
"\x85\xaa4\xb5\xdb\xd2Sh\x00\xe4~N\xf4_\x10\xbd" +
"\xba>\x8d\xd5\x00\xd2\x0b.\xfdy\xa2\xbfB\xf4\x9a\xe9" +
"i\xac\x01\x90^\xc6\xdd\x00\xb9\x97\x88~\x92\xe8\x931" +
"\x8d\x93\x01\xa4\xd7\xf1n\x80\xdcI\xa2\xbfM\xf4)\x93" +
"\xd28\x05@z\xcb\xbd\xcf\x1bD?K\xf4\xdaD\x1a" +
"k\x01\xa4w\xf0(@\xee,\xd1?\"z\x9d\x90\xc6" +
":\x00\xe9\x03W\xae\xdf\x12\xbd\x9a\x0bq\xb0\xa3\x10\x87" +
"crC5*Gx\xdd\x0c]\x81\xf9\x9d)z\xb9" +
"\xa2SORk\x8a\xc9h\x84\x0c\x88I@\xa7\xac\xeb" +
"\xc55\xa3a\xfeb\x15\x91\xefF\x90\xd4\xb5\x8eB\x18" +
"\x97\x9e\xf3\xad\xd2!\x93W\x8a\x1d\xe5\xa8F2\x9bm" +
"K\xb7\xcb\x90)(\x16+\x84\x89\xda\xb0\xb5\x15\x86^" +
"\xeaFf\x94TM)B\xf8e\"_L\xda\xb6Z" +
"\x08\xf7\x9e\xb0\xb0s\xfa\x99b\xd9\x063I\xb4\x0bd" +
"\\\xae\xd2\xa33\xe5\xc6ne\xa0b\xc0\xb0(J\x0f" +
"!\xda-\xbe6\xca\x0e\xc9x\x14f6)E\x9b]" +
"J18a\xcb\xd2\x95\xf5Z\x9e\x8bu\xb6\xc18\xec" +
"\xe2\xd5|OE\xe6\xf5\xf2\xe1\x98iJK$l(" +
"\xab\xe1OX\xda\xb9(\xe7\x05\xd6\xea\xf7;W\xc8\xd0" +
"\xde1\xbf\x09\xe7\x95\xbe\xdf\\\xaa&\x06\x98\xe5\xfd\xea" +
"\xd0\xfau*\x0f\x04\xa5d~\xcd\xd5]\xccL^\x8a" +
"\x16\xa3\x09\xe4\xc5\xf3w{wwg4\xc4\xe0=\xf0" +
"\xbf&\xc4\xbbf\xec\x02\xc85Q\xe0\xae\xc2P\x87R" +
"\x87\x8b;\xedD\xee\xc6\xa8\xea\x95d\x17_:\x89\xbe" +
"\x1e\xa3\xbeH\xba\xd1\xc5\x85\xf5D\x1ft\xf1\xae\xd9\xc3" +
";\xe6n_ z\xd9\xc5;\xf4\xf0\xae\xe4\xee_$" +
"\xfa\x968\xde\xd982\x0a~\x05\xde\xc3\xbb].N" +
"\xed!\xfa\x01\x17\xef\x12\x1e\xde\xed\xc7'\x00r\x07\x88" +
"~\xc4\xc5\xbb*\x0f\xef\x0e\xe3\xd3\x00\xb9#D\x7f\xd8" +
"\xc5\xbbI\x1e\xde=\xe8\xf2?\x1c\xe2\xec\x94\x16\x0f\xef" +
"\x8e\xb9\xf8\x18\xe2\xacc\x1b\xc5\x9ce\xa8\x1a\xe0@\x14" +
"\x1b\xf9\xf2\xf7\x18+7C\xb2\xa8nba.*\xa8" +
"Jq\xb9\xad\x14!\x93\xb3\x94\xfc\x86\xa8\xb4/\x9a\xed" +
"\x8aV0qP\xd9\xc0(\x83\x09\xf1\\o\x15\xcdu" +
"\xccP\xfb\x01\xa3f \xac}\x92\x9d\xba^Y\x12\xb9" +
"5%3<\xf0\x0b\xbf\x95\x94-\x1d\x85\"k\xc5\xa0" +
"\x02\xe2\xb5(\x83\xaa\xf4E\xd74\xf4\xca\x92n53" +
"\xba\xde(\xfb\xedEP\xb7tg+\x0a\x12\xb6\xa5\xcc" +
"\xf2V\xab\x8e\x9a\xa5j6\x1b\xb3A~\xd0\xd66\xb0" +
"B\x1bjy\xbd\xa0j\x030\xa6\xaf\xe1/4;\x8a" +
"\x15jn4c\xec\xedM\\\xd8\x08\x9c\x0b]Tv" +
"\x88\x8d\xd1t \x9bwWe\x0d\xa6\x98\xb1\xc6v\x82" +
"\xd3\xfcY\xa7\x17d\xde$\xa0\x0a |\xa8\xc2`\xd8" +
"/\x1e\xdb\x0a\x9c\xf8\x88\x80\xd1\x1b\x09\x06O\"\xe2=" +
"\x06p\xe2A\x01\xb9\xf0\x01\x11\x83\xc7?q\xef\x08p" +
"\xe2-\x02\xf2\xe1\xa3\x1e\x06\x93tq\xb8\x058\xb1$" +
"`\"|\xe0\xc4`\x0c/*TZ\xdd(`U\xf8" +
"Z\x88\xc1[\x8f\xb8z7pb\x9b\xe0\x04\x1d\x14d" +
"=1\x9a\xd0\x09\x00\x032.d4\xa1\x13L\x9f0" +
"\xe8\xb4\x00\x9ap\x87\x0f\xcfM\xe8\x04\xf3WH\xe6\x15" +
"\x8b5Q{\xea}D\x1f\xbc\xa1\x09\xe3sM\xfeB" +
"=\xd1\xf8\xb5uKT\xff\x05\x00\xbck$*\xff\xc2" +
">t\xff\xa3\xf1\xd2\xda\x1f\xa7\x1c\xde\xed\x0fc\x8e\xc7" +
"\xc6)\xc7\xa8\xde>\xce\xa3\xfc\x1a\x17\x15\x0d\x81O\x07" +
"\xa3@\xd4\x8d\xa01\x9e`\"\xe8{\xbe_\xf6V\xce" +
"\x05\x9d\x82>\xe8\x96\xc5\xe8meB\x94\x0e\xe2\xc3\xc2" +
"\xa9\xb1a!\x06-\xb90*{\xc4G\x87S/\xd2" +
"\xdf\xc5\x1bL7\x9d%\\\x97\x0c\x9eF1x\xc5\x16" +
"Er\xad:\xc1\x09\x9aP\x0cr!T\x98\xec2;" +
"\xf1.\x96\xf9\xdf$\xebq\x1c\xc4;'I\x1e\xe9\x09" +
"\x14\xee;\x14\x1b\xed\x15u\xbf\x89L\xae\x89\xf7\x01\x13" +
"\xe8\xca\xbbpP\xb5'i1\xed\xff\x8dp\xff\xd7\xe7" +
"\xc6Fo\x81\xff\x9d\"\xe2k<\xcao\xc6Z\xbb\xd3" +
"+\x01\xe47x\x94?\x8d\xde\x89\xce\x91\xa3~\xcac" +
"W\xacD\x17\xbf$\xc6/\xa8\x90\x8d'\xac*\xbc\x13" +
" WM\x09\"\xed&\xac\x84\x97\xb0D\xec\x03\xc8\xa5" +
"\x88>3^\xa0O\xc7^\x80\\=\xd1\xe7\xa3\xdf\x91" +
"\x07oL\xb6\x11\x81{Q\x1fX\xa5j\xe3V}\xc1" +
"\xc3\x15Z\x04\x99\xb6A\xb8?\x1a_;\x96\xc7\xea\xe0" +
"p\xec\x84\xcc\xc8Q\x88\x17\xd0\x0c\xc79\xe3\x0fz\x09" +
"\x07\x96\xab\x03\xcc\x1d\x07\x05\xc4\x09\xcc\x91\xf3\x83\xcf\x8b" +
"=\xbf\x96\x88\x0d\x03\x8e\xc6\xe6d\x811\xe4\xa7\xfd\xf9" +
"\xd3\xcd1c|\xbf/\x9ag\x13@\xe9=\xe5\x82\x82" +
"\x16[a\xb0\x8d6\x13\xb4\xfcp\xd4\x14S[\x987" +
"{\xb0L\x05\xf9\x0a\x83e7\xda,\xce\x10\xbca\x80" +
"\xa0\xea\x851\x8f\x17\xe3T\x96\xd7\xb3\xbe\x9c\x9e\xdf\xc0" +
"\xacQo;\x15\xef\x8f]\xd1\x03F\xf8\xfc\xd8\x15\x7f" +
"~\xf4am\xe3P4Z\x0famx$\xea\xa8\xc7" +
"/%\xfeo\xb2\xff\xd7z\x82\xa3BZ\xb8\x94\"3" +
"\xfc\xcb\xa0\xaf9\xe8\xbf\xd4\x9e zX\xbe\xcc\xe1\x18" +
"\x84X\x83\xb1?\x1c\xa1C8\x7f\xf3\xff\x09\x00\x00\xff" +
"\xffm\x81\xedW"
const schema_db8274f9144abc7e = "x\xda\xccz}\x90\x14uz\xff\xf3t\xcf\xd2\xbb\xb0" +
"\xcbL\xdbc\xfdv)\xf67\xc7\x8bQ8!\"G" +
"\xa2\x9b\xe4\xf6\x0d\xb8]\x0ea{g\x17u\xe5R\xf6" +
"\xce|w\xb6a\xa6{\xe8\xee\x01\x96\xe0\xf1R\x10e" +
"\x03'x\x90\x02\x0f\xaf\x00\x8f\xf8\x12\xbd\x13\x0f+\xa7" +
"\x11K\x93\xab\xa89\x13\xe5\x82)\xbd\x98\x8a\x11\xa8T" +
"\xac\xb3<\xd1\x94eJ\xed\xd4\xf3\xed\xd7\x1d\x96\x05L" +
"R\x95\x7f`\xea\xe9\xe7\xfb\xf2\xbc}\x9e\x97\xef\xde\xf4" +
"\xe3\xc9m\xc2\x82\x9a\xeb\x93\x00\xeaS5\x93\\6\xf7" +
"\x97\x9b\x8e\\\xf7\xd7\xdbA\x9d\x86\xe8~\xf7\xf9e\xe9" +
"\xcf\x9c\xed\xff\x045\xa2\x04\xb0pD\xda\x84\xca\x1eI" +
"\x02PvI\xff\x06\xe8\xd6\xfc\xd6\x9b\xef\x96\xdf\x95v" +
"\x80<-\xce,\x10s\xa9v\x19*\xdbj\x89\xf9\x9e" +
"\xda\x0d\x80\xee\xef\x97^?\xf6;\x07~A\xccB\xc4" +
"\x0c\xb8\xf0|\xed&T>\xe3\x9c\xffQ\xbb\x12\xd0\xfd" +
"x\x7f\xe3\x9f\x1f\xfd\xfbWv\x82|=\x82\x7fvC" +
"\xdd\xaf\x10P\x99Q\xf7\x13@\xf7\x1fn\xda|\xee\xee" +
"\x8f\xf7\xdd7\xf6\xdc\x04\xf1\xbdT7\x8a\xca\xdbu\x12" +
"\x88\xeeCw\xa5\xff\x16\x8f|\xba\x0f\xe4\x1bh\x1b\xa4" +
"\xcf\xcf\xd4M\x16\x00\x95\xbf\xabk\x05t_\xbf\xf1\xf9" +
"\xe7\xf6\xfe\xf4\xde\x1f\x80z=\"x\xeb?\xa8\xfbO" +
":\x07'\x13\xc3G?\xfaz\xe2\xc9\xd7\xaf\xf9!g" +
"p\x8f\x9f\xbe\xfd\xe9\xbd?\xfd\xda\xfb\xd0/H\x98\x00" +
"X8g\xb2E\xbc\x8b&\x93.\xf6\xbfujEi" +
"\xdf\x83\xc7\xbcK\xf3\xbd\xae\x9d\"\x08\x90pwt\x7f" +
"Z\xea\x7f8\xfb\xb0/N\x0d}\xaa\x9br\x01\x01\x17" +
"6O\xc9 \xa0\xbb\xe8W\xe7W\xde\xf6\xf4\xd0#>" +
"\x07\xbf\xe9\xad\xf5O\xd3\xe6\xdd\xf5t\x91W6\xa4v" +
"\xb7\xff\xee\xfd\x8fT\x9b\x85\xefU\xaa\x1fEeg=" +
"\xfd\xdcV\x7f;\xed7z\xeb\xa9U\x1f\xff\xb1\xfd8" +
"\xa8\xf30\xe1\xfe|\xd7\xd9\xf5s\x1e\x1bz\x99\xdf[" +
"\x04X\xf8Y\xc3/i\xeb\x86\xa9\xa4\xcb\x86\xbf\x9c\xbb" +
"\xe2\xfes\xcbO\xd0\xd61\xbbx\x97xrj\x0b*" +
"\xa7\xa6\x92i\x9e\xe5\xdco\xdc\xb8\xea\x85\x17\x9e*\x9c" +
"\xa8\xbe\x087\xf9\x9d\xc9e\xa8\x94\x92\xc4\xad'\x89\xfb" +
"\xdan|\xe7\xc5\x05\x89\xbf\x88\x1b\xb29\xf5>\x1d\xbe" +
" E\x0cw}\xfe\xcc_-\xf9\xf0\xcc\xb3q\x13\x9d" +
"N\x09d\xa2\xf3)\x12|`\x14K\xef\xb4\xb4\xbd\x00" +
"\xea\x0d\x88\xee\x9a\x03\x9b\x9d\xae\x83{\\\xe8G\x09\x05" +
"\xf2\x0ay\x13m\xd6$\x93\x835\x7f\xd0\xd1`|\xb8" +
"\xfd\xc5*o\xe4\xa7V\xe4e\xa8\xec\x92\xe9j;\xe5" +
"\x9f\x00~\xfa\xf8\xbd{\xbb\xcf.~Y\x9d\x86\x89j" +
"\xa1g\\\xb3\x09\x95E\xd7\xd0\xcf\x05\xd7p\xfb\x84\x1a" +
"\xacb\xe7Rk\xca\x1aT*\x0a\xfd\\\xa7p\xf6e" +
"w}\xff\x81\x9a\xf3\xdf\x7f\xb9Z\xa5\xe4\xe2\x0b\xefI" +
"[\xa8\xecK\xd3\xcf=\xe9\xff'\x02\xba\xd3\x9e\xfa\xbd" +
"\x1fw\xe4\xdf\xfe\xc58Q\xa444^P\x9a\x1a\xe9" +
"\xd7\xb5\x8d$\xe3\xd9y'\xfe\xe8\xdf\xf7\x9c>\x13\xf7" +
"\x94u\x8d\xdcew6\x92\xc2\xee\xfd\xfa\xc8\xa6\x15\xd7" +
"\x8d\xbeYm \xcey\xbcq\x14\x95S|\xbbg\xf9" +
"v\xc2y\xadi\xeb?~\xf3\x9d\x98\xd3\xceiz\x0f" +
"!\xe1\xaeXu\xd7\x9a\xba{\xce\x9e\x8d\x1f\xd4\xdc\xe4" +
"\x99\xae\x89\x0e:)?\xa0<\x7f\xf4\xcf\xce\xd1AR" +
"\xb5\xba\xd5\xa6\x01TX\x13WO\xd3#\x02\xc4\x82g" +
"<\xc7\xf9\xce\xf4\x16TJ\xd3\xb9\xe3L\xa7{-\xba" +
"\xbb\x9d\xad\xbe\xe5\x8e\xf7A\x9e&\x8e\xc1\x8a\xc7\x88\xf3" +
"\xd9\xe9<\x94\xa7\xdf\x8b\xca\xa9f\x09\xc0\xfd^a\xe0" +
"\xd5\x8f:\x8f\xfe\xa6zs.\xd0\xf1\xe6\x16T\x9e!" +
"\xbe\x85'\x9a\xb9}\x16.\xf8\x93\x0f\x0e<\xdc\xf9\xd1" +
"E\xbb\x7f\xf1\xff;Pi\xc8\xd0=\xea2\xdfRn" +
"\xcd\xf0\xcd\xbf\xbbx\xe5\xad3_\xba\x10\xd7\xc4\x8c\xcc" +
"\x05\x1e\xf9\x19\xd2\xc4\xd0-\xbf\xfe\xd6u\xdf\xfb\x9b\x0b" +
"U\xf6\xe3\x8c\xfd\x99\xb9\xa80\xbe\xa3F\xcc\x1f.\xfd" +
"\xe1\x99i\xc9i\x9fT]t\x12\xf1\xee\xcc\xacA\xe5" +
"\x10\xf1.<\x90y\x99.z\xc7{\x0fnh\xfd\xc1" +
"'\x9f\x92\\b\x15\xd0\xed\x9a1\x80\xcaC3h\xe7" +
"C3(\x96\x96?\xf1\xf67\x87\x0f\xbc\xf2\xd9\xb8\xd0" +
"\xbdd\xe6vT\xee\x9cI\xdc\xfd3\x09\xae\xfeT:" +
"|v\xeb\xbf\xfc\xe1\xe7q\xa9\xfe`\xd6{$\x95:" +
"\x8b\xa4\xda\xfc\xe1\xa1\xae\xfbW?\xf1\xe5\x18O\x9b\xf5" +
"\x1c1l\xe3\x0ca0\x8e\xe7iGgu\xa0rb" +
"\x16\x9d\xf7\xe4\xacV\x98\xe7:\x15\xc3`E\xab\x9c\xc8" +
"\xfdv\xf037?\xa7\x95\x8drK{\xc5\x19f\x86" +
"\xa3\xe74\x87\xf5\xb2V\xbbl\x1a6\xebATSb" +
"\x02 \x81\x00\xb2\xb6\x06@\xbd[D\xb5(\xa0\x8c\x98" +
"&\xb8\x96u\"\x0e\x8b\xa8:\x02\xca\x82\x90&D\x90" +
"\xd7\xcd\x04P\x8b\"\xaa\x1b\x05D1Mx'W\x1e" +
"\x00P7\x8a\xa8\xee\x10\xd0-3\xab\xa4\x19\xcc\x80\xa4" +
"\xb3\xc4\xb2\xb0\x1e\x04\xac\x07t-\xe6X#\xda`\x11" +
"\x92,F\x96\xd6lp\xb0\x01\x04l\x00t\x87\xcd\x8a" +
"e\xf7\x1b\x0e\xea\xc5^6d1\x1b\x87q\x12\x088" +
"\x09p\"\xf1:M\xc3`9'[\xc9\xe5\x98m\x03" +
"\x90d\xb5\xa1ds\x1e\x04Po\x14Q\xbd%&\xd9" +
"\"\x92\xec\x1b\"\xaam\x02\xba6\xb3\xd63k\xb9\x89" +
"9\xcd\xd1Mc\x85&\x96Xx\xed\\Qg\x86\xd3" +
"iB\xd2\x18\xd2\x0b\x98\x8aB\x01\x10S\x13_l\xc9" +
"F\xddvt\xa3\xd0\xc7\xe9\xad=fQ\xcf\x8d\xd0\xed" +
"\xea\xb9&\x9b[h\x0f\xf9\xda\x01\x00\x14d\xb9\x03\xa0" +
"U/\x18\xa6\xc5\xdc\xbcn\xe7H(\x10s\xce\x96A" +
"\xad\xa8\x199\x16\x1e4\xe9\xe2\x83\xbc\x03\xb2\\\x8e\xf9" +
"Z\xcc\xda\xb3{4K\x13K\xb6Z\x1f\xeac\xc9\x00" +
"\x80\xbaXD\xb5'\xa6\x8f\xdb\x96\x01\xa8\xcbET\xef" +
"\x88Y\xba\xbf\x03@\xed\x11Q]-\xa0kZzA" +
"7:\x19\x88V\xdc`\xb6ch%\x06\x00\x81\xc2\xb6" +
"\x98eR\xa2\x8d\xa9\x08\xa5\xab4Us\xb1\x00]\xac" +
"X4o7\xadb~\xa5w\x8eI\xda\xe6\xa6\x0c\x97" +
"I\xe3X\x9e\x1b\x87\xe4\xd6sl~\xc5f\xde\xba\x8a" +
"\xc5\x0d9\xbb\x97\xd9\x95\xa2c\x03\xa8\x89P\xfc\x86\x16" +
"\x00\xb5VD5-`\xab\xc5\x190\x15\x81z\xd5U" +
"/\xa7\xeb\x8aa\xb1\x82n;\xcc\xf2\xc8\xb3[I\xe1" +
"%;~ \xf9_JDu\xba\x80n\xc1\xd2r\xac" +
"\x87Y\xa8\x9b\xf9\x15\x9aafE\x96\xc3\x1a\x10\xb0f" +
"bOZ\xaa\xe9E\x96\xf7\xa4\x9b\x9f\xcb\xf0\xff)z" +
"\xeb]\xd7\x0b\xdf\x81(|\x1b\xf0K\xd7\x8f\xdfMQ" +
"\xfc6\x08_\xb8\x17\x07p\x83\xf8\xb9\xeb\x870E\x84" +
"#\xa2\xba\x95\"\xa2R&\x9d\xda \x9a\x16\xa6\"\x94" +
"\xf4\xb5\xc3\xf2\x05\xd2\xb4\x01\xad,G\x8a\xc6T\x90\xed" +
"=\x06)o\x0ec**e\xfce\x16[\xcf,\x9b" +
"\xf5@\xd227\x8e`*\xca\xfaUZ\x9fz\xb5Z" +
"\x0f\x0c\x1d\xae\x9ax\xbd\xc5r\x1ed\xf8\xcb{2\x9e" +
"\xd1\xd2\xa1\xd1\xee\x99\x19\x01Z\x18$\xdb\x06\x01\xd4\xad" +
"\"\xaa\xbbcA\xb2\x8b4\x7f\x9f\x88\xea~\x01e\xd1" +
"\xc7\xc3}\x14N{ET\x0f\x0b('\x12i*f" +
"\xe5C\x14N\xfbET\x8f\x08ca\x8f\xadg\x86\xb3" +
"X/\x80\xc4\xec\x88JW\\\xac\x17\x18\x88\xf6\xffB" +
"\xc0\x8d\xd1\x87\xaf\x8dP\x0f1\xe7%\xe9\xeaET\x1b" +
"\x09\xd8\xe9+s\x08\x02\xe8\xb4\xb0d\xbe\xfci\x9d\xf4" +
"\xaf\x0f\xd3=\xfe.\x96\x8f\xd4\x8d\xe1a\x87\xe8\xb0\x83" +
"\"\xaa?\x8a)\xfd\xa8\x05\xa0\x1e\x11Q}B@\xf4" +
"u\xfe\xd81\x00\xf5\x09\x11\xd5\x9f\x91\xce\x05O\xe7\xcf" +
"\xcc\xa5\x0eKD\xf55\xd2\xb9\xe8\xe9\xfcU\x0a\xbe\xd7" +
"DT\xdf\x12P\xaeI\xa4\xb1\x06@~\x93\xecxF" +
"D\xf5\xddK\xe1Z\xaehV\xf2CE\x0d2\x16\xcb" +
"w/\x0e\xe9F\xa5\xd4c\xb1\xf5:\x9a\x15\xbb\xddq" +
"XI*;v\x90\xa2\x92\x8eV\xb0q*`\x8f\x88" +
"\x98\x8a\x8aN@\"\x86{\xa2\xc5\xf2\xab\x98e\xeb\xa2" +
"i\x84YF7\x1cf8\xcb5\x90\x06Y1\xa4N" +
"\x80B\xbd~,Q$\xf9\xb0`F\xc8\x89\x05\x02\xfc" +
"\xe9\xae\xeb+q\x09\xe9\xa6MDu\xb9\x80\xcd\xf8%" +
"\x91I\x8f\xdd\xbd\x00j\x97\x88j\x9f\x80\xcd\xc2\x17D" +
"&M\xaa\x03\x11\xee'\x87\x1d\xa7\x8c\xa9\xa8\x18\xf5\x8d" +
"\xbd\x81\x0d\xdafn-\x03$\xf8\x0c+#\xff\xeb\xb0" +
"\x0f\xe7 \x16\xf3\x98\x8a\xba\xc9*O\x11/\x95\xcb[" +
"\xa9r0-\x9e*\xa3\xc4us$D\xe0\x1d\xdd\x03" +
"\x91\x04\xb2\xd0\xe6\x89\xa5\x0eF\xf7\xcf\xe4\xb4\x8a\xcd\xc6" +
"\x16!\xedC\x0e\x88\xcc\x0aq\xd7\x1e6+\xc5|/" +
"\x03\xc9\xb1F\x10A@\x9c\x18\x8d\x17\x9b]1\xc5{" +
"n<~\x82\x0d\xf3\xeb@<\xbf\xfa\xea\xef'\xf5\xf7" +
"\x89\xa8\x96\x05t\x8b\x84gF\x97\xc9\xc3=\xb8\xaeG" +
"\xec1\xb9sJ \xa0\x04\xe8V\xca\xb6c1\xad\x04" +
"\x18z\x1b\xf1O\xbd\x8a\xb4U\x05\x9f=Z\x92\xc7\xfd" +
"\xff\xa5\"\xe1\xea\xb3\xbd\x97y\xc7\xe4\xfac\xb1\xd4\x9b" +
"\xf3W#_\xdei\x1a\xd2U\xd7s>\x82y\xd9f" +
"\xbe_=P\xa9\x19\xa4\xe19\x946f\x8b\xa8\xde\x14" +
"O\xc3\xf3HE7\x88\xa8~C@\x89Y\x94Q\xc3" +
"\x99\x80w\xe8\x16\xdb\xab]1\x15M|.\x7f\x9dX" +
"Y\xaf\x9b\xc6En83\x0a\x97\xd0\x84\xdd7\xc7\xec" +
"\x1a\x98\xf0\xb6\xc1\xc8\xae\xd2Z6\x12X)\xc3J\x9a" +
"\x1e\xa1\x91o\xdcv\x90\xbe\x1d\xf1LX\xfe\xfae\x82" +
"W$\xb4z\xd6\xa2K\xc6\xf2\xech,\xa5\x06\x97\xdc" +
"E\xdd\xc4n\x11\xd5\x83\xb1K\x1e\xe8\x88\xa5\xd4 \xcf" +
"\x1e\"\x03\x1f\x16Q}T@\xf4\xd3\xecq\x82\xfcG" +
"ETO\x0a\x1c\xb0\xbb\xda;M\x03\xfdK\xd8\x00a" +
"G1\xcc4\xcb\x19d\x1a:\xdd\x86\xc3\xac\xf5\x1a\x16" +
"\x03H\xd8\xe2\xe8%fV\x9c\x10\"J\xdaF^\x82" +
"a\xbe\xcb[%i\x8e\x8du `\x1dE\xa4\xcd\xac" +
"N\x8b\xe5\x91\xac\xa1\x15{4\xd1\x19\xbe\x12\x05\x8d\x05" +
"\xf1\xe48\xea\xa1\x02n\xb3\x88\xea}\x04%\x18\x9b;" +
"\xc9;\xd7\x80\xc0\x91\x84d^\xd7\x11\x95t<!\xd6" +
"T5e<!N\xa2\x1a\x86\xb4\xb3CDu\xaf\x10" +
"\\\xad\xcb\x84V/B\xabM\xed7=[\x085u" +
"\x16\xc9\xeb\xd7\x0b:\x9aF\x1fW\x14F\x9a\xca\x99\xa5" +
"\xb2E\xae\xac\x9b\x86Z\xd1\x8a\xba\xe8\x8c\x84\x0b'\xd4" +
"\x05A\x92\x17\xca+\xcb\x19n,R\xc6-\x812\x94" +
"\x11\\\x06\x90\xdd\x88\"fw`\xe4.\xca6\xec\x00" +
"\xc8n&\xfa}\x18y\x8c\xb2\x13\xa7\x01d\xb7\x12}" +
"7\x86\xbd\xaa\xb2\x0b\x1f\x07\xc8\xee&\xf2A\x8cJ\x05" +
"\xe5\x00\xdf~?\xd1\x8f`T-(\x0f\xe1\\\x80\xec" +
"A\xa2\x9f$\xfa$\x81kR9\x81k\x00\xb2O\x11" +
"\xfdy\xa2K5i\xe4s\x1f\xb4\x00\xb2?#\xfa\xcf" +
"\x89^\xdb\x98\xc6Z\x00\xe5%N\x7f\x91\xe8\xaf\x11\xbd" +
"\xae)\x8du\x00\xca\xab\xb8\x1d \xfb\x0a\xd1\xcf\x10}" +
"2\xa6q2\x80r\x1a\x1f\x04\xc8\x9e!\xfa\xbbD\x9f" +
"2)\x8dS\x00\x94\x7f\xe6\xf7y\x8b\xe8\xe7\x88^\x9f" +
"Hc=\x80\xf2\xafx\x0c {\x8e\xe8\xbf!z\x83" +
"\x94\xc6\x06\x00\xe5\x03.\xd7\xaf\x89^+\x848\xd8\x9d" +
"\x8f\xc31\xb9\xa1\x1e\x95#\xa2i\x87\xae\xc0\xfc\x1e\x16" +
"\xbd\\\xd1c&\xa9\x89\xc5d4m\x06\xc4$\xa0[" +
"6\xcd\xe2\x8a\xb10\x7f\xb9\x8a\xc8w#H\x9aFw" +
">\x8cK\xcf\xf9\x96\x9b\x90\xc9i\xc5\xeerT#\xd9" +
"\xed\x15\xc7\xac\x94!\x93\xd7\x1c\x96\x0f\x13\xb5U1\x96" +
"Zf\xa9\x0f\x99U\xd2\x0d\xad\x08\xe1\x97\x89|1Y" +
"\xa9\xe8\xf9p\xef\x09\x0b;w\x88iN\xc5b6\x89" +
"v\x89\x8c+T{t\xa6\xdc\xd2\xa7\x15\xaaF\x11s" +
"\xa3\xf4\x10\xa2\xdd\xbc\x9b\xa3\xec\x90\x8cGaf\xbdV" +
"\xac\xb0+)\x06'lnz[\xbd\xe6\xe8r=p" +
"08\xbb|5\xdf_\x95y\xbd|x\xd1\xdc\xa5#" +
"\x126\x94\xd5\xf2g1]B\x94\xf3\x02k\x0d\xf9=" +
".dh\xef\x98\xdf\x84\x93M\xdfo\xaeT\x13\x05\xe6" +
"x\xbf\xba\x8d!\x93\xca\x03I+\xd9_qu/\xb3" +
"\x93W\xa2\xc5hVy\xf9\xfc\xdd\xd5\xd7\xd7\x13\x8d;" +
"D\x0f\xfco\x0a\xf1\xae\x1d{\x01\xb2m\x14\xb8\xcb1" +
"\xd4\xa1\xd2\xcdq\xa7\x8b\xc8}\x18U\xbd\x8a\xca\xf1\xa5" +
"\x87\xe8\xab1\xea\x8b\x94;9.\xac&\xfa0\xc7\xbb" +
"v\x0f\xef\x18\xdf>O\xf42\xc7;\xf4\xf0\xae\xc4\xf7" +
"/\x12}c\x1c\xef*8:\x06~%\xd1\xc3\xbbm" +
"\x1c\xa7v\x10}/\xc7\xbb\x84\x87w{\xf0i\x80\xec" +
"^\xa2\x1f\xe6xW\xe3\xe1\xdd!|\x0e {\x98\xe8" +
"\x8fr\xbc\x9b\xe4\xe1\xddq\xce\xffh\x88\xb3S:<" +
"\xbc;\xc1\xf11\xc4Y\xb7b\x15\xb3\x8e\xa5\x1b\x80\x85" +
"(6r\xe5o3Vn\x87dQ_\xcf\xc2\\\x94" +
"\xd7\xb5\xe2\xe2\x8aV\x84L\xd6\xd1rk\xa3\xd2\xbeh" +
"wiF\xde\xc6am-\xa3\x0c&\xc5s\xbdS\xb4" +
"W1K\x1f\x02\x8c\x9a\x81\xb0\xf6I\xf6\x98fuI" +
"\xc4kJfy\xe0\x17~+i\x1b\xbb\xf3E\xd6\x89" +
"A\x05$\x1aQ\x06\xd5\xe9\x8bi\x18\xe8\x95%}z" +
"fl\xbdQ\xf6\xdb\x8b\xa0n\xe9k\xad*H\xd8\xc6" +
"2\xcb9\x9d&\x1a\x8enT\xd8E\x1b\xe4\x86+\xc6" +
"Z\x96_\x82F\xce\xcc\xebF\x01.\xeak\xc4KM" +
"\x99b\x85\x1a\x8ff\x8c=\xd3\xc9sZ@\xe0\xd0E" +
"e\x87\xdc\x12M\x07Zs|U\xab\xc54;\xd6\xd8" +
"Np\x9a?\x15\xf5\x82\xcc\x9b\x04\xd4\x00\x84OZ\x18" +
"<\x0b\xc8'6\x81 ?&a\xf4\x9a\x82\xc1\xe3\x89" +
"\xfc\x90\x05\x82|@B!|k\xc4\xe0\x9dP\xde5" +
"\x0a\x82\xbcSB1|\xfe\xc3`\xe6.\x8ft\x80 " +
"\x97$L\x84o\xa1\x18\x0c\xece\x8dJ\xab;%\xac" +
"\x09\x1f\x161x\x15\x92o\xdb\x0e\x82\xbcDr\x83\x0e" +
"\x0aZ=1\xda\xd0\x0d\x00\x032\x1c2\xda\xd0\x0d\xe6" +
"T\x18tZ\x00m\xb8\xc5\x87\xe76t\x83I-$" +
"s\x9a\xc3\xda\xa8=\xf5>\xa2\x0f\xde\xd0\x86\xf1\x09\xa8" +
"x\xa9\x9eh\xfc\xda\xba#\xaa\xff\xc2\x11\xd6hT\xfe" +
"\x85}\xe8\x9e\xc7\xe3\xa5\xb5?N9\xb4\xdd\x1f\xc6\x9c" +
"\x8c\x8dSNP\xbd}RD\xf5\x0d!*\x1a\x02\x9f" +
"\x0e\x86\x86hZAc<\xc1\xec\xd0\xf7|\xbf\xec\xad" +
"\x9e \xbays\x98\x97\xc5\xe8meC\x94\x0e\xe2c" +
"\xc5\xa9\xb1\xb1\"\x06-\xb94&{\xc4\x87\x8cS/" +
"\xd3\xdf\xc5\x1bL\x9e\xce\x12\xdc%\x83GT\x0c\x1e\xbc" +
"e\x99\\\xabAr\x83&\x14\x83\\\x08U&\xbb\xca" +
"N\xbc\x97e\xfe;\xc9z\x1c\x07\xf1\xceI\x92Gz" +
"\x02\x85\xfb\xae\x89\x8d\xf6\x8a\xa6\xdfD&W\xc4\xfb\x80" +
"\x09t\xe5]8\xa8\xda\x93\xb4\x98\xf6\xffZ\xb8\xff\xe9" +
"\x99\xb1\xd1[\xe0\x7fo\x12\xf1\x0d\x11\xd5wb\xad\xdd" +
"\xdb\xcb\x00\xd4\xb7DT?\x89^\x94>\"G\xfdD" +
"\xc4\xdeX\x89.\x7fA\x8c\x9fS!\x1bOX5\xf8" +
"\x00@\xb6\x96\x12D\x9a'\xac\x84\x97\xb0d\x1c\x04\xc8" +
"\xa6\x88>=^\xa07\xe1\x00@\xb6\x91\xe8\xb3\xd1\xef" +
"\xc8\x83\xd7\xa8\x8a\x15\x81{\xd1,,\xd7\x8dq\xab\xbe" +
"\xe0\x89\x0b\x1d\x82\xcc\x8aE\xb8?\x16_\xbb\x17\xc7\xea" +
"\xe0p\xec\x84\xcc\xcaR\x88\xe7\xd1\x0e\xc79W1\xfd" +
"\x9d\xc0\x1cY?\xf8\xbc\xd8\xf3k\x89\xd80\xe0Xl" +
"N\x16\x18C}\xce\x9f?\xdd\x1d3\xc6w\x06\x01\xd4" +
"\xd5\"\xaa\xc3\x02\x07(\xb3\xbf\x9c\xd7\xd0aK-\xb6" +
"\xae\xc2$#7\x125\xc5\xd4\x16\xe6\xec~,SA" +
"\xbe\xd4b\xad\xeb*,\xce\x10\xbcv\x80\xa4\x9b\xf9\x8b" +
"\x9e9\xc6\xa9,og\x83Y3\xb7\x969c^\x81" +
"\xaa^*{\xa3\xa7\x8e\xf0\xa1\xb27\xfeP\xe9\xc3\xda" +
":r\xf0\xb2\x88\xea\xe6\x18\xac\x8d\x8cF\x1d\xf5\xf8\xa5" +
"\xc4\xffL\xf6\xffJ\x8fuTHKWRd\x86\x7f" +
"D\xf4\x15\x07\xfdW\xda\x13DO\xd0W9\x1c\x83\x10" +
"k0\xf6'&t\x88\xe0o\xfe_\x01\x00\x00\xff\xff" +
"\x86\xbe\xf5t"
func init() {
schemas.Register(schema_db8274f9144abc7e,