From 8ecdb419cc429141c62f889b5bd0f5b7d631c3df Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Thu, 27 Aug 2026 17:56:13 +0800 Subject: [PATCH 01/34] fix: wait for DDL visibility on all working CNs --- pkg/cnservice/server_query.go | 9 +- pkg/cnservice/server_query_test.go | 40 +++++ pkg/frontend/cdc_dao_sync_test.go | 9 +- pkg/frontend/txn.go | 92 ++++++++++- pkg/frontend/txn_test.go | 249 +++++++++++++++++++++++++++++ pkg/txn/client/client.go | 2 +- pkg/txn/client/client_test.go | 53 ++++++ 7 files changed, 450 insertions(+), 4 deletions(-) diff --git a/pkg/cnservice/server_query.go b/pkg/cnservice/server_query.go index fd904ccf551f6..54519b0017898 100644 --- a/pkg/cnservice/server_query.go +++ b/pkg/cnservice/server_query.go @@ -445,7 +445,14 @@ func (s *service) handleGetTxnInfo(ctx context.Context, req *query.Request, resp } func (s *service) handleSyncCommit(ctx context.Context, req *query.Request, resp *query.Response, _ *morpc.Buffer) error { - s._txnClient.SyncLatestCommitTS(req.SycnCommit.LatestCommitTS) + targetTS := req.SycnCommit.LatestCommitTS + if _, err := s._txnClient.WaitLogTailAppliedAt(ctx, targetTS); err != nil { + return err + } + // Preserve the existing CN-based latest-commit update and BVT counter. The + // timestamp wait above makes this call non-blocking while keeping it on the + // established SyncCommit path. + s._txnClient.SyncLatestCommitTS(targetTS) return nil } diff --git a/pkg/cnservice/server_query_test.go b/pkg/cnservice/server_query_test.go index bb881375b135e..9541978cb57d9 100644 --- a/pkg/cnservice/server_query_test.go +++ b/pkg/cnservice/server_query_test.go @@ -53,6 +53,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/pb/query" "github.com/matrixorigin/matrixone/pkg/pb/statsinfo" "github.com/matrixorigin/matrixone/pkg/pb/task" + "github.com/matrixorigin/matrixone/pkg/pb/timestamp" "github.com/matrixorigin/matrixone/pkg/queryservice" "github.com/matrixorigin/matrixone/pkg/shardservice" sqlmongodb "github.com/matrixorigin/matrixone/pkg/sql/mongodb" @@ -67,6 +68,45 @@ import ( var dummyBadRequestErr = moerr.NewInternalError(context.TODO(), "bad request") var dummyErr = moerr.NewInternalError(context.TODO(), "dummy error") +func TestServiceHandleSyncCommitWaitsForAppliedLogtail(t *testing.T) { + targetTS := timestamp.Timestamp{PhysicalTime: 100, LogicalTime: 7} + + t.Run("updates latest commit after logtail is applied", func(t *testing.T) { + ctrl := gomock.NewController(t) + txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS). + Return(targetTS.Next(), nil) + txnClient.EXPECT().SyncLatestCommitTS(targetTS) + + s := &service{_txnClient: txnClient} + err := s.handleSyncCommit( + context.Background(), + &query.Request{SycnCommit: &query.SyncCommitRequest{LatestCommitTS: targetTS}}, + &query.Response{}, + nil, + ) + require.NoError(t, err) + }) + + t.Run("propagates cancellation without updating latest commit", func(t *testing.T) { + ctrl := gomock.NewController(t) + txnClient := mock_frontend.NewMockTxnClient(ctrl) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + txnClient.EXPECT().WaitLogTailAppliedAt(ctx, targetTS). + Return(timestamp.Timestamp{}, context.Canceled) + + s := &service{_txnClient: txnClient} + err := s.handleSyncCommit( + ctx, + &query.Request{SycnCommit: &query.SyncCommitRequest{LatestCommitTS: targetTS}}, + &query.Response{}, + nil, + ) + require.ErrorIs(t, err, context.Canceled) + }) +} + func Test_service_handleISCPDrainConsumerRenewFenceOnly(t *testing.T) { exec := &iscp.ISCPTaskExecutor{} iscp.RegisterExecutorRuntime("runner-cn", exec) diff --git a/pkg/frontend/cdc_dao_sync_test.go b/pkg/frontend/cdc_dao_sync_test.go index 98d940f5dfca0..2333fd8fd2896 100644 --- a/pkg/frontend/cdc_dao_sync_test.go +++ b/pkg/frontend/cdc_dao_sync_test.go @@ -80,7 +80,9 @@ func (m *mockQueryClient) Close() error { // Mock MOCluster for testing type mockMOCluster struct { - cnServices []metadata.CNService + cnServices []metadata.CNService + refreshCalls int + refreshError error } func (m *mockMOCluster) GetCNService(selector clusterservice.Selector, apply func(metadata.CNService) bool) { @@ -107,6 +109,11 @@ func (m *mockMOCluster) ForceRefresh(sync bool) { // Not used in syncCommitTimestamp } +func (m *mockMOCluster) Refresh(context.Context) error { + m.refreshCalls++ + return m.refreshError +} + func (m *mockMOCluster) Close() { // Not used in syncCommitTimestamp } diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index b9cfcb97cc7ce..0a0885cea246e 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -24,9 +24,13 @@ import ( "github.com/google/uuid" "go.uber.org/zap" + "github.com/matrixorigin/matrixone/pkg/clusterservice" "github.com/matrixorigin/matrixone/pkg/common/moerr" moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" "github.com/matrixorigin/matrixone/pkg/defines" + "github.com/matrixorigin/matrixone/pkg/pb/metadata" + querypb "github.com/matrixorigin/matrixone/pkg/pb/query" + "github.com/matrixorigin/matrixone/pkg/pb/timestamp" pbtxn "github.com/matrixorigin/matrixone/pkg/pb/txn" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" txnclient "github.com/matrixorigin/matrixone/pkg/txn/client" @@ -835,7 +839,14 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { if th.txnOp != nil { execCtx.ses.EnterFPrint(FPCommitUnsafeBeforeCommitWithTxn) defer execCtx.ses.ExitFPrint(FPCommitUnsafeBeforeCommitWithTxn) - commitTs := th.txnOp.Txn().CommitTS + txnMeta := th.txnOp.Txn() + commitTs := txnMeta.CommitTS + visibilityTS := timestamp.Timestamp{} + if !txnMeta.SnapshotTS.IsEmpty() { + // SnapshotTS is exclusive. A no-op DDL observed catalog state through + // SnapshotTS.Prev(), which is the frontier other CNs must also apply. + visibilityTS = txnMeta.SnapshotTS.Prev() + } tempTxnKey := tempTableTxnKey(th.txnOp) haveDDL := th.txnOp.GetWorkspace().GetHaveDDL() execCtx.ses.SetTxnId(th.txnOp.Txn().ID) @@ -850,6 +861,9 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { // left in a state that is unsafe to inspect. if !hasRecovered { commitTs = th.txnOp.Txn().CommitTS + if !commitTs.IsEmpty() { + visibilityTS = commitTs + } } if err != nil { err = moerr.AttachCause(ctx2, err) @@ -889,12 +903,88 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { execCtx.ses.SetTxnId(dumpUUID[:]) return err } + if err == nil && haveDDL && execCtx.ses.GetFromRealUser() && !visibilityTS.IsEmpty() { + // A fresh proxy connection has no session commit timestamp to carry + // across CNs. Do not acknowledge a client DDL until every working CN + // has reached the commit, or the observed catalog frontier for a no-op. + err = syncDDLCommitToWorkingCNs(ctx2, execCtx.ses.GetService(), visibilityTS) + } } th.invalidateTxnUnsafe() execCtx.ses.SetTxnId(dumpUUID[:]) return err } +// syncDDLCommitToWorkingCNs waits until every CN that can accept a fresh proxy +// connection has applied the DDL visibility frontier. Embedded and test +// frontends may omit a query client because they do not expose a multi-CN +// routing boundary. +func syncDDLCommitToWorkingCNs( + ctx context.Context, + service string, + visibilityTS timestamp.Timestamp, +) error { + pu := getPuIfPresent(service) + if pu == nil || pu.QueryClient == nil { + return nil + } + + qc := pu.QueryClient + cluster := clusterservice.GetMOCluster(qc.ServiceID()) + if cluster == nil { + return moerr.NewInternalError(ctx, "cannot establish DDL visibility barrier: cluster service is unavailable") + } + if refresher, ok := cluster.(clusterservice.AuthoritativeRefresher); ok { + if err := refresher.Refresh(ctx); err != nil { + return errors.Join( + err, + moerr.NewInternalError(ctx, "failed to refresh CNs for DDL visibility barrier"), + ) + } + } + + addresses := make([]string, 0, 4) + missingAddress := "" + cluster.GetCNService( + clusterservice.NewSelector(), + func(cn metadata.CNService) bool { + if cn.QueryAddress == "" { + missingAddress = cn.ServiceID + return false + } + addresses = append(addresses, cn.QueryAddress) + return true + }, + ) + if missingAddress != "" { + return moerr.NewInternalErrorf( + ctx, + "cannot establish DDL visibility barrier: working CN %s has no query address", + missingAddress, + ) + } + if len(addresses) == 0 { + return moerr.NewInternalError(ctx, "cannot establish DDL visibility barrier: no working CN is available") + } + + for _, address := range addresses { + req := qc.NewRequest(querypb.CmdMethod_SyncCommit) + req.SycnCommit = &querypb.SyncCommitRequest{LatestCommitTS: visibilityTS} + resp, err := qc.SendMessage(ctx, address, req) + if err != nil { + return errors.Join( + err, + moerr.NewInternalErrorf(ctx, "failed to apply DDL commit on CN %s", address), + ) + } + if resp == nil { + return moerr.NewInternalErrorf(ctx, "empty DDL visibility response from CN %s", address) + } + qc.Release(resp) + } + return nil +} + // Rollback rolls back the txn // the option bits decide the actual behavior func (th *TxnHandler) Rollback(execCtx *ExecCtx) error { diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index 1e405743554b8..9c01a06a8d471 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -27,10 +27,14 @@ import ( "github.com/smartystreets/goconvey/convey" "github.com/stretchr/testify/require" + "github.com/matrixorigin/matrixone/pkg/clusterservice" "github.com/matrixorigin/matrixone/pkg/common/moerr" + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" "github.com/matrixorigin/matrixone/pkg/defines" mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test" "github.com/matrixorigin/matrixone/pkg/pb/lock" + "github.com/matrixorigin/matrixone/pkg/pb/metadata" + querypb "github.com/matrixorigin/matrixone/pkg/pb/query" "github.com/matrixorigin/matrixone/pkg/pb/timestamp" "github.com/matrixorigin/matrixone/pkg/pb/txn" "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" @@ -853,6 +857,251 @@ func TestCommitUsesFinalCommitTSForNextTxn(t *testing.T) { } } +type ddlSyncRequest struct { + address string + method querypb.CmdMethod + commitTS timestamp.Timestamp +} + +type ddlSyncQueryClient struct { + serviceID string + sendError map[string]error + nilResponse map[string]bool + requests []ddlSyncRequest + releases int +} + +func (c *ddlSyncQueryClient) ServiceID() string { + return c.serviceID +} + +func (c *ddlSyncQueryClient) SendMessage( + _ context.Context, + address string, + req *querypb.Request, +) (*querypb.Response, error) { + request := ddlSyncRequest{address: address, method: req.CmdMethod} + if req.SycnCommit != nil { + request.commitTS = req.SycnCommit.LatestCommitTS + } + c.requests = append(c.requests, request) + if err := c.sendError[address]; err != nil { + return nil, err + } + if c.nilResponse[address] { + return nil, nil + } + return &querypb.Response{}, nil +} + +func (c *ddlSyncQueryClient) NewRequest(method querypb.CmdMethod) *querypb.Request { + return &querypb.Request{CmdMethod: method} +} + +func (c *ddlSyncQueryClient) Release(*querypb.Response) { + c.releases++ +} + +func (c *ddlSyncQueryClient) Close() error { + return nil +} + +func TestCommitSyncsDDLCommitToWorkingCNs(t *testing.T) { + const queryServiceID = "ddl-sync-commit-test" + commitTS := timestamp.Timestamp{PhysicalTime: 100, LogicalTime: 7} + snapshotTS := timestamp.Timestamp{PhysicalTime: 90, LogicalTime: 5} + targets := []metadata.CNService{ + {ServiceID: "cn-1", QueryAddress: "cn-1:6001"}, + {ServiceID: "cn-2", QueryAddress: "cn-2:6001"}, + } + + newState := func(t *testing.T) (*Session, *testTxnOp, *ddlSyncQueryClient, *ExecCtx) { + t.Helper() + ctrl := gomock.NewController(t) + ctx := defines.AttachAccountId(context.Background(), sysAccountID) + ses := newTestSession(t, ctrl) + ses.SetFromRealUser(true) + eng := mock_frontend.NewMockEngine(ctrl) + eng.EXPECT().Hints().Return(engine.Hints{CommitOrRollbackTimeout: time.Second}).AnyTimes() + ses.txnHandler.storage = eng + + op := newTestTxnOp() + op.meta = txn.TxnMeta{ + ID: []byte{1, 2, 3, 4}, + Status: txn.TxnStatus_Active, + SnapshotTS: snapshotTS, + } + op.commitTS = commitTS + op.wp.SetHaveDDL(true) + ses.txnHandler.txnOp = op + ses.txnHandler.txnCtx = ctx + + qc := &ddlSyncQueryClient{ + serviceID: queryServiceID, + sendError: make(map[string]error), + nilResponse: make(map[string]bool), + } + pu := getPu("") + previousQueryClient := pu.QueryClient + pu.QueryClient = qc + t.Cleanup(func() { pu.QueryClient = previousQueryClient }) + moruntime.SetupServiceBasedRuntime(queryServiceID, moruntime.DefaultRuntime()) + moruntime.ServiceRuntime(queryServiceID).SetGlobalVariables( + moruntime.ClusterService, + &mockMOCluster{cnServices: targets}, + ) + + execCtx := newTestExecCtx(ctx, ctrl) + execCtx.ses = ses + execCtx.stmt = &tree.CreateTable{} + execCtx.txnOpt = FeTxnOption{autoCommit: true} + return ses, op, qc, execCtx + } + + t.Run("waits for every working CN", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Equal(t, []ddlSyncRequest{ + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommit, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommit, commitTS: commitTS}, + }, qc.requests) + require.Equal(t, 2, qc.releases) + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + require.Equal(t, 1, cluster.refreshCalls) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Zero(t, op.rollbackCalls) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("does not acknowledge a membership refresh failure", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + refreshErr := moerr.NewInternalErrorNoCtx("HAKeeper unavailable") + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + cluster.refreshError = refreshErr + + err := ses.GetTxnHandler().Commit(execCtx) + require.ErrorIs(t, err, refreshErr) + require.Equal(t, 1, cluster.refreshCalls) + require.Empty(t, qc.requests) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Zero(t, op.rollbackCalls) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("does not acknowledge a partial barrier", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + sendErr := moerr.NewInternalErrorNoCtx("CN unavailable") + qc.sendError["cn-2:6001"] = sendErr + + err := ses.GetTxnHandler().Commit(execCtx) + require.ErrorIs(t, err, sendErr) + require.Len(t, qc.requests, 2) + require.Equal(t, 1, qc.releases) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Zero(t, op.rollbackCalls) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("rejects an empty CN response", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + qc.nilResponse["cn-1:6001"] = true + + err := ses.GetTxnHandler().Commit(execCtx) + require.ErrorContains(t, err, "empty DDL visibility response") + require.Len(t, qc.requests, 1) + require.Zero(t, qc.releases) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("rejects an empty working CN set", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + moruntime.ServiceRuntime(queryServiceID).SetGlobalVariables( + moruntime.ClusterService, + &mockMOCluster{}, + ) + + err := ses.GetTxnHandler().Commit(execCtx) + require.ErrorContains(t, err, "no working CN is available") + require.Empty(t, qc.requests) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("rejects a working CN without query address", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + moruntime.ServiceRuntime(queryServiceID).SetGlobalVariables( + moruntime.ClusterService, + &mockMOCluster{cnServices: []metadata.CNService{{ServiceID: "cn-missing-address"}}}, + ) + + err := ses.GetTxnHandler().Commit(execCtx) + require.ErrorContains(t, err, "working CN cn-missing-address has no query address") + require.Empty(t, qc.requests) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("synchronizes the observed frontier for a DDL no-op", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + op.commitTS = timestamp.Timestamp{} + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Equal(t, []ddlSyncRequest{ + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommit, commitTS: snapshotTS.Prev()}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommit, commitTS: snapshotTS.Prev()}, + }, qc.requests) + require.Equal(t, 2, qc.releases) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + tests := []struct { + name string + configure func(*Session, *testTxnOp) + }{ + { + name: "non-DDL transaction", + configure: func(_ *Session, op *testTxnOp) { + op.wp.SetHaveDDL(false) + }, + }, + { + name: "internal session", + configure: func(ses *Session, _ *testTxnOp) { + ses.SetFromRealUser(false) + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ses, _, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + test.configure(ses, ses.txnHandler.txnOp.(*testTxnOp)) + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Empty(t, qc.requests) + require.Zero(t, qc.releases) + }) + } +} + func TestTxnHandlerDoesNotOwnKafkaProgress(t *testing.T) { newState := func(t *testing.T) (*Session, *ExecCtx, *testTxnOp) { t.Helper() diff --git a/pkg/txn/client/client.go b/pkg/txn/client/client.go index 46d9d0b50eaa9..4cde087a80a6d 100644 --- a/pkg/txn/client/client.go +++ b/pkg/txn/client/client.go @@ -948,7 +948,7 @@ func (client *txnClient) GetLatestCommitTS() timestamp.Timestamp { func (client *txnClient) SyncLatestCommitTS(ts timestamp.Timestamp) { client.updateLastCommitTS(context.TODO(), nil, TxnEvent{Txn: txn.TxnMeta{CommitTS: ts}}, nil) - if client.timestampWaiter != nil { + if client.timestampWaiter != nil && client.timestampWaiter.LatestTS().Less(ts) { ctx, cancel := context.WithTimeoutCause(context.Background(), time.Minute*5, moerr.CauseSyncLatestCommitT) defer cancel() for { diff --git a/pkg/txn/client/client_test.go b/pkg/txn/client/client_test.go index fe66a1f0c3a23..a8f69e2ad5ce5 100644 --- a/pkg/txn/client/client_test.go +++ b/pkg/txn/client/client_test.go @@ -212,6 +212,11 @@ type snapshotTimestampWaiter struct { waitForContext bool } +type appliedTimestampWaiter struct { + latest timestamp.Timestamp + getCalls int +} + func (w *snapshotTimestampWaiter) GetTimestamp( ctx context.Context, ts timestamp.Timestamp, @@ -229,6 +234,18 @@ func (*snapshotTimestampWaiter) NotifyLatestCommitTS(timestamp.Timestamp) {} func (*snapshotTimestampWaiter) Close() {} func (*snapshotTimestampWaiter) LatestTS() timestamp.Timestamp { return timestamp.Timestamp{} } +func (w *appliedTimestampWaiter) GetTimestamp( + context.Context, + timestamp.Timestamp, +) (timestamp.Timestamp, error) { + w.getCalls++ + return w.latest.Next(), nil +} + +func (*appliedTimestampWaiter) NotifyLatestCommitTS(timestamp.Timestamp) {} +func (*appliedTimestampWaiter) Close() {} +func (w *appliedTimestampWaiter) LatestTS() timestamp.Timestamp { return w.latest } + // selectedSuccessTimestampWaiter models the valid notify-vs-cancel ordering // where notification wins the waiter's select, but the successful return is // delayed until after the transaction client has closed. @@ -273,6 +290,42 @@ func TestAdjustClient(t *testing.T) { } } +func TestSyncLatestCommitTS(t *testing.T) { + targetTS := timestamp.Timestamp{PhysicalTime: 100, LogicalTime: 7} + + t.Run("without timestamp waiter", func(t *testing.T) { + client := &txnClient{} + + client.SyncLatestCommitTS(targetTS) + + require.Equal(t, targetTS, client.GetLatestCommitTS()) + require.Equal(t, uint64(1), client.GetSyncLatestCommitTSTimes()) + }) + + t.Run("skips an already applied timestamp waiter", func(t *testing.T) { + waiter := &appliedTimestampWaiter{latest: targetTS} + client := &txnClient{timestampWaiter: waiter} + + client.SyncLatestCommitTS(targetTS) + + require.Zero(t, waiter.getCalls) + require.Equal(t, targetTS, client.GetLatestCommitTS()) + require.Equal(t, uint64(1), client.GetSyncLatestCommitTSTimes()) + }) + + t.Run("waits for an unapplied timestamp", func(t *testing.T) { + waiter := &snapshotTimestampWaiter{} + client := &txnClient{timestampWaiter: waiter} + + client.SyncLatestCommitTS(targetTS) + + require.Equal(t, 1, waiter.called) + require.Equal(t, targetTS, waiter.got) + require.Equal(t, targetTS, client.GetLatestCommitTS()) + require.Equal(t, uint64(1), client.GetSyncLatestCommitTSTimes()) + }) +} + func TestNewWithSnapshotWaitsForLocalLogtail(t *testing.T) { rt := runtime.NewRuntime(metadata.ServiceType_CN, "", logutil.GetPanicLogger(), From bc0d8e0e0db2089a8d2c053a5231c5b662a3d169 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Thu, 27 Aug 2026 20:18:01 +0800 Subject: [PATCH 02/34] fix: fence DDL visibility across CN admission --- pkg/clusterservice/cluster.go | 1 + pkg/clusterservice/cluster_test.go | 6 + pkg/cnservice/server.go | 3 + pkg/cnservice/server_ddl_visibility.go | 169 ++++ pkg/cnservice/server_ddl_visibility_test.go | 201 ++++ pkg/cnservice/server_heartbeat.go | 1 + pkg/cnservice/server_query.go | 1 + .../server_view_metadata_admission.go | 1 + pkg/cnservice/types.go | 1 + pkg/defines/const.go | 3 +- pkg/frontend/cdc_dao_sync_test.go | 16 +- pkg/frontend/txn.go | 127 ++- pkg/frontend/txn_test.go | 103 +- pkg/hakeeper/rsm.go | 1 + pkg/hakeeper/view_metadata_admission_test.go | 2 + pkg/pb/logservice/logservice.go | 1 + pkg/pb/logservice/logservice.pb.go | 891 ++++++++++-------- pkg/pb/logservice/logservice_test.go | 2 + pkg/pb/metadata/metadata.pb.go | 174 ++-- pkg/pb/query/query.pb.go | 546 +++++------ pkg/queryservice/client/query_client.go | 1 + pkg/queryservice/client/query_client_test.go | 15 + proto/logservice.proto | 5 + proto/metadata.proto | 3 + proto/query.proto | 3 + 25 files changed, 1511 insertions(+), 766 deletions(-) create mode 100644 pkg/cnservice/server_ddl_visibility.go create mode 100644 pkg/cnservice/server_ddl_visibility_test.go diff --git a/pkg/clusterservice/cluster.go b/pkg/clusterservice/cluster.go index 2b19e767f2906..784eee14b0f14 100644 --- a/pkg/clusterservice/cluster.go +++ b/pkg/clusterservice/cluster.go @@ -655,6 +655,7 @@ func newCNService(cn logpb.CNStore) metadata.CNService { ViewMetadataAdmissionGeneration: cn.ViewMetadataAdmissionGeneration, ViewMetadataAdmissionReady: cn.ViewMetadataAdmissionReady, ViewMetadataObservedEpoch: cn.ViewMetadataObservedEpoch, + DDLVisibilityBarrierReady: cn.DDLVisibilityBarrierReady, } } diff --git a/pkg/clusterservice/cluster_test.go b/pkg/clusterservice/cluster_test.go index 49b488c0aa81c..bb5fd3f34f053 100644 --- a/pkg/clusterservice/cluster_test.go +++ b/pkg/clusterservice/cluster_test.go @@ -169,6 +169,7 @@ func TestClusterAdmissionSnapshotFiltersEveryPublicInventory(t *testing.T) { UUID: "pending", WorkState: metadata.WorkState_Working, ViewMetadataAdmissionGeneration: 11, + DDLVisibilityBarrierReady: true, }, } hc.Unlock() @@ -189,12 +190,17 @@ func TestClusterAdmissionSnapshotFiltersEveryPublicInventory(t *testing.T) { require.Equal(t, []string{"ready"}, withoutWorkState) var raw []string + pendingBarrierReady := false require.NoError(t, GetCNServiceRawWithContext( context.Background(), c, NewSelector(), func(service metadata.CNService) bool { raw = append(raw, service.ServiceID) + if service.ServiceID == "pending" { + pendingBarrierReady = service.DDLVisibilityBarrierReady + } return true })) require.ElementsMatch(t, []string{"ready", "pending"}, raw) + require.True(t, pendingBarrierReady) admission := c.GetViewMetadataAdmission() require.True(t, admission.Enabled) diff --git a/pkg/cnservice/server.go b/pkg/cnservice/server.go index 906249160b224..2f7237d6ac8c6 100644 --- a/pkg/cnservice/server.go +++ b/pkg/cnservice/server.go @@ -463,6 +463,9 @@ func (s *service) Start() (err error) { if err = s.startUnlessViewMetadataGenerationRevoked(s.queryService.Start); err != nil { return err } + if err = s.prepareDDLVisibilityBarrier(); err != nil { + return err + } if err = s.startFrontendUnlessViewMetadataGenerationRevoked(); err != nil { return err } diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go new file mode 100644 index 0000000000000..4c4386a870ab3 --- /dev/null +++ b/pkg/cnservice/server_ddl_visibility.go @@ -0,0 +1,169 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cnservice + +import ( + "context" + "time" + + "github.com/matrixorigin/matrixone/pkg/clusterservice" + "github.com/matrixorigin/matrixone/pkg/common/moerr" + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/defines" + "github.com/matrixorigin/matrixone/pkg/pb/metadata" + "github.com/matrixorigin/matrixone/pkg/pb/query" + "github.com/matrixorigin/matrixone/pkg/pb/timestamp" +) + +func ddlVisibilityBarrierSupported(serviceID string) bool { + value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) + version, valid := value.(int64) + return ok && valid && version >= defines.MORPCVersion32 +} + +// prepareDDLVisibilityBarrier publishes this CN only after QueryService is +// listening. With protocol v32 active, it then catches up to the largest +// frontier held by the already-published barrier participants before public +// SQL ingress can be admitted. +func (s *service) prepareDDLVisibilityBarrier() error { + s.ddlVisibilityBarrierReady.Store(true) + s.notifyHeartbeat() + if !ddlVisibilityBarrierSupported(s.cfg.UUID) { + return nil + } + // Focused service tests may construct only the dependencies relevant to + // their lifecycle assertion. Production NewService initializes a non-zero + // admission generation together with all three barrier dependencies. + if s.moCluster == nil || s.queryClient == nil || s._txnClient == nil { + if s.viewMetadataAdmissionGeneration == 0 { + return nil + } + return moerr.NewInternalErrorNoCtx("DDL visibility barrier dependencies are unavailable") + } + + timeout := s.cfg.HAKeeper.DiscoveryTimeout.Duration + if timeout <= 0 { + timeout = 30 * time.Second + } + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + retryInterval := s.cfg.HAKeeper.HeatbeatInterval.Duration + if retryInterval < minClusterReadinessRetryInterval { + retryInterval = minClusterReadinessRetryInterval + } + if err := s.waitForDDLVisibilityBarrierPublication(ctx, retryInterval); err != nil { + return err + } + return s.syncStartupDDLVisibilityFrontier(ctx) +} + +func (s *service) waitForDDLVisibilityBarrierPublication( + ctx context.Context, + retryInterval time.Duration, +) error { + refresher, ok := s.moCluster.(clusterservice.AuthoritativeRefresher) + if !ok { + return moerr.NewInternalErrorNoCtx( + "CN cluster service does not support authoritative DDL visibility refresh") + } + + for { + if err := refresher.Refresh(ctx); err == nil { + published := false + err = clusterservice.GetCNServiceRawWithContext( + ctx, + s.moCluster, + clusterservice.NewServiceIDSelector(s.cfg.UUID), + func(cn metadata.CNService) bool { + published = cn.ViewMetadataAdmissionGeneration == s.viewMetadataAdmissionGeneration && + cn.DDLVisibilityBarrierReady + return false + }) + if err != nil { + return err + } + if published { + return nil + } + } + + timer := time.NewTimer(retryInterval) + select { + case <-ctx.Done(): + if !timer.Stop() { + select { + case <-timer.C: + default: + } + } + return moerr.NewInternalErrorf( + context.Background(), + "CN %s DDL visibility barrier was not published before startup deadline: %v", + s.cfg.UUID, + ctx.Err()) + case <-timer.C: + } + } +} + +func (s *service) syncStartupDDLVisibilityFrontier(ctx context.Context) error { + addresses := make([]string, 0, 4) + err := clusterservice.GetCNServiceRawWithContext( + ctx, + s.moCluster, + clusterservice.NewSelector(), + func(cn metadata.CNService) bool { + if cn.DDLVisibilityBarrierReady { + addresses = append(addresses, cn.QueryAddress) + } + return true + }) + if err != nil { + return err + } + + maxTS := timestamp.Timestamp{} + for _, address := range addresses { + if address == "" { + return moerr.NewInternalErrorNoCtx( + "barrier-ready CN has no query address during DDL visibility startup fence") + } + req := s.queryClient.NewRequest(query.CmdMethod_GetCommit) + resp, err := s.queryClient.SendMessage(ctx, address, req) + if err != nil { + return err + } + if resp == nil { + return moerr.NewInternalErrorf(ctx, "empty DDL frontier response from CN %s", address) + } + if resp.GetCommit == nil { + s.queryClient.Release(resp) + return moerr.NewInternalErrorf(ctx, "missing DDL frontier response from CN %s", address) + } + if maxTS.Less(resp.GetCommit.CurrentCommitTS) { + maxTS = resp.GetCommit.CurrentCommitTS + } + s.queryClient.Release(resp) + } + if maxTS.IsEmpty() { + return nil + } + if _, err := s._txnClient.WaitLogTailAppliedAt(ctx, maxTS); err != nil { + return err + } + s._txnClient.SyncLatestCommitTS(maxTS) + return nil +} diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go new file mode 100644 index 0000000000000..8e9796e3e1526 --- /dev/null +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -0,0 +1,201 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 + +package cnservice + +import ( + "context" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + + "github.com/matrixorigin/matrixone/pkg/clusterservice" + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/defines" + mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test" + "github.com/matrixorigin/matrixone/pkg/pb/metadata" + "github.com/matrixorigin/matrixone/pkg/pb/query" + "github.com/matrixorigin/matrixone/pkg/pb/timestamp" +) + +type ddlVisibilityTestCluster struct { + cnServices []metadata.CNService + refreshCalls int +} + +func (c *ddlVisibilityTestCluster) GetCNService( + selector clusterservice.Selector, + apply func(metadata.CNService) bool, +) { + c.forEachCN(selector, apply) +} + +func (*ddlVisibilityTestCluster) GetTNService( + clusterservice.Selector, + func(metadata.TNService) bool, +) { +} + +func (*ddlVisibilityTestCluster) GetAllTNServices() []metadata.TNService { return nil } + +func (c *ddlVisibilityTestCluster) GetCNServiceWithoutWorkingState( + selector clusterservice.Selector, + apply func(metadata.CNService) bool, +) { + c.forEachCN(selector, apply) +} + +func (c *ddlVisibilityTestCluster) forEachCN( + selector clusterservice.Selector, + apply func(metadata.CNService) bool, +) { + for _, cn := range c.cnServices { + if selector.MatchCN(cn) && !apply(cn) { + return + } + } +} + +func (*ddlVisibilityTestCluster) ForceRefresh(bool) {} +func (c *ddlVisibilityTestCluster) Refresh(context.Context) error { + c.refreshCalls++ + return nil +} +func (*ddlVisibilityTestCluster) Close() {} +func (*ddlVisibilityTestCluster) DebugUpdateCNLabel(string, map[string][]string) error { + return nil +} +func (*ddlVisibilityTestCluster) DebugUpdateCNWorkState(string, int) error { return nil } +func (*ddlVisibilityTestCluster) RemoveCN(string) {} +func (*ddlVisibilityTestCluster) AddCN(metadata.CNService) {} +func (*ddlVisibilityTestCluster) UpdateCN(metadata.CNService) {} + +type ddlVisibilityTestQueryClient struct { + serviceID string + frontiers map[string]timestamp.Timestamp + requests []string + methods []query.CmdMethod + releases int +} + +func (c *ddlVisibilityTestQueryClient) ServiceID() string { return c.serviceID } +func (c *ddlVisibilityTestQueryClient) SendMessage( + _ context.Context, + address string, + req *query.Request, +) (*query.Response, error) { + c.requests = append(c.requests, address) + c.methods = append(c.methods, req.CmdMethod) + return &query.Response{GetCommit: &query.GetCommitResponse{ + CurrentCommitTS: c.frontiers[address], + }}, nil +} +func (*ddlVisibilityTestQueryClient) NewRequest(method query.CmdMethod) *query.Request { + return &query.Request{CmdMethod: method} +} +func (c *ddlVisibilityTestQueryClient) Release(*query.Response) { c.releases++ } +func (*ddlVisibilityTestQueryClient) Close() error { return nil } + +func TestPrepareDDLVisibilityBarrier(t *testing.T) { + const serviceID = "ddl-visibility-startup-test" + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + targetTS := timestamp.Timestamp{PhysicalTime: 200, LogicalTime: 3} + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ + { + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: 7, DDLVisibilityBarrierReady: true, + }, + { + ServiceID: "peer", QueryAddress: "peer:6001", + ViewMetadataAdmissionGeneration: 9, DDLVisibilityBarrierReady: true, + }, + }} + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, + frontiers: map[string]timestamp.Timestamp{ + "self:6001": {PhysicalTime: 100}, + "peer:6001": targetTS, + }, + } + ctrl := gomock.NewController(t) + txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS.Next(), nil) + txnClient.EXPECT().SyncLatestCommitTS(targetTS) + + s := &service{ + cfg: &Config{UUID: serviceID}, + moCluster: cluster, + queryClient: queryClient, + _txnClient: txnClient, + viewMetadataAdmissionGeneration: 7, + } + require.NoError(t, s.prepareDDLVisibilityBarrier()) + require.True(t, s.ddlVisibilityBarrierReady.Load()) + require.Equal(t, 1, cluster.refreshCalls) + require.Equal(t, []string{"self:6001", "peer:6001"}, queryClient.requests) + require.Equal(t, []query.CmdMethod{query.CmdMethod_GetCommit, query.CmdMethod_GetCommit}, queryClient.methods) + require.Equal(t, 2, queryClient.releases) +} + +func TestPrepareDDLVisibilityBarrierRejectsMissingProductionDependencies(t *testing.T) { + const serviceID = "ddl-visibility-missing-dependency-test" + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + s := &service{ + cfg: &Config{UUID: serviceID}, + viewMetadataAdmissionGeneration: 1, + } + + err := s.prepareDDLVisibilityBarrier() + require.ErrorContains(t, err, "dependencies are unavailable") + require.True(t, s.ddlVisibilityBarrierReady.Load()) +} + +func TestPrepareDDLVisibilityBarrierSkipsFrontierSyncDuringRollingUpgrade(t *testing.T) { + const serviceID = "ddl-visibility-mixed-version-test" + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion31) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + + s := &service{cfg: &Config{UUID: serviceID}} + require.NoError(t, s.prepareDDLVisibilityBarrier()) + require.True(t, s.ddlVisibilityBarrierReady.Load()) +} + +func TestWaitForDDLVisibilityBarrierPublicationHonorsCancellation(t *testing.T) { + cluster := &ddlVisibilityTestCluster{} + s := &service{ + cfg: &Config{UUID: "unpublished-cn"}, + moCluster: cluster, + viewMetadataAdmissionGeneration: 1, + } + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + defer cancel() + + err := s.waitForDDLVisibilityBarrierPublication(ctx, time.Second) + require.Error(t, err) + require.Equal(t, 1, cluster.refreshCalls) +} + +func TestSyncStartupDDLVisibilityFrontierAllowsEmptyFrontier(t *testing.T) { + const serviceID = "ddl-visibility-empty-frontier-test" + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, QueryAddress: "self:6001", + DDLVisibilityBarrierReady: true, + }}} + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, + frontiers: map[string]timestamp.Timestamp{"self:6001": {}}, + } + s := &service{moCluster: cluster, queryClient: queryClient} + + require.NoError(t, s.syncStartupDDLVisibilityFrontier(context.Background())) + require.Equal(t, []string{"self:6001"}, queryClient.requests) + require.Equal(t, 1, queryClient.releases) +} diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 2a9b2c01fefb0..10c2b8a230f48 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -218,6 +218,7 @@ func (s *service) heartbeat(ctx context.Context) { ViewMetadataAdmissionGeneration: s.viewMetadataAdmissionGeneration, ViewMetadataCatalogFencedEpoch: s.viewMetadataCatalogFencedEpoch.Load(), ViewMetadataIngressReady: s.viewMetadataIngressReady.Load(), + DDLVisibilityBarrierReady: s.ddlVisibilityBarrierReady.Load(), } if s.viewMetadataEpochFence != nil { hb.ViewMetadataObservedEpoch = s.viewMetadataEpochFence.Epoch() diff --git a/pkg/cnservice/server_query.go b/pkg/cnservice/server_query.go index 54519b0017898..35b888ed818e5 100644 --- a/pkg/cnservice/server_query.go +++ b/pkg/cnservice/server_query.go @@ -147,6 +147,7 @@ func (s *service) initQueryCommandHandler() { s.addQueryCommandHandler(query.CmdMethod_GetTxnInfo, s.handleGetTxnInfo) s.addQueryCommandHandler(query.CmdMethod_GetCacheInfo, s.handleGetCacheInfo) s.addQueryCommandHandler(query.CmdMethod_SyncCommit, s.handleSyncCommit) + s.addQueryCommandHandler(query.CmdMethod_SyncCommitV2, s.handleSyncCommit) s.addQueryCommandHandler(query.CmdMethod_GetCommit, s.handleGetCommit) s.addQueryCommandHandler(query.CmdMethod_ShowProcessList, s.handleShowProcessList) s.addQueryCommandHandler(query.CmdMethod_RunTask, s.handleRunTask) diff --git a/pkg/cnservice/server_view_metadata_admission.go b/pkg/cnservice/server_view_metadata_admission.go index fa7332e792af8..912ec86778c3f 100644 --- a/pkg/cnservice/server_view_metadata_admission.go +++ b/pkg/cnservice/server_view_metadata_admission.go @@ -121,6 +121,7 @@ func (s *service) revokeViewMetadataGeneration(authoritative uint64) { s.viewMetadataRevocationOnce.Do(func() { s.viewMetadataGenerationRevoked.Store(true) s.viewMetadataIngressReady.Store(false) + s.ddlVisibilityBarrierReady.Store(false) _ = s.closePipelineAdmission() s.queryWork.beginClose() runner := s.detachRevokedTaskRunner() diff --git a/pkg/cnservice/types.go b/pkg/cnservice/types.go index 7520a3c572633..b0c89846e9454 100644 --- a/pkg/cnservice/types.go +++ b/pkg/cnservice/types.go @@ -799,6 +799,7 @@ type service struct { viewMetadataCatalogFenceMu sync.Mutex viewMetadataCatalogFenceReady atomic.Bool viewMetadataIngressReady atomic.Bool + ddlVisibilityBarrierReady atomic.Bool viewMetadataGenerationRevoked atomic.Bool viewMetadataRevocationOnce sync.Once // viewMetadataCloseFn is a deterministic test hook for the asynchronous diff --git a/pkg/defines/const.go b/pkg/defines/const.go index 16ac67dc9d08d..d91d5fcdf6e89 100644 --- a/pkg/defines/const.go +++ b/pkg/defines/const.go @@ -67,7 +67,8 @@ const ( MORPCVersion29 int64 = 29 // FOUND_ROWS connection migration state MORPCVersion30 int64 = 30 // prepared numeric-prefix common-type casts MORPCVersion31 int64 = 31 // batched multi-table remote transaction unlock - MORPCLatestVersion = MORPCVersion31 + MORPCVersion32 int64 = 32 // cancellable cross-CN DDL visibility fence + MORPCLatestVersion = MORPCVersion32 ) // DefaultLockWaitTimeoutSeconds is shared by the frontend default and by diff --git a/pkg/frontend/cdc_dao_sync_test.go b/pkg/frontend/cdc_dao_sync_test.go index 2333fd8fd2896..3a595c7dc2434 100644 --- a/pkg/frontend/cdc_dao_sync_test.go +++ b/pkg/frontend/cdc_dao_sync_test.go @@ -80,9 +80,10 @@ func (m *mockQueryClient) Close() error { // Mock MOCluster for testing type mockMOCluster struct { - cnServices []metadata.CNService - refreshCalls int - refreshError error + cnServices []metadata.CNService + refreshSnapshots [][]metadata.CNService + refreshCalls int + refreshError error } func (m *mockMOCluster) GetCNService(selector clusterservice.Selector, apply func(metadata.CNService) bool) { @@ -102,7 +103,11 @@ func (m *mockMOCluster) GetAllTNServices() []metadata.TNService { } func (m *mockMOCluster) GetCNServiceWithoutWorkingState(selector clusterservice.Selector, apply func(metadata.CNService) bool) { - // Not used in syncCommitTimestamp + for _, cn := range m.cnServices { + if !apply(cn) { + break + } + } } func (m *mockMOCluster) ForceRefresh(sync bool) { @@ -111,6 +116,9 @@ func (m *mockMOCluster) ForceRefresh(sync bool) { func (m *mockMOCluster) Refresh(context.Context) error { m.refreshCalls++ + if m.refreshCalls <= len(m.refreshSnapshots) { + m.cnServices = m.refreshSnapshots[m.refreshCalls-1] + } return m.refreshError } diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index 0a0885cea246e..e6312fa3807dc 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -17,6 +17,8 @@ package frontend import ( "context" "errors" + "maps" + "sort" "strings" "sync" "time" @@ -907,7 +909,7 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { // A fresh proxy connection has no session commit timestamp to carry // across CNs. Do not acknowledge a client DDL until every working CN // has reached the commit, or the observed catalog frontier for a no-op. - err = syncDDLCommitToWorkingCNs(ctx2, execCtx.ses.GetService(), visibilityTS) + err = syncDDLCommitToBarrierReadyCNs(ctx2, execCtx.ses.GetService(), visibilityTS) } } th.invalidateTxnUnsafe() @@ -915,11 +917,19 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { return err } -// syncDDLCommitToWorkingCNs waits until every CN that can accept a fresh proxy -// connection has applied the DDL visibility frontier. Embedded and test -// frontends may omit a query client because they do not expose a multi-CN -// routing boundary. -func syncDDLCommitToWorkingCNs( +type ddlVisibilityTarget struct { + serviceID string + generation uint64 + address string +} + +// syncDDLCommitToBarrierReadyCNs closes both sides of CN admission. A CN publishes +// barrier readiness before its startup frontier fence and public ingress. The +// DDL sender refreshes membership again after fan-out and repeats if any ready +// generation changed. Protocol v32 is a deployment gate: mixed-version +// clusters retain legacy behavior without invoking an old receiver's fatal +// SyncCommit path. +func syncDDLCommitToBarrierReadyCNs( ctx context.Context, service string, visibilityTS timestamp.Timestamp, @@ -930,59 +940,108 @@ func syncDDLCommitToWorkingCNs( } qc := pu.QueryClient + protocol, ok := moruntime.ServiceRuntime(qc.ServiceID()).GetGlobalVariables(moruntime.MOProtocolVersion) + protocolVersion, valid := protocol.(int64) + if !ok || !valid || protocolVersion < defines.MORPCVersion32 { + return nil + } cluster := clusterservice.GetMOCluster(qc.ServiceID()) if cluster == nil { return moerr.NewInternalError(ctx, "cannot establish DDL visibility barrier: cluster service is unavailable") } - if refresher, ok := cluster.(clusterservice.AuthoritativeRefresher); ok { + refresher, ok := cluster.(clusterservice.AuthoritativeRefresher) + if !ok { + return moerr.NewInternalError(ctx, "cannot establish DDL visibility barrier: authoritative refresh is unavailable") + } + + for { if err := refresher.Refresh(ctx); err != nil { return errors.Join( err, moerr.NewInternalError(ctx, "failed to refresh CNs for DDL visibility barrier"), ) } + targets, err := ddlVisibilityTargets(ctx, cluster) + if err != nil { + return err + } + if len(targets) == 0 { + return moerr.NewInternalError(ctx, "cannot establish DDL visibility barrier: no barrier-ready CN is available") + } + + ordered := make([]ddlVisibilityTarget, 0, len(targets)) + for _, target := range targets { + ordered = append(ordered, target) + } + sort.Slice(ordered, func(i, j int) bool { return ordered[i].serviceID < ordered[j].serviceID }) + for _, target := range ordered { + req := qc.NewRequest(querypb.CmdMethod_SyncCommitV2) + req.SycnCommit = &querypb.SyncCommitRequest{LatestCommitTS: visibilityTS} + resp, err := qc.SendMessage(ctx, target.address, req) + if err != nil { + return errors.Join( + err, + moerr.NewInternalErrorf(ctx, "failed to apply DDL commit on CN %s", target.address), + ) + } + if resp == nil { + return moerr.NewInternalErrorf(ctx, "empty DDL visibility response from CN %s", target.address) + } + qc.Release(resp) + } + + if err := refresher.Refresh(ctx); err != nil { + return errors.Join( + err, + moerr.NewInternalError(ctx, "failed to verify CNs for DDL visibility barrier"), + ) + } + verified, err := ddlVisibilityTargets(ctx, cluster) + if err != nil { + return err + } + if maps.Equal(targets, verified) { + return nil + } } +} - addresses := make([]string, 0, 4) +func ddlVisibilityTargets( + ctx context.Context, + cluster clusterservice.MOCluster, +) (map[string]ddlVisibilityTarget, error) { + targets := make(map[string]ddlVisibilityTarget) missingAddress := "" - cluster.GetCNService( + err := clusterservice.GetCNServiceRawWithContext( + ctx, + cluster, clusterservice.NewSelector(), func(cn metadata.CNService) bool { + if !cn.DDLVisibilityBarrierReady { + return true + } if cn.QueryAddress == "" { missingAddress = cn.ServiceID return false } - addresses = append(addresses, cn.QueryAddress) + targets[cn.ServiceID] = ddlVisibilityTarget{ + serviceID: cn.ServiceID, + generation: cn.ViewMetadataAdmissionGeneration, + address: cn.QueryAddress, + } return true - }, - ) + }) + if err != nil { + return nil, err + } if missingAddress != "" { - return moerr.NewInternalErrorf( + return nil, moerr.NewInternalErrorf( ctx, - "cannot establish DDL visibility barrier: working CN %s has no query address", + "cannot establish DDL visibility barrier: barrier-ready CN %s has no query address", missingAddress, ) } - if len(addresses) == 0 { - return moerr.NewInternalError(ctx, "cannot establish DDL visibility barrier: no working CN is available") - } - - for _, address := range addresses { - req := qc.NewRequest(querypb.CmdMethod_SyncCommit) - req.SycnCommit = &querypb.SyncCommitRequest{LatestCommitTS: visibilityTS} - resp, err := qc.SendMessage(ctx, address, req) - if err != nil { - return errors.Join( - err, - moerr.NewInternalErrorf(ctx, "failed to apply DDL commit on CN %s", address), - ) - } - if resp == nil { - return moerr.NewInternalErrorf(ctx, "empty DDL visibility response from CN %s", address) - } - qc.Release(resp) - } - return nil + return targets, nil } // Rollback rolls back the txn diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index 9c01a06a8d471..d9793897a3e64 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -906,13 +906,19 @@ func (c *ddlSyncQueryClient) Close() error { return nil } -func TestCommitSyncsDDLCommitToWorkingCNs(t *testing.T) { +func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { const queryServiceID = "ddl-sync-commit-test" commitTS := timestamp.Timestamp{PhysicalTime: 100, LogicalTime: 7} snapshotTS := timestamp.Timestamp{PhysicalTime: 90, LogicalTime: 5} targets := []metadata.CNService{ - {ServiceID: "cn-1", QueryAddress: "cn-1:6001"}, - {ServiceID: "cn-2", QueryAddress: "cn-2:6001"}, + { + ServiceID: "cn-1", QueryAddress: "cn-1:6001", + ViewMetadataAdmissionGeneration: 1, DDLVisibilityBarrierReady: true, + }, + { + ServiceID: "cn-2", QueryAddress: "cn-2:6001", + ViewMetadataAdmissionGeneration: 1, DDLVisibilityBarrierReady: true, + }, } newState := func(t *testing.T) (*Session, *testTxnOp, *ddlSyncQueryClient, *ExecCtx) { @@ -958,24 +964,91 @@ func TestCommitSyncsDDLCommitToWorkingCNs(t *testing.T) { return ses, op, qc, execCtx } - t.Run("waits for every working CN", func(t *testing.T) { + t.Run("waits for every stable barrier-ready CN", func(t *testing.T) { ses, op, qc, execCtx := newState(t) defer ses.Close() defer execCtx.Close() require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) require.Equal(t, []ddlSyncRequest{ - {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommit, commitTS: commitTS}, - {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommit, commitTS: commitTS}, + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, }, qc.requests) require.Equal(t, 2, qc.releases) cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) - require.Equal(t, 1, cluster.refreshCalls) + require.Equal(t, 2, cluster.refreshCalls) require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) require.Zero(t, op.rollbackCalls) require.Nil(t, ses.GetTxnHandler().GetTxn()) }) + t.Run("retries when a CN becomes barrier-ready during fan-out", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + expanded := append([]metadata.CNService{}, targets...) + expanded = append(expanded, metadata.CNService{ + ServiceID: "cn-3", QueryAddress: "cn-3:6001", + ViewMetadataAdmissionGeneration: 7, DDLVisibilityBarrierReady: true, + }) + cluster.refreshSnapshots = [][]metadata.CNService{targets, expanded, expanded, expanded} + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Equal(t, []ddlSyncRequest{ + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-3:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + }, qc.requests) + require.Equal(t, 5, qc.releases) + require.Equal(t, 4, cluster.refreshCalls) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("retries when a barrier-ready CN generation is replaced", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + replaced := append([]metadata.CNService{}, targets...) + replaced[1].ViewMetadataAdmissionGeneration = 2 + replaced[1].QueryAddress = "cn-2-new:6001" + cluster.refreshSnapshots = [][]metadata.CNService{targets, replaced, replaced, replaced} + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Equal(t, []ddlSyncRequest{ + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2-new:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + }, qc.requests) + require.Equal(t, 4, qc.releases) + require.Equal(t, 4, cluster.refreshCalls) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("mixed-version cluster does not call a legacy receiver", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + moruntime.ServiceRuntime(queryServiceID).SetGlobalVariables( + moruntime.MOProtocolVersion, + defines.MORPCVersion31, + ) + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Empty(t, qc.requests) + require.Zero(t, qc.releases) + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + require.Zero(t, cluster.refreshCalls) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + t.Run("does not acknowledge a membership refresh failure", func(t *testing.T) { ses, op, qc, execCtx := newState(t) defer ses.Close() @@ -1023,7 +1096,7 @@ func TestCommitSyncsDDLCommitToWorkingCNs(t *testing.T) { require.Nil(t, ses.GetTxnHandler().GetTxn()) }) - t.Run("rejects an empty working CN set", func(t *testing.T) { + t.Run("rejects an empty barrier-ready CN set", func(t *testing.T) { ses, op, qc, execCtx := newState(t) defer ses.Close() defer execCtx.Close() @@ -1033,23 +1106,25 @@ func TestCommitSyncsDDLCommitToWorkingCNs(t *testing.T) { ) err := ses.GetTxnHandler().Commit(execCtx) - require.ErrorContains(t, err, "no working CN is available") + require.ErrorContains(t, err, "no barrier-ready CN is available") require.Empty(t, qc.requests) require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) require.Nil(t, ses.GetTxnHandler().GetTxn()) }) - t.Run("rejects a working CN without query address", func(t *testing.T) { + t.Run("rejects a barrier-ready CN without query address", func(t *testing.T) { ses, op, qc, execCtx := newState(t) defer ses.Close() defer execCtx.Close() moruntime.ServiceRuntime(queryServiceID).SetGlobalVariables( moruntime.ClusterService, - &mockMOCluster{cnServices: []metadata.CNService{{ServiceID: "cn-missing-address"}}}, + &mockMOCluster{cnServices: []metadata.CNService{{ + ServiceID: "cn-missing-address", DDLVisibilityBarrierReady: true, + }}}, ) err := ses.GetTxnHandler().Commit(execCtx) - require.ErrorContains(t, err, "working CN cn-missing-address has no query address") + require.ErrorContains(t, err, "barrier-ready CN cn-missing-address has no query address") require.Empty(t, qc.requests) require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) require.Nil(t, ses.GetTxnHandler().GetTxn()) @@ -1063,8 +1138,8 @@ func TestCommitSyncsDDLCommitToWorkingCNs(t *testing.T) { require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) require.Equal(t, []ddlSyncRequest{ - {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommit, commitTS: snapshotTS.Prev()}, - {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommit, commitTS: snapshotTS.Prev()}, + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: snapshotTS.Prev()}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: snapshotTS.Prev()}, }, qc.requests) require.Equal(t, 2, qc.releases) require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) diff --git a/pkg/hakeeper/rsm.go b/pkg/hakeeper/rsm.go index fa9e52ef76526..1f09abdf71bf2 100644 --- a/pkg/hakeeper/rsm.go +++ b/pkg/hakeeper/rsm.go @@ -1749,6 +1749,7 @@ func (s *stateMachine) handleClusterDetailsQuery(cfg Config) *pb.ClusterDetails ViewMetadataAdmissionGeneration: info.ViewMetadataAdmissionGeneration, ViewMetadataObservedEpoch: info.ViewMetadataObservedEpoch, ViewMetadataAdmissionReady: info.ViewMetadataAdmissionReady, + DDLVisibilityBarrierReady: info.DDLVisibilityBarrierReady, } cd.CNStores = append(cd.CNStores, n) } diff --git a/pkg/hakeeper/view_metadata_admission_test.go b/pkg/hakeeper/view_metadata_admission_test.go index 5dc2c051dccb2..787ff2250308a 100644 --- a/pkg/hakeeper/view_metadata_admission_test.go +++ b/pkg/hakeeper/view_metadata_admission_test.go @@ -612,6 +612,7 @@ func TestClusterDetailsKeepsSupportedPendingButHidesLegacyIngress(t *testing.T) rsm.state.CNState.Stores["pending"] = pb.CNStoreInfo{ ViewMetadataAdmissionSupported: true, ViewMetadataAdmissionGeneration: 2, + DDLVisibilityBarrierReady: true, } rsm.state.CNState.Stores["ready"] = pb.CNStoreInfo{ ViewMetadataAdmissionSupported: true, @@ -629,6 +630,7 @@ func TestClusterDetailsKeepsSupportedPendingButHidesLegacyIngress(t *testing.T) } require.Contains(t, byID, "pending") require.False(t, byID["pending"].ViewMetadataAdmissionReady) + require.True(t, byID["pending"].DDLVisibilityBarrierReady) require.Contains(t, byID, "ready") require.NotContains(t, byID, "legacy") } diff --git a/pkg/pb/logservice/logservice.go b/pkg/pb/logservice/logservice.go index fffce7594142f..40c9bdaa8dc44 100644 --- a/pkg/pb/logservice/logservice.go +++ b/pkg/pb/logservice/logservice.go @@ -163,6 +163,7 @@ func (s *CNState) Update(hb CNStoreHeartbeat, tick uint64) { storeInfo.ViewMetadataRefreshSupported = hb.ViewMetadataRefreshSupported storeInfo.ViewMetadataRevalidatedEpoch = hb.ViewMetadataRevalidatedEpoch storeInfo.ViewMetadataIngressReady = hb.ViewMetadataIngressReady + storeInfo.DDLVisibilityBarrierReady = hb.DDLVisibilityBarrierReady s.Stores[hb.UUID] = storeInfo } diff --git a/pkg/pb/logservice/logservice.pb.go b/pkg/pb/logservice/logservice.pb.go index 187fb5f887d5e..0f7378d0bcab3 100644 --- a/pkg/pb/logservice/logservice.pb.go +++ b/pkg/pb/logservice/logservice.pb.go @@ -530,9 +530,12 @@ type CNStore struct { ViewMetadataAdmissionGeneration uint64 `protobuf:"varint,18,opt,name=ViewMetadataAdmissionGeneration,proto3" json:"ViewMetadataAdmissionGeneration,omitempty"` ViewMetadataObservedEpoch uint64 `protobuf:"varint,19,opt,name=ViewMetadataObservedEpoch,proto3" json:"ViewMetadataObservedEpoch,omitempty"` ViewMetadataAdmissionReady bool `protobuf:"varint,20,opt,name=ViewMetadataAdmissionReady,proto3" json:"ViewMetadataAdmissionReady,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + // DDLVisibilityBarrierReady means QueryService can accept the versioned DDL + // visibility fence even when public SQL ingress is not admitted yet. + DDLVisibilityBarrierReady bool `protobuf:"varint,21,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNStore) Reset() { *m = CNStore{} } @@ -701,6 +704,13 @@ func (m *CNStore) GetViewMetadataAdmissionReady() bool { return false } +func (m *CNStore) GetDDLVisibilityBarrierReady() bool { + if m != nil { + return m.DDLVisibilityBarrierReady + } + return false +} + type TNStore struct { UUID string `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"` ServiceAddress string `protobuf:"bytes,2,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` @@ -1184,10 +1194,11 @@ type CNStoreHeartbeat struct { ViewMetadataRevalidatedEpoch uint64 `protobuf:"varint,23,opt,name=ViewMetadataRevalidatedEpoch,proto3" json:"ViewMetadataRevalidatedEpoch,omitempty"` // ViewMetadataIngressReady is published only after every public CN ingress // listener has started successfully. Admission alone is not routability. - ViewMetadataIngressReady bool `protobuf:"varint,24,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ViewMetadataIngressReady bool `protobuf:"varint,24,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` + DDLVisibilityBarrierReady bool `protobuf:"varint,25,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNStoreHeartbeat) Reset() { *m = CNStoreHeartbeat{} } @@ -1384,6 +1395,13 @@ func (m *CNStoreHeartbeat) GetViewMetadataIngressReady() bool { return false } +func (m *CNStoreHeartbeat) GetDDLVisibilityBarrierReady() bool { + if m != nil { + return m.DDLVisibilityBarrierReady + } + return false +} + // CNAllocateID is the periodic message sent tp the HAKeeper by CN stores. type CNAllocateID struct { Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -4030,6 +4048,7 @@ type CNStoreInfo struct { ViewMetadataRevalidatedEpoch uint64 `protobuf:"varint,24,opt,name=ViewMetadataRevalidatedEpoch,proto3" json:"ViewMetadataRevalidatedEpoch,omitempty"` ViewMetadataAdmissionReady bool `protobuf:"varint,25,opt,name=ViewMetadataAdmissionReady,proto3" json:"ViewMetadataAdmissionReady,omitempty"` ViewMetadataIngressReady bool `protobuf:"varint,26,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` + DDLVisibilityBarrierReady bool `protobuf:"varint,27,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -4243,6 +4262,13 @@ func (m *CNStoreInfo) GetViewMetadataIngressReady() bool { return false } +func (m *CNStoreInfo) GetDDLVisibilityBarrierReady() bool { + if m != nil { + return m.DDLVisibilityBarrierReady + } + return false +} + // CNState contains all CN details known to the HAKeeper. type CNState struct { // Stores is keyed by CN store UUID. @@ -6465,378 +6491,380 @@ func init() { func init() { proto.RegisterFile("logservice.proto", fileDescriptor_fd1040c5381ab5a7) } var fileDescriptor_fd1040c5381ab5a7 = []byte{ - // 5923 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3d, 0x4d, 0x6f, 0x23, 0xc9, - 0x75, 0xd3, 0x24, 0x25, 0x91, 0x8f, 0x92, 0xa6, 0x55, 0xfa, 0x18, 0x8e, 0x66, 0x46, 0xa3, 0xe5, - 0x8e, 0x77, 0x67, 0xe5, 0xb5, 0xc6, 0x99, 0xf1, 0x2e, 0xd6, 0xce, 0x78, 0x76, 0x29, 0x92, 0x3b, - 0xe2, 0x0c, 0x45, 0x69, 0x9b, 0xad, 0x5d, 0xdb, 0xc0, 0x42, 0x68, 0x89, 0x35, 0x1a, 0x5a, 0x14, - 0x9b, 0xee, 0x6e, 0xcd, 0x47, 0x72, 0x0b, 0xe2, 0x20, 0x88, 0x81, 0x20, 0x06, 0x8c, 0xd8, 0x49, - 0xec, 0x7c, 0xdd, 0x72, 0xf2, 0x25, 0xf9, 0x0b, 0x81, 0x4f, 0x86, 0xe1, 0x63, 0x80, 0x38, 0xb6, - 0x73, 0x09, 0xe0, 0x6b, 0x10, 0x23, 0x87, 0x00, 0x41, 0x7d, 0x75, 0x57, 0x75, 0x57, 0x93, 0xd4, - 0xc7, 0x3a, 0xb1, 0xe1, 0x93, 0x58, 0xef, 0xa3, 0x3e, 0xdf, 0x7b, 0xf5, 0xea, 0xd5, 0xab, 0x16, - 0x98, 0x3d, 0xf7, 0xd0, 0xc7, 0xde, 0xb3, 0xee, 0x01, 0x5e, 0x1f, 0x78, 0x6e, 0xe0, 0x22, 0x88, - 0x20, 0xcb, 0x9f, 0x39, 0xec, 0x06, 0x4f, 0x4f, 0xf6, 0xd7, 0x0f, 0xdc, 0xe3, 0x3b, 0x87, 0xee, - 0xa1, 0x7b, 0x87, 0x92, 0xec, 0x9f, 0x3c, 0xa1, 0x25, 0x5a, 0xa0, 0xbf, 0x18, 0xeb, 0xf2, 0xcd, - 0x43, 0xd7, 0x3d, 0xec, 0xe1, 0x88, 0x2a, 0xe8, 0x1e, 0x63, 0x3f, 0x70, 0x8e, 0x07, 0x9c, 0x60, - 0xf6, 0x18, 0x07, 0x4e, 0xc7, 0x09, 0x1c, 0x56, 0x2e, 0xff, 0x70, 0x0a, 0xa6, 0xaa, 0xad, 0x76, - 0xe0, 0x7a, 0x18, 0x21, 0xc8, 0xed, 0xee, 0x36, 0x6a, 0x25, 0x63, 0xd5, 0xb8, 0x5d, 0xb0, 0xe8, - 0x6f, 0xf4, 0x1a, 0xcc, 0xb6, 0x59, 0x57, 0x2a, 0x9d, 0x8e, 0x87, 0x7d, 0xbf, 0x94, 0xa1, 0xd8, - 0x18, 0x14, 0xad, 0x00, 0xb4, 0x3f, 0x68, 0x0a, 0x9a, 0x2c, 0xa5, 0x91, 0x20, 0x68, 0x1d, 0x50, - 0xd3, 0x3d, 0x38, 0x8a, 0xd5, 0x95, 0xa3, 0x74, 0x1a, 0x0c, 0xba, 0x05, 0x39, 0xcb, 0xed, 0xe1, - 0xd2, 0xe4, 0xaa, 0x71, 0x7b, 0xf6, 0xae, 0xb9, 0x1e, 0x76, 0xbb, 0xda, 0x22, 0x70, 0x8b, 0x62, - 0x49, 0x8f, 0xed, 0xee, 0xc1, 0x51, 0x69, 0x6a, 0xd5, 0xb8, 0x9d, 0xb3, 0xe8, 0x6f, 0xf4, 0x69, - 0x98, 0x68, 0x07, 0x4e, 0x80, 0x4b, 0x79, 0xca, 0xba, 0xb8, 0x2e, 0xcd, 0x6f, 0xcb, 0xed, 0x60, - 0x8a, 0xb4, 0x18, 0x0d, 0xfa, 0x22, 0x4c, 0x36, 0x9d, 0x7d, 0xdc, 0xf3, 0x4b, 0x85, 0xd5, 0xec, - 0xed, 0xe2, 0xdd, 0x9b, 0x32, 0x35, 0x9f, 0x97, 0x75, 0x46, 0x51, 0xef, 0x07, 0xde, 0xcb, 0x8d, - 0xdc, 0x0f, 0x7e, 0x72, 0xf3, 0x92, 0xc5, 0x99, 0xd0, 0xef, 0x40, 0xe1, 0x23, 0xd7, 0x3b, 0x62, - 0xed, 0x01, 0x6d, 0x6f, 0x3e, 0xea, 0x6a, 0x88, 0xb2, 0x22, 0x2a, 0x54, 0x86, 0xe9, 0x0f, 0x4e, - 0xb0, 0xf7, 0x52, 0x4c, 0x41, 0x91, 0x4e, 0x81, 0x02, 0x43, 0x6f, 0x03, 0x54, 0xdd, 0xfe, 0x93, - 0xee, 0x61, 0xcd, 0x09, 0x9c, 0xd2, 0xf4, 0xaa, 0x71, 0xbb, 0x78, 0x77, 0x49, 0xe9, 0x59, 0x88, - 0xb5, 0x24, 0x4a, 0xf4, 0x36, 0xe4, 0x2d, 0xec, 0xbb, 0x27, 0xde, 0x01, 0x2e, 0xcd, 0x50, 0xae, - 0x05, 0x99, 0x4b, 0xe0, 0xf8, 0x20, 0x42, 0x5a, 0xb4, 0x04, 0x93, 0xbb, 0x03, 0xbb, 0x7b, 0x8c, - 0x4b, 0xb3, 0xab, 0xc6, 0xed, 0xac, 0xc5, 0x4b, 0xe8, 0xb3, 0x30, 0xdf, 0x7e, 0xea, 0x78, 0x9d, - 0xd8, 0xaa, 0x5d, 0xa6, 0x5d, 0xd6, 0xa1, 0xd0, 0x32, 0xe4, 0xab, 0xee, 0xf1, 0x71, 0x37, 0x68, - 0xd4, 0x4a, 0x26, 0x25, 0x0b, 0xcb, 0xe8, 0x7d, 0x58, 0xf9, 0xb0, 0x8b, 0x9f, 0x6f, 0xf1, 0xe9, - 0xa9, 0x74, 0x8e, 0xbb, 0xbe, 0xdf, 0x75, 0xfb, 0xed, 0x93, 0xc1, 0xc0, 0xf5, 0x02, 0xdc, 0x29, - 0xcd, 0xad, 0x1a, 0xb7, 0xf3, 0xd6, 0x08, 0x2a, 0xb4, 0x09, 0x37, 0xb5, 0x14, 0x0f, 0x71, 0x1f, - 0x7b, 0x4e, 0xd0, 0x75, 0xfb, 0x25, 0x44, 0xe5, 0x61, 0x14, 0x19, 0xba, 0x0f, 0x57, 0x65, 0x92, - 0xed, 0x7d, 0x32, 0x53, 0xb8, 0x53, 0x1f, 0xb8, 0x07, 0x4f, 0x4b, 0xf3, 0xb4, 0x8e, 0x74, 0x02, - 0xf4, 0x00, 0x96, 0xb5, 0x0d, 0x58, 0xd8, 0xe9, 0xbc, 0x2c, 0x2d, 0xd0, 0xb1, 0x0c, 0xa1, 0x58, - 0x6e, 0x41, 0x51, 0x92, 0x2c, 0x64, 0x42, 0xf6, 0x08, 0xbf, 0xe4, 0xca, 0x47, 0x7e, 0xa2, 0x37, - 0x60, 0xe2, 0x99, 0xd3, 0x3b, 0xc1, 0x54, 0xe5, 0x8a, 0xb2, 0x64, 0x51, 0xbe, 0x66, 0xd7, 0x0f, - 0x2c, 0x46, 0xf1, 0x85, 0xcc, 0x3b, 0xc6, 0xa3, 0x5c, 0x7e, 0xc2, 0x9c, 0x2c, 0xff, 0x32, 0x0b, - 0x53, 0xf6, 0x05, 0x28, 0xb4, 0x50, 0xad, 0xac, 0x4e, 0xb5, 0x72, 0x63, 0xa8, 0xd6, 0x5b, 0x30, - 0x49, 0x25, 0xc4, 0x2f, 0x4d, 0x50, 0xd5, 0xba, 0x22, 0x53, 0xdb, 0x2d, 0x8a, 0x6b, 0xf4, 0x9f, - 0xb8, 0x42, 0xa5, 0x18, 0x31, 0xba, 0x0b, 0x0b, 0x4d, 0xf7, 0x30, 0x70, 0xba, 0x3d, 0xd2, 0x21, - 0xec, 0x89, 0x5e, 0x4e, 0xd2, 0x5e, 0x6a, 0x71, 0x29, 0xc6, 0x65, 0x2a, 0xd5, 0xb8, 0xa8, 0xfa, - 0x55, 0x18, 0x5b, 0xbf, 0xe2, 0xba, 0x0b, 0x1a, 0xdd, 0x4d, 0xd1, 0x99, 0x62, 0xba, 0xce, 0xbc, - 0x07, 0xd7, 0x2a, 0x27, 0x81, 0xdb, 0xe8, 0x1f, 0x78, 0x54, 0xb0, 0xde, 0xc7, 0xfd, 0x03, 0x1c, - 0x29, 0xc5, 0x34, 0x15, 0xa4, 0x61, 0x24, 0x8f, 0x72, 0xf9, 0xbc, 0x59, 0x28, 0xff, 0x53, 0x06, - 0xf2, 0x4d, 0xf7, 0xf0, 0xff, 0xc1, 0xd2, 0xdf, 0x27, 0x76, 0x68, 0xd0, 0xeb, 0x1e, 0x38, 0x62, - 0xf1, 0x97, 0x65, 0xfa, 0xa6, 0x7b, 0xc8, 0xd1, 0xd2, 0xfa, 0x87, 0x1c, 0xb1, 0xd5, 0x99, 0x3c, - 0x8d, 0xf5, 0x6b, 0xba, 0x07, 0x4e, 0xaf, 0x1b, 0xbc, 0xa4, 0x6b, 0x1f, 0xb3, 0x7e, 0x02, 0x27, - 0xda, 0x13, 0xe5, 0xf2, 0xb7, 0xb2, 0x30, 0x4d, 0xe6, 0x4d, 0x08, 0x24, 0x2a, 0xc1, 0x14, 0x2b, - 0xb0, 0xe9, 0xcb, 0x59, 0xa2, 0x88, 0x36, 0xa4, 0x81, 0x65, 0xe8, 0xc0, 0x5e, 0x8b, 0x0d, 0x2c, - 0xac, 0x65, 0x5d, 0x10, 0x52, 0xed, 0x96, 0x86, 0xb7, 0x00, 0x13, 0xcc, 0xc0, 0xb0, 0xe9, 0x65, - 0x05, 0x62, 0x38, 0x9b, 0xd8, 0xe9, 0x60, 0xaf, 0x51, 0xa3, 0x53, 0x9c, 0xb3, 0xc2, 0x32, 0x5d, - 0x0f, 0xec, 0x1d, 0x97, 0x26, 0xf8, 0x7a, 0x60, 0xef, 0x18, 0x7d, 0x0c, 0x73, 0x2d, 0xb7, 0xff, - 0xa1, 0x1b, 0x74, 0xfb, 0x87, 0x61, 0x97, 0x26, 0x69, 0x97, 0xee, 0xa4, 0x76, 0x29, 0xc1, 0xc1, - 0xfa, 0x96, 0xac, 0x69, 0xf9, 0x77, 0x61, 0x46, 0xa1, 0x91, 0xad, 0x53, 0x8e, 0x59, 0xa7, 0x05, - 0xd9, 0x3a, 0x15, 0x24, 0x43, 0xb4, 0x5c, 0x83, 0x25, 0x7d, 0x4b, 0xa7, 0xa9, 0xa5, 0xfc, 0x1d, - 0x03, 0x66, 0x55, 0x49, 0x41, 0xef, 0xab, 0x0b, 0x45, 0xeb, 0x29, 0xde, 0x2d, 0xa5, 0x8d, 0x77, - 0x23, 0x4f, 0x56, 0xfa, 0x47, 0x3f, 0xb9, 0x69, 0x58, 0xea, 0x02, 0x5f, 0x87, 0x82, 0xa8, 0xb6, - 0x46, 0x1b, 0xce, 0x59, 0x11, 0x00, 0xad, 0x42, 0xb1, 0xe1, 0x87, 0x03, 0xa0, 0xcb, 0x94, 0xb7, - 0x64, 0x50, 0xf9, 0x4f, 0x8c, 0x68, 0xa3, 0xa5, 0x5b, 0xde, 0xce, 0xae, 0xed, 0x06, 0x4e, 0x8f, - 0x0f, 0x2c, 0x2c, 0x13, 0x83, 0x51, 0xdd, 0xd9, 0xad, 0x3c, 0x73, 0xba, 0x3d, 0x67, 0xbf, 0xc7, - 0x06, 0x69, 0x58, 0x0a, 0x8c, 0xf0, 0x6f, 0xe1, 0x63, 0xc6, 0xcf, 0x44, 0x22, 0x2c, 0x13, 0xfe, - 0x2d, 0x7c, 0x1c, 0xf1, 0x33, 0xc9, 0x50, 0x60, 0xe5, 0xef, 0x16, 0xc0, 0xe4, 0x9e, 0xca, 0x26, - 0x76, 0xbc, 0x60, 0x1f, 0x3b, 0xc1, 0xaf, 0xa1, 0x2b, 0xb7, 0x0e, 0xc8, 0x76, 0x7c, 0xc1, 0x5b, - 0xf5, 0xb0, 0x43, 0x8c, 0xdf, 0x14, 0x9d, 0x7c, 0x0d, 0x26, 0x61, 0x8b, 0xf3, 0x1a, 0x5b, 0x7c, - 0x0b, 0x66, 0x1a, 0xfd, 0x6e, 0x10, 0xb9, 0x68, 0x05, 0x4a, 0xa4, 0x02, 0x09, 0xd5, 0x43, 0xd7, - 0xf7, 0xbb, 0x03, 0xd5, 0xac, 0xab, 0x40, 0xd2, 0x1e, 0x03, 0x3c, 0x72, 0xbb, 0x7d, 0xdc, 0xa1, - 0x06, 0x3d, 0x6f, 0x29, 0xb0, 0x5f, 0xb9, 0xdf, 0x96, 0xb2, 0xd7, 0xcc, 0x8e, 0xe7, 0x9f, 0x5d, - 0x8e, 0xf9, 0x67, 0x9f, 0x85, 0xf9, 0xca, 0xc1, 0x11, 0xee, 0x10, 0x80, 0xd3, 0xef, 0x6c, 0x38, - 0xc1, 0xc1, 0x53, 0xee, 0xc6, 0xe5, 0x2c, 0x1d, 0x8a, 0xec, 0x5c, 0x1c, 0x52, 0xc3, 0xbd, 0xee, - 0x33, 0x32, 0xf3, 0x07, 0x47, 0x71, 0x77, 0x6e, 0x18, 0xc9, 0x18, 0x3e, 0x21, 0xba, 0x28, 0x9f, - 0x70, 0xfe, 0x02, 0x7c, 0xc2, 0x85, 0x51, 0x3e, 0x61, 0x6c, 0x3c, 0x55, 0x27, 0x70, 0x7a, 0xee, - 0x21, 0xdd, 0xae, 0x79, 0x15, 0x8b, 0xb4, 0x8a, 0x11, 0x54, 0x68, 0x03, 0xae, 0xcb, 0x14, 0x16, - 0x7e, 0xe2, 0x61, 0xff, 0x69, 0x34, 0x2b, 0x4b, 0x74, 0x56, 0x86, 0xd2, 0x24, 0xeb, 0x78, 0xe6, - 0xf4, 0xba, 0x1d, 0xa2, 0x3c, 0xac, 0x27, 0x57, 0x68, 0x4f, 0x86, 0xd2, 0xa0, 0x2f, 0x40, 0x49, - 0xc6, 0x37, 0xfa, 0x87, 0x44, 0x8c, 0x98, 0x87, 0x5b, 0xa2, 0x7d, 0x48, 0xc5, 0x73, 0x7f, 0xd4, - 0x86, 0xe9, 0x6a, 0xab, 0xd2, 0xeb, 0xb9, 0x07, 0x4e, 0x80, 0x1b, 0x35, 0x8d, 0x9b, 0xbb, 0x00, - 0x13, 0x54, 0xa0, 0xb8, 0x25, 0x66, 0x05, 0x66, 0xa3, 0xbf, 0x76, 0x82, 0x7d, 0x22, 0xaa, 0xcc, - 0x08, 0x45, 0x80, 0xf2, 0x7f, 0x67, 0x61, 0x4e, 0xf8, 0x3a, 0xc3, 0xad, 0xde, 0x2a, 0x14, 0x2d, - 0xe7, 0x49, 0xa0, 0x9a, 0x3c, 0x19, 0xa4, 0xb1, 0x8b, 0x59, 0xad, 0x5d, 0x4c, 0xd8, 0x89, 0x9c, - 0xce, 0x4e, 0x9c, 0xcf, 0xf7, 0xd1, 0x5b, 0xc1, 0xc9, 0x54, 0x2b, 0xa8, 0x5a, 0x9c, 0xa9, 0x33, - 0xf9, 0x4a, 0xf9, 0xf1, 0x7d, 0x25, 0x22, 0x0f, 0x31, 0x75, 0x8e, 0x64, 0xb2, 0xc0, 0xe4, 0x21, - 0x0d, 0x3f, 0x86, 0xae, 0xc3, 0x38, 0xba, 0x5e, 0xae, 0x43, 0x51, 0x3a, 0x3e, 0x0c, 0xf1, 0xd6, - 0x86, 0x6e, 0xf3, 0xe5, 0xaf, 0x4f, 0x80, 0x69, 0x5f, 0xe4, 0xbe, 0x19, 0x1d, 0x78, 0xb2, 0xa7, - 0x39, 0xf0, 0xe8, 0x97, 0x3c, 0x97, 0xba, 0xe4, 0x69, 0x07, 0xa4, 0x89, 0x53, 0x1f, 0x90, 0x26, - 0xc7, 0x3c, 0x20, 0xe5, 0xcf, 0x7c, 0x40, 0x2a, 0x8c, 0x7f, 0x40, 0x82, 0xf4, 0x4d, 0x8b, 0xa8, - 0x30, 0x1e, 0xf4, 0x9c, 0x97, 0xb8, 0xd3, 0xf4, 0xfb, 0x74, 0xe7, 0xcd, 0x59, 0x32, 0xe8, 0xfc, - 0x47, 0xa8, 0xb4, 0xcd, 0x6f, 0xe6, 0xcc, 0x9b, 0xdf, 0xec, 0xc8, 0xcd, 0xef, 0x51, 0x2e, 0x3f, - 0x65, 0xe6, 0xcb, 0xdf, 0x9f, 0x80, 0xbc, 0xd5, 0xde, 0x62, 0xbe, 0x88, 0x09, 0x59, 0xdb, 0x77, - 0x85, 0x83, 0x6c, 0xfb, 0x2e, 0xb1, 0x8e, 0x8d, 0x7e, 0x07, 0xbf, 0x10, 0xd6, 0x91, 0x16, 0x88, - 0x2d, 0x6a, 0x62, 0xc7, 0xc7, 0x9b, 0x6e, 0x8f, 0x9d, 0x19, 0x98, 0xe7, 0xa8, 0x02, 0xc9, 0x72, - 0xd8, 0xde, 0x49, 0x9f, 0x58, 0x5e, 0x3a, 0x73, 0xdc, 0x7d, 0x94, 0x61, 0xe8, 0x11, 0x4c, 0x33, - 0xa6, 0xae, 0x1f, 0xb8, 0xde, 0x4b, 0x6e, 0xb3, 0x94, 0x63, 0x8d, 0xe8, 0xdd, 0xba, 0x4c, 0xc8, - 0x8e, 0x0e, 0x0a, 0x2f, 0x5b, 0xa8, 0xaf, 0x9d, 0x74, 0x3d, 0xd6, 0xdc, 0xa4, 0x58, 0xa8, 0x10, - 0x84, 0xde, 0x84, 0xb9, 0x8f, 0x2a, 0x4d, 0x0b, 0x1f, 0xb8, 0x64, 0x36, 0x6a, 0xdd, 0x43, 0xec, - 0x07, 0xfc, 0xa0, 0x9e, 0x44, 0xa0, 0xcf, 0xc1, 0xa2, 0x04, 0xa4, 0x2d, 0x56, 0xdd, 0x93, 0x7e, - 0x40, 0x25, 0x32, 0x67, 0xe9, 0x91, 0x64, 0x61, 0x24, 0x44, 0xd5, 0x3d, 0x1e, 0xf4, 0x30, 0xd9, - 0xd0, 0xfa, 0x81, 0xd7, 0xc5, 0x4c, 0x26, 0x73, 0xd6, 0x30, 0x12, 0xa2, 0x2e, 0x12, 0x7a, 0xc3, - 0xf1, 0x31, 0x19, 0x0e, 0x50, 0x46, 0x0d, 0x26, 0x46, 0xdf, 0x74, 0xfc, 0x20, 0x92, 0x53, 0x0d, - 0x06, 0x3d, 0x82, 0x55, 0x09, 0xba, 0xed, 0x75, 0x0f, 0xbb, 0x7d, 0xa7, 0xa7, 0x2e, 0xe8, 0x34, - 0xe5, 0x1e, 0x49, 0x47, 0x04, 0x57, 0x33, 0x14, 0x2a, 0xb8, 0x79, 0x4b, 0x87, 0x5a, 0x7e, 0x17, - 0xe6, 0x12, 0x0b, 0x39, 0xea, 0x64, 0x96, 0x93, 0x4f, 0x66, 0x1f, 0x43, 0x81, 0x6e, 0x63, 0x07, - 0xae, 0xd7, 0x21, 0x8c, 0x64, 0xb0, 0x9c, 0x91, 0x8c, 0x6e, 0x0d, 0x72, 0xf6, 0xcb, 0x01, 0xe3, - 0x9b, 0x55, 0xcd, 0x06, 0xe3, 0x21, 0x58, 0x8b, 0xd2, 0x10, 0x7b, 0x4b, 0x4d, 0x0c, 0x11, 0xdf, - 0x69, 0x8b, 0xfe, 0x2e, 0xff, 0x34, 0x03, 0x40, 0xeb, 0xa7, 0x9b, 0x3d, 0x21, 0x69, 0x39, 0xc7, - 0x58, 0x98, 0x64, 0xf2, 0x5b, 0xb6, 0xf9, 0x19, 0xd5, 0xe6, 0xf3, 0xee, 0x64, 0xa3, 0xee, 0x94, - 0x60, 0x6a, 0xcb, 0x79, 0xd1, 0xee, 0xfe, 0x9e, 0x38, 0x3e, 0x89, 0x22, 0xd9, 0x1f, 0x84, 0x59, - 0xae, 0xf1, 0xc3, 0x75, 0x04, 0xa0, 0xa7, 0xee, 0x56, 0xa3, 0xc6, 0xa5, 0x98, 0xfe, 0x46, 0x9f, - 0x83, 0x8c, 0xdd, 0xe6, 0xdb, 0xec, 0xf2, 0x3a, 0x8b, 0xb5, 0xaf, 0x8b, 0x58, 0xfb, 0xba, 0x2d, - 0x62, 0xed, 0xec, 0xe0, 0xf9, 0x67, 0xff, 0x76, 0xd3, 0xb0, 0x32, 0x76, 0x9b, 0x6c, 0x7c, 0x8d, - 0xfe, 0x41, 0xef, 0xa4, 0x83, 0xeb, 0x2f, 0x06, 0x44, 0x13, 0xf8, 0x26, 0xc4, 0xed, 0x1b, 0x66, - 0x87, 0x97, 0xbc, 0x35, 0x82, 0x8a, 0x38, 0xb9, 0xf5, 0x17, 0x94, 0x62, 0xd3, 0xf1, 0x3a, 0x35, - 0xf7, 0x79, 0x3f, 0x51, 0x11, 0xdb, 0x83, 0x47, 0x91, 0x95, 0xcb, 0x00, 0xb6, 0xef, 0x8a, 0x19, - 0x5e, 0x80, 0x09, 0xa6, 0x56, 0x6c, 0x11, 0x59, 0xa1, 0xfc, 0x0b, 0x83, 0x78, 0x6e, 0x74, 0x7f, - 0xa4, 0xe1, 0x46, 0xed, 0xde, 0x78, 0x0f, 0x0a, 0xdb, 0x03, 0xe1, 0x61, 0x67, 0x92, 0xa1, 0xa1, - 0x6a, 0x8b, 0xf2, 0x6e, 0x0f, 0xac, 0x88, 0x0e, 0x6d, 0x84, 0x41, 0x77, 0xb6, 0x51, 0xde, 0xd2, - 0x04, 0xdd, 0x29, 0x41, 0x7a, 0xe4, 0xfd, 0xa2, 0x83, 0xa7, 0xe5, 0x26, 0x14, 0xab, 0xad, 0xe8, - 0x4c, 0xa8, 0x1b, 0xeb, 0x1b, 0x22, 0x04, 0x96, 0x49, 0x0f, 0xf4, 0x33, 0x8a, 0xf2, 0xcf, 0xf8, - 0xdc, 0x39, 0xc1, 0x90, 0xb9, 0x1b, 0xbf, 0xbe, 0xd1, 0x33, 0x26, 0x1a, 0xfa, 0x15, 0xce, 0xd8, - 0x37, 0xf3, 0x30, 0x25, 0x24, 0x48, 0x71, 0xd6, 0x0d, 0xe1, 0x69, 0x71, 0x00, 0x5a, 0x87, 0xc9, - 0x2d, 0x1c, 0x3c, 0x75, 0x3b, 0x3a, 0x93, 0xc0, 0x30, 0xd4, 0x24, 0x70, 0x2a, 0x74, 0x5f, 0xd6, - 0x7f, 0xaa, 0xca, 0x31, 0xef, 0x23, 0xc2, 0xf2, 0x31, 0xca, 0xf6, 0xa2, 0x42, 0x83, 0x44, 0xa1, - 0x4b, 0x47, 0x95, 0xbe, 0x78, 0xf7, 0x46, 0x3c, 0x48, 0xa4, 0xf8, 0x7d, 0x96, 0xc2, 0x82, 0x1e, - 0x10, 0x61, 0x88, 0x6a, 0x98, 0xa0, 0x35, 0x5c, 0xd7, 0x48, 0x69, 0x54, 0x81, 0xcc, 0x40, 0xf8, - 0x6d, 0x89, 0x7f, 0x32, 0xc9, 0x6f, 0x27, 0xf8, 0x25, 0x06, 0xe2, 0x7e, 0x45, 0xea, 0xa9, 0xf3, - 0xea, 0x23, 0xac, 0x25, 0x2b, 0xf2, 0x7d, 0xf5, 0xac, 0xc5, 0x1d, 0xb7, 0x92, 0xda, 0xf1, 0x08, - 0x6f, 0xa9, 0x27, 0xb3, 0xfb, 0xaa, 0xbe, 0xf3, 0xb8, 0x78, 0x29, 0x4d, 0x39, 0x2d, 0xd5, 0x3a, - 0x7c, 0x5e, 0x51, 0x20, 0xba, 0x59, 0xc6, 0x5c, 0x60, 0x09, 0x6d, 0x29, 0xca, 0x76, 0x5f, 0x55, - 0x16, 0xba, 0x71, 0x6a, 0x1a, 0x16, 0x78, 0x4b, 0x55, 0xad, 0x77, 0x61, 0xa6, 0x86, 0xc9, 0xc6, - 0xc6, 0xbb, 0xc3, 0xe3, 0x2e, 0x57, 0x65, 0x76, 0x85, 0xc0, 0x52, 0xe9, 0xd1, 0x06, 0xcc, 0xee, - 0x78, 0xee, 0x8b, 0x97, 0xd1, 0x82, 0xcd, 0x70, 0x03, 0x2f, 0xd5, 0xa0, 0x52, 0x58, 0x31, 0x0e, - 0xb2, 0x0b, 0xc7, 0x43, 0x9e, 0xad, 0x93, 0x63, 0xea, 0x04, 0xe6, 0x2c, 0x1d, 0x0a, 0x6d, 0x48, - 0x01, 0xdc, 0xf0, 0x28, 0x76, 0x39, 0xfd, 0x28, 0x66, 0x25, 0xc9, 0xe9, 0x9c, 0x3f, 0xc5, 0x07, - 0x47, 0x9b, 0xd8, 0xe9, 0x05, 0x4f, 0x69, 0xa4, 0x26, 0x3e, 0xe7, 0x11, 0xda, 0x92, 0x69, 0x91, - 0x0d, 0x0b, 0xed, 0x83, 0xa7, 0xb8, 0x73, 0xd2, 0xc3, 0xdc, 0x45, 0xa5, 0x4e, 0x3a, 0x8d, 0xd9, - 0x14, 0xef, 0xae, 0xca, 0x75, 0xe8, 0xe8, 0x2c, 0x2d, 0x77, 0xd9, 0x85, 0x22, 0xd5, 0x44, 0x7f, - 0xe0, 0xf6, 0x7d, 0x3c, 0xe4, 0x68, 0xc6, 0xb7, 0xe9, 0x8c, 0xb2, 0x4d, 0x0b, 0xc7, 0x89, 0x6d, - 0xde, 0xa2, 0x38, 0x2c, 0x34, 0x5e, 0x5e, 0x07, 0x24, 0xc9, 0xb3, 0xd4, 0xee, 0xfb, 0x5d, 0x4f, - 0x32, 0x46, 0xa2, 0x58, 0xfe, 0xaf, 0x1c, 0x0d, 0xb5, 0x31, 0xb2, 0x8b, 0xb5, 0x5a, 0xd7, 0xa1, - 0x50, 0xf7, 0x3c, 0xd7, 0xab, 0xba, 0x1d, 0x4c, 0x87, 0x30, 0x63, 0x45, 0x00, 0xe2, 0x8a, 0xd3, - 0xc2, 0x16, 0xf6, 0x7d, 0xe7, 0x10, 0xf3, 0xd8, 0x81, 0x02, 0x43, 0x2b, 0x00, 0x0d, 0x7f, 0xb3, - 0xf2, 0x18, 0xe3, 0x01, 0xf6, 0xa8, 0xd5, 0xc9, 0x5b, 0x12, 0x04, 0xbd, 0xab, 0xcc, 0x2e, 0x37, - 0x2b, 0x57, 0x12, 0x86, 0x91, 0xa1, 0xb9, 0x65, 0x54, 0xd6, 0x83, 0x28, 0x9a, 0x74, 0x88, 0xe1, - 0x96, 0x45, 0x55, 0x34, 0x09, 0x6f, 0x29, 0xd4, 0x44, 0xda, 0xa8, 0xad, 0xe1, 0xcd, 0xe7, 0x93, - 0xcd, 0x4b, 0x68, 0x4b, 0xa6, 0x25, 0x2a, 0x56, 0xed, 0x9d, 0xf8, 0x01, 0xf6, 0x6a, 0x98, 0x9c, - 0x4e, 0x7d, 0x6e, 0x5c, 0x14, 0x15, 0x53, 0x29, 0xac, 0x18, 0x07, 0x7a, 0x00, 0x85, 0x28, 0xf2, - 0x0f, 0x1a, 0x31, 0x15, 0x48, 0x26, 0xa0, 0xd8, 0x3f, 0xe9, 0x05, 0x56, 0xc4, 0x82, 0x1e, 0x00, - 0x48, 0xa6, 0x91, 0xd9, 0x98, 0x15, 0xb9, 0x82, 0xa4, 0x20, 0x59, 0x10, 0x33, 0x8f, 0x44, 0x81, - 0xb0, 0xc7, 0x2c, 0xdc, 0xb4, 0x66, 0xf2, 0x24, 0xbc, 0xa5, 0x50, 0x97, 0x1f, 0xd1, 0x78, 0x15, - 0xf3, 0x7f, 0xc3, 0x69, 0x79, 0x8b, 0xec, 0xa0, 0x04, 0xe2, 0x97, 0x0c, 0xba, 0xaf, 0x2f, 0x26, - 0x16, 0x93, 0x60, 0xf9, 0x52, 0x0a, 0xda, 0xf2, 0xab, 0xca, 0x42, 0x10, 0xf7, 0xed, 0x43, 0xba, - 0x6f, 0x73, 0xf7, 0x8d, 0x16, 0xca, 0x0f, 0x61, 0xc6, 0x76, 0xfc, 0x23, 0xdb, 0xd9, 0xef, 0xe1, - 0x5d, 0x1f, 0x7b, 0x44, 0x8d, 0xc8, 0xdf, 0x7e, 0xe4, 0x4b, 0x87, 0x65, 0x82, 0xdb, 0x71, 0x7c, - 0xff, 0xb9, 0xeb, 0x75, 0x78, 0x70, 0x23, 0x2c, 0x97, 0xbf, 0x61, 0x90, 0x5e, 0x52, 0xbb, 0xa5, - 0x75, 0x63, 0xd2, 0x7d, 0x71, 0x25, 0xfe, 0x92, 0x8d, 0x5f, 0xb3, 0x84, 0xf7, 0x60, 0x39, 0xf9, - 0x1e, 0x6c, 0x85, 0xee, 0xfd, 0xaa, 0x53, 0x2e, 0x41, 0xca, 0x7f, 0x99, 0x21, 0x32, 0xdc, 0x7f, - 0xd2, 0x3d, 0xac, 0x3e, 0x75, 0xfa, 0x87, 0x18, 0xdd, 0x0b, 0x7b, 0xc7, 0xaf, 0x83, 0xe6, 0xd5, - 0x03, 0x07, 0x45, 0x45, 0x33, 0xc8, 0xc6, 0x71, 0x1f, 0x80, 0xb1, 0x4b, 0x07, 0x95, 0xeb, 0xc9, - 0xf8, 0x46, 0x44, 0x63, 0x49, 0xf4, 0xc8, 0x86, 0xd9, 0x46, 0xbf, 0x1b, 0x74, 0x9d, 0xde, 0x16, - 0x3e, 0xde, 0xc7, 0x9e, 0xf0, 0xca, 0xde, 0x4c, 0xab, 0x61, 0x5d, 0x25, 0x67, 0x47, 0xe7, 0x58, - 0x1d, 0xcb, 0x15, 0x98, 0xd7, 0x90, 0x9d, 0xea, 0xca, 0xec, 0x0d, 0x98, 0x69, 0x3f, 0x3d, 0x09, - 0x3a, 0xee, 0xf3, 0x3e, 0xdb, 0xda, 0xc8, 0xda, 0x90, 0x1f, 0xe1, 0x92, 0x89, 0x62, 0xf9, 0x1f, - 0x26, 0xe0, 0x72, 0xcc, 0x84, 0x6b, 0x57, 0xf7, 0x16, 0xcc, 0x6c, 0xb8, 0x6e, 0xe0, 0x07, 0x9e, - 0x33, 0x18, 0x74, 0xfb, 0x87, 0xb4, 0xd1, 0xbc, 0xa5, 0x02, 0x89, 0x69, 0xe0, 0x31, 0x1b, 0x3a, - 0xa1, 0x59, 0x3a, 0xa1, 0x8a, 0x69, 0x90, 0xd0, 0x96, 0x4c, 0xcb, 0x6c, 0x52, 0x34, 0x55, 0xdc, - 0x5d, 0x2b, 0xa5, 0x4d, 0xa5, 0xa5, 0xae, 0xfe, 0xbb, 0xb1, 0x11, 0x73, 0x5f, 0xed, 0xaa, 0x6a, - 0x18, 0x24, 0x02, 0x2b, 0x36, 0x43, 0x8f, 0x61, 0x8e, 0x05, 0xd6, 0xa4, 0x48, 0x1b, 0xb7, 0xac, - 0x8a, 0xcb, 0x98, 0x20, 0xb2, 0x92, 0x7c, 0x49, 0x57, 0x64, 0xea, 0x94, 0xae, 0xc8, 0x63, 0x98, - 0x7b, 0xe4, 0x76, 0xfb, 0x2c, 0xa2, 0xcc, 0xed, 0x1f, 0x37, 0xb4, 0x4a, 0x6f, 0x12, 0x44, 0x56, - 0x92, 0x0f, 0x6d, 0x82, 0xc9, 0x6a, 0xa7, 0xbe, 0x0a, 0xeb, 0x50, 0x21, 0xe9, 0x8a, 0xc6, 0x69, - 0xac, 0x04, 0x17, 0x59, 0xde, 0x4a, 0xa7, 0x23, 0xb4, 0x50, 0xe7, 0xdb, 0x49, 0x68, 0x4b, 0xa6, - 0x25, 0x96, 0x3f, 0x14, 0x15, 0xc6, 0x5d, 0x4c, 0x5a, 0x7e, 0x95, 0xc2, 0x8a, 0x71, 0x94, 0xb1, - 0xde, 0x57, 0xd1, 0xca, 0x6b, 0x4c, 0x12, 0x33, 0xe3, 0x4b, 0x62, 0xf9, 0xcf, 0x33, 0xb0, 0x14, - 0x0b, 0xd7, 0xd9, 0x8e, 0x77, 0x88, 0x03, 0x7a, 0xf9, 0xc7, 0x97, 0x88, 0x34, 0xc2, 0xac, 0x75, - 0xc1, 0x52, 0x60, 0x34, 0xd8, 0x26, 0xd3, 0x64, 0x18, 0x8d, 0x0c, 0x23, 0x76, 0xb6, 0xfe, 0x82, - 0x98, 0xa0, 0x6e, 0xc0, 0xef, 0x95, 0xc3, 0x32, 0x71, 0x21, 0x79, 0x7d, 0x76, 0xf7, 0x18, 0xbb, - 0x27, 0x81, 0xdd, 0x3d, 0x38, 0xf2, 0xb9, 0x75, 0xd4, 0xa1, 0x08, 0x87, 0xad, 0xe1, 0x60, 0x46, - 0x53, 0x87, 0x42, 0x9f, 0x83, 0xc5, 0x3a, 0x31, 0x17, 0x4e, 0x80, 0xab, 0x27, 0x9e, 0x87, 0xfb, - 0x01, 0xa5, 0xf1, 0xf9, 0x0d, 0x83, 0x1e, 0x59, 0xbe, 0xa3, 0x91, 0x4a, 0x36, 0x94, 0xae, 0x4f, - 0xaf, 0xc8, 0xd9, 0x74, 0x84, 0xe5, 0x72, 0x4f, 0xa3, 0x54, 0xe8, 0x1e, 0xe4, 0xc8, 0x7e, 0xc3, - 0xad, 0xb4, 0xa2, 0x13, 0xca, 0x46, 0xc5, 0x6d, 0x35, 0x25, 0xa6, 0x93, 0xea, 0xf8, 0x47, 0x35, - 0x27, 0x70, 0xf6, 0x1d, 0x5f, 0x98, 0x3c, 0x05, 0x46, 0xac, 0x9e, 0xaa, 0x45, 0xe9, 0x56, 0xef, - 0xcd, 0xa4, 0x4a, 0x0c, 0xa1, 0x7e, 0x5d, 0x11, 0xfb, 0x74, 0x6f, 0xb6, 0xfc, 0x4b, 0x23, 0x2e, - 0xe5, 0x67, 0xbd, 0x95, 0x40, 0x1f, 0xa6, 0xec, 0x2d, 0xeb, 0xe9, 0xfa, 0x32, 0xce, 0xee, 0x42, - 0x74, 0x85, 0xac, 0x21, 0xbf, 0x57, 0xa0, 0xbf, 0x2f, 0x62, 0xc7, 0xf9, 0x8b, 0x8c, 0xea, 0x52, - 0x86, 0xb9, 0x2a, 0x86, 0x94, 0xab, 0xf2, 0x45, 0x76, 0xe9, 0xec, 0xf4, 0x3b, 0x22, 0x6b, 0xe6, - 0xda, 0x90, 0xf3, 0x85, 0xb8, 0x73, 0x12, 0x2c, 0x64, 0x2a, 0x45, 0x38, 0x9e, 0x9f, 0x0c, 0x44, - 0x08, 0xbe, 0x0a, 0xc0, 0xa9, 0x88, 0xc2, 0xe5, 0x68, 0xd5, 0x37, 0x86, 0x54, 0xdd, 0xa8, 0x89, - 0x78, 0x41, 0xc4, 0x86, 0x3e, 0x82, 0x45, 0xed, 0x85, 0x13, 0xdf, 0x4a, 0x5e, 0x91, 0xeb, 0xd3, - 0x67, 0xf3, 0xe9, 0xf9, 0xcb, 0x7f, 0x95, 0x49, 0xa9, 0x99, 0x88, 0xc0, 0x8e, 0x87, 0x07, 0x8e, - 0xc7, 0x94, 0x87, 0xac, 0x48, 0x04, 0x20, 0xe3, 0xad, 0xf7, 0x89, 0x36, 0x74, 0xf8, 0x66, 0x2b, - 0x8a, 0x29, 0xa9, 0x43, 0x77, 0x61, 0x21, 0xbc, 0xb7, 0xa5, 0xc9, 0x85, 0x2c, 0xdc, 0xce, 0x97, - 0x5a, 0x8b, 0x43, 0xeb, 0x80, 0x34, 0x77, 0xd3, 0xcc, 0x72, 0x68, 0x30, 0xc4, 0x2d, 0x93, 0xae, - 0xd2, 0x59, 0x48, 0x54, 0x82, 0x90, 0x9e, 0xb1, 0x4b, 0x61, 0x96, 0xb0, 0xc1, 0x0a, 0xc4, 0x46, - 0x90, 0x41, 0x07, 0x01, 0xee, 0xf0, 0x10, 0x67, 0x58, 0x2e, 0xff, 0x8b, 0xa1, 0x5e, 0x4f, 0x87, - 0xb3, 0x23, 0x6c, 0xae, 0x6c, 0x2b, 0x8d, 0xf1, 0x6c, 0x65, 0x26, 0xdd, 0x56, 0xbe, 0x0d, 0x4b, - 0x91, 0xce, 0x2b, 0x4c, 0x6c, 0x2e, 0x53, 0xb0, 0xe9, 0x16, 0x33, 0x37, 0xcc, 0x62, 0xfe, 0x2b, - 0x40, 0x91, 0xf7, 0x82, 0x9e, 0x3d, 0x44, 0x46, 0x9d, 0x21, 0x65, 0xd4, 0xfd, 0x66, 0xa5, 0xe3, - 0x54, 0xc2, 0x08, 0x65, 0x9e, 0xaa, 0xe1, 0xab, 0x9a, 0xb0, 0x11, 0xcd, 0x41, 0x1b, 0x33, 0x99, - 0xba, 0x70, 0xa6, 0x64, 0x6a, 0xd0, 0x27, 0x01, 0xa9, 0xd7, 0xf6, 0xc5, 0x71, 0xd2, 0x7b, 0xa6, - 0x47, 0xa6, 0xf7, 0xcc, 0x9c, 0x29, 0xbd, 0x67, 0xf6, 0x4c, 0x69, 0xd9, 0x97, 0xc7, 0x49, 0xcb, - 0x36, 0xc7, 0x4b, 0xfb, 0x99, 0x8b, 0xa5, 0xfd, 0x8c, 0xb8, 0xc7, 0x44, 0x17, 0x91, 0xc4, 0x33, - 0x7f, 0x51, 0x49, 0x3c, 0x0b, 0x17, 0x90, 0xc4, 0xb3, 0x78, 0xfe, 0x24, 0x9e, 0xa5, 0x0b, 0x49, - 0xe2, 0xb9, 0x72, 0x01, 0x49, 0x3c, 0xa5, 0x31, 0x92, 0x78, 0x86, 0x27, 0xaa, 0x5f, 0x1d, 0x95, - 0xa8, 0x3e, 0x34, 0x09, 0x68, 0x79, 0x78, 0x12, 0xd0, 0x27, 0x94, 0xe4, 0xfe, 0x5d, 0x83, 0xbd, - 0x5a, 0xe1, 0x4f, 0x38, 0xb8, 0x49, 0x36, 0xf4, 0x4f, 0x38, 0x9c, 0x00, 0xaf, 0x33, 0x0a, 0xc5, - 0xea, 0x30, 0xd0, 0xb2, 0x05, 0x45, 0x09, 0xa9, 0xe9, 0xe0, 0x67, 0xd4, 0x0e, 0x5e, 0x49, 0x31, - 0x6c, 0xb2, 0x57, 0xf4, 0xc3, 0x1c, 0x4d, 0x51, 0xb9, 0x10, 0xf3, 0xff, 0xdb, 0xac, 0x92, 0x5f, - 0xe3, 0xac, 0x92, 0x11, 0xb6, 0x75, 0x66, 0xdc, 0x1c, 0x11, 0x22, 0xef, 0xf6, 0x38, 0xf2, 0x6e, - 0x7f, 0xb2, 0xf2, 0x6e, 0xeb, 0xe5, 0xfd, 0xef, 0xb3, 0x00, 0xd2, 0x89, 0x4a, 0x77, 0x2e, 0x17, - 0x2a, 0x90, 0x91, 0x54, 0xe0, 0x16, 0xcc, 0x10, 0xf5, 0xc6, 0x7d, 0xd5, 0xb9, 0x51, 0x81, 0x31, - 0xa9, 0xc9, 0x8d, 0x2d, 0x35, 0xa3, 0x77, 0xa5, 0x89, 0x8b, 0xda, 0x95, 0x26, 0x2f, 0x60, 0x57, - 0x9a, 0x3a, 0xdf, 0x73, 0xa3, 0xfc, 0x28, 0x2b, 0x5e, 0xfe, 0x3b, 0x23, 0x5c, 0x24, 0x22, 0x46, - 0xef, 0xc5, 0xc4, 0xa8, 0x9c, 0xb8, 0xed, 0x1a, 0x25, 0x49, 0x1f, 0x8c, 0x92, 0xa4, 0x37, 0x55, - 0x49, 0x5a, 0xd2, 0xb4, 0xe0, 0x7a, 0x58, 0x16, 0xa4, 0x1f, 0x67, 0xe2, 0x77, 0x71, 0x69, 0x41, - 0x49, 0x55, 0x70, 0x32, 0xa3, 0x05, 0x27, 0x7b, 0x81, 0x82, 0x93, 0xbb, 0x28, 0xc1, 0x99, 0xb8, - 0x00, 0xc1, 0x99, 0x1c, 0x21, 0x38, 0xe5, 0x6f, 0x67, 0xe3, 0xb7, 0x2f, 0xe8, 0x2d, 0xc8, 0x73, - 0x55, 0x16, 0xcb, 0x3f, 0xaf, 0x51, 0x73, 0xe1, 0x90, 0x0a, 0x52, 0xc2, 0x56, 0x15, 0x6c, 0x99, - 0x24, 0x5b, 0x55, 0x65, 0x13, 0xa4, 0xe8, 0x1d, 0x9a, 0x2f, 0xc4, 0xf9, 0xd8, 0x2e, 0xb6, 0xa0, - 0xbb, 0x8e, 0xe7, 0x8c, 0x11, 0x31, 0x7a, 0x00, 0xc5, 0x48, 0x50, 0xc4, 0x09, 0x3f, 0x45, 0x8e, - 0xc4, 0x85, 0x97, 0xc4, 0x80, 0x6a, 0x22, 0x34, 0xd4, 0xe1, 0x35, 0xb0, 0xec, 0xb6, 0x52, 0x32, - 0xfe, 0xd9, 0x91, 0xeb, 0x50, 0x99, 0xd2, 0x23, 0x04, 0x93, 0xe7, 0x8c, 0x10, 0xfc, 0x91, 0x01, - 0x45, 0xbe, 0x32, 0xd4, 0x4f, 0xf8, 0x3c, 0x5d, 0x16, 0xb6, 0xdb, 0x1b, 0x7c, 0xb7, 0x0f, 0xdd, - 0x21, 0x8e, 0x51, 0xae, 0x84, 0x42, 0x72, 0x74, 0x9f, 0xcd, 0x31, 0xe3, 0xcd, 0xf0, 0x51, 0x46, - 0xae, 0x94, 0x88, 0xcd, 0xca, 0xcc, 0x11, 0x43, 0xf9, 0x7b, 0x39, 0x58, 0xe4, 0xa1, 0x20, 0x11, - 0x50, 0xe6, 0x29, 0x05, 0xaf, 0xc1, 0x6c, 0xeb, 0xe4, 0x78, 0xfb, 0x49, 0x54, 0x39, 0x73, 0x62, - 0x62, 0x50, 0xa2, 0x92, 0x14, 0x12, 0xf6, 0x9f, 0x19, 0x7a, 0x15, 0x88, 0xd6, 0xc0, 0x14, 0x7c, - 0x61, 0x92, 0x34, 0x3b, 0x7f, 0x27, 0xe0, 0xe4, 0xf4, 0xd3, 0xc2, 0x2f, 0x82, 0xf0, 0xd2, 0x97, - 0x97, 0x90, 0x0d, 0x45, 0xf6, 0x6b, 0xe3, 0xe5, 0x63, 0x2c, 0xf2, 0x15, 0xef, 0xca, 0x6b, 0xa0, - 0x1d, 0xc9, 0xba, 0xc4, 0xc4, 0x42, 0x64, 0x72, 0x35, 0xe8, 0x89, 0xee, 0x3a, 0x9e, 0xbd, 0xa7, - 0x7a, 0x67, 0x8c, 0xba, 0xe3, 0xac, 0xf1, 0x87, 0x55, 0xe1, 0x95, 0x3d, 0xf5, 0x99, 0x0e, 0xc5, - 0x1d, 0x02, 0x4f, 0xcd, 0x13, 0xe7, 0xea, 0x24, 0x66, 0xf9, 0x01, 0x98, 0xf1, 0x8e, 0xeb, 0x53, - 0xe8, 0xf5, 0xb9, 0x7a, 0xca, 0x5b, 0x2c, 0xa5, 0x73, 0xa3, 0x6a, 0x51, 0xc2, 0x7c, 0xff, 0x63, - 0xc0, 0x55, 0x0b, 0xfb, 0x2c, 0x2e, 0xfa, 0x91, 0x13, 0x60, 0xef, 0xd8, 0xf1, 0x8e, 0x84, 0x8c, - 0x44, 0x2b, 0x65, 0x28, 0x2b, 0xf5, 0x25, 0x75, 0xa5, 0x98, 0x54, 0xbe, 0x1d, 0x3b, 0xfa, 0xea, - 0xeb, 0x1c, 0xb1, 0x5a, 0xfa, 0x59, 0xcc, 0x7e, 0x52, 0xb3, 0x58, 0xfe, 0x4f, 0xfe, 0x44, 0x70, - 0xa8, 0x47, 0xff, 0xdb, 0x97, 0x06, 0xbf, 0x69, 0x2f, 0x0d, 0xfe, 0x51, 0xbc, 0xa8, 0x25, 0x0e, - 0xd3, 0x83, 0xf0, 0x20, 0xc6, 0x4c, 0xf3, 0x6a, 0x62, 0x0b, 0xa3, 0xee, 0x12, 0x25, 0x51, 0xdd, - 0x25, 0x66, 0xfb, 0x1e, 0x84, 0x0e, 0x57, 0x66, 0x18, 0x7f, 0xaa, 0xbb, 0xd5, 0x86, 0xa2, 0x54, - 0xb9, 0x26, 0x4a, 0xbf, 0xae, 0xba, 0x5b, 0xa9, 0xcf, 0x22, 0x65, 0xf3, 0xd0, 0x1e, 0xe5, 0xc3, - 0x8d, 0xaa, 0x54, 0x77, 0x1c, 0xf8, 0x8f, 0xbc, 0x9a, 0x2a, 0xa1, 0xd5, 0x96, 0x77, 0x95, 0xad, - 0x4f, 0x7b, 0xb8, 0x8e, 0xd0, 0x62, 0x6f, 0x97, 0x37, 0xcb, 0x7b, 0xe1, 0x91, 0x88, 0xfb, 0x76, - 0xf3, 0x9a, 0x83, 0x90, 0xb8, 0xf8, 0x17, 0x87, 0xa7, 0xb7, 0xa3, 0x05, 0xe5, 0x47, 0x89, 0x05, - 0xdd, 0x32, 0x44, 0xd2, 0xc8, 0x17, 0xff, 0x5e, 0x18, 0x6f, 0xe0, 0xd7, 0x02, 0xf3, 0x9a, 0x28, - 0x83, 0x68, 0x4c, 0x44, 0x26, 0xee, 0x88, 0x04, 0x4f, 0x16, 0x6a, 0x55, 0xae, 0xbc, 0x44, 0x52, - 0x8f, 0x92, 0xe6, 0xd9, 0xe2, 0x3a, 0xc9, 0x6f, 0x2d, 0x78, 0xa2, 0xc9, 0x14, 0xe5, 0x5e, 0x89, - 0x5f, 0x98, 0xa9, 0x54, 0x96, 0x86, 0x13, 0xd5, 0x63, 0x39, 0x20, 0x5c, 0x01, 0x47, 0xde, 0xbd, - 0xc5, 0x32, 0x47, 0x84, 0x7d, 0xef, 0xf0, 0xdc, 0x79, 0x5e, 0x42, 0x8f, 0x55, 0xfb, 0x0e, 0x54, - 0xac, 0xdf, 0x48, 0x4b, 0x88, 0x19, 0x61, 0xd2, 0xef, 0xcb, 0xa7, 0x13, 0x7e, 0x49, 0xbc, 0xa4, - 0x3f, 0x93, 0x88, 0x4b, 0x1c, 0xe9, 0x34, 0x23, 0x87, 0x58, 0xa7, 0x4f, 0xf7, 0x82, 0x52, 0x97, - 0xb7, 0x37, 0x93, 0x9e, 0xb7, 0xb7, 0xa9, 0x73, 0x14, 0x66, 0x47, 0x1a, 0x36, 0x8d, 0x2b, 0x70, - 0x1f, 0xae, 0x26, 0xb7, 0xaa, 0x1d, 0xdc, 0xef, 0x74, 0xfb, 0x87, 0x34, 0xe2, 0x9b, 0xb7, 0xd2, - 0x09, 0xd0, 0x06, 0x5c, 0x57, 0xb6, 0x4d, 0xba, 0x91, 0x4a, 0x47, 0x0b, 0xf6, 0x6c, 0x73, 0x28, - 0x0d, 0x39, 0x52, 0x6a, 0x1a, 0xa0, 0x17, 0x51, 0xe1, 0xf3, 0xcd, 0x21, 0x14, 0xe8, 0x3d, 0xb8, - 0x96, 0xc4, 0x86, 0xaf, 0x29, 0x44, 0xe8, 0x78, 0x08, 0xc9, 0xb9, 0x37, 0xe6, 0x3f, 0x35, 0x60, - 0x5a, 0x76, 0xd6, 0xb5, 0xc7, 0xc5, 0xeb, 0x50, 0x60, 0x17, 0x3b, 0x22, 0x23, 0xa0, 0x60, 0x45, - 0x00, 0x54, 0x82, 0x29, 0x75, 0x37, 0x16, 0x45, 0x29, 0xfe, 0x9e, 0x53, 0xe2, 0xef, 0xcb, 0x90, - 0xaf, 0xb9, 0xcf, 0xfb, 0x14, 0x33, 0x41, 0x31, 0x61, 0xb9, 0xfc, 0xed, 0x32, 0x98, 0x42, 0xb7, - 0xc3, 0x57, 0x3d, 0xe1, 0x1b, 0x1e, 0x43, 0x7e, 0xc3, 0xa3, 0x0b, 0x89, 0x44, 0xae, 0x54, 0x56, - 0x71, 0xa5, 0xb6, 0x55, 0x55, 0x63, 0x07, 0xa1, 0xcf, 0xe8, 0x0c, 0x4a, 0xf8, 0x58, 0x67, 0xb8, - 0xba, 0xe9, 0xbe, 0x29, 0xf0, 0x7f, 0x6e, 0xaf, 0x3a, 0x60, 0xc6, 0x6e, 0x6c, 0xc5, 0x75, 0xd2, - 0xdd, 0xa1, 0x43, 0x8d, 0x33, 0xc9, 0xdb, 0x67, 0xa2, 0x46, 0xd4, 0x90, 0x8f, 0x4a, 0xec, 0xb3, - 0x3f, 0x9f, 0x1e, 0x5a, 0x7d, 0x48, 0xcd, 0xe6, 0x31, 0xe2, 0x96, 0xb7, 0x05, 0x18, 0x7b, 0x5b, - 0x90, 0x36, 0xae, 0xe2, 0x99, 0x36, 0xae, 0xe9, 0x53, 0x6c, 0x5c, 0xb1, 0x6d, 0x76, 0xe6, 0xd4, - 0xdb, 0x6c, 0x62, 0x0f, 0x99, 0x3d, 0xd3, 0x1e, 0xa2, 0x9a, 0xf7, 0xcb, 0xa7, 0x34, 0xef, 0x89, - 0x73, 0xbc, 0x79, 0x96, 0x73, 0x7c, 0x8a, 0xb1, 0x9f, 0x3b, 0xa5, 0xb1, 0x47, 0x17, 0x6e, 0xec, - 0xe7, 0xcf, 0x6b, 0xec, 0x17, 0xce, 0x6d, 0xec, 0x17, 0xcf, 0x6b, 0xec, 0x97, 0x46, 0x1a, 0x7b, - 0xf4, 0x76, 0x22, 0xbf, 0x4a, 0xe4, 0x39, 0xb0, 0x9b, 0xb0, 0x14, 0xac, 0xe6, 0x28, 0x10, 0x65, - 0x4f, 0x94, 0xb4, 0x47, 0x81, 0x28, 0x99, 0xe2, 0xab, 0xb0, 0x10, 0xc3, 0x89, 0x5b, 0xaf, 0xc4, - 0x61, 0x34, 0xa1, 0xf7, 0x3a, 0x46, 0x66, 0x02, 0xb4, 0x75, 0xa2, 0x41, 0x62, 0x7c, 0xd5, 0x96, - 0xb8, 0x25, 0x4b, 0x04, 0x12, 0x46, 0xb5, 0xc6, 0x59, 0x59, 0x7b, 0x29, 0xf5, 0x6a, 0x5a, 0xb4, - 0x79, 0x8b, 0xd7, 0x4e, 0xdf, 0xa2, 0x3d, 0xac, 0x45, 0x8e, 0x44, 0x9b, 0x70, 0x33, 0x86, 0xe1, - 0xc9, 0x38, 0x7e, 0xc5, 0xf7, 0xbb, 0x87, 0x7d, 0xdc, 0x29, 0x5d, 0x67, 0x6f, 0xd0, 0x46, 0x90, - 0xa1, 0x26, 0xbc, 0x12, 0x1f, 0x55, 0x98, 0x94, 0x13, 0xd6, 0x75, 0x83, 0xd6, 0x35, 0x9a, 0x30, - 0xf5, 0xc8, 0x17, 0x49, 0xca, 0xca, 0x90, 0x23, 0x5f, 0x24, 0x2f, 0x1b, 0x29, 0x59, 0x29, 0x42, - 0x52, 0x6f, 0x26, 0xef, 0x6c, 0xe3, 0x34, 0xa9, 0x91, 0x7a, 0x16, 0xaf, 0x5d, 0xa5, 0xba, 0x3a, - 0x84, 0x02, 0x3d, 0x82, 0x55, 0xed, 0x7d, 0xae, 0x9c, 0xdc, 0xf3, 0x0a, 0xed, 0xc7, 0x48, 0xba, - 0x31, 0xee, 0xb2, 0xcb, 0x63, 0xdd, 0x65, 0x7f, 0xdd, 0x80, 0x1b, 0xda, 0x2e, 0xd3, 0x30, 0x03, - 0x91, 0xb8, 0x57, 0xa9, 0xc4, 0xbd, 0x3b, 0x54, 0xe2, 0x86, 0xd6, 0xc0, 0x04, 0x6f, 0x78, 0x2b, - 0xe8, 0x0f, 0xd2, 0xd2, 0x86, 0x84, 0xaa, 0xdd, 0xa2, 0xdd, 0x78, 0x70, 0xfa, 0x6e, 0x28, 0x0a, - 0x37, 0xb4, 0x0d, 0xf4, 0x0d, 0x23, 0x25, 0xb4, 0x4f, 0xb7, 0x2c, 0xd6, 0x8f, 0x4f, 0xd1, 0x7e, - 0x54, 0x4e, 0xdf, 0x8f, 0xa8, 0x0e, 0xd6, 0x95, 0x51, 0x2d, 0xa1, 0x3f, 0x36, 0x52, 0x64, 0xbf, - 0xda, 0xe2, 0xb9, 0x54, 0xa5, 0xd7, 0x68, 0x67, 0xde, 0x3b, 0xcb, 0xa4, 0xf0, 0x2a, 0x58, 0x5f, - 0x46, 0xb4, 0x83, 0xbe, 0x69, 0xc0, 0x2b, 0xe9, 0xdd, 0x15, 0xbd, 0x79, 0x9d, 0xf6, 0xa6, 0x7a, - 0xc6, 0xa9, 0x51, 0x3a, 0x34, 0xba, 0xb5, 0x54, 0x8d, 0x16, 0x9b, 0xef, 0xed, 0x21, 0x1a, 0x2d, - 0xf6, 0xdf, 0x6f, 0x19, 0x50, 0x1e, 0x3a, 0x74, 0x96, 0x4a, 0xf6, 0x06, 0x1d, 0x58, 0xed, 0xec, - 0xd3, 0x4c, 0xab, 0x61, 0x23, 0x1b, 0xa3, 0x3d, 0xf4, 0x3d, 0x03, 0x3e, 0x35, 0x6a, 0x02, 0x58, - 0xcf, 0xd6, 0x68, 0xcf, 0x1e, 0x9e, 0x6b, 0xca, 0xa5, 0xce, 0x8d, 0xd7, 0xea, 0xb9, 0x83, 0xd7, - 0x1f, 0xc3, 0xa2, 0xd6, 0xb5, 0x3f, 0x65, 0x9c, 0x4a, 0x79, 0xd3, 0x24, 0x55, 0x7f, 0x9f, 0x7e, - 0x60, 0x2c, 0x25, 0xa8, 0x36, 0xb2, 0x73, 0x0f, 0xe1, 0x6a, 0xaa, 0x83, 0x30, 0xaa, 0xa2, 0xbc, - 0x5c, 0x51, 0x23, 0x91, 0x24, 0x20, 0x9b, 0xa2, 0x73, 0x56, 0x65, 0x9f, 0xb5, 0xaa, 0x9d, 0x14, - 0x89, 0x57, 0xac, 0xf5, 0xa9, 0x6a, 0xdc, 0x4e, 0xb1, 0x0d, 0x67, 0x1e, 0xad, 0x05, 0xb7, 0xc6, - 0xb1, 0xa0, 0xa7, 0xaa, 0xf3, 0x03, 0x78, 0x75, 0x0c, 0x43, 0x78, 0x2a, 0x41, 0xb1, 0xe1, 0xb5, - 0xf1, 0xac, 0xd9, 0xa9, 0x6a, 0xdd, 0x85, 0xd7, 0xc7, 0x34, 0x25, 0xa7, 0xaa, 0xf6, 0x4b, 0xb0, - 0x36, 0xbe, 0x1d, 0x38, 0x55, 0xa8, 0xa6, 0xc1, 0xf2, 0x6d, 0xc4, 0xb7, 0xfc, 0xce, 0xf1, 0xa5, - 0x9d, 0xf2, 0x5f, 0x67, 0x60, 0x41, 0xf7, 0xdc, 0x6f, 0x48, 0xd6, 0xfd, 0x4e, 0xe2, 0xcb, 0x8d, - 0xeb, 0xa3, 0x1e, 0x0f, 0xaa, 0x5f, 0x70, 0x4c, 0x5c, 0xa0, 0x5c, 0xc8, 0x77, 0x1c, 0x97, 0xed, - 0xd1, 0x1f, 0x5a, 0x1c, 0x96, 0x90, 0x23, 0xcd, 0xa8, 0x3c, 0xd7, 0xdf, 0x37, 0x00, 0x36, 0x9c, - 0x83, 0xa3, 0x93, 0x01, 0xbd, 0x83, 0x49, 0xbb, 0xa0, 0x6b, 0xe8, 0x2e, 0xe8, 0x5e, 0x57, 0x5e, - 0x1a, 0x84, 0x95, 0x0c, 0x8f, 0x27, 0x9d, 0x3b, 0x90, 0xf7, 0x87, 0x86, 0xb8, 0x5f, 0x6a, 0x04, - 0xf8, 0x58, 0xfb, 0xd1, 0x8f, 0x32, 0x4c, 0xf3, 0x2c, 0xeb, 0x0f, 0xa5, 0x5b, 0x4a, 0x05, 0x46, - 0x68, 0x6a, 0xf8, 0x89, 0x73, 0xd2, 0xe3, 0x34, 0x2c, 0xa2, 0xa7, 0xc0, 0xc8, 0x12, 0x35, 0xfa, - 0x01, 0xf6, 0xfa, 0x4e, 0x8f, 0x5f, 0xac, 0x85, 0xe5, 0xf2, 0xdf, 0x18, 0xf2, 0x35, 0x17, 0xfa, - 0x22, 0x4c, 0x55, 0xdd, 0x7e, 0x80, 0xe9, 0xb7, 0x31, 0x92, 0x69, 0xcd, 0x21, 0xe1, 0x3a, 0xa7, - 0x62, 0x13, 0x23, 0x78, 0x96, 0x2d, 0xfa, 0xb6, 0x2d, 0x44, 0x9c, 0x32, 0x45, 0x26, 0x9a, 0x0e, - 0x79, 0xa2, 0x7e, 0x3f, 0xba, 0x4f, 0x43, 0x6f, 0x45, 0x2f, 0x3f, 0x13, 0x99, 0x60, 0x82, 0x68, - 0x9d, 0x52, 0xb0, 0x8e, 0x31, 0xea, 0xe5, 0x77, 0x00, 0x22, 0xe0, 0xa9, 0xee, 0x81, 0x5f, 0x57, - 0x1e, 0x9c, 0x0f, 0x79, 0x11, 0xf3, 0x31, 0xcc, 0x25, 0xde, 0x5e, 0xa0, 0x5b, 0x30, 0xc3, 0xbe, - 0x61, 0x23, 0x9e, 0x73, 0x30, 0x26, 0x15, 0x48, 0x97, 0x99, 0xb3, 0x48, 0xdf, 0x3d, 0x52, 0x60, - 0x6b, 0xcf, 0x01, 0x76, 0x07, 0x1d, 0x27, 0x60, 0x11, 0xdc, 0x2b, 0x30, 0xaf, 0x7c, 0x13, 0x87, - 0xa1, 0xcc, 0x4b, 0x68, 0x11, 0xe6, 0xc4, 0xb7, 0x8e, 0x9a, 0xed, 0x16, 0x07, 0x1b, 0x68, 0x1e, - 0x2e, 0xef, 0xfa, 0xd8, 0xa3, 0xc3, 0xe7, 0xc0, 0x0c, 0x9a, 0x81, 0x82, 0xdd, 0xde, 0xe6, 0xc5, - 0x2c, 0x61, 0x0d, 0xbf, 0x5b, 0x14, 0xb2, 0xe6, 0xd6, 0xd6, 0xa1, 0x10, 0x7e, 0xed, 0x16, 0x5d, - 0x86, 0x62, 0xcb, 0xf5, 0x8e, 0x9d, 0x1e, 0x2d, 0x9a, 0x97, 0x90, 0x09, 0xd3, 0xfc, 0xf1, 0x00, - 0x83, 0x18, 0x6b, 0xbf, 0xc8, 0x01, 0x44, 0x6f, 0xc5, 0xd1, 0x2c, 0x80, 0xdd, 0xde, 0xde, 0xdb, - 0xdd, 0xa9, 0x55, 0xec, 0xba, 0x79, 0x09, 0x01, 0x4c, 0x56, 0x76, 0x76, 0xea, 0xad, 0x9a, 0x69, - 0xa0, 0x3c, 0xe4, 0xac, 0x7a, 0xa5, 0x66, 0x66, 0xd0, 0x34, 0xe4, 0x6d, 0x6b, 0xb7, 0x55, 0x25, - 0x34, 0x59, 0x52, 0xe9, 0xc3, 0xba, 0xbd, 0x17, 0x42, 0x72, 0xa8, 0x08, 0x53, 0xd5, 0xed, 0x56, - 0xab, 0x5e, 0xb5, 0xcd, 0x09, 0x52, 0x25, 0x2f, 0xec, 0x59, 0xdb, 0xe6, 0x24, 0x9a, 0x83, 0x99, - 0xe6, 0xf6, 0xc3, 0xbd, 0xcd, 0x7a, 0xc5, 0xb2, 0x37, 0xea, 0x15, 0xdb, 0x9c, 0x22, 0x35, 0x54, - 0x5b, 0x12, 0x24, 0x4f, 0x3b, 0x2a, 0x43, 0x0a, 0x08, 0xc1, 0x6c, 0x75, 0xb3, 0x5e, 0x7d, 0xbc, - 0xb7, 0x59, 0x79, 0x5c, 0xaf, 0xef, 0xd4, 0x2d, 0x13, 0xc8, 0xbc, 0x92, 0x96, 0xab, 0xcd, 0xdd, - 0xb6, 0x5d, 0xb7, 0xf6, 0x6a, 0x75, 0xbb, 0xd2, 0x68, 0xb6, 0xcd, 0x22, 0x21, 0x26, 0x88, 0xf6, - 0x66, 0xc5, 0xaa, 0xed, 0x35, 0x5a, 0xef, 0x6f, 0x9b, 0xd3, 0xb4, 0x82, 0xd6, 0x5e, 0xa5, 0xd9, - 0xdc, 0x26, 0xbd, 0xdc, 0x6b, 0xd4, 0xcc, 0x19, 0x32, 0x89, 0x72, 0x05, 0x6d, 0x9b, 0xf4, 0x7f, - 0x96, 0xce, 0x3f, 0x9d, 0x81, 0xbd, 0x6a, 0x6b, 0xaf, 0x59, 0xd9, 0xa8, 0x37, 0xcd, 0xcb, 0xa8, - 0x04, 0x0b, 0x11, 0xf0, 0xa3, 0x6d, 0xeb, 0x31, 0x27, 0x37, 0x49, 0xcd, 0x3b, 0x15, 0xbb, 0xba, - 0x49, 0x10, 0x6d, 0x7b, 0xdb, 0xaa, 0x9b, 0x73, 0xa4, 0x8a, 0x5a, 0xbd, 0x59, 0x67, 0xd4, 0x0c, - 0x88, 0x08, 0x70, 0xc7, 0xda, 0xfe, 0xd2, 0x97, 0xa5, 0x81, 0xcd, 0xa3, 0x57, 0xe0, 0x06, 0xaf, - 0xb7, 0xb5, 0xdd, 0xda, 0xfb, 0x70, 0xdb, 0x6e, 0xb4, 0x1e, 0xee, 0x59, 0xf5, 0x9d, 0x66, 0xa3, - 0x5a, 0xd9, 0x6b, 0xed, 0x6e, 0x99, 0x0b, 0x68, 0x05, 0x96, 0x93, 0x24, 0x64, 0x1c, 0xcd, 0x86, - 0xfd, 0x65, 0x73, 0x11, 0x2d, 0x80, 0xd9, 0xae, 0xdb, 0x7b, 0x56, 0xfd, 0x83, 0xdd, 0x86, 0x55, - 0xaf, 0xed, 0x35, 0xdb, 0x2d, 0x73, 0x89, 0x40, 0x1f, 0xc6, 0xa1, 0x57, 0xc4, 0xd4, 0x34, 0x2b, - 0x76, 0xbd, 0x6d, 0x53, 0x58, 0x89, 0x2c, 0x09, 0x85, 0xd5, 0x2b, 0xb5, 0xba, 0x45, 0x66, 0xe6, - 0x2a, 0x5d, 0x12, 0x36, 0xdd, 0xf5, 0x4a, 0xd3, 0xde, 0x34, 0x97, 0xc9, 0xa2, 0x93, 0xe5, 0xa7, - 0x2c, 0xd7, 0xd0, 0x55, 0x58, 0xe4, 0x5d, 0x6a, 0xd6, 0x2b, 0xed, 0xfa, 0xe6, 0x76, 0x93, 0xb3, - 0x5e, 0x27, 0x28, 0x3a, 0xf9, 0xd5, 0xcd, 0x7a, 0x6d, 0xb7, 0x59, 0xdf, 0xab, 0x6e, 0x6f, 0x6d, - 0x55, 0x5a, 0xb5, 0xb6, 0x79, 0x63, 0xad, 0x05, 0x10, 0x7d, 0x61, 0x89, 0x48, 0x06, 0x11, 0x73, - 0x06, 0x31, 0x2f, 0x91, 0x16, 0x84, 0x9d, 0x33, 0x0d, 0x22, 0xbc, 0x54, 0x69, 0x42, 0x05, 0x98, - 0xe3, 0x9f, 0x14, 0xb3, 0xf0, 0x57, 0xf1, 0x41, 0x80, 0x3b, 0x66, 0x76, 0x6d, 0x0d, 0x0a, 0xe1, - 0x07, 0x7c, 0x08, 0x7b, 0x1b, 0x07, 0xb4, 0x64, 0x5e, 0x22, 0xec, 0x2c, 0xb8, 0xca, 0x00, 0xc6, - 0xda, 0x3f, 0xe7, 0x00, 0x89, 0x23, 0x85, 0xa4, 0x9b, 0x44, 0xe2, 0xbb, 0x07, 0x47, 0xb2, 0x4a, - 0x4a, 0x5f, 0x4a, 0x09, 0x55, 0x92, 0x68, 0x6a, 0x02, 0x9c, 0x41, 0x4b, 0x34, 0xcf, 0x23, 0x0e, - 0xcf, 0x92, 0xd6, 0x1f, 0xe2, 0x20, 0xd4, 0xf4, 0x1c, 0x99, 0x94, 0x98, 0xbd, 0xe1, 0xa8, 0x09, - 0xb2, 0x22, 0x6d, 0xcc, 0x14, 0x92, 0xc3, 0x26, 0x89, 0xb0, 0xa9, 0x89, 0x3c, 0x1c, 0x33, 0x85, - 0x6e, 0xc2, 0xb5, 0x36, 0x0e, 0x92, 0x77, 0x13, 0x9c, 0x20, 0x8f, 0x96, 0x61, 0x89, 0x13, 0x84, - 0xc1, 0x6d, 0x8e, 0x2b, 0x90, 0x29, 0x64, 0xbf, 0xf9, 0xac, 0x99, 0x40, 0x06, 0x26, 0x40, 0xe1, - 0xb3, 0x15, 0xb3, 0x48, 0xd6, 0x7f, 0x87, 0xd8, 0x3b, 0x9e, 0x23, 0x67, 0x4e, 0x13, 0x5e, 0x0b, - 0x1f, 0xbb, 0xcf, 0xc4, 0x2b, 0x46, 0x73, 0x86, 0xf4, 0x52, 0x4d, 0x86, 0xe4, 0x0d, 0xcd, 0xa2, - 0x1b, 0x70, 0x95, 0xfd, 0xd6, 0x04, 0xad, 0xcd, 0xcb, 0xe8, 0x1a, 0x5c, 0x89, 0xa1, 0xc5, 0x6e, - 0xc0, 0xd4, 0x49, 0x9c, 0x7a, 0x78, 0x7d, 0x73, 0xe8, 0x3a, 0x94, 0x92, 0xa9, 0x38, 0x1c, 0x8b, - 0xd0, 0x2d, 0x58, 0x15, 0x41, 0xdc, 0x64, 0x78, 0x97, 0x53, 0xcd, 0x93, 0x99, 0x63, 0x01, 0xb0, - 0xd8, 0x09, 0x84, 0x13, 0x2c, 0xa0, 0x4f, 0xc1, 0x2b, 0x8c, 0x40, 0xeb, 0x60, 0x72, 0xb2, 0xc5, - 0xb5, 0xef, 0x18, 0x30, 0xa3, 0xdc, 0x36, 0x11, 0xbd, 0x16, 0x00, 0x9e, 0x8d, 0x62, 0x5e, 0x22, - 0x2b, 0x2e, 0x80, 0xca, 0x5b, 0x74, 0xd3, 0x20, 0x0d, 0x25, 0x50, 0xe2, 0xfc, 0x68, 0xe1, 0x03, - 0xdc, 0x7d, 0x86, 0x3b, 0x66, 0x86, 0xcc, 0x52, 0x82, 0xec, 0x7d, 0xa7, 0xdb, 0x23, 0xa2, 0x2f, - 0xb7, 0x69, 0x9d, 0xf4, 0xfb, 0xa4, 0xe2, 0xdc, 0xda, 0xbe, 0xee, 0xbe, 0x8b, 0x2c, 0x93, 0x02, - 0x8d, 0xfa, 0x18, 0xc7, 0x88, 0x9a, 0x8c, 0x04, 0xa6, 0x1d, 0xb8, 0x83, 0x01, 0xe9, 0xd5, 0xda, - 0x8f, 0x0d, 0x30, 0xe3, 0x5f, 0x1f, 0x20, 0x5a, 0x54, 0xe9, 0x88, 0x0f, 0x82, 0x99, 0x97, 0x22, - 0x61, 0x11, 0x20, 0x83, 0x48, 0x54, 0x3b, 0x70, 0xbc, 0x40, 0x40, 0x32, 0x44, 0x49, 0x48, 0xb5, - 0x02, 0x90, 0x25, 0xb5, 0x3c, 0xee, 0xf6, 0x7a, 0x5f, 0x71, 0x8f, 0xf7, 0xbb, 0x44, 0x69, 0xae, - 0xc0, 0x7c, 0xa5, 0xd3, 0x89, 0x8b, 0x90, 0x39, 0x41, 0x64, 0x9c, 0x55, 0x9f, 0xc0, 0x4d, 0x52, - 0x4d, 0x23, 0xed, 0x24, 0x50, 0x53, 0x64, 0x50, 0xa4, 0xc1, 0x04, 0x26, 0xbf, 0xb6, 0xa5, 0xbc, - 0xca, 0x26, 0x1d, 0x89, 0x04, 0xc9, 0xbc, 0x44, 0xf7, 0xde, 0x96, 0x28, 0x1a, 0xa4, 0x58, 0x0d, - 0x8b, 0x19, 0xaa, 0x2b, 0xf4, 0x2a, 0x88, 0x43, 0xb2, 0x1b, 0x8d, 0x1f, 0xfd, 0x6c, 0xe5, 0xd2, - 0x0f, 0x7e, 0xbe, 0x62, 0xfc, 0xe8, 0xe7, 0x2b, 0xc6, 0x4f, 0x7f, 0xbe, 0x72, 0xe9, 0x6f, 0xff, - 0x7d, 0xc5, 0xf8, 0xca, 0x3d, 0xe9, 0x5f, 0xa5, 0x1c, 0x3b, 0x81, 0xd7, 0x7d, 0xe1, 0x52, 0xc7, - 0x42, 0x14, 0xfa, 0xf8, 0xce, 0xe0, 0xe8, 0xf0, 0xce, 0x60, 0xff, 0x4e, 0xe4, 0x26, 0xed, 0x4f, - 0xd2, 0xaf, 0xb7, 0xdd, 0xfb, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x3a, 0xb3, 0x7e, 0x86, - 0x65, 0x00, 0x00, + // 5959 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xdd, 0x6f, 0x1b, 0xd9, + 0x75, 0xb8, 0x87, 0xa2, 0x24, 0xf2, 0x50, 0x92, 0x47, 0x57, 0x92, 0x4d, 0xcb, 0xb6, 0xac, 0xe5, + 0x3a, 0xbb, 0x5e, 0x65, 0x23, 0xe7, 0x67, 0x67, 0x17, 0x9b, 0xfc, 0x1c, 0xef, 0x52, 0x24, 0xd7, + 0xa2, 0x4d, 0x53, 0xda, 0xe1, 0xc8, 0x9b, 0x04, 0x58, 0x08, 0x23, 0xf1, 0x5a, 0x9e, 0x88, 0xe2, + 0x30, 0x33, 0x23, 0xaf, 0xdd, 0xbe, 0x15, 0x4d, 0x51, 0x34, 0x45, 0xd1, 0x00, 0x41, 0x93, 0x36, + 0x4d, 0xbf, 0xde, 0xfa, 0x94, 0x97, 0xf6, 0x5f, 0x28, 0xf2, 0x54, 0x04, 0x79, 0xcc, 0x43, 0x9a, + 0x6c, 0x5f, 0x0a, 0xe4, 0xb5, 0x68, 0xd0, 0x87, 0x02, 0xc5, 0xfd, 0x9a, 0xb9, 0x77, 0xe6, 0x0e, + 0x49, 0x7d, 0x24, 0x69, 0x82, 0x3c, 0x89, 0xf7, 0x7c, 0xdc, 0xcf, 0x73, 0xce, 0x3d, 0xf7, 0xdc, + 0x73, 0x47, 0x60, 0xf6, 0xbc, 0x83, 0x00, 0xfb, 0xcf, 0xdd, 0x7d, 0xbc, 0x3e, 0xf0, 0xbd, 0xd0, + 0x43, 0x10, 0x43, 0x96, 0x3f, 0x73, 0xe0, 0x86, 0xcf, 0x8e, 0xf7, 0xd6, 0xf7, 0xbd, 0xa3, 0xdb, + 0x07, 0xde, 0x81, 0x77, 0x9b, 0x92, 0xec, 0x1d, 0x3f, 0xa5, 0x25, 0x5a, 0xa0, 0xbf, 0x18, 0xeb, + 0xf2, 0x8d, 0x03, 0xcf, 0x3b, 0xe8, 0xe1, 0x98, 0x2a, 0x74, 0x8f, 0x70, 0x10, 0x3a, 0x47, 0x03, + 0x4e, 0x30, 0x77, 0x84, 0x43, 0xa7, 0xeb, 0x84, 0x0e, 0x2b, 0x57, 0xfe, 0xb4, 0x00, 0xd3, 0xb5, + 0x76, 0x27, 0xf4, 0x7c, 0x8c, 0x10, 0xe4, 0x77, 0x76, 0x9a, 0xf5, 0xb2, 0xb1, 0x6a, 0xdc, 0x2a, + 0x5a, 0xf4, 0x37, 0x7a, 0x0d, 0xe6, 0x3a, 0xac, 0x2b, 0xd5, 0x6e, 0xd7, 0xc7, 0x41, 0x50, 0xce, + 0x51, 0x6c, 0x02, 0x8a, 0x56, 0x00, 0x3a, 0x1f, 0xb4, 0x04, 0xcd, 0x04, 0xa5, 0x91, 0x20, 0x68, + 0x1d, 0x50, 0xcb, 0xdb, 0x3f, 0x4c, 0xd4, 0x95, 0xa7, 0x74, 0x1a, 0x0c, 0xba, 0x09, 0x79, 0xcb, + 0xeb, 0xe1, 0xf2, 0xd4, 0xaa, 0x71, 0x6b, 0xee, 0x8e, 0xb9, 0x1e, 0x75, 0xbb, 0xd6, 0x26, 0x70, + 0x8b, 0x62, 0x49, 0x8f, 0x6d, 0x77, 0xff, 0xb0, 0x3c, 0xbd, 0x6a, 0xdc, 0xca, 0x5b, 0xf4, 0x37, + 0xfa, 0x34, 0x4c, 0x76, 0x42, 0x27, 0xc4, 0xe5, 0x02, 0x65, 0x5d, 0x5a, 0x97, 0xe6, 0xb7, 0xed, + 0x75, 0x31, 0x45, 0x5a, 0x8c, 0x06, 0x7d, 0x11, 0xa6, 0x5a, 0xce, 0x1e, 0xee, 0x05, 0xe5, 0xe2, + 0xea, 0xc4, 0xad, 0xd2, 0x9d, 0x1b, 0x32, 0x35, 0x9f, 0x97, 0x75, 0x46, 0xd1, 0xe8, 0x87, 0xfe, + 0xcb, 0x8d, 0xfc, 0x0f, 0x7e, 0x72, 0xe3, 0x82, 0xc5, 0x99, 0xd0, 0xff, 0x83, 0xe2, 0x87, 0x9e, + 0x7f, 0xc8, 0xda, 0x03, 0xda, 0xde, 0x42, 0xdc, 0xd5, 0x08, 0x65, 0xc5, 0x54, 0xa8, 0x02, 0x33, + 0x1f, 0x1c, 0x63, 0xff, 0xa5, 0x98, 0x82, 0x12, 0x9d, 0x02, 0x05, 0x86, 0xde, 0x06, 0xa8, 0x79, + 0xfd, 0xa7, 0xee, 0x41, 0xdd, 0x09, 0x9d, 0xf2, 0xcc, 0xaa, 0x71, 0xab, 0x74, 0xe7, 0x92, 0xd2, + 0xb3, 0x08, 0x6b, 0x49, 0x94, 0xe8, 0x6d, 0x28, 0x58, 0x38, 0xf0, 0x8e, 0xfd, 0x7d, 0x5c, 0x9e, + 0xa5, 0x5c, 0x8b, 0x32, 0x97, 0xc0, 0xf1, 0x41, 0x44, 0xb4, 0xe8, 0x12, 0x4c, 0xed, 0x0c, 0x6c, + 0xf7, 0x08, 0x97, 0xe7, 0x56, 0x8d, 0x5b, 0x13, 0x16, 0x2f, 0xa1, 0xcf, 0xc2, 0x42, 0xe7, 0x99, + 0xe3, 0x77, 0x13, 0xab, 0x76, 0x91, 0x76, 0x59, 0x87, 0x42, 0xcb, 0x50, 0xa8, 0x79, 0x47, 0x47, + 0x6e, 0xd8, 0xac, 0x97, 0x4d, 0x4a, 0x16, 0x95, 0xd1, 0xfb, 0xb0, 0xf2, 0xc4, 0xc5, 0x1f, 0x3f, + 0xe6, 0xd3, 0x53, 0xed, 0x1e, 0xb9, 0x41, 0xe0, 0x7a, 0xfd, 0xce, 0xf1, 0x60, 0xe0, 0xf9, 0x21, + 0xee, 0x96, 0xe7, 0x57, 0x8d, 0x5b, 0x05, 0x6b, 0x04, 0x15, 0xda, 0x84, 0x1b, 0x5a, 0x8a, 0x07, + 0xb8, 0x8f, 0x7d, 0x27, 0x74, 0xbd, 0x7e, 0x19, 0x51, 0x79, 0x18, 0x45, 0x86, 0xee, 0xc1, 0x15, + 0x99, 0x64, 0x6b, 0x8f, 0xcc, 0x14, 0xee, 0x36, 0x06, 0xde, 0xfe, 0xb3, 0xf2, 0x02, 0xad, 0x23, + 0x9b, 0x00, 0xdd, 0x87, 0x65, 0x6d, 0x03, 0x16, 0x76, 0xba, 0x2f, 0xcb, 0x8b, 0x74, 0x2c, 0x43, + 0x28, 0x48, 0xeb, 0xf5, 0x7a, 0xeb, 0x89, 0x1b, 0xb8, 0x7b, 0x6e, 0xcf, 0x0d, 0x5f, 0x6e, 0x38, + 0xbe, 0xef, 0x62, 0x9f, 0xb1, 0x2f, 0x51, 0xf6, 0x6c, 0x82, 0xe5, 0x36, 0x94, 0x24, 0xb9, 0x44, + 0x26, 0x4c, 0x1c, 0xe2, 0x97, 0x5c, 0x75, 0xc9, 0x4f, 0xf4, 0x06, 0x4c, 0x3e, 0x77, 0x7a, 0xc7, + 0x98, 0x2a, 0x6c, 0x49, 0x96, 0x4b, 0xca, 0xd7, 0x72, 0x83, 0xd0, 0x62, 0x14, 0x5f, 0xc8, 0xbd, + 0x63, 0x3c, 0xcc, 0x17, 0x26, 0xcd, 0xa9, 0xca, 0x2f, 0x26, 0x60, 0xda, 0x3e, 0x07, 0x73, 0x20, + 0x14, 0x73, 0x42, 0xa7, 0x98, 0xf9, 0x31, 0x14, 0xf3, 0x2d, 0x98, 0xa2, 0xf2, 0x15, 0x94, 0x27, + 0xa9, 0x62, 0x5e, 0x96, 0xa9, 0xed, 0x36, 0xc5, 0x35, 0xfb, 0x4f, 0x3d, 0xa1, 0x90, 0x8c, 0x18, + 0xdd, 0x81, 0xc5, 0x96, 0x77, 0x10, 0x3a, 0x6e, 0x8f, 0x74, 0x08, 0xfb, 0xa2, 0x97, 0x53, 0xb4, + 0x97, 0x5a, 0x5c, 0x86, 0x69, 0x9a, 0xce, 0x34, 0x4d, 0xaa, 0x76, 0x16, 0xc7, 0xd6, 0xce, 0xa4, + 0xe6, 0x83, 0x46, 0xf3, 0x33, 0x34, 0xae, 0x94, 0xad, 0x71, 0xef, 0xc1, 0xd5, 0xea, 0x71, 0xe8, + 0x35, 0xfb, 0xfb, 0x3e, 0x15, 0xcb, 0xf7, 0x71, 0x7f, 0x1f, 0xc7, 0x2a, 0x35, 0x43, 0xe5, 0x68, + 0x18, 0xc9, 0xc3, 0x7c, 0xa1, 0x60, 0x16, 0x2b, 0xff, 0x9c, 0x83, 0x42, 0xcb, 0x3b, 0xf8, 0x3f, + 0xb0, 0xf4, 0xf7, 0x88, 0x15, 0x1b, 0xf4, 0xdc, 0x7d, 0x47, 0x2c, 0xfe, 0xb2, 0x4c, 0xdf, 0xf2, + 0x0e, 0x38, 0x5a, 0x5a, 0xff, 0x88, 0x23, 0xb1, 0x3a, 0x53, 0x27, 0xb1, 0x9d, 0x2d, 0x6f, 0xdf, + 0x21, 0x7a, 0x46, 0xd7, 0x3e, 0x61, 0x3b, 0x05, 0x4e, 0xb4, 0x27, 0xca, 0x95, 0x6f, 0x4d, 0xc0, + 0x0c, 0x99, 0x37, 0x21, 0x90, 0xa8, 0x0c, 0xd3, 0xac, 0xc0, 0xa6, 0x2f, 0x6f, 0x89, 0x22, 0xda, + 0x90, 0x06, 0x96, 0xa3, 0x03, 0x7b, 0x2d, 0x31, 0xb0, 0xa8, 0x96, 0x75, 0x41, 0x48, 0xb5, 0x5b, + 0x1a, 0xde, 0x22, 0x4c, 0x32, 0xf3, 0xc4, 0xa6, 0x97, 0x15, 0x88, 0xd9, 0x6d, 0x61, 0xa7, 0x8b, + 0xfd, 0x66, 0x9d, 0x4e, 0x71, 0xde, 0x8a, 0xca, 0x74, 0x3d, 0xb0, 0x7f, 0x54, 0x9e, 0xe4, 0xeb, + 0x81, 0xfd, 0x23, 0xf4, 0x11, 0xcc, 0xb7, 0xbd, 0xfe, 0x13, 0x2f, 0x74, 0xfb, 0x07, 0x51, 0x97, + 0xa6, 0x68, 0x97, 0x6e, 0x67, 0x76, 0x29, 0xc5, 0xc1, 0xfa, 0x96, 0xae, 0x69, 0xf9, 0xff, 0xc3, + 0xac, 0x42, 0x23, 0x5b, 0xa7, 0x3c, 0xb3, 0x4e, 0x8b, 0xb2, 0x75, 0x2a, 0x4a, 0x86, 0x68, 0xb9, + 0x0e, 0x97, 0xf4, 0x2d, 0x9d, 0xa4, 0x96, 0xca, 0x77, 0x0c, 0x98, 0x53, 0x25, 0x05, 0xbd, 0xaf, + 0x2e, 0x14, 0xad, 0xa7, 0x74, 0xa7, 0x9c, 0x35, 0xde, 0x8d, 0x02, 0x59, 0xe9, 0x1f, 0xfe, 0xe4, + 0x86, 0x61, 0xa9, 0x0b, 0x7c, 0x0d, 0x8a, 0xa2, 0xda, 0x3a, 0x6d, 0x38, 0x6f, 0xc5, 0x00, 0xb4, + 0x0a, 0xa5, 0x66, 0x10, 0x0d, 0x80, 0x2e, 0x53, 0xc1, 0x92, 0x41, 0x95, 0x3f, 0x31, 0xe2, 0x6d, + 0x9a, 0x6e, 0x98, 0xdb, 0x3b, 0xb6, 0x17, 0x3a, 0x3d, 0x3e, 0xb0, 0xa8, 0x4c, 0x0c, 0x46, 0x6d, + 0x7b, 0xa7, 0xfa, 0xdc, 0x71, 0x7b, 0xce, 0x5e, 0x8f, 0x0d, 0xd2, 0xb0, 0x14, 0x18, 0xe1, 0x7f, + 0x8c, 0x8f, 0x18, 0x3f, 0x13, 0x89, 0xa8, 0x4c, 0xf8, 0x1f, 0xe3, 0xa3, 0x98, 0x9f, 0x49, 0x86, + 0x02, 0xab, 0xfc, 0xb8, 0x08, 0x26, 0xf7, 0x73, 0x36, 0xb1, 0xe3, 0x87, 0x7b, 0xd8, 0x09, 0x7f, + 0x03, 0x1d, 0xc1, 0x75, 0x40, 0xb6, 0x13, 0x08, 0xde, 0x9a, 0x8f, 0x1d, 0x62, 0xfc, 0xa6, 0xe9, + 0xe4, 0x6b, 0x30, 0x29, 0x5b, 0x5c, 0xd0, 0xd8, 0xe2, 0x9b, 0x30, 0xdb, 0xec, 0xbb, 0x61, 0xec, + 0xe0, 0x15, 0x29, 0x91, 0x0a, 0x24, 0x54, 0x0f, 0xbc, 0x20, 0x70, 0x07, 0xaa, 0x59, 0x57, 0x81, + 0xa4, 0x3d, 0x06, 0x78, 0xe8, 0xb9, 0x7d, 0xdc, 0xa5, 0x06, 0xbd, 0x60, 0x29, 0xb0, 0x5f, 0xb9, + 0xd7, 0x97, 0xb1, 0xd7, 0xcc, 0x8d, 0xe7, 0xdd, 0x5d, 0x4c, 0x78, 0x77, 0x9f, 0x85, 0x85, 0xea, + 0xfe, 0x21, 0xee, 0x12, 0x80, 0xd3, 0xef, 0x6e, 0x38, 0xe1, 0xfe, 0x33, 0xee, 0x04, 0xe6, 0x2d, + 0x1d, 0x8a, 0xec, 0x5c, 0x1c, 0x52, 0xc7, 0x3d, 0xf7, 0x39, 0x99, 0xf9, 0xfd, 0xc3, 0xa4, 0x33, + 0x38, 0x8c, 0x64, 0x0c, 0x8f, 0x12, 0x9d, 0x97, 0x47, 0xb9, 0x70, 0x0e, 0x1e, 0xe5, 0xe2, 0x28, + 0x8f, 0x32, 0x31, 0x9e, 0x9a, 0x13, 0x3a, 0x3d, 0xef, 0x80, 0x6e, 0xd7, 0xbc, 0x8a, 0x25, 0x5a, + 0xc5, 0x08, 0x2a, 0xb4, 0x01, 0xd7, 0x64, 0x0a, 0x0b, 0x3f, 0xf5, 0x71, 0xf0, 0x2c, 0x9e, 0x95, + 0x4b, 0x74, 0x56, 0x86, 0xd2, 0xa4, 0xeb, 0x78, 0xee, 0xf4, 0xdc, 0x2e, 0x51, 0x1e, 0xd6, 0x93, + 0xcb, 0xb4, 0x27, 0x43, 0x69, 0xd0, 0x17, 0xa0, 0x2c, 0xe3, 0x9b, 0xfd, 0x03, 0x22, 0x46, 0xcc, + 0xc1, 0x2d, 0xd3, 0x3e, 0x64, 0xe2, 0x87, 0x7b, 0xc7, 0x57, 0x46, 0x78, 0xc7, 0xdc, 0x9b, 0xb5, + 0x61, 0xa6, 0xd6, 0xae, 0xf6, 0x7a, 0xde, 0xbe, 0x13, 0xe2, 0x66, 0x5d, 0xe3, 0x24, 0x2f, 0xc2, + 0x24, 0x15, 0x47, 0x6e, 0xc7, 0x59, 0x81, 0x59, 0xf8, 0xaf, 0x1d, 0xe3, 0x80, 0x08, 0x3a, 0x33, + 0x61, 0x31, 0xa0, 0xf2, 0xdf, 0x13, 0x30, 0x2f, 0x3c, 0xa5, 0xe1, 0x36, 0x73, 0x15, 0x4a, 0x96, + 0xf3, 0x34, 0x54, 0x0d, 0xa6, 0x0c, 0xd2, 0x58, 0xd5, 0x09, 0xad, 0x55, 0x4d, 0x59, 0x99, 0xbc, + 0xce, 0xca, 0x9c, 0xcd, 0x73, 0xd2, 0xdb, 0xd0, 0xa9, 0x4c, 0x1b, 0xaa, 0xda, 0xab, 0xe9, 0x53, + 0x79, 0x5a, 0x85, 0xf1, 0x3d, 0x2d, 0x22, 0x4d, 0x09, 0x63, 0x10, 0x4b, 0x74, 0x91, 0x49, 0x53, + 0x16, 0x7e, 0x0c, 0x4b, 0x01, 0xe3, 0x58, 0x8a, 0x4a, 0x03, 0x4a, 0xd2, 0xe1, 0x63, 0x88, 0xaf, + 0x37, 0xd4, 0x49, 0xa8, 0x7c, 0x7d, 0x12, 0x4c, 0xfb, 0x3c, 0x77, 0xdd, 0xf8, 0xb8, 0x34, 0x71, + 0x92, 0xe3, 0x92, 0x7e, 0xc9, 0xf3, 0x99, 0x4b, 0x9e, 0x75, 0xbc, 0x9a, 0x3c, 0xf1, 0xf1, 0x6a, + 0x6a, 0xcc, 0xe3, 0x55, 0xe1, 0xd4, 0xc7, 0xab, 0xe2, 0xf8, 0xc7, 0x2b, 0xc8, 0xde, 0xf2, 0x88, + 0x0a, 0xe3, 0x41, 0xcf, 0x79, 0x89, 0xbb, 0xad, 0xa0, 0x4f, 0xf7, 0xed, 0xbc, 0x25, 0x83, 0xce, + 0x7e, 0x00, 0xcb, 0xda, 0x3a, 0x67, 0x4f, 0xbd, 0x75, 0xce, 0x8d, 0xdc, 0x3a, 0x1f, 0xe6, 0x0b, + 0xd3, 0x66, 0xa1, 0xf2, 0xfd, 0x49, 0x28, 0x58, 0x9d, 0xc7, 0xcc, 0x93, 0x31, 0x61, 0xc2, 0x0e, + 0x3c, 0xe1, 0x5e, 0xdb, 0x81, 0x47, 0xac, 0x63, 0xb3, 0xdf, 0xc5, 0x2f, 0x84, 0x75, 0xa4, 0x05, + 0x62, 0x8b, 0x5a, 0xd8, 0x09, 0xf0, 0xa6, 0xd7, 0x63, 0x27, 0x0e, 0xe6, 0x77, 0xaa, 0x40, 0xb2, + 0x1c, 0xb6, 0x7f, 0xdc, 0x27, 0x96, 0x97, 0xce, 0x1c, 0x77, 0x3e, 0x65, 0x18, 0x7a, 0x08, 0x33, + 0x8c, 0xc9, 0x0d, 0x42, 0xcf, 0x7f, 0xc9, 0x6d, 0x96, 0x72, 0x28, 0x12, 0xbd, 0x5b, 0x97, 0x09, + 0xd9, 0xc1, 0x43, 0xe1, 0x65, 0x0b, 0xf5, 0xb5, 0x63, 0xd7, 0x67, 0xcd, 0x4d, 0x89, 0x85, 0x8a, + 0x40, 0xe8, 0x4d, 0x98, 0xff, 0xb0, 0xda, 0xb2, 0xf0, 0xbe, 0x47, 0x66, 0xa3, 0xee, 0x1e, 0xe0, + 0x20, 0xe4, 0xc7, 0xfc, 0x34, 0x02, 0x7d, 0x0e, 0x96, 0x24, 0x20, 0x6d, 0xb1, 0xe6, 0x1d, 0xf7, + 0x43, 0x2a, 0x91, 0x79, 0x4b, 0x8f, 0x24, 0x0b, 0x23, 0x21, 0x6a, 0xde, 0xd1, 0xa0, 0x87, 0xc9, + 0x76, 0xd8, 0x0f, 0x7d, 0x17, 0x33, 0x99, 0xcc, 0x5b, 0xc3, 0x48, 0x88, 0xba, 0x48, 0xe8, 0x0d, + 0x27, 0xc0, 0x64, 0x38, 0x40, 0x19, 0x35, 0x98, 0x04, 0x7d, 0xcb, 0x09, 0xc2, 0x58, 0x4e, 0x35, + 0x18, 0xf4, 0x10, 0x56, 0x25, 0xe8, 0x96, 0xef, 0x1e, 0xb8, 0x7d, 0xa7, 0xa7, 0x2e, 0xe8, 0x0c, + 0xe5, 0x1e, 0x49, 0x47, 0x04, 0x57, 0x33, 0x14, 0x2a, 0xb8, 0x05, 0x4b, 0x87, 0x5a, 0x7e, 0x17, + 0xe6, 0x53, 0x0b, 0x39, 0xea, 0x5c, 0x97, 0x97, 0xcf, 0x75, 0x1f, 0x41, 0x91, 0x6e, 0x63, 0xfb, + 0x9e, 0xdf, 0x25, 0x8c, 0x64, 0xb0, 0x9c, 0x91, 0x8c, 0x6e, 0x0d, 0xf2, 0xf6, 0xcb, 0x01, 0xe3, + 0x9b, 0x53, 0xcd, 0x06, 0xe3, 0x21, 0x58, 0x8b, 0xd2, 0x10, 0x7b, 0x4b, 0x4d, 0x0c, 0x11, 0xdf, + 0x19, 0x8b, 0xfe, 0xae, 0xfc, 0x34, 0x07, 0x40, 0xeb, 0xa7, 0x9b, 0x3d, 0x21, 0x69, 0x3b, 0x47, + 0x58, 0x98, 0x64, 0xf2, 0x5b, 0xb6, 0xf9, 0x39, 0xd5, 0xe6, 0xf3, 0xee, 0x4c, 0xc4, 0xdd, 0x29, + 0xc3, 0xf4, 0x63, 0xe7, 0x45, 0xc7, 0xfd, 0x3d, 0x71, 0xf8, 0x12, 0x45, 0xb2, 0x3f, 0x08, 0xb3, + 0x5c, 0xe7, 0x47, 0xf3, 0x18, 0x40, 0xcf, 0xec, 0xed, 0x66, 0x9d, 0x4b, 0x31, 0xfd, 0x8d, 0x3e, + 0x07, 0x39, 0xbb, 0xc3, 0xb7, 0xd9, 0xe5, 0x75, 0x16, 0xe7, 0x5f, 0x17, 0x71, 0xfe, 0x75, 0x5b, + 0xc4, 0xf9, 0xd9, 0xb1, 0xf5, 0xcf, 0xff, 0xed, 0x86, 0x61, 0xe5, 0xec, 0x0e, 0xd9, 0xf8, 0x9a, + 0xfd, 0xfd, 0xde, 0x71, 0x17, 0x37, 0x5e, 0x0c, 0x88, 0x26, 0xf0, 0x4d, 0x88, 0xdb, 0x37, 0xcc, + 0x8e, 0x3e, 0x05, 0x6b, 0x04, 0x15, 0x71, 0x91, 0x1b, 0x2f, 0x28, 0xc5, 0xa6, 0xe3, 0x77, 0xeb, + 0xde, 0xc7, 0xfd, 0x54, 0x45, 0x6c, 0x0f, 0x1e, 0x45, 0x56, 0xa9, 0x00, 0xd8, 0x81, 0x27, 0x66, + 0x78, 0x11, 0x26, 0x99, 0x5a, 0xb1, 0x45, 0x64, 0x85, 0xca, 0xcf, 0x0d, 0xe2, 0xb9, 0xd1, 0xfd, + 0x91, 0x06, 0x2b, 0xb5, 0x7b, 0xe3, 0x5d, 0x28, 0x6e, 0x0d, 0x84, 0x7f, 0x9e, 0x4b, 0x07, 0x96, + 0x6a, 0x6d, 0xca, 0xbb, 0x35, 0xb0, 0x62, 0x3a, 0xb4, 0x11, 0x05, 0xfc, 0xd9, 0x46, 0x79, 0x53, + 0x13, 0xf0, 0xa7, 0x04, 0xd9, 0x51, 0xff, 0xf3, 0x0e, 0xbd, 0x56, 0x5a, 0x50, 0xaa, 0xb5, 0xe3, + 0x13, 0xa5, 0x6e, 0xac, 0x6f, 0x88, 0x00, 0x5a, 0x2e, 0xfb, 0x92, 0x81, 0x51, 0x54, 0x7e, 0xc6, + 0xe7, 0xce, 0x09, 0x87, 0xcc, 0xdd, 0xf8, 0xf5, 0x8d, 0x9e, 0x31, 0xd1, 0xd0, 0xaf, 0x70, 0xc6, + 0xbe, 0x59, 0x80, 0x69, 0x21, 0x41, 0x8a, 0xb3, 0x6e, 0x08, 0x4f, 0x8b, 0x03, 0xd0, 0x3a, 0x4c, + 0x3d, 0xc6, 0xe1, 0x33, 0xaf, 0xab, 0x33, 0x09, 0x0c, 0x43, 0x4d, 0x02, 0xa7, 0x42, 0xf7, 0x64, + 0xfd, 0xa7, 0xaa, 0x9c, 0xf0, 0x3e, 0x62, 0x2c, 0x1f, 0xa3, 0x6c, 0x2f, 0xaa, 0x34, 0xc4, 0x14, + 0xb9, 0x74, 0x54, 0xe9, 0x4b, 0x77, 0xae, 0x27, 0x43, 0x4c, 0x8a, 0xdf, 0x67, 0x29, 0x2c, 0xe8, + 0x3e, 0x11, 0x86, 0xb8, 0x86, 0x49, 0x5a, 0xc3, 0x35, 0x8d, 0x94, 0xc6, 0x15, 0xc8, 0x0c, 0x84, + 0xdf, 0x96, 0xf8, 0xa7, 0xd2, 0xfc, 0x76, 0x8a, 0x5f, 0x62, 0x20, 0xee, 0x57, 0xac, 0x9e, 0x3a, + 0xaf, 0x3e, 0xc6, 0x5a, 0xb2, 0x22, 0xdf, 0x53, 0xcf, 0x5a, 0xdc, 0x71, 0x2b, 0xab, 0x1d, 0x8f, + 0xf1, 0x96, 0x7a, 0x32, 0xbb, 0xa7, 0xea, 0x3b, 0x8f, 0xaa, 0x97, 0xb3, 0x94, 0xd3, 0x52, 0xad, + 0xc3, 0xe7, 0x15, 0x05, 0xa2, 0x9b, 0x65, 0xc2, 0x05, 0x96, 0xd0, 0x96, 0xa2, 0x6c, 0xf7, 0x54, + 0x65, 0xa1, 0x1b, 0xa7, 0xa6, 0x61, 0x81, 0xb7, 0x54, 0xd5, 0x7a, 0x17, 0x66, 0xeb, 0x98, 0x6c, + 0x6c, 0xbc, 0x3b, 0x3c, 0x6a, 0x73, 0x45, 0x66, 0x57, 0x08, 0x2c, 0x95, 0x1e, 0x6d, 0xc0, 0xdc, + 0xb6, 0xef, 0xbd, 0x78, 0x19, 0x2f, 0xd8, 0x2c, 0x37, 0xf0, 0x52, 0x0d, 0x2a, 0x85, 0x95, 0xe0, + 0x20, 0xbb, 0x70, 0x32, 0x60, 0xda, 0x3e, 0x3e, 0xa2, 0x4e, 0x60, 0xde, 0xd2, 0xa1, 0xd0, 0x86, + 0x14, 0xfe, 0x8d, 0x8e, 0x62, 0x17, 0xb3, 0x8f, 0x62, 0x56, 0x9a, 0x9c, 0xce, 0xf9, 0x33, 0xbc, + 0x7f, 0xb8, 0x89, 0x9d, 0x5e, 0xf8, 0x8c, 0xc6, 0x79, 0x92, 0x73, 0x1e, 0xa3, 0x2d, 0x99, 0x16, + 0xd9, 0xb0, 0xd8, 0xd9, 0x7f, 0x86, 0xbb, 0xc7, 0x3d, 0xcc, 0x5d, 0x54, 0xea, 0xa4, 0xd3, 0x88, + 0x4f, 0xe9, 0xce, 0xaa, 0x5c, 0x87, 0x8e, 0xce, 0xd2, 0x72, 0x57, 0x3c, 0x28, 0x51, 0x4d, 0x0c, + 0x06, 0x5e, 0x3f, 0xc0, 0x43, 0x8e, 0x66, 0x7c, 0x9b, 0xce, 0x29, 0xdb, 0xb4, 0x70, 0x9c, 0xd8, + 0xe6, 0x2d, 0x8a, 0xc3, 0x02, 0xeb, 0x95, 0x75, 0x40, 0x92, 0x3c, 0x4b, 0xed, 0xbe, 0xef, 0xfa, + 0x92, 0x31, 0x12, 0xc5, 0xca, 0x7f, 0xe5, 0x69, 0xa0, 0x8e, 0x91, 0x9d, 0xaf, 0xd5, 0xba, 0x06, + 0xc5, 0x86, 0xef, 0x7b, 0x7e, 0xcd, 0xeb, 0x62, 0x3a, 0x84, 0x59, 0x2b, 0x06, 0x10, 0x57, 0x9c, + 0x16, 0x1e, 0xe3, 0x20, 0x70, 0x0e, 0x30, 0x8f, 0x1d, 0x28, 0x30, 0xb4, 0x02, 0xd0, 0x0c, 0x36, + 0xab, 0x8f, 0x30, 0x1e, 0x60, 0x9f, 0x5a, 0x9d, 0x82, 0x25, 0x41, 0xd0, 0xbb, 0xca, 0xec, 0x72, + 0xb3, 0x72, 0x39, 0x65, 0x18, 0x19, 0x9a, 0x5b, 0x46, 0x65, 0x3d, 0x88, 0xa2, 0x49, 0x87, 0x18, + 0x6e, 0x59, 0x54, 0x45, 0x93, 0xf0, 0x96, 0x42, 0x4d, 0xa4, 0x8d, 0xda, 0x1a, 0xde, 0x7c, 0x21, + 0xdd, 0xbc, 0x84, 0xb6, 0x64, 0x5a, 0xa2, 0x62, 0xb5, 0xde, 0x71, 0x10, 0x62, 0xbf, 0x8e, 0xc9, + 0xe9, 0x34, 0xe0, 0xc6, 0x45, 0x51, 0x31, 0x95, 0xc2, 0x4a, 0x70, 0xa0, 0xfb, 0x50, 0x8c, 0xef, + 0x0d, 0x40, 0x23, 0xa6, 0x02, 0xc9, 0x04, 0x14, 0x07, 0xc7, 0xbd, 0xd0, 0x8a, 0x59, 0xd0, 0x7d, + 0x00, 0xc9, 0x34, 0x32, 0x1b, 0xb3, 0x22, 0x57, 0x90, 0x16, 0x24, 0x0b, 0x12, 0xe6, 0x91, 0x28, + 0x10, 0xf6, 0x99, 0x85, 0x9b, 0xd1, 0x4c, 0x9e, 0x84, 0xb7, 0x14, 0xea, 0xca, 0x43, 0x1a, 0xaf, + 0x62, 0xfe, 0x6f, 0x34, 0x2d, 0x6f, 0x91, 0x1d, 0x94, 0x40, 0x82, 0xb2, 0x41, 0xf7, 0xf5, 0xa5, + 0xd4, 0x62, 0x12, 0x2c, 0x5f, 0x4a, 0x41, 0x5b, 0x79, 0x55, 0x59, 0x08, 0xe2, 0xbe, 0x3d, 0xa1, + 0xfb, 0x36, 0x77, 0xdf, 0x68, 0xa1, 0xf2, 0x00, 0x66, 0x6d, 0x27, 0x38, 0xb4, 0x9d, 0xbd, 0x1e, + 0xde, 0x09, 0xb0, 0x4f, 0xd4, 0x88, 0xfc, 0xed, 0xc7, 0xbe, 0x74, 0x54, 0x26, 0xb8, 0x6d, 0x27, + 0x08, 0x3e, 0xf6, 0xfc, 0x2e, 0x0f, 0x6e, 0x44, 0xe5, 0xca, 0x37, 0x0c, 0xd2, 0x4b, 0x6a, 0xb7, + 0xb4, 0x6e, 0x4c, 0xb6, 0x2f, 0xae, 0xc4, 0x5f, 0x26, 0x92, 0x97, 0x34, 0xd1, 0x2d, 0x5a, 0x5e, + 0xbe, 0x45, 0x5b, 0xa1, 0x7b, 0xbf, 0xea, 0x94, 0x4b, 0x90, 0xca, 0x5f, 0xe5, 0x88, 0x0c, 0xf7, + 0x9f, 0xba, 0x07, 0xb5, 0x67, 0x4e, 0xff, 0x00, 0xa3, 0xbb, 0x51, 0xef, 0xf8, 0x65, 0xd2, 0x82, + 0x7a, 0xe0, 0xa0, 0xa8, 0x78, 0x06, 0xd9, 0x38, 0xee, 0x01, 0x30, 0x76, 0xe9, 0xa0, 0x72, 0x2d, + 0x1d, 0xdf, 0x88, 0x69, 0x2c, 0x89, 0x1e, 0xd9, 0x30, 0xd7, 0xec, 0xbb, 0xa1, 0xeb, 0xf4, 0x1e, + 0xe3, 0xa3, 0x3d, 0xec, 0x0b, 0xaf, 0xec, 0xcd, 0xac, 0x1a, 0xd6, 0x55, 0x72, 0x76, 0x74, 0x4e, + 0xd4, 0xb1, 0x5c, 0x85, 0x05, 0x0d, 0xd9, 0x89, 0x2e, 0xdc, 0xde, 0x80, 0xd9, 0xce, 0xb3, 0xe3, + 0xb0, 0xeb, 0x7d, 0xdc, 0x67, 0x5b, 0x1b, 0x59, 0x1b, 0xf2, 0x23, 0x5a, 0x32, 0x51, 0xac, 0xfc, + 0xe3, 0x24, 0x5c, 0x4c, 0x98, 0x70, 0xed, 0xea, 0xde, 0x84, 0xd9, 0x0d, 0xcf, 0x0b, 0x83, 0xd0, + 0x77, 0x06, 0x03, 0xb7, 0x7f, 0x40, 0x1b, 0x2d, 0x58, 0x2a, 0x90, 0x98, 0x06, 0x1e, 0xb3, 0xa1, + 0x13, 0x3a, 0x41, 0x27, 0x54, 0x31, 0x0d, 0x12, 0xda, 0x92, 0x69, 0x99, 0x4d, 0x8a, 0xa7, 0x8a, + 0xbb, 0x6b, 0xe5, 0xac, 0xa9, 0xb4, 0xd4, 0xd5, 0x7f, 0x37, 0x31, 0x62, 0xee, 0xab, 0x5d, 0x51, + 0x0d, 0x83, 0x44, 0x60, 0x25, 0x66, 0xe8, 0x11, 0xcc, 0xb3, 0xc0, 0x9a, 0x14, 0x69, 0xe3, 0x96, + 0x55, 0x71, 0x19, 0x53, 0x44, 0x56, 0x9a, 0x2f, 0xed, 0x8a, 0x4c, 0x9f, 0xd0, 0x15, 0x79, 0x04, + 0xf3, 0x0f, 0x3d, 0xb7, 0xcf, 0x22, 0xca, 0xdc, 0xfe, 0x71, 0x43, 0xab, 0xf4, 0x26, 0x45, 0x64, + 0xa5, 0xf9, 0xd0, 0x26, 0x98, 0xac, 0x76, 0xea, 0xab, 0xb0, 0x0e, 0x15, 0xd3, 0xae, 0x68, 0x92, + 0xc6, 0x4a, 0x71, 0x91, 0xe5, 0xad, 0x76, 0xbb, 0x42, 0x0b, 0x75, 0xbe, 0x9d, 0x84, 0xb6, 0x64, + 0x5a, 0x62, 0xf9, 0x23, 0x51, 0x61, 0xdc, 0xa5, 0xb4, 0xe5, 0x57, 0x29, 0xac, 0x04, 0x47, 0x05, + 0xeb, 0x7d, 0x15, 0xad, 0xbc, 0x26, 0x24, 0x31, 0x37, 0xbe, 0x24, 0x56, 0xfe, 0x22, 0x07, 0x97, + 0x12, 0xe1, 0x3a, 0xdb, 0xf1, 0x0f, 0x70, 0x48, 0xaf, 0x0e, 0xf9, 0x12, 0x91, 0x46, 0x98, 0xb5, + 0x2e, 0x5a, 0x0a, 0x8c, 0x06, 0xdb, 0x64, 0x9a, 0x1c, 0xa3, 0x91, 0x61, 0xc4, 0xce, 0x36, 0x5e, + 0x10, 0x13, 0xe4, 0x86, 0xfc, 0x56, 0x3a, 0x2a, 0x13, 0x17, 0x92, 0xd7, 0x67, 0xbb, 0x47, 0xd8, + 0x3b, 0x0e, 0x6d, 0x77, 0xff, 0x30, 0xe0, 0xd6, 0x51, 0x87, 0x22, 0x1c, 0xb6, 0x86, 0x83, 0x19, + 0x4d, 0x1d, 0x0a, 0x7d, 0x0e, 0x96, 0x1a, 0xc4, 0x5c, 0x38, 0x21, 0xae, 0x1d, 0xfb, 0x3e, 0xee, + 0x87, 0x94, 0x26, 0xe0, 0x37, 0x0c, 0x7a, 0x64, 0xe5, 0xb6, 0x46, 0x2a, 0xd9, 0x50, 0xdc, 0x80, + 0x5e, 0xb0, 0xb3, 0xe9, 0x88, 0xca, 0x95, 0x9e, 0x46, 0xa9, 0xd0, 0x5d, 0xc8, 0x93, 0xfd, 0x86, + 0x5b, 0x69, 0x45, 0x27, 0x94, 0x8d, 0x8a, 0xdb, 0x6a, 0x4a, 0x4c, 0x27, 0xd5, 0x09, 0x0e, 0xeb, + 0x4e, 0xe8, 0xec, 0x39, 0x81, 0x30, 0x79, 0x0a, 0x8c, 0x58, 0x3d, 0x55, 0x8b, 0xb2, 0xad, 0xde, + 0x9b, 0x69, 0x95, 0x18, 0x42, 0xfd, 0xba, 0x22, 0xf6, 0xd9, 0xde, 0x6c, 0xe5, 0x17, 0x46, 0x52, + 0xca, 0x4f, 0x7b, 0x2b, 0x81, 0x9e, 0x64, 0xec, 0x2d, 0xeb, 0xd9, 0xfa, 0x32, 0xce, 0xee, 0x42, + 0x74, 0x85, 0xac, 0x21, 0xbf, 0x57, 0xa0, 0xbf, 0xcf, 0x63, 0xc7, 0xf9, 0xcb, 0x9c, 0xea, 0x52, + 0x46, 0x99, 0x2e, 0x86, 0x94, 0xe9, 0xf2, 0x45, 0x76, 0x65, 0xed, 0xf4, 0xbb, 0x22, 0xe7, 0xe6, + 0xea, 0x90, 0xf3, 0x85, 0xb8, 0x73, 0x12, 0x2c, 0x64, 0x2a, 0x45, 0x38, 0x9e, 0x9f, 0x0c, 0x44, + 0x08, 0xbe, 0x06, 0xc0, 0xa9, 0x88, 0xc2, 0xe5, 0x69, 0xd5, 0xd7, 0x87, 0x54, 0xdd, 0xac, 0x8b, + 0x78, 0x41, 0xcc, 0x86, 0x3e, 0x84, 0x25, 0xed, 0x85, 0x13, 0xdf, 0x4a, 0x5e, 0x91, 0xeb, 0xd3, + 0x67, 0x12, 0xea, 0xf9, 0x2b, 0xdf, 0xcd, 0x65, 0xd4, 0x4c, 0x44, 0x60, 0xdb, 0xc7, 0x03, 0xc7, + 0x67, 0xca, 0x43, 0x56, 0x24, 0x06, 0x90, 0xf1, 0x36, 0xfa, 0x44, 0x1b, 0xba, 0x7c, 0xb3, 0x15, + 0xc5, 0x8c, 0xc4, 0xa3, 0x3b, 0xb0, 0x18, 0xdd, 0xfa, 0xd2, 0xc4, 0x46, 0x16, 0x6e, 0xe7, 0x4b, + 0xad, 0xc5, 0xa1, 0x75, 0x40, 0x9a, 0x9b, 0x6d, 0x66, 0x39, 0x34, 0x18, 0xe2, 0x96, 0x49, 0x17, + 0xf1, 0x2c, 0x24, 0x2a, 0x41, 0x48, 0xcf, 0xd8, 0xad, 0x30, 0x4b, 0xf7, 0x60, 0x05, 0x62, 0x23, + 0xc8, 0xa0, 0xc3, 0x10, 0x77, 0x79, 0x88, 0x33, 0x2a, 0x57, 0x7e, 0x6c, 0xa8, 0x97, 0xdb, 0xd1, + 0xec, 0x08, 0x9b, 0x2b, 0xdb, 0x4a, 0x63, 0x3c, 0x5b, 0x99, 0xcb, 0xb6, 0x95, 0x6f, 0xc3, 0xa5, + 0x58, 0xe7, 0x15, 0x26, 0x36, 0x97, 0x19, 0xd8, 0x6c, 0x8b, 0x99, 0x1f, 0x66, 0x31, 0xbf, 0x5b, + 0x82, 0x12, 0xef, 0x05, 0x3d, 0x7b, 0x88, 0x7c, 0x3c, 0x43, 0xca, 0xc7, 0xfb, 0xed, 0x4a, 0xe6, + 0xa9, 0x46, 0x11, 0xca, 0x02, 0x55, 0xc3, 0x57, 0x35, 0x61, 0x23, 0x9a, 0xc1, 0x36, 0x66, 0x22, + 0x77, 0xf1, 0x54, 0x89, 0xdc, 0xa0, 0x4f, 0x21, 0x52, 0xaf, 0xed, 0x4b, 0xe3, 0x24, 0x07, 0xcd, + 0x8c, 0x4c, 0x0e, 0x9a, 0x3d, 0x55, 0x72, 0xd0, 0xdc, 0xa9, 0x52, 0xc2, 0x2f, 0x8e, 0x93, 0x12, + 0x6e, 0x8e, 0x97, 0x34, 0x34, 0x9f, 0x48, 0x1a, 0x1a, 0x71, 0x8f, 0x89, 0xce, 0x23, 0x05, 0x68, + 0xe1, 0xbc, 0x52, 0x80, 0x16, 0xcf, 0x21, 0x05, 0x68, 0xe9, 0xec, 0x29, 0x40, 0x97, 0xce, 0x25, + 0x05, 0xe8, 0xf2, 0x39, 0xa4, 0x00, 0x95, 0xc7, 0x48, 0x01, 0x1a, 0x9e, 0x24, 0x7f, 0x65, 0x64, + 0x92, 0xfc, 0xb0, 0x14, 0xa2, 0xe5, 0xb3, 0xa4, 0x10, 0x5d, 0xfd, 0xf5, 0x24, 0xd8, 0xff, 0xb5, + 0xc1, 0xde, 0xdb, 0xf0, 0xc7, 0x27, 0xdc, 0xa0, 0x1b, 0xfa, 0xc7, 0x27, 0x4e, 0x88, 0xd7, 0x19, + 0x85, 0x62, 0xb3, 0x18, 0x68, 0xd9, 0x82, 0x92, 0x84, 0xd4, 0x74, 0xf0, 0x33, 0x6a, 0x07, 0x2f, + 0x67, 0x98, 0x45, 0xd9, 0xa7, 0xfa, 0xd7, 0x3c, 0x4d, 0x70, 0x39, 0x97, 0xcd, 0xe3, 0x77, 0x39, + 0x29, 0xbf, 0xc1, 0x39, 0x29, 0x23, 0x2c, 0xf3, 0xec, 0xb8, 0x19, 0x26, 0x44, 0xde, 0xed, 0x71, + 0xe4, 0xdd, 0xfe, 0xe5, 0xca, 0xbb, 0xad, 0x97, 0xf7, 0x7f, 0x98, 0x00, 0x90, 0xce, 0x63, 0xba, + 0x53, 0xbd, 0x50, 0x81, 0x9c, 0xa4, 0x02, 0x37, 0x61, 0x96, 0xa8, 0x37, 0xee, 0xab, 0xae, 0x91, + 0x0a, 0x4c, 0x48, 0x4d, 0x7e, 0x6c, 0xa9, 0x19, 0xbd, 0xa7, 0x4d, 0x9e, 0xd7, 0x9e, 0x36, 0x75, + 0x0e, 0x7b, 0xda, 0xf4, 0xd9, 0x1e, 0x4a, 0x15, 0x46, 0xed, 0x01, 0x95, 0xbf, 0x37, 0xa2, 0x45, + 0x22, 0x62, 0xf4, 0x5e, 0x42, 0x8c, 0x2a, 0xa9, 0xbb, 0xb2, 0x51, 0x92, 0xf4, 0xc1, 0x28, 0x49, + 0x7a, 0x53, 0x95, 0xa4, 0x4b, 0x9a, 0x16, 0x3c, 0x1f, 0xcb, 0x82, 0xf4, 0xa3, 0x5c, 0xf2, 0x26, + 0x2f, 0x2b, 0xa4, 0xa9, 0x0a, 0x4e, 0x6e, 0xb4, 0xe0, 0x4c, 0x9c, 0xa3, 0xe0, 0xe4, 0xcf, 0x4b, + 0x70, 0x26, 0xcf, 0x41, 0x70, 0xa6, 0x46, 0x08, 0x4e, 0xe5, 0xdb, 0x13, 0xc9, 0xbb, 0x1b, 0xf4, + 0x16, 0x14, 0xb8, 0x2a, 0x8b, 0xe5, 0x5f, 0xd0, 0xa8, 0xb9, 0x70, 0x67, 0x05, 0x29, 0x61, 0xab, + 0x09, 0xb6, 0x5c, 0x9a, 0xad, 0xa6, 0xb2, 0x09, 0x52, 0xf4, 0x0e, 0xcd, 0x36, 0xe2, 0x7c, 0x6c, + 0x17, 0x5b, 0xd4, 0x5d, 0xe6, 0x73, 0xc6, 0x98, 0x18, 0xdd, 0x87, 0x52, 0x2c, 0x28, 0x22, 0x3e, + 0x90, 0x21, 0x47, 0xe2, 0xba, 0x4c, 0x62, 0x40, 0x75, 0x11, 0x58, 0xea, 0xf2, 0x1a, 0x58, 0x6e, + 0x5c, 0x39, 0x1d, 0x3d, 0xed, 0xca, 0x75, 0xa8, 0x4c, 0xd9, 0xf1, 0x85, 0xa9, 0x33, 0xc6, 0x17, + 0xfe, 0xc8, 0x80, 0x12, 0x5f, 0x19, 0xea, 0x27, 0x7c, 0x9e, 0x2e, 0x0b, 0xdb, 0xed, 0x0d, 0xbe, + 0xdb, 0x47, 0xee, 0x10, 0xc7, 0x28, 0x17, 0x4a, 0x11, 0x39, 0xba, 0xc7, 0xe6, 0x98, 0xf1, 0xe6, + 0xf8, 0x28, 0x63, 0x57, 0x4a, 0x44, 0x76, 0x65, 0xe6, 0x98, 0xa1, 0xf2, 0xbd, 0x3c, 0x2c, 0xf1, + 0x40, 0x92, 0x08, 0x47, 0xf3, 0x84, 0x84, 0xd7, 0x60, 0xae, 0x7d, 0x7c, 0xb4, 0xf5, 0x34, 0xae, + 0x9c, 0x39, 0x31, 0x09, 0x28, 0x51, 0x49, 0x0a, 0x89, 0xfa, 0xcf, 0x0c, 0xbd, 0x0a, 0x44, 0x6b, + 0x60, 0x0a, 0xbe, 0x28, 0xc5, 0x9a, 0x9d, 0xde, 0x53, 0x70, 0x72, 0x76, 0x6a, 0xe3, 0x17, 0x61, + 0x74, 0x65, 0xcc, 0x4b, 0xc8, 0x86, 0x12, 0xfb, 0xb5, 0xf1, 0xf2, 0x11, 0x16, 0xd9, 0x8e, 0x77, + 0xe4, 0x35, 0xd0, 0x8e, 0x64, 0x5d, 0x62, 0x62, 0x01, 0x36, 0xb9, 0x1a, 0xf4, 0x54, 0x77, 0x99, + 0xcf, 0xde, 0x72, 0xbd, 0x33, 0x46, 0xdd, 0x49, 0xd6, 0xe4, 0xa3, 0xae, 0xe8, 0xc2, 0x9f, 0xfa, + 0x4c, 0x07, 0xe2, 0x06, 0x82, 0x27, 0xf6, 0x89, 0x53, 0x79, 0x1a, 0xb3, 0x7c, 0x1f, 0xcc, 0x64, + 0xc7, 0xf5, 0x09, 0xf8, 0xfa, 0x4c, 0x3f, 0xe5, 0x1d, 0x98, 0xd2, 0xb9, 0x51, 0xb5, 0x28, 0x41, + 0xc2, 0xff, 0x31, 0xe0, 0x8a, 0x85, 0x03, 0x16, 0x55, 0xfd, 0xd0, 0x09, 0xb1, 0x7f, 0xe4, 0xf8, + 0x87, 0x42, 0x46, 0xe2, 0x95, 0x32, 0x94, 0x95, 0xfa, 0x92, 0xba, 0x52, 0x4c, 0x2a, 0xdf, 0x4e, + 0x1c, 0x9c, 0xf5, 0x75, 0x8e, 0x58, 0x2d, 0xfd, 0x2c, 0x4e, 0xfc, 0xb2, 0x66, 0xb1, 0xf2, 0x9f, + 0xfc, 0x79, 0xe2, 0x50, 0x8f, 0xfe, 0x77, 0xef, 0x14, 0x7e, 0xdb, 0xde, 0x29, 0xfc, 0x93, 0x78, + 0xcd, 0x4b, 0x1c, 0xa6, 0xfb, 0xd1, 0x41, 0x8c, 0x99, 0xe6, 0xd5, 0xd4, 0x16, 0x46, 0xdd, 0x25, + 0x4a, 0xa2, 0xba, 0x4b, 0xcc, 0xf6, 0xdd, 0x8f, 0x1c, 0xae, 0xdc, 0x30, 0xfe, 0x4c, 0x77, 0xab, + 0x03, 0x25, 0xa9, 0x72, 0x4d, 0x8c, 0x7f, 0x5d, 0x75, 0xb7, 0x32, 0x9f, 0x64, 0xca, 0xe6, 0xa1, + 0x33, 0xca, 0x87, 0x1b, 0x55, 0xa9, 0xee, 0x38, 0xf0, 0x1f, 0x05, 0x35, 0xd1, 0x42, 0xab, 0x2d, + 0xef, 0x2a, 0x5b, 0x9f, 0xf6, 0x70, 0x1d, 0xa3, 0xc5, 0xde, 0x2e, 0x6f, 0x96, 0x77, 0xa3, 0x23, + 0x11, 0xf7, 0xed, 0x16, 0x34, 0x07, 0x21, 0x91, 0x36, 0x20, 0x0e, 0x4f, 0x6f, 0xc7, 0x0b, 0xca, + 0x8f, 0x12, 0x8b, 0xba, 0x65, 0x88, 0xa5, 0x91, 0x2f, 0xfe, 0xdd, 0x28, 0xde, 0xc0, 0x2f, 0x15, + 0x16, 0x34, 0x51, 0x06, 0xd1, 0x98, 0x88, 0x4c, 0xdc, 0x16, 0xe9, 0xa1, 0x2c, 0x50, 0xab, 0x5c, + 0x98, 0x89, 0x94, 0x20, 0x25, 0x49, 0xb4, 0xcd, 0x75, 0x92, 0xdf, 0x79, 0xf0, 0x34, 0x95, 0x69, + 0xca, 0xbd, 0x92, 0xbc, 0x6e, 0x53, 0xa9, 0x2c, 0x0d, 0x27, 0x6a, 0x24, 0x32, 0x48, 0xb8, 0x02, + 0x8e, 0xbc, 0xb9, 0x4b, 0xe4, 0x9d, 0x08, 0xfb, 0xde, 0xe5, 0x99, 0xf7, 0xbc, 0x84, 0x1e, 0xa9, + 0xf6, 0x1d, 0xa8, 0x58, 0xbf, 0x91, 0x95, 0x4e, 0x33, 0xc2, 0xa4, 0xdf, 0x93, 0x4f, 0x27, 0xfc, + 0x8a, 0xf9, 0x92, 0xfe, 0x4c, 0x22, 0xae, 0x80, 0xa4, 0xd3, 0x8c, 0x1c, 0xa0, 0x9d, 0x39, 0xd9, + 0xeb, 0x4d, 0x5d, 0xd6, 0xdf, 0x6c, 0x76, 0xd6, 0xdf, 0xa6, 0xce, 0x51, 0x98, 0x1b, 0x69, 0xd8, + 0x34, 0xae, 0xc0, 0x3d, 0xb8, 0x92, 0xde, 0xaa, 0xb6, 0x71, 0xbf, 0xeb, 0xf6, 0x0f, 0x68, 0xbc, + 0xb8, 0x60, 0x65, 0x13, 0xa0, 0x0d, 0xb8, 0xa6, 0x6c, 0x9b, 0x74, 0x23, 0x95, 0x8e, 0x16, 0xec, + 0xc9, 0xe8, 0x50, 0x1a, 0x72, 0xa4, 0xd4, 0x34, 0x40, 0xaf, 0xb1, 0xa2, 0xa7, 0xa3, 0x43, 0x28, + 0xd0, 0x7b, 0x70, 0x35, 0x8d, 0x8d, 0xde, 0x62, 0x88, 0xc0, 0xf3, 0x10, 0x92, 0x33, 0x6f, 0xcc, + 0x7f, 0x66, 0xc0, 0x8c, 0xec, 0xac, 0x6b, 0x8f, 0x8b, 0xd7, 0xa0, 0xc8, 0xae, 0x85, 0x44, 0x3e, + 0x41, 0xd1, 0x8a, 0x01, 0xa8, 0x0c, 0xd3, 0xea, 0x6e, 0x2c, 0x8a, 0x52, 0xf4, 0x3e, 0xaf, 0x44, + 0xef, 0x97, 0xa1, 0x50, 0xf7, 0x3e, 0xee, 0x53, 0xcc, 0x24, 0xc5, 0x44, 0xe5, 0xca, 0xb7, 0x2b, + 0x60, 0x0a, 0xdd, 0x8e, 0xde, 0x04, 0x45, 0x2f, 0x80, 0x0c, 0xf9, 0x05, 0x90, 0x2e, 0x24, 0x12, + 0xbb, 0x52, 0x13, 0x8a, 0x2b, 0xb5, 0xa5, 0xaa, 0x1a, 0x3b, 0x08, 0x7d, 0x46, 0x67, 0x50, 0xa2, + 0xa7, 0x3e, 0xc3, 0xd5, 0x4d, 0xf7, 0x3d, 0x83, 0x5f, 0xbb, 0xbd, 0xea, 0x82, 0x99, 0xb8, 0xef, + 0x15, 0x97, 0x51, 0x77, 0x86, 0x0e, 0x35, 0xc9, 0x24, 0x6f, 0x9f, 0xa9, 0x1a, 0x51, 0x53, 0x3e, + 0x2a, 0xb1, 0x0f, 0x16, 0x7d, 0x7a, 0x68, 0xf5, 0x11, 0x35, 0x9b, 0xc7, 0x98, 0x5b, 0xde, 0x16, + 0x60, 0xec, 0x6d, 0x41, 0xda, 0xb8, 0x4a, 0xa7, 0xda, 0xb8, 0x66, 0x4e, 0xb0, 0x71, 0x25, 0xb6, + 0xd9, 0xd9, 0x13, 0x6f, 0xb3, 0xa9, 0x3d, 0x64, 0xee, 0x54, 0x7b, 0x88, 0x6a, 0xde, 0x2f, 0x9e, + 0xd0, 0xbc, 0xa7, 0xce, 0xf1, 0xe6, 0x69, 0xce, 0xf1, 0x19, 0xc6, 0x7e, 0xfe, 0x84, 0xc6, 0x1e, + 0x9d, 0xbb, 0xb1, 0x5f, 0x38, 0xab, 0xb1, 0x5f, 0x3c, 0xb3, 0xb1, 0x5f, 0x3a, 0xab, 0xb1, 0xbf, + 0x34, 0xd2, 0xd8, 0xa3, 0xb7, 0x53, 0xd9, 0x59, 0x22, 0x4b, 0x82, 0xdd, 0xa3, 0x65, 0x60, 0x35, + 0x47, 0x81, 0x38, 0xf7, 0xa2, 0xac, 0x3d, 0x0a, 0xc4, 0xa9, 0x18, 0x5f, 0x85, 0xc5, 0x04, 0x4e, + 0xdc, 0x99, 0xa5, 0x0e, 0xa3, 0x29, 0xbd, 0xd7, 0x31, 0x32, 0x13, 0xa0, 0xad, 0x13, 0x0d, 0x52, + 0xe3, 0xab, 0xb5, 0xc5, 0x1d, 0x5b, 0x2a, 0x90, 0x30, 0xaa, 0x35, 0xce, 0xca, 0xda, 0xcb, 0xa8, + 0x57, 0xd3, 0xa2, 0xdd, 0x16, 0x17, 0x73, 0x27, 0x6e, 0xd1, 0x1e, 0xd6, 0x22, 0x47, 0xa2, 0x4d, + 0xb8, 0x91, 0xc0, 0xf0, 0x54, 0x9e, 0xa0, 0x1a, 0x04, 0xee, 0x41, 0x1f, 0x77, 0xcb, 0xd7, 0xd8, + 0x0b, 0xb6, 0x11, 0x64, 0xa8, 0x05, 0xaf, 0x24, 0x47, 0x15, 0xa5, 0xf4, 0x44, 0x75, 0x5d, 0xa7, + 0x75, 0x8d, 0x26, 0xcc, 0x3c, 0xf2, 0xc5, 0x92, 0xb2, 0x32, 0xe4, 0xc8, 0x17, 0xcb, 0xcb, 0x46, + 0x46, 0x4e, 0x8b, 0x90, 0xd4, 0x1b, 0xe9, 0x1b, 0xdf, 0x24, 0x4d, 0x66, 0xa4, 0x9e, 0xc5, 0x6b, + 0x57, 0xa9, 0xae, 0x0e, 0xa1, 0x40, 0x0f, 0x61, 0x55, 0x7b, 0x1b, 0x2c, 0xa7, 0x06, 0xbd, 0x42, + 0xfb, 0x31, 0x92, 0x6e, 0x8c, 0x9b, 0xf0, 0xca, 0x58, 0x37, 0xe1, 0x5f, 0x37, 0xe0, 0xba, 0xb6, + 0xcb, 0x34, 0xcc, 0x40, 0x24, 0xee, 0x55, 0x2a, 0x71, 0xef, 0x0e, 0x95, 0xb8, 0xa1, 0x35, 0x30, + 0xc1, 0x1b, 0xde, 0x0a, 0xfa, 0x83, 0xac, 0xa4, 0x23, 0xa1, 0x6a, 0x37, 0x69, 0x37, 0xee, 0x9f, + 0xbc, 0x1b, 0x8a, 0xc2, 0x0d, 0x6d, 0x03, 0x7d, 0xc3, 0xc8, 0x08, 0xed, 0xd3, 0x2d, 0x8b, 0xf5, + 0xe3, 0x53, 0xb4, 0x1f, 0xd5, 0x93, 0xf7, 0x23, 0xae, 0x83, 0x75, 0x65, 0x54, 0x4b, 0xe8, 0x8f, + 0x8d, 0x0c, 0xd9, 0xaf, 0xb5, 0x79, 0x26, 0x56, 0xf9, 0x35, 0xda, 0x99, 0xf7, 0x4e, 0x33, 0x29, + 0xbc, 0x0a, 0xd6, 0x97, 0x11, 0xed, 0xa0, 0x6f, 0x1a, 0xf0, 0x4a, 0x76, 0x77, 0x45, 0x6f, 0x5e, + 0xa7, 0xbd, 0xa9, 0x9d, 0x72, 0x6a, 0x94, 0x0e, 0x8d, 0x6e, 0x2d, 0x53, 0xa3, 0xc5, 0xe6, 0x7b, + 0x6b, 0x88, 0x46, 0x8b, 0xfd, 0xf7, 0x5b, 0x06, 0x54, 0x86, 0x0e, 0x9d, 0x25, 0xa2, 0xbd, 0x41, + 0x07, 0x56, 0x3f, 0xfd, 0x34, 0xd3, 0x6a, 0xd8, 0xc8, 0xc6, 0x68, 0x0f, 0x7d, 0xcf, 0x80, 0x4f, + 0x8d, 0x9a, 0x00, 0xd6, 0xb3, 0x35, 0xda, 0xb3, 0x07, 0x67, 0x9a, 0x72, 0xa9, 0x73, 0xe3, 0xb5, + 0x7a, 0xe6, 0xe0, 0xf5, 0x47, 0xb0, 0xa4, 0x75, 0xed, 0x4f, 0x18, 0xa7, 0x52, 0x5e, 0x44, 0x49, + 0xd5, 0xdf, 0xa3, 0x1f, 0x37, 0xcb, 0x08, 0xaa, 0x8d, 0xec, 0xdc, 0x03, 0xb8, 0x92, 0xe9, 0x20, + 0x8c, 0xaa, 0xa8, 0x20, 0x57, 0xd4, 0x4c, 0x25, 0x09, 0xc8, 0xa6, 0xe8, 0x8c, 0x55, 0xd9, 0xa7, + 0xad, 0x6a, 0x3b, 0x43, 0xe2, 0x15, 0x6b, 0x7d, 0xa2, 0x1a, 0xb7, 0x32, 0x6c, 0xc3, 0xa9, 0x47, + 0x6b, 0xc1, 0xcd, 0x71, 0x2c, 0xe8, 0x89, 0xea, 0xfc, 0x00, 0x5e, 0x1d, 0xc3, 0x10, 0x9e, 0x48, + 0x50, 0x6c, 0x78, 0x6d, 0x3c, 0x6b, 0x76, 0xa2, 0x5a, 0x77, 0xe0, 0xf5, 0x31, 0x4d, 0xc9, 0x89, + 0xaa, 0xfd, 0x12, 0xac, 0x8d, 0x6f, 0x07, 0x4e, 0x14, 0xaa, 0x69, 0xb2, 0x7c, 0x1b, 0xf1, 0x1d, + 0xc1, 0x33, 0x7c, 0xa7, 0xa7, 0xf2, 0x37, 0x39, 0x58, 0xd4, 0x3d, 0x16, 0x1c, 0x92, 0xb3, 0xbf, + 0x9d, 0xfa, 0x6a, 0xe4, 0xfa, 0xa8, 0xa7, 0x87, 0xea, 0xd7, 0x23, 0x53, 0x17, 0x28, 0xe7, 0xf2, + 0x0d, 0xc9, 0x65, 0x7b, 0xf4, 0x47, 0x1e, 0x87, 0x25, 0xe4, 0x48, 0x33, 0x2a, 0xcf, 0xf5, 0xf7, + 0x0d, 0x80, 0x0d, 0x67, 0xff, 0xf0, 0x78, 0x40, 0xef, 0x60, 0xb2, 0x2e, 0xe8, 0x9a, 0xba, 0x0b, + 0xba, 0xd7, 0x95, 0x77, 0x0a, 0x51, 0x25, 0xc3, 0xe3, 0x49, 0x67, 0x0e, 0xe4, 0xfd, 0xa1, 0x21, + 0xee, 0x97, 0x9a, 0x21, 0x3e, 0xd2, 0x7e, 0x32, 0xa4, 0x02, 0x33, 0x3c, 0x47, 0xfb, 0x89, 0x74, + 0x4b, 0xa9, 0xc0, 0x08, 0x4d, 0x1d, 0x3f, 0x75, 0x8e, 0x7b, 0x9c, 0x86, 0x45, 0xf4, 0x14, 0x18, + 0x59, 0xa2, 0x66, 0x3f, 0xc4, 0x7e, 0xdf, 0xe9, 0xf1, 0x8b, 0xb5, 0xa8, 0x5c, 0xf9, 0x5b, 0x43, + 0xbe, 0xe6, 0x42, 0x5f, 0x84, 0xe9, 0x9a, 0xd7, 0x0f, 0x31, 0xfd, 0xb2, 0x46, 0x3a, 0x29, 0x3a, + 0x22, 0x5c, 0xe7, 0x54, 0x6c, 0x62, 0x04, 0xcf, 0xb2, 0x45, 0x5f, 0xc6, 0x45, 0x88, 0x13, 0xa6, + 0xc8, 0xc4, 0xd3, 0x21, 0x4f, 0xd4, 0xef, 0xc7, 0xf7, 0x69, 0xe8, 0xad, 0xf8, 0xdd, 0x68, 0x2a, + 0x13, 0x4c, 0x10, 0xad, 0x53, 0x0a, 0xd6, 0x31, 0x46, 0xbd, 0xfc, 0x0e, 0x40, 0x0c, 0x3c, 0xd1, + 0x3d, 0xf0, 0xeb, 0xca, 0x73, 0xf5, 0x21, 0xef, 0x69, 0x3e, 0x82, 0xf9, 0xd4, 0xcb, 0x0d, 0x74, + 0x13, 0x66, 0xd9, 0x17, 0x70, 0xc4, 0x63, 0x10, 0xc6, 0xa4, 0x02, 0xe9, 0x32, 0x73, 0x16, 0xe9, + 0xab, 0x49, 0x0a, 0x6c, 0xed, 0x63, 0x80, 0x9d, 0x41, 0xd7, 0x09, 0x59, 0x04, 0xf7, 0x32, 0x2c, + 0x28, 0x5f, 0xd4, 0x61, 0x28, 0xf3, 0x02, 0x5a, 0x82, 0x79, 0xf1, 0xa5, 0xa4, 0x56, 0xa7, 0xcd, + 0xc1, 0x06, 0x5a, 0x80, 0x8b, 0x3b, 0x01, 0xf6, 0xe9, 0xf0, 0x39, 0x30, 0x87, 0x66, 0xa1, 0x68, + 0x77, 0xb6, 0x78, 0x71, 0x82, 0xb0, 0x46, 0x5f, 0x3d, 0x8a, 0x58, 0xf3, 0x6b, 0xeb, 0x50, 0x8c, + 0xbe, 0xb4, 0x8b, 0x2e, 0x42, 0xa9, 0xed, 0xf9, 0x47, 0x4e, 0x8f, 0x16, 0xcd, 0x0b, 0xc8, 0x84, + 0x19, 0xfe, 0xf4, 0x80, 0x41, 0x8c, 0xb5, 0x9f, 0xe7, 0x01, 0xe2, 0x97, 0xe6, 0x68, 0x0e, 0xc0, + 0xee, 0x6c, 0xed, 0xee, 0x6c, 0xd7, 0xab, 0x76, 0xc3, 0xbc, 0x80, 0x00, 0xa6, 0xaa, 0xdb, 0xdb, + 0x8d, 0x76, 0xdd, 0x34, 0x50, 0x01, 0xf2, 0x56, 0xa3, 0x5a, 0x37, 0x73, 0x68, 0x06, 0x0a, 0xb6, + 0xb5, 0xd3, 0xae, 0x11, 0x9a, 0x09, 0x52, 0xe9, 0x83, 0x86, 0xbd, 0x1b, 0x41, 0xf2, 0xa8, 0x04, + 0xd3, 0xb5, 0xad, 0x76, 0xbb, 0x51, 0xb3, 0xcd, 0x49, 0x52, 0x25, 0x2f, 0xec, 0x5a, 0x5b, 0xe6, + 0x14, 0x9a, 0x87, 0xd9, 0xd6, 0xd6, 0x83, 0xdd, 0xcd, 0x46, 0xd5, 0xb2, 0x37, 0x1a, 0x55, 0xdb, + 0x9c, 0x26, 0x35, 0xd4, 0xda, 0x12, 0xa4, 0x40, 0x3b, 0x2a, 0x43, 0x8a, 0x08, 0xc1, 0x5c, 0x6d, + 0xb3, 0x51, 0x7b, 0xb4, 0xbb, 0x59, 0x7d, 0xd4, 0x68, 0x6c, 0x37, 0x2c, 0x13, 0xc8, 0xbc, 0x92, + 0x96, 0x6b, 0xad, 0x9d, 0x8e, 0xdd, 0xb0, 0x76, 0xeb, 0x0d, 0xbb, 0xda, 0x6c, 0x75, 0xcc, 0x12, + 0x21, 0x26, 0x88, 0xce, 0x66, 0xd5, 0xaa, 0xef, 0x36, 0xdb, 0xef, 0x6f, 0x99, 0x33, 0xb4, 0x82, + 0xf6, 0x6e, 0xb5, 0xd5, 0xda, 0x22, 0xbd, 0xdc, 0x6d, 0xd6, 0xcd, 0x59, 0x32, 0x89, 0x72, 0x05, + 0x1d, 0x9b, 0xf4, 0x7f, 0x8e, 0xce, 0x3f, 0x9d, 0x81, 0xdd, 0x5a, 0x7b, 0xb7, 0x55, 0xdd, 0x68, + 0xb4, 0xcc, 0x8b, 0xa8, 0x0c, 0x8b, 0x31, 0xf0, 0xc3, 0x2d, 0xeb, 0x11, 0x27, 0x37, 0x49, 0xcd, + 0xdb, 0x55, 0xbb, 0xb6, 0x49, 0x10, 0x1d, 0x7b, 0xcb, 0x6a, 0x98, 0xf3, 0xa4, 0x8a, 0x7a, 0xa3, + 0xd5, 0x60, 0xd4, 0x0c, 0x88, 0x08, 0x70, 0xdb, 0xda, 0xfa, 0xd2, 0x97, 0xa5, 0x81, 0x2d, 0xa0, + 0x57, 0xe0, 0x3a, 0xaf, 0xb7, 0xbd, 0xd5, 0xde, 0x7d, 0xb2, 0x65, 0x37, 0xdb, 0x0f, 0x76, 0xad, + 0xc6, 0x76, 0xab, 0x59, 0xab, 0xee, 0xb6, 0x77, 0x1e, 0x9b, 0x8b, 0x68, 0x05, 0x96, 0xd3, 0x24, + 0x64, 0x1c, 0xad, 0xa6, 0xfd, 0x65, 0x73, 0x09, 0x2d, 0x82, 0xd9, 0x69, 0xd8, 0xbb, 0x56, 0xe3, + 0x83, 0x9d, 0xa6, 0xd5, 0xa8, 0xef, 0xb6, 0x3a, 0x6d, 0xf3, 0x12, 0x81, 0x3e, 0x48, 0x42, 0x2f, + 0x8b, 0xa9, 0x69, 0x55, 0xed, 0x46, 0xc7, 0xa6, 0xb0, 0x32, 0x59, 0x12, 0x0a, 0x6b, 0x54, 0xeb, + 0x0d, 0x8b, 0xcc, 0xcc, 0x15, 0xba, 0x24, 0x6c, 0xba, 0x1b, 0xd5, 0x96, 0xbd, 0x69, 0x2e, 0x93, + 0x45, 0x27, 0xcb, 0x4f, 0x59, 0xae, 0xa2, 0x2b, 0xb0, 0xc4, 0xbb, 0xd4, 0x6a, 0x54, 0x3b, 0x8d, + 0xcd, 0xad, 0x16, 0x67, 0xbd, 0x46, 0x50, 0x74, 0xf2, 0x6b, 0x9b, 0x8d, 0xfa, 0x4e, 0xab, 0xb1, + 0x5b, 0xdb, 0x7a, 0xfc, 0xb8, 0xda, 0xae, 0x77, 0xcc, 0xeb, 0x6b, 0x6d, 0x80, 0xf8, 0xfb, 0x4c, + 0x44, 0x32, 0x88, 0x98, 0x33, 0x88, 0x79, 0x81, 0xb4, 0x20, 0xec, 0x9c, 0x69, 0x10, 0xe1, 0xa5, + 0x4a, 0x13, 0x29, 0xc0, 0x3c, 0xff, 0x20, 0x99, 0x85, 0xbf, 0x8a, 0xf7, 0x43, 0xdc, 0x35, 0x27, + 0xd6, 0xd6, 0xa0, 0x18, 0x7d, 0xfe, 0x87, 0xb0, 0x77, 0x70, 0x48, 0x4b, 0xe6, 0x05, 0xc2, 0xce, + 0x82, 0xab, 0x0c, 0x60, 0xac, 0xfd, 0x4b, 0x1e, 0x90, 0x38, 0x52, 0x48, 0xba, 0x49, 0x24, 0xde, + 0xdd, 0x3f, 0x94, 0x55, 0x52, 0xfa, 0xce, 0x4a, 0xa4, 0x92, 0x44, 0x53, 0x53, 0xe0, 0x1c, 0xba, + 0x44, 0xf3, 0x3c, 0x92, 0xf0, 0x09, 0xd2, 0xfa, 0x03, 0x1c, 0x46, 0x9a, 0x9e, 0x27, 0x93, 0x92, + 0xb0, 0x37, 0x1c, 0x35, 0x49, 0x56, 0xa4, 0x83, 0x99, 0x42, 0x72, 0xd8, 0x14, 0x11, 0x36, 0x35, + 0x91, 0x87, 0x63, 0xa6, 0xd1, 0x0d, 0xb8, 0xda, 0xc1, 0x61, 0xfa, 0x6e, 0x82, 0x13, 0x14, 0xd0, + 0x32, 0x5c, 0xe2, 0x04, 0x51, 0x70, 0x9b, 0xe3, 0x8a, 0x64, 0x0a, 0xd9, 0x6f, 0x3e, 0x6b, 0x26, + 0x90, 0x81, 0x09, 0x50, 0xf4, 0xe8, 0xc5, 0x2c, 0x91, 0xf5, 0xdf, 0x26, 0xf6, 0x8e, 0xe7, 0xc8, + 0x99, 0x33, 0x84, 0xd7, 0xc2, 0x47, 0xde, 0x73, 0xf1, 0x06, 0xd2, 0x9c, 0x25, 0xbd, 0x54, 0x93, + 0x21, 0x79, 0x43, 0x73, 0xe8, 0x3a, 0x5c, 0x61, 0xbf, 0x35, 0x41, 0x6b, 0xf3, 0x22, 0xba, 0x0a, + 0x97, 0x13, 0x68, 0xb1, 0x1b, 0x30, 0x75, 0x12, 0xa7, 0x1e, 0x5e, 0xdf, 0x3c, 0xba, 0x06, 0xe5, + 0x74, 0x2a, 0x0e, 0xc7, 0x22, 0x74, 0x13, 0x56, 0x45, 0x10, 0x37, 0x1d, 0xde, 0xe5, 0x54, 0x0b, + 0x64, 0xe6, 0x58, 0x00, 0x2c, 0x71, 0x02, 0xe1, 0x04, 0x8b, 0xe8, 0x53, 0xf0, 0x0a, 0x23, 0xd0, + 0x3a, 0x98, 0x9c, 0x6c, 0x69, 0xed, 0x3b, 0x06, 0xcc, 0x2a, 0xb7, 0x4d, 0x44, 0xaf, 0x05, 0x80, + 0x67, 0xa3, 0x98, 0x17, 0xc8, 0x8a, 0x0b, 0xa0, 0xf2, 0x92, 0xdd, 0x34, 0x48, 0x43, 0x29, 0x94, + 0x38, 0x3f, 0x5a, 0x78, 0x1f, 0xbb, 0xcf, 0x71, 0xd7, 0xcc, 0x91, 0x59, 0x4a, 0x91, 0xbd, 0xef, + 0xb8, 0x3d, 0x22, 0xfa, 0x72, 0x9b, 0xd6, 0x71, 0xbf, 0x4f, 0x2a, 0xce, 0xaf, 0xed, 0xe9, 0xee, + 0xbb, 0xc8, 0x32, 0x29, 0xd0, 0xb8, 0x8f, 0x49, 0x8c, 0xa8, 0xc9, 0x48, 0x61, 0x3a, 0xa1, 0x37, + 0x18, 0x90, 0x5e, 0xad, 0xfd, 0xc8, 0x00, 0x33, 0xf9, 0xed, 0x02, 0xa2, 0x45, 0xd5, 0xae, 0xf8, + 0x9c, 0x98, 0x79, 0x21, 0x16, 0x16, 0x01, 0x32, 0x88, 0x44, 0x75, 0x42, 0xc7, 0x0f, 0x05, 0x24, + 0x47, 0x94, 0x84, 0x54, 0x2b, 0x00, 0x13, 0xa4, 0x96, 0x47, 0x6e, 0xaf, 0xf7, 0x15, 0xef, 0x68, + 0xcf, 0x25, 0x4a, 0x73, 0x19, 0x16, 0xaa, 0xdd, 0x6e, 0x52, 0x84, 0xcc, 0x49, 0x22, 0xe3, 0xac, + 0xfa, 0x14, 0x6e, 0x8a, 0x6a, 0x1a, 0x69, 0x27, 0x85, 0x9a, 0x26, 0x83, 0x22, 0x0d, 0xa6, 0x30, + 0x85, 0xb5, 0xc7, 0xca, 0x9b, 0x6e, 0xd2, 0x91, 0x58, 0x90, 0xcc, 0x0b, 0x74, 0xef, 0x6d, 0x8b, + 0xa2, 0x41, 0x8a, 0xb5, 0xa8, 0x98, 0xa3, 0xba, 0x42, 0xaf, 0x82, 0x38, 0x64, 0x62, 0xa3, 0xf9, + 0xc3, 0x9f, 0xad, 0x5c, 0xf8, 0xc1, 0x27, 0x2b, 0xc6, 0x0f, 0x3f, 0x59, 0x31, 0x7e, 0xfa, 0xc9, + 0xca, 0x85, 0xbf, 0xfb, 0xf7, 0x15, 0xe3, 0x2b, 0x77, 0xa5, 0x7f, 0xf2, 0x72, 0xe4, 0x84, 0xbe, + 0xfb, 0xc2, 0xa3, 0x8e, 0x85, 0x28, 0xf4, 0xf1, 0xed, 0xc1, 0xe1, 0xc1, 0xed, 0xc1, 0xde, 0xed, + 0xd8, 0x4d, 0xda, 0x9b, 0xa2, 0xdf, 0x7e, 0xbb, 0xfb, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xad, + 0xd6, 0x4d, 0xc8, 0x40, 0x66, 0x00, 0x00, } func (m *CNStore) Marshal() (dAtA []byte, err error) { @@ -6863,6 +6891,18 @@ func (m *CNStore) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityBarrierReady { + i-- + if m.DDLVisibilityBarrierReady { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa8 + } if m.ViewMetadataAdmissionReady { i-- if m.ViewMetadataAdmissionReady { @@ -7433,6 +7473,18 @@ func (m *CNStoreHeartbeat) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityBarrierReady { + i-- + if m.DDLVisibilityBarrierReady { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc8 + } if m.ViewMetadataIngressReady { i-- if m.ViewMetadataIngressReady { @@ -9851,6 +9903,18 @@ func (m *CNStoreInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityBarrierReady { + i-- + if m.DDLVisibilityBarrierReady { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd8 + } if m.ViewMetadataIngressReady { i-- if m.ViewMetadataIngressReady { @@ -12331,6 +12395,9 @@ func (m *CNStore) ProtoSize() (n int) { if m.ViewMetadataAdmissionReady { n += 3 } + if m.DDLVisibilityBarrierReady { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -12598,6 +12665,9 @@ func (m *CNStoreHeartbeat) ProtoSize() (n int) { if m.ViewMetadataIngressReady { n += 3 } + if m.DDLVisibilityBarrierReady { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -13662,6 +13732,9 @@ func (m *CNStoreInfo) ProtoSize() (n int) { if m.ViewMetadataIngressReady { n += 3 } + if m.DDLVisibilityBarrierReady { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -15182,6 +15255,26 @@ func (m *CNStore) Unmarshal(dAtA []byte) error { } } m.ViewMetadataAdmissionReady = bool(v != 0) + case 21: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityBarrierReady", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityBarrierReady = bool(v != 0) default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -17046,6 +17139,26 @@ func (m *CNStoreHeartbeat) Unmarshal(dAtA []byte) error { } } m.ViewMetadataIngressReady = bool(v != 0) + case 25: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityBarrierReady", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityBarrierReady = bool(v != 0) default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -24022,6 +24135,26 @@ func (m *CNStoreInfo) Unmarshal(dAtA []byte) error { } } m.ViewMetadataIngressReady = bool(v != 0) + case 27: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityBarrierReady", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityBarrierReady = bool(v != 0) default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) diff --git a/pkg/pb/logservice/logservice_test.go b/pkg/pb/logservice/logservice_test.go index ba264a35435b7..30d3f5b21467d 100644 --- a/pkg/pb/logservice/logservice_test.go +++ b/pkg/pb/logservice/logservice_test.go @@ -39,6 +39,7 @@ func TestCNStateUpdate(t *testing.T) { ServiceAddress: "addr-a", Role: metadata.CNRole_AP, CommandDeliveryAckSupported: true, + DDLVisibilityBarrierReady: true, } tick1 := uint64(100) @@ -51,6 +52,7 @@ func TestCNStateUpdate(t *testing.T) { Labels: map[string]metadata.LabelList{}, UpTime: state.Stores[hb1.UUID].UpTime, CommandDeliveryAckSupported: true, + DDLVisibilityBarrierReady: true, }) hb2 := CNStoreHeartbeat{UUID: "cn-b", ServiceAddress: "addr-b", Role: metadata.CNRole_TP} diff --git a/pkg/pb/metadata/metadata.pb.go b/pkg/pb/metadata/metadata.pb.go index 6e597ae379440..531a212422dac 100644 --- a/pkg/pb/metadata/metadata.pb.go +++ b/pkg/pb/metadata/metadata.pb.go @@ -562,13 +562,16 @@ type CNService struct { // CPUTotal is cpu quota from logservicepb.CNStore CPUTotal uint64 `protobuf:"varint,11,opt,name=CPUTotal,proto3" json:"CPUTotal,omitempty"` // MemTotal is mem quota from logservicepb.CNStore - MemTotal uint64 `protobuf:"varint,12,opt,name=MemTotal,proto3" json:"MemTotal,omitempty"` - ViewMetadataAdmissionGeneration uint64 `protobuf:"varint,13,opt,name=ViewMetadataAdmissionGeneration,proto3" json:"ViewMetadataAdmissionGeneration,omitempty"` - ViewMetadataAdmissionReady bool `protobuf:"varint,14,opt,name=ViewMetadataAdmissionReady,proto3" json:"ViewMetadataAdmissionReady,omitempty"` - ViewMetadataObservedEpoch uint64 `protobuf:"varint,15,opt,name=ViewMetadataObservedEpoch,proto3" json:"ViewMetadataObservedEpoch,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + MemTotal uint64 `protobuf:"varint,12,opt,name=MemTotal,proto3" json:"MemTotal,omitempty"` + ViewMetadataAdmissionGeneration uint64 `protobuf:"varint,13,opt,name=ViewMetadataAdmissionGeneration,proto3" json:"ViewMetadataAdmissionGeneration,omitempty"` + ViewMetadataAdmissionReady bool `protobuf:"varint,14,opt,name=ViewMetadataAdmissionReady,proto3" json:"ViewMetadataAdmissionReady,omitempty"` + ViewMetadataObservedEpoch uint64 `protobuf:"varint,15,opt,name=ViewMetadataObservedEpoch,proto3" json:"ViewMetadataObservedEpoch,omitempty"` + // DDLVisibilityBarrierReady is published after QueryService is listening. + // A CN is not publicly routable until its startup DDL frontier fence completes. + DDLVisibilityBarrierReady bool `protobuf:"varint,16,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNService) Reset() { *m = CNService{} } @@ -702,6 +705,13 @@ func (m *CNService) GetViewMetadataObservedEpoch() uint64 { return 0 } +func (m *CNService) GetDDLVisibilityBarrierReady() bool { + if m != nil { + return m.DDLVisibilityBarrierReady + } + return false +} + // TNService tn service metadata type TNService struct { // ServiceID service ID @@ -892,64 +902,65 @@ func init() { func init() { proto.RegisterFile("metadata.proto", fileDescriptor_56d9f74966f40d04) } var fileDescriptor_56d9f74966f40d04 = []byte{ - // 905 bytes of a gzipped FileDescriptorProto + // 928 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xc1, 0x6e, 0xdb, 0x46, - 0x10, 0x35, 0x25, 0x5a, 0x22, 0x47, 0x8e, 0xca, 0x6c, 0xd0, 0x94, 0x75, 0x03, 0xd9, 0x60, 0x7b, - 0x70, 0x8d, 0x56, 0x4a, 0xdc, 0xa2, 0x28, 0x8a, 0xb6, 0x88, 0x2c, 0x27, 0x8e, 0x03, 0x85, 0x52, - 0x28, 0xca, 0x6d, 0x7a, 0x29, 0x28, 0x71, 0x43, 0x2f, 0x24, 0xed, 0x12, 0x2b, 0xca, 0x89, 0x7e, - 0xa1, 0xc7, 0x5e, 0x7b, 0xe9, 0xe7, 0xe4, 0xe8, 0x2f, 0x08, 0x5a, 0xf7, 0xd8, 0x9f, 0x08, 0xb8, - 0x24, 0x45, 0x9a, 0x96, 0x14, 0x5f, 0x72, 0xe2, 0xce, 0xbc, 0xb7, 0xb3, 0xf3, 0x66, 0x67, 0x16, - 0x84, 0xea, 0x04, 0x07, 0x8e, 0xeb, 0x04, 0x4e, 0xdd, 0xe7, 0x2c, 0x60, 0x48, 0x49, 0xec, 0xed, - 0xaf, 0x3d, 0x12, 0x9c, 0xcd, 0x06, 0xf5, 0x21, 0x9b, 0x34, 0x3c, 0xe6, 0xb1, 0x86, 0x20, 0x0c, - 0x66, 0x2f, 0x85, 0x25, 0x0c, 0xb1, 0x8a, 0x36, 0x1a, 0x27, 0x70, 0xcb, 0x36, 0x7b, 0x67, 0x0e, - 0x77, 0x2d, 0x3c, 0x64, 0xdc, 0x45, 0x3a, 0x94, 0x85, 0x79, 0x72, 0xa4, 0x4b, 0xbb, 0xd2, 0x9e, - 0x6c, 0x25, 0x26, 0xaa, 0x01, 0xb4, 0x99, 0x97, 0x80, 0x05, 0x01, 0x66, 0x3c, 0xc6, 0x1f, 0x12, - 0x94, 0xe3, 0x58, 0xe8, 0x38, 0x17, 0x56, 0xc4, 0xaa, 0x1c, 0x7c, 0x52, 0x5f, 0xe4, 0x7d, 0x05, - 0x3e, 0x54, 0xde, 0xbc, 0xdd, 0xd9, 0xb8, 0x78, 0xbb, 0x23, 0x59, 0xb9, 0x74, 0xee, 0x81, 0x6a, - 0x61, 0x7f, 0x4c, 0x86, 0xce, 0xe2, 0xcc, 0xd4, 0x11, 0x26, 0xdb, 0x74, 0x5d, 0x8e, 0xa7, 0x53, - 0xbd, 0xb8, 0x2b, 0xed, 0xa9, 0x56, 0x62, 0x1a, 0xa7, 0x50, 0x4d, 0x52, 0x7b, 0xaf, 0xb0, 0x7d, - 0xd0, 0xcc, 0xd9, 0x64, 0x80, 0x79, 0xe7, 0x65, 0x1c, 0x7a, 0x1a, 0x1f, 0x75, 0xcd, 0x6f, 0xfc, - 0x29, 0x81, 0x92, 0x04, 0x46, 0x4f, 0xf3, 0x87, 0xc4, 0x32, 0xf5, 0x54, 0xe6, 0x55, 0x3c, 0xa3, - 0x33, 0x9f, 0xde, 0x7a, 0xa1, 0xf7, 0x40, 0x35, 0x19, 0x3d, 0x65, 0x01, 0xa1, 0x9e, 0x90, 0xaa, - 0x58, 0xa9, 0xc3, 0x30, 0x45, 0xe1, 0x03, 0xc6, 0x31, 0x42, 0x20, 0xf7, 0xfb, 0xb1, 0x44, 0xd5, - 0x12, 0x6b, 0xd4, 0x80, 0x92, 0x38, 0x29, 0x54, 0x55, 0xdc, 0xab, 0x1c, 0xdc, 0xbe, 0x76, 0x0b, - 0x87, 0x72, 0x98, 0x97, 0x15, 0xd3, 0x8c, 0x6e, 0xa4, 0x71, 0x65, 0xc0, 0xfb, 0xb9, 0x80, 0xe8, - 0xba, 0xde, 0x5c, 0xc4, 0x16, 0x94, 0x5b, 0x6b, 0x32, 0xfc, 0x02, 0x64, 0x8b, 0x8d, 0xb1, 0xd0, - 0x5d, 0x3d, 0xd0, 0xd2, 0x70, 0x2d, 0x33, 0xf4, 0x5b, 0x02, 0x35, 0xfe, 0xdf, 0x04, 0xb5, 0x65, - 0xf6, 0x30, 0x3f, 0x27, 0x43, 0x1c, 0x96, 0x24, 0x5e, 0x2e, 0x82, 0xa5, 0x0e, 0x54, 0x07, 0xd4, - 0x66, 0xc3, 0x51, 0xec, 0x48, 0x9a, 0xa4, 0x20, 0x68, 0x4b, 0x10, 0xf4, 0x1d, 0xdc, 0xed, 0x12, - 0x1f, 0x8f, 0x09, 0xc5, 0xb9, 0x3d, 0x51, 0x63, 0xad, 0x40, 0xc3, 0xa1, 0xe8, 0x3d, 0x6f, 0x27, - 0x5c, 0x59, 0x70, 0x33, 0x1e, 0xf4, 0x13, 0x94, 0xda, 0xce, 0x00, 0x8f, 0xa7, 0x7a, 0x49, 0x94, - 0x6a, 0x27, 0xab, 0x2d, 0x8e, 0x55, 0x8f, 0x18, 0x8f, 0x68, 0xc0, 0xe7, 0x49, 0xdd, 0x22, 0x17, - 0x7a, 0x00, 0xea, 0x2f, 0x8c, 0x8f, 0x7a, 0x81, 0x13, 0x60, 0xbd, 0x2c, 0xaa, 0x73, 0x27, 0x8d, - 0xb0, 0x80, 0xac, 0x94, 0x85, 0x0c, 0xd8, 0x7a, 0x3e, 0xc3, 0x7c, 0x9e, 0xe4, 0xa4, 0x88, 0x9c, - 0xae, 0xf8, 0xd0, 0x7d, 0xb8, 0x23, 0x2e, 0x26, 0x27, 0x55, 0x15, 0xd4, 0x65, 0x10, 0xda, 0x06, - 0xa5, 0xc5, 0x26, 0x13, 0x12, 0x9c, 0x1c, 0xe9, 0x20, 0x68, 0x0b, 0x5b, 0x60, 0xdd, 0xbe, 0xcd, - 0x02, 0x67, 0xac, 0x57, 0x44, 0xe7, 0x2e, 0xec, 0x10, 0x7b, 0x86, 0x27, 0x11, 0xb6, 0x15, 0x61, - 0x89, 0x8d, 0x9e, 0xc0, 0xce, 0x29, 0xc1, 0xaf, 0x9e, 0xc5, 0x72, 0x9a, 0xee, 0x84, 0x4c, 0xa7, - 0x84, 0xd1, 0x63, 0x4c, 0x31, 0x77, 0x02, 0xc2, 0xa8, 0x7e, 0x4b, 0x6c, 0x79, 0x1f, 0x0d, 0xfd, - 0x0c, 0xdb, 0x4b, 0x29, 0x16, 0x76, 0xdc, 0xb9, 0x5e, 0x15, 0xf3, 0xb2, 0x86, 0x81, 0x7e, 0x84, - 0x4f, 0xb3, 0x68, 0x67, 0x30, 0xc5, 0xfc, 0x1c, 0xbb, 0x8f, 0x7c, 0x36, 0x3c, 0xd3, 0x3f, 0x12, - 0x39, 0xac, 0x26, 0x6c, 0x9b, 0x50, 0xc9, 0xdc, 0x20, 0xd2, 0xa0, 0x38, 0xc2, 0xf3, 0xb8, 0x25, - 0xc3, 0x25, 0xfa, 0x12, 0x36, 0xcf, 0x9d, 0xf1, 0x2c, 0xea, 0xef, 0x4a, 0xf6, 0x06, 0xc5, 0xbe, - 0x36, 0x99, 0x06, 0x56, 0xc4, 0xf8, 0xa1, 0xf0, 0xbd, 0xf4, 0x54, 0x56, 0x36, 0xb5, 0x92, 0xf1, - 0x97, 0x0c, 0xaa, 0x7d, 0xc3, 0x6e, 0xff, 0x0a, 0x6e, 0xdb, 0xaf, 0xe9, 0xd2, 0x66, 0xbf, 0x0e, - 0xa0, 0x6f, 0xe1, 0xe3, 0x36, 0xf3, 0x6c, 0x87, 0x8c, 0x97, 0xb6, 0xfa, 0x72, 0x70, 0xc5, 0x44, - 0xc9, 0x2b, 0x27, 0x2a, 0x7d, 0x75, 0x4a, 0x37, 0x7a, 0x75, 0x32, 0xa3, 0x52, 0xce, 0x8f, 0x8a, - 0x7d, 0x83, 0x51, 0xf9, 0x30, 0x7d, 0xff, 0x10, 0x3e, 0x6b, 0xce, 0x02, 0x76, 0x42, 0x87, 0x5c, - 0x5c, 0xf6, 0x63, 0x4c, 0x87, 0xb8, 0x37, 0xf3, 0x7d, 0xc6, 0x03, 0xec, 0x8a, 0x51, 0x50, 0xac, - 0x75, 0x94, 0x0f, 0xd4, 0x1d, 0x9f, 0x83, 0xba, 0x40, 0xd1, 0xdd, 0x45, 0xe5, 0xa4, 0xdd, 0xe2, - 0x9e, 0x9a, 0x94, 0x64, 0xbf, 0x09, 0x95, 0x58, 0x8e, 0x3d, 0xf7, 0x31, 0x2a, 0x41, 0xa1, 0x65, - 0x6a, 0x1b, 0xe1, 0xd7, 0x36, 0x35, 0x09, 0x95, 0xa1, 0xd8, 0xee, 0x1c, 0x6b, 0x05, 0xa4, 0xc2, - 0x66, 0xd7, 0xea, 0xfc, 0xfa, 0x42, 0x2b, 0xa2, 0x2a, 0x40, 0xf7, 0x85, 0xfd, 0xa4, 0x63, 0xfe, - 0xde, 0x3f, 0x7a, 0xac, 0xc9, 0xfb, 0x3a, 0x94, 0xa2, 0x37, 0x58, 0xec, 0xea, 0x46, 0xbb, 0x9b, - 0x5d, 0x4d, 0xda, 0x7f, 0x98, 0x79, 0x9a, 0x50, 0x05, 0xca, 0x7d, 0x3a, 0xa2, 0xec, 0x15, 0xd5, - 0x36, 0x42, 0x23, 0x44, 0x08, 0xf5, 0x34, 0x09, 0x6d, 0x81, 0x72, 0xc4, 0x1d, 0x42, 0x43, 0xab, - 0x10, 0x42, 0xc2, 0xc2, 0xae, 0x56, 0x3c, 0x3c, 0xbe, 0xf8, 0xb7, 0x26, 0xbd, 0xb9, 0xac, 0x49, - 0x17, 0x97, 0x35, 0xe9, 0x9f, 0xcb, 0xda, 0xc6, 0xdf, 0xff, 0xd5, 0xa4, 0xdf, 0x1e, 0x64, 0x7e, - 0x60, 0x26, 0x4e, 0xc0, 0xc9, 0x6b, 0xc6, 0x89, 0x47, 0x68, 0x62, 0x50, 0xdc, 0xf0, 0x47, 0x5e, - 0xc3, 0x1f, 0x34, 0x92, 0x3a, 0x0d, 0x4a, 0xe2, 0x5f, 0xe6, 0x9b, 0x77, 0x01, 0x00, 0x00, 0xff, - 0xff, 0xe7, 0xa7, 0x5a, 0x4c, 0x16, 0x09, 0x00, 0x00, + 0x10, 0x35, 0x25, 0x99, 0x22, 0x47, 0x8e, 0xca, 0x6c, 0xd0, 0x94, 0x75, 0x03, 0xd9, 0x60, 0x7b, + 0x70, 0x8d, 0x56, 0x4a, 0xdc, 0xa2, 0x28, 0x8a, 0xb6, 0x88, 0x2c, 0x25, 0x8e, 0x03, 0x85, 0x52, + 0x28, 0xca, 0x6d, 0x7a, 0x29, 0x28, 0x71, 0x43, 0x2f, 0x24, 0x71, 0x89, 0xe5, 0xca, 0x89, 0x7e, + 0xa1, 0xc7, 0x5e, 0x7b, 0xe9, 0xb5, 0x7f, 0x92, 0xa3, 0xbf, 0x20, 0x68, 0xdd, 0x1f, 0x09, 0xb8, + 0x24, 0x25, 0x9a, 0x96, 0x1c, 0x5f, 0x72, 0xe2, 0xce, 0xbc, 0x37, 0xb3, 0xf3, 0x66, 0x77, 0x16, + 0x84, 0xea, 0x14, 0x73, 0xc7, 0x75, 0xb8, 0x53, 0x0f, 0x18, 0xe5, 0x14, 0x29, 0xa9, 0xbd, 0xfd, + 0xb5, 0x47, 0xf8, 0xe9, 0x6c, 0x58, 0x1f, 0xd1, 0x69, 0xc3, 0xa3, 0x1e, 0x6d, 0x08, 0xc2, 0x70, + 0xf6, 0x52, 0x58, 0xc2, 0x10, 0xab, 0x38, 0xd0, 0x38, 0x86, 0x5b, 0xb6, 0xd9, 0x3f, 0x75, 0x98, + 0x6b, 0xe1, 0x11, 0x65, 0x2e, 0xd2, 0xa1, 0x2c, 0xcc, 0xe3, 0xb6, 0x2e, 0xed, 0x4a, 0x7b, 0x25, + 0x2b, 0x35, 0x51, 0x0d, 0xa0, 0x43, 0xbd, 0x14, 0x2c, 0x08, 0x30, 0xe3, 0x31, 0xfe, 0x90, 0xa0, + 0x9c, 0xe4, 0x42, 0x47, 0xb9, 0xb4, 0x22, 0x57, 0xe5, 0xe0, 0x93, 0xfa, 0xa2, 0xee, 0x4b, 0xf0, + 0xa1, 0xf2, 0xe6, 0xed, 0xce, 0xc6, 0xf9, 0xdb, 0x1d, 0xc9, 0xca, 0x95, 0x73, 0x0f, 0x54, 0x0b, + 0x07, 0x13, 0x32, 0x72, 0x16, 0x7b, 0x2e, 0x1d, 0x51, 0xb1, 0x4d, 0xd7, 0x65, 0x38, 0x0c, 0xf5, + 0xe2, 0xae, 0xb4, 0xa7, 0x5a, 0xa9, 0x69, 0x9c, 0x40, 0x35, 0x2d, 0xed, 0xbd, 0xc2, 0xf6, 0x41, + 0x33, 0x67, 0xd3, 0x21, 0x66, 0xdd, 0x97, 0x49, 0xea, 0x30, 0xd9, 0xea, 0x8a, 0xdf, 0xf8, 0x53, + 0x02, 0x25, 0x4d, 0x8c, 0x9e, 0xe6, 0x37, 0x49, 0x64, 0xea, 0x4b, 0x99, 0x97, 0xf1, 0x8c, 0xce, + 0x7c, 0x79, 0xd7, 0x0b, 0xbd, 0x07, 0xaa, 0x49, 0xfd, 0x13, 0xca, 0x89, 0xef, 0x09, 0xa9, 0x8a, + 0xb5, 0x74, 0x18, 0xa6, 0x68, 0x3c, 0xa7, 0x0c, 0x23, 0x04, 0xa5, 0xc1, 0x20, 0x91, 0xa8, 0x5a, + 0x62, 0x8d, 0x1a, 0x20, 0x8b, 0x9d, 0x22, 0x55, 0xc5, 0xbd, 0xca, 0xc1, 0xed, 0x2b, 0xa7, 0x70, + 0x58, 0x8a, 0xea, 0xb2, 0x12, 0x9a, 0xd1, 0x8b, 0x35, 0xae, 0x4d, 0x78, 0x3f, 0x97, 0x10, 0x5d, + 0xd5, 0x9b, 0xcb, 0xd8, 0x82, 0x72, 0xeb, 0x9a, 0x0a, 0xbf, 0x80, 0x92, 0x45, 0x27, 0x58, 0xe8, + 0xae, 0x1e, 0x68, 0xcb, 0x74, 0x2d, 0x33, 0xf2, 0x5b, 0x02, 0x35, 0xfe, 0x91, 0x41, 0x6d, 0x99, + 0x7d, 0xcc, 0xce, 0xc8, 0x08, 0x47, 0x2d, 0x49, 0x96, 0x8b, 0x64, 0x4b, 0x07, 0xaa, 0x03, 0xea, + 0xd0, 0xd1, 0x38, 0x71, 0xa4, 0x97, 0xa4, 0x20, 0x68, 0x2b, 0x10, 0xf4, 0x1d, 0xdc, 0xed, 0x91, + 0x00, 0x4f, 0x88, 0x8f, 0x73, 0x31, 0xf1, 0xc5, 0x5a, 0x83, 0x46, 0x43, 0xd1, 0x7f, 0xde, 0x49, + 0xb9, 0x25, 0xc1, 0xcd, 0x78, 0xd0, 0x4f, 0x20, 0x77, 0x9c, 0x21, 0x9e, 0x84, 0xba, 0x2c, 0x5a, + 0xb5, 0x93, 0xd5, 0x96, 0xe4, 0xaa, 0xc7, 0x8c, 0x47, 0x3e, 0x67, 0xf3, 0xb4, 0x6f, 0xb1, 0x0b, + 0x3d, 0x00, 0xf5, 0x17, 0xca, 0xc6, 0x7d, 0xee, 0x70, 0xac, 0x97, 0x45, 0x77, 0xee, 0x2c, 0x33, + 0x2c, 0x20, 0x6b, 0xc9, 0x42, 0x06, 0x6c, 0x3d, 0x9f, 0x61, 0x36, 0x4f, 0x6b, 0x52, 0x44, 0x4d, + 0x97, 0x7c, 0xe8, 0x3e, 0xdc, 0x11, 0x07, 0x93, 0x93, 0xaa, 0x0a, 0xea, 0x2a, 0x08, 0x6d, 0x83, + 0xd2, 0xa2, 0xd3, 0x29, 0xe1, 0xc7, 0x6d, 0x1d, 0x04, 0x6d, 0x61, 0x0b, 0xac, 0x37, 0xb0, 0x29, + 0x77, 0x26, 0x7a, 0x45, 0xdc, 0xdc, 0x85, 0x1d, 0x61, 0xcf, 0xf0, 0x34, 0xc6, 0xb6, 0x62, 0x2c, + 0xb5, 0xd1, 0x13, 0xd8, 0x39, 0x21, 0xf8, 0xd5, 0xb3, 0x44, 0x4e, 0xd3, 0x9d, 0x92, 0x30, 0x24, + 0xd4, 0x3f, 0xc2, 0x3e, 0x66, 0x0e, 0x27, 0xd4, 0xd7, 0x6f, 0x89, 0x90, 0xf7, 0xd1, 0xd0, 0xcf, + 0xb0, 0xbd, 0x92, 0x62, 0x61, 0xc7, 0x9d, 0xeb, 0x55, 0x31, 0x2f, 0xd7, 0x30, 0xd0, 0x8f, 0xf0, + 0x69, 0x16, 0xed, 0x0e, 0x43, 0xcc, 0xce, 0xb0, 0xfb, 0x28, 0xa0, 0xa3, 0x53, 0xfd, 0x23, 0x51, + 0xc3, 0x7a, 0x42, 0x14, 0xdd, 0x6e, 0x77, 0x4e, 0x48, 0x48, 0x86, 0x64, 0x42, 0xf8, 0xfc, 0xd0, + 0x61, 0x8c, 0x60, 0x16, 0x6f, 0xae, 0x89, 0xcd, 0xd7, 0x13, 0xb6, 0x4d, 0xa8, 0x64, 0xce, 0x1f, + 0x69, 0x50, 0x1c, 0xe3, 0x79, 0x72, 0xa1, 0xa3, 0x25, 0xfa, 0x12, 0x36, 0xcf, 0x9c, 0xc9, 0x2c, + 0x9e, 0x8e, 0x4a, 0xf6, 0xfc, 0x45, 0x5c, 0x87, 0x84, 0xdc, 0x8a, 0x19, 0x3f, 0x14, 0xbe, 0x97, + 0x9e, 0x96, 0x94, 0x4d, 0x4d, 0x36, 0xfe, 0x2a, 0x81, 0x6a, 0xdf, 0x70, 0x56, 0xbe, 0x82, 0xdb, + 0xf6, 0x6b, 0x7f, 0xe5, 0xa8, 0x5c, 0x05, 0xd0, 0xb7, 0xf0, 0x71, 0x87, 0x7a, 0xb6, 0x43, 0x26, + 0x2b, 0x07, 0x65, 0x35, 0xb8, 0x66, 0x1e, 0x4b, 0x6b, 0xe7, 0x71, 0xf9, 0x66, 0xc9, 0x37, 0x7a, + 0xb3, 0x32, 0x83, 0x56, 0xce, 0x0f, 0x9a, 0x7d, 0x83, 0x41, 0xfb, 0x30, 0x53, 0xf3, 0x10, 0x3e, + 0x6b, 0xce, 0x38, 0x3d, 0xf6, 0x47, 0x4c, 0x5c, 0x95, 0xc7, 0xd8, 0x1f, 0xe1, 0xfe, 0x2c, 0x08, + 0x28, 0xe3, 0xd8, 0x15, 0x83, 0xa4, 0x58, 0xd7, 0x51, 0x3e, 0xd0, 0xed, 0xf8, 0x1c, 0xd4, 0x05, + 0x8a, 0xee, 0x2e, 0x3a, 0x27, 0xed, 0x16, 0xf7, 0xd4, 0xb4, 0x25, 0xfb, 0x4d, 0xa8, 0x24, 0x72, + 0xec, 0x79, 0x80, 0x91, 0x0c, 0x85, 0x96, 0xa9, 0x6d, 0x44, 0x5f, 0xdb, 0xd4, 0x24, 0x54, 0x86, + 0x62, 0xa7, 0x7b, 0xa4, 0x15, 0x90, 0x0a, 0x9b, 0x3d, 0xab, 0xfb, 0xeb, 0x0b, 0xad, 0x88, 0xaa, + 0x00, 0xbd, 0x17, 0xf6, 0x93, 0xae, 0xf9, 0xfb, 0xa0, 0xfd, 0x58, 0x2b, 0xed, 0xeb, 0x20, 0xc7, + 0x2f, 0xb8, 0x88, 0xea, 0xc5, 0xd1, 0xcd, 0x9e, 0x26, 0xed, 0x3f, 0xcc, 0x3c, 0x6c, 0xa8, 0x02, + 0xe5, 0x81, 0x3f, 0xf6, 0xe9, 0x2b, 0x5f, 0xdb, 0x88, 0x8c, 0x08, 0x21, 0xbe, 0xa7, 0x49, 0x68, + 0x0b, 0x94, 0x36, 0x73, 0x88, 0x1f, 0x59, 0x85, 0x08, 0x12, 0x16, 0x76, 0xb5, 0xe2, 0xe1, 0xd1, + 0xf9, 0x7f, 0x35, 0xe9, 0xcd, 0x45, 0x4d, 0x3a, 0xbf, 0xa8, 0x49, 0xff, 0x5e, 0xd4, 0x36, 0xfe, + 0xfe, 0xbf, 0x26, 0xfd, 0xf6, 0x20, 0xf3, 0xfb, 0x33, 0x75, 0x38, 0x23, 0xaf, 0x29, 0x23, 0x1e, + 0xf1, 0x53, 0xc3, 0xc7, 0x8d, 0x60, 0xec, 0x35, 0x82, 0x61, 0x23, 0xed, 0xd3, 0x50, 0x16, 0x7f, + 0x42, 0xdf, 0xbc, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x83, 0x15, 0xa1, 0x75, 0x54, 0x09, 0x00, 0x00, } func (m *TNShardRecord) Marshal() (dAtA []byte, err error) { @@ -1286,6 +1297,18 @@ func (m *CNService) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityBarrierReady { + i-- + if m.DDLVisibilityBarrierReady { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } if m.ViewMetadataObservedEpoch != 0 { i = encodeVarintMetadata(dAtA, i, uint64(m.ViewMetadataObservedEpoch)) i-- @@ -1762,6 +1785,9 @@ func (m *CNService) ProtoSize() (n int) { if m.ViewMetadataObservedEpoch != 0 { n += 1 + sovMetadata(uint64(m.ViewMetadataObservedEpoch)) } + if m.DDLVisibilityBarrierReady { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -3115,6 +3141,26 @@ func (m *CNService) Unmarshal(dAtA []byte) error { break } } + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityBarrierReady", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetadata + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityBarrierReady = bool(v != 0) default: iNdEx = preIndex skippy, err := skipMetadata(dAtA[iNdEx:]) diff --git a/pkg/pb/query/query.pb.go b/pkg/pb/query/query.pb.go index 6b08925c37484..64669a7df6fa5 100644 --- a/pkg/pb/query/query.pb.go +++ b/pkg/pb/query/query.pb.go @@ -109,6 +109,9 @@ const ( CmdMethod_IcebergCacheInvalidate CmdMethod = 38 // MongoDBClientRetire drains obsolete MongoDB driver clients after catalog DDL. CmdMethod_MongoDBClientRetire CmdMethod = 39 + // SyncCommitV2 waits for local logtail application with the request context. + // Unlike legacy SyncCommit, cancellation is returned to the sender. + CmdMethod_SyncCommitV2 CmdMethod = 40 ) var CmdMethod_name = map[int32]string{ @@ -152,6 +155,7 @@ var CmdMethod_name = map[int32]string{ 37: "ISCPDrainConsumer", 38: "IcebergCacheInvalidate", 39: "MongoDBClientRetire", + 40: "SyncCommitV2", } var CmdMethod_value = map[string]int32{ @@ -195,6 +199,7 @@ var CmdMethod_value = map[string]int32{ "ISCPDrainConsumer": 37, "IcebergCacheInvalidate": 38, "MongoDBClientRetire": 39, + "SyncCommitV2": 40, } func (x CmdMethod) String() string { @@ -5867,279 +5872,280 @@ func init() { func init() { proto.RegisterFile("query.proto", fileDescriptor_5c6ac9b241082464) } var fileDescriptor_5c6ac9b241082464 = []byte{ - // 4352 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xb4, 0x5b, 0xcd, 0x73, 0xdb, 0x38, + // 4356 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5b, 0xcd, 0x73, 0xdb, 0x38, 0x96, 0x8f, 0xe2, 0x2f, 0xe9, 0x59, 0xb6, 0x69, 0xc4, 0x1f, 0xb4, 0xe3, 0xc8, 0x0e, 0x3b, 0x9d, 0x38, 0xc9, 0xb4, 0xdd, 0x9b, 0xe9, 0x64, 0xbe, 0x7a, 0xb7, 0x3a, 0x96, 0xe2, 0x44, 0x89, 0x1c, 0x3b, 0x90, 0xf3, 0x31, 0x3d, 0x55, 0x5d, 0x45, 0x4b, 0xb0, 0xcc, 0xb1, 0x44, 0xaa, 0x49, 0x2a, - 0x6d, 0x77, 0xd5, 0x1e, 0xf7, 0xb2, 0x87, 0xad, 0xf9, 0x13, 0x66, 0xab, 0xb6, 0x6a, 0xff, 0x83, - 0xad, 0xda, 0xe3, 0xdc, 0xe6, 0x38, 0x87, 0x3d, 0xcc, 0x69, 0x77, 0xab, 0xfb, 0x0f, 0xd9, 0x2d, - 0x80, 0x00, 0x49, 0x80, 0x20, 0xd5, 0x3d, 0xdd, 0x7d, 0x51, 0x11, 0x0f, 0xef, 0xfd, 0x00, 0x82, - 0xc0, 0xc3, 0xfb, 0x3d, 0x40, 0x30, 0xfb, 0xe5, 0x88, 0xf8, 0x97, 0x3b, 0x43, 0xdf, 0x0b, 0x3d, - 0x34, 0xc5, 0x0a, 0xeb, 0xd5, 0x20, 0xb4, 0xc3, 0x51, 0x10, 0x09, 0xd7, 0xa1, 0xef, 0x75, 0xce, - 0xf9, 0x73, 0x25, 0xbc, 0x70, 0xf9, 0xe3, 0x42, 0xe8, 0x0c, 0x48, 0x10, 0xda, 0x83, 0xa1, 0x10, - 0x50, 0xab, 0xc0, 0x71, 0x4f, 0x3d, 0x61, 0x38, 0xec, 0xdb, 0x42, 0xfb, 0xa3, 0x9e, 0x13, 0x9e, - 0x8d, 0x4e, 0x76, 0x3a, 0xde, 0x60, 0xb7, 0xe7, 0xf5, 0xbc, 0x5d, 0x26, 0x3e, 0x19, 0x9d, 0xb2, - 0x12, 0x2b, 0xb0, 0x27, 0xae, 0xbe, 0xd9, 0xf3, 0xbc, 0x5e, 0x9f, 0x24, 0x5a, 0x4a, 0x63, 0xd6, - 0x2d, 0xa8, 0xbe, 0xa2, 0x7d, 0xc5, 0xe4, 0xcb, 0x11, 0x09, 0x42, 0xb4, 0x04, 0x53, 0xac, 0x6c, - 0x96, 0xb6, 0x4a, 0xdb, 0x15, 0x1c, 0x15, 0xac, 0x97, 0xb0, 0xd2, 0x3e, 0xf3, 0xbe, 0x3a, 0xf2, - 0xbd, 0x0e, 0x09, 0x82, 0x96, 0x13, 0x84, 0x42, 0x7f, 0x05, 0xa6, 0x8f, 0x89, 0x6b, 0xbb, 0x21, - 0x37, 0xe0, 0x25, 0xb4, 0x01, 0x95, 0xf6, 0x65, 0xc0, 0xab, 0xae, 0x6e, 0x95, 0xb6, 0xcb, 0x38, - 0x11, 0x58, 0x6f, 0x61, 0xb1, 0x7d, 0xe9, 0x76, 0xea, 0xde, 0x60, 0xe0, 0xc4, 0x50, 0x7b, 0x30, - 0xdf, 0xb2, 0x43, 0x12, 0x84, 0x91, 0xf8, 0xb8, 0xcd, 0x20, 0x67, 0x1f, 0x2c, 0xed, 0x24, 0x9d, - 0x3e, 0x16, 0x4f, 0x7b, 0x93, 0x7f, 0xfe, 0xef, 0xcd, 0x2b, 0x58, 0xb1, 0xb0, 0x3e, 0x07, 0x94, - 0x06, 0x0e, 0x86, 0x9e, 0x1b, 0x10, 0xd4, 0x80, 0x85, 0xfa, 0xc8, 0xf7, 0x89, 0xfb, 0x7d, 0xa0, - 0x55, 0x13, 0x0b, 0x81, 0xf1, 0x94, 0x84, 0x52, 0x9f, 0xad, 0xdf, 0xc2, 0x62, 0x4a, 0xf6, 0xa3, - 0x36, 0xb7, 0x0b, 0xcb, 0x75, 0xcf, 0x27, 0x8d, 0xd1, 0x60, 0x58, 0xf7, 0xdc, 0x53, 0xa7, 0x97, - 0x1a, 0xf2, 0xc7, 0x9d, 0xd0, 0xf1, 0x5c, 0x31, 0xe4, 0x51, 0xc9, 0x32, 0x61, 0x45, 0x35, 0x88, - 0x3a, 0x64, 0x5d, 0x87, 0xb5, 0xa7, 0x24, 0x3c, 0xa2, 0x1f, 0xbc, 0xe3, 0xf5, 0xdf, 0x10, 0x3f, - 0x70, 0x3c, 0x57, 0xbc, 0xc2, 0x23, 0x58, 0xd7, 0x55, 0xf2, 0x77, 0x31, 0x61, 0x86, 0x8b, 0x58, - 0x6b, 0x13, 0x58, 0x14, 0xad, 0x87, 0xb0, 0xd6, 0xce, 0x03, 0x2d, 0x30, 0x7b, 0x04, 0xeb, 0x3a, - 0xb3, 0xb1, 0xcd, 0xfd, 0x0c, 0xe6, 0xf1, 0xc8, 0x3d, 0xb6, 0x83, 0x73, 0xd1, 0xc6, 0x3a, 0x94, - 0x69, 0xb1, 0xee, 0x75, 0x09, 0x53, 0x9e, 0xc2, 0x71, 0xd9, 0xba, 0x0b, 0x0b, 0xb1, 0x36, 0x87, - 0x5e, 0x81, 0x69, 0x4c, 0x82, 0x51, 0x3f, 0x9e, 0xa9, 0x51, 0x89, 0x0e, 0x1b, 0x7d, 0x7f, 0x67, - 0x48, 0xfa, 0x8e, 0x4b, 0x9a, 0xee, 0xa9, 0x27, 0x46, 0x66, 0x17, 0x56, 0x33, 0x35, 0x1c, 0x6c, - 0x09, 0xa6, 0xea, 0xde, 0x88, 0xcf, 0xfa, 0x09, 0x1c, 0x15, 0xac, 0xff, 0x58, 0x83, 0x19, 0xd1, - 0xbb, 0x0d, 0xa8, 0xf0, 0xc7, 0x66, 0x83, 0x69, 0x4d, 0xe2, 0x44, 0x80, 0x76, 0xa0, 0x52, 0x1f, - 0x74, 0x0f, 0x48, 0x78, 0xe6, 0x75, 0xd9, 0xf2, 0x98, 0x7f, 0x60, 0xec, 0x44, 0x1e, 0x24, 0x96, - 0xe3, 0x44, 0x05, 0xfd, 0x42, 0x5e, 0xa6, 0xe6, 0x04, 0x9b, 0x4f, 0xd7, 0xb8, 0x49, 0xba, 0x0a, - 0xcb, 0xeb, 0xf9, 0x75, 0xde, 0xca, 0x35, 0x27, 0x19, 0xc4, 0x0d, 0x0e, 0xa1, 0x57, 0xc2, 0x79, - 0xcb, 0xbe, 0x05, 0xd7, 0x1e, 0xf7, 0x43, 0xe2, 0x3f, 0xee, 0x74, 0xe8, 0x9b, 0x0b, 0xcc, 0x29, - 0x86, 0xb9, 0xce, 0x31, 0x35, 0x1a, 0x58, 0x67, 0x86, 0x3e, 0x83, 0x85, 0x17, 0x4e, 0xbf, 0x5f, - 0xf7, 0x5c, 0x31, 0x81, 0xcc, 0x69, 0x86, 0xb4, 0xc2, 0x91, 0x94, 0x5a, 0xac, 0xaa, 0xa3, 0x3a, - 0x18, 0xc7, 0xbe, 0xdd, 0x21, 0xed, 0xa1, 0x1d, 0x43, 0xcc, 0x30, 0x88, 0x55, 0x0e, 0xa1, 0x56, - 0xe3, 0x8c, 0x01, 0x6a, 0x02, 0x7a, 0x4a, 0xc2, 0x96, 0xd7, 0x39, 0x4f, 0xcd, 0x02, 0xb3, 0xcc, - 0x60, 0xd6, 0x38, 0x4c, 0x56, 0x01, 0x6b, 0x8c, 0xd0, 0x3e, 0xf3, 0x0b, 0xc7, 0x17, 0x6e, 0x1a, - 0xa9, 0xc2, 0x90, 0xcc, 0x04, 0x49, 0xae, 0xc7, 0x59, 0x13, 0x3a, 0xce, 0xd4, 0xbf, 0xd8, 0x9d, - 0xb3, 0xf4, 0xcc, 0x34, 0x41, 0x1a, 0x67, 0x8d, 0x06, 0xd6, 0x99, 0xa1, 0x5f, 0x02, 0xb4, 0x2f, - 0x3b, 0x6e, 0xe4, 0x62, 0xcc, 0x59, 0xa9, 0x3b, 0x19, 0x7f, 0x8c, 0x53, 0xba, 0xe8, 0x21, 0x54, - 0x62, 0x3f, 0x67, 0x56, 0xa5, 0x81, 0x55, 0x7d, 0x22, 0x4e, 0x34, 0xd1, 0x11, 0x1b, 0x51, 0x65, - 0xb1, 0x9b, 0x73, 0xcc, 0x7e, 0x2b, 0xb1, 0xd7, 0x3b, 0x11, 0xac, 0xb1, 0xa5, 0x88, 0x59, 0xf7, - 0x61, 0xce, 0x4b, 0x88, 0xb9, 0x6e, 0x09, 0x6b, 0x6c, 0x51, 0x03, 0xe6, 0x65, 0xb7, 0x69, 0x2e, - 0x30, 0xb4, 0x0d, 0xb1, 0x1e, 0x75, 0x4e, 0x18, 0x2b, 0x36, 0x68, 0x17, 0x66, 0xb8, 0xc3, 0x31, - 0x0d, 0x66, 0xbe, 0xcc, 0xcd, 0x65, 0xa7, 0x85, 0x85, 0x16, 0xfa, 0x2d, 0x2c, 0x63, 0x32, 0xf0, - 0xde, 0x13, 0xfa, 0x1b, 0x12, 0x3a, 0x81, 0x8e, 0xed, 0x93, 0x3e, 0x31, 0x17, 0x99, 0xf9, 0x07, - 0xc2, 0x5c, 0xa7, 0x23, 0xc0, 0xf4, 0x08, 0xe8, 0x31, 0xcc, 0xd1, 0x29, 0xc9, 0x76, 0xc6, 0x3d, - 0xc7, 0xed, 0x9a, 0x88, 0x41, 0x5e, 0x4f, 0x4d, 0xe1, 0xb8, 0x4e, 0x40, 0xc9, 0x16, 0xe8, 0x39, - 0x18, 0xaf, 0xdd, 0x60, 0x74, 0x12, 0x74, 0x7c, 0xe7, 0x84, 0x44, 0x1d, 0xbb, 0xc6, 0x50, 0x6a, - 0x1c, 0x45, 0xad, 0x8e, 0x97, 0x95, 0x5a, 0x91, 0x9e, 0xc3, 0x0d, 0x3b, 0xb4, 0xc5, 0x1c, 0x5e, - 0xd2, 0xce, 0xe1, 0x94, 0x06, 0xd6, 0x99, 0x71, 0xb4, 0x36, 0x0d, 0x91, 0xd2, 0x2b, 0x62, 0x59, - 0x45, 0x53, 0x35, 0xb0, 0xce, 0x8c, 0xba, 0x47, 0xbd, 0xf3, 0x37, 0x57, 0x24, 0xf7, 0xa8, 0x57, - 0xc2, 0x39, 0xc6, 0x14, 0xf6, 0xc0, 0xe9, 0xf9, 0x76, 0x48, 0xa8, 0x93, 0xda, 0xf7, 0xbd, 0x81, - 0x80, 0x5d, 0x95, 0x60, 0xf5, 0x4a, 0x38, 0xc7, 0x18, 0x1d, 0xc2, 0x52, 0xaa, 0xe6, 0x38, 0xee, - 0xab, 0x29, 0x7d, 0x5f, 0x9d, 0x0a, 0xd6, 0x1a, 0xa2, 0x13, 0x30, 0x31, 0xe9, 0x7b, 0x76, 0xf7, - 0xf1, 0x28, 0xf4, 0x9a, 0x6e, 0xc7, 0x27, 0x03, 0x1a, 0x82, 0xd0, 0x31, 0x37, 0xd7, 0x18, 0xe8, - 0xed, 0x78, 0x1e, 0xea, 0xd5, 0x04, 0x7e, 0x2e, 0x0e, 0x75, 0xcd, 0xf5, 0xb0, 0x8f, 0x89, 0xdd, - 0x25, 0xbe, 0xe8, 0xf0, 0xba, 0xe4, 0x41, 0xd4, 0x6a, 0x9c, 0x31, 0x40, 0x07, 0xb0, 0xf0, 0x94, - 0x84, 0x98, 0x0c, 0xfb, 0x4e, 0xc7, 0x8e, 0x76, 0xde, 0xeb, 0xea, 0x07, 0x4a, 0xd7, 0x72, 0x3b, - 0x11, 0x5b, 0x29, 0xb5, 0x74, 0x12, 0x61, 0x12, 0x90, 0xb0, 0x4d, 0x82, 0x94, 0x7b, 0x30, 0x37, - 0xa4, 0x49, 0xa4, 0xd1, 0xc0, 0x3a, 0x33, 0xd4, 0x82, 0xc5, 0xa7, 0xde, 0x81, 0x7d, 0x41, 0xf7, - 0xc9, 0x40, 0x60, 0xdd, 0x90, 0x9d, 0xbd, 0x5a, 0xcf, 0x7b, 0x96, 0x35, 0xe4, 0x68, 0x64, 0xd0, - 0x72, 0x12, 0x9f, 0x6a, 0xd6, 0x54, 0x34, 0xb9, 0x3e, 0x85, 0x26, 0x57, 0xa0, 0x2f, 0x60, 0x75, - 0xdf, 0xe9, 0x93, 0x36, 0xf1, 0xdf, 0x3b, 0x1d, 0x92, 0xfe, 0x64, 0xe6, 0xa6, 0xb4, 0x9e, 0x73, - 0xb4, 0x38, 0x72, 0x1e, 0x08, 0x1a, 0xc0, 0x86, 0x5a, 0xf5, 0xe4, 0xbd, 0xd3, 0x89, 0x3b, 0xbe, - 0x25, 0x79, 0xb3, 0x22, 0x55, 0xde, 0x52, 0x21, 0x1c, 0x7a, 0x0d, 0x4b, 0x07, 0x24, 0xb4, 0xbb, - 0x76, 0x68, 0x4b, 0xef, 0x72, 0x53, 0x5e, 0x01, 0x1a, 0x15, 0x0e, 0xaf, 0x35, 0x47, 0x87, 0x80, - 0x9e, 0x7a, 0x4f, 0xeb, 0x47, 0xc4, 0xef, 0x90, 0x24, 0x9a, 0xb1, 0xe4, 0x9d, 0x3f, 0xa3, 0xc0, - 0x21, 0x35, 0xa6, 0x34, 0x94, 0xd8, 0xb7, 0x47, 0xfd, 0xb0, 0xe9, 0xfe, 0x9e, 0x24, 0x83, 0xf1, - 0x81, 0x04, 0x98, 0x55, 0xc0, 0x1a, 0x23, 0xf4, 0x3b, 0x58, 0xa9, 0x87, 0xfd, 0x03, 0x8f, 0x39, - 0x53, 0xe6, 0xc0, 0x04, 0xdc, 0x2d, 0x69, 0x05, 0xe8, 0x95, 0x78, 0x1f, 0x73, 0x20, 0xd0, 0x17, - 0xb0, 0xf6, 0xd6, 0xf3, 0xcf, 0x83, 0xa1, 0xdd, 0x21, 0xc7, 0x67, 0x3e, 0x09, 0xce, 0xbc, 0xbe, - 0xd8, 0x13, 0xcc, 0x0f, 0xa5, 0x5d, 0x35, 0x57, 0x0f, 0xe7, 0x43, 0xa0, 0x01, 0xd4, 0xea, 0x61, - 0xff, 0xc8, 0x27, 0xa7, 0x24, 0xec, 0x9c, 0x1d, 0xba, 0x6d, 0xb1, 0x35, 0xc4, 0x8d, 0xdc, 0x66, - 0x8d, 0x7c, 0x98, 0xbc, 0x44, 0x81, 0x32, 0x1e, 0x03, 0x86, 0x7e, 0x07, 0x66, 0xb3, 0x5d, 0x3f, - 0x6a, 0xf8, 0xb6, 0xe3, 0xd6, 0x3d, 0x37, 0x18, 0x0d, 0x12, 0x9f, 0x73, 0x87, 0x35, 0xb4, 0xc9, - 0x1b, 0xca, 0x53, 0xc3, 0xb9, 0x00, 0x68, 0x08, 0x37, 0x9a, 0x1d, 0x72, 0x42, 0xfc, 0x1e, 0x0f, - 0xac, 0xde, 0xdb, 0x7d, 0xa7, 0x6b, 0x87, 0xf1, 0x24, 0xdc, 0x66, 0x2d, 0xdc, 0x12, 0x2d, 0x14, - 0xe9, 0xf2, 0xcf, 0x52, 0x0c, 0x88, 0x7a, 0xb0, 0x7e, 0xe0, 0xb9, 0x3d, 0xaf, 0xb1, 0x57, 0xef, - 0x3b, 0x6c, 0x76, 0x85, 0x8e, 0x1f, 0x37, 0x77, 0x97, 0x35, 0x77, 0x53, 0xcc, 0xf9, 0x5c, 0x45, - 0xde, 0x56, 0x01, 0x94, 0xb5, 0x0f, 0xab, 0x99, 0x40, 0x9f, 0x33, 0x9d, 0xfb, 0x50, 0xe6, 0xee, - 0x2e, 0x30, 0x4b, 0x5b, 0x13, 0xdb, 0xb3, 0x0f, 0x16, 0x76, 0x78, 0x5a, 0x43, 0xb8, 0xc1, 0x58, - 0xc1, 0xfa, 0xd3, 0x3a, 0x94, 0x63, 0xcb, 0x1f, 0x97, 0x01, 0x2d, 0xc1, 0xd4, 0x13, 0xdf, 0xf7, - 0x7c, 0x46, 0x7d, 0xaa, 0x38, 0x2a, 0xa0, 0x77, 0xb9, 0x1d, 0xe7, 0xfc, 0xa6, 0x96, 0xc7, 0x6f, - 0x22, 0x2d, 0x9c, 0xfb, 0xde, 0x87, 0xb0, 0x24, 0x53, 0x15, 0x0e, 0x3b, 0x25, 0x79, 0x1a, 0x9d, - 0x0a, 0xd6, 0x1a, 0xd2, 0x7d, 0x30, 0x61, 0x2d, 0x1c, 0x6c, 0x5a, 0xda, 0x07, 0xd5, 0x6a, 0x9c, - 0x31, 0xa0, 0xbc, 0x22, 0x45, 0x5b, 0x38, 0xca, 0x8c, 0xb4, 0x39, 0x64, 0xea, 0x71, 0xd6, 0x84, - 0x47, 0x51, 0x09, 0x6b, 0xe1, 0x48, 0x65, 0x35, 0x8a, 0x52, 0x35, 0xb0, 0xce, 0x8c, 0x13, 0xa7, - 0x98, 0xba, 0x70, 0xb0, 0x8a, 0x4a, 0x9c, 0x14, 0x05, 0xac, 0x31, 0xa2, 0xc3, 0x2e, 0x33, 0x17, - 0x0e, 0x06, 0x6a, 0x08, 0x9b, 0x51, 0xc1, 0x5a, 0x43, 0xf4, 0x2b, 0xca, 0x79, 0x04, 0xb5, 0xe1, - 0x9c, 0x67, 0x4d, 0xc3, 0x79, 0x38, 0x48, 0x4a, 0x19, 0x3d, 0xca, 0x92, 0x1e, 0x33, 0x4b, 0x7a, - 0xb8, 0x61, 0x8a, 0xf5, 0xbc, 0x2a, 0x60, 0x3d, 0x37, 0x0b, 0x58, 0x4f, 0x6a, 0x58, 0x54, 0x92, - 0xf2, 0xaa, 0x80, 0xf6, 0xdc, 0x2c, 0xa0, 0x3d, 0x02, 0x52, 0xc3, 0x7b, 0x9e, 0xe4, 0xf0, 0x9e, - 0x1b, 0x39, 0xbc, 0x87, 0x43, 0xa9, 0xc4, 0xe7, 0x63, 0x95, 0xf8, 0xac, 0xa8, 0xc4, 0x87, 0x1b, - 0xc6, 0xcc, 0xe7, 0xf3, 0x62, 0xe6, 0x73, 0xab, 0x98, 0xf9, 0x70, 0xb4, 0x1c, 0xea, 0xb3, 0xa7, - 0xa7, 0x3e, 0x1b, 0x7a, 0xea, 0xc3, 0xb1, 0x14, 0xee, 0xf3, 0x22, 0x97, 0xfb, 0x6c, 0xe6, 0x72, - 0x1f, 0xb1, 0x60, 0x33, 0xe4, 0x27, 0x35, 0x9f, 0x23, 0x16, 0xc3, 0xe7, 0xf3, 0x92, 0x76, 0x3e, - 0xa7, 0x55, 0xb0, 0xd6, 0x90, 0x03, 0xa6, 0x88, 0x0c, 0x07, 0x5c, 0x56, 0x01, 0x33, 0x2a, 0x58, - 0x6b, 0x48, 0x5d, 0x68, 0x4e, 0x96, 0x8b, 0x73, 0xa0, 0x5a, 0x1e, 0x07, 0x12, 0x2e, 0x34, 0x2f, - 0x49, 0xf6, 0x0e, 0x56, 0x33, 0x44, 0x86, 0x23, 0xaf, 0x4a, 0xc8, 0x39, 0x5a, 0x38, 0xcf, 0x1c, - 0x61, 0x58, 0x56, 0xf8, 0x0c, 0xc7, 0x35, 0xa5, 0xcf, 0xad, 0xd5, 0xc1, 0x7a, 0x53, 0xd4, 0x19, - 0xcb, 0x85, 0xee, 0x8c, 0xe5, 0x42, 0xbc, 0x85, 0x7c, 0x32, 0xb4, 0x0f, 0x8b, 0x29, 0x6e, 0xc3, - 0x3b, 0xbd, 0x2e, 0xb9, 0x96, 0x4c, 0x3d, 0xce, 0x9a, 0xa0, 0x97, 0x79, 0x7c, 0xa8, 0x96, 0xc7, - 0x87, 0x22, 0xc3, 0x3c, 0x42, 0x74, 0x08, 0x4b, 0x32, 0xb3, 0xe1, 0x5d, 0xdb, 0x90, 0x66, 0x95, - 0x4e, 0x05, 0x6b, 0x0d, 0xa3, 0x88, 0x3a, 0xa1, 0x36, 0x1c, 0xee, 0x86, 0x12, 0x51, 0xab, 0x0a, - 0x49, 0x44, 0xad, 0xd6, 0x70, 0xc0, 0x98, 0xdd, 0x70, 0xc0, 0x9a, 0x0a, 0xa8, 0x28, 0xa4, 0x00, - 0x95, 0x1a, 0x64, 0x83, 0x99, 0x25, 0x35, 0x1c, 0x76, 0x53, 0x5a, 0xee, 0x79, 0x6a, 0x1c, 0x3c, - 0x17, 0x86, 0x46, 0x8c, 0x39, 0x6c, 0x86, 0xb7, 0xb3, 0x25, 0x79, 0xbc, 0x42, 0x5d, 0x11, 0x31, - 0x16, 0x2a, 0xa1, 0x77, 0xb0, 0xac, 0x10, 0x1c, 0xde, 0xd2, 0x4d, 0x79, 0x61, 0xe8, 0x74, 0x78, - 0x0b, 0x7a, 0x00, 0x84, 0xe1, 0x9a, 0xc4, 0x73, 0x38, 0xae, 0x25, 0x47, 0x0c, 0x59, 0x0d, 0x8e, - 0xaa, 0x33, 0xa6, 0x51, 0x88, 0x44, 0x78, 0x38, 0xe6, 0x07, 0x12, 0xa6, 0x46, 0x03, 0xeb, 0xcc, - 0x28, 0xd5, 0xcd, 0xb0, 0x1c, 0x8e, 0x78, 0x4b, 0x5a, 0x1b, 0x39, 0x5a, 0x82, 0xea, 0xe6, 0x54, - 0x23, 0x1b, 0xd6, 0x75, 0x44, 0x87, 0x37, 0xf1, 0xa1, 0xb4, 0x17, 0xe7, 0x2b, 0xe2, 0x02, 0x90, - 0x28, 0xc1, 0xe3, 0xc6, 0x47, 0x43, 0x31, 0xf8, 0x6d, 0x25, 0xc1, 0x93, 0x55, 0xc1, 0x5a, 0x43, - 0x34, 0x84, 0xcd, 0x5c, 0xca, 0xc4, 0xb1, 0xef, 0x48, 0x79, 0x9e, 0x31, 0xda, 0x78, 0x1c, 0x1c, - 0x65, 0x94, 0x1a, 0x06, 0xc5, 0xdb, 0xda, 0x96, 0x18, 0x65, 0xae, 0x1e, 0xce, 0x87, 0x40, 0x01, - 0xd4, 0xf2, 0x48, 0x13, 0x6f, 0xe4, 0xae, 0xc4, 0x28, 0x8b, 0x95, 0xf9, 0x37, 0x1f, 0x03, 0x89, - 0x7e, 0x0f, 0xd7, 0xb5, 0xec, 0x89, 0xb7, 0x78, 0x8f, 0xb5, 0x68, 0x15, 0x31, 0x31, 0xa9, 0xb9, - 0x22, 0x30, 0xab, 0xa9, 0x3d, 0x5a, 0x61, 0xa7, 0x5d, 0xec, 0xf0, 0xb4, 0xd9, 0xe5, 0x87, 0x4e, - 0x71, 0x19, 0xad, 0xc0, 0x74, 0x9b, 0x51, 0x32, 0x46, 0x8e, 0x2a, 0x98, 0x97, 0xac, 0x5f, 0xeb, - 0x39, 0x0c, 0xb2, 0xa0, 0x6a, 0x53, 0x79, 0x7b, 0xd4, 0xa1, 0xbc, 0x87, 0xe1, 0x95, 0xb1, 0x24, - 0xb3, 0x9a, 0x99, 0x33, 0x19, 0x4a, 0xe8, 0x38, 0x12, 0x27, 0x74, 0x13, 0x38, 0x11, 0xa4, 0x8f, - 0xee, 0xae, 0x32, 0xb2, 0x97, 0x3a, 0xba, 0xcb, 0x12, 0x19, 0x13, 0x66, 0xe4, 0xd6, 0x45, 0xd1, - 0x6a, 0x65, 0xf3, 0x85, 0xc8, 0x80, 0x89, 0xfa, 0xa0, 0xcb, 0x0f, 0xee, 0xe8, 0x23, 0x93, 0x9c, - 0xf6, 0x58, 0x4b, 0x54, 0x72, 0xda, 0x63, 0x04, 0xf1, 0x22, 0xf4, 0xed, 0x98, 0x20, 0xd2, 0x82, - 0x75, 0x47, 0xb3, 0xe1, 0x22, 0x04, 0x93, 0xf4, 0x99, 0xe3, 0xb1, 0x67, 0xeb, 0xd3, 0x71, 0x99, - 0x0a, 0xfa, 0x05, 0x8e, 0xec, 0x30, 0x24, 0x3e, 0x67, 0xc2, 0x15, 0x1c, 0x97, 0xad, 0x87, 0x63, - 0xd7, 0x99, 0xb6, 0xd1, 0xff, 0x2a, 0xe5, 0x27, 0x2c, 0xb2, 0xc3, 0x3d, 0xa7, 0x0c, 0x37, 0xf3, - 0x51, 0xcd, 0x86, 0x18, 0x6e, 0x5e, 0xa4, 0x35, 0xcf, 0xbd, 0x93, 0x97, 0xf6, 0x80, 0xf0, 0xe9, - 0x20, 0x8a, 0x74, 0x88, 0x9e, 0x7b, 0x27, 0xcd, 0x06, 0xe3, 0xc6, 0x93, 0x38, 0x2a, 0xa0, 0x6d, - 0x58, 0x88, 0x82, 0xe9, 0x7d, 0xe2, 0x76, 0xc8, 0xa1, 0xdb, 0xbf, 0x64, 0x24, 0xb7, 0x8c, 0x55, - 0x31, 0xba, 0x0d, 0xf3, 0x98, 0xb8, 0xe4, 0xab, 0x44, 0x71, 0x9a, 0x29, 0x2a, 0x52, 0xeb, 0x61, - 0x81, 0x0f, 0x28, 0xf8, 0xf2, 0xef, 0xb2, 0x87, 0x78, 0x9a, 0x2f, 0xbf, 0x04, 0x53, 0x54, 0x21, - 0xe0, 0xdf, 0x3e, 0x2a, 0xd0, 0xc1, 0x8a, 0xdd, 0x29, 0x7b, 0xed, 0x09, 0x9c, 0x08, 0xe8, 0x2c, - 0xc8, 0x72, 0x60, 0xdd, 0x07, 0x59, 0xd2, 0x1d, 0x01, 0x5a, 0x7f, 0x2d, 0x41, 0x59, 0xc8, 0x92, - 0x81, 0xef, 0xf2, 0xa4, 0x86, 0x28, 0x52, 0xc0, 0x17, 0xe4, 0x92, 0x76, 0x6c, 0x62, 0xbb, 0x8a, - 0xd9, 0x33, 0xba, 0x17, 0x59, 0x1e, 0x78, 0xdd, 0xe8, 0x6b, 0xcc, 0x3f, 0x98, 0xdf, 0x61, 0xf7, - 0x40, 0x84, 0x14, 0xc7, 0xf5, 0x68, 0x0b, 0x66, 0x9d, 0x00, 0xdb, 0x6e, 0x8f, 0x11, 0x1a, 0xf6, - 0x91, 0xca, 0x38, 0x2d, 0x42, 0x77, 0x60, 0xe6, 0x99, 0xd7, 0xef, 0x12, 0x3f, 0x30, 0xa7, 0x58, - 0x2e, 0x66, 0x2e, 0x02, 0x7b, 0x6b, 0x3b, 0x94, 0x49, 0x63, 0x51, 0x4b, 0x15, 0xa9, 0x8c, 0x2a, - 0x4e, 0x6b, 0x15, 0x79, 0xad, 0xf5, 0x85, 0x36, 0x11, 0x40, 0x5f, 0xa5, 0xee, 0x36, 0xc5, 0xb8, - 0xb3, 0x67, 0xf4, 0x73, 0xa8, 0x0a, 0xbd, 0x96, 0x13, 0x84, 0xec, 0x35, 0x67, 0x1f, 0x2c, 0x70, - 0xaf, 0x17, 0x43, 0x48, 0x4a, 0xd6, 0x35, 0xcd, 0x41, 0xa8, 0x75, 0x06, 0xb3, 0xc7, 0x17, 0xee, - 0x77, 0x1b, 0x51, 0xec, 0x7d, 0x15, 0x8f, 0x28, 0x7d, 0x46, 0xf7, 0x61, 0xe6, 0x70, 0x18, 0xb2, - 0x7c, 0x54, 0x74, 0x0a, 0xbe, 0x98, 0x0c, 0x28, 0xaf, 0xc0, 0x42, 0xc3, 0xfa, 0xcf, 0x12, 0xcc, - 0xf0, 0xc6, 0xd1, 0x67, 0x50, 0xae, 0xfb, 0xc4, 0x0e, 0xc9, 0xe3, 0x90, 0xdf, 0xc7, 0x58, 0xdf, - 0x89, 0xae, 0xc7, 0xec, 0x88, 0xeb, 0x31, 0xa9, 0x5b, 0x19, 0x65, 0xea, 0xa9, 0xff, 0xf0, 0x3f, - 0x9b, 0x25, 0x1c, 0x5b, 0xa1, 0x2d, 0x98, 0xa4, 0xc1, 0x11, 0x9b, 0x79, 0xb3, 0x0f, 0xaa, 0x3b, - 0xe1, 0x85, 0xbb, 0x73, 0x7c, 0xe1, 0x52, 0x19, 0x66, 0x35, 0xf4, 0x55, 0x5e, 0x07, 0xc4, 0x3f, - 0xbe, 0x70, 0x59, 0xe7, 0xca, 0x58, 0x14, 0xd1, 0xc7, 0x50, 0xa1, 0x63, 0x4e, 0x7b, 0x19, 0x98, - 0x93, 0x6c, 0xe8, 0x90, 0xc8, 0xd8, 0x24, 0x63, 0x81, 0x13, 0x25, 0xeb, 0x73, 0x5d, 0x56, 0x45, - 0xfb, 0x65, 0x3e, 0x66, 0xe3, 0xa9, 0x7c, 0x98, 0xf9, 0x04, 0x9d, 0x01, 0xa4, 0x55, 0xac, 0x65, - 0xed, 0xb9, 0xb2, 0xf5, 0xaf, 0x25, 0xa8, 0xc4, 0x42, 0xea, 0xf0, 0x5e, 0x7a, 0x5d, 0x72, 0x7c, - 0x39, 0x24, 0xbc, 0xb9, 0xb8, 0x4c, 0xb7, 0x1c, 0xfa, 0xdc, 0xec, 0xf2, 0x65, 0xc8, 0x4b, 0x74, - 0x1d, 0x32, 0x00, 0x66, 0x14, 0xb9, 0x9f, 0x44, 0x40, 0x3b, 0xff, 0x3a, 0x20, 0x5d, 0xee, 0x7f, - 0xd8, 0x33, 0x95, 0xed, 0xfb, 0x24, 0x4a, 0xac, 0x4d, 0x62, 0xf6, 0x4c, 0x5b, 0x7e, 0xe6, 0x84, - 0xd8, 0x0e, 0x1d, 0x8f, 0xb9, 0x98, 0xab, 0x38, 0x2e, 0x5b, 0x2f, 0xf5, 0x19, 0x22, 0xf4, 0x08, - 0xe6, 0x62, 0x21, 0x1b, 0x86, 0x28, 0x5b, 0x19, 0x27, 0x15, 0x63, 0x03, 0x59, 0xcd, 0xea, 0xc3, - 0x46, 0xd1, 0x21, 0x2b, 0xfd, 0xa4, 0x4f, 0x7d, 0x6f, 0x34, 0x8c, 0x9d, 0xb0, 0x28, 0x16, 0xbb, - 0x60, 0xb1, 0x17, 0x4e, 0xc8, 0x7b, 0xe1, 0x43, 0xb8, 0x51, 0x98, 0xd8, 0x90, 0x6f, 0x96, 0x4c, - 0x89, 0x9b, 0x25, 0xcf, 0xd9, 0x4b, 0x67, 0x8e, 0x6d, 0xff, 0x96, 0xce, 0x59, 0xf7, 0x61, 0x59, - 0x9b, 0x07, 0xa1, 0x5f, 0x82, 0xe5, 0x4c, 0xf8, 0xd4, 0xa2, 0xcf, 0x56, 0x1b, 0x56, 0x73, 0x4e, - 0x7a, 0x51, 0x0d, 0xa0, 0x61, 0x87, 0xf6, 0x89, 0x1d, 0x90, 0x38, 0xc1, 0x9b, 0x92, 0x14, 0xf4, - 0xe0, 0x13, 0x30, 0xf3, 0x52, 0x28, 0x05, 0xdb, 0xc3, 0x3e, 0x94, 0xd9, 0x97, 0x7b, 0x41, 0x2e, - 0x69, 0x57, 0x8f, 0xec, 0xf0, 0x4c, 0x74, 0x95, 0x3e, 0xd3, 0x29, 0x79, 0x78, 0x7a, 0x1a, 0x90, - 0xe8, 0xbe, 0xd9, 0x04, 0xe6, 0x25, 0x34, 0x0f, 0x57, 0xdb, 0x5f, 0xf3, 0x3d, 0xe1, 0x6a, 0xfb, - 0x6b, 0xeb, 0x11, 0x9f, 0xa2, 0xcc, 0x3f, 0xdf, 0x85, 0xc9, 0x73, 0xea, 0xb3, 0x4b, 0x92, 0x33, - 0x13, 0xf5, 0x3c, 0x5e, 0x63, 0x2a, 0xd6, 0x31, 0xdd, 0x27, 0xd9, 0xab, 0xc7, 0xdd, 0x58, 0x82, - 0xa9, 0xa6, 0xdb, 0x25, 0x17, 0xe2, 0x63, 0xb1, 0x02, 0xba, 0x9f, 0x74, 0x94, 0xbb, 0x0a, 0x15, - 0x17, 0xc7, 0x0a, 0xd6, 0x5b, 0xed, 0xe9, 0x38, 0xfa, 0x2c, 0xd3, 0x18, 0xef, 0x62, 0x9c, 0x5e, - 0x93, 0x6b, 0xb1, 0xaa, 0x6e, 0x1d, 0xc2, 0xa2, 0x18, 0xd4, 0x18, 0x3d, 0xa7, 0xc3, 0x06, 0x4c, - 0x3c, 0x73, 0xc4, 0x35, 0x3d, 0xfa, 0x48, 0xc7, 0x97, 0xea, 0xf3, 0x58, 0x8a, 0x3d, 0x5b, 0x5f, - 0xe8, 0x53, 0x59, 0x68, 0x5f, 0xd3, 0x10, 0xef, 0xac, 0x99, 0x24, 0x0e, 0xe4, 0x7a, 0x9c, 0x35, - 0xb1, 0xb0, 0xf6, 0x64, 0x1f, 0xfd, 0x06, 0xaa, 0xb1, 0x2c, 0x1a, 0x86, 0x28, 0x67, 0x9e, 0xdc, - 0x92, 0x4c, 0x57, 0x63, 0x49, 0x99, 0xaf, 0x9b, 0x6c, 0xd2, 0xeb, 0x01, 0x54, 0x62, 0x61, 0x7c, - 0x39, 0x4f, 0x83, 0x88, 0x13, 0x35, 0xab, 0x0d, 0xb3, 0x47, 0x3e, 0x19, 0xda, 0x3e, 0x69, 0x87, - 0x03, 0x36, 0x44, 0x2c, 0xc6, 0xe2, 0x53, 0x90, 0x05, 0x58, 0x06, 0x4c, 0xb4, 0x5f, 0xb5, 0x44, - 0x54, 0xda, 0x7e, 0xd5, 0xa2, 0x8b, 0xe4, 0xc8, 0xf6, 0xed, 0x01, 0x75, 0x7f, 0x01, 0x1f, 0xce, - 0x94, 0xc4, 0xea, 0xe7, 0xdd, 0x14, 0xa0, 0xd3, 0x99, 0x8a, 0xe2, 0x95, 0xcd, 0x4b, 0xe8, 0x93, - 0xf8, 0xfa, 0x5f, 0x74, 0x6a, 0xa2, 0x49, 0x76, 0x51, 0x98, 0x48, 0x47, 0x5c, 0x0e, 0x7c, 0x3e, - 0x59, 0x9e, 0x30, 0x26, 0xad, 0x7f, 0x9a, 0xc9, 0x4d, 0xc9, 0xd1, 0x65, 0xd2, 0xd8, 0xe3, 0x6f, - 0x73, 0xb5, 0xb1, 0x87, 0x1e, 0x41, 0x35, 0xf5, 0xba, 0x01, 0xdf, 0x55, 0xc4, 0x9e, 0x95, 0xaa, - 0xc2, 0x92, 0x1e, 0xba, 0x07, 0x46, 0xcb, 0x0e, 0xc2, 0xc7, 0xa7, 0xa7, 0xa4, 0x13, 0x92, 0x2e, - 0xdb, 0xbf, 0xa3, 0xc5, 0x97, 0x91, 0xa3, 0x4f, 0x61, 0x9e, 0xee, 0x8f, 0x2d, 0xf2, 0x9e, 0xf4, - 0xd3, 0x3b, 0xe3, 0x92, 0x48, 0xb4, 0xa6, 0x2b, 0xb1, 0xa2, 0x8b, 0x1a, 0x70, 0x43, 0x56, 0x20, - 0x7d, 0x62, 0x07, 0xa4, 0x3d, 0x1a, 0x0e, 0x3d, 0x3f, 0x24, 0x5d, 0x1e, 0xc6, 0x16, 0x2b, 0xa1, - 0x7d, 0x58, 0xa0, 0x0a, 0x0d, 0x72, 0xea, 0xb8, 0xa4, 0xfb, 0xc6, 0x8e, 0x43, 0x26, 0x65, 0x60, - 0x65, 0x25, 0xac, 0x1a, 0xa1, 0x5f, 0xc2, 0xaa, 0x22, 0x7a, 0x72, 0xc1, 0xfb, 0x31, 0xc3, 0xfa, - 0x91, 0x57, 0x4d, 0x7b, 0xd0, 0xbe, 0x0c, 0x42, 0x32, 0x78, 0x63, 0xfb, 0x0e, 0x75, 0x86, 0x81, - 0x59, 0xd6, 0xf5, 0x40, 0x56, 0xc2, 0xaa, 0x11, 0xed, 0x81, 0x22, 0x8a, 0x7b, 0x50, 0x89, 0x7a, - 0x90, 0x53, 0x8d, 0x3e, 0x85, 0x35, 0xa5, 0x73, 0x98, 0x0c, 0xfb, 0xf6, 0x25, 0xcb, 0x7d, 0x03, - 0xb3, 0xcd, 0x57, 0xa0, 0xd6, 0x0a, 0x70, 0xca, 0x7a, 0x36, 0xb2, 0xce, 0x55, 0x40, 0xcf, 0x60, - 0x53, 0xa9, 0x6c, 0xbb, 0xf6, 0x30, 0x38, 0xf3, 0xc2, 0x63, 0xcf, 0x6b, 0xd9, 0x7e, 0x8f, 0xb0, - 0xb3, 0x97, 0x32, 0x1e, 0xa7, 0x46, 0x91, 0x94, 0x4e, 0x66, 0x90, 0xe6, 0x22, 0xa4, 0x31, 0x6a, - 0xe8, 0x33, 0xb8, 0xce, 0xe7, 0x74, 0x97, 0x4e, 0xea, 0x96, 0xe7, 0xf6, 0xa8, 0x8b, 0xaa, 0x9f, - 0x91, 0xce, 0x39, 0xe9, 0xb2, 0x73, 0x97, 0x32, 0x2e, 0x52, 0xa1, 0x71, 0xd0, 0xbe, 0x37, 0x72, - 0xa3, 0xe9, 0xbf, 0x10, 0x1d, 0x7e, 0xc6, 0x02, 0xeb, 0x8f, 0x53, 0xfa, 0x9b, 0x3c, 0xb9, 0x8b, - 0x3e, 0x5a, 0x9c, 0x57, 0xe3, 0xc5, 0xb9, 0x05, 0xb3, 0x6d, 0x12, 0xbe, 0xb1, 0xfd, 0x68, 0x6d, - 0x4e, 0x30, 0x3a, 0x9a, 0x16, 0x65, 0x96, 0xef, 0xe4, 0x0f, 0x58, 0xbe, 0x53, 0xdf, 0x79, 0xf9, - 0x4e, 0x7f, 0x8f, 0xe5, 0xab, 0x59, 0x78, 0x33, 0x3f, 0xf2, 0xc2, 0x2b, 0x7f, 0xef, 0x85, 0x57, - 0xf9, 0x91, 0x17, 0x1e, 0xfc, 0x80, 0x85, 0x37, 0xfb, 0x83, 0x16, 0x5e, 0x75, 0xdc, 0xc2, 0x93, - 0xa6, 0xe8, 0x9c, 0x3a, 0x45, 0xff, 0x54, 0x8a, 0xcf, 0x58, 0xe4, 0x0e, 0x68, 0x37, 0xbe, 0x2d, - 0x98, 0x7a, 0x63, 0xf7, 0x47, 0x84, 0xc7, 0x3b, 0xb0, 0xc3, 0xfe, 0xb2, 0xf0, 0xe4, 0x62, 0xe8, - 0xe3, 0xa8, 0x82, 0x6d, 0x8d, 0x5f, 0xf6, 0x39, 0x25, 0xa0, 0x8f, 0x2c, 0x16, 0x09, 0xf6, 0x1c, - 0x97, 0x13, 0xdd, 0xa8, 0x40, 0xe7, 0x1f, 0x9f, 0x8f, 0x6c, 0x97, 0x7c, 0x41, 0x03, 0xd2, 0x29, - 0xb6, 0x16, 0x32, 0x72, 0x54, 0x83, 0x49, 0xc6, 0x33, 0xa6, 0xd3, 0x8d, 0x52, 0x09, 0x66, 0x72, - 0xeb, 0x15, 0xcc, 0x49, 0x73, 0x4e, 0xdb, 0xf5, 0x38, 0xe0, 0x8e, 0x82, 0xd4, 0xa8, 0xc0, 0xfe, - 0xd7, 0x70, 0xe1, 0x36, 0x1b, 0xd1, 0xda, 0xaa, 0x62, 0x5e, 0xb2, 0xfe, 0x2e, 0xe7, 0xe4, 0xa9, - 0x20, 0x6e, 0xfd, 0x0d, 0x6c, 0x8e, 0xb9, 0x3d, 0x97, 0x0e, 0x95, 0x4b, 0x72, 0xa8, 0x6c, 0xc1, - 0xd6, 0xb8, 0xe3, 0x26, 0x6b, 0x9b, 0x5d, 0x62, 0xd4, 0x5c, 0x7f, 0xa3, 0x6e, 0xa3, 0xfe, 0x52, - 0xec, 0xe9, 0xf5, 0x97, 0xfc, 0x46, 0xbb, 0xee, 0x60, 0x28, 0xe7, 0x46, 0xfb, 0x47, 0xda, 0x8b, - 0x72, 0x79, 0x6e, 0xca, 0x3a, 0xd2, 0x1f, 0x23, 0xe5, 0x0f, 0x0e, 0x8d, 0x8f, 0x1e, 0x8f, 0xc2, - 0xb3, 0x76, 0xe8, 0x3b, 0x6e, 0x94, 0xce, 0xab, 0xe2, 0x94, 0xc4, 0xda, 0xd5, 0xdc, 0xad, 0xa3, - 0xf4, 0x50, 0x88, 0xc4, 0xcd, 0x7f, 0x51, 0xb6, 0x3e, 0xd6, 0x1d, 0x3c, 0x15, 0x5a, 0xfc, 0x4a, - 0x73, 0xe1, 0x0e, 0xdd, 0x82, 0x39, 0x21, 0xda, 0xbb, 0x0c, 0x49, 0xc0, 0x87, 0x45, 0x16, 0x5a, - 0xbf, 0xd6, 0x1d, 0x4a, 0x7d, 0x47, 0xdb, 0xb3, 0xdc, 0x9b, 0x79, 0x68, 0x97, 0xcf, 0xeb, 0x12, - 0x0b, 0xf0, 0xae, 0xe7, 0x1c, 0x0f, 0x25, 0x13, 0x3d, 0x66, 0xdd, 0x6d, 0xe7, 0x6b, 0xc2, 0xd9, - 0x4f, 0x22, 0xb0, 0x2e, 0xf2, 0x4f, 0xba, 0x64, 0xcb, 0x92, 0x62, 0x49, 0xdf, 0x84, 0x15, 0xea, - 0xf6, 0xd0, 0xee, 0x38, 0xe1, 0x25, 0xc7, 0x96, 0x85, 0xf4, 0xeb, 0x1e, 0x90, 0x20, 0xb0, 0x7b, - 0x71, 0xc2, 0x91, 0x17, 0xad, 0xc3, 0xe2, 0xdb, 0x81, 0xdf, 0xfb, 0x45, 0xad, 0x7f, 0x1c, 0x73, - 0xa2, 0xf6, 0x13, 0xbf, 0xcf, 0x27, 0xfa, 0xeb, 0x87, 0xc5, 0xad, 0x5a, 0x7f, 0x9f, 0x73, 0x28, - 0x97, 0xed, 0x4e, 0x49, 0xd3, 0x1d, 0xeb, 0xff, 0x4a, 0x63, 0x2e, 0x9e, 0x8d, 0xc9, 0x14, 0xb3, - 0xce, 0x85, 0x76, 0xdf, 0xeb, 0xc5, 0x4c, 0x3c, 0x11, 0xd0, 0x5a, 0xea, 0x06, 0xd9, 0x81, 0x94, - 0x48, 0xd8, 0xc4, 0x02, 0xea, 0x15, 0xa2, 0x0b, 0x10, 0x93, 0x51, 0xb2, 0x35, 0xba, 0xd4, 0x50, - 0x03, 0x10, 0x21, 0x53, 0xb3, 0xc1, 0xa3, 0x83, 0x94, 0x04, 0x3d, 0x48, 0x86, 0xa9, 0xe5, 0x75, - 0x6c, 0x4a, 0x40, 0x9e, 0xd9, 0xc1, 0x19, 0xf3, 0xd3, 0x15, 0xac, 0xad, 0xa3, 0x2b, 0x34, 0xba, - 0x3e, 0xd3, 0x6c, 0xb0, 0x78, 0xb9, 0x82, 0xe3, 0xb2, 0xf5, 0x6c, 0xdc, 0x99, 0x4f, 0x94, 0x99, - 0x1e, 0x78, 0xef, 0x49, 0xf7, 0x89, 0x1b, 0xfa, 0x4e, 0xbc, 0xe6, 0x14, 0xa9, 0xb5, 0xa3, 0xbb, - 0xe8, 0x49, 0x3f, 0x38, 0x97, 0x70, 0xe7, 0x20, 0x8a, 0xd6, 0xae, 0xf6, 0xd4, 0xb3, 0xc0, 0xa0, - 0xa5, 0xbb, 0xf8, 0x49, 0xfd, 0x25, 0xbf, 0xe9, 0xc6, 0xff, 0x7b, 0xc4, 0x2f, 0xb5, 0x09, 0x76, - 0x48, 0x58, 0xa6, 0x36, 0x0a, 0xef, 0x52, 0x12, 0xeb, 0xae, 0xf6, 0x80, 0x54, 0x9b, 0xb9, 0xbe, - 0x97, 0x77, 0x4d, 0x34, 0x9b, 0x42, 0xb7, 0x3e, 0xca, 0x3d, 0x29, 0xd5, 0x42, 0x0f, 0x0a, 0x2e, - 0x89, 0xa2, 0x6d, 0x58, 0xe0, 0x7f, 0x59, 0x8b, 0xd3, 0xef, 0xd1, 0x16, 0xa6, 0x8a, 0xe9, 0x37, - 0x7a, 0xeb, 0x3b, 0x61, 0x02, 0xc1, 0x27, 0xa3, 0x22, 0xb5, 0xdc, 0xa2, 0x73, 0xd6, 0x9f, 0xa0, - 0xbd, 0x37, 0xfa, 0x43, 0x57, 0xf4, 0x0f, 0x50, 0x4d, 0xcb, 0xbf, 0xc3, 0x7f, 0xf8, 0x24, 0x7d, - 0xeb, 0x9f, 0x4b, 0x45, 0xd7, 0x37, 0xc7, 0x2c, 0x5a, 0x0b, 0xaa, 0x74, 0x4f, 0x25, 0x8c, 0xbd, - 0xc7, 0xeb, 0x56, 0x92, 0xd1, 0x50, 0x89, 0xa7, 0x15, 0x9f, 0x5c, 0x74, 0xfa, 0xa3, 0xc0, 0x79, - 0x4f, 0x78, 0xba, 0x31, 0x23, 0xb7, 0x7e, 0x51, 0x78, 0x82, 0x59, 0x10, 0xbd, 0xfc, 0x7b, 0x12, - 0x07, 0xca, 0xa1, 0xe4, 0xdf, 0x18, 0x07, 0x6e, 0xc3, 0xc2, 0x4b, 0x72, 0x11, 0x1e, 0xfb, 0xb6, - 0x1b, 0xd8, 0x51, 0x1e, 0x23, 0xca, 0x94, 0xab, 0x62, 0xb4, 0x03, 0x55, 0x3c, 0x72, 0xe9, 0x68, - 0x47, 0x90, 0x93, 0x19, 0x48, 0xa9, 0xfe, 0xde, 0xbf, 0x4d, 0xa7, 0xae, 0x94, 0xa2, 0x0a, 0xff, - 0x23, 0xab, 0x71, 0x05, 0x5d, 0x83, 0x05, 0xe5, 0x96, 0xa7, 0x51, 0x42, 0x06, 0x54, 0xd3, 0x67, - 0xa3, 0xc6, 0x55, 0x54, 0x85, 0xb2, 0x38, 0xa6, 0x34, 0x26, 0xd0, 0x1c, 0x54, 0xe2, 0x23, 0x23, - 0x63, 0x12, 0x2d, 0xc0, 0x6c, 0xea, 0x9c, 0xc4, 0x98, 0x42, 0xf3, 0x00, 0x49, 0x76, 0xde, 0x98, - 0xa6, 0x78, 0xe9, 0xb4, 0xb4, 0x31, 0x43, 0x35, 0x92, 0xcb, 0x84, 0x46, 0x99, 0x22, 0xc6, 0x77, - 0x04, 0x8d, 0x0a, 0x5a, 0xd1, 0xdd, 0x12, 0x34, 0x80, 0xca, 0xb3, 0xb7, 0xf5, 0x8c, 0x59, 0x84, - 0xd4, 0xfb, 0x7a, 0x46, 0x15, 0xcd, 0xc6, 0x97, 0xef, 0x8c, 0x39, 0xb4, 0x96, 0x73, 0xaf, 0xce, - 0x98, 0x47, 0x8b, 0xca, 0xb5, 0x38, 0x63, 0x01, 0x2d, 0x65, 0x6f, 0xb9, 0x19, 0x46, 0xfa, 0x2d, - 0x28, 0x9b, 0x35, 0x16, 0xb9, 0x24, 0xce, 0x82, 0x19, 0x88, 0x0e, 0xa7, 0x72, 0xe3, 0xcb, 0xb8, - 0x46, 0x85, 0x4a, 0x62, 0xc9, 0x58, 0xa2, 0xcd, 0x4a, 0xc1, 0xb2, 0xb1, 0x8c, 0x36, 0xf2, 0x6f, - 0x59, 0x19, 0x2b, 0x74, 0x88, 0xe2, 0xd3, 0x5a, 0x63, 0x95, 0xb7, 0x94, 0x0e, 0x57, 0x0d, 0x93, - 0x76, 0x28, 0x1d, 0x63, 0x1a, 0x6b, 0xec, 0x53, 0x1c, 0x1e, 0x3c, 0x7e, 0x77, 0x84, 0x0f, 0xeb, - 0x6d, 0x63, 0x9d, 0x97, 0x9f, 0x1c, 0xb4, 0x9a, 0x07, 0xcd, 0x63, 0xe3, 0x3a, 0x7d, 0x55, 0x35, - 0x68, 0x30, 0x36, 0xe8, 0x70, 0x69, 0x43, 0x09, 0xe3, 0x06, 0xeb, 0x77, 0x7a, 0xc3, 0x36, 0x6a, - 0xec, 0xfb, 0x1f, 0xc6, 0x1b, 0x81, 0xb1, 0x49, 0x05, 0x29, 0xd7, 0x6c, 0x6c, 0xd1, 0xce, 0x2a, - 0x4e, 0xd5, 0xb8, 0x49, 0x3f, 0x66, 0xd6, 0x97, 0x19, 0x16, 0x7d, 0x89, 0xb4, 0xaf, 0x30, 0x3e, - 0x40, 0xd7, 0x99, 0x4f, 0xd6, 0x9d, 0x20, 0x1b, 0xb7, 0xd0, 0x32, 0x2c, 0x66, 0x0e, 0x54, 0x8d, - 0x0f, 0xd1, 0x3a, 0xac, 0xe8, 0xf7, 0x45, 0xe3, 0x36, 0x5a, 0x85, 0x6b, 0x9a, 0x05, 0x6f, 0xdc, - 0xb9, 0xf7, 0x2f, 0x25, 0x89, 0xc2, 0x24, 0xb9, 0x42, 0x3a, 0x22, 0x4a, 0x45, 0xc4, 0x53, 0x8d, - 0x2b, 0xe8, 0x3e, 0xdc, 0x51, 0xaa, 0xda, 0xe7, 0xce, 0x50, 0x97, 0x58, 0x33, 0x4a, 0xe8, 0x23, - 0xb8, 0xab, 0xe2, 0xb8, 0x74, 0x50, 0xb4, 0xea, 0x57, 0xef, 0xfd, 0x0c, 0x96, 0x74, 0x11, 0x1f, - 0x02, 0xba, 0x69, 0x0e, 0x3c, 0xb6, 0x84, 0xcb, 0x30, 0xd9, 0x70, 0x82, 0x73, 0xa3, 0xb4, 0xd7, - 0xfa, 0xf3, 0x37, 0xb5, 0xd2, 0x5f, 0xbe, 0xa9, 0x95, 0xfe, 0xf7, 0x9b, 0xda, 0x95, 0x3f, 0x7c, - 0x5b, 0xbb, 0xf2, 0xc7, 0x6f, 0x6b, 0xa5, 0xbf, 0x7c, 0x5b, 0xbb, 0xf2, 0xd7, 0x6f, 0x6b, 0x57, - 0x3e, 0xdf, 0x49, 0xfd, 0x3d, 0x7e, 0x60, 0x87, 0xbe, 0x73, 0xe1, 0xf9, 0x4e, 0xcf, 0x71, 0x45, - 0xc1, 0x25, 0xbb, 0xc3, 0xf3, 0xde, 0xee, 0xf0, 0x64, 0x97, 0x85, 0x9a, 0x27, 0xd3, 0xec, 0xe4, - 0xef, 0xe7, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xca, 0x40, 0x1b, 0xbe, 0x3f, 0x00, 0x00, + 0x6d, 0x77, 0xd5, 0x1e, 0xf7, 0xb2, 0x87, 0xad, 0xf9, 0x13, 0x66, 0x4f, 0xfb, 0x1f, 0x4c, 0xd5, + 0x1e, 0xe7, 0x36, 0xc7, 0x39, 0xec, 0x61, 0x4e, 0xbb, 0x5b, 0xdd, 0x7f, 0xc8, 0x6e, 0x01, 0x04, + 0x48, 0x02, 0x04, 0xa9, 0xfe, 0x9a, 0x8b, 0x8a, 0x78, 0x78, 0xef, 0x07, 0x10, 0x04, 0x1e, 0xde, + 0xef, 0x01, 0x82, 0xd9, 0x2f, 0x47, 0xc4, 0xbf, 0xdc, 0x19, 0xfa, 0x5e, 0xe8, 0xa1, 0x29, 0x56, + 0x58, 0xaf, 0x06, 0xa1, 0x1d, 0x8e, 0x82, 0x48, 0xb8, 0x0e, 0x7d, 0xaf, 0x73, 0xce, 0x9f, 0x2b, + 0xe1, 0x85, 0xcb, 0x1f, 0x17, 0x42, 0x67, 0x40, 0x82, 0xd0, 0x1e, 0x0c, 0x85, 0x80, 0x5a, 0x05, + 0x8e, 0x7b, 0xea, 0x09, 0xc3, 0x61, 0xdf, 0x16, 0xda, 0x1f, 0xf5, 0x9c, 0xf0, 0x6c, 0x74, 0xb2, + 0xd3, 0xf1, 0x06, 0xbb, 0x3d, 0xaf, 0xe7, 0xed, 0x32, 0xf1, 0xc9, 0xe8, 0x94, 0x95, 0x58, 0x81, + 0x3d, 0x71, 0xf5, 0xcd, 0x9e, 0xe7, 0xf5, 0xfa, 0x24, 0xd1, 0x52, 0x1a, 0xb3, 0x6e, 0x41, 0xf5, + 0x15, 0xed, 0x2b, 0x26, 0x5f, 0x8e, 0x48, 0x10, 0xa2, 0x25, 0x98, 0x62, 0x65, 0xb3, 0xb4, 0x55, + 0xda, 0xae, 0xe0, 0xa8, 0x60, 0xbd, 0x84, 0x95, 0xf6, 0x99, 0xf7, 0xd5, 0x91, 0xef, 0x75, 0x48, + 0x10, 0xb4, 0x9c, 0x20, 0x14, 0xfa, 0x2b, 0x30, 0x7d, 0x4c, 0x5c, 0xdb, 0x0d, 0xb9, 0x01, 0x2f, + 0xa1, 0x0d, 0xa8, 0xb4, 0x2f, 0x03, 0x5e, 0x75, 0x75, 0xab, 0xb4, 0x5d, 0xc6, 0x89, 0xc0, 0x7a, + 0x0b, 0x8b, 0xed, 0x4b, 0xb7, 0x53, 0xf7, 0x06, 0x03, 0x27, 0x86, 0xda, 0x83, 0xf9, 0x96, 0x1d, + 0x92, 0x20, 0x8c, 0xc4, 0xc7, 0x6d, 0x06, 0x39, 0xfb, 0x60, 0x69, 0x27, 0xe9, 0xf4, 0xb1, 0x78, + 0xda, 0x9b, 0xfc, 0xcb, 0x7f, 0x6f, 0x5e, 0xc1, 0x8a, 0x85, 0xf5, 0x39, 0xa0, 0x34, 0x70, 0x30, + 0xf4, 0xdc, 0x80, 0xa0, 0x06, 0x2c, 0xd4, 0x47, 0xbe, 0x4f, 0xdc, 0xef, 0x03, 0xad, 0x9a, 0x58, + 0x08, 0x8c, 0xa7, 0x24, 0x94, 0xfa, 0x6c, 0xfd, 0x16, 0x16, 0x53, 0xb2, 0x9f, 0xb4, 0xb9, 0x5d, + 0x58, 0xae, 0x7b, 0x3e, 0x69, 0x8c, 0x06, 0xc3, 0xba, 0xe7, 0x9e, 0x3a, 0xbd, 0xd4, 0x90, 0x3f, + 0xee, 0x84, 0x8e, 0xe7, 0x8a, 0x21, 0x8f, 0x4a, 0x96, 0x09, 0x2b, 0xaa, 0x41, 0xd4, 0x21, 0xeb, + 0x3a, 0xac, 0x3d, 0x25, 0xe1, 0x11, 0xfd, 0xe0, 0x1d, 0xaf, 0xff, 0x86, 0xf8, 0x81, 0xe3, 0xb9, + 0xe2, 0x15, 0x1e, 0xc1, 0xba, 0xae, 0x92, 0xbf, 0x8b, 0x09, 0x33, 0x5c, 0xc4, 0x5a, 0x9b, 0xc0, + 0xa2, 0x68, 0x3d, 0x84, 0xb5, 0x76, 0x1e, 0x68, 0x81, 0xd9, 0x23, 0x58, 0x6f, 0xff, 0x90, 0xe6, + 0x7e, 0x06, 0xf3, 0x78, 0xe4, 0x1e, 0xdb, 0xc1, 0xb9, 0x68, 0x63, 0x1d, 0xca, 0xb4, 0x58, 0xf7, + 0xba, 0x84, 0x29, 0x4f, 0xe1, 0xb8, 0x6c, 0xdd, 0x85, 0x85, 0x58, 0x9b, 0x43, 0xaf, 0xc0, 0x34, + 0x26, 0xc1, 0xa8, 0x1f, 0xcf, 0xd4, 0xa8, 0x44, 0x87, 0x8d, 0xbe, 0xbf, 0x33, 0x24, 0x7d, 0xc7, + 0x25, 0x4d, 0xf7, 0xd4, 0x13, 0x23, 0xb3, 0x0b, 0xab, 0x99, 0x1a, 0x0e, 0xb6, 0x04, 0x53, 0x75, + 0x6f, 0xc4, 0x67, 0xfd, 0x04, 0x8e, 0x0a, 0xd6, 0x9f, 0xd6, 0x60, 0x46, 0xf4, 0x6e, 0x03, 0x2a, + 0xfc, 0xb1, 0xd9, 0x60, 0x5a, 0x93, 0x38, 0x11, 0xa0, 0x1d, 0xa8, 0xd4, 0x07, 0xdd, 0x03, 0x12, + 0x9e, 0x79, 0x5d, 0xb6, 0x3c, 0xe6, 0x1f, 0x18, 0x3b, 0x91, 0x07, 0x89, 0xe5, 0x38, 0x51, 0x41, + 0xbf, 0x90, 0x97, 0xa9, 0x39, 0xc1, 0xe6, 0xd3, 0x35, 0x6e, 0x92, 0xae, 0xc2, 0xf2, 0x7a, 0x7e, + 0x9d, 0xb7, 0x72, 0xcd, 0x49, 0x06, 0x71, 0x83, 0x43, 0xe8, 0x95, 0x70, 0xde, 0xb2, 0x6f, 0xc1, + 0xb5, 0xc7, 0xfd, 0x90, 0xf8, 0x8f, 0x3b, 0x1d, 0xfa, 0xe6, 0x02, 0x73, 0x8a, 0x61, 0xae, 0x73, + 0x4c, 0x8d, 0x06, 0xd6, 0x99, 0xa1, 0xcf, 0x60, 0xe1, 0x85, 0xd3, 0xef, 0xd7, 0x3d, 0x57, 0x4c, + 0x20, 0x73, 0x9a, 0x21, 0xad, 0x70, 0x24, 0xa5, 0x16, 0xab, 0xea, 0xa8, 0x0e, 0xc6, 0xb1, 0x6f, + 0x77, 0x48, 0x7b, 0x68, 0xc7, 0x10, 0x33, 0x0c, 0x62, 0x95, 0x43, 0xa8, 0xd5, 0x38, 0x63, 0x80, + 0x9a, 0x80, 0x9e, 0x92, 0xb0, 0xe5, 0x75, 0xce, 0x53, 0xb3, 0xc0, 0x2c, 0x33, 0x98, 0x35, 0x0e, + 0x93, 0x55, 0xc0, 0x1a, 0x23, 0xb4, 0xcf, 0xfc, 0xc2, 0xf1, 0x85, 0x9b, 0x46, 0xaa, 0x30, 0x24, + 0x33, 0x41, 0x92, 0xeb, 0x71, 0xd6, 0x84, 0x8e, 0x33, 0xf5, 0x2f, 0x76, 0xe7, 0x2c, 0x3d, 0x33, + 0x4d, 0x90, 0xc6, 0x59, 0xa3, 0x81, 0x75, 0x66, 0xe8, 0x97, 0x00, 0xed, 0xcb, 0x8e, 0x1b, 0xb9, + 0x18, 0x73, 0x56, 0xea, 0x4e, 0xc6, 0x1f, 0xe3, 0x94, 0x2e, 0x7a, 0x08, 0x95, 0xd8, 0xcf, 0x99, + 0x55, 0x69, 0x60, 0x55, 0x9f, 0x88, 0x13, 0x4d, 0x74, 0xc4, 0x46, 0x54, 0x59, 0xec, 0xe6, 0x1c, + 0xb3, 0xdf, 0x4a, 0xec, 0xf5, 0x4e, 0x04, 0x6b, 0x6c, 0x29, 0x62, 0xd6, 0x7d, 0x98, 0xf3, 0x12, + 0x62, 0x3b, 0x1f, 0x31, 0x5b, 0x85, 0x1a, 0x30, 0x2f, 0xbb, 0x4d, 0x73, 0x81, 0xa1, 0x6d, 0x88, + 0xf5, 0xa8, 0x73, 0xc2, 0x58, 0xb1, 0x41, 0xbb, 0x30, 0xc3, 0x1d, 0x8e, 0x69, 0x30, 0xf3, 0x65, + 0x6e, 0x2e, 0x3b, 0x2d, 0x2c, 0xb4, 0xd0, 0x6f, 0x61, 0x19, 0x93, 0x81, 0xf7, 0x9e, 0xd0, 0xdf, + 0x90, 0xd0, 0x09, 0x74, 0x6c, 0x9f, 0xf4, 0x89, 0xb9, 0xc8, 0xcc, 0x3f, 0x10, 0xe6, 0x3a, 0x1d, + 0x01, 0xa6, 0x47, 0x40, 0x8f, 0x61, 0x8e, 0x4e, 0x49, 0xb6, 0x33, 0xee, 0x39, 0x6e, 0xd7, 0x44, + 0x0c, 0xf2, 0x7a, 0x6a, 0x0a, 0xc7, 0x75, 0x02, 0x4a, 0xb6, 0x40, 0xcf, 0xc1, 0x78, 0xed, 0x06, + 0xa3, 0x93, 0xa0, 0xe3, 0x3b, 0x27, 0x24, 0xea, 0xd8, 0x35, 0x86, 0x52, 0xe3, 0x28, 0x6a, 0x75, + 0xbc, 0xac, 0xd4, 0x8a, 0xf4, 0x1c, 0x6e, 0xd8, 0xa1, 0x2d, 0xe6, 0xf0, 0x92, 0x76, 0x0e, 0xa7, + 0x34, 0xb0, 0xce, 0x8c, 0xa3, 0xb5, 0x69, 0x88, 0x94, 0x5e, 0x11, 0xcb, 0x2a, 0x9a, 0xaa, 0x81, + 0x75, 0x66, 0xd4, 0x3d, 0xea, 0x9d, 0xbf, 0xb9, 0x22, 0xb9, 0x47, 0xbd, 0x12, 0xce, 0x31, 0xa6, + 0xb0, 0x07, 0x4e, 0xcf, 0xb7, 0x43, 0x42, 0x9d, 0xd4, 0xbe, 0xef, 0x0d, 0x04, 0xec, 0xaa, 0x04, + 0xab, 0x57, 0xc2, 0x39, 0xc6, 0xe8, 0x10, 0x96, 0x52, 0x35, 0xc7, 0x71, 0x5f, 0x4d, 0xe9, 0xfb, + 0xea, 0x54, 0xb0, 0xd6, 0x10, 0x9d, 0x80, 0x89, 0x49, 0xdf, 0xb3, 0xbb, 0x8f, 0x47, 0xa1, 0xd7, + 0x74, 0x3b, 0x3e, 0x19, 0xd0, 0x10, 0x84, 0x8e, 0xb9, 0xb9, 0xc6, 0x40, 0x6f, 0xc7, 0xf3, 0x50, + 0xaf, 0x26, 0xf0, 0x73, 0x71, 0xa8, 0x6b, 0xae, 0x87, 0x7d, 0x4c, 0xec, 0x2e, 0xf1, 0x45, 0x87, + 0xd7, 0x25, 0x0f, 0xa2, 0x56, 0xe3, 0x8c, 0x01, 0x3a, 0x80, 0x85, 0xa7, 0x24, 0xc4, 0x64, 0xd8, + 0x77, 0x3a, 0x76, 0xb4, 0xf3, 0x5e, 0x57, 0x3f, 0x50, 0xba, 0x96, 0xdb, 0x89, 0xd8, 0x4a, 0xa9, + 0xa5, 0x93, 0x08, 0x93, 0x80, 0x84, 0x6d, 0x12, 0xa4, 0xdc, 0x83, 0xb9, 0x21, 0x4d, 0x22, 0x8d, + 0x06, 0xd6, 0x99, 0xa1, 0x16, 0x2c, 0x3e, 0xf5, 0x0e, 0xec, 0x0b, 0xba, 0x4f, 0x06, 0x02, 0xeb, + 0x86, 0xec, 0xec, 0xd5, 0x7a, 0xde, 0xb3, 0xac, 0x21, 0x47, 0x23, 0x83, 0x96, 0x93, 0xf8, 0x54, + 0xb3, 0xa6, 0xa2, 0xc9, 0xf5, 0x29, 0x34, 0xb9, 0x02, 0x7d, 0x01, 0xab, 0xfb, 0x4e, 0x9f, 0xb4, + 0x89, 0xff, 0xde, 0xe9, 0x90, 0xf4, 0x27, 0x33, 0x37, 0xa5, 0xf5, 0x9c, 0xa3, 0xc5, 0x91, 0xf3, + 0x40, 0xd0, 0x00, 0x36, 0xd4, 0xaa, 0x27, 0xef, 0x9d, 0x4e, 0xdc, 0xf1, 0x2d, 0xc9, 0x9b, 0x15, + 0xa9, 0xf2, 0x96, 0x0a, 0xe1, 0xd0, 0x6b, 0x58, 0x3a, 0x20, 0xa1, 0xdd, 0xb5, 0x43, 0x5b, 0x7a, + 0x97, 0x9b, 0xf2, 0x0a, 0xd0, 0xa8, 0x70, 0x78, 0xad, 0x39, 0x3a, 0x04, 0xf4, 0xd4, 0x7b, 0x5a, + 0x3f, 0x22, 0x7e, 0x87, 0x24, 0xd1, 0x8c, 0x25, 0xef, 0xfc, 0x19, 0x05, 0x0e, 0xa9, 0x31, 0xa5, + 0xa1, 0xc4, 0xbe, 0x3d, 0xea, 0x87, 0x4d, 0xf7, 0xf7, 0x24, 0x19, 0x8c, 0x0f, 0x24, 0xc0, 0xac, + 0x02, 0xd6, 0x18, 0xa1, 0xdf, 0xc1, 0x4a, 0x3d, 0xec, 0x1f, 0x78, 0xcc, 0x99, 0x32, 0x07, 0x26, + 0xe0, 0x6e, 0x49, 0x2b, 0x40, 0xaf, 0xc4, 0xfb, 0x98, 0x03, 0x81, 0xbe, 0x80, 0xb5, 0xb7, 0x9e, + 0x7f, 0x1e, 0x0c, 0xed, 0x0e, 0x39, 0x3e, 0xf3, 0x49, 0x70, 0xe6, 0xf5, 0xc5, 0x9e, 0x60, 0x7e, + 0x28, 0xed, 0xaa, 0xb9, 0x7a, 0x38, 0x1f, 0x02, 0x0d, 0xa0, 0x56, 0x0f, 0xfb, 0x47, 0x3e, 0x39, + 0x25, 0x61, 0xe7, 0xec, 0xd0, 0x6d, 0x8b, 0xad, 0x21, 0x6e, 0xe4, 0x36, 0x6b, 0xe4, 0xc3, 0xe4, + 0x25, 0x0a, 0x94, 0xf1, 0x18, 0x30, 0xf4, 0x3b, 0x30, 0x9b, 0xed, 0xfa, 0x51, 0xc3, 0xb7, 0x1d, + 0xb7, 0xee, 0xb9, 0xc1, 0x68, 0x90, 0xf8, 0x9c, 0x3b, 0xac, 0xa1, 0x4d, 0xde, 0x50, 0x9e, 0x1a, + 0xce, 0x05, 0x40, 0x43, 0xb8, 0xd1, 0xec, 0x90, 0x13, 0xe2, 0xf7, 0x78, 0x60, 0xf5, 0xde, 0xee, + 0x3b, 0x5d, 0x3b, 0x8c, 0x27, 0xe1, 0x36, 0x6b, 0xe1, 0x96, 0x68, 0xa1, 0x48, 0x97, 0x7f, 0x96, + 0x62, 0x40, 0xd4, 0x83, 0xf5, 0x03, 0xcf, 0xed, 0x79, 0x8d, 0xbd, 0x7a, 0xdf, 0x61, 0xb3, 0x2b, + 0x74, 0xfc, 0xb8, 0xb9, 0xbb, 0xac, 0xb9, 0x9b, 0x62, 0xce, 0xe7, 0x2a, 0xf2, 0xb6, 0x0a, 0xa0, + 0xac, 0x7d, 0x58, 0xcd, 0x04, 0xfa, 0x9c, 0xe9, 0xdc, 0x87, 0x32, 0x77, 0x77, 0x81, 0x59, 0xda, + 0x9a, 0xd8, 0x9e, 0x7d, 0xb0, 0xb0, 0xc3, 0xd3, 0x1a, 0xc2, 0x0d, 0xc6, 0x0a, 0xd6, 0x9f, 0xd7, + 0xa1, 0x1c, 0x5b, 0xfe, 0xb4, 0x0c, 0x68, 0x09, 0xa6, 0x9e, 0xf8, 0xbe, 0xe7, 0x33, 0xea, 0x53, + 0xc5, 0x51, 0x01, 0xbd, 0xcb, 0xed, 0x38, 0xe7, 0x37, 0xb5, 0x3c, 0x7e, 0x13, 0x69, 0xe1, 0xdc, + 0xf7, 0x3e, 0x84, 0x25, 0x99, 0xaa, 0x70, 0xd8, 0x29, 0xc9, 0xd3, 0xe8, 0x54, 0xb0, 0xd6, 0x90, + 0xee, 0x83, 0x09, 0x6b, 0xe1, 0x60, 0xd3, 0xd2, 0x3e, 0xa8, 0x56, 0xe3, 0x8c, 0x01, 0xe5, 0x15, + 0x29, 0xda, 0xc2, 0x51, 0x66, 0xa4, 0xcd, 0x21, 0x53, 0x8f, 0xb3, 0x26, 0x3c, 0x8a, 0x4a, 0x58, + 0x0b, 0x47, 0x2a, 0xab, 0x51, 0x94, 0xaa, 0x81, 0x75, 0x66, 0x9c, 0x38, 0xc5, 0xd4, 0x85, 0x83, + 0x55, 0x54, 0xe2, 0xa4, 0x28, 0x60, 0x8d, 0x11, 0x1d, 0x76, 0x99, 0xb9, 0x70, 0x30, 0x50, 0x43, + 0xd8, 0x8c, 0x0a, 0xd6, 0x1a, 0xa2, 0x5f, 0x51, 0xce, 0x23, 0xa8, 0x0d, 0xe7, 0x3c, 0x6b, 0x1a, + 0xce, 0xc3, 0x41, 0x52, 0xca, 0xe8, 0x51, 0x96, 0xf4, 0x98, 0x59, 0xd2, 0xc3, 0x0d, 0x53, 0xac, + 0xe7, 0x55, 0x01, 0xeb, 0xb9, 0x59, 0xc0, 0x7a, 0x52, 0xc3, 0xa2, 0x92, 0x94, 0x57, 0x05, 0xb4, + 0xe7, 0x66, 0x01, 0xed, 0x11, 0x90, 0x1a, 0xde, 0xf3, 0x24, 0x87, 0xf7, 0xdc, 0xc8, 0xe1, 0x3d, + 0x1c, 0x4a, 0x25, 0x3e, 0x1f, 0xab, 0xc4, 0x67, 0x45, 0x25, 0x3e, 0xdc, 0x30, 0x66, 0x3e, 0x9f, + 0x17, 0x33, 0x9f, 0x5b, 0xc5, 0xcc, 0x87, 0xa3, 0xe5, 0x50, 0x9f, 0x3d, 0x3d, 0xf5, 0xd9, 0xd0, + 0x53, 0x1f, 0x8e, 0xa5, 0x70, 0x9f, 0x17, 0xb9, 0xdc, 0x67, 0x33, 0x97, 0xfb, 0x88, 0x05, 0x9b, + 0x21, 0x3f, 0xa9, 0xf9, 0x1c, 0xb1, 0x18, 0x3e, 0x9f, 0x97, 0xb4, 0xf3, 0x39, 0xad, 0x82, 0xb5, + 0x86, 0x1c, 0x30, 0x45, 0x64, 0x38, 0xe0, 0xb2, 0x0a, 0x98, 0x51, 0xc1, 0x5a, 0x43, 0xea, 0x42, + 0x73, 0xb2, 0x5c, 0x9c, 0x03, 0xd5, 0xf2, 0x38, 0x90, 0x70, 0xa1, 0x79, 0x49, 0xb2, 0x77, 0xb0, + 0x9a, 0x21, 0x32, 0x1c, 0x79, 0x55, 0x42, 0xce, 0xd1, 0xc2, 0x79, 0xe6, 0x08, 0xc3, 0xb2, 0xc2, + 0x67, 0x38, 0xae, 0x29, 0x7d, 0x6e, 0xad, 0x0e, 0xd6, 0x9b, 0xa2, 0xce, 0x58, 0x2e, 0x74, 0x67, + 0x2c, 0x17, 0xe2, 0x2d, 0xe4, 0x93, 0xa1, 0x7d, 0x58, 0x4c, 0x71, 0x1b, 0xde, 0xe9, 0x75, 0xc9, + 0xb5, 0x64, 0xea, 0x71, 0xd6, 0x04, 0xbd, 0xcc, 0xe3, 0x43, 0xb5, 0x3c, 0x3e, 0x14, 0x19, 0xe6, + 0x11, 0xa2, 0x43, 0x58, 0x92, 0x99, 0x0d, 0xef, 0xda, 0x86, 0x34, 0xab, 0x74, 0x2a, 0x58, 0x6b, + 0x18, 0x45, 0xd4, 0x09, 0xb5, 0xe1, 0x70, 0x37, 0x94, 0x88, 0x5a, 0x55, 0x48, 0x22, 0x6a, 0xb5, + 0x86, 0x03, 0xc6, 0xec, 0x86, 0x03, 0xd6, 0x54, 0x40, 0x45, 0x21, 0x05, 0xa8, 0xd4, 0x20, 0x1b, + 0xcc, 0x2c, 0xa9, 0xe1, 0xb0, 0x9b, 0xd2, 0x72, 0xcf, 0x53, 0xe3, 0xe0, 0xb9, 0x30, 0x34, 0x62, + 0xcc, 0x61, 0x33, 0xbc, 0x9d, 0x2d, 0xc9, 0xe3, 0x15, 0xea, 0x8a, 0x88, 0xb1, 0x50, 0x09, 0xbd, + 0x83, 0x65, 0x85, 0xe0, 0xf0, 0x96, 0x6e, 0xca, 0x0b, 0x43, 0xa7, 0xc3, 0x5b, 0xd0, 0x03, 0x20, + 0x0c, 0xd7, 0x24, 0x9e, 0xc3, 0x71, 0x2d, 0x39, 0x62, 0xc8, 0x6a, 0x70, 0x54, 0x9d, 0x31, 0x8d, + 0x42, 0x24, 0xc2, 0xc3, 0x31, 0x3f, 0x90, 0x30, 0x35, 0x1a, 0x58, 0x67, 0x46, 0xa9, 0x6e, 0x86, + 0xe5, 0x70, 0xc4, 0x5b, 0xd2, 0xda, 0xc8, 0xd1, 0x12, 0x54, 0x37, 0xa7, 0x1a, 0xd9, 0xb0, 0xae, + 0x23, 0x3a, 0xbc, 0x89, 0x0f, 0xa5, 0xbd, 0x38, 0x5f, 0x11, 0x17, 0x80, 0x44, 0x09, 0x1e, 0x37, + 0x3e, 0x1a, 0x8a, 0xc1, 0x6f, 0x2b, 0x09, 0x9e, 0xac, 0x0a, 0xd6, 0x1a, 0xa2, 0x21, 0x6c, 0xe6, + 0x52, 0x26, 0x8e, 0x7d, 0x47, 0xca, 0xf3, 0x8c, 0xd1, 0xc6, 0xe3, 0xe0, 0x28, 0xa3, 0xd4, 0x30, + 0x28, 0xde, 0xd6, 0xb6, 0xc4, 0x28, 0x73, 0xf5, 0x70, 0x3e, 0x04, 0x0a, 0xa0, 0x96, 0x47, 0x9a, + 0x78, 0x23, 0x77, 0x25, 0x46, 0x59, 0xac, 0xcc, 0xbf, 0xf9, 0x18, 0x48, 0xf4, 0x7b, 0xb8, 0xae, + 0x65, 0x4f, 0xbc, 0xc5, 0x7b, 0xac, 0x45, 0xab, 0x88, 0x89, 0x49, 0xcd, 0x15, 0x81, 0x59, 0x4d, + 0xed, 0xd1, 0x0a, 0x3b, 0xed, 0x62, 0x87, 0xa7, 0xcd, 0x2e, 0x3f, 0x74, 0x8a, 0xcb, 0x68, 0x05, + 0xa6, 0xdb, 0x8c, 0x92, 0x31, 0x72, 0x54, 0xc1, 0xbc, 0x64, 0xfd, 0x5a, 0xcf, 0x61, 0x90, 0x05, + 0x55, 0x9b, 0xca, 0xdb, 0xa3, 0x0e, 0xe5, 0x3d, 0x0c, 0xaf, 0x8c, 0x25, 0x99, 0xd5, 0xcc, 0x9c, + 0xc9, 0x50, 0x42, 0xc7, 0x91, 0x38, 0xa1, 0x9b, 0xc0, 0x89, 0x20, 0x7d, 0x74, 0x77, 0x95, 0x91, + 0xbd, 0xd4, 0xd1, 0x5d, 0x96, 0xc8, 0x98, 0x30, 0x23, 0xb7, 0x2e, 0x8a, 0x56, 0x2b, 0x9b, 0x2f, + 0x44, 0x06, 0x4c, 0xd4, 0x07, 0x5d, 0x7e, 0x70, 0x47, 0x1f, 0x99, 0xe4, 0xb4, 0xc7, 0x5a, 0xa2, + 0x92, 0xd3, 0x1e, 0x23, 0x88, 0x17, 0xa1, 0x6f, 0xc7, 0x04, 0x91, 0x16, 0xac, 0x3b, 0x9a, 0x0d, + 0x17, 0x21, 0x98, 0xa4, 0xcf, 0x1c, 0x8f, 0x3d, 0x5b, 0x9f, 0x8e, 0xcb, 0x54, 0xd0, 0x2f, 0x70, + 0x64, 0x87, 0x21, 0xf1, 0x39, 0x13, 0xae, 0xe0, 0xb8, 0x6c, 0x3d, 0x1c, 0xbb, 0xce, 0xb4, 0x8d, + 0xfe, 0x57, 0x29, 0x3f, 0x61, 0x91, 0x1d, 0xee, 0x39, 0x65, 0xb8, 0x99, 0x8f, 0x6a, 0x36, 0xc4, + 0x70, 0xf3, 0x22, 0xad, 0x79, 0xee, 0x9d, 0xbc, 0xb4, 0x07, 0x84, 0x4f, 0x07, 0x51, 0xa4, 0x43, + 0xf4, 0xdc, 0x3b, 0x69, 0x36, 0x18, 0x37, 0x9e, 0xc4, 0x51, 0x01, 0x6d, 0xc3, 0x42, 0x14, 0x4c, + 0xef, 0x13, 0xb7, 0x43, 0x0e, 0xdd, 0xfe, 0x25, 0x23, 0xb9, 0x65, 0xac, 0x8a, 0xd1, 0x6d, 0x98, + 0xc7, 0xc4, 0x25, 0x5f, 0x25, 0x8a, 0xd3, 0x4c, 0x51, 0x91, 0x5a, 0x0f, 0x0b, 0x7c, 0x40, 0xc1, + 0x97, 0x7f, 0x97, 0x3d, 0xc4, 0xd3, 0x7c, 0xf9, 0x25, 0x98, 0xa2, 0x0a, 0x01, 0xff, 0xf6, 0x51, + 0x81, 0x0e, 0x56, 0xec, 0x4e, 0xd9, 0x6b, 0x4f, 0xe0, 0x44, 0x40, 0x67, 0x41, 0x96, 0x03, 0xeb, + 0x3e, 0xc8, 0x92, 0xee, 0x08, 0xd0, 0xfa, 0x5b, 0x09, 0xca, 0x42, 0x96, 0x0c, 0x7c, 0x97, 0x27, + 0x35, 0x44, 0x91, 0x02, 0xbe, 0x20, 0x97, 0xb4, 0x63, 0x13, 0xdb, 0x55, 0xcc, 0x9e, 0xd1, 0xbd, + 0xc8, 0xf2, 0xc0, 0xeb, 0x46, 0x5f, 0x63, 0xfe, 0xc1, 0xfc, 0x0e, 0xbb, 0x07, 0x22, 0xa4, 0x38, + 0xae, 0x47, 0x5b, 0x30, 0xeb, 0x04, 0xd8, 0x76, 0x7b, 0x8c, 0xd0, 0xb0, 0x8f, 0x54, 0xc6, 0x69, + 0x11, 0xba, 0x03, 0x33, 0xcf, 0xbc, 0x7e, 0x97, 0xf8, 0x81, 0x39, 0xc5, 0x72, 0x31, 0x73, 0x11, + 0xd8, 0x5b, 0xdb, 0xa1, 0x4c, 0x1a, 0x8b, 0x5a, 0xaa, 0x48, 0x65, 0x54, 0x71, 0x5a, 0xab, 0xc8, + 0x6b, 0xad, 0x2f, 0xb4, 0x89, 0x00, 0xfa, 0x2a, 0x75, 0xb7, 0x29, 0xc6, 0x9d, 0x3d, 0xa3, 0x9f, + 0x43, 0x55, 0xe8, 0xb5, 0x9c, 0x20, 0x64, 0xaf, 0x39, 0xfb, 0x60, 0x81, 0x7b, 0xbd, 0x18, 0x42, + 0x52, 0xb2, 0xae, 0x69, 0x0e, 0x42, 0xad, 0x33, 0x98, 0x3d, 0xbe, 0x70, 0xbf, 0xdb, 0x88, 0x62, + 0xef, 0xab, 0x78, 0x44, 0xe9, 0x33, 0xba, 0x0f, 0x33, 0x87, 0xc3, 0x90, 0xe5, 0xa3, 0xa2, 0x53, + 0xf0, 0xc5, 0x64, 0x40, 0x79, 0x05, 0x16, 0x1a, 0xd6, 0x7f, 0x96, 0x60, 0x86, 0x37, 0x8e, 0x3e, + 0x83, 0x72, 0xdd, 0x27, 0x76, 0x48, 0x1e, 0x87, 0xfc, 0x3e, 0xc6, 0xfa, 0x4e, 0x74, 0x3d, 0x66, + 0x47, 0x5c, 0x8f, 0x49, 0xdd, 0xca, 0x28, 0x53, 0x4f, 0xfd, 0x87, 0xff, 0xd9, 0x2c, 0xe1, 0xd8, + 0x0a, 0x6d, 0xc1, 0x24, 0x0d, 0x8e, 0xd8, 0xcc, 0x9b, 0x7d, 0x50, 0xdd, 0x09, 0x2f, 0xdc, 0x9d, + 0xe3, 0x0b, 0x97, 0xca, 0x30, 0xab, 0xa1, 0xaf, 0xf2, 0x3a, 0x20, 0xfe, 0xf1, 0x85, 0xcb, 0x3a, + 0x57, 0xc6, 0xa2, 0x88, 0x3e, 0x86, 0x0a, 0x1d, 0x73, 0xda, 0xcb, 0xc0, 0x9c, 0x64, 0x43, 0x87, + 0x44, 0xc6, 0x26, 0x19, 0x0b, 0x9c, 0x28, 0x59, 0x9f, 0xeb, 0xb2, 0x2a, 0xda, 0x2f, 0xf3, 0x31, + 0x1b, 0x4f, 0xe5, 0xc3, 0xcc, 0x27, 0xe8, 0x0c, 0x20, 0xad, 0x62, 0x2d, 0x6b, 0xcf, 0x95, 0xad, + 0x7f, 0x2f, 0x41, 0x25, 0x16, 0x52, 0x87, 0xf7, 0xd2, 0xeb, 0x92, 0xe3, 0xcb, 0x21, 0xe1, 0xcd, + 0xc5, 0x65, 0xba, 0xe5, 0xd0, 0xe7, 0x66, 0x97, 0x2f, 0x43, 0x5e, 0xa2, 0xeb, 0x90, 0x01, 0x30, + 0xa3, 0xc8, 0xfd, 0x24, 0x02, 0xda, 0xf9, 0xd7, 0x01, 0xe9, 0x72, 0xff, 0xc3, 0x9e, 0xa9, 0x6c, + 0xdf, 0x27, 0x51, 0x62, 0x6d, 0x12, 0xb3, 0x67, 0xda, 0xf2, 0x33, 0x27, 0xc4, 0x76, 0xe8, 0x78, + 0xcc, 0xc5, 0x5c, 0xc5, 0x71, 0xd9, 0x7a, 0xa9, 0xcf, 0x10, 0xa1, 0x47, 0x30, 0x17, 0x0b, 0xd9, + 0x30, 0x44, 0xd9, 0xca, 0x38, 0xa9, 0x18, 0x1b, 0xc8, 0x6a, 0x56, 0x1f, 0x36, 0x8a, 0x0e, 0x59, + 0xe9, 0x27, 0x7d, 0xea, 0x7b, 0xa3, 0x61, 0xec, 0x84, 0x45, 0xb1, 0xd8, 0x05, 0x8b, 0xbd, 0x70, + 0x42, 0xde, 0x0b, 0x1f, 0xc2, 0x8d, 0xc2, 0xc4, 0x86, 0x7c, 0xb3, 0x64, 0x4a, 0xdc, 0x2c, 0x79, + 0xce, 0x5e, 0x3a, 0x73, 0x6c, 0xfb, 0x43, 0x3a, 0x67, 0xdd, 0x87, 0x65, 0x6d, 0x1e, 0x84, 0x7e, + 0x09, 0x96, 0x33, 0xe1, 0x53, 0x8b, 0x3e, 0x5b, 0x6d, 0x58, 0xcd, 0x39, 0xe9, 0x45, 0x35, 0x80, + 0x86, 0x1d, 0xda, 0x27, 0x76, 0x40, 0xe2, 0x04, 0x6f, 0x4a, 0x52, 0xd0, 0x83, 0x4f, 0xc0, 0xcc, + 0x4b, 0xa1, 0x14, 0x6c, 0x0f, 0xfb, 0x50, 0x66, 0x5f, 0xee, 0x05, 0xb9, 0xa4, 0x5d, 0x3d, 0xb2, + 0xc3, 0x33, 0xd1, 0x55, 0xfa, 0x4c, 0xa7, 0xe4, 0xe1, 0xe9, 0x69, 0x40, 0xa2, 0xfb, 0x66, 0x13, + 0x98, 0x97, 0xd0, 0x3c, 0x5c, 0x6d, 0x7f, 0xcd, 0xf7, 0x84, 0xab, 0xed, 0xaf, 0xad, 0x47, 0x7c, + 0x8a, 0x32, 0xff, 0x7c, 0x17, 0x26, 0xcf, 0xa9, 0xcf, 0x2e, 0x49, 0xce, 0x4c, 0xd4, 0xf3, 0x78, + 0x8d, 0xa9, 0x58, 0xc7, 0x74, 0x9f, 0x64, 0xaf, 0x1e, 0x77, 0x63, 0x09, 0xa6, 0x9a, 0x6e, 0x97, + 0x5c, 0x88, 0x8f, 0xc5, 0x0a, 0xe8, 0x7e, 0xd2, 0x51, 0xee, 0x2a, 0x54, 0x5c, 0x1c, 0x2b, 0x58, + 0x6f, 0xb5, 0xa7, 0xe3, 0xe8, 0xb3, 0x4c, 0x63, 0xbc, 0x8b, 0x71, 0x7a, 0x4d, 0xae, 0xc5, 0xaa, + 0xba, 0x75, 0x08, 0x8b, 0x62, 0x50, 0x63, 0xf4, 0x9c, 0x0e, 0x1b, 0x30, 0xf1, 0xcc, 0x11, 0xd7, + 0xf4, 0xe8, 0x23, 0x1d, 0x5f, 0xaa, 0xcf, 0x63, 0x29, 0xf6, 0x6c, 0x7d, 0xa1, 0x4f, 0x65, 0xa1, + 0x7d, 0x4d, 0x43, 0xbc, 0xb3, 0x66, 0x92, 0x38, 0x90, 0xeb, 0x71, 0xd6, 0xc4, 0xc2, 0xda, 0x93, + 0x7d, 0xf4, 0x1b, 0xa8, 0xc6, 0xb2, 0x68, 0x18, 0xa2, 0x9c, 0x79, 0x72, 0x4b, 0x32, 0x5d, 0x8d, + 0x25, 0x65, 0xbe, 0x6e, 0xb2, 0x49, 0xaf, 0x07, 0x50, 0x89, 0x85, 0xf1, 0xe5, 0x3c, 0x0d, 0x22, + 0x4e, 0xd4, 0xac, 0x36, 0xcc, 0x1e, 0xf9, 0x64, 0x68, 0xfb, 0xa4, 0x1d, 0x0e, 0xd8, 0x10, 0xb1, + 0x18, 0x8b, 0x4f, 0x41, 0x16, 0x60, 0x19, 0x30, 0xd1, 0x7e, 0xd5, 0x12, 0x51, 0x69, 0xfb, 0x55, + 0x8b, 0x2e, 0x92, 0x23, 0xdb, 0xb7, 0x07, 0xd4, 0xfd, 0x05, 0x7c, 0x38, 0x53, 0x12, 0xab, 0x9f, + 0x77, 0x53, 0x80, 0x4e, 0x67, 0x2a, 0x8a, 0x57, 0x36, 0x2f, 0xa1, 0x4f, 0xe2, 0xeb, 0x7f, 0xd1, + 0xa9, 0xc9, 0x86, 0x3e, 0x89, 0x16, 0xe9, 0x88, 0xcb, 0x81, 0xcf, 0x27, 0xcb, 0x13, 0xc6, 0xa4, + 0xf5, 0x2f, 0x33, 0xb9, 0x29, 0x39, 0xba, 0x4c, 0x1a, 0x7b, 0xfc, 0x6d, 0xae, 0x36, 0xf6, 0xd0, + 0x23, 0xa8, 0xa6, 0x5e, 0x37, 0xe0, 0xbb, 0x8a, 0xd8, 0xb3, 0x52, 0x55, 0x58, 0xd2, 0x43, 0xf7, + 0xc0, 0x68, 0xd9, 0x41, 0xf8, 0xf8, 0xf4, 0x94, 0x74, 0x42, 0xd2, 0x65, 0xfb, 0x77, 0xb4, 0xf8, + 0x32, 0x72, 0xf4, 0x29, 0xcc, 0xd3, 0xfd, 0xb1, 0x45, 0xde, 0x93, 0x7e, 0x7a, 0x67, 0x5c, 0x12, + 0x89, 0xd6, 0x74, 0x25, 0x56, 0x74, 0x51, 0x03, 0x6e, 0xc8, 0x0a, 0xa4, 0x4f, 0xec, 0x80, 0xb4, + 0x47, 0xc3, 0xa1, 0xe7, 0x87, 0xa4, 0xcb, 0xc3, 0xd8, 0x62, 0x25, 0xb4, 0x0f, 0x0b, 0x54, 0xa1, + 0x41, 0x4e, 0x1d, 0x97, 0x74, 0xdf, 0xd8, 0x71, 0xc8, 0xa4, 0x0c, 0xac, 0xac, 0x84, 0x55, 0x23, + 0xf4, 0x4b, 0x58, 0x55, 0x44, 0x4f, 0x2e, 0x78, 0x3f, 0x66, 0x58, 0x3f, 0xf2, 0xaa, 0x69, 0x0f, + 0xda, 0x97, 0x41, 0x48, 0x06, 0x6f, 0x6c, 0xdf, 0xa1, 0xce, 0x30, 0x30, 0xcb, 0xba, 0x1e, 0xc8, + 0x4a, 0x58, 0x35, 0xa2, 0x3d, 0x50, 0x44, 0x71, 0x0f, 0x2a, 0x51, 0x0f, 0x72, 0xaa, 0xd1, 0xa7, + 0xb0, 0xa6, 0x74, 0x0e, 0x93, 0x61, 0xdf, 0xbe, 0x64, 0xb9, 0x6f, 0x60, 0xb6, 0xf9, 0x0a, 0xd4, + 0x5a, 0x01, 0x4e, 0x59, 0xcf, 0x46, 0xd6, 0xb9, 0x0a, 0xe8, 0x19, 0x6c, 0x2a, 0x95, 0x6d, 0xd7, + 0x1e, 0x06, 0x67, 0x5e, 0x78, 0xec, 0x79, 0x2d, 0xdb, 0xef, 0x11, 0x76, 0xf6, 0x52, 0xc6, 0xe3, + 0xd4, 0x28, 0x92, 0xd2, 0xc9, 0x0c, 0xd2, 0x5c, 0x84, 0x34, 0x46, 0x0d, 0x7d, 0x06, 0xd7, 0xf9, + 0x9c, 0xee, 0xd2, 0x49, 0xdd, 0xf2, 0xdc, 0x1e, 0x75, 0x51, 0xf5, 0x33, 0xd2, 0x39, 0x27, 0x5d, + 0x76, 0xee, 0x52, 0xc6, 0x45, 0x2a, 0x34, 0x0e, 0xda, 0xf7, 0x46, 0x6e, 0x34, 0xfd, 0x17, 0xa2, + 0xc3, 0xcf, 0x58, 0x60, 0xfd, 0x71, 0x4a, 0x7f, 0x93, 0x27, 0x77, 0xd1, 0x47, 0x8b, 0xf3, 0x6a, + 0xbc, 0x38, 0xb7, 0x60, 0xb6, 0x4d, 0xc2, 0x37, 0xb6, 0x1f, 0xad, 0xcd, 0x09, 0x46, 0x47, 0xd3, + 0xa2, 0xcc, 0xf2, 0x9d, 0xfc, 0x11, 0xcb, 0x77, 0xea, 0x3b, 0x2f, 0xdf, 0xe9, 0xef, 0xb1, 0x7c, + 0x35, 0x0b, 0x6f, 0xe6, 0x27, 0x5e, 0x78, 0xe5, 0xef, 0xbd, 0xf0, 0x2a, 0x3f, 0xf1, 0xc2, 0x83, + 0x1f, 0xb1, 0xf0, 0x66, 0x7f, 0xd4, 0xc2, 0xab, 0x8e, 0x5b, 0x78, 0xd2, 0x14, 0x9d, 0x53, 0xa7, + 0xe8, 0x9f, 0x4b, 0xf1, 0x19, 0x8b, 0xdc, 0x01, 0xed, 0xc6, 0xb7, 0x05, 0x53, 0x6f, 0xec, 0xfe, + 0x88, 0xf0, 0x78, 0x07, 0x76, 0xd8, 0x5f, 0x16, 0x9e, 0x5c, 0x0c, 0x7d, 0x1c, 0x55, 0xb0, 0xad, + 0xf1, 0xcb, 0x3e, 0xa7, 0x04, 0xf4, 0x91, 0xc5, 0x22, 0xc1, 0x9e, 0xe3, 0x72, 0xa2, 0x1b, 0x15, + 0xe8, 0xfc, 0xe3, 0xf3, 0x91, 0xed, 0x92, 0x2f, 0x68, 0x40, 0x3a, 0xc5, 0xd6, 0x42, 0x46, 0x8e, + 0x6a, 0x30, 0xc9, 0x78, 0xc6, 0x74, 0xba, 0x51, 0x2a, 0xc1, 0x4c, 0x6e, 0xbd, 0x82, 0x39, 0x69, + 0xce, 0x69, 0xbb, 0x1e, 0x07, 0xdc, 0x51, 0x90, 0x1a, 0x15, 0xd8, 0xff, 0x1a, 0x2e, 0xdc, 0x66, + 0x23, 0x5a, 0x5b, 0x55, 0xcc, 0x4b, 0xd6, 0x3f, 0xe4, 0x9c, 0x3c, 0x15, 0xc4, 0xad, 0xbf, 0x81, + 0xcd, 0x31, 0xb7, 0xe7, 0xd2, 0xa1, 0x72, 0x49, 0x0e, 0x95, 0x2d, 0xd8, 0x1a, 0x77, 0xdc, 0x64, + 0x6d, 0xb3, 0x4b, 0x8c, 0x9a, 0xeb, 0x6f, 0xd4, 0x6d, 0xd4, 0x5f, 0x8a, 0x3d, 0xbd, 0xfe, 0x92, + 0xdf, 0x68, 0xd7, 0x1d, 0x0c, 0xe5, 0xdc, 0x68, 0xff, 0x48, 0x7b, 0x51, 0x2e, 0xcf, 0x4d, 0x59, + 0x47, 0xfa, 0x63, 0xa4, 0xfc, 0xc1, 0xa1, 0xf1, 0xd1, 0xe3, 0x51, 0x78, 0xd6, 0x0e, 0x7d, 0xc7, + 0x8d, 0xd2, 0x79, 0x55, 0x9c, 0x92, 0x58, 0xbb, 0x9a, 0xbb, 0x75, 0x94, 0x1e, 0x0a, 0x91, 0xb8, + 0xf9, 0x2f, 0xca, 0xd6, 0xc7, 0xba, 0x83, 0xa7, 0x42, 0x8b, 0x5f, 0x69, 0x2e, 0xdc, 0xa1, 0x5b, + 0x30, 0x27, 0x44, 0x7b, 0x97, 0x21, 0x09, 0xf8, 0xb0, 0xc8, 0x42, 0xeb, 0xd7, 0xba, 0x43, 0xa9, + 0xef, 0x68, 0x7b, 0x96, 0x7b, 0x33, 0x0f, 0xed, 0xf2, 0x79, 0x5d, 0x62, 0x01, 0xde, 0xf5, 0x9c, + 0xe3, 0xa1, 0x64, 0xa2, 0xc7, 0xac, 0xbb, 0xed, 0x7c, 0x4d, 0x38, 0xfb, 0x49, 0x04, 0xd6, 0x45, + 0xfe, 0x49, 0x97, 0x6c, 0x59, 0x52, 0x2c, 0xe9, 0x9b, 0xb0, 0x42, 0xdd, 0x1e, 0xda, 0x1d, 0x27, + 0xbc, 0xe4, 0xd8, 0xb2, 0x90, 0x7e, 0xdd, 0x03, 0x12, 0x04, 0x76, 0x2f, 0x4e, 0x38, 0xf2, 0xa2, + 0x75, 0x58, 0x7c, 0x3b, 0xf0, 0x7b, 0xbf, 0xa8, 0xf5, 0xcf, 0x63, 0x4e, 0xd4, 0xfe, 0xce, 0xef, + 0xf3, 0x89, 0xfe, 0xfa, 0x61, 0x71, 0xab, 0xd6, 0x3f, 0xe6, 0x1c, 0xca, 0x65, 0xbb, 0x53, 0xd2, + 0x74, 0xc7, 0xfa, 0xbf, 0xd2, 0x98, 0x8b, 0x67, 0x63, 0x32, 0xc5, 0xac, 0x73, 0xa1, 0xdd, 0xf7, + 0x7a, 0x31, 0x13, 0x4f, 0x04, 0xb4, 0x96, 0xba, 0x41, 0x76, 0x20, 0x25, 0x12, 0x36, 0xb1, 0x80, + 0x7a, 0x85, 0xe8, 0x02, 0xc4, 0x64, 0x94, 0x6c, 0x8d, 0x2e, 0x35, 0xd4, 0x00, 0x44, 0xc8, 0xd4, + 0x6c, 0xf0, 0xe8, 0x20, 0x25, 0x41, 0x0f, 0x92, 0x61, 0x6a, 0x79, 0x1d, 0x9b, 0x12, 0x90, 0x67, + 0x76, 0x70, 0xc6, 0xfc, 0x74, 0x05, 0x6b, 0xeb, 0xe8, 0x0a, 0x8d, 0xae, 0xcf, 0x34, 0x1b, 0x2c, + 0x5e, 0xae, 0xe0, 0xb8, 0x6c, 0x3d, 0x1b, 0x77, 0xe6, 0x13, 0x65, 0xa6, 0x07, 0xde, 0x7b, 0xd2, + 0x7d, 0xe2, 0x86, 0xbe, 0x13, 0xaf, 0x39, 0x45, 0x6a, 0xed, 0xe8, 0x2e, 0x7a, 0xd2, 0x0f, 0xce, + 0x25, 0xdc, 0x39, 0x88, 0xa2, 0xb5, 0xab, 0x3d, 0xf5, 0x2c, 0x30, 0x68, 0xe9, 0x2e, 0x7e, 0x52, + 0x7f, 0xc9, 0x6f, 0xba, 0xf1, 0xff, 0x1e, 0xf1, 0x4b, 0x6d, 0x82, 0x1d, 0x12, 0x96, 0xa9, 0x8d, + 0xc2, 0xbb, 0x94, 0xc4, 0xba, 0xab, 0x3d, 0x20, 0xd5, 0x66, 0xae, 0xef, 0xe5, 0x5d, 0x13, 0xcd, + 0xa6, 0xd0, 0xad, 0x8f, 0x72, 0x4f, 0x4a, 0xb5, 0xd0, 0x83, 0x82, 0x4b, 0xa2, 0x68, 0x1b, 0x16, + 0xf8, 0x5f, 0xd6, 0xe2, 0xf4, 0x7b, 0xb4, 0x85, 0xa9, 0x62, 0xfa, 0x8d, 0xde, 0xfa, 0x4e, 0x98, + 0x40, 0xf0, 0xc9, 0xa8, 0x48, 0x2d, 0xb7, 0xe8, 0x9c, 0xf5, 0xef, 0xd0, 0xde, 0x1b, 0xfd, 0xa1, + 0x2b, 0xfa, 0x27, 0xa8, 0xa6, 0xe5, 0xdf, 0xe1, 0x3f, 0x7c, 0x92, 0xbe, 0xf5, 0xaf, 0xa5, 0xa2, + 0xeb, 0x9b, 0x63, 0x16, 0xad, 0x05, 0x55, 0xba, 0xa7, 0x12, 0xc6, 0xde, 0xe3, 0x75, 0x2b, 0xc9, + 0x68, 0xa8, 0xc4, 0xd3, 0x8a, 0x4f, 0x2e, 0x3a, 0xfd, 0x51, 0xe0, 0xbc, 0x27, 0x3c, 0xdd, 0x98, + 0x91, 0x5b, 0xbf, 0x28, 0x3c, 0xc1, 0x2c, 0x88, 0x5e, 0xfe, 0x23, 0x89, 0x03, 0xe5, 0x50, 0xf2, + 0x07, 0xc6, 0x81, 0xdb, 0xb0, 0xf0, 0x92, 0x5c, 0x84, 0xc7, 0xbe, 0xed, 0x06, 0x76, 0x94, 0xc7, + 0x88, 0x32, 0xe5, 0xaa, 0x18, 0xed, 0x40, 0x15, 0x8f, 0x5c, 0x3a, 0xda, 0x11, 0xe4, 0x64, 0x06, + 0x52, 0xaa, 0xbf, 0xf7, 0xa7, 0xe9, 0xd4, 0x95, 0x52, 0x54, 0xe1, 0x7f, 0x64, 0x35, 0xae, 0xa0, + 0x6b, 0xb0, 0xa0, 0xdc, 0xf2, 0x34, 0x4a, 0xc8, 0x80, 0x6a, 0xfa, 0x6c, 0xd4, 0xb8, 0x8a, 0xaa, + 0x50, 0x16, 0xc7, 0x94, 0xc6, 0x04, 0x9a, 0x83, 0x4a, 0x7c, 0x64, 0x64, 0x4c, 0xa2, 0x05, 0x98, + 0x4d, 0x9d, 0x93, 0x18, 0x53, 0x68, 0x1e, 0x20, 0xc9, 0xce, 0x1b, 0xd3, 0x14, 0x2f, 0x9d, 0x96, + 0x36, 0x66, 0xa8, 0x46, 0x72, 0x99, 0xd0, 0x28, 0x53, 0xc4, 0xf8, 0x8e, 0xa0, 0x51, 0x41, 0x2b, + 0xba, 0x5b, 0x82, 0x06, 0x50, 0x79, 0xf6, 0xb6, 0x9e, 0x31, 0x8b, 0x90, 0x7a, 0x5f, 0xcf, 0xa8, + 0xa2, 0xd9, 0xf8, 0xf2, 0x9d, 0x31, 0x87, 0xd6, 0x72, 0xee, 0xd5, 0x19, 0xf3, 0x68, 0x51, 0xb9, + 0x16, 0x67, 0x2c, 0xa0, 0xa5, 0xec, 0x2d, 0x37, 0xc3, 0x48, 0xbf, 0x05, 0x65, 0xb3, 0xc6, 0x22, + 0x97, 0xc4, 0x59, 0x30, 0x03, 0xd1, 0xe1, 0x54, 0x6e, 0x7c, 0x19, 0xd7, 0xa8, 0x50, 0x49, 0x2c, + 0x19, 0x4b, 0xb4, 0x59, 0x29, 0x58, 0x36, 0x96, 0xd1, 0x46, 0xfe, 0x2d, 0x2b, 0x63, 0x85, 0x0e, + 0x51, 0x7c, 0x5a, 0x6b, 0xac, 0xf2, 0x96, 0xd2, 0xe1, 0xaa, 0x61, 0xd2, 0x0e, 0xa5, 0x63, 0x4c, + 0x63, 0x8d, 0x7d, 0x8a, 0xc3, 0x83, 0xc7, 0xef, 0x8e, 0xf0, 0x61, 0xbd, 0x6d, 0xac, 0xf3, 0xf2, + 0x93, 0x83, 0x56, 0xf3, 0xa0, 0x79, 0x6c, 0x5c, 0xa7, 0xaf, 0xaa, 0x06, 0x0d, 0xc6, 0x06, 0x1d, + 0x2e, 0x6d, 0x28, 0x61, 0xdc, 0x60, 0xfd, 0x4e, 0x6f, 0xd8, 0x46, 0x8d, 0x7d, 0xff, 0xc3, 0x78, + 0x23, 0x30, 0x36, 0xa9, 0x20, 0xe5, 0x9a, 0x8d, 0x2d, 0xda, 0x59, 0xc5, 0xa9, 0x1a, 0x37, 0xe9, + 0xc7, 0xcc, 0xfa, 0x32, 0xc3, 0xa2, 0x2f, 0x91, 0xf6, 0x15, 0xc6, 0x07, 0xe8, 0x3a, 0xf3, 0xc9, + 0xba, 0x13, 0x64, 0xe3, 0x16, 0x5a, 0x86, 0xc5, 0xcc, 0x81, 0xaa, 0xf1, 0x21, 0x5a, 0x87, 0x15, + 0xfd, 0xbe, 0x68, 0xdc, 0x46, 0xab, 0x70, 0x4d, 0xb3, 0xe0, 0x8d, 0x3b, 0xb4, 0xe9, 0x64, 0x5a, + 0xbe, 0x79, 0x60, 0x6c, 0xdf, 0xfb, 0xb7, 0x92, 0x44, 0x6a, 0x92, 0xec, 0x21, 0x1d, 0x23, 0xa5, + 0x22, 0x62, 0xae, 0xc6, 0x15, 0x74, 0x1f, 0xee, 0x28, 0x55, 0xed, 0x73, 0x67, 0xa8, 0x4b, 0xb5, + 0x19, 0x25, 0xf4, 0x11, 0xdc, 0x55, 0x71, 0x5c, 0x3a, 0x4c, 0x5a, 0xf5, 0xab, 0xf7, 0x7e, 0x06, + 0x4b, 0xba, 0x18, 0x10, 0x01, 0xdd, 0x46, 0x07, 0x1e, 0x5b, 0xd4, 0x65, 0x98, 0x6c, 0x38, 0xc1, + 0xb9, 0x51, 0xda, 0x6b, 0xfd, 0xe5, 0x9b, 0x5a, 0xe9, 0xaf, 0xdf, 0xd4, 0x4a, 0xff, 0xfb, 0x4d, + 0xed, 0xca, 0x1f, 0xbe, 0xad, 0x5d, 0xf9, 0xe3, 0xb7, 0xb5, 0xd2, 0x5f, 0xbf, 0xad, 0x5d, 0xf9, + 0xdb, 0xb7, 0xb5, 0x2b, 0x9f, 0xef, 0xa4, 0xfe, 0x30, 0x3f, 0xb0, 0x43, 0xdf, 0xb9, 0xf0, 0x7c, + 0xa7, 0xe7, 0xb8, 0xa2, 0xe0, 0x92, 0xdd, 0xe1, 0x79, 0x6f, 0x77, 0x78, 0xb2, 0xcb, 0x82, 0xcf, + 0x93, 0x69, 0x76, 0x16, 0xf8, 0xf3, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x21, 0xf5, 0x90, 0x5c, + 0xd0, 0x3f, 0x00, 0x00, } func (m *QueryRequest) Marshal() (dAtA []byte, err error) { diff --git a/pkg/queryservice/client/query_client.go b/pkg/queryservice/client/query_client.go index 9196d8816f8f1..e185a813c6549 100644 --- a/pkg/queryservice/client/query_client.go +++ b/pkg/queryservice/client/query_client.go @@ -63,6 +63,7 @@ var methodVersions = map[pb.CmdMethod]int64{ pb.CmdMethod_ISCPDrainConsumer: defines.MORPCVersion4, pb.CmdMethod_IcebergCacheInvalidate: defines.MORPCVersion4, pb.CmdMethod_MongoDBClientRetire: defines.MORPCVersion5, + pb.CmdMethod_SyncCommitV2: defines.MORPCVersion32, } type queryClient struct { diff --git a/pkg/queryservice/client/query_client_test.go b/pkg/queryservice/client/query_client_test.go index b119e07d7ec9c..baa3053a30798 100644 --- a/pkg/queryservice/client/query_client_test.go +++ b/pkg/queryservice/client/query_client_test.go @@ -15,10 +15,12 @@ package client import ( + "context" "testing" "github.com/matrixorigin/matrixone/pkg/common/moerr" "github.com/matrixorigin/matrixone/pkg/common/morpc" + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" "github.com/matrixorigin/matrixone/pkg/defines" "github.com/matrixorigin/matrixone/pkg/pb/query" "github.com/stretchr/testify/assert" @@ -34,6 +36,19 @@ func TestMongoDBClientRetireRequiresProtocolVersion5(t *testing.T) { assert.Equal(t, defines.MORPCVersion5, methodVersions[query.CmdMethod_MongoDBClientRetire]) } +func TestSyncCommitV2RequiresProtocolVersion32(t *testing.T) { + assert.Equal(t, defines.MORPCVersion32, methodVersions[query.CmdMethod_SyncCommitV2]) + + const serviceID = "sync-commit-v2-version-test" + rt := moruntime.DefaultRuntime() + moruntime.SetupServiceBasedRuntime(serviceID, rt) + req := &query.Request{CmdMethod: query.CmdMethod_SyncCommitV2} + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion31) + assert.Error(t, checkMethodVersion(context.Background(), serviceID, req)) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion32) + assert.NoError(t, checkMethodVersion(context.Background(), serviceID, req)) +} + func TestNewCacheClient(t *testing.T) { ct := testCreateQueryClient(t) assert.NotNil(t, ct) diff --git a/proto/logservice.proto b/proto/logservice.proto index 9174ee41784a1..35e34933ddd74 100644 --- a/proto/logservice.proto +++ b/proto/logservice.proto @@ -61,6 +61,9 @@ message CNStore { uint64 ViewMetadataAdmissionGeneration = 18; uint64 ViewMetadataObservedEpoch = 19; bool ViewMetadataAdmissionReady = 20; + // DDLVisibilityBarrierReady means QueryService can accept the versioned DDL + // visibility fence even when public SQL ingress is not admitted yet. + bool DDLVisibilityBarrierReady = 21; } message TNStore { @@ -164,6 +167,7 @@ message CNStoreHeartbeat { // ViewMetadataIngressReady is published only after every public CN ingress // listener has started successfully. Admission alone is not routability. bool ViewMetadataIngressReady = 24; + bool DDLVisibilityBarrierReady = 25; } // CNAllocateID is the periodic message sent tp the HAKeeper by CN stores. @@ -687,6 +691,7 @@ message CNStoreInfo { uint64 ViewMetadataRevalidatedEpoch = 24; bool ViewMetadataAdmissionReady = 25; bool ViewMetadataIngressReady = 26; + bool DDLVisibilityBarrierReady = 27; } // CNState contains all CN details known to the HAKeeper. diff --git a/proto/metadata.proto b/proto/metadata.proto index 465382f0dda6d..1c435c5929aab 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -139,6 +139,9 @@ message CNService { uint64 ViewMetadataAdmissionGeneration = 13; bool ViewMetadataAdmissionReady = 14; uint64 ViewMetadataObservedEpoch = 15; + // DDLVisibilityBarrierReady is published after QueryService is listening. + // A CN is not publicly routable until its startup DDL frontier fence completes. + bool DDLVisibilityBarrierReady = 16; } // TNService tn service metadata diff --git a/proto/query.proto b/proto/query.proto index 67b3b1b0919e7..26e040bc4e4a2 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -108,6 +108,9 @@ enum CmdMethod { IcebergCacheInvalidate = 38; // MongoDBClientRetire drains obsolete MongoDB driver clients after catalog DDL. MongoDBClientRetire = 39; + // SyncCommitV2 waits for local logtail application with the request context. + // Unlike legacy SyncCommit, cancellation is returned to the sender. + SyncCommitV2 = 40; } // QueryRequest is the common query request. It contains the query From 7d6b81249a48e3ce585f79bf5fa4c8a27bb29791 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Thu, 27 Aug 2026 23:27:22 +0800 Subject: [PATCH 03/34] fix: withdraw DDL barrier before CN shutdown --- pkg/cnservice/server.go | 4 + pkg/cnservice/server_ddl_visibility.go | 107 ++++++++++- pkg/cnservice/server_ddl_visibility_test.go | 191 +++++++++++++++++++- pkg/cnservice/server_heartbeat.go | 22 ++- 4 files changed, 304 insertions(+), 20 deletions(-) diff --git a/pkg/cnservice/server.go b/pkg/cnservice/server.go index 2f7237d6ac8c6..9f5d580b75927 100644 --- a/pkg/cnservice/server.go +++ b/pkg/cnservice/server.go @@ -511,9 +511,13 @@ func (s *service) closeService() error { defer logutil.LogClose(s.logger, "cnservice")() s.closeViewMetadataAdmission() + // Stop periodic heartbeats before publishing the final false readiness. + // QueryService remains available until the authoritative inventory has + // observed the withdrawal, so healthy CNs cannot target a closed barrier. s.stopper.Stop() s.closeErr = closeCNServiceSteps( + s.withdrawDDLVisibilityBarrier, // Query commands can reach frontend, task, engine, lock, shard, // auto-increment, and transaction state. Stop and drain this remote // ingress before clearing any of those dependencies. diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index c25acf311a8f8..45958ff427239 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -38,20 +38,21 @@ func ddlVisibilityBarrierSupported(serviceID string) bool { // frontier held by the already-published barrier participants before public // SQL ingress can be admitted. func (s *service) prepareDDLVisibilityBarrier() error { + supported := ddlVisibilityBarrierSupported(s.cfg.UUID) + if supported && (s.moCluster == nil || s.queryClient == nil || s._txnClient == nil) { + // Focused service tests may construct only the dependencies relevant to + // their lifecycle assertion. Production NewService initializes a non-zero + // admission generation together with all three barrier dependencies. + if s.viewMetadataAdmissionGeneration != 0 { + return moerr.NewInternalErrorNoCtx("DDL visibility barrier dependencies are unavailable") + } + } + s.ddlVisibilityBarrierReady.Store(true) s.notifyHeartbeat() - if !ddlVisibilityBarrierSupported(s.cfg.UUID) { + if !supported || s.moCluster == nil || s.queryClient == nil || s._txnClient == nil { return nil } - // Focused service tests may construct only the dependencies relevant to - // their lifecycle assertion. Production NewService initializes a non-zero - // admission generation together with all three barrier dependencies. - if s.moCluster == nil || s.queryClient == nil || s._txnClient == nil { - if s.viewMetadataAdmissionGeneration == 0 { - return nil - } - return moerr.NewInternalErrorNoCtx("DDL visibility barrier dependencies are unavailable") - } timeout := s.cfg.HAKeeper.DiscoveryTimeout.Duration if timeout <= 0 { @@ -70,6 +71,92 @@ func (s *service) prepareDDLVisibilityBarrier() error { return s.syncStartupDDLVisibilityFrontier(ctx) } +// withdrawDDLVisibilityBarrier closes both externally published gates before +// QueryService is stopped. closeService invokes it only after the periodic +// heartbeat task has terminated, so no previously captured ready heartbeat can +// overwrite this final withdrawal. +func (s *service) withdrawDDLVisibilityBarrier() error { + ingressWasReady := s.viewMetadataIngressReady.Swap(false) + barrierWasReady := s.ddlVisibilityBarrierReady.Swap(false) + if !ingressWasReady && !barrierWasReady { + return nil + } + if s.viewMetadataAdmissionGeneration == 0 { + return nil + } + if s.cfg == nil || s._hakeeperClient == nil || s.moCluster == nil || s.config == nil { + return moerr.NewInternalErrorNoCtx("DDL visibility barrier withdrawal dependencies are unavailable") + } + + timeout := s.cfg.HAKeeper.DiscoveryTimeout.Duration + if timeout <= 0 { + timeout = 30 * time.Second + } + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + if _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { + return moerr.AttachCause(ctx, err) + } + retryInterval := s.cfg.HAKeeper.HeatbeatInterval.Duration + if retryInterval < minClusterReadinessRetryInterval { + retryInterval = minClusterReadinessRetryInterval + } + return s.waitForDDLVisibilityBarrierWithdrawal(ctx, retryInterval) +} + +func (s *service) waitForDDLVisibilityBarrierWithdrawal( + ctx context.Context, + retryInterval time.Duration, +) error { + refresher, ok := s.moCluster.(clusterservice.AuthoritativeRefresher) + if !ok { + return moerr.NewInternalErrorNoCtx( + "CN cluster service does not support authoritative DDL visibility refresh") + } + + for { + if err := refresher.Refresh(ctx); err == nil { + withdrawn := true + err = clusterservice.GetCNServiceRawWithContext( + ctx, + s.moCluster, + clusterservice.NewServiceIDSelector(s.cfg.UUID), + func(cn metadata.CNService) bool { + if cn.ViewMetadataAdmissionGeneration < s.viewMetadataAdmissionGeneration || + (cn.ViewMetadataAdmissionGeneration == s.viewMetadataAdmissionGeneration && + cn.DDLVisibilityBarrierReady) { + withdrawn = false + } + return false + }) + if err != nil { + return err + } + if withdrawn { + return nil + } + } + + timer := time.NewTimer(retryInterval) + select { + case <-ctx.Done(): + if !timer.Stop() { + select { + case <-timer.C: + default: + } + } + return moerr.NewInternalErrorf( + context.Background(), + "CN %s DDL visibility barrier was not withdrawn before shutdown deadline: %v", + s.cfg.UUID, + ctx.Err()) + case <-timer.C: + } + } +} + func (s *service) waitForDDLVisibilityBarrierPublication( ctx context.Context, retryInterval time.Duration, diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index cb781540a8327..f917be8842978 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -16,24 +16,33 @@ package cnservice import ( "context" + "errors" "testing" "time" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/zap" "github.com/matrixorigin/matrixone/pkg/clusterservice" moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/common/stopper" "github.com/matrixorigin/matrixone/pkg/defines" mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test" + "github.com/matrixorigin/matrixone/pkg/gossip" + "github.com/matrixorigin/matrixone/pkg/lockservice" + "github.com/matrixorigin/matrixone/pkg/logservice" + logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" "github.com/matrixorigin/matrixone/pkg/pb/metadata" "github.com/matrixorigin/matrixone/pkg/pb/query" "github.com/matrixorigin/matrixone/pkg/pb/timestamp" + "github.com/matrixorigin/matrixone/pkg/util" ) type ddlVisibilityTestCluster struct { cnServices []metadata.CNService refreshCalls int + refreshHook func() } func (c *ddlVisibilityTestCluster) GetCNService( @@ -72,6 +81,9 @@ func (c *ddlVisibilityTestCluster) forEachCN( func (*ddlVisibilityTestCluster) ForceRefresh(bool) {} func (c *ddlVisibilityTestCluster) Refresh(context.Context) error { c.refreshCalls++ + if c.refreshHook != nil { + c.refreshHook() + } return nil } func (*ddlVisibilityTestCluster) Close() {} @@ -109,6 +121,110 @@ func (*ddlVisibilityTestQueryClient) NewRequest(method query.CmdMethod) *query.R func (c *ddlVisibilityTestQueryClient) Release(*query.Response) { c.releases++ } func (*ddlVisibilityTestQueryClient) Close() error { return nil } +type ddlVisibilityWithdrawalHAKeeperClient struct { + logservice.CNHAKeeperClient + cluster *ddlVisibilityTestCluster + queryClosed <-chan struct{} + sendErr error + heartbeats []logservicepb.CNStoreHeartbeat + queryClosedBeforeSend bool + closeCalls int +} + +func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( + _ context.Context, + hb logservicepb.CNStoreHeartbeat, +) (logservicepb.CommandBatch, error) { + select { + case <-c.queryClosed: + c.queryClosedBeforeSend = true + default: + } + c.heartbeats = append(c.heartbeats, hb) + if c.sendErr != nil { + return logservicepb.CommandBatch{}, c.sendErr + } + for i := range c.cluster.cnServices { + cn := &c.cluster.cnServices[i] + if cn.ServiceID == hb.UUID { + cn.ViewMetadataAdmissionGeneration = hb.ViewMetadataAdmissionGeneration + cn.DDLVisibilityBarrierReady = hb.DDLVisibilityBarrierReady + } + } + return logservicepb.CommandBatch{}, nil +} + +func (c *ddlVisibilityWithdrawalHAKeeperClient) Close() error { + c.closeCalls++ + return nil +} + +type ddlVisibilityCloseLockService struct { + lockservice.LockService + closeCalls int +} + +func (s *ddlVisibilityCloseLockService) Close() error { + s.closeCalls++ + return nil +} + +type ddlVisibilityCloseTestState struct { + service *service + hakeeperClient *ddlVisibilityWithdrawalHAKeeperClient + queryService *closeRecordingQueryService + lockService *ddlVisibilityCloseLockService + cluster *ddlVisibilityTestCluster + queryClosedBeforeRefresh bool +} + +func newDDLVisibilityCloseTestService(t *testing.T, sendErr error) *ddlVisibilityCloseTestState { + t.Helper() + const generation = uint64(7) + moruntime.SetupServiceBasedRuntime(t.Name(), moruntime.DefaultRuntime()) + gossipNode, err := gossip.NewNode(context.Background(), t.Name()) + require.NoError(t, err) + cfg := &Config{UUID: t.Name()} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + state := &ddlVisibilityCloseTestState{ + queryService: &closeRecordingQueryService{closed: make(chan struct{})}, + lockService: &ddlVisibilityCloseLockService{}, + cluster: &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: t.Name(), QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + }}}, + } + state.cluster.refreshHook = func() { + select { + case <-state.queryService.closed: + state.queryClosedBeforeRefresh = true + default: + } + } + state.hakeeperClient = &ddlVisibilityWithdrawalHAKeeperClient{ + cluster: state.cluster, queryClosed: state.queryService.closed, sendErr: sendErr, + } + state.service = &service{ + cfg: cfg, + logger: zap.NewNop(), + stopper: stopper.NewStopper("ddl-visibility-close-test"), + _hakeeperClient: state.hakeeperClient, + moCluster: state.cluster, + queryService: state.queryService, + mo: closeErrorMOServer{}, + cancelMoServerFunc: func() {}, + server: closeOnlyRPCServer{}, + lockService: state.lockService, + gossipNode: gossipNode, + config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: generation, + } + state.service.viewMetadataIngressReady.Store(true) + state.service.ddlVisibilityBarrierReady.Store(true) + return state +} + func TestPrepareDDLVisibilityBarrier(t *testing.T) { const serviceID = "ddl-visibility-startup-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) @@ -160,7 +276,7 @@ func TestPrepareDDLVisibilityBarrierRejectsMissingProductionDependencies(t *test err := s.prepareDDLVisibilityBarrier() require.ErrorContains(t, err, "dependencies are unavailable") - require.True(t, s.ddlVisibilityBarrierReady.Load()) + require.False(t, s.ddlVisibilityBarrierReady.Load()) } func TestPrepareDDLVisibilityBarrierSkipsFrontierSyncDuringRollingUpgrade(t *testing.T) { @@ -189,6 +305,79 @@ func TestWaitForDDLVisibilityBarrierPublicationHonorsCancellation(t *testing.T) require.Equal(t, 1, cluster.refreshCalls) } +func TestServiceCloseWithdrawsDDLVisibilityBeforeQueryService(t *testing.T) { + state := newDDLVisibilityCloseTestService(t, nil) + + require.NoError(t, state.service.Close()) + require.False(t, state.hakeeperClient.queryClosedBeforeSend) + require.False(t, state.queryClosedBeforeRefresh) + require.Len(t, state.hakeeperClient.heartbeats, 1) + require.False(t, state.hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) + require.False(t, state.hakeeperClient.heartbeats[0].ViewMetadataIngressReady) + require.Equal(t, 1, state.cluster.refreshCalls) + require.False(t, state.cluster.cnServices[0].DDLVisibilityBarrierReady) + require.Equal(t, 1, state.hakeeperClient.closeCalls) + require.Equal(t, 2, state.lockService.closeCalls) + select { + case <-state.queryService.closed: + default: + t.Fatal("QueryService was not closed after authoritative barrier withdrawal") + } +} + +func TestServiceCloseContinuesAfterDDLVisibilityWithdrawalFailure(t *testing.T) { + withdrawErr := errors.New("withdraw heartbeat failed") + state := newDDLVisibilityCloseTestService(t, withdrawErr) + + err := state.service.Close() + require.ErrorIs(t, err, withdrawErr) + require.False(t, state.hakeeperClient.queryClosedBeforeSend) + require.Len(t, state.hakeeperClient.heartbeats, 1) + require.Zero(t, state.cluster.refreshCalls) + require.Equal(t, 1, state.hakeeperClient.closeCalls) + require.Equal(t, 2, state.lockService.closeCalls) + select { + case <-state.queryService.closed: + default: + t.Fatal("QueryService cleanup was skipped after barrier withdrawal failure") + } +} + +func TestWaitForDDLVisibilityBarrierWithdrawalAcceptsNewerGeneration(t *testing.T) { + const serviceID = "ddl-visibility-newer-generation-test" + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, ViewMetadataAdmissionGeneration: 8, + DDLVisibilityBarrierReady: true, + }}} + s := &service{ + cfg: &Config{UUID: serviceID}, + moCluster: cluster, + viewMetadataAdmissionGeneration: 7, + } + + require.NoError(t, s.waitForDDLVisibilityBarrierWithdrawal(context.Background(), time.Second)) + require.Equal(t, 1, cluster.refreshCalls) +} + +func TestWaitForDDLVisibilityBarrierWithdrawalHonorsCancellation(t *testing.T) { + const serviceID = "ddl-visibility-withdrawal-timeout-test" + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, ViewMetadataAdmissionGeneration: 7, + DDLVisibilityBarrierReady: true, + }}} + s := &service{ + cfg: &Config{UUID: serviceID}, + moCluster: cluster, + viewMetadataAdmissionGeneration: 7, + } + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + defer cancel() + + err := s.waitForDDLVisibilityBarrierWithdrawal(ctx, time.Second) + require.Error(t, err) + require.Equal(t, 1, cluster.refreshCalls) +} + func TestSyncStartupDDLVisibilityFrontierAllowsEmptyFrontier(t *testing.T) { const serviceID = "ddl-visibility-empty-frontier-test" cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 10c2b8a230f48..36a74c6dec32f 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -185,15 +185,7 @@ func (s *service) notifyCommandPoll() { } } -func (s *service) heartbeat(ctx context.Context) { - start := time.Now() - defer func() { - v2.CNHeartbeatHistogram.Observe(time.Since(start).Seconds()) - }() - - ctx2, cancel := context.WithTimeoutCause(ctx, s.cfg.HAKeeper.HeatbeatTimeout.Duration, moerr.CauseHeartbeat) - defer cancel() - +func (s *service) newCNStoreHeartbeat() logservicepb.CNStoreHeartbeat { hb := logservicepb.CNStoreHeartbeat{ UUID: s.cfg.UUID, ServiceAddress: s.pipelineServiceServiceAddr(), @@ -227,7 +219,19 @@ func (s *service) heartbeat(ctx context.Context) { hb.GossipAddress = s.gossipServiceAddr() hb.GossipJoined = s.gossipNode.Joined() } + return hb +} + +func (s *service) heartbeat(ctx context.Context) { + start := time.Now() + defer func() { + v2.CNHeartbeatHistogram.Observe(time.Since(start).Seconds()) + }() + + ctx2, cancel := context.WithTimeoutCause(ctx, s.cfg.HAKeeper.HeatbeatTimeout.Duration, moerr.CauseHeartbeat) + defer cancel() + hb := s.newCNStoreHeartbeat() s.heartbeatInFlight.Store(true) s.notifyCommandPoll() cb, err := s._hakeeperClient.SendCNHeartbeat(ctx2, hb) From 877db80e1d691b4e5248b9c6bd13627f3031545c Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Fri, 28 Aug 2026 00:31:00 +0800 Subject: [PATCH 04/34] fix: revalidate failed DDL barrier targets --- pkg/frontend/cdc_dao_sync_test.go | 4 ++ pkg/frontend/txn.go | 60 ++++++++++++++++++++++--- pkg/frontend/txn_test.go | 74 +++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 6 deletions(-) diff --git a/pkg/frontend/cdc_dao_sync_test.go b/pkg/frontend/cdc_dao_sync_test.go index 3a595c7dc2434..07491ac83a3bc 100644 --- a/pkg/frontend/cdc_dao_sync_test.go +++ b/pkg/frontend/cdc_dao_sync_test.go @@ -84,6 +84,7 @@ type mockMOCluster struct { refreshSnapshots [][]metadata.CNService refreshCalls int refreshError error + refreshErrors map[int]error } func (m *mockMOCluster) GetCNService(selector clusterservice.Selector, apply func(metadata.CNService) bool) { @@ -119,6 +120,9 @@ func (m *mockMOCluster) Refresh(context.Context) error { if m.refreshCalls <= len(m.refreshSnapshots) { m.cnServices = m.refreshSnapshots[m.refreshCalls-1] } + if err := m.refreshErrors[m.refreshCalls]; err != nil { + return err + } return m.refreshError } diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index 45e5d2d49d7ab..01e8542470e28 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -926,7 +926,9 @@ type ddlVisibilityTarget struct { // syncDDLCommitToBarrierReadyCNs closes both sides of CN admission. A CN publishes // barrier readiness before its startup frontier fence and public ingress. The // DDL sender refreshes membership again after fan-out and repeats if any ready -// generation changed. Protocol v33 is a deployment gate: mixed-version +// generation changed. A failed target is retried only after authoritative +// revalidation proves that exact generation/address tuple has departed. +// Protocol v33 is a deployment gate: mixed-version // clusters retain legacy behavior without invoking an old receiver's fatal // SyncCommit path. func syncDDLCommitToBarrierReadyCNs( @@ -974,21 +976,38 @@ func syncDDLCommitToBarrierReadyCNs( ordered = append(ordered, target) } sort.Slice(ordered, func(i, j int) bool { return ordered[i].serviceID < ordered[j].serviceID }) + retryFanout := false for _, target := range ordered { req := qc.NewRequest(querypb.CmdMethod_SyncCommitV2) req.SycnCommit = &querypb.SyncCommitRequest{LatestCommitTS: visibilityTS} - resp, err := qc.SendMessage(ctx, target.address, req) - if err != nil { - return errors.Join( - err, + resp, sendErr := qc.SendMessage(ctx, target.address, req) + if sendErr != nil { + failure := errors.Join( + sendErr, moerr.NewInternalErrorf(ctx, "failed to apply DDL commit on CN %s", target.address), ) + retryFanout, err = revalidateDDLVisibilityTargetFailure( + ctx, refresher, cluster, target, failure) + if err != nil { + return err + } + break } if resp == nil { - return moerr.NewInternalErrorf(ctx, "empty DDL visibility response from CN %s", target.address) + failure := moerr.NewInternalErrorf( + ctx, "empty DDL visibility response from CN %s", target.address) + retryFanout, err = revalidateDDLVisibilityTargetFailure( + ctx, refresher, cluster, target, failure) + if err != nil { + return err + } + break } qc.Release(resp) } + if retryFanout { + continue + } if err := refresher.Refresh(ctx); err != nil { return errors.Join( @@ -1006,6 +1025,35 @@ func syncDDLCommitToBarrierReadyCNs( } } +// revalidateDDLVisibilityTargetFailure distinguishes a graceful target +// withdrawal/replacement from a failure of a still-required barrier member. +// Unknown membership never becomes success: refresh and inventory errors are +// joined with the original target failure. +func revalidateDDLVisibilityTargetFailure( + ctx context.Context, + refresher clusterservice.AuthoritativeRefresher, + cluster clusterservice.MOCluster, + failed ddlVisibilityTarget, + failure error, +) (bool, error) { + if err := refresher.Refresh(ctx); err != nil { + return false, errors.Join( + failure, + err, + moerr.NewInternalError(ctx, "failed to revalidate CN after DDL visibility target failure"), + ) + } + targets, err := ddlVisibilityTargets(ctx, cluster) + if err != nil { + return false, errors.Join(failure, err) + } + current, ok := targets[failed.serviceID] + if ok && current == failed { + return false, failure + } + return true, nil +} + func ddlVisibilityTargets( ctx context.Context, cluster clusterservice.MOCluster, diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index 14373afb1db76..8265a45fb5ff2 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -1031,6 +1031,55 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { require.Nil(t, ses.GetTxnHandler().GetTxn()) }) + t.Run("retries when a failed target withdrew after the membership snapshot", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + sendErr := moerr.NewInternalErrorNoCtx("closing CN unavailable") + qc.sendError["cn-2:6001"] = sendErr + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + remaining := append([]metadata.CNService{}, targets[:1]...) + cluster.refreshSnapshots = [][]metadata.CNService{targets, remaining, remaining, remaining} + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Equal(t, []ddlSyncRequest{ + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + }, qc.requests) + require.Equal(t, 2, qc.releases) + require.Equal(t, 4, cluster.refreshCalls) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Zero(t, op.rollbackCalls) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("retries when a failed target tuple is replaced", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + sendErr := moerr.NewInternalErrorNoCtx("replaced CN unavailable") + qc.sendError["cn-2:6001"] = sendErr + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + replaced := append([]metadata.CNService{}, targets...) + replaced[1].ViewMetadataAdmissionGeneration = 2 + replaced[1].QueryAddress = "cn-2-new:6001" + cluster.refreshSnapshots = [][]metadata.CNService{targets, replaced, replaced, replaced} + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Equal(t, []ddlSyncRequest{ + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2-new:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + }, qc.requests) + require.Equal(t, 3, qc.releases) + require.Equal(t, 4, cluster.refreshCalls) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Zero(t, op.rollbackCalls) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + t.Run("mixed-version cluster does not call a legacy receiver", func(t *testing.T) { ses, op, qc, execCtx := newState(t) defer ses.Close() @@ -1077,6 +1126,29 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { require.ErrorIs(t, err, sendErr) require.Len(t, qc.requests, 2) require.Equal(t, 1, qc.releases) + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + require.Equal(t, 2, cluster.refreshCalls) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + require.Zero(t, op.rollbackCalls) + require.Nil(t, ses.GetTxnHandler().GetTxn()) + }) + + t.Run("does not retry when failure revalidation cannot refresh membership", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + sendErr := moerr.NewInternalErrorNoCtx("CN unavailable") + refreshErr := moerr.NewInternalErrorNoCtx("HAKeeper unavailable after send failure") + qc.sendError["cn-2:6001"] = sendErr + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + cluster.refreshErrors = map[int]error{2: refreshErr} + + err := ses.GetTxnHandler().Commit(execCtx) + require.ErrorIs(t, err, sendErr) + require.ErrorIs(t, err, refreshErr) + require.Len(t, qc.requests, 2) + require.Equal(t, 1, qc.releases) + require.Equal(t, 2, cluster.refreshCalls) require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) require.Zero(t, op.rollbackCalls) require.Nil(t, ses.GetTxnHandler().GetTxn()) @@ -1092,6 +1164,8 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { require.ErrorContains(t, err, "empty DDL visibility response") require.Len(t, qc.requests, 1) require.Zero(t, qc.releases) + cluster := clusterservice.GetMOCluster(queryServiceID).(*mockMOCluster) + require.Equal(t, 2, cluster.refreshCalls) require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) require.Nil(t, ses.GetTxnHandler().GetTxn()) }) From 73405751e8f30fcb7e5381ae83d367ed1fcf9d71 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Fri, 28 Aug 2026 14:05:44 +0800 Subject: [PATCH 05/34] fix: fence live DDL protocol activation --- pkg/cnservice/server.go | 4 + pkg/cnservice/server_ddl_visibility.go | 122 +++++++- pkg/cnservice/server_ddl_visibility_test.go | 277 ++++++++++++++++++ pkg/cnservice/server_query.go | 21 ++ pkg/cnservice/types.go | 3 + pkg/sql/plan/function/ctl/cmd_rpc_version.go | 6 +- .../plan/function/ctl/cmd_rpc_version_test.go | 34 ++- 7 files changed, 450 insertions(+), 17 deletions(-) diff --git a/pkg/cnservice/server.go b/pkg/cnservice/server.go index 9f5d580b75927..6148e87a558a0 100644 --- a/pkg/cnservice/server.go +++ b/pkg/cnservice/server.go @@ -511,6 +511,10 @@ func (s *service) closeService() error { defer logutil.LogClose(s.logger, "cnservice")() s.closeViewMetadataAdmission() + // Prevent an already-admitted protocol command from republishing the + // barrier after shutdown begins. Other QueryService methods remain live + // until authoritative withdrawal, preserving the stale-target retry path. + s.ddlVisibilityBarrierClosing.Store(true) // Stop periodic heartbeats before publishing the final false readiness. // QueryService remains available until the authoritative inventory has // observed the withdrawal, so healthy CNs cannot target a closed barrier. diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index d17626b6a911c..c26305bfdf7dd 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -16,6 +16,7 @@ package cnservice import ( "context" + "errors" "time" "github.com/matrixorigin/matrixone/pkg/clusterservice" @@ -38,6 +39,16 @@ func ddlVisibilityBarrierSupported(serviceID string) bool { // frontier held by the already-published barrier participants before public // SQL ingress can be admitted. func (s *service) prepareDDLVisibilityBarrier() error { + s.ddlVisibilityBarrierMu.Lock() + defer s.ddlVisibilityBarrierMu.Unlock() + if err := s.prepareDDLVisibilityBarrierLocked(); err != nil { + return err + } + s.ddlVisibilityBarrierPrepared.Store(true) + return nil +} + +func (s *service) prepareDDLVisibilityBarrierLocked() error { supported := ddlVisibilityBarrierSupported(s.cfg.UUID) if supported && (s.moCluster == nil || s.queryClient == nil || s._txnClient == nil) { // Focused service tests may construct only the dependencies relevant to @@ -76,11 +87,16 @@ func (s *service) prepareDDLVisibilityBarrier() error { // heartbeat task has terminated, so no previously captured ready heartbeat can // overwrite this final withdrawal. func (s *service) withdrawDDLVisibilityBarrier() error { - ingressWasReady := s.viewMetadataIngressReady.Swap(false) - barrierWasReady := s.ddlVisibilityBarrierReady.Swap(false) - if !ingressWasReady && !barrierWasReady { - return nil - } + s.ddlVisibilityBarrierMu.Lock() + defer s.ddlVisibilityBarrierMu.Unlock() + ctx, cancel := s.newDDLVisibilityBarrierContext(context.Background()) + defer cancel() + return s.withdrawDDLVisibilityBarrierLocked(ctx) +} + +func (s *service) withdrawDDLVisibilityBarrierLocked(ctx context.Context) error { + s.viewMetadataIngressReady.Store(false) + s.ddlVisibilityBarrierReady.Store(false) if s.viewMetadataAdmissionGeneration == 0 { return nil } @@ -88,21 +104,99 @@ func (s *service) withdrawDDLVisibilityBarrier() error { return moerr.NewInternalErrorNoCtx("DDL visibility barrier withdrawal dependencies are unavailable") } - timeout := s.cfg.HAKeeper.DiscoveryTimeout.Duration - if timeout <= 0 { - timeout = 30 * time.Second - } - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - if _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { return moerr.AttachCause(ctx, err) } - retryInterval := s.cfg.HAKeeper.HeatbeatInterval.Duration + return s.waitForDDLVisibilityBarrierWithdrawal(ctx, s.ddlVisibilityBarrierRetryInterval()) +} + +func (s *service) newDDLVisibilityBarrierContext(parent context.Context) (context.Context, context.CancelFunc) { + timeout := 30 * time.Second + if s.cfg != nil && s.cfg.HAKeeper.DiscoveryTimeout.Duration > 0 { + timeout = s.cfg.HAKeeper.DiscoveryTimeout.Duration + } + return context.WithTimeout(parent, timeout) +} + +func (s *service) ddlVisibilityBarrierRetryInterval() time.Duration { + retryInterval := time.Duration(0) + if s.cfg != nil { + retryInterval = s.cfg.HAKeeper.HeatbeatInterval.Duration + } if retryInterval < minClusterReadinessRetryInterval { retryInterval = minClusterReadinessRetryInterval } - return s.waitForDDLVisibilityBarrierWithdrawal(ctx, retryInterval) + return retryInterval +} + +// setProtocolVersion serializes the live protocol transition with startup and +// shutdown. Before startup preparation, changing the runtime value is enough: +// the normal startup path will observe it and fence before ingress. Once this +// generation has been published, the first transition into v35 must withdraw, +// catch up, and republish before the new capability becomes visible locally. +func (s *service) setProtocolVersion(ctx context.Context, version int64) error { + s.ddlVisibilityBarrierMu.Lock() + defer s.ddlVisibilityBarrierMu.Unlock() + + if s.cfg == nil { + return moerr.NewInternalError(ctx, "CN configuration is unavailable") + } + rt := moruntime.ServiceRuntime(s.cfg.UUID) + value, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + if !ok { + return moerr.NewInternalError(ctx, "protocol version not found") + } + current, ok := value.(int64) + if !ok { + return moerr.NewInternalError(ctx, "invalid protocol version") + } + if current >= defines.MORPCVersion35 || version < defines.MORPCVersion35 || + !s.ddlVisibilityBarrierPrepared.Load() { + rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) + return nil + } + if s.ddlVisibilityBarrierClosing.Load() || s.viewMetadataGenerationRevoked.Load() { + return moerr.NewServiceUnavailableNoCtx("CN is closing") + } + if s.viewMetadataAdmissionGeneration == 0 || s.cfg == nil || s._hakeeperClient == nil || + s.moCluster == nil || s.queryClient == nil || s._txnClient == nil || s.config == nil { + return moerr.NewInternalError(ctx, "DDL visibility activation dependencies are unavailable") + } + + barrierCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) + defer cancel() + if err := s.withdrawDDLVisibilityBarrierLocked(barrierCtx); err != nil { + return err + } + if err := s.syncStartupDDLVisibilityFrontier(barrierCtx); err != nil { + return err + } + if s.ddlVisibilityBarrierClosing.Load() || s.viewMetadataGenerationRevoked.Load() { + return moerr.NewServiceUnavailableNoCtx("CN is closing") + } + + // The local gates are opened before their heartbeat is sent, but ingress is + // not externally routable until HAKeeper publishes that heartbeat. The + // runtime version remains old until publication is authoritative. + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + _, publishErr := s._hakeeperClient.SendCNHeartbeat(barrierCtx, s.newCNStoreHeartbeat()) + if publishErr == nil { + publishErr = s.waitForDDLVisibilityBarrierPublication( + barrierCtx, s.ddlVisibilityBarrierRetryInterval()) + } + if publishErr != nil { + // A successful heartbeat followed by an uncertain refresh may already + // have published true. Always issue a fresh bounded withdrawal before + // returning the activation failure. + cleanupCtx, cleanupCancel := s.newDDLVisibilityBarrierContext(context.Background()) + cleanupErr := s.withdrawDDLVisibilityBarrierLocked(cleanupCtx) + cleanupCancel() + return errors.Join(moerr.AttachCause(barrierCtx, publishErr), cleanupErr) + } + + rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) + return nil } func (s *service) waitForDDLVisibilityBarrierWithdrawal( diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index e0a9c232e71f4..15ee44eedded3 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -25,6 +25,7 @@ import ( "go.uber.org/zap" "github.com/matrixorigin/matrixone/pkg/clusterservice" + "github.com/matrixorigin/matrixone/pkg/common/morpc" moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" "github.com/matrixorigin/matrixone/pkg/common/stopper" "github.com/matrixorigin/matrixone/pkg/defines" @@ -126,6 +127,7 @@ type ddlVisibilityWithdrawalHAKeeperClient struct { cluster *ddlVisibilityTestCluster queryClosed <-chan struct{} sendErr error + sendErrors map[int]error heartbeats []logservicepb.CNStoreHeartbeat queryClosedBeforeSend bool closeCalls int @@ -141,6 +143,9 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( default: } c.heartbeats = append(c.heartbeats, hb) + if err := c.sendErrors[len(c.heartbeats)]; err != nil { + return logservicepb.CommandBatch{}, err + } if c.sendErr != nil { return logservicepb.CommandBatch{}, c.sendErr } @@ -259,6 +264,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { viewMetadataAdmissionGeneration: 7, } require.NoError(t, s.prepareDDLVisibilityBarrier()) + require.True(t, s.ddlVisibilityBarrierPrepared.Load()) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.Equal(t, 1, cluster.refreshCalls) require.Equal(t, []string{"self:6001", "peer:6001"}, queryClient.requests) @@ -276,6 +282,7 @@ func TestPrepareDDLVisibilityBarrierRejectsMissingProductionDependencies(t *test err := s.prepareDDLVisibilityBarrier() require.ErrorContains(t, err, "dependencies are unavailable") + require.False(t, s.ddlVisibilityBarrierPrepared.Load()) require.False(t, s.ddlVisibilityBarrierReady.Load()) } @@ -287,9 +294,279 @@ func TestPrepareDDLVisibilityBarrierSkipsFrontierSyncDuringRollingUpgrade(t *tes s := &service{cfg: &Config{UUID: serviceID}} require.NoError(t, s.prepareDDLVisibilityBarrier()) + require.True(t, s.ddlVisibilityBarrierPrepared.Load()) require.True(t, s.ddlVisibilityBarrierReady.Load()) } +func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { + const serviceID = "ddl-visibility-live-activation-test" + const generation = uint64(7) + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion34) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + targetTS := timestamp.Timestamp{PhysicalTime: 300, LogicalTime: 4} + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ + { + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + }, + { + ServiceID: "peer", QueryAddress: "peer:6001", + ViewMetadataAdmissionGeneration: 9, DDLVisibilityBarrierReady: true, + }, + }} + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, + frontiers: map[string]timestamp.Timestamp{"peer:6001": targetTS}, + } + ctrl := gomock.NewController(t) + txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).DoAndReturn( + func(context.Context, timestamp.Timestamp) (timestamp.Timestamp, error) { + version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion34, version, + "v35 must not become visible before the activation frontier is applied") + require.False(t, cluster.cnServices[0].DDLVisibilityBarrierReady, + "the transitioning CN must be authoritatively withdrawn while applying the frontier") + return targetTS.Next(), nil + }) + txnClient.EXPECT().SyncLatestCommitTS(targetTS) + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + hakeeperClient := &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster} + s := &service{ + cfg: cfg, + _hakeeperClient: hakeeperClient, + moCluster: cluster, + queryClient: queryClient, + _txnClient: txnClient, + config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: generation, + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + + req := &query.Request{SetProtocolVersion: &query.SetProtocolVersionRequest{ + Version: defines.MORPCVersion35, + }} + resp := &query.Response{} + require.NoError(t, s.handleSetProtocolVersion(context.Background(), req, resp, nil)) + require.Equal(t, defines.MORPCVersion35, resp.SetProtocolVersion.Version) + version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion35, version) + require.Equal(t, []string{"peer:6001"}, queryClient.requests) + require.Equal(t, []query.CmdMethod{query.CmdMethod_GetCommit}, queryClient.methods) + require.Equal(t, 1, queryClient.releases) + require.Len(t, hakeeperClient.heartbeats, 2) + require.False(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) + require.False(t, hakeeperClient.heartbeats[0].ViewMetadataIngressReady) + require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityBarrierReady) + require.True(t, hakeeperClient.heartbeats[1].ViewMetadataIngressReady) + require.Equal(t, 2, cluster.refreshCalls) + require.True(t, s.ddlVisibilityBarrierReady.Load()) + require.True(t, s.viewMetadataIngressReady.Load()) + + // Repeating an already-active version must not withdraw or re-run the fence. + resp = &query.Response{} + require.NoError(t, s.handleSetProtocolVersion(context.Background(), req, resp, nil)) + require.Equal(t, defines.MORPCVersion35, resp.SetProtocolVersion.Version) + require.Len(t, hakeeperClient.heartbeats, 2) + require.Equal(t, 2, cluster.refreshCalls) + require.Len(t, queryClient.requests, 1) +} + +func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T) { + const serviceID = "ddl-visibility-live-activation-failure-test" + const generation = uint64(7) + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion34) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + targetTS := timestamp.Timestamp{PhysicalTime: 300, LogicalTime: 4} + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ + { + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + }, + {ServiceID: "peer", QueryAddress: "peer:6001", DDLVisibilityBarrierReady: true}, + }} + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, + frontiers: map[string]timestamp.Timestamp{"peer:6001": targetTS}, + } + ctrl := gomock.NewController(t) + txnClient := mock_frontend.NewMockTxnClient(ctrl) + syncErr := errors.New("logtail activation sync failed") + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(timestamp.Timestamp{}, syncErr) + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + hakeeperClient := &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster} + s := &service{ + cfg: cfg, + _hakeeperClient: hakeeperClient, + moCluster: cluster, + queryClient: queryClient, + _txnClient: txnClient, + config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: generation, + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + + resp := &query.Response{} + err := s.handleSetProtocolVersion(context.Background(), &query.Request{ + SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion35}, + }, resp, nil) + require.ErrorIs(t, err, syncErr) + require.Nil(t, resp.SetProtocolVersion) + version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion34, version) + require.Len(t, hakeeperClient.heartbeats, 1) + require.False(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) + require.False(t, s.ddlVisibilityBarrierReady.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + require.False(t, cluster.cnServices[0].DDLVisibilityBarrierReady) +} + +func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing.T) { + const serviceID = "ddl-visibility-live-activation-publish-failure-test" + const generation = uint64(7) + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion34) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + targetTS := timestamp.Timestamp{PhysicalTime: 300, LogicalTime: 4} + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ + { + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + }, + {ServiceID: "peer", QueryAddress: "peer:6001", DDLVisibilityBarrierReady: true}, + }} + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, + frontiers: map[string]timestamp.Timestamp{"peer:6001": targetTS}, + } + ctrl := gomock.NewController(t) + txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS.Next(), nil) + txnClient.EXPECT().SyncLatestCommitTS(targetTS) + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + publishErr := errors.New("activation publication failed") + hakeeperClient := &ddlVisibilityWithdrawalHAKeeperClient{ + cluster: cluster, sendErrors: map[int]error{2: publishErr}, + } + s := &service{ + cfg: cfg, + _hakeeperClient: hakeeperClient, + moCluster: cluster, + queryClient: queryClient, + _txnClient: txnClient, + config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: generation, + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + + err := s.handleSetProtocolVersion(context.Background(), &query.Request{ + SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion35}, + }, &query.Response{}, nil) + require.ErrorIs(t, err, publishErr) + version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion34, version) + require.Len(t, hakeeperClient.heartbeats, 3) + require.False(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) + require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityBarrierReady) + require.False(t, hakeeperClient.heartbeats[2].DDLVisibilityBarrierReady) + require.False(t, s.ddlVisibilityBarrierReady.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + require.False(t, cluster.cnServices[0].DDLVisibilityBarrierReady) + require.Equal(t, 2, cluster.refreshCalls) +} + +func TestSetProtocolVersionBeforeBarrierPreparationDefersToStartupFence(t *testing.T) { + const serviceID = "ddl-visibility-pre-start-activation-test" + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion34) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + s := &service{cfg: &Config{UUID: serviceID}} + + require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion35)) + version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion35, version) + require.False(t, s.ddlVisibilityBarrierPrepared.Load()) + require.False(t, s.ddlVisibilityBarrierReady.Load()) +} + +func TestInitQueryCommandHandlerOverridesProtocolActivation(t *testing.T) { + const serviceID = "ddl-visibility-public-protocol-handler-test" + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion34) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + queryService := &closeRecordingQueryService{ + handlers: make(map[query.CmdMethod]func(context.Context, *query.Request, *query.Response, *morpc.Buffer) error), + } + s := &service{cfg: &Config{UUID: serviceID}, queryService: queryService} + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierClosing.Store(true) + s.initQueryCommandHandler() + + handler, ok := queryService.handlers[query.CmdMethod_SetProtocolVersion] + require.True(t, ok) + resp := &query.Response{} + err := handler(context.Background(), &query.Request{ + SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion35}, + }, resp, nil) + require.ErrorContains(t, err, "CN is closing") + require.Nil(t, resp.SetProtocolVersion) + version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion34, version) +} + +func TestSetProtocolVersionRejectsActivationDuringClose(t *testing.T) { + const serviceID = "ddl-visibility-closing-activation-test" + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion34) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + s := &service{cfg: &Config{UUID: serviceID}} + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierClosing.Store(true) + + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion35) + require.ErrorContains(t, err, "CN is closing") + version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion34, version) +} + +func TestWithdrawDDLVisibilityBarrierHandlesPartialService(t *testing.T) { + t.Run("zero generation has no authoritative publication", func(t *testing.T) { + s := &service{} + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + require.NoError(t, s.withdrawDDLVisibilityBarrierLocked(context.Background())) + require.False(t, s.ddlVisibilityBarrierReady.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + }) + + t.Run("published generation requires dependencies", func(t *testing.T) { + s := &service{cfg: &Config{}, viewMetadataAdmissionGeneration: 1} + err := s.withdrawDDLVisibilityBarrierLocked(context.Background()) + require.ErrorContains(t, err, "withdrawal dependencies are unavailable") + }) +} + func TestWaitForDDLVisibilityBarrierPublicationHonorsCancellation(t *testing.T) { cluster := &ddlVisibilityTestCluster{} s := &service{ diff --git a/pkg/cnservice/server_query.go b/pkg/cnservice/server_query.go index 35b888ed818e5..26105113a6a24 100644 --- a/pkg/cnservice/server_query.go +++ b/pkg/cnservice/server_query.go @@ -140,6 +140,10 @@ func (s *service) initQueryService() error { } func (s *service) initQueryCommandHandler() { + // Override queryservice's generic runtime-only setter so a live CN can + // execute the v35 DDL visibility activation fence before acknowledging the + // protocol transition. + s.addQueryCommandHandler(query.CmdMethod_SetProtocolVersion, s.handleSetProtocolVersion) s.addQueryCommandHandler(query.CmdMethod_KillConn, s.handleKillConn) s.addQueryCommandHandler(query.CmdMethod_AlterAccount, s.handleAlterAccount) s.addQueryCommandHandler(query.CmdMethod_TraceSpan, s.handleTraceSpan) @@ -205,6 +209,23 @@ func (s *service) closeQueryService() error { }) } +func (s *service) handleSetProtocolVersion( + ctx context.Context, + req *query.Request, + resp *query.Response, + _ *morpc.Buffer, +) error { + if req == nil || req.SetProtocolVersion == nil { + return moerr.NewInternalError(ctx, "bad request") + } + version := req.SetProtocolVersion.Version + if err := s.setProtocolVersion(ctx, version); err != nil { + return err + } + resp.SetProtocolVersion = &query.SetProtocolVersionResponse{Version: version} + return nil +} + func (s *service) handleKillConn(ctx context.Context, req *query.Request, resp *query.Response, _ *morpc.Buffer) error { if req == nil || req.KillConnRequest == nil { return moerr.NewInternalError(ctx, "bad request") diff --git a/pkg/cnservice/types.go b/pkg/cnservice/types.go index b0c89846e9454..e85b6a8cba365 100644 --- a/pkg/cnservice/types.go +++ b/pkg/cnservice/types.go @@ -800,6 +800,9 @@ type service struct { viewMetadataCatalogFenceReady atomic.Bool viewMetadataIngressReady atomic.Bool ddlVisibilityBarrierReady atomic.Bool + ddlVisibilityBarrierPrepared atomic.Bool + ddlVisibilityBarrierClosing atomic.Bool + ddlVisibilityBarrierMu sync.Mutex viewMetadataGenerationRevoked atomic.Bool viewMetadataRevocationOnce sync.Once // viewMetadataCloseFn is a deterministic test hook for the asynchronous diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version.go b/pkg/sql/plan/function/ctl/cmd_rpc_version.go index 8dcff5b268dac..8435d14ff995d 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version.go @@ -195,7 +195,11 @@ func transferToCN(qt qclient.QueryClient, target string, version int64) (resp *q req.SetProtocolVersion = &querypb.SetProtocolVersionRequest{ Version: version, } - ctx, cancel := context.WithTimeoutCause(context.Background(), time.Second, moerr.CauseTransferToCN) + // Live protocol activation may withdraw CN ingress and wait for a + // bounded logtail frontier fence before acknowledging the transition. + // Keep the caller deadline above the CN's default 30-second discovery + // bound instead of truncating the safety fence at the historical 1s. + ctx, cancel := context.WithTimeoutCause(context.Background(), time.Minute, moerr.CauseTransferToCN) defer cancel() resp, err = qt.SendMessage(ctx, cn.QueryAddress, req) diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go index 1fd53a045b270..c908e0fb1d648 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go @@ -142,16 +142,46 @@ func requireVersionValue(t *testing.T, version int64) { type addressRecordingQueryClient struct { testQClient - address string + address string + deadline time.Time } func (c *addressRecordingQueryClient) SendMessage( - _ context.Context, address string, _ *query.Request, + ctx context.Context, address string, _ *query.Request, ) (*query.Response, error) { c.address = address + c.deadline, _ = ctx.Deadline() return nil, moerr.NewInternalErrorNoCtx("send error") } +func TestTransferToCNAllowsActivationFence(t *testing.T) { + const serviceID = "activation-cn" + rt := runtime.DefaultRuntime() + runtime.SetupServiceBasedRuntime("", rt) + mc := clusterservice.NewMOCluster( + "", + nil, + 3*time.Second, + clusterservice.WithDisableRefresh(), + clusterservice.WithServices( + []metadata.CNService{{ + ServiceID: serviceID, QueryAddress: "activation-cn:6001", + WorkState: metadata.WorkState_Working, + }}, + nil, + ), + ) + defer mc.Close() + rt.SetGlobalVariables(runtime.ClusterService, mc) + + qcli := &addressRecordingQueryClient{} + started := time.Now() + _, err := transferToCN(qcli, serviceID, defines.MORPCVersion35) + require.Error(t, err) + require.Equal(t, "activation-cn:6001", qcli.address) + require.WithinDuration(t, started.Add(time.Minute), qcli.deadline, time.Second) +} + func Test_transferToTN(t *testing.T) { rt := runtime.DefaultRuntime() From b0b703225cde068c686077a12e2c588a04f075c7 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Fri, 28 Aug 2026 15:42:52 +0800 Subject: [PATCH 06/34] fix: linearize DDL during protocol activation --- pkg/clusterservice/cluster.go | 1 + pkg/clusterservice/cluster_test.go | 4 + pkg/cnservice/server.go | 24 +- pkg/cnservice/server_ddl_visibility.go | 253 +++++- pkg/cnservice/server_ddl_visibility_test.go | 288 ++++++- pkg/cnservice/server_query.go | 29 +- pkg/cnservice/types.go | 4 + pkg/frontend/ddl_commit_gate.go | 144 ++++ pkg/frontend/ddl_commit_gate_test.go | 83 ++ pkg/frontend/txn.go | 7 + pkg/frontend/txn_test.go | 30 + pkg/hakeeper/rsm.go | 1 + pkg/hakeeper/view_metadata_admission_test.go | 1 + pkg/pb/logservice/logservice.pb.go | 792 +++++++++--------- pkg/pb/logservice/logservice_test.go | 2 + pkg/pb/metadata/metadata.pb.go | 172 ++-- pkg/pb/query/query.pb.go | 695 +++++++++------ pkg/sql/plan/function/ctl/cmd_rpc_version.go | 95 ++- .../plan/function/ctl/cmd_rpc_version_test.go | 83 +- proto/logservice.proto | 2 + proto/metadata.proto | 3 + proto/query.proto | 9 + 22 files changed, 1925 insertions(+), 797 deletions(-) create mode 100644 pkg/frontend/ddl_commit_gate.go create mode 100644 pkg/frontend/ddl_commit_gate_test.go diff --git a/pkg/clusterservice/cluster.go b/pkg/clusterservice/cluster.go index 784eee14b0f14..eb51088f3f448 100644 --- a/pkg/clusterservice/cluster.go +++ b/pkg/clusterservice/cluster.go @@ -656,6 +656,7 @@ func newCNService(cn logpb.CNStore) metadata.CNService { ViewMetadataAdmissionReady: cn.ViewMetadataAdmissionReady, ViewMetadataObservedEpoch: cn.ViewMetadataObservedEpoch, DDLVisibilityBarrierReady: cn.DDLVisibilityBarrierReady, + ViewMetadataIngressReady: cn.ViewMetadataIngressReady, } } diff --git a/pkg/clusterservice/cluster_test.go b/pkg/clusterservice/cluster_test.go index bb5fd3f34f053..36f1fd8772f22 100644 --- a/pkg/clusterservice/cluster_test.go +++ b/pkg/clusterservice/cluster_test.go @@ -170,6 +170,7 @@ func TestClusterAdmissionSnapshotFiltersEveryPublicInventory(t *testing.T) { WorkState: metadata.WorkState_Working, ViewMetadataAdmissionGeneration: 11, DDLVisibilityBarrierReady: true, + ViewMetadataIngressReady: true, }, } hc.Unlock() @@ -191,16 +192,19 @@ func TestClusterAdmissionSnapshotFiltersEveryPublicInventory(t *testing.T) { var raw []string pendingBarrierReady := false + pendingIngressReady := false require.NoError(t, GetCNServiceRawWithContext( context.Background(), c, NewSelector(), func(service metadata.CNService) bool { raw = append(raw, service.ServiceID) if service.ServiceID == "pending" { pendingBarrierReady = service.DDLVisibilityBarrierReady + pendingIngressReady = service.ViewMetadataIngressReady } return true })) require.ElementsMatch(t, []string{"ready", "pending"}, raw) require.True(t, pendingBarrierReady) + require.True(t, pendingIngressReady) admission := c.GetViewMetadataAdmission() require.True(t, admission.Enabled) diff --git a/pkg/cnservice/server.go b/pkg/cnservice/server.go index 6148e87a558a0..b17a3a89d46c8 100644 --- a/pkg/cnservice/server.go +++ b/pkg/cnservice/server.go @@ -155,15 +155,18 @@ func NewService( UUID: cfg.UUID, Role: metadata.MustParseCNRole(cfg.Role), }, - cfg: cfg, - logger: logutil.GetGlobalLogger().Named("cn-service"), - metadataFS: metadataFS, - etlFS: etlFS, - fileService: fileService, - sessionMgr: queryservice.NewSessionManager(), - addressMgr: address.NewAddressManager(cfg.ServiceHost, cfg.PortBase), - gossipNode: gossipNode, - } + cfg: cfg, + logger: logutil.GetGlobalLogger().Named("cn-service"), + metadataFS: metadataFS, + etlFS: etlFS, + fileService: fileService, + sessionMgr: queryservice.NewSessionManager(), + addressMgr: address.NewAddressManager(cfg.ServiceHost, cfg.PortBase), + gossipNode: gossipNode, + ddlCommitGate: frontend.NewDDLCommitGate(), + } + runtime.ServiceRuntime(cfg.UUID).SetGlobalVariables( + frontend.DDLCommitGateRuntimeKey, srv.ddlCommitGate) srv.colexecServer = colexec.NewServer(cfg.UUID) srv.requestHandler = func(ctx context.Context, @@ -515,6 +518,9 @@ func (s *service) closeService() error { // barrier after shutdown begins. Other QueryService methods remain live // until authoritative withdrawal, preserving the stale-target retry path. s.ddlVisibilityBarrierClosing.Store(true) + if s.ddlCommitGate != nil { + s.ddlCommitGate.Close() + } // Stop periodic heartbeats before publishing the final false readiness. // QueryService remains available until the authoritative inventory has // observed the withdrawal, so healthy CNs cannot target a closed barrier. diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index c26305bfdf7dd..fadfe0a5df26e 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -45,6 +45,12 @@ func (s *service) prepareDDLVisibilityBarrier() error { return err } s.ddlVisibilityBarrierPrepared.Store(true) + if ddlVisibilityBarrierSupported(s.cfg.UUID) { + // A v35 startup has no admitted DDL producers and has already applied the + // startup frontier, so it satisfies both live-activation phases. + s.ddlVisibilityActivationPrepared.Store(true) + s.ddlVisibilityActivationFenced.Store(true) + } return nil } @@ -129,12 +135,13 @@ func (s *service) ddlVisibilityBarrierRetryInterval() time.Duration { return retryInterval } -// setProtocolVersion serializes the live protocol transition with startup and -// shutdown. Before startup preparation, changing the runtime value is enough: -// the normal startup path will observe it and fence before ingress. Once this -// generation has been published, the first transition into v35 must withdraw, -// catch up, and republish before the new capability becomes visible locally. -func (s *service) setProtocolVersion(ctx context.Context, version int64) error { +// setProtocolVersion serializes live activation with startup and shutdown. +// Every target CN blocks and drains local DDL before publishing Prepared. Once +// all targets are prepared, no v34 DDL producer exists; each CN applies the +// converged frontier and publishes Fenced. A CN releases its DDL gate only after +// every target is fenced, at which point all later DDL uses the v35 fan-out and +// every still-fencing receiver remains barrier-reachable. +func (s *service) setProtocolVersion(ctx context.Context, version int64, targets []string) error { s.ddlVisibilityBarrierMu.Lock() defer s.ddlVisibilityBarrierMu.Unlock() @@ -150,55 +157,243 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64) error { if !ok { return moerr.NewInternalError(ctx, "invalid protocol version") } - if current >= defines.MORPCVersion35 || version < defines.MORPCVersion35 || - !s.ddlVisibilityBarrierPrepared.Load() { + pending := s.ddlVisibilityActivationPending.Load() + if version < defines.MORPCVersion35 { + if pending { + return moerr.NewInvalidStateNoCtx("cannot downgrade during DDL visibility activation") + } + rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) + s.ddlVisibilityActivationPrepared.Store(false) + s.ddlVisibilityActivationFenced.Store(false) + return nil + } + if !s.ddlVisibilityBarrierPrepared.Load() { + rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) + return nil + } + if current >= defines.MORPCVersion35 && !pending { rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) return nil } if s.ddlVisibilityBarrierClosing.Load() || s.viewMetadataGenerationRevoked.Load() { return moerr.NewServiceUnavailableNoCtx("CN is closing") } - if s.viewMetadataAdmissionGeneration == 0 || s.cfg == nil || s._hakeeperClient == nil || - s.moCluster == nil || s.queryClient == nil || s._txnClient == nil || s.config == nil { + if s.viewMetadataAdmissionGeneration == 0 || s._hakeeperClient == nil || + s.moCluster == nil || s.queryClient == nil || s._txnClient == nil || s.config == nil || + s.ddlCommitGate == nil { return moerr.NewInternalError(ctx, "DDL visibility activation dependencies are unavailable") } + activationTargets, err := validateDDLVisibilityActivationTargets(s.cfg.UUID, targets) + if err != nil { + return err + } barrierCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) defer cancel() - if err := s.withdrawDDLVisibilityBarrierLocked(barrierCtx); err != nil { + s.ddlVisibilityActivationPending.Store(true) + s.ddlVisibilityActivationPrepared.Store(false) + s.ddlVisibilityActivationFenced.Store(false) + if err := s.ddlCommitGate.Block(barrierCtx); err != nil { + return err + } + if err := s.setDDLVisibilityIngressLocked(barrierCtx, false); err != nil { + return err + } + + // Version 35 is visible only after the local v34 producers are drained. It + // acts as the distributed Prepared signal queried by every other target. + rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) + s.ddlVisibilityActivationPrepared.Store(true) + if err := s.waitForDDLVisibilityActivationPhase( + barrierCtx, activationTargets, false); err != nil { return err } if err := s.syncStartupDDLVisibilityFrontier(barrierCtx); err != nil { return err } + s.ddlVisibilityActivationFenced.Store(true) + if err := s.waitForDDLVisibilityActivationPhase( + barrierCtx, activationTargets, true); err != nil { + return err + } if s.ddlVisibilityBarrierClosing.Load() || s.viewMetadataGenerationRevoked.Load() { return moerr.NewServiceUnavailableNoCtx("CN is closing") } - - // The local gates are opened before their heartbeat is sent, but ingress is - // not externally routable until HAKeeper publishes that heartbeat. The - // runtime version remains old until publication is authoritative. - s.ddlVisibilityBarrierReady.Store(true) - s.viewMetadataIngressReady.Store(true) - _, publishErr := s._hakeeperClient.SendCNHeartbeat(barrierCtx, s.newCNStoreHeartbeat()) - if publishErr == nil { - publishErr = s.waitForDDLVisibilityBarrierPublication( - barrierCtx, s.ddlVisibilityBarrierRetryInterval()) - } - if publishErr != nil { - // A successful heartbeat followed by an uncertain refresh may already - // have published true. Always issue a fresh bounded withdrawal before - // returning the activation failure. + if err := s.setDDLVisibilityIngressLocked(barrierCtx, true); err != nil { cleanupCtx, cleanupCancel := s.newDDLVisibilityBarrierContext(context.Background()) - cleanupErr := s.withdrawDDLVisibilityBarrierLocked(cleanupCtx) + cleanupErr := s.setDDLVisibilityIngressLocked(cleanupCtx, false) cleanupCancel() - return errors.Join(moerr.AttachCause(barrierCtx, publishErr), cleanupErr) + return errors.Join(err, cleanupErr) } - rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) + s.ddlVisibilityActivationPending.Store(false) + s.ddlCommitGate.Unblock() return nil } +func validateDDLVisibilityActivationTargets(serviceID string, targets []string) (map[string]struct{}, error) { + result := make(map[string]struct{}, len(targets)) + for _, target := range targets { + if target == "" { + return nil, moerr.NewInternalErrorNoCtx("DDL visibility activation target is empty") + } + if _, exists := result[target]; exists { + return nil, moerr.NewInternalErrorNoCtxf( + "DDL visibility activation target %s is duplicated", target) + } + result[target] = struct{}{} + } + if _, ok := result[serviceID]; !ok { + return nil, moerr.NewInternalErrorNoCtxf( + "DDL visibility activation targets do not include local CN %s", serviceID) + } + return result, nil +} + +func (s *service) setDDLVisibilityIngressLocked(ctx context.Context, ready bool) error { + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(ready) + if _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { + return moerr.AttachCause(ctx, err) + } + return s.waitForDDLVisibilityIngress( + ctx, s.ddlVisibilityBarrierRetryInterval(), ready) +} + +func (s *service) waitForDDLVisibilityIngress( + ctx context.Context, + retryInterval time.Duration, + ready bool, +) error { + refresher, ok := s.moCluster.(clusterservice.AuthoritativeRefresher) + if !ok { + return moerr.NewInternalErrorNoCtx( + "CN cluster service does not support authoritative DDL visibility refresh") + } + for { + if err := refresher.Refresh(ctx); err == nil { + matched := false + err = clusterservice.GetCNServiceRawWithContext( + ctx, + s.moCluster, + clusterservice.NewServiceIDSelector(s.cfg.UUID), + func(cn metadata.CNService) bool { + matched = cn.ViewMetadataAdmissionGeneration == s.viewMetadataAdmissionGeneration && + cn.DDLVisibilityBarrierReady && cn.ViewMetadataIngressReady == ready + return false + }) + if err != nil { + return err + } + if matched { + return nil + } + } + if err := waitDDLVisibilityRetry(ctx, retryInterval); err != nil { + return moerr.NewInternalErrorf( + context.Background(), + "CN %s DDL visibility ingress=%t was not published before deadline: %v", + s.cfg.UUID, + ready, + err) + } + } +} + +func (s *service) waitForDDLVisibilityActivationPhase( + ctx context.Context, + targets map[string]struct{}, + requireFenced bool, +) error { + refresher, ok := s.moCluster.(clusterservice.AuthoritativeRefresher) + if !ok { + return moerr.NewInternalErrorNoCtx( + "CN cluster service does not support authoritative DDL visibility refresh") + } + for { + allReady := true + addresses := make(map[string]string, len(targets)) + if err := refresher.Refresh(ctx); err != nil { + allReady = false + } else if err := clusterservice.GetCNServiceRawWithContext( + ctx, + s.moCluster, + clusterservice.NewSelector(), + func(cn metadata.CNService) bool { + if !cn.DDLVisibilityBarrierReady { + return true + } + if _, expected := targets[cn.ServiceID]; !expected { + allReady = false + return true + } + addresses[cn.ServiceID] = cn.QueryAddress + return true + }); err != nil { + return err + } + if len(addresses) != len(targets) { + allReady = false + } + for serviceID := range targets { + if !allReady { + break + } + if serviceID == s.cfg.UUID { + if !s.ddlVisibilityActivationPrepared.Load() || + (requireFenced && !s.ddlVisibilityActivationFenced.Load()) { + allReady = false + } + continue + } + address := addresses[serviceID] + if address == "" { + return moerr.NewInternalErrorNoCtxf( + "DDL visibility activation target %s has no query address", serviceID) + } + req := s.queryClient.NewRequest(query.CmdMethod_GetProtocolVersion) + resp, err := s.queryClient.SendMessage(ctx, address, req) + if err != nil { + allReady = false + break + } + if resp == nil || resp.GetProtocolVersion == nil { + if resp != nil { + s.queryClient.Release(resp) + } + return moerr.NewInternalErrorNoCtxf( + "missing protocol activation response from CN %s", serviceID) + } + phase := resp.GetProtocolVersion + allReady = phase.Version >= defines.MORPCVersion35 && + phase.DDLVisibilityActivationPrepared && + (!requireFenced || phase.DDLVisibilityActivationFenced) + s.queryClient.Release(resp) + } + if allReady { + return nil + } + if err := waitDDLVisibilityRetry(ctx, s.ddlVisibilityBarrierRetryInterval()); err != nil { + return moerr.NewInternalErrorf( + context.Background(), + "DDL visibility activation fenced=%t did not converge before deadline: %v", + requireFenced, + err) + } + } +} + +func waitDDLVisibilityRetry(ctx context.Context, retryInterval time.Duration) error { + timer := time.NewTimer(retryInterval) + defer timer.Stop() + select { + case <-ctx.Done(): + return ctx.Err() + case <-timer.C: + return nil + } +} + func (s *service) waitForDDLVisibilityBarrierWithdrawal( ctx context.Context, retryInterval time.Duration, diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 15ee44eedded3..b3d225886e54f 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -17,6 +17,7 @@ package cnservice import ( "context" "errors" + "sync/atomic" "testing" "time" @@ -29,6 +30,7 @@ import ( moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" "github.com/matrixorigin/matrixone/pkg/common/stopper" "github.com/matrixorigin/matrixone/pkg/defines" + "github.com/matrixorigin/matrixone/pkg/frontend" mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test" "github.com/matrixorigin/matrixone/pkg/gossip" "github.com/matrixorigin/matrixone/pkg/lockservice" @@ -97,11 +99,14 @@ func (*ddlVisibilityTestCluster) AddCN(metadata.CNService) {} func (*ddlVisibilityTestCluster) UpdateCN(metadata.CNService) {} type ddlVisibilityTestQueryClient struct { - serviceID string - frontiers map[string]timestamp.Timestamp - requests []string - methods []query.CmdMethod - releases int + serviceID string + frontiers map[string]timestamp.Timestamp + protocols map[string]query.GetProtocolVersionResponse + protocolFn func(string) query.GetProtocolVersionResponse + nilProtocol map[string]bool + requests []string + methods []query.CmdMethod + releases int } func (c *ddlVisibilityTestQueryClient) ServiceID() string { return c.serviceID } @@ -112,6 +117,16 @@ func (c *ddlVisibilityTestQueryClient) SendMessage( ) (*query.Response, error) { c.requests = append(c.requests, address) c.methods = append(c.methods, req.CmdMethod) + if req.CmdMethod == query.CmdMethod_GetProtocolVersion { + if c.nilProtocol[address] { + return &query.Response{}, nil + } + protocol := c.protocols[address] + if c.protocolFn != nil { + protocol = c.protocolFn(address) + } + return &query.Response{GetProtocolVersion: &protocol}, nil + } return &query.Response{GetCommit: &query.GetCommitResponse{ CurrentCommitTS: c.frontiers[address], }}, nil @@ -122,6 +137,16 @@ func (*ddlVisibilityTestQueryClient) NewRequest(method query.CmdMethod) *query.R func (c *ddlVisibilityTestQueryClient) Release(*query.Response) { c.releases++ } func (*ddlVisibilityTestQueryClient) Close() error { return nil } +func activationTestPeerProtocols() map[string]query.GetProtocolVersionResponse { + return map[string]query.GetProtocolVersionResponse{ + "peer:6001": { + Version: defines.MORPCVersion35, + DDLVisibilityActivationPrepared: true, + DDLVisibilityActivationFenced: true, + }, + } +} + type ddlVisibilityWithdrawalHAKeeperClient struct { logservice.CNHAKeeperClient cluster *ddlVisibilityTestCluster @@ -154,6 +179,7 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( if cn.ServiceID == hb.UUID { cn.ViewMetadataAdmissionGeneration = hb.ViewMetadataAdmissionGeneration cn.DDLVisibilityBarrierReady = hb.DDLVisibilityBarrierReady + cn.ViewMetadataIngressReady = hb.ViewMetadataIngressReady } } return logservicepb.CommandBatch{}, nil @@ -224,6 +250,7 @@ func newDDLVisibilityCloseTestService(t *testing.T, sendErr error) *ddlVisibilit gossipNode: gossipNode, config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: frontend.NewDDLCommitGate(), } state.service.viewMetadataIngressReady.Store(true) state.service.ddlVisibilityBarrierReady.Store(true) @@ -265,6 +292,8 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { } require.NoError(t, s.prepareDDLVisibilityBarrier()) require.True(t, s.ddlVisibilityBarrierPrepared.Load()) + require.True(t, s.ddlVisibilityActivationPrepared.Load()) + require.True(t, s.ddlVisibilityActivationFenced.Load()) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.Equal(t, 1, cluster.refreshCalls) require.Equal(t, []string{"self:6001", "peer:6001"}, queryClient.requests) @@ -295,6 +324,8 @@ func TestPrepareDDLVisibilityBarrierSkipsFrontierSyncDuringRollingUpgrade(t *tes s := &service{cfg: &Config{UUID: serviceID}} require.NoError(t, s.prepareDDLVisibilityBarrier()) require.True(t, s.ddlVisibilityBarrierPrepared.Load()) + require.False(t, s.ddlVisibilityActivationPrepared.Load()) + require.False(t, s.ddlVisibilityActivationFenced.Load()) require.True(t, s.ddlVisibilityBarrierReady.Load()) } @@ -315,9 +346,26 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { ViewMetadataAdmissionGeneration: 9, DDLVisibilityBarrierReady: true, }, }} + var peerReady atomic.Bool + var protocolObserved atomic.Bool + firstProtocol := make(chan struct{}) queryClient := &ddlVisibilityTestQueryClient{ serviceID: serviceID, - frontiers: map[string]timestamp.Timestamp{"peer:6001": targetTS}, + frontiers: map[string]timestamp.Timestamp{ + "self:6001": {PhysicalTime: 200}, + "peer:6001": targetTS, + }, + protocolFn: func(string) query.GetProtocolVersionResponse { + if protocolObserved.CompareAndSwap(false, true) { + close(firstProtocol) + } + ready := peerReady.Load() + return query.GetProtocolVersionResponse{ + Version: defines.MORPCVersion35, + DDLVisibilityActivationPrepared: ready, + DDLVisibilityActivationFenced: ready, + } + }, } ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) @@ -325,10 +373,12 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { func(context.Context, timestamp.Timestamp) (timestamp.Timestamp, error) { version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion34, version, - "v35 must not become visible before the activation frontier is applied") - require.False(t, cluster.cnServices[0].DDLVisibilityBarrierReady, - "the transitioning CN must be authoritatively withdrawn while applying the frontier") + require.Equal(t, defines.MORPCVersion35, version, + "sender capability must be v35 after every local v34 DDL producer is drained") + require.True(t, cluster.cnServices[0].DDLVisibilityBarrierReady, + "the transitioning CN must remain reachable by v35 DDL fan-out") + require.False(t, cluster.cnServices[0].ViewMetadataIngressReady, + "the transitioning CN must not accept new proxy sessions before the fence") return targetTS.Next(), nil }) txnClient.EXPECT().SyncLatestCommitTS(targetTS) @@ -336,6 +386,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond hakeeperClient := &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster} + ddlCommitGate := frontend.NewDDLCommitGate() s := &service{ cfg: cfg, _hakeeperClient: hakeeperClient, @@ -344,29 +395,53 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { _txnClient: txnClient, config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: ddlCommitGate, } s.ddlVisibilityBarrierPrepared.Store(true) s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) req := &query.Request{SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion35, + Version: defines.MORPCVersion35, + DDLVisibilityActivationTargets: []string{serviceID, "peer"}, }} resp := &query.Response{} - require.NoError(t, s.handleSetProtocolVersion(context.Background(), req, resp, nil)) + activationDone := make(chan error, 1) + go func() { + activationDone <- s.handleSetProtocolVersion(context.Background(), req, resp, nil) + }() + <-firstProtocol + blockedCtx, cancelBlocked := context.WithCancel(context.Background()) + cancelBlocked() + _, err := ddlCommitGate.Enter(blockedCtx) + require.ErrorIs(t, err, context.Canceled, + "DDL producer must remain blocked until every target is prepared and fenced") + peerReady.Store(true) + require.NoError(t, <-activationDone) + releaseDDL, err := ddlCommitGate.Enter(context.Background()) + require.NoError(t, err, "activation must release DDL producers after global convergence") + releaseDDL() require.Equal(t, defines.MORPCVersion35, resp.SetProtocolVersion.Version) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) require.Equal(t, defines.MORPCVersion35, version) - require.Equal(t, []string{"peer:6001"}, queryClient.requests) - require.Equal(t, []query.CmdMethod{query.CmdMethod_GetCommit}, queryClient.methods) - require.Equal(t, 1, queryClient.releases) + require.Equal(t, []string{ + "peer:6001", "peer:6001", "self:6001", "peer:6001", "peer:6001", + }, queryClient.requests) + require.Equal(t, []query.CmdMethod{ + query.CmdMethod_GetProtocolVersion, + query.CmdMethod_GetProtocolVersion, + query.CmdMethod_GetCommit, + query.CmdMethod_GetCommit, + query.CmdMethod_GetProtocolVersion, + }, queryClient.methods) + require.Equal(t, 5, queryClient.releases) require.Len(t, hakeeperClient.heartbeats, 2) - require.False(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) + require.True(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) require.False(t, hakeeperClient.heartbeats[0].ViewMetadataIngressReady) require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityBarrierReady) require.True(t, hakeeperClient.heartbeats[1].ViewMetadataIngressReady) - require.Equal(t, 2, cluster.refreshCalls) + require.Equal(t, 5, cluster.refreshCalls) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.True(t, s.viewMetadataIngressReady.Load()) @@ -375,8 +450,8 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { require.NoError(t, s.handleSetProtocolVersion(context.Background(), req, resp, nil)) require.Equal(t, defines.MORPCVersion35, resp.SetProtocolVersion.Version) require.Len(t, hakeeperClient.heartbeats, 2) - require.Equal(t, 2, cluster.refreshCalls) - require.Len(t, queryClient.requests, 1) + require.Equal(t, 5, cluster.refreshCalls) + require.Len(t, queryClient.requests, 5) } func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T) { @@ -395,7 +470,10 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T }} queryClient := &ddlVisibilityTestQueryClient{ serviceID: serviceID, - frontiers: map[string]timestamp.Timestamp{"peer:6001": targetTS}, + frontiers: map[string]timestamp.Timestamp{ + "self:6001": {PhysicalTime: 200}, "peer:6001": targetTS, + }, + protocols: activationTestPeerProtocols(), } ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) @@ -413,6 +491,7 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T _txnClient: txnClient, config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: frontend.NewDDLCommitGate(), } s.ddlVisibilityBarrierPrepared.Store(true) s.ddlVisibilityBarrierReady.Store(true) @@ -420,18 +499,26 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T resp := &query.Response{} err := s.handleSetProtocolVersion(context.Background(), &query.Request{ - SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion35}, + SetProtocolVersion: &query.SetProtocolVersionRequest{ + Version: defines.MORPCVersion35, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, + }, }, resp, nil) require.ErrorIs(t, err, syncErr) require.Nil(t, resp.SetProtocolVersion) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion34, version) + require.Equal(t, defines.MORPCVersion35, version) + require.True(t, s.ddlVisibilityActivationPending.Load()) + require.True(t, s.ddlVisibilityActivationPrepared.Load()) + require.False(t, s.ddlVisibilityActivationFenced.Load()) + blockedCtx, cancelBlocked := context.WithCancel(context.Background()) + cancelBlocked() + _, gateErr := s.ddlCommitGate.Enter(blockedCtx) + require.ErrorIs(t, gateErr, context.Canceled) require.Len(t, hakeeperClient.heartbeats, 1) - require.False(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) - require.False(t, s.ddlVisibilityBarrierReady.Load()) + require.True(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) require.False(t, s.viewMetadataIngressReady.Load()) - require.False(t, cluster.cnServices[0].DDLVisibilityBarrierReady) + require.True(t, cluster.cnServices[0].DDLVisibilityBarrierReady) } func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing.T) { @@ -450,7 +537,10 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing }} queryClient := &ddlVisibilityTestQueryClient{ serviceID: serviceID, - frontiers: map[string]timestamp.Timestamp{"peer:6001": targetTS}, + frontiers: map[string]timestamp.Timestamp{ + "self:6001": {PhysicalTime: 200}, "peer:6001": targetTS, + }, + protocols: activationTestPeerProtocols(), } ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) @@ -471,26 +561,34 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing _txnClient: txnClient, config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: frontend.NewDDLCommitGate(), } s.ddlVisibilityBarrierPrepared.Store(true) s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) err := s.handleSetProtocolVersion(context.Background(), &query.Request{ - SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion35}, + SetProtocolVersion: &query.SetProtocolVersionRequest{ + Version: defines.MORPCVersion35, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, + }, }, &query.Response{}, nil) require.ErrorIs(t, err, publishErr) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion34, version) + require.Equal(t, defines.MORPCVersion35, version) + require.True(t, s.ddlVisibilityActivationPending.Load()) + require.True(t, s.ddlVisibilityActivationFenced.Load()) + blockedCtx, cancelBlocked := context.WithCancel(context.Background()) + cancelBlocked() + _, gateErr := s.ddlCommitGate.Enter(blockedCtx) + require.ErrorIs(t, gateErr, context.Canceled) require.Len(t, hakeeperClient.heartbeats, 3) - require.False(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) + require.True(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityBarrierReady) - require.False(t, hakeeperClient.heartbeats[2].DDLVisibilityBarrierReady) - require.False(t, s.ddlVisibilityBarrierReady.Load()) + require.True(t, hakeeperClient.heartbeats[2].DDLVisibilityBarrierReady) require.False(t, s.viewMetadataIngressReady.Load()) - require.False(t, cluster.cnServices[0].DDLVisibilityBarrierReady) - require.Equal(t, 2, cluster.refreshCalls) + require.True(t, cluster.cnServices[0].DDLVisibilityBarrierReady) + require.Equal(t, 4, cluster.refreshCalls) } func TestSetProtocolVersionBeforeBarrierPreparationDefersToStartupFence(t *testing.T) { @@ -500,7 +598,7 @@ func TestSetProtocolVersionBeforeBarrierPreparationDefersToStartupFence(t *testi moruntime.SetupServiceBasedRuntime(serviceID, rt) s := &service{cfg: &Config{UUID: serviceID}} - require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion35)) + require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion35, nil)) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) require.Equal(t, defines.MORPCVersion35, version) @@ -519,8 +617,28 @@ func TestInitQueryCommandHandlerOverridesProtocolActivation(t *testing.T) { s := &service{cfg: &Config{UUID: serviceID}, queryService: queryService} s.ddlVisibilityBarrierPrepared.Store(true) s.ddlVisibilityBarrierClosing.Store(true) + s.ddlVisibilityActivationPrepared.Store(true) + s.ddlVisibilityActivationFenced.Store(true) s.initQueryCommandHandler() + getHandler, ok := queryService.handlers[query.CmdMethod_GetProtocolVersion] + require.True(t, ok) + getResp := &query.Response{} + require.NoError(t, getHandler(context.Background(), &query.Request{ + GetProtocolVersion: &query.GetProtocolVersionRequest{}, + }, getResp, nil)) + require.Equal(t, defines.MORPCVersion34, getResp.GetProtocolVersion.Version) + require.True(t, getResp.GetProtocolVersion.DDLVisibilityActivationPrepared) + require.True(t, getResp.GetProtocolVersion.DDLVisibilityActivationFenced) + require.ErrorContains(t, + getHandler(context.Background(), &query.Request{}, &query.Response{}, nil), + "bad request") + rt.SetGlobalVariables(moruntime.MOProtocolVersion, "invalid") + require.ErrorContains(t, getHandler(context.Background(), &query.Request{ + GetProtocolVersion: &query.GetProtocolVersionRequest{}, + }, &query.Response{}, nil), "invalid protocol version") + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion34) + handler, ok := queryService.handlers[query.CmdMethod_SetProtocolVersion] require.True(t, ok) resp := &query.Response{} @@ -543,7 +661,7 @@ func TestSetProtocolVersionRejectsActivationDuringClose(t *testing.T) { s.ddlVisibilityBarrierPrepared.Store(true) s.ddlVisibilityBarrierClosing.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion35) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion35, nil) require.ErrorContains(t, err, "CN is closing") version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) @@ -567,6 +685,104 @@ func TestWithdrawDDLVisibilityBarrierHandlesPartialService(t *testing.T) { }) } +func TestValidateDDLVisibilityActivationTargets(t *testing.T) { + _, err := validateDDLVisibilityActivationTargets("self", []string{"self", ""}) + require.ErrorContains(t, err, "empty") + _, err = validateDDLVisibilityActivationTargets("self", []string{"self", "self"}) + require.ErrorContains(t, err, "duplicated") + _, err = validateDDLVisibilityActivationTargets("self", []string{"peer"}) + require.ErrorContains(t, err, "do not include local CN") + targets, err := validateDDLVisibilityActivationTargets("self", []string{"self", "peer"}) + require.NoError(t, err) + require.Equal(t, map[string]struct{}{"self": {}, "peer": {}}, targets) +} + +func TestSetProtocolVersionDowngradeAndPendingGuard(t *testing.T) { + const serviceID = "ddl-visibility-downgrade-test" + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion35) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + s := &service{cfg: &Config{UUID: serviceID}} + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityActivationPrepared.Store(true) + s.ddlVisibilityActivationFenced.Store(true) + + require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil)) + version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion34, version) + require.False(t, s.ddlVisibilityActivationPrepared.Load()) + require.False(t, s.ddlVisibilityActivationFenced.Load()) + + s.ddlVisibilityActivationPending.Store(true) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil) + require.ErrorContains(t, err, "cannot downgrade") +} + +func TestWaitForDDLVisibilityActivationPhaseRejectsInvalidInventory(t *testing.T) { + const serviceID = "activation-phase-inventory-test" + newService := func(cluster *ddlVisibilityTestCluster, queryClient *ddlVisibilityTestQueryClient) *service { + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + s := &service{cfg: cfg, moCluster: cluster, queryClient: queryClient} + s.ddlVisibilityActivationPrepared.Store(true) + s.ddlVisibilityActivationFenced.Store(true) + return s + } + targets := map[string]struct{}{serviceID: {}, "peer": {}} + + t.Run("target address is required", func(t *testing.T) { + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ + {ServiceID: serviceID, DDLVisibilityBarrierReady: true}, + {ServiceID: "peer", DDLVisibilityBarrierReady: true}, + }} + s := newService(cluster, &ddlVisibilityTestQueryClient{}) + err := s.waitForDDLVisibilityActivationPhase(context.Background(), targets, false) + require.ErrorContains(t, err, "has no query address") + }) + + t.Run("protocol response is required", func(t *testing.T) { + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ + {ServiceID: serviceID, QueryAddress: "self:6001", DDLVisibilityBarrierReady: true}, + {ServiceID: "peer", QueryAddress: "peer:6001", DDLVisibilityBarrierReady: true}, + }} + s := newService(cluster, &ddlVisibilityTestQueryClient{ + nilProtocol: map[string]bool{"peer:6001": true}, + }) + err := s.waitForDDLVisibilityActivationPhase(context.Background(), targets, false) + require.ErrorContains(t, err, "missing protocol activation response") + }) + + t.Run("target list must include every barrier participant", func(t *testing.T) { + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ + {ServiceID: serviceID, DDLVisibilityBarrierReady: true}, + {ServiceID: "peer", DDLVisibilityBarrierReady: true}, + {ServiceID: "extra", DDLVisibilityBarrierReady: true}, + }} + s := newService(cluster, &ddlVisibilityTestQueryClient{}) + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + defer cancel() + err := s.waitForDDLVisibilityActivationPhase(ctx, targets, false) + require.ErrorContains(t, err, "did not converge") + }) +} + +func TestWaitForDDLVisibilityIngressHonorsCancellation(t *testing.T) { + const serviceID = "ddl-visibility-ingress-cancel-test" + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, ViewMetadataAdmissionGeneration: 1, + DDLVisibilityBarrierReady: true, ViewMetadataIngressReady: true, + }}} + s := &service{ + cfg: &Config{UUID: serviceID}, moCluster: cluster, + viewMetadataAdmissionGeneration: 1, + } + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + defer cancel() + err := s.waitForDDLVisibilityIngress(ctx, time.Second, false) + require.ErrorContains(t, err, "was not published") +} + func TestWaitForDDLVisibilityBarrierPublicationHonorsCancellation(t *testing.T) { cluster := &ddlVisibilityTestCluster{} s := &service{ @@ -595,6 +811,8 @@ func TestServiceCloseWithdrawsDDLVisibilityBeforeQueryService(t *testing.T) { require.False(t, state.cluster.cnServices[0].DDLVisibilityBarrierReady) require.Equal(t, 1, state.hakeeperClient.closeCalls) require.Equal(t, 2, state.lockService.closeCalls) + _, err := state.service.ddlCommitGate.Enter(context.Background()) + require.ErrorContains(t, err, "closed") select { case <-state.queryService.closed: default: diff --git a/pkg/cnservice/server_query.go b/pkg/cnservice/server_query.go index 26105113a6a24..606c9dbb22244 100644 --- a/pkg/cnservice/server_query.go +++ b/pkg/cnservice/server_query.go @@ -143,6 +143,7 @@ func (s *service) initQueryCommandHandler() { // Override queryservice's generic runtime-only setter so a live CN can // execute the v35 DDL visibility activation fence before acknowledging the // protocol transition. + s.addQueryCommandHandler(query.CmdMethod_GetProtocolVersion, s.handleGetProtocolVersion) s.addQueryCommandHandler(query.CmdMethod_SetProtocolVersion, s.handleSetProtocolVersion) s.addQueryCommandHandler(query.CmdMethod_KillConn, s.handleKillConn) s.addQueryCommandHandler(query.CmdMethod_AlterAccount, s.handleAlterAccount) @@ -209,6 +210,31 @@ func (s *service) closeQueryService() error { }) } +func (s *service) handleGetProtocolVersion( + ctx context.Context, + req *query.Request, + resp *query.Response, + _ *morpc.Buffer, +) error { + if req == nil || req.GetProtocolVersion == nil { + return moerr.NewInternalError(ctx, "bad request") + } + value, ok := moruntime.ServiceRuntime(s.cfg.UUID).GetGlobalVariables(moruntime.MOProtocolVersion) + if !ok { + return moerr.NewInternalError(ctx, "protocol version not found") + } + version, ok := value.(int64) + if !ok { + return moerr.NewInternalError(ctx, "invalid protocol version") + } + resp.GetProtocolVersion = &query.GetProtocolVersionResponse{ + Version: version, + DDLVisibilityActivationPrepared: s.ddlVisibilityActivationPrepared.Load(), + DDLVisibilityActivationFenced: s.ddlVisibilityActivationFenced.Load(), + } + return nil +} + func (s *service) handleSetProtocolVersion( ctx context.Context, req *query.Request, @@ -219,7 +245,8 @@ func (s *service) handleSetProtocolVersion( return moerr.NewInternalError(ctx, "bad request") } version := req.SetProtocolVersion.Version - if err := s.setProtocolVersion(ctx, version); err != nil { + if err := s.setProtocolVersion( + ctx, version, req.SetProtocolVersion.DDLVisibilityActivationTargets); err != nil { return err } resp.SetProtocolVersion = &query.SetProtocolVersionResponse{Version: version} diff --git a/pkg/cnservice/types.go b/pkg/cnservice/types.go index e85b6a8cba365..dc40fd316999b 100644 --- a/pkg/cnservice/types.go +++ b/pkg/cnservice/types.go @@ -802,7 +802,11 @@ type service struct { ddlVisibilityBarrierReady atomic.Bool ddlVisibilityBarrierPrepared atomic.Bool ddlVisibilityBarrierClosing atomic.Bool + ddlVisibilityActivationPending atomic.Bool + ddlVisibilityActivationPrepared atomic.Bool + ddlVisibilityActivationFenced atomic.Bool ddlVisibilityBarrierMu sync.Mutex + ddlCommitGate *frontend.DDLCommitGate viewMetadataGenerationRevoked atomic.Bool viewMetadataRevocationOnce sync.Once // viewMetadataCloseFn is a deterministic test hook for the asynchronous diff --git a/pkg/frontend/ddl_commit_gate.go b/pkg/frontend/ddl_commit_gate.go new file mode 100644 index 0000000000000..95c2f819ceaea --- /dev/null +++ b/pkg/frontend/ddl_commit_gate.go @@ -0,0 +1,144 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package frontend + +import ( + "context" + "sync" + + "github.com/matrixorigin/matrixone/pkg/common/moerr" + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" +) + +const DDLCommitGateRuntimeKey = "frontend.ddl-commit-gate" + +// DDLCommitGate gives DDL producers and live protocol activation one local +// linearization point. Enter admits a commit while Block prevents new commits +// and waits for already-admitted commits to leave. A failed activation may keep +// the gate blocked across RPC attempts; Close wakes blocked sessions during CN +// shutdown. +type DDLCommitGate struct { + mu sync.Mutex + changed chan struct{} + blocked bool + closed bool + active int + // enterBlockedHook is a deterministic test hook invoked after Enter observes + // a blocked gate and before it waits. Production leaves it nil. + enterBlockedHook func() +} + +func NewDDLCommitGate() *DDLCommitGate { + return &DDLCommitGate{changed: make(chan struct{})} +} + +func enterDDLCommitGate(ctx context.Context, serviceID string) (func(), error) { + value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(DDLCommitGateRuntimeKey) + if !ok || value == nil { + return func() {}, nil + } + gate, ok := value.(*DDLCommitGate) + if !ok { + return nil, moerr.NewInternalError(ctx, "invalid DDL commit gate") + } + return gate.Enter(ctx) +} + +func (g *DDLCommitGate) Enter(ctx context.Context) (func(), error) { + for { + g.mu.Lock() + if g.closed { + g.mu.Unlock() + return nil, moerr.NewServiceUnavailableNoCtx("DDL commit gate is closed") + } + if !g.blocked { + g.active++ + g.mu.Unlock() + var once sync.Once + return func() { + once.Do(func() { + g.mu.Lock() + g.active-- + g.signalLocked() + g.mu.Unlock() + }) + }, nil + } + changed := g.changed + hook := g.enterBlockedHook + g.mu.Unlock() + if hook != nil { + hook() + } + + select { + case <-ctx.Done(): + return nil, context.Cause(ctx) + case <-changed: + } + } +} + +func (g *DDLCommitGate) Block(ctx context.Context) error { + g.mu.Lock() + if g.closed { + g.mu.Unlock() + return moerr.NewServiceUnavailableNoCtx("DDL commit gate is closed") + } + if !g.blocked { + g.blocked = true + g.signalLocked() + } + for g.active > 0 { + changed := g.changed + g.mu.Unlock() + select { + case <-ctx.Done(): + return context.Cause(ctx) + case <-changed: + } + g.mu.Lock() + if g.closed { + g.mu.Unlock() + return moerr.NewServiceUnavailableNoCtx("DDL commit gate is closed") + } + } + g.mu.Unlock() + return nil +} + +func (g *DDLCommitGate) Unblock() { + g.mu.Lock() + if !g.closed && g.blocked { + g.blocked = false + g.signalLocked() + } + g.mu.Unlock() +} + +func (g *DDLCommitGate) Close() { + g.mu.Lock() + if !g.closed { + g.closed = true + g.blocked = true + g.signalLocked() + } + g.mu.Unlock() +} + +func (g *DDLCommitGate) signalLocked() { + close(g.changed) + g.changed = make(chan struct{}) +} diff --git a/pkg/frontend/ddl_commit_gate_test.go b/pkg/frontend/ddl_commit_gate_test.go new file mode 100644 index 0000000000000..8a80cd283c9af --- /dev/null +++ b/pkg/frontend/ddl_commit_gate_test.go @@ -0,0 +1,83 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package frontend + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestDDLCommitGateLinearizesBlockAndCommit(t *testing.T) { + gate := NewDDLCommitGate() + releaseFirst, err := gate.Enter(context.Background()) + require.NoError(t, err) + + gate.mu.Lock() + blockStarted := gate.changed + gate.mu.Unlock() + blockDone := make(chan error, 1) + go func() { blockDone <- gate.Block(context.Background()) }() + <-blockStarted // Block has published blocked=true. + select { + case err := <-blockDone: + t.Fatalf("block returned before the admitted DDL left: %v", err) + default: + } + releaseFirst() + require.NoError(t, <-blockDone) + + enterDone := make(chan error, 1) + go func() { + release, enterErr := gate.Enter(context.Background()) + if enterErr == nil { + release() + } + enterDone <- enterErr + }() + gate.mu.Lock() + require.True(t, gate.blocked) + require.Zero(t, gate.active) + gate.mu.Unlock() + select { + case err := <-enterDone: + t.Fatalf("DDL entered while activation held the gate: %v", err) + default: + } + gate.Unblock() + require.NoError(t, <-enterDone) +} + +func TestDDLCommitGateCancellationAndClose(t *testing.T) { + gate := NewDDLCommitGate() + release, err := gate.Enter(context.Background()) + require.NoError(t, err) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err = gate.Block(ctx) + require.ErrorIs(t, err, context.Canceled) + release() + require.NoError(t, gate.Block(context.Background()), + "a canceled activation must retain the producer fence for a safe retry") + _, err = gate.Enter(ctx) + require.ErrorIs(t, err, context.Canceled) + + gate.Close() + _, err = gate.Enter(context.Background()) + require.ErrorContains(t, err, "closed") + err = gate.Block(context.Background()) + require.ErrorContains(t, err, "closed") +} diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index 035d5226215f0..5543d452ceb6c 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -875,6 +875,13 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { } tempTxnKey := tempTableTxnKey(th.txnOp) haveDDL := th.txnOp.GetWorkspace().GetHaveDDL() + if haveDDL { + releaseDDLCommit, gateErr := enterDDLCommitGate(ctx2, execCtx.ses.GetService()) + if gateErr != nil { + return gateErr + } + defer releaseDDLCommit() + } execCtx.ses.SetTxnId(th.txnOp.Txn().ID) commitResultUnknown := false err, hasRecovered = ExecuteFuncWithRecover(func() error { diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index b2648658a3d29..30962c2096ac8 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -982,6 +982,36 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { require.Nil(t, ses.GetTxnHandler().GetTxn()) }) + t.Run("activation gate drains and blocks concurrent DDL commit", func(t *testing.T) { + ses, op, _, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + gate := NewDDLCommitGate() + require.NoError(t, gate.Block(context.Background())) + var once sync.Once + commitWaiting := make(chan struct{}) + gate.enterBlockedHook = func() { once.Do(func() { close(commitWaiting) }) } + rt := moruntime.ServiceRuntime(ses.GetService()) + previousGate, hadPreviousGate := rt.GetGlobalVariables(DDLCommitGateRuntimeKey) + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, gate) + t.Cleanup(func() { + if hadPreviousGate { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, previousGate) + } else { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, nil) + } + }) + + commitDone := make(chan error, 1) + go func() { commitDone <- ses.GetTxnHandler().Commit(execCtx) }() + <-commitWaiting + require.Zero(t, op.commitCalls, + "DDL commit must not cross the activation linearization point") + gate.Unblock() + require.NoError(t, <-commitDone) + require.Equal(t, 1, op.commitCalls) + }) + t.Run("retries when a CN becomes barrier-ready during fan-out", func(t *testing.T) { ses, op, qc, execCtx := newState(t) defer ses.Close() diff --git a/pkg/hakeeper/rsm.go b/pkg/hakeeper/rsm.go index 1f09abdf71bf2..ac3cc734945d5 100644 --- a/pkg/hakeeper/rsm.go +++ b/pkg/hakeeper/rsm.go @@ -1750,6 +1750,7 @@ func (s *stateMachine) handleClusterDetailsQuery(cfg Config) *pb.ClusterDetails ViewMetadataObservedEpoch: info.ViewMetadataObservedEpoch, ViewMetadataAdmissionReady: info.ViewMetadataAdmissionReady, DDLVisibilityBarrierReady: info.DDLVisibilityBarrierReady, + ViewMetadataIngressReady: info.ViewMetadataIngressReady, } cd.CNStores = append(cd.CNStores, n) } diff --git a/pkg/hakeeper/view_metadata_admission_test.go b/pkg/hakeeper/view_metadata_admission_test.go index 787ff2250308a..91335a14d9e35 100644 --- a/pkg/hakeeper/view_metadata_admission_test.go +++ b/pkg/hakeeper/view_metadata_admission_test.go @@ -632,6 +632,7 @@ func TestClusterDetailsKeepsSupportedPendingButHidesLegacyIngress(t *testing.T) require.False(t, byID["pending"].ViewMetadataAdmissionReady) require.True(t, byID["pending"].DDLVisibilityBarrierReady) require.Contains(t, byID, "ready") + require.True(t, byID["ready"].ViewMetadataIngressReady) require.NotContains(t, byID, "legacy") } diff --git a/pkg/pb/logservice/logservice.pb.go b/pkg/pb/logservice/logservice.pb.go index 0f7378d0bcab3..142cf6abf721d 100644 --- a/pkg/pb/logservice/logservice.pb.go +++ b/pkg/pb/logservice/logservice.pb.go @@ -532,10 +532,12 @@ type CNStore struct { ViewMetadataAdmissionReady bool `protobuf:"varint,20,opt,name=ViewMetadataAdmissionReady,proto3" json:"ViewMetadataAdmissionReady,omitempty"` // DDLVisibilityBarrierReady means QueryService can accept the versioned DDL // visibility fence even when public SQL ingress is not admitted yet. - DDLVisibilityBarrierReady bool `protobuf:"varint,21,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + DDLVisibilityBarrierReady bool `protobuf:"varint,21,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` + // ViewMetadataIngressReady is retained for raw control-plane inventory. + ViewMetadataIngressReady bool `protobuf:"varint,22,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNStore) Reset() { *m = CNStore{} } @@ -711,6 +713,13 @@ func (m *CNStore) GetDDLVisibilityBarrierReady() bool { return false } +func (m *CNStore) GetViewMetadataIngressReady() bool { + if m != nil { + return m.ViewMetadataIngressReady + } + return false +} + type TNStore struct { UUID string `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"` ServiceAddress string `protobuf:"bytes,2,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` @@ -6491,380 +6500,380 @@ func init() { func init() { proto.RegisterFile("logservice.proto", fileDescriptor_fd1040c5381ab5a7) } var fileDescriptor_fd1040c5381ab5a7 = []byte{ - // 5959 bytes of a gzipped FileDescriptorProto + // 5968 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xdd, 0x6f, 0x1b, 0xd9, - 0x75, 0xb8, 0x87, 0xa2, 0x24, 0xf2, 0x50, 0x92, 0x47, 0x57, 0x92, 0x4d, 0xcb, 0xb6, 0xac, 0xe5, + 0x75, 0xb8, 0x87, 0xa2, 0x24, 0xf2, 0x50, 0x92, 0x47, 0x57, 0x1f, 0xa6, 0xb5, 0xb6, 0xac, 0xe5, 0x3a, 0xbb, 0x5e, 0x65, 0x23, 0xe7, 0x67, 0x67, 0x17, 0x9b, 0xfc, 0x1c, 0xef, 0x52, 0x24, 0xd7, 0xa2, 0x4d, 0x53, 0xda, 0xe1, 0xc8, 0x9b, 0x04, 0x58, 0x08, 0x23, 0xf1, 0x5a, 0x9e, 0x88, 0xe2, - 0x30, 0x33, 0x23, 0xaf, 0xdd, 0xbe, 0x15, 0x4d, 0x51, 0x34, 0x45, 0xd1, 0x00, 0x41, 0x93, 0x36, + 0x30, 0x33, 0x23, 0xaf, 0xdd, 0xbe, 0x15, 0x4d, 0x51, 0x34, 0x40, 0xd1, 0x00, 0x41, 0x93, 0x36, 0x4d, 0xbf, 0xde, 0xfa, 0x94, 0x97, 0xf6, 0x5f, 0x28, 0xf2, 0x54, 0x04, 0x79, 0xcc, 0x43, 0x9a, - 0x6c, 0x5f, 0x0a, 0xe4, 0xb5, 0x68, 0xd0, 0x87, 0x02, 0xc5, 0xfd, 0x9a, 0xb9, 0x77, 0xe6, 0x0e, - 0x49, 0x7d, 0x24, 0x69, 0x82, 0x3c, 0x89, 0xf7, 0x7c, 0xdc, 0xcf, 0x73, 0xce, 0x3d, 0xf7, 0xdc, - 0x73, 0x47, 0x60, 0xf6, 0xbc, 0x83, 0x00, 0xfb, 0xcf, 0xdd, 0x7d, 0xbc, 0x3e, 0xf0, 0xbd, 0xd0, - 0x43, 0x10, 0x43, 0x96, 0x3f, 0x73, 0xe0, 0x86, 0xcf, 0x8e, 0xf7, 0xd6, 0xf7, 0xbd, 0xa3, 0xdb, - 0x07, 0xde, 0x81, 0x77, 0x9b, 0x92, 0xec, 0x1d, 0x3f, 0xa5, 0x25, 0x5a, 0xa0, 0xbf, 0x18, 0xeb, - 0xf2, 0x8d, 0x03, 0xcf, 0x3b, 0xe8, 0xe1, 0x98, 0x2a, 0x74, 0x8f, 0x70, 0x10, 0x3a, 0x47, 0x03, - 0x4e, 0x30, 0x77, 0x84, 0x43, 0xa7, 0xeb, 0x84, 0x0e, 0x2b, 0x57, 0xfe, 0xb4, 0x00, 0xd3, 0xb5, - 0x76, 0x27, 0xf4, 0x7c, 0x8c, 0x10, 0xe4, 0x77, 0x76, 0x9a, 0xf5, 0xb2, 0xb1, 0x6a, 0xdc, 0x2a, - 0x5a, 0xf4, 0x37, 0x7a, 0x0d, 0xe6, 0x3a, 0xac, 0x2b, 0xd5, 0x6e, 0xd7, 0xc7, 0x41, 0x50, 0xce, - 0x51, 0x6c, 0x02, 0x8a, 0x56, 0x00, 0x3a, 0x1f, 0xb4, 0x04, 0xcd, 0x04, 0xa5, 0x91, 0x20, 0x68, - 0x1d, 0x50, 0xcb, 0xdb, 0x3f, 0x4c, 0xd4, 0x95, 0xa7, 0x74, 0x1a, 0x0c, 0xba, 0x09, 0x79, 0xcb, - 0xeb, 0xe1, 0xf2, 0xd4, 0xaa, 0x71, 0x6b, 0xee, 0x8e, 0xb9, 0x1e, 0x75, 0xbb, 0xd6, 0x26, 0x70, - 0x8b, 0x62, 0x49, 0x8f, 0x6d, 0x77, 0xff, 0xb0, 0x3c, 0xbd, 0x6a, 0xdc, 0xca, 0x5b, 0xf4, 0x37, - 0xfa, 0x34, 0x4c, 0x76, 0x42, 0x27, 0xc4, 0xe5, 0x02, 0x65, 0x5d, 0x5a, 0x97, 0xe6, 0xb7, 0xed, - 0x75, 0x31, 0x45, 0x5a, 0x8c, 0x06, 0x7d, 0x11, 0xa6, 0x5a, 0xce, 0x1e, 0xee, 0x05, 0xe5, 0xe2, - 0xea, 0xc4, 0xad, 0xd2, 0x9d, 0x1b, 0x32, 0x35, 0x9f, 0x97, 0x75, 0x46, 0xd1, 0xe8, 0x87, 0xfe, - 0xcb, 0x8d, 0xfc, 0x0f, 0x7e, 0x72, 0xe3, 0x82, 0xc5, 0x99, 0xd0, 0xff, 0x83, 0xe2, 0x87, 0x9e, - 0x7f, 0xc8, 0xda, 0x03, 0xda, 0xde, 0x42, 0xdc, 0xd5, 0x08, 0x65, 0xc5, 0x54, 0xa8, 0x02, 0x33, - 0x1f, 0x1c, 0x63, 0xff, 0xa5, 0x98, 0x82, 0x12, 0x9d, 0x02, 0x05, 0x86, 0xde, 0x06, 0xa8, 0x79, - 0xfd, 0xa7, 0xee, 0x41, 0xdd, 0x09, 0x9d, 0xf2, 0xcc, 0xaa, 0x71, 0xab, 0x74, 0xe7, 0x92, 0xd2, - 0xb3, 0x08, 0x6b, 0x49, 0x94, 0xe8, 0x6d, 0x28, 0x58, 0x38, 0xf0, 0x8e, 0xfd, 0x7d, 0x5c, 0x9e, - 0xa5, 0x5c, 0x8b, 0x32, 0x97, 0xc0, 0xf1, 0x41, 0x44, 0xb4, 0xe8, 0x12, 0x4c, 0xed, 0x0c, 0x6c, - 0xf7, 0x08, 0x97, 0xe7, 0x56, 0x8d, 0x5b, 0x13, 0x16, 0x2f, 0xa1, 0xcf, 0xc2, 0x42, 0xe7, 0x99, - 0xe3, 0x77, 0x13, 0xab, 0x76, 0x91, 0x76, 0x59, 0x87, 0x42, 0xcb, 0x50, 0xa8, 0x79, 0x47, 0x47, - 0x6e, 0xd8, 0xac, 0x97, 0x4d, 0x4a, 0x16, 0x95, 0xd1, 0xfb, 0xb0, 0xf2, 0xc4, 0xc5, 0x1f, 0x3f, - 0xe6, 0xd3, 0x53, 0xed, 0x1e, 0xb9, 0x41, 0xe0, 0x7a, 0xfd, 0xce, 0xf1, 0x60, 0xe0, 0xf9, 0x21, - 0xee, 0x96, 0xe7, 0x57, 0x8d, 0x5b, 0x05, 0x6b, 0x04, 0x15, 0xda, 0x84, 0x1b, 0x5a, 0x8a, 0x07, - 0xb8, 0x8f, 0x7d, 0x27, 0x74, 0xbd, 0x7e, 0x19, 0x51, 0x79, 0x18, 0x45, 0x86, 0xee, 0xc1, 0x15, - 0x99, 0x64, 0x6b, 0x8f, 0xcc, 0x14, 0xee, 0x36, 0x06, 0xde, 0xfe, 0xb3, 0xf2, 0x02, 0xad, 0x23, - 0x9b, 0x00, 0xdd, 0x87, 0x65, 0x6d, 0x03, 0x16, 0x76, 0xba, 0x2f, 0xcb, 0x8b, 0x74, 0x2c, 0x43, - 0x28, 0x48, 0xeb, 0xf5, 0x7a, 0xeb, 0x89, 0x1b, 0xb8, 0x7b, 0x6e, 0xcf, 0x0d, 0x5f, 0x6e, 0x38, - 0xbe, 0xef, 0x62, 0x9f, 0xb1, 0x2f, 0x51, 0xf6, 0x6c, 0x82, 0xe5, 0x36, 0x94, 0x24, 0xb9, 0x44, - 0x26, 0x4c, 0x1c, 0xe2, 0x97, 0x5c, 0x75, 0xc9, 0x4f, 0xf4, 0x06, 0x4c, 0x3e, 0x77, 0x7a, 0xc7, - 0x98, 0x2a, 0x6c, 0x49, 0x96, 0x4b, 0xca, 0xd7, 0x72, 0x83, 0xd0, 0x62, 0x14, 0x5f, 0xc8, 0xbd, - 0x63, 0x3c, 0xcc, 0x17, 0x26, 0xcd, 0xa9, 0xca, 0x2f, 0x26, 0x60, 0xda, 0x3e, 0x07, 0x73, 0x20, - 0x14, 0x73, 0x42, 0xa7, 0x98, 0xf9, 0x31, 0x14, 0xf3, 0x2d, 0x98, 0xa2, 0xf2, 0x15, 0x94, 0x27, - 0xa9, 0x62, 0x5e, 0x96, 0xa9, 0xed, 0x36, 0xc5, 0x35, 0xfb, 0x4f, 0x3d, 0xa1, 0x90, 0x8c, 0x18, - 0xdd, 0x81, 0xc5, 0x96, 0x77, 0x10, 0x3a, 0x6e, 0x8f, 0x74, 0x08, 0xfb, 0xa2, 0x97, 0x53, 0xb4, - 0x97, 0x5a, 0x5c, 0x86, 0x69, 0x9a, 0xce, 0x34, 0x4d, 0xaa, 0x76, 0x16, 0xc7, 0xd6, 0xce, 0xa4, - 0xe6, 0x83, 0x46, 0xf3, 0x33, 0x34, 0xae, 0x94, 0xad, 0x71, 0xef, 0xc1, 0xd5, 0xea, 0x71, 0xe8, - 0x35, 0xfb, 0xfb, 0x3e, 0x15, 0xcb, 0xf7, 0x71, 0x7f, 0x1f, 0xc7, 0x2a, 0x35, 0x43, 0xe5, 0x68, - 0x18, 0xc9, 0xc3, 0x7c, 0xa1, 0x60, 0x16, 0x2b, 0xff, 0x9c, 0x83, 0x42, 0xcb, 0x3b, 0xf8, 0x3f, - 0xb0, 0xf4, 0xf7, 0x88, 0x15, 0x1b, 0xf4, 0xdc, 0x7d, 0x47, 0x2c, 0xfe, 0xb2, 0x4c, 0xdf, 0xf2, - 0x0e, 0x38, 0x5a, 0x5a, 0xff, 0x88, 0x23, 0xb1, 0x3a, 0x53, 0x27, 0xb1, 0x9d, 0x2d, 0x6f, 0xdf, - 0x21, 0x7a, 0x46, 0xd7, 0x3e, 0x61, 0x3b, 0x05, 0x4e, 0xb4, 0x27, 0xca, 0x95, 0x6f, 0x4d, 0xc0, - 0x0c, 0x99, 0x37, 0x21, 0x90, 0xa8, 0x0c, 0xd3, 0xac, 0xc0, 0xa6, 0x2f, 0x6f, 0x89, 0x22, 0xda, - 0x90, 0x06, 0x96, 0xa3, 0x03, 0x7b, 0x2d, 0x31, 0xb0, 0xa8, 0x96, 0x75, 0x41, 0x48, 0xb5, 0x5b, - 0x1a, 0xde, 0x22, 0x4c, 0x32, 0xf3, 0xc4, 0xa6, 0x97, 0x15, 0x88, 0xd9, 0x6d, 0x61, 0xa7, 0x8b, - 0xfd, 0x66, 0x9d, 0x4e, 0x71, 0xde, 0x8a, 0xca, 0x74, 0x3d, 0xb0, 0x7f, 0x54, 0x9e, 0xe4, 0xeb, - 0x81, 0xfd, 0x23, 0xf4, 0x11, 0xcc, 0xb7, 0xbd, 0xfe, 0x13, 0x2f, 0x74, 0xfb, 0x07, 0x51, 0x97, - 0xa6, 0x68, 0x97, 0x6e, 0x67, 0x76, 0x29, 0xc5, 0xc1, 0xfa, 0x96, 0xae, 0x69, 0xf9, 0xff, 0xc3, - 0xac, 0x42, 0x23, 0x5b, 0xa7, 0x3c, 0xb3, 0x4e, 0x8b, 0xb2, 0x75, 0x2a, 0x4a, 0x86, 0x68, 0xb9, - 0x0e, 0x97, 0xf4, 0x2d, 0x9d, 0xa4, 0x96, 0xca, 0x77, 0x0c, 0x98, 0x53, 0x25, 0x05, 0xbd, 0xaf, - 0x2e, 0x14, 0xad, 0xa7, 0x74, 0xa7, 0x9c, 0x35, 0xde, 0x8d, 0x02, 0x59, 0xe9, 0x1f, 0xfe, 0xe4, - 0x86, 0x61, 0xa9, 0x0b, 0x7c, 0x0d, 0x8a, 0xa2, 0xda, 0x3a, 0x6d, 0x38, 0x6f, 0xc5, 0x00, 0xb4, - 0x0a, 0xa5, 0x66, 0x10, 0x0d, 0x80, 0x2e, 0x53, 0xc1, 0x92, 0x41, 0x95, 0x3f, 0x31, 0xe2, 0x6d, - 0x9a, 0x6e, 0x98, 0xdb, 0x3b, 0xb6, 0x17, 0x3a, 0x3d, 0x3e, 0xb0, 0xa8, 0x4c, 0x0c, 0x46, 0x6d, - 0x7b, 0xa7, 0xfa, 0xdc, 0x71, 0x7b, 0xce, 0x5e, 0x8f, 0x0d, 0xd2, 0xb0, 0x14, 0x18, 0xe1, 0x7f, - 0x8c, 0x8f, 0x18, 0x3f, 0x13, 0x89, 0xa8, 0x4c, 0xf8, 0x1f, 0xe3, 0xa3, 0x98, 0x9f, 0x49, 0x86, - 0x02, 0xab, 0xfc, 0xb8, 0x08, 0x26, 0xf7, 0x73, 0x36, 0xb1, 0xe3, 0x87, 0x7b, 0xd8, 0x09, 0x7f, - 0x03, 0x1d, 0xc1, 0x75, 0x40, 0xb6, 0x13, 0x08, 0xde, 0x9a, 0x8f, 0x1d, 0x62, 0xfc, 0xa6, 0xe9, - 0xe4, 0x6b, 0x30, 0x29, 0x5b, 0x5c, 0xd0, 0xd8, 0xe2, 0x9b, 0x30, 0xdb, 0xec, 0xbb, 0x61, 0xec, - 0xe0, 0x15, 0x29, 0x91, 0x0a, 0x24, 0x54, 0x0f, 0xbc, 0x20, 0x70, 0x07, 0xaa, 0x59, 0x57, 0x81, - 0xa4, 0x3d, 0x06, 0x78, 0xe8, 0xb9, 0x7d, 0xdc, 0xa5, 0x06, 0xbd, 0x60, 0x29, 0xb0, 0x5f, 0xb9, - 0xd7, 0x97, 0xb1, 0xd7, 0xcc, 0x8d, 0xe7, 0xdd, 0x5d, 0x4c, 0x78, 0x77, 0x9f, 0x85, 0x85, 0xea, - 0xfe, 0x21, 0xee, 0x12, 0x80, 0xd3, 0xef, 0x6e, 0x38, 0xe1, 0xfe, 0x33, 0xee, 0x04, 0xe6, 0x2d, - 0x1d, 0x8a, 0xec, 0x5c, 0x1c, 0x52, 0xc7, 0x3d, 0xf7, 0x39, 0x99, 0xf9, 0xfd, 0xc3, 0xa4, 0x33, - 0x38, 0x8c, 0x64, 0x0c, 0x8f, 0x12, 0x9d, 0x97, 0x47, 0xb9, 0x70, 0x0e, 0x1e, 0xe5, 0xe2, 0x28, - 0x8f, 0x32, 0x31, 0x9e, 0x9a, 0x13, 0x3a, 0x3d, 0xef, 0x80, 0x6e, 0xd7, 0xbc, 0x8a, 0x25, 0x5a, - 0xc5, 0x08, 0x2a, 0xb4, 0x01, 0xd7, 0x64, 0x0a, 0x0b, 0x3f, 0xf5, 0x71, 0xf0, 0x2c, 0x9e, 0x95, - 0x4b, 0x74, 0x56, 0x86, 0xd2, 0xa4, 0xeb, 0x78, 0xee, 0xf4, 0xdc, 0x2e, 0x51, 0x1e, 0xd6, 0x93, - 0xcb, 0xb4, 0x27, 0x43, 0x69, 0xd0, 0x17, 0xa0, 0x2c, 0xe3, 0x9b, 0xfd, 0x03, 0x22, 0x46, 0xcc, - 0xc1, 0x2d, 0xd3, 0x3e, 0x64, 0xe2, 0x87, 0x7b, 0xc7, 0x57, 0x46, 0x78, 0xc7, 0xdc, 0x9b, 0xb5, - 0x61, 0xa6, 0xd6, 0xae, 0xf6, 0x7a, 0xde, 0xbe, 0x13, 0xe2, 0x66, 0x5d, 0xe3, 0x24, 0x2f, 0xc2, - 0x24, 0x15, 0x47, 0x6e, 0xc7, 0x59, 0x81, 0x59, 0xf8, 0xaf, 0x1d, 0xe3, 0x80, 0x08, 0x3a, 0x33, - 0x61, 0x31, 0xa0, 0xf2, 0xdf, 0x13, 0x30, 0x2f, 0x3c, 0xa5, 0xe1, 0x36, 0x73, 0x15, 0x4a, 0x96, - 0xf3, 0x34, 0x54, 0x0d, 0xa6, 0x0c, 0xd2, 0x58, 0xd5, 0x09, 0xad, 0x55, 0x4d, 0x59, 0x99, 0xbc, - 0xce, 0xca, 0x9c, 0xcd, 0x73, 0xd2, 0xdb, 0xd0, 0xa9, 0x4c, 0x1b, 0xaa, 0xda, 0xab, 0xe9, 0x53, - 0x79, 0x5a, 0x85, 0xf1, 0x3d, 0x2d, 0x22, 0x4d, 0x09, 0x63, 0x10, 0x4b, 0x74, 0x91, 0x49, 0x53, - 0x16, 0x7e, 0x0c, 0x4b, 0x01, 0xe3, 0x58, 0x8a, 0x4a, 0x03, 0x4a, 0xd2, 0xe1, 0x63, 0x88, 0xaf, - 0x37, 0xd4, 0x49, 0xa8, 0x7c, 0x7d, 0x12, 0x4c, 0xfb, 0x3c, 0x77, 0xdd, 0xf8, 0xb8, 0x34, 0x71, - 0x92, 0xe3, 0x92, 0x7e, 0xc9, 0xf3, 0x99, 0x4b, 0x9e, 0x75, 0xbc, 0x9a, 0x3c, 0xf1, 0xf1, 0x6a, - 0x6a, 0xcc, 0xe3, 0x55, 0xe1, 0xd4, 0xc7, 0xab, 0xe2, 0xf8, 0xc7, 0x2b, 0xc8, 0xde, 0xf2, 0x88, - 0x0a, 0xe3, 0x41, 0xcf, 0x79, 0x89, 0xbb, 0xad, 0xa0, 0x4f, 0xf7, 0xed, 0xbc, 0x25, 0x83, 0xce, - 0x7e, 0x00, 0xcb, 0xda, 0x3a, 0x67, 0x4f, 0xbd, 0x75, 0xce, 0x8d, 0xdc, 0x3a, 0x1f, 0xe6, 0x0b, - 0xd3, 0x66, 0xa1, 0xf2, 0xfd, 0x49, 0x28, 0x58, 0x9d, 0xc7, 0xcc, 0x93, 0x31, 0x61, 0xc2, 0x0e, - 0x3c, 0xe1, 0x5e, 0xdb, 0x81, 0x47, 0xac, 0x63, 0xb3, 0xdf, 0xc5, 0x2f, 0x84, 0x75, 0xa4, 0x05, - 0x62, 0x8b, 0x5a, 0xd8, 0x09, 0xf0, 0xa6, 0xd7, 0x63, 0x27, 0x0e, 0xe6, 0x77, 0xaa, 0x40, 0xb2, - 0x1c, 0xb6, 0x7f, 0xdc, 0x27, 0x96, 0x97, 0xce, 0x1c, 0x77, 0x3e, 0x65, 0x18, 0x7a, 0x08, 0x33, - 0x8c, 0xc9, 0x0d, 0x42, 0xcf, 0x7f, 0xc9, 0x6d, 0x96, 0x72, 0x28, 0x12, 0xbd, 0x5b, 0x97, 0x09, - 0xd9, 0xc1, 0x43, 0xe1, 0x65, 0x0b, 0xf5, 0xb5, 0x63, 0xd7, 0x67, 0xcd, 0x4d, 0x89, 0x85, 0x8a, - 0x40, 0xe8, 0x4d, 0x98, 0xff, 0xb0, 0xda, 0xb2, 0xf0, 0xbe, 0x47, 0x66, 0xa3, 0xee, 0x1e, 0xe0, - 0x20, 0xe4, 0xc7, 0xfc, 0x34, 0x02, 0x7d, 0x0e, 0x96, 0x24, 0x20, 0x6d, 0xb1, 0xe6, 0x1d, 0xf7, - 0x43, 0x2a, 0x91, 0x79, 0x4b, 0x8f, 0x24, 0x0b, 0x23, 0x21, 0x6a, 0xde, 0xd1, 0xa0, 0x87, 0xc9, - 0x76, 0xd8, 0x0f, 0x7d, 0x17, 0x33, 0x99, 0xcc, 0x5b, 0xc3, 0x48, 0x88, 0xba, 0x48, 0xe8, 0x0d, - 0x27, 0xc0, 0x64, 0x38, 0x40, 0x19, 0x35, 0x98, 0x04, 0x7d, 0xcb, 0x09, 0xc2, 0x58, 0x4e, 0x35, - 0x18, 0xf4, 0x10, 0x56, 0x25, 0xe8, 0x96, 0xef, 0x1e, 0xb8, 0x7d, 0xa7, 0xa7, 0x2e, 0xe8, 0x0c, - 0xe5, 0x1e, 0x49, 0x47, 0x04, 0x57, 0x33, 0x14, 0x2a, 0xb8, 0x05, 0x4b, 0x87, 0x5a, 0x7e, 0x17, - 0xe6, 0x53, 0x0b, 0x39, 0xea, 0x5c, 0x97, 0x97, 0xcf, 0x75, 0x1f, 0x41, 0x91, 0x6e, 0x63, 0xfb, - 0x9e, 0xdf, 0x25, 0x8c, 0x64, 0xb0, 0x9c, 0x91, 0x8c, 0x6e, 0x0d, 0xf2, 0xf6, 0xcb, 0x01, 0xe3, - 0x9b, 0x53, 0xcd, 0x06, 0xe3, 0x21, 0x58, 0x8b, 0xd2, 0x10, 0x7b, 0x4b, 0x4d, 0x0c, 0x11, 0xdf, - 0x19, 0x8b, 0xfe, 0xae, 0xfc, 0x34, 0x07, 0x40, 0xeb, 0xa7, 0x9b, 0x3d, 0x21, 0x69, 0x3b, 0x47, - 0x58, 0x98, 0x64, 0xf2, 0x5b, 0xb6, 0xf9, 0x39, 0xd5, 0xe6, 0xf3, 0xee, 0x4c, 0xc4, 0xdd, 0x29, - 0xc3, 0xf4, 0x63, 0xe7, 0x45, 0xc7, 0xfd, 0x3d, 0x71, 0xf8, 0x12, 0x45, 0xb2, 0x3f, 0x08, 0xb3, - 0x5c, 0xe7, 0x47, 0xf3, 0x18, 0x40, 0xcf, 0xec, 0xed, 0x66, 0x9d, 0x4b, 0x31, 0xfd, 0x8d, 0x3e, - 0x07, 0x39, 0xbb, 0xc3, 0xb7, 0xd9, 0xe5, 0x75, 0x16, 0xe7, 0x5f, 0x17, 0x71, 0xfe, 0x75, 0x5b, - 0xc4, 0xf9, 0xd9, 0xb1, 0xf5, 0xcf, 0xff, 0xed, 0x86, 0x61, 0xe5, 0xec, 0x0e, 0xd9, 0xf8, 0x9a, - 0xfd, 0xfd, 0xde, 0x71, 0x17, 0x37, 0x5e, 0x0c, 0x88, 0x26, 0xf0, 0x4d, 0x88, 0xdb, 0x37, 0xcc, - 0x8e, 0x3e, 0x05, 0x6b, 0x04, 0x15, 0x71, 0x91, 0x1b, 0x2f, 0x28, 0xc5, 0xa6, 0xe3, 0x77, 0xeb, - 0xde, 0xc7, 0xfd, 0x54, 0x45, 0x6c, 0x0f, 0x1e, 0x45, 0x56, 0xa9, 0x00, 0xd8, 0x81, 0x27, 0x66, - 0x78, 0x11, 0x26, 0x99, 0x5a, 0xb1, 0x45, 0x64, 0x85, 0xca, 0xcf, 0x0d, 0xe2, 0xb9, 0xd1, 0xfd, - 0x91, 0x06, 0x2b, 0xb5, 0x7b, 0xe3, 0x5d, 0x28, 0x6e, 0x0d, 0x84, 0x7f, 0x9e, 0x4b, 0x07, 0x96, - 0x6a, 0x6d, 0xca, 0xbb, 0x35, 0xb0, 0x62, 0x3a, 0xb4, 0x11, 0x05, 0xfc, 0xd9, 0x46, 0x79, 0x53, - 0x13, 0xf0, 0xa7, 0x04, 0xd9, 0x51, 0xff, 0xf3, 0x0e, 0xbd, 0x56, 0x5a, 0x50, 0xaa, 0xb5, 0xe3, - 0x13, 0xa5, 0x6e, 0xac, 0x6f, 0x88, 0x00, 0x5a, 0x2e, 0xfb, 0x92, 0x81, 0x51, 0x54, 0x7e, 0xc6, - 0xe7, 0xce, 0x09, 0x87, 0xcc, 0xdd, 0xf8, 0xf5, 0x8d, 0x9e, 0x31, 0xd1, 0xd0, 0xaf, 0x70, 0xc6, - 0xbe, 0x59, 0x80, 0x69, 0x21, 0x41, 0x8a, 0xb3, 0x6e, 0x08, 0x4f, 0x8b, 0x03, 0xd0, 0x3a, 0x4c, - 0x3d, 0xc6, 0xe1, 0x33, 0xaf, 0xab, 0x33, 0x09, 0x0c, 0x43, 0x4d, 0x02, 0xa7, 0x42, 0xf7, 0x64, - 0xfd, 0xa7, 0xaa, 0x9c, 0xf0, 0x3e, 0x62, 0x2c, 0x1f, 0xa3, 0x6c, 0x2f, 0xaa, 0x34, 0xc4, 0x14, - 0xb9, 0x74, 0x54, 0xe9, 0x4b, 0x77, 0xae, 0x27, 0x43, 0x4c, 0x8a, 0xdf, 0x67, 0x29, 0x2c, 0xe8, - 0x3e, 0x11, 0x86, 0xb8, 0x86, 0x49, 0x5a, 0xc3, 0x35, 0x8d, 0x94, 0xc6, 0x15, 0xc8, 0x0c, 0x84, - 0xdf, 0x96, 0xf8, 0xa7, 0xd2, 0xfc, 0x76, 0x8a, 0x5f, 0x62, 0x20, 0xee, 0x57, 0xac, 0x9e, 0x3a, - 0xaf, 0x3e, 0xc6, 0x5a, 0xb2, 0x22, 0xdf, 0x53, 0xcf, 0x5a, 0xdc, 0x71, 0x2b, 0xab, 0x1d, 0x8f, - 0xf1, 0x96, 0x7a, 0x32, 0xbb, 0xa7, 0xea, 0x3b, 0x8f, 0xaa, 0x97, 0xb3, 0x94, 0xd3, 0x52, 0xad, - 0xc3, 0xe7, 0x15, 0x05, 0xa2, 0x9b, 0x65, 0xc2, 0x05, 0x96, 0xd0, 0x96, 0xa2, 0x6c, 0xf7, 0x54, - 0x65, 0xa1, 0x1b, 0xa7, 0xa6, 0x61, 0x81, 0xb7, 0x54, 0xd5, 0x7a, 0x17, 0x66, 0xeb, 0x98, 0x6c, - 0x6c, 0xbc, 0x3b, 0x3c, 0x6a, 0x73, 0x45, 0x66, 0x57, 0x08, 0x2c, 0x95, 0x1e, 0x6d, 0xc0, 0xdc, - 0xb6, 0xef, 0xbd, 0x78, 0x19, 0x2f, 0xd8, 0x2c, 0x37, 0xf0, 0x52, 0x0d, 0x2a, 0x85, 0x95, 0xe0, - 0x20, 0xbb, 0x70, 0x32, 0x60, 0xda, 0x3e, 0x3e, 0xa2, 0x4e, 0x60, 0xde, 0xd2, 0xa1, 0xd0, 0x86, - 0x14, 0xfe, 0x8d, 0x8e, 0x62, 0x17, 0xb3, 0x8f, 0x62, 0x56, 0x9a, 0x9c, 0xce, 0xf9, 0x33, 0xbc, - 0x7f, 0xb8, 0x89, 0x9d, 0x5e, 0xf8, 0x8c, 0xc6, 0x79, 0x92, 0x73, 0x1e, 0xa3, 0x2d, 0x99, 0x16, - 0xd9, 0xb0, 0xd8, 0xd9, 0x7f, 0x86, 0xbb, 0xc7, 0x3d, 0xcc, 0x5d, 0x54, 0xea, 0xa4, 0xd3, 0x88, - 0x4f, 0xe9, 0xce, 0xaa, 0x5c, 0x87, 0x8e, 0xce, 0xd2, 0x72, 0x57, 0x3c, 0x28, 0x51, 0x4d, 0x0c, - 0x06, 0x5e, 0x3f, 0xc0, 0x43, 0x8e, 0x66, 0x7c, 0x9b, 0xce, 0x29, 0xdb, 0xb4, 0x70, 0x9c, 0xd8, - 0xe6, 0x2d, 0x8a, 0xc3, 0x02, 0xeb, 0x95, 0x75, 0x40, 0x92, 0x3c, 0x4b, 0xed, 0xbe, 0xef, 0xfa, - 0x92, 0x31, 0x12, 0xc5, 0xca, 0x7f, 0xe5, 0x69, 0xa0, 0x8e, 0x91, 0x9d, 0xaf, 0xd5, 0xba, 0x06, - 0xc5, 0x86, 0xef, 0x7b, 0x7e, 0xcd, 0xeb, 0x62, 0x3a, 0x84, 0x59, 0x2b, 0x06, 0x10, 0x57, 0x9c, - 0x16, 0x1e, 0xe3, 0x20, 0x70, 0x0e, 0x30, 0x8f, 0x1d, 0x28, 0x30, 0xb4, 0x02, 0xd0, 0x0c, 0x36, - 0xab, 0x8f, 0x30, 0x1e, 0x60, 0x9f, 0x5a, 0x9d, 0x82, 0x25, 0x41, 0xd0, 0xbb, 0xca, 0xec, 0x72, - 0xb3, 0x72, 0x39, 0x65, 0x18, 0x19, 0x9a, 0x5b, 0x46, 0x65, 0x3d, 0x88, 0xa2, 0x49, 0x87, 0x18, - 0x6e, 0x59, 0x54, 0x45, 0x93, 0xf0, 0x96, 0x42, 0x4d, 0xa4, 0x8d, 0xda, 0x1a, 0xde, 0x7c, 0x21, - 0xdd, 0xbc, 0x84, 0xb6, 0x64, 0x5a, 0xa2, 0x62, 0xb5, 0xde, 0x71, 0x10, 0x62, 0xbf, 0x8e, 0xc9, - 0xe9, 0x34, 0xe0, 0xc6, 0x45, 0x51, 0x31, 0x95, 0xc2, 0x4a, 0x70, 0xa0, 0xfb, 0x50, 0x8c, 0xef, - 0x0d, 0x40, 0x23, 0xa6, 0x02, 0xc9, 0x04, 0x14, 0x07, 0xc7, 0xbd, 0xd0, 0x8a, 0x59, 0xd0, 0x7d, - 0x00, 0xc9, 0x34, 0x32, 0x1b, 0xb3, 0x22, 0x57, 0x90, 0x16, 0x24, 0x0b, 0x12, 0xe6, 0x91, 0x28, - 0x10, 0xf6, 0x99, 0x85, 0x9b, 0xd1, 0x4c, 0x9e, 0x84, 0xb7, 0x14, 0xea, 0xca, 0x43, 0x1a, 0xaf, - 0x62, 0xfe, 0x6f, 0x34, 0x2d, 0x6f, 0x91, 0x1d, 0x94, 0x40, 0x82, 0xb2, 0x41, 0xf7, 0xf5, 0xa5, - 0xd4, 0x62, 0x12, 0x2c, 0x5f, 0x4a, 0x41, 0x5b, 0x79, 0x55, 0x59, 0x08, 0xe2, 0xbe, 0x3d, 0xa1, - 0xfb, 0x36, 0x77, 0xdf, 0x68, 0xa1, 0xf2, 0x00, 0x66, 0x6d, 0x27, 0x38, 0xb4, 0x9d, 0xbd, 0x1e, - 0xde, 0x09, 0xb0, 0x4f, 0xd4, 0x88, 0xfc, 0xed, 0xc7, 0xbe, 0x74, 0x54, 0x26, 0xb8, 0x6d, 0x27, - 0x08, 0x3e, 0xf6, 0xfc, 0x2e, 0x0f, 0x6e, 0x44, 0xe5, 0xca, 0x37, 0x0c, 0xd2, 0x4b, 0x6a, 0xb7, - 0xb4, 0x6e, 0x4c, 0xb6, 0x2f, 0xae, 0xc4, 0x5f, 0x26, 0x92, 0x97, 0x34, 0xd1, 0x2d, 0x5a, 0x5e, - 0xbe, 0x45, 0x5b, 0xa1, 0x7b, 0xbf, 0xea, 0x94, 0x4b, 0x90, 0xca, 0x5f, 0xe5, 0x88, 0x0c, 0xf7, - 0x9f, 0xba, 0x07, 0xb5, 0x67, 0x4e, 0xff, 0x00, 0xa3, 0xbb, 0x51, 0xef, 0xf8, 0x65, 0xd2, 0x82, - 0x7a, 0xe0, 0xa0, 0xa8, 0x78, 0x06, 0xd9, 0x38, 0xee, 0x01, 0x30, 0x76, 0xe9, 0xa0, 0x72, 0x2d, - 0x1d, 0xdf, 0x88, 0x69, 0x2c, 0x89, 0x1e, 0xd9, 0x30, 0xd7, 0xec, 0xbb, 0xa1, 0xeb, 0xf4, 0x1e, - 0xe3, 0xa3, 0x3d, 0xec, 0x0b, 0xaf, 0xec, 0xcd, 0xac, 0x1a, 0xd6, 0x55, 0x72, 0x76, 0x74, 0x4e, - 0xd4, 0xb1, 0x5c, 0x85, 0x05, 0x0d, 0xd9, 0x89, 0x2e, 0xdc, 0xde, 0x80, 0xd9, 0xce, 0xb3, 0xe3, - 0xb0, 0xeb, 0x7d, 0xdc, 0x67, 0x5b, 0x1b, 0x59, 0x1b, 0xf2, 0x23, 0x5a, 0x32, 0x51, 0xac, 0xfc, - 0xe3, 0x24, 0x5c, 0x4c, 0x98, 0x70, 0xed, 0xea, 0xde, 0x84, 0xd9, 0x0d, 0xcf, 0x0b, 0x83, 0xd0, - 0x77, 0x06, 0x03, 0xb7, 0x7f, 0x40, 0x1b, 0x2d, 0x58, 0x2a, 0x90, 0x98, 0x06, 0x1e, 0xb3, 0xa1, - 0x13, 0x3a, 0x41, 0x27, 0x54, 0x31, 0x0d, 0x12, 0xda, 0x92, 0x69, 0x99, 0x4d, 0x8a, 0xa7, 0x8a, - 0xbb, 0x6b, 0xe5, 0xac, 0xa9, 0xb4, 0xd4, 0xd5, 0x7f, 0x37, 0x31, 0x62, 0xee, 0xab, 0x5d, 0x51, - 0x0d, 0x83, 0x44, 0x60, 0x25, 0x66, 0xe8, 0x11, 0xcc, 0xb3, 0xc0, 0x9a, 0x14, 0x69, 0xe3, 0x96, - 0x55, 0x71, 0x19, 0x53, 0x44, 0x56, 0x9a, 0x2f, 0xed, 0x8a, 0x4c, 0x9f, 0xd0, 0x15, 0x79, 0x04, - 0xf3, 0x0f, 0x3d, 0xb7, 0xcf, 0x22, 0xca, 0xdc, 0xfe, 0x71, 0x43, 0xab, 0xf4, 0x26, 0x45, 0x64, - 0xa5, 0xf9, 0xd0, 0x26, 0x98, 0xac, 0x76, 0xea, 0xab, 0xb0, 0x0e, 0x15, 0xd3, 0xae, 0x68, 0x92, - 0xc6, 0x4a, 0x71, 0x91, 0xe5, 0xad, 0x76, 0xbb, 0x42, 0x0b, 0x75, 0xbe, 0x9d, 0x84, 0xb6, 0x64, - 0x5a, 0x62, 0xf9, 0x23, 0x51, 0x61, 0xdc, 0xa5, 0xb4, 0xe5, 0x57, 0x29, 0xac, 0x04, 0x47, 0x05, - 0xeb, 0x7d, 0x15, 0xad, 0xbc, 0x26, 0x24, 0x31, 0x37, 0xbe, 0x24, 0x56, 0xfe, 0x22, 0x07, 0x97, - 0x12, 0xe1, 0x3a, 0xdb, 0xf1, 0x0f, 0x70, 0x48, 0xaf, 0x0e, 0xf9, 0x12, 0x91, 0x46, 0x98, 0xb5, - 0x2e, 0x5a, 0x0a, 0x8c, 0x06, 0xdb, 0x64, 0x9a, 0x1c, 0xa3, 0x91, 0x61, 0xc4, 0xce, 0x36, 0x5e, - 0x10, 0x13, 0xe4, 0x86, 0xfc, 0x56, 0x3a, 0x2a, 0x13, 0x17, 0x92, 0xd7, 0x67, 0xbb, 0x47, 0xd8, - 0x3b, 0x0e, 0x6d, 0x77, 0xff, 0x30, 0xe0, 0xd6, 0x51, 0x87, 0x22, 0x1c, 0xb6, 0x86, 0x83, 0x19, - 0x4d, 0x1d, 0x0a, 0x7d, 0x0e, 0x96, 0x1a, 0xc4, 0x5c, 0x38, 0x21, 0xae, 0x1d, 0xfb, 0x3e, 0xee, - 0x87, 0x94, 0x26, 0xe0, 0x37, 0x0c, 0x7a, 0x64, 0xe5, 0xb6, 0x46, 0x2a, 0xd9, 0x50, 0xdc, 0x80, - 0x5e, 0xb0, 0xb3, 0xe9, 0x88, 0xca, 0x95, 0x9e, 0x46, 0xa9, 0xd0, 0x5d, 0xc8, 0x93, 0xfd, 0x86, - 0x5b, 0x69, 0x45, 0x27, 0x94, 0x8d, 0x8a, 0xdb, 0x6a, 0x4a, 0x4c, 0x27, 0xd5, 0x09, 0x0e, 0xeb, - 0x4e, 0xe8, 0xec, 0x39, 0x81, 0x30, 0x79, 0x0a, 0x8c, 0x58, 0x3d, 0x55, 0x8b, 0xb2, 0xad, 0xde, - 0x9b, 0x69, 0x95, 0x18, 0x42, 0xfd, 0xba, 0x22, 0xf6, 0xd9, 0xde, 0x6c, 0xe5, 0x17, 0x46, 0x52, - 0xca, 0x4f, 0x7b, 0x2b, 0x81, 0x9e, 0x64, 0xec, 0x2d, 0xeb, 0xd9, 0xfa, 0x32, 0xce, 0xee, 0x42, - 0x74, 0x85, 0xac, 0x21, 0xbf, 0x57, 0xa0, 0xbf, 0xcf, 0x63, 0xc7, 0xf9, 0xcb, 0x9c, 0xea, 0x52, - 0x46, 0x99, 0x2e, 0x86, 0x94, 0xe9, 0xf2, 0x45, 0x76, 0x65, 0xed, 0xf4, 0xbb, 0x22, 0xe7, 0xe6, - 0xea, 0x90, 0xf3, 0x85, 0xb8, 0x73, 0x12, 0x2c, 0x64, 0x2a, 0x45, 0x38, 0x9e, 0x9f, 0x0c, 0x44, - 0x08, 0xbe, 0x06, 0xc0, 0xa9, 0x88, 0xc2, 0xe5, 0x69, 0xd5, 0xd7, 0x87, 0x54, 0xdd, 0xac, 0x8b, - 0x78, 0x41, 0xcc, 0x86, 0x3e, 0x84, 0x25, 0xed, 0x85, 0x13, 0xdf, 0x4a, 0x5e, 0x91, 0xeb, 0xd3, - 0x67, 0x12, 0xea, 0xf9, 0x2b, 0xdf, 0xcd, 0x65, 0xd4, 0x4c, 0x44, 0x60, 0xdb, 0xc7, 0x03, 0xc7, - 0x67, 0xca, 0x43, 0x56, 0x24, 0x06, 0x90, 0xf1, 0x36, 0xfa, 0x44, 0x1b, 0xba, 0x7c, 0xb3, 0x15, - 0xc5, 0x8c, 0xc4, 0xa3, 0x3b, 0xb0, 0x18, 0xdd, 0xfa, 0xd2, 0xc4, 0x46, 0x16, 0x6e, 0xe7, 0x4b, - 0xad, 0xc5, 0xa1, 0x75, 0x40, 0x9a, 0x9b, 0x6d, 0x66, 0x39, 0x34, 0x18, 0xe2, 0x96, 0x49, 0x17, - 0xf1, 0x2c, 0x24, 0x2a, 0x41, 0x48, 0xcf, 0xd8, 0xad, 0x30, 0x4b, 0xf7, 0x60, 0x05, 0x62, 0x23, - 0xc8, 0xa0, 0xc3, 0x10, 0x77, 0x79, 0x88, 0x33, 0x2a, 0x57, 0x7e, 0x6c, 0xa8, 0x97, 0xdb, 0xd1, - 0xec, 0x08, 0x9b, 0x2b, 0xdb, 0x4a, 0x63, 0x3c, 0x5b, 0x99, 0xcb, 0xb6, 0x95, 0x6f, 0xc3, 0xa5, - 0x58, 0xe7, 0x15, 0x26, 0x36, 0x97, 0x19, 0xd8, 0x6c, 0x8b, 0x99, 0x1f, 0x66, 0x31, 0xbf, 0x5b, - 0x82, 0x12, 0xef, 0x05, 0x3d, 0x7b, 0x88, 0x7c, 0x3c, 0x43, 0xca, 0xc7, 0xfb, 0xed, 0x4a, 0xe6, - 0xa9, 0x46, 0x11, 0xca, 0x02, 0x55, 0xc3, 0x57, 0x35, 0x61, 0x23, 0x9a, 0xc1, 0x36, 0x66, 0x22, - 0x77, 0xf1, 0x54, 0x89, 0xdc, 0xa0, 0x4f, 0x21, 0x52, 0xaf, 0xed, 0x4b, 0xe3, 0x24, 0x07, 0xcd, - 0x8c, 0x4c, 0x0e, 0x9a, 0x3d, 0x55, 0x72, 0xd0, 0xdc, 0xa9, 0x52, 0xc2, 0x2f, 0x8e, 0x93, 0x12, - 0x6e, 0x8e, 0x97, 0x34, 0x34, 0x9f, 0x48, 0x1a, 0x1a, 0x71, 0x8f, 0x89, 0xce, 0x23, 0x05, 0x68, - 0xe1, 0xbc, 0x52, 0x80, 0x16, 0xcf, 0x21, 0x05, 0x68, 0xe9, 0xec, 0x29, 0x40, 0x97, 0xce, 0x25, - 0x05, 0xe8, 0xf2, 0x39, 0xa4, 0x00, 0x95, 0xc7, 0x48, 0x01, 0x1a, 0x9e, 0x24, 0x7f, 0x65, 0x64, - 0x92, 0xfc, 0xb0, 0x14, 0xa2, 0xe5, 0xb3, 0xa4, 0x10, 0x5d, 0xfd, 0xf5, 0x24, 0xd8, 0xff, 0xb5, - 0xc1, 0xde, 0xdb, 0xf0, 0xc7, 0x27, 0xdc, 0xa0, 0x1b, 0xfa, 0xc7, 0x27, 0x4e, 0x88, 0xd7, 0x19, - 0x85, 0x62, 0xb3, 0x18, 0x68, 0xd9, 0x82, 0x92, 0x84, 0xd4, 0x74, 0xf0, 0x33, 0x6a, 0x07, 0x2f, - 0x67, 0x98, 0x45, 0xd9, 0xa7, 0xfa, 0xd7, 0x3c, 0x4d, 0x70, 0x39, 0x97, 0xcd, 0xe3, 0x77, 0x39, - 0x29, 0xbf, 0xc1, 0x39, 0x29, 0x23, 0x2c, 0xf3, 0xec, 0xb8, 0x19, 0x26, 0x44, 0xde, 0xed, 0x71, - 0xe4, 0xdd, 0xfe, 0xe5, 0xca, 0xbb, 0xad, 0x97, 0xf7, 0x7f, 0x98, 0x00, 0x90, 0xce, 0x63, 0xba, - 0x53, 0xbd, 0x50, 0x81, 0x9c, 0xa4, 0x02, 0x37, 0x61, 0x96, 0xa8, 0x37, 0xee, 0xab, 0xae, 0x91, - 0x0a, 0x4c, 0x48, 0x4d, 0x7e, 0x6c, 0xa9, 0x19, 0xbd, 0xa7, 0x4d, 0x9e, 0xd7, 0x9e, 0x36, 0x75, - 0x0e, 0x7b, 0xda, 0xf4, 0xd9, 0x1e, 0x4a, 0x15, 0x46, 0xed, 0x01, 0x95, 0xbf, 0x37, 0xa2, 0x45, - 0x22, 0x62, 0xf4, 0x5e, 0x42, 0x8c, 0x2a, 0xa9, 0xbb, 0xb2, 0x51, 0x92, 0xf4, 0xc1, 0x28, 0x49, - 0x7a, 0x53, 0x95, 0xa4, 0x4b, 0x9a, 0x16, 0x3c, 0x1f, 0xcb, 0x82, 0xf4, 0xa3, 0x5c, 0xf2, 0x26, - 0x2f, 0x2b, 0xa4, 0xa9, 0x0a, 0x4e, 0x6e, 0xb4, 0xe0, 0x4c, 0x9c, 0xa3, 0xe0, 0xe4, 0xcf, 0x4b, - 0x70, 0x26, 0xcf, 0x41, 0x70, 0xa6, 0x46, 0x08, 0x4e, 0xe5, 0xdb, 0x13, 0xc9, 0xbb, 0x1b, 0xf4, - 0x16, 0x14, 0xb8, 0x2a, 0x8b, 0xe5, 0x5f, 0xd0, 0xa8, 0xb9, 0x70, 0x67, 0x05, 0x29, 0x61, 0xab, - 0x09, 0xb6, 0x5c, 0x9a, 0xad, 0xa6, 0xb2, 0x09, 0x52, 0xf4, 0x0e, 0xcd, 0x36, 0xe2, 0x7c, 0x6c, - 0x17, 0x5b, 0xd4, 0x5d, 0xe6, 0x73, 0xc6, 0x98, 0x18, 0xdd, 0x87, 0x52, 0x2c, 0x28, 0x22, 0x3e, - 0x90, 0x21, 0x47, 0xe2, 0xba, 0x4c, 0x62, 0x40, 0x75, 0x11, 0x58, 0xea, 0xf2, 0x1a, 0x58, 0x6e, - 0x5c, 0x39, 0x1d, 0x3d, 0xed, 0xca, 0x75, 0xa8, 0x4c, 0xd9, 0xf1, 0x85, 0xa9, 0x33, 0xc6, 0x17, - 0xfe, 0xc8, 0x80, 0x12, 0x5f, 0x19, 0xea, 0x27, 0x7c, 0x9e, 0x2e, 0x0b, 0xdb, 0xed, 0x0d, 0xbe, - 0xdb, 0x47, 0xee, 0x10, 0xc7, 0x28, 0x17, 0x4a, 0x11, 0x39, 0xba, 0xc7, 0xe6, 0x98, 0xf1, 0xe6, - 0xf8, 0x28, 0x63, 0x57, 0x4a, 0x44, 0x76, 0x65, 0xe6, 0x98, 0xa1, 0xf2, 0xbd, 0x3c, 0x2c, 0xf1, - 0x40, 0x92, 0x08, 0x47, 0xf3, 0x84, 0x84, 0xd7, 0x60, 0xae, 0x7d, 0x7c, 0xb4, 0xf5, 0x34, 0xae, - 0x9c, 0x39, 0x31, 0x09, 0x28, 0x51, 0x49, 0x0a, 0x89, 0xfa, 0xcf, 0x0c, 0xbd, 0x0a, 0x44, 0x6b, - 0x60, 0x0a, 0xbe, 0x28, 0xc5, 0x9a, 0x9d, 0xde, 0x53, 0x70, 0x72, 0x76, 0x6a, 0xe3, 0x17, 0x61, - 0x74, 0x65, 0xcc, 0x4b, 0xc8, 0x86, 0x12, 0xfb, 0xb5, 0xf1, 0xf2, 0x11, 0x16, 0xd9, 0x8e, 0x77, - 0xe4, 0x35, 0xd0, 0x8e, 0x64, 0x5d, 0x62, 0x62, 0x01, 0x36, 0xb9, 0x1a, 0xf4, 0x54, 0x77, 0x99, - 0xcf, 0xde, 0x72, 0xbd, 0x33, 0x46, 0xdd, 0x49, 0xd6, 0xe4, 0xa3, 0xae, 0xe8, 0xc2, 0x9f, 0xfa, - 0x4c, 0x07, 0xe2, 0x06, 0x82, 0x27, 0xf6, 0x89, 0x53, 0x79, 0x1a, 0xb3, 0x7c, 0x1f, 0xcc, 0x64, - 0xc7, 0xf5, 0x09, 0xf8, 0xfa, 0x4c, 0x3f, 0xe5, 0x1d, 0x98, 0xd2, 0xb9, 0x51, 0xb5, 0x28, 0x41, - 0xc2, 0xff, 0x31, 0xe0, 0x8a, 0x85, 0x03, 0x16, 0x55, 0xfd, 0xd0, 0x09, 0xb1, 0x7f, 0xe4, 0xf8, - 0x87, 0x42, 0x46, 0xe2, 0x95, 0x32, 0x94, 0x95, 0xfa, 0x92, 0xba, 0x52, 0x4c, 0x2a, 0xdf, 0x4e, - 0x1c, 0x9c, 0xf5, 0x75, 0x8e, 0x58, 0x2d, 0xfd, 0x2c, 0x4e, 0xfc, 0xb2, 0x66, 0xb1, 0xf2, 0x9f, - 0xfc, 0x79, 0xe2, 0x50, 0x8f, 0xfe, 0x77, 0xef, 0x14, 0x7e, 0xdb, 0xde, 0x29, 0xfc, 0x93, 0x78, - 0xcd, 0x4b, 0x1c, 0xa6, 0xfb, 0xd1, 0x41, 0x8c, 0x99, 0xe6, 0xd5, 0xd4, 0x16, 0x46, 0xdd, 0x25, - 0x4a, 0xa2, 0xba, 0x4b, 0xcc, 0xf6, 0xdd, 0x8f, 0x1c, 0xae, 0xdc, 0x30, 0xfe, 0x4c, 0x77, 0xab, - 0x03, 0x25, 0xa9, 0x72, 0x4d, 0x8c, 0x7f, 0x5d, 0x75, 0xb7, 0x32, 0x9f, 0x64, 0xca, 0xe6, 0xa1, - 0x33, 0xca, 0x87, 0x1b, 0x55, 0xa9, 0xee, 0x38, 0xf0, 0x1f, 0x05, 0x35, 0xd1, 0x42, 0xab, 0x2d, - 0xef, 0x2a, 0x5b, 0x9f, 0xf6, 0x70, 0x1d, 0xa3, 0xc5, 0xde, 0x2e, 0x6f, 0x96, 0x77, 0xa3, 0x23, - 0x11, 0xf7, 0xed, 0x16, 0x34, 0x07, 0x21, 0x91, 0x36, 0x20, 0x0e, 0x4f, 0x6f, 0xc7, 0x0b, 0xca, - 0x8f, 0x12, 0x8b, 0xba, 0x65, 0x88, 0xa5, 0x91, 0x2f, 0xfe, 0xdd, 0x28, 0xde, 0xc0, 0x2f, 0x15, - 0x16, 0x34, 0x51, 0x06, 0xd1, 0x98, 0x88, 0x4c, 0xdc, 0x16, 0xe9, 0xa1, 0x2c, 0x50, 0xab, 0x5c, - 0x98, 0x89, 0x94, 0x20, 0x25, 0x49, 0xb4, 0xcd, 0x75, 0x92, 0xdf, 0x79, 0xf0, 0x34, 0x95, 0x69, - 0xca, 0xbd, 0x92, 0xbc, 0x6e, 0x53, 0xa9, 0x2c, 0x0d, 0x27, 0x6a, 0x24, 0x32, 0x48, 0xb8, 0x02, - 0x8e, 0xbc, 0xb9, 0x4b, 0xe4, 0x9d, 0x08, 0xfb, 0xde, 0xe5, 0x99, 0xf7, 0xbc, 0x84, 0x1e, 0xa9, - 0xf6, 0x1d, 0xa8, 0x58, 0xbf, 0x91, 0x95, 0x4e, 0x33, 0xc2, 0xa4, 0xdf, 0x93, 0x4f, 0x27, 0xfc, - 0x8a, 0xf9, 0x92, 0xfe, 0x4c, 0x22, 0xae, 0x80, 0xa4, 0xd3, 0x8c, 0x1c, 0xa0, 0x9d, 0x39, 0xd9, - 0xeb, 0x4d, 0x5d, 0xd6, 0xdf, 0x6c, 0x76, 0xd6, 0xdf, 0xa6, 0xce, 0x51, 0x98, 0x1b, 0x69, 0xd8, - 0x34, 0xae, 0xc0, 0x3d, 0xb8, 0x92, 0xde, 0xaa, 0xb6, 0x71, 0xbf, 0xeb, 0xf6, 0x0f, 0x68, 0xbc, - 0xb8, 0x60, 0x65, 0x13, 0xa0, 0x0d, 0xb8, 0xa6, 0x6c, 0x9b, 0x74, 0x23, 0x95, 0x8e, 0x16, 0xec, - 0xc9, 0xe8, 0x50, 0x1a, 0x72, 0xa4, 0xd4, 0x34, 0x40, 0xaf, 0xb1, 0xa2, 0xa7, 0xa3, 0x43, 0x28, - 0xd0, 0x7b, 0x70, 0x35, 0x8d, 0x8d, 0xde, 0x62, 0x88, 0xc0, 0xf3, 0x10, 0x92, 0x33, 0x6f, 0xcc, - 0x7f, 0x66, 0xc0, 0x8c, 0xec, 0xac, 0x6b, 0x8f, 0x8b, 0xd7, 0xa0, 0xc8, 0xae, 0x85, 0x44, 0x3e, - 0x41, 0xd1, 0x8a, 0x01, 0xa8, 0x0c, 0xd3, 0xea, 0x6e, 0x2c, 0x8a, 0x52, 0xf4, 0x3e, 0xaf, 0x44, - 0xef, 0x97, 0xa1, 0x50, 0xf7, 0x3e, 0xee, 0x53, 0xcc, 0x24, 0xc5, 0x44, 0xe5, 0xca, 0xb7, 0x2b, - 0x60, 0x0a, 0xdd, 0x8e, 0xde, 0x04, 0x45, 0x2f, 0x80, 0x0c, 0xf9, 0x05, 0x90, 0x2e, 0x24, 0x12, - 0xbb, 0x52, 0x13, 0x8a, 0x2b, 0xb5, 0xa5, 0xaa, 0x1a, 0x3b, 0x08, 0x7d, 0x46, 0x67, 0x50, 0xa2, - 0xa7, 0x3e, 0xc3, 0xd5, 0x4d, 0xf7, 0x3d, 0x83, 0x5f, 0xbb, 0xbd, 0xea, 0x82, 0x99, 0xb8, 0xef, - 0x15, 0x97, 0x51, 0x77, 0x86, 0x0e, 0x35, 0xc9, 0x24, 0x6f, 0x9f, 0xa9, 0x1a, 0x51, 0x53, 0x3e, - 0x2a, 0xb1, 0x0f, 0x16, 0x7d, 0x7a, 0x68, 0xf5, 0x11, 0x35, 0x9b, 0xc7, 0x98, 0x5b, 0xde, 0x16, - 0x60, 0xec, 0x6d, 0x41, 0xda, 0xb8, 0x4a, 0xa7, 0xda, 0xb8, 0x66, 0x4e, 0xb0, 0x71, 0x25, 0xb6, - 0xd9, 0xd9, 0x13, 0x6f, 0xb3, 0xa9, 0x3d, 0x64, 0xee, 0x54, 0x7b, 0x88, 0x6a, 0xde, 0x2f, 0x9e, - 0xd0, 0xbc, 0xa7, 0xce, 0xf1, 0xe6, 0x69, 0xce, 0xf1, 0x19, 0xc6, 0x7e, 0xfe, 0x84, 0xc6, 0x1e, - 0x9d, 0xbb, 0xb1, 0x5f, 0x38, 0xab, 0xb1, 0x5f, 0x3c, 0xb3, 0xb1, 0x5f, 0x3a, 0xab, 0xb1, 0xbf, - 0x34, 0xd2, 0xd8, 0xa3, 0xb7, 0x53, 0xd9, 0x59, 0x22, 0x4b, 0x82, 0xdd, 0xa3, 0x65, 0x60, 0x35, - 0x47, 0x81, 0x38, 0xf7, 0xa2, 0xac, 0x3d, 0x0a, 0xc4, 0xa9, 0x18, 0x5f, 0x85, 0xc5, 0x04, 0x4e, - 0xdc, 0x99, 0xa5, 0x0e, 0xa3, 0x29, 0xbd, 0xd7, 0x31, 0x32, 0x13, 0xa0, 0xad, 0x13, 0x0d, 0x52, - 0xe3, 0xab, 0xb5, 0xc5, 0x1d, 0x5b, 0x2a, 0x90, 0x30, 0xaa, 0x35, 0xce, 0xca, 0xda, 0xcb, 0xa8, - 0x57, 0xd3, 0xa2, 0xdd, 0x16, 0x17, 0x73, 0x27, 0x6e, 0xd1, 0x1e, 0xd6, 0x22, 0x47, 0xa2, 0x4d, - 0xb8, 0x91, 0xc0, 0xf0, 0x54, 0x9e, 0xa0, 0x1a, 0x04, 0xee, 0x41, 0x1f, 0x77, 0xcb, 0xd7, 0xd8, - 0x0b, 0xb6, 0x11, 0x64, 0xa8, 0x05, 0xaf, 0x24, 0x47, 0x15, 0xa5, 0xf4, 0x44, 0x75, 0x5d, 0xa7, - 0x75, 0x8d, 0x26, 0xcc, 0x3c, 0xf2, 0xc5, 0x92, 0xb2, 0x32, 0xe4, 0xc8, 0x17, 0xcb, 0xcb, 0x46, - 0x46, 0x4e, 0x8b, 0x90, 0xd4, 0x1b, 0xe9, 0x1b, 0xdf, 0x24, 0x4d, 0x66, 0xa4, 0x9e, 0xc5, 0x6b, - 0x57, 0xa9, 0xae, 0x0e, 0xa1, 0x40, 0x0f, 0x61, 0x55, 0x7b, 0x1b, 0x2c, 0xa7, 0x06, 0xbd, 0x42, - 0xfb, 0x31, 0x92, 0x6e, 0x8c, 0x9b, 0xf0, 0xca, 0x58, 0x37, 0xe1, 0x5f, 0x37, 0xe0, 0xba, 0xb6, - 0xcb, 0x34, 0xcc, 0x40, 0x24, 0xee, 0x55, 0x2a, 0x71, 0xef, 0x0e, 0x95, 0xb8, 0xa1, 0x35, 0x30, - 0xc1, 0x1b, 0xde, 0x0a, 0xfa, 0x83, 0xac, 0xa4, 0x23, 0xa1, 0x6a, 0x37, 0x69, 0x37, 0xee, 0x9f, - 0xbc, 0x1b, 0x8a, 0xc2, 0x0d, 0x6d, 0x03, 0x7d, 0xc3, 0xc8, 0x08, 0xed, 0xd3, 0x2d, 0x8b, 0xf5, - 0xe3, 0x53, 0xb4, 0x1f, 0xd5, 0x93, 0xf7, 0x23, 0xae, 0x83, 0x75, 0x65, 0x54, 0x4b, 0xe8, 0x8f, - 0x8d, 0x0c, 0xd9, 0xaf, 0xb5, 0x79, 0x26, 0x56, 0xf9, 0x35, 0xda, 0x99, 0xf7, 0x4e, 0x33, 0x29, - 0xbc, 0x0a, 0xd6, 0x97, 0x11, 0xed, 0xa0, 0x6f, 0x1a, 0xf0, 0x4a, 0x76, 0x77, 0x45, 0x6f, 0x5e, - 0xa7, 0xbd, 0xa9, 0x9d, 0x72, 0x6a, 0x94, 0x0e, 0x8d, 0x6e, 0x2d, 0x53, 0xa3, 0xc5, 0xe6, 0x7b, - 0x6b, 0x88, 0x46, 0x8b, 0xfd, 0xf7, 0x5b, 0x06, 0x54, 0x86, 0x0e, 0x9d, 0x25, 0xa2, 0xbd, 0x41, - 0x07, 0x56, 0x3f, 0xfd, 0x34, 0xd3, 0x6a, 0xd8, 0xc8, 0xc6, 0x68, 0x0f, 0x7d, 0xcf, 0x80, 0x4f, - 0x8d, 0x9a, 0x00, 0xd6, 0xb3, 0x35, 0xda, 0xb3, 0x07, 0x67, 0x9a, 0x72, 0xa9, 0x73, 0xe3, 0xb5, - 0x7a, 0xe6, 0xe0, 0xf5, 0x47, 0xb0, 0xa4, 0x75, 0xed, 0x4f, 0x18, 0xa7, 0x52, 0x5e, 0x44, 0x49, - 0xd5, 0xdf, 0xa3, 0x1f, 0x37, 0xcb, 0x08, 0xaa, 0x8d, 0xec, 0xdc, 0x03, 0xb8, 0x92, 0xe9, 0x20, - 0x8c, 0xaa, 0xa8, 0x20, 0x57, 0xd4, 0x4c, 0x25, 0x09, 0xc8, 0xa6, 0xe8, 0x8c, 0x55, 0xd9, 0xa7, - 0xad, 0x6a, 0x3b, 0x43, 0xe2, 0x15, 0x6b, 0x7d, 0xa2, 0x1a, 0xb7, 0x32, 0x6c, 0xc3, 0xa9, 0x47, - 0x6b, 0xc1, 0xcd, 0x71, 0x2c, 0xe8, 0x89, 0xea, 0xfc, 0x00, 0x5e, 0x1d, 0xc3, 0x10, 0x9e, 0x48, - 0x50, 0x6c, 0x78, 0x6d, 0x3c, 0x6b, 0x76, 0xa2, 0x5a, 0x77, 0xe0, 0xf5, 0x31, 0x4d, 0xc9, 0x89, - 0xaa, 0xfd, 0x12, 0xac, 0x8d, 0x6f, 0x07, 0x4e, 0x14, 0xaa, 0x69, 0xb2, 0x7c, 0x1b, 0xf1, 0x1d, - 0xc1, 0x33, 0x7c, 0xa7, 0xa7, 0xf2, 0x37, 0x39, 0x58, 0xd4, 0x3d, 0x16, 0x1c, 0x92, 0xb3, 0xbf, - 0x9d, 0xfa, 0x6a, 0xe4, 0xfa, 0xa8, 0xa7, 0x87, 0xea, 0xd7, 0x23, 0x53, 0x17, 0x28, 0xe7, 0xf2, - 0x0d, 0xc9, 0x65, 0x7b, 0xf4, 0x47, 0x1e, 0x87, 0x25, 0xe4, 0x48, 0x33, 0x2a, 0xcf, 0xf5, 0xf7, - 0x0d, 0x80, 0x0d, 0x67, 0xff, 0xf0, 0x78, 0x40, 0xef, 0x60, 0xb2, 0x2e, 0xe8, 0x9a, 0xba, 0x0b, - 0xba, 0xd7, 0x95, 0x77, 0x0a, 0x51, 0x25, 0xc3, 0xe3, 0x49, 0x67, 0x0e, 0xe4, 0xfd, 0xa1, 0x21, - 0xee, 0x97, 0x9a, 0x21, 0x3e, 0xd2, 0x7e, 0x32, 0xa4, 0x02, 0x33, 0x3c, 0x47, 0xfb, 0x89, 0x74, - 0x4b, 0xa9, 0xc0, 0x08, 0x4d, 0x1d, 0x3f, 0x75, 0x8e, 0x7b, 0x9c, 0x86, 0x45, 0xf4, 0x14, 0x18, - 0x59, 0xa2, 0x66, 0x3f, 0xc4, 0x7e, 0xdf, 0xe9, 0xf1, 0x8b, 0xb5, 0xa8, 0x5c, 0xf9, 0x5b, 0x43, - 0xbe, 0xe6, 0x42, 0x5f, 0x84, 0xe9, 0x9a, 0xd7, 0x0f, 0x31, 0xfd, 0xb2, 0x46, 0x3a, 0x29, 0x3a, - 0x22, 0x5c, 0xe7, 0x54, 0x6c, 0x62, 0x04, 0xcf, 0xb2, 0x45, 0x5f, 0xc6, 0x45, 0x88, 0x13, 0xa6, - 0xc8, 0xc4, 0xd3, 0x21, 0x4f, 0xd4, 0xef, 0xc7, 0xf7, 0x69, 0xe8, 0xad, 0xf8, 0xdd, 0x68, 0x2a, - 0x13, 0x4c, 0x10, 0xad, 0x53, 0x0a, 0xd6, 0x31, 0x46, 0xbd, 0xfc, 0x0e, 0x40, 0x0c, 0x3c, 0xd1, - 0x3d, 0xf0, 0xeb, 0xca, 0x73, 0xf5, 0x21, 0xef, 0x69, 0x3e, 0x82, 0xf9, 0xd4, 0xcb, 0x0d, 0x74, - 0x13, 0x66, 0xd9, 0x17, 0x70, 0xc4, 0x63, 0x10, 0xc6, 0xa4, 0x02, 0xe9, 0x32, 0x73, 0x16, 0xe9, - 0xab, 0x49, 0x0a, 0x6c, 0xed, 0x63, 0x80, 0x9d, 0x41, 0xd7, 0x09, 0x59, 0x04, 0xf7, 0x32, 0x2c, - 0x28, 0x5f, 0xd4, 0x61, 0x28, 0xf3, 0x02, 0x5a, 0x82, 0x79, 0xf1, 0xa5, 0xa4, 0x56, 0xa7, 0xcd, - 0xc1, 0x06, 0x5a, 0x80, 0x8b, 0x3b, 0x01, 0xf6, 0xe9, 0xf0, 0x39, 0x30, 0x87, 0x66, 0xa1, 0x68, - 0x77, 0xb6, 0x78, 0x71, 0x82, 0xb0, 0x46, 0x5f, 0x3d, 0x8a, 0x58, 0xf3, 0x6b, 0xeb, 0x50, 0x8c, - 0xbe, 0xb4, 0x8b, 0x2e, 0x42, 0xa9, 0xed, 0xf9, 0x47, 0x4e, 0x8f, 0x16, 0xcd, 0x0b, 0xc8, 0x84, - 0x19, 0xfe, 0xf4, 0x80, 0x41, 0x8c, 0xb5, 0x9f, 0xe7, 0x01, 0xe2, 0x97, 0xe6, 0x68, 0x0e, 0xc0, - 0xee, 0x6c, 0xed, 0xee, 0x6c, 0xd7, 0xab, 0x76, 0xc3, 0xbc, 0x80, 0x00, 0xa6, 0xaa, 0xdb, 0xdb, - 0x8d, 0x76, 0xdd, 0x34, 0x50, 0x01, 0xf2, 0x56, 0xa3, 0x5a, 0x37, 0x73, 0x68, 0x06, 0x0a, 0xb6, - 0xb5, 0xd3, 0xae, 0x11, 0x9a, 0x09, 0x52, 0xe9, 0x83, 0x86, 0xbd, 0x1b, 0x41, 0xf2, 0xa8, 0x04, - 0xd3, 0xb5, 0xad, 0x76, 0xbb, 0x51, 0xb3, 0xcd, 0x49, 0x52, 0x25, 0x2f, 0xec, 0x5a, 0x5b, 0xe6, - 0x14, 0x9a, 0x87, 0xd9, 0xd6, 0xd6, 0x83, 0xdd, 0xcd, 0x46, 0xd5, 0xb2, 0x37, 0x1a, 0x55, 0xdb, - 0x9c, 0x26, 0x35, 0xd4, 0xda, 0x12, 0xa4, 0x40, 0x3b, 0x2a, 0x43, 0x8a, 0x08, 0xc1, 0x5c, 0x6d, - 0xb3, 0x51, 0x7b, 0xb4, 0xbb, 0x59, 0x7d, 0xd4, 0x68, 0x6c, 0x37, 0x2c, 0x13, 0xc8, 0xbc, 0x92, - 0x96, 0x6b, 0xad, 0x9d, 0x8e, 0xdd, 0xb0, 0x76, 0xeb, 0x0d, 0xbb, 0xda, 0x6c, 0x75, 0xcc, 0x12, - 0x21, 0x26, 0x88, 0xce, 0x66, 0xd5, 0xaa, 0xef, 0x36, 0xdb, 0xef, 0x6f, 0x99, 0x33, 0xb4, 0x82, - 0xf6, 0x6e, 0xb5, 0xd5, 0xda, 0x22, 0xbd, 0xdc, 0x6d, 0xd6, 0xcd, 0x59, 0x32, 0x89, 0x72, 0x05, - 0x1d, 0x9b, 0xf4, 0x7f, 0x8e, 0xce, 0x3f, 0x9d, 0x81, 0xdd, 0x5a, 0x7b, 0xb7, 0x55, 0xdd, 0x68, - 0xb4, 0xcc, 0x8b, 0xa8, 0x0c, 0x8b, 0x31, 0xf0, 0xc3, 0x2d, 0xeb, 0x11, 0x27, 0x37, 0x49, 0xcd, - 0xdb, 0x55, 0xbb, 0xb6, 0x49, 0x10, 0x1d, 0x7b, 0xcb, 0x6a, 0x98, 0xf3, 0xa4, 0x8a, 0x7a, 0xa3, - 0xd5, 0x60, 0xd4, 0x0c, 0x88, 0x08, 0x70, 0xdb, 0xda, 0xfa, 0xd2, 0x97, 0xa5, 0x81, 0x2d, 0xa0, - 0x57, 0xe0, 0x3a, 0xaf, 0xb7, 0xbd, 0xd5, 0xde, 0x7d, 0xb2, 0x65, 0x37, 0xdb, 0x0f, 0x76, 0xad, - 0xc6, 0x76, 0xab, 0x59, 0xab, 0xee, 0xb6, 0x77, 0x1e, 0x9b, 0x8b, 0x68, 0x05, 0x96, 0xd3, 0x24, - 0x64, 0x1c, 0xad, 0xa6, 0xfd, 0x65, 0x73, 0x09, 0x2d, 0x82, 0xd9, 0x69, 0xd8, 0xbb, 0x56, 0xe3, - 0x83, 0x9d, 0xa6, 0xd5, 0xa8, 0xef, 0xb6, 0x3a, 0x6d, 0xf3, 0x12, 0x81, 0x3e, 0x48, 0x42, 0x2f, - 0x8b, 0xa9, 0x69, 0x55, 0xed, 0x46, 0xc7, 0xa6, 0xb0, 0x32, 0x59, 0x12, 0x0a, 0x6b, 0x54, 0xeb, - 0x0d, 0x8b, 0xcc, 0xcc, 0x15, 0xba, 0x24, 0x6c, 0xba, 0x1b, 0xd5, 0x96, 0xbd, 0x69, 0x2e, 0x93, - 0x45, 0x27, 0xcb, 0x4f, 0x59, 0xae, 0xa2, 0x2b, 0xb0, 0xc4, 0xbb, 0xd4, 0x6a, 0x54, 0x3b, 0x8d, - 0xcd, 0xad, 0x16, 0x67, 0xbd, 0x46, 0x50, 0x74, 0xf2, 0x6b, 0x9b, 0x8d, 0xfa, 0x4e, 0xab, 0xb1, - 0x5b, 0xdb, 0x7a, 0xfc, 0xb8, 0xda, 0xae, 0x77, 0xcc, 0xeb, 0x6b, 0x6d, 0x80, 0xf8, 0xfb, 0x4c, - 0x44, 0x32, 0x88, 0x98, 0x33, 0x88, 0x79, 0x81, 0xb4, 0x20, 0xec, 0x9c, 0x69, 0x10, 0xe1, 0xa5, - 0x4a, 0x13, 0x29, 0xc0, 0x3c, 0xff, 0x20, 0x99, 0x85, 0xbf, 0x8a, 0xf7, 0x43, 0xdc, 0x35, 0x27, - 0xd6, 0xd6, 0xa0, 0x18, 0x7d, 0xfe, 0x87, 0xb0, 0x77, 0x70, 0x48, 0x4b, 0xe6, 0x05, 0xc2, 0xce, - 0x82, 0xab, 0x0c, 0x60, 0xac, 0xfd, 0x4b, 0x1e, 0x90, 0x38, 0x52, 0x48, 0xba, 0x49, 0x24, 0xde, - 0xdd, 0x3f, 0x94, 0x55, 0x52, 0xfa, 0xce, 0x4a, 0xa4, 0x92, 0x44, 0x53, 0x53, 0xe0, 0x1c, 0xba, - 0x44, 0xf3, 0x3c, 0x92, 0xf0, 0x09, 0xd2, 0xfa, 0x03, 0x1c, 0x46, 0x9a, 0x9e, 0x27, 0x93, 0x92, - 0xb0, 0x37, 0x1c, 0x35, 0x49, 0x56, 0xa4, 0x83, 0x99, 0x42, 0x72, 0xd8, 0x14, 0x11, 0x36, 0x35, - 0x91, 0x87, 0x63, 0xa6, 0xd1, 0x0d, 0xb8, 0xda, 0xc1, 0x61, 0xfa, 0x6e, 0x82, 0x13, 0x14, 0xd0, - 0x32, 0x5c, 0xe2, 0x04, 0x51, 0x70, 0x9b, 0xe3, 0x8a, 0x64, 0x0a, 0xd9, 0x6f, 0x3e, 0x6b, 0x26, - 0x90, 0x81, 0x09, 0x50, 0xf4, 0xe8, 0xc5, 0x2c, 0x91, 0xf5, 0xdf, 0x26, 0xf6, 0x8e, 0xe7, 0xc8, - 0x99, 0x33, 0x84, 0xd7, 0xc2, 0x47, 0xde, 0x73, 0xf1, 0x06, 0xd2, 0x9c, 0x25, 0xbd, 0x54, 0x93, - 0x21, 0x79, 0x43, 0x73, 0xe8, 0x3a, 0x5c, 0x61, 0xbf, 0x35, 0x41, 0x6b, 0xf3, 0x22, 0xba, 0x0a, - 0x97, 0x13, 0x68, 0xb1, 0x1b, 0x30, 0x75, 0x12, 0xa7, 0x1e, 0x5e, 0xdf, 0x3c, 0xba, 0x06, 0xe5, - 0x74, 0x2a, 0x0e, 0xc7, 0x22, 0x74, 0x13, 0x56, 0x45, 0x10, 0x37, 0x1d, 0xde, 0xe5, 0x54, 0x0b, - 0x64, 0xe6, 0x58, 0x00, 0x2c, 0x71, 0x02, 0xe1, 0x04, 0x8b, 0xe8, 0x53, 0xf0, 0x0a, 0x23, 0xd0, - 0x3a, 0x98, 0x9c, 0x6c, 0x69, 0xed, 0x3b, 0x06, 0xcc, 0x2a, 0xb7, 0x4d, 0x44, 0xaf, 0x05, 0x80, - 0x67, 0xa3, 0x98, 0x17, 0xc8, 0x8a, 0x0b, 0xa0, 0xf2, 0x92, 0xdd, 0x34, 0x48, 0x43, 0x29, 0x94, - 0x38, 0x3f, 0x5a, 0x78, 0x1f, 0xbb, 0xcf, 0x71, 0xd7, 0xcc, 0x91, 0x59, 0x4a, 0x91, 0xbd, 0xef, - 0xb8, 0x3d, 0x22, 0xfa, 0x72, 0x9b, 0xd6, 0x71, 0xbf, 0x4f, 0x2a, 0xce, 0xaf, 0xed, 0xe9, 0xee, - 0xbb, 0xc8, 0x32, 0x29, 0xd0, 0xb8, 0x8f, 0x49, 0x8c, 0xa8, 0xc9, 0x48, 0x61, 0x3a, 0xa1, 0x37, - 0x18, 0x90, 0x5e, 0xad, 0xfd, 0xc8, 0x00, 0x33, 0xf9, 0xed, 0x02, 0xa2, 0x45, 0xd5, 0xae, 0xf8, - 0x9c, 0x98, 0x79, 0x21, 0x16, 0x16, 0x01, 0x32, 0x88, 0x44, 0x75, 0x42, 0xc7, 0x0f, 0x05, 0x24, - 0x47, 0x94, 0x84, 0x54, 0x2b, 0x00, 0x13, 0xa4, 0x96, 0x47, 0x6e, 0xaf, 0xf7, 0x15, 0xef, 0x68, - 0xcf, 0x25, 0x4a, 0x73, 0x19, 0x16, 0xaa, 0xdd, 0x6e, 0x52, 0x84, 0xcc, 0x49, 0x22, 0xe3, 0xac, - 0xfa, 0x14, 0x6e, 0x8a, 0x6a, 0x1a, 0x69, 0x27, 0x85, 0x9a, 0x26, 0x83, 0x22, 0x0d, 0xa6, 0x30, - 0x85, 0xb5, 0xc7, 0xca, 0x9b, 0x6e, 0xd2, 0x91, 0x58, 0x90, 0xcc, 0x0b, 0x74, 0xef, 0x6d, 0x8b, - 0xa2, 0x41, 0x8a, 0xb5, 0xa8, 0x98, 0xa3, 0xba, 0x42, 0xaf, 0x82, 0x38, 0x64, 0x62, 0xa3, 0xf9, - 0xc3, 0x9f, 0xad, 0x5c, 0xf8, 0xc1, 0x27, 0x2b, 0xc6, 0x0f, 0x3f, 0x59, 0x31, 0x7e, 0xfa, 0xc9, - 0xca, 0x85, 0xbf, 0xfb, 0xf7, 0x15, 0xe3, 0x2b, 0x77, 0xa5, 0x7f, 0xf2, 0x72, 0xe4, 0x84, 0xbe, - 0xfb, 0xc2, 0xa3, 0x8e, 0x85, 0x28, 0xf4, 0xf1, 0xed, 0xc1, 0xe1, 0xc1, 0xed, 0xc1, 0xde, 0xed, - 0xd8, 0x4d, 0xda, 0x9b, 0xa2, 0xdf, 0x7e, 0xbb, 0xfb, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xad, - 0xd6, 0x4d, 0xc8, 0x40, 0x66, 0x00, 0x00, + 0xa4, 0x2f, 0x05, 0xf2, 0x5a, 0x34, 0xe8, 0x43, 0x81, 0xe2, 0x7e, 0xcd, 0xdc, 0x3b, 0x73, 0x87, + 0xa4, 0x3e, 0x92, 0x36, 0x41, 0x9e, 0xc4, 0x7b, 0x3e, 0xee, 0xe7, 0x39, 0xe7, 0x9e, 0x7b, 0xee, + 0xb9, 0x23, 0x30, 0x7b, 0xde, 0x61, 0x80, 0xfd, 0xe7, 0xee, 0x01, 0xde, 0x18, 0xf8, 0x5e, 0xe8, + 0x21, 0x88, 0x21, 0x2b, 0x9f, 0x39, 0x74, 0xc3, 0x67, 0x27, 0xfb, 0x1b, 0x07, 0xde, 0xf1, 0xed, + 0x43, 0xef, 0xd0, 0xbb, 0x4d, 0x49, 0xf6, 0x4f, 0x9e, 0xd2, 0x12, 0x2d, 0xd0, 0x5f, 0x8c, 0x75, + 0xe5, 0xc6, 0xa1, 0xe7, 0x1d, 0xf6, 0x70, 0x4c, 0x15, 0xba, 0xc7, 0x38, 0x08, 0x9d, 0xe3, 0x01, + 0x27, 0x98, 0x3b, 0xc6, 0xa1, 0xd3, 0x75, 0x42, 0x87, 0x95, 0x2b, 0x3f, 0x28, 0xc0, 0x74, 0xad, + 0xdd, 0x09, 0x3d, 0x1f, 0x23, 0x04, 0xf9, 0xdd, 0xdd, 0x66, 0xbd, 0x6c, 0xac, 0x19, 0xb7, 0x8a, + 0x16, 0xfd, 0x8d, 0x5e, 0x87, 0xb9, 0x0e, 0xeb, 0x4a, 0xb5, 0xdb, 0xf5, 0x71, 0x10, 0x94, 0x73, + 0x14, 0x9b, 0x80, 0xa2, 0x55, 0x80, 0xce, 0x87, 0x2d, 0x41, 0x33, 0x41, 0x69, 0x24, 0x08, 0xda, + 0x00, 0xd4, 0xf2, 0x0e, 0x8e, 0x12, 0x75, 0xe5, 0x29, 0x9d, 0x06, 0x83, 0x6e, 0x42, 0xde, 0xf2, + 0x7a, 0xb8, 0x3c, 0xb5, 0x66, 0xdc, 0x9a, 0xbb, 0x63, 0x6e, 0x44, 0xdd, 0xae, 0xb5, 0x09, 0xdc, + 0xa2, 0x58, 0xd2, 0x63, 0xdb, 0x3d, 0x38, 0x2a, 0x4f, 0xaf, 0x19, 0xb7, 0xf2, 0x16, 0xfd, 0x8d, + 0x3e, 0x0d, 0x93, 0x9d, 0xd0, 0x09, 0x71, 0xb9, 0x40, 0x59, 0x97, 0x36, 0xa4, 0xf9, 0x6d, 0x7b, + 0x5d, 0x4c, 0x91, 0x16, 0xa3, 0x41, 0x5f, 0x84, 0xa9, 0x96, 0xb3, 0x8f, 0x7b, 0x41, 0xb9, 0xb8, + 0x36, 0x71, 0xab, 0x74, 0xe7, 0x86, 0x4c, 0xcd, 0xe7, 0x65, 0x83, 0x51, 0x34, 0xfa, 0xa1, 0xff, + 0x72, 0x33, 0xff, 0x83, 0x9f, 0xdc, 0xb8, 0x64, 0x71, 0x26, 0xf4, 0xff, 0xa0, 0xf8, 0x91, 0xe7, + 0x1f, 0xb1, 0xf6, 0x80, 0xb6, 0xb7, 0x10, 0x77, 0x35, 0x42, 0x59, 0x31, 0x15, 0xaa, 0xc0, 0xcc, + 0x87, 0x27, 0xd8, 0x7f, 0x29, 0xa6, 0xa0, 0x44, 0xa7, 0x40, 0x81, 0xa1, 0x77, 0x00, 0x6a, 0x5e, + 0xff, 0xa9, 0x7b, 0x58, 0x77, 0x42, 0xa7, 0x3c, 0xb3, 0x66, 0xdc, 0x2a, 0xdd, 0x59, 0x56, 0x7a, + 0x16, 0x61, 0x2d, 0x89, 0x12, 0xbd, 0x03, 0x05, 0x0b, 0x07, 0xde, 0x89, 0x7f, 0x80, 0xcb, 0xb3, + 0x94, 0x6b, 0x51, 0xe6, 0x12, 0x38, 0x3e, 0x88, 0x88, 0x16, 0x2d, 0xc3, 0xd4, 0xee, 0xc0, 0x76, + 0x8f, 0x71, 0x79, 0x6e, 0xcd, 0xb8, 0x35, 0x61, 0xf1, 0x12, 0xfa, 0x2c, 0x2c, 0x74, 0x9e, 0x39, + 0x7e, 0x37, 0xb1, 0x6a, 0x97, 0x69, 0x97, 0x75, 0x28, 0xb4, 0x02, 0x85, 0x9a, 0x77, 0x7c, 0xec, + 0x86, 0xcd, 0x7a, 0xd9, 0xa4, 0x64, 0x51, 0x19, 0x7d, 0x00, 0xab, 0x4f, 0x5c, 0xfc, 0xc9, 0x63, + 0x3e, 0x3d, 0xd5, 0xee, 0xb1, 0x1b, 0x04, 0xae, 0xd7, 0xef, 0x9c, 0x0c, 0x06, 0x9e, 0x1f, 0xe2, + 0x6e, 0x79, 0x7e, 0xcd, 0xb8, 0x55, 0xb0, 0x46, 0x50, 0xa1, 0x2d, 0xb8, 0xa1, 0xa5, 0x78, 0x80, + 0xfb, 0xd8, 0x77, 0x42, 0xd7, 0xeb, 0x97, 0x11, 0x95, 0x87, 0x51, 0x64, 0xe8, 0x1e, 0x5c, 0x95, + 0x49, 0xb6, 0xf7, 0xc9, 0x4c, 0xe1, 0x6e, 0x63, 0xe0, 0x1d, 0x3c, 0x2b, 0x2f, 0xd0, 0x3a, 0xb2, + 0x09, 0xd0, 0x7d, 0x58, 0xd1, 0x36, 0x60, 0x61, 0xa7, 0xfb, 0xb2, 0xbc, 0x48, 0xc7, 0x32, 0x84, + 0x82, 0xb4, 0x5e, 0xaf, 0xb7, 0x9e, 0xb8, 0x81, 0xbb, 0xef, 0xf6, 0xdc, 0xf0, 0xe5, 0xa6, 0xe3, + 0xfb, 0x2e, 0xf6, 0x19, 0xfb, 0x12, 0x65, 0xcf, 0x26, 0x40, 0x5f, 0x80, 0xb2, 0x5c, 0x77, 0xb3, + 0x7f, 0x48, 0x16, 0x80, 0x31, 0x2f, 0x53, 0xe6, 0x4c, 0xfc, 0x4a, 0x1b, 0x4a, 0x92, 0x4c, 0x23, + 0x13, 0x26, 0x8e, 0xf0, 0x4b, 0xae, 0xf6, 0xe4, 0x27, 0x7a, 0x13, 0x26, 0x9f, 0x3b, 0xbd, 0x13, + 0x4c, 0x95, 0xbd, 0x24, 0xcb, 0x34, 0xe5, 0x6b, 0xb9, 0x41, 0x68, 0x31, 0x8a, 0x2f, 0xe4, 0xde, + 0x35, 0x1e, 0xe6, 0x0b, 0x93, 0xe6, 0x54, 0xe5, 0x97, 0x13, 0x30, 0x6d, 0x5f, 0x80, 0x29, 0x11, + 0x4a, 0x3d, 0xa1, 0x53, 0xea, 0xfc, 0x18, 0x4a, 0xfd, 0x36, 0x4c, 0x51, 0xd9, 0x0c, 0xca, 0x93, + 0x54, 0xa9, 0xaf, 0xc8, 0xd4, 0x76, 0x9b, 0xe2, 0x9a, 0xfd, 0xa7, 0x9e, 0x50, 0x66, 0x46, 0x8c, + 0xee, 0xc0, 0x62, 0xcb, 0x3b, 0x0c, 0x1d, 0xb7, 0x47, 0x3a, 0x84, 0x7d, 0xd1, 0xcb, 0x29, 0xda, + 0x4b, 0x2d, 0x2e, 0xc3, 0xac, 0x4d, 0x67, 0x9a, 0x35, 0x55, 0xb3, 0x8b, 0x63, 0x6b, 0x76, 0xd2, + 0x6a, 0x80, 0xc6, 0x6a, 0x64, 0x68, 0x6b, 0x29, 0x5b, 0x5b, 0xdf, 0x87, 0x57, 0xaa, 0x27, 0xa1, + 0xd7, 0xec, 0x1f, 0xf8, 0x54, 0xa4, 0x3f, 0xc0, 0xfd, 0x03, 0x1c, 0xab, 0xe3, 0x0c, 0x15, 0xa3, + 0x61, 0x24, 0x0f, 0xf3, 0x85, 0x82, 0x59, 0xac, 0xfc, 0x53, 0x0e, 0x0a, 0x2d, 0xef, 0xf0, 0xff, + 0xc0, 0xd2, 0xdf, 0x23, 0x16, 0x70, 0xd0, 0x73, 0x0f, 0x1c, 0xb1, 0xf8, 0x2b, 0x32, 0x7d, 0xcb, + 0x3b, 0xe4, 0x68, 0x69, 0xfd, 0x23, 0x8e, 0xc4, 0xea, 0x4c, 0x9d, 0xc6, 0xee, 0xb6, 0xbc, 0x03, + 0x87, 0xe8, 0x28, 0x5d, 0xfb, 0x84, 0xdd, 0x15, 0x38, 0xd1, 0x9e, 0x28, 0x57, 0xbe, 0x35, 0x01, + 0x33, 0x64, 0xde, 0x84, 0x40, 0xa2, 0x32, 0x4c, 0xb3, 0x02, 0x9b, 0xbe, 0xbc, 0x25, 0x8a, 0x68, + 0x53, 0x1a, 0x58, 0x8e, 0x0e, 0xec, 0xf5, 0xc4, 0xc0, 0xa2, 0x5a, 0x36, 0x04, 0x21, 0xd5, 0x6e, + 0x69, 0x78, 0x8b, 0x30, 0xc9, 0x4c, 0x1b, 0x9b, 0x5e, 0x56, 0x20, 0x26, 0xbb, 0x85, 0x9d, 0x2e, + 0xf6, 0x9b, 0x75, 0x3a, 0xc5, 0x79, 0x2b, 0x2a, 0xd3, 0xf5, 0xc0, 0xfe, 0x71, 0x79, 0x92, 0xaf, + 0x07, 0xf6, 0x8f, 0xd1, 0xc7, 0x30, 0xdf, 0xf6, 0xfa, 0x4f, 0xbc, 0xd0, 0xed, 0x1f, 0x46, 0x5d, + 0x9a, 0xa2, 0x5d, 0xba, 0x9d, 0xd9, 0xa5, 0x14, 0x07, 0xeb, 0x5b, 0xba, 0xa6, 0x95, 0xff, 0x0f, + 0xb3, 0x0a, 0x8d, 0x6c, 0x9d, 0xf2, 0xcc, 0x3a, 0x2d, 0xca, 0xd6, 0xa9, 0x28, 0x19, 0xa2, 0x95, + 0x3a, 0x2c, 0xeb, 0x5b, 0x3a, 0x4d, 0x2d, 0x95, 0xef, 0x18, 0x30, 0xa7, 0x4a, 0x0a, 0xfa, 0x40, + 0x5d, 0x28, 0x5a, 0x4f, 0xe9, 0x4e, 0x39, 0x6b, 0xbc, 0x9b, 0x05, 0xb2, 0xd2, 0x3f, 0xfc, 0xc9, + 0x0d, 0xc3, 0x52, 0x17, 0xf8, 0x1a, 0x14, 0x45, 0xb5, 0x75, 0xda, 0x70, 0xde, 0x8a, 0x01, 0x68, + 0x0d, 0x4a, 0xcd, 0x20, 0x1a, 0x00, 0x5d, 0xa6, 0x82, 0x25, 0x83, 0x2a, 0x7f, 0x62, 0xc4, 0x5b, + 0x3c, 0xdd, 0x6c, 0x77, 0x76, 0x6d, 0x2f, 0x74, 0x7a, 0x7c, 0x60, 0x51, 0x99, 0x18, 0x8c, 0xda, + 0xce, 0x6e, 0xf5, 0xb9, 0xe3, 0xf6, 0x9c, 0xfd, 0x1e, 0x1b, 0xa4, 0x61, 0x29, 0x30, 0xc2, 0xff, + 0x18, 0x1f, 0x33, 0x7e, 0x26, 0x12, 0x51, 0x99, 0xf0, 0x3f, 0xc6, 0xc7, 0x31, 0x3f, 0x93, 0x0c, + 0x05, 0x56, 0xf9, 0x71, 0x11, 0x4c, 0xee, 0x23, 0x6d, 0x61, 0xc7, 0x0f, 0xf7, 0xb1, 0x13, 0xfe, + 0x06, 0x3a, 0x91, 0x1b, 0x80, 0x6c, 0x27, 0x10, 0xbc, 0x35, 0x1f, 0x3b, 0xc4, 0xf8, 0x4d, 0xd3, + 0xc9, 0xd7, 0x60, 0x52, 0xb6, 0xb8, 0xa0, 0xb1, 0xc5, 0x37, 0x61, 0xb6, 0xd9, 0x77, 0xc3, 0xd8, + 0x39, 0x2c, 0x52, 0x22, 0x15, 0x48, 0xa8, 0x1e, 0x78, 0x41, 0xe0, 0x0e, 0x54, 0xb3, 0xae, 0x02, + 0x49, 0x7b, 0x0c, 0xf0, 0xd0, 0x73, 0xfb, 0xb8, 0x4b, 0x0d, 0x7a, 0xc1, 0x52, 0x60, 0xbf, 0x76, + 0x8f, 0x31, 0x63, 0xaf, 0x99, 0x1b, 0xcf, 0x33, 0xbc, 0x9c, 0xf0, 0x0c, 0x3f, 0x0b, 0x0b, 0xd5, + 0x83, 0x23, 0xdc, 0x25, 0x00, 0xa7, 0xdf, 0xdd, 0x74, 0xc2, 0x83, 0x67, 0xdc, 0x81, 0xcc, 0x5b, + 0x3a, 0x14, 0xd9, 0xb9, 0x38, 0xa4, 0x8e, 0x7b, 0xee, 0x73, 0x32, 0xf3, 0x07, 0x47, 0x49, 0x47, + 0x72, 0x18, 0xc9, 0x18, 0xde, 0x28, 0xba, 0x28, 0x6f, 0x74, 0xe1, 0x02, 0xbc, 0xd1, 0xc5, 0x51, + 0xde, 0x68, 0x62, 0x3c, 0x35, 0x27, 0x74, 0x7a, 0xde, 0x21, 0xdd, 0xae, 0x79, 0x15, 0x4b, 0xb4, + 0x8a, 0x11, 0x54, 0x68, 0x13, 0xae, 0xc9, 0x14, 0x16, 0x7e, 0xea, 0xe3, 0xe0, 0x59, 0x3c, 0x2b, + 0xcc, 0xb7, 0x1c, 0x4a, 0x93, 0xae, 0xe3, 0xb9, 0xd3, 0x73, 0xbb, 0x44, 0x79, 0x58, 0x4f, 0xae, + 0xd0, 0x9e, 0x0c, 0xa5, 0x19, 0xea, 0xdf, 0x96, 0x87, 0xfb, 0xb7, 0xc3, 0x3d, 0xeb, 0xab, 0x23, + 0x3c, 0x6b, 0xee, 0xcd, 0xda, 0x30, 0x53, 0x6b, 0x57, 0x7b, 0x3d, 0xef, 0xc0, 0x09, 0x71, 0xb3, + 0xae, 0x71, 0x92, 0x17, 0x61, 0x92, 0x8a, 0x23, 0xb7, 0xe3, 0xac, 0xc0, 0x2c, 0xfc, 0xd7, 0x4e, + 0x70, 0x40, 0x04, 0x9d, 0x99, 0xb0, 0x18, 0x50, 0xf9, 0xaf, 0x09, 0x98, 0x17, 0x9e, 0xd2, 0x70, + 0x9b, 0xb9, 0x06, 0x25, 0xcb, 0x79, 0x1a, 0xaa, 0x06, 0x53, 0x06, 0x69, 0xac, 0xea, 0x84, 0xd6, + 0xaa, 0xa6, 0xac, 0x4c, 0x5e, 0x67, 0x65, 0xce, 0xe7, 0x39, 0xe9, 0x6d, 0xe8, 0x54, 0xa6, 0x0d, + 0x55, 0xed, 0xd5, 0xf4, 0x99, 0x3c, 0xad, 0xc2, 0xf8, 0x9e, 0x16, 0x91, 0xa6, 0x84, 0x31, 0x88, + 0x25, 0xba, 0xc8, 0xa4, 0x29, 0x0b, 0x3f, 0x86, 0xa5, 0x80, 0x71, 0x2c, 0x45, 0xa5, 0x01, 0x25, + 0xe9, 0xf0, 0x31, 0xc4, 0xd7, 0x1b, 0xea, 0x24, 0x54, 0xbe, 0x3e, 0x09, 0xa6, 0x7d, 0x91, 0xbb, + 0x6e, 0x7c, 0x5c, 0x9a, 0x38, 0xcd, 0x71, 0x49, 0xbf, 0xe4, 0xf9, 0xcc, 0x25, 0xcf, 0x3a, 0x5e, + 0x4d, 0x9e, 0xfa, 0x78, 0x35, 0x35, 0xe6, 0xf1, 0xaa, 0x70, 0xe6, 0xe3, 0x55, 0x71, 0xfc, 0xe3, + 0x15, 0x64, 0x6f, 0x79, 0x44, 0x85, 0xf1, 0xa0, 0xe7, 0xbc, 0xc4, 0xdd, 0x56, 0xd0, 0xa7, 0xfb, + 0x76, 0xde, 0x92, 0x41, 0xe7, 0x3f, 0x80, 0x65, 0x6d, 0x9d, 0xb3, 0x67, 0xde, 0x3a, 0xe7, 0x46, + 0x6e, 0x9d, 0x0f, 0xf3, 0x85, 0x69, 0xb3, 0x50, 0xf9, 0xfe, 0x24, 0x14, 0xac, 0xce, 0x63, 0xe6, + 0xc9, 0x98, 0x30, 0x61, 0x07, 0x9e, 0x70, 0xaf, 0xed, 0xc0, 0x23, 0xd6, 0xb1, 0xd9, 0xef, 0xe2, + 0x17, 0xc2, 0x3a, 0xd2, 0x02, 0xb1, 0x45, 0x2d, 0xec, 0x04, 0x78, 0xcb, 0xeb, 0xb1, 0x13, 0x07, + 0xf3, 0x3b, 0x55, 0x20, 0x59, 0x0e, 0xdb, 0x3f, 0xe9, 0x13, 0xcb, 0x4b, 0x67, 0x8e, 0x3b, 0x9f, + 0x32, 0x0c, 0x3d, 0x84, 0x19, 0xc6, 0xe4, 0x06, 0xa1, 0xe7, 0xbf, 0xe4, 0x36, 0x4b, 0x39, 0x14, + 0x89, 0xde, 0x6d, 0xc8, 0x84, 0xec, 0xe0, 0xa1, 0xf0, 0xb2, 0x85, 0xfa, 0xda, 0x89, 0xeb, 0xb3, + 0xe6, 0xa6, 0xc4, 0x42, 0x45, 0x20, 0xf4, 0x16, 0xcc, 0x7f, 0x54, 0x6d, 0x59, 0xf8, 0xc0, 0x23, + 0xb3, 0x51, 0x77, 0x0f, 0x71, 0x10, 0xf2, 0x63, 0x7e, 0x1a, 0x81, 0x3e, 0x07, 0x4b, 0x12, 0x90, + 0xb6, 0x58, 0xf3, 0x4e, 0xfa, 0x21, 0x95, 0xc8, 0xbc, 0xa5, 0x47, 0x92, 0x85, 0x91, 0x10, 0x35, + 0xef, 0x78, 0xd0, 0xc3, 0x64, 0x3b, 0xec, 0x87, 0xbe, 0x8b, 0x99, 0x4c, 0xe6, 0xad, 0x61, 0x24, + 0x44, 0x5d, 0x24, 0xf4, 0xa6, 0x13, 0x60, 0x32, 0x1c, 0xa0, 0x8c, 0x1a, 0x4c, 0x82, 0xbe, 0xe5, + 0x04, 0x61, 0x2c, 0xa7, 0x1a, 0x0c, 0x7a, 0x08, 0x6b, 0x12, 0x74, 0xdb, 0x77, 0x0f, 0xdd, 0xbe, + 0xd3, 0x53, 0x17, 0x74, 0x86, 0x72, 0x8f, 0xa4, 0x23, 0x82, 0xab, 0x19, 0x0a, 0x15, 0xdc, 0x82, + 0xa5, 0x43, 0xad, 0xbc, 0x07, 0xf3, 0xa9, 0x85, 0x1c, 0x75, 0xae, 0xcb, 0xcb, 0xe7, 0xba, 0x8f, + 0xa1, 0x48, 0xb7, 0xb1, 0x03, 0xcf, 0xef, 0x12, 0x46, 0x32, 0x58, 0xce, 0x48, 0x46, 0xb7, 0x0e, + 0x79, 0xfb, 0xe5, 0x80, 0xf1, 0xcd, 0xa9, 0x66, 0x83, 0xf1, 0x10, 0xac, 0x45, 0x69, 0x88, 0xbd, + 0xa5, 0x26, 0x86, 0x88, 0xef, 0x8c, 0x45, 0x7f, 0x57, 0x7e, 0x9a, 0x03, 0xa0, 0xf5, 0xd3, 0xcd, + 0x9e, 0x90, 0xb4, 0x9d, 0x63, 0x2c, 0x4c, 0x32, 0xf9, 0x2d, 0xdb, 0xfc, 0x9c, 0x6a, 0xf3, 0x79, + 0x77, 0x26, 0xe2, 0xee, 0x94, 0x61, 0xfa, 0xb1, 0xf3, 0xa2, 0xe3, 0xfe, 0x9e, 0x38, 0x7c, 0x89, + 0x22, 0xd9, 0x1f, 0x84, 0x59, 0xae, 0xf3, 0xa3, 0x79, 0x0c, 0xa0, 0x67, 0xf6, 0x76, 0xb3, 0xce, + 0xa5, 0x98, 0xfe, 0x46, 0x9f, 0x83, 0x9c, 0xdd, 0xe1, 0xdb, 0xec, 0xca, 0x06, 0xbb, 0x23, 0xd8, + 0x10, 0x77, 0x04, 0x1b, 0xb6, 0xb8, 0x23, 0x60, 0xc7, 0xd6, 0x3f, 0xfb, 0xd7, 0x1b, 0x86, 0x95, + 0xb3, 0x3b, 0x64, 0xe3, 0x6b, 0xf6, 0x0f, 0x7a, 0x27, 0x5d, 0xdc, 0x78, 0x31, 0x20, 0x9a, 0xc0, + 0x37, 0x21, 0x6e, 0xdf, 0x30, 0x3b, 0xfa, 0x14, 0xac, 0x11, 0x54, 0xc4, 0x45, 0x6e, 0xbc, 0xa0, + 0x14, 0x5b, 0x8e, 0xdf, 0xad, 0x7b, 0x9f, 0xf4, 0x53, 0x15, 0xb1, 0x3d, 0x78, 0x14, 0x59, 0xa5, + 0x02, 0x60, 0x07, 0x9e, 0x98, 0xe1, 0x45, 0x98, 0x64, 0x6a, 0xc5, 0x16, 0x91, 0x15, 0x2a, 0xbf, + 0x30, 0x88, 0xe7, 0x46, 0xf7, 0x47, 0x1a, 0xac, 0xd4, 0xee, 0x8d, 0x77, 0xa1, 0xb8, 0x3d, 0x10, + 0xfe, 0x79, 0x2e, 0x1d, 0x58, 0xaa, 0xb5, 0x29, 0xef, 0xf6, 0xc0, 0x8a, 0xe9, 0xd0, 0x66, 0x74, + 0x59, 0xc0, 0x36, 0xca, 0x9b, 0x9a, 0xcb, 0x02, 0x4a, 0x90, 0x7d, 0x63, 0x70, 0xd1, 0xa1, 0xd7, + 0x4a, 0x0b, 0x4a, 0xb5, 0x76, 0x7c, 0xa2, 0xd4, 0x8d, 0xf5, 0x4d, 0x11, 0x40, 0xcb, 0x65, 0x5f, + 0x50, 0x30, 0x8a, 0xca, 0xcf, 0xf8, 0xdc, 0x39, 0xe1, 0x90, 0xb9, 0x1b, 0xbf, 0xbe, 0xd1, 0x33, + 0x26, 0x1a, 0xfa, 0x35, 0xce, 0xd8, 0x37, 0x0b, 0x30, 0x2d, 0x24, 0x48, 0x71, 0xd6, 0x0d, 0xe1, + 0x69, 0x71, 0x00, 0xda, 0x80, 0xa9, 0xc7, 0x38, 0x7c, 0xe6, 0x75, 0x75, 0x26, 0x81, 0x61, 0xa8, + 0x49, 0xe0, 0x54, 0xe8, 0x9e, 0xac, 0xff, 0x54, 0x95, 0x13, 0xde, 0x47, 0x8c, 0xe5, 0x63, 0x94, + 0xed, 0x45, 0x95, 0x86, 0x98, 0x22, 0x97, 0x8e, 0x2a, 0x7d, 0xe9, 0xce, 0xf5, 0x64, 0x88, 0x49, + 0xf1, 0xfb, 0x2c, 0x85, 0x05, 0xdd, 0x27, 0xc2, 0x10, 0xd7, 0x30, 0x49, 0x6b, 0xb8, 0xa6, 0x91, + 0xd2, 0xb8, 0x02, 0x99, 0x81, 0xf0, 0xdb, 0x12, 0xff, 0x54, 0x9a, 0xdf, 0x4e, 0xf1, 0x4b, 0x0c, + 0xc4, 0xfd, 0x8a, 0xd5, 0x53, 0xe7, 0xd5, 0xc7, 0x58, 0x4b, 0x56, 0xe4, 0x7b, 0xea, 0x59, 0x8b, + 0x3b, 0x6e, 0x65, 0xb5, 0xe3, 0x31, 0xde, 0x52, 0x4f, 0x66, 0xf7, 0x54, 0x7d, 0xe7, 0x51, 0xf5, + 0x72, 0x96, 0x72, 0x5a, 0xaa, 0x75, 0xf8, 0xbc, 0xa2, 0x40, 0x74, 0xb3, 0x4c, 0xb8, 0xc0, 0x12, + 0xda, 0x52, 0x94, 0xed, 0x9e, 0xaa, 0x2c, 0x74, 0xe3, 0xd4, 0x34, 0x2c, 0xf0, 0x96, 0xaa, 0x5a, + 0xef, 0xc1, 0x6c, 0x1d, 0x93, 0x8d, 0x8d, 0x77, 0x87, 0x47, 0x6d, 0xae, 0xca, 0xec, 0x0a, 0x81, + 0xa5, 0xd2, 0xa3, 0x4d, 0x98, 0xdb, 0xf1, 0xbd, 0x17, 0x2f, 0xe3, 0x05, 0x9b, 0xe5, 0x06, 0x5e, + 0xaa, 0x41, 0xa5, 0xb0, 0x12, 0x1c, 0x64, 0x17, 0x4e, 0x06, 0x4c, 0xdb, 0x27, 0xc7, 0xd4, 0x09, + 0xcc, 0x5b, 0x3a, 0x14, 0xda, 0x94, 0xc2, 0xbf, 0xd1, 0x51, 0xec, 0x72, 0xf6, 0x51, 0xcc, 0x4a, + 0x93, 0xd3, 0x39, 0x7f, 0x86, 0x0f, 0x8e, 0xb6, 0xb0, 0xd3, 0x0b, 0x9f, 0xd1, 0x38, 0x4f, 0x72, + 0xce, 0x63, 0xb4, 0x25, 0xd3, 0x22, 0x1b, 0x16, 0x3b, 0x07, 0xcf, 0x70, 0xf7, 0xa4, 0x87, 0xb9, + 0x8b, 0x4a, 0x9d, 0x74, 0x1a, 0xf1, 0x29, 0xdd, 0x59, 0x93, 0xeb, 0xd0, 0xd1, 0x59, 0x5a, 0xee, + 0x8a, 0x07, 0x25, 0xaa, 0x89, 0xc1, 0xc0, 0xeb, 0x07, 0x78, 0xc8, 0xd1, 0x8c, 0x6f, 0xd3, 0x39, + 0x65, 0x9b, 0x16, 0x8e, 0x13, 0xdb, 0xbc, 0x45, 0x71, 0x58, 0x60, 0xbd, 0xb2, 0x01, 0x48, 0x92, + 0x67, 0xa9, 0xdd, 0x0f, 0x5c, 0x5f, 0x32, 0x46, 0xa2, 0x58, 0xf9, 0xcf, 0x3c, 0x0d, 0xd4, 0x31, + 0xb2, 0x8b, 0xb5, 0x5a, 0xd7, 0xa0, 0xd8, 0xf0, 0x7d, 0xcf, 0xaf, 0x79, 0x5d, 0x4c, 0x87, 0x30, + 0x6b, 0xc5, 0x00, 0xe2, 0x8a, 0xd3, 0xc2, 0x63, 0x1c, 0x04, 0xce, 0x21, 0xe6, 0xb1, 0x03, 0x05, + 0x86, 0x56, 0x01, 0x9a, 0xc1, 0x56, 0xf5, 0x11, 0xc6, 0x03, 0xec, 0x53, 0xab, 0x53, 0xb0, 0x24, + 0x08, 0x7a, 0x4f, 0x99, 0x5d, 0x6e, 0x56, 0xae, 0xa4, 0x0c, 0x23, 0x43, 0x73, 0xcb, 0xa8, 0xac, + 0x07, 0x51, 0x34, 0xe9, 0x10, 0xc3, 0x2d, 0x8b, 0xaa, 0x68, 0x12, 0xde, 0x52, 0xa8, 0x89, 0xb4, + 0x51, 0x5b, 0xc3, 0x9b, 0x2f, 0xa4, 0x9b, 0x97, 0xd0, 0x96, 0x4c, 0x4b, 0x54, 0xac, 0xd6, 0x3b, + 0x09, 0x42, 0xec, 0xd7, 0x31, 0x39, 0x9d, 0x06, 0xdc, 0xb8, 0x28, 0x2a, 0xa6, 0x52, 0x58, 0x09, + 0x0e, 0x74, 0x1f, 0x8a, 0xf1, 0xbd, 0x01, 0x68, 0xc4, 0x54, 0x20, 0x99, 0x80, 0xe2, 0xe0, 0xa4, + 0x17, 0x5a, 0x31, 0x0b, 0xba, 0x0f, 0x20, 0x99, 0x46, 0x66, 0x63, 0x56, 0xe5, 0x0a, 0xd2, 0x82, + 0x64, 0x41, 0xc2, 0x3c, 0x12, 0x05, 0xc2, 0x3e, 0xb3, 0x70, 0x33, 0x9a, 0xc9, 0x93, 0xf0, 0x96, + 0x42, 0x5d, 0x79, 0x48, 0xe3, 0x55, 0xcc, 0xff, 0x8d, 0xa6, 0xe5, 0x6d, 0xb2, 0x83, 0x12, 0x48, + 0x50, 0x36, 0xe8, 0xbe, 0xbe, 0x94, 0x5a, 0x4c, 0x82, 0xe5, 0x4b, 0x29, 0x68, 0x2b, 0xaf, 0x29, + 0x0b, 0x41, 0xdc, 0xb7, 0x27, 0x74, 0xdf, 0xe6, 0xee, 0x1b, 0x2d, 0x54, 0x1e, 0xc0, 0xac, 0xed, + 0x04, 0x47, 0xb6, 0xb3, 0xdf, 0xc3, 0xbb, 0x01, 0xf6, 0x89, 0x1a, 0x91, 0xbf, 0xfd, 0xd8, 0x97, + 0x8e, 0xca, 0x04, 0xb7, 0xe3, 0x04, 0xc1, 0x27, 0x9e, 0xdf, 0xe5, 0xc1, 0x8d, 0xa8, 0x5c, 0xf9, + 0x86, 0x41, 0x7a, 0x49, 0xed, 0x96, 0xd6, 0x8d, 0xc9, 0xf6, 0xc5, 0x95, 0xf8, 0xcb, 0x44, 0xf2, + 0x92, 0x26, 0xba, 0x45, 0xcb, 0xcb, 0xb7, 0x68, 0xab, 0x74, 0xef, 0x57, 0x9d, 0x72, 0x09, 0x52, + 0xf9, 0xcb, 0x1c, 0x91, 0xe1, 0xfe, 0x53, 0xf7, 0xb0, 0xf6, 0xcc, 0xe9, 0x1f, 0x62, 0x74, 0x37, + 0xea, 0x1d, 0xbf, 0x4c, 0x5a, 0x50, 0x0f, 0x1c, 0x14, 0x15, 0xcf, 0x20, 0x1b, 0xc7, 0x3d, 0x00, + 0xc6, 0x2e, 0x1d, 0x54, 0xae, 0xa5, 0xe3, 0x1b, 0x31, 0x8d, 0x25, 0xd1, 0x23, 0x1b, 0xe6, 0x9a, + 0x7d, 0x37, 0x74, 0x9d, 0xde, 0x63, 0x7c, 0xbc, 0x8f, 0x7d, 0xe1, 0x95, 0xbd, 0x95, 0x55, 0xc3, + 0x86, 0x4a, 0xce, 0x8e, 0xce, 0x89, 0x3a, 0x56, 0xaa, 0xb0, 0xa0, 0x21, 0x3b, 0xd5, 0x85, 0xdb, + 0x9b, 0x30, 0xdb, 0x79, 0x76, 0x12, 0x76, 0xbd, 0x4f, 0xfa, 0x6c, 0x6b, 0x23, 0x6b, 0x43, 0x7e, + 0x44, 0x4b, 0x26, 0x8a, 0x95, 0x7f, 0x98, 0x84, 0xcb, 0x09, 0x13, 0xae, 0x5d, 0xdd, 0x9b, 0x30, + 0xbb, 0xe9, 0x79, 0x61, 0x10, 0xfa, 0xce, 0x60, 0xe0, 0xf6, 0x0f, 0x69, 0xa3, 0x05, 0x4b, 0x05, + 0x12, 0xd3, 0xc0, 0x63, 0x36, 0x74, 0x42, 0x27, 0xe8, 0x84, 0x2a, 0xa6, 0x41, 0x42, 0x5b, 0x32, + 0x2d, 0xb3, 0x49, 0xf1, 0x54, 0x71, 0x77, 0xad, 0x9c, 0x35, 0x95, 0x96, 0xba, 0xfa, 0xef, 0x25, + 0x46, 0xcc, 0x7d, 0xb5, 0xab, 0xaa, 0x61, 0x90, 0x08, 0xac, 0xc4, 0x0c, 0x3d, 0x82, 0x79, 0x16, + 0x58, 0x93, 0x22, 0x6d, 0xdc, 0xb2, 0x2a, 0x2e, 0x63, 0x8a, 0xc8, 0x4a, 0xf3, 0xa5, 0x5d, 0x91, + 0xe9, 0x53, 0xba, 0x22, 0x8f, 0x60, 0xfe, 0xa1, 0xe7, 0xf6, 0x59, 0x44, 0x99, 0xdb, 0x3f, 0x6e, + 0x68, 0x95, 0xde, 0xa4, 0x88, 0xac, 0x34, 0x1f, 0xda, 0x02, 0x93, 0xd5, 0x4e, 0x7d, 0x15, 0xd6, + 0xa1, 0x62, 0xda, 0x15, 0x4d, 0xd2, 0x58, 0x29, 0x2e, 0xb2, 0xbc, 0xd5, 0x6e, 0x57, 0x68, 0xa1, + 0xce, 0xb7, 0x93, 0xd0, 0x96, 0x4c, 0x4b, 0x2c, 0x7f, 0x24, 0x2a, 0x8c, 0xbb, 0x94, 0xb6, 0xfc, + 0x2a, 0x85, 0x95, 0xe0, 0xa8, 0x60, 0xbd, 0xaf, 0xa2, 0x95, 0xd7, 0x84, 0x24, 0xe6, 0xc6, 0x97, + 0xc4, 0xca, 0x9f, 0xe7, 0x60, 0x39, 0x11, 0xae, 0xb3, 0x1d, 0xff, 0x10, 0x87, 0xf4, 0xea, 0x90, + 0x2f, 0x11, 0x69, 0x84, 0x59, 0xeb, 0xa2, 0xa5, 0xc0, 0x68, 0xb0, 0x4d, 0xa6, 0xc9, 0x31, 0x1a, + 0x19, 0x46, 0xec, 0x6c, 0xe3, 0x05, 0x31, 0x41, 0x6e, 0xc8, 0x6f, 0xa5, 0xa3, 0x32, 0x71, 0x21, + 0x79, 0x7d, 0xb6, 0x7b, 0x8c, 0xbd, 0x93, 0xd0, 0x76, 0x0f, 0x8e, 0x02, 0x6e, 0x1d, 0x75, 0x28, + 0xc2, 0x61, 0x6b, 0x38, 0x98, 0xd1, 0xd4, 0xa1, 0xd0, 0xe7, 0x60, 0xa9, 0x41, 0xcc, 0x85, 0x13, + 0xe2, 0xda, 0x89, 0xef, 0xe3, 0x7e, 0x48, 0x69, 0x02, 0x7e, 0xc3, 0xa0, 0x47, 0x56, 0x6e, 0x6b, + 0xa4, 0x92, 0x0d, 0xc5, 0x0d, 0xe8, 0x05, 0x3b, 0x9b, 0x8e, 0xa8, 0x5c, 0xe9, 0x69, 0x94, 0x0a, + 0xdd, 0x85, 0x3c, 0xd9, 0x6f, 0xb8, 0x95, 0x56, 0x74, 0x42, 0xd9, 0xa8, 0xb8, 0xad, 0xa6, 0xc4, + 0x74, 0x52, 0x9d, 0xe0, 0xa8, 0xee, 0x84, 0xce, 0xbe, 0x13, 0x08, 0x93, 0xa7, 0xc0, 0x88, 0xd5, + 0x53, 0xb5, 0x28, 0xdb, 0xea, 0xbd, 0x95, 0x56, 0x89, 0x21, 0xd4, 0x6f, 0x28, 0x62, 0x9f, 0xed, + 0xcd, 0x56, 0x7e, 0x69, 0x24, 0xa5, 0xfc, 0xac, 0xb7, 0x12, 0xe8, 0x49, 0xc6, 0xde, 0xb2, 0x91, + 0xad, 0x2f, 0xe3, 0xec, 0x2e, 0x44, 0x57, 0xc8, 0x1a, 0xf2, 0x7b, 0x05, 0xfa, 0xfb, 0x22, 0x76, + 0x9c, 0xbf, 0xc8, 0xa9, 0x2e, 0x65, 0x94, 0xe9, 0x62, 0x48, 0x99, 0x2e, 0x5f, 0x64, 0x57, 0xd6, + 0x4e, 0xbf, 0x2b, 0x72, 0x6e, 0x5e, 0x19, 0x72, 0xbe, 0x10, 0x77, 0x4e, 0x82, 0x85, 0x4c, 0xa5, + 0x08, 0xc7, 0xf3, 0x93, 0x81, 0x08, 0xc1, 0xd7, 0x00, 0x38, 0x15, 0x51, 0xb8, 0x3c, 0xad, 0xfa, + 0xfa, 0x90, 0xaa, 0x9b, 0x75, 0x11, 0x2f, 0x88, 0xd9, 0xd0, 0x47, 0xb0, 0xa4, 0xbd, 0x70, 0xe2, + 0x5b, 0xc9, 0xab, 0x72, 0x7d, 0xfa, 0x2c, 0x44, 0x3d, 0x7f, 0xe5, 0xbb, 0xb9, 0x8c, 0x9a, 0x89, + 0x08, 0xec, 0xf8, 0x78, 0xe0, 0xf8, 0x4c, 0x79, 0xc8, 0x8a, 0xc4, 0x00, 0x32, 0xde, 0x46, 0x9f, + 0x68, 0x43, 0x97, 0x6f, 0xb6, 0xa2, 0x98, 0x91, 0x78, 0x74, 0x07, 0x16, 0xa3, 0x5b, 0x5f, 0x9a, + 0x14, 0xc9, 0xc2, 0xed, 0x7c, 0xa9, 0xb5, 0x38, 0xb4, 0x01, 0x48, 0x73, 0xb3, 0xcd, 0x2c, 0x87, + 0x06, 0x43, 0xdc, 0x32, 0xe9, 0x22, 0x9e, 0x85, 0x44, 0x25, 0x08, 0xe9, 0x19, 0xbb, 0x15, 0x66, + 0xe9, 0x1e, 0xac, 0x40, 0x6c, 0x04, 0x19, 0x74, 0x18, 0xe2, 0x2e, 0x0f, 0x71, 0x46, 0xe5, 0xca, + 0x8f, 0x0d, 0xf5, 0x72, 0x3b, 0x9a, 0x1d, 0x61, 0x73, 0x65, 0x5b, 0x69, 0x8c, 0x67, 0x2b, 0x73, + 0xd9, 0xb6, 0xf2, 0x1d, 0x58, 0x8e, 0x75, 0x5e, 0x61, 0x62, 0x73, 0x99, 0x81, 0xcd, 0xb6, 0x98, + 0xf9, 0x61, 0x16, 0xf3, 0xbb, 0x25, 0x28, 0xf1, 0x5e, 0xd0, 0xb3, 0x87, 0xc8, 0xc7, 0x33, 0xa4, + 0x7c, 0xbc, 0xdf, 0xae, 0x64, 0x9e, 0x6a, 0x14, 0xa1, 0x2c, 0x50, 0x35, 0x7c, 0x4d, 0x13, 0x36, + 0xa2, 0x19, 0x6c, 0x63, 0x26, 0x81, 0x17, 0xcf, 0x94, 0x04, 0x0e, 0xfa, 0x14, 0x22, 0xf5, 0xda, + 0xbe, 0x34, 0x4e, 0x72, 0xd0, 0xcc, 0xc8, 0xe4, 0xa0, 0xd9, 0x33, 0x25, 0x07, 0xcd, 0x9d, 0x29, + 0x9d, 0xfc, 0xf2, 0x38, 0xe9, 0xe4, 0xe6, 0x78, 0x49, 0x43, 0xf3, 0x89, 0xa4, 0xa1, 0x11, 0xf7, + 0x98, 0xe8, 0x22, 0x52, 0x80, 0x16, 0x2e, 0x2a, 0x05, 0x68, 0xf1, 0x02, 0x52, 0x80, 0x96, 0xce, + 0x9f, 0x02, 0xb4, 0x7c, 0x21, 0x29, 0x40, 0x57, 0x2e, 0x20, 0x05, 0xa8, 0x3c, 0x46, 0x0a, 0xd0, + 0xf0, 0x04, 0xfb, 0xab, 0x23, 0x13, 0xec, 0x87, 0xa5, 0x10, 0xad, 0x9c, 0x27, 0x85, 0xe8, 0x95, + 0x11, 0x29, 0x44, 0xbf, 0xa2, 0x04, 0xfb, 0xbf, 0x32, 0xd8, 0x5b, 0x1d, 0xfe, 0x70, 0x85, 0x1b, + 0x74, 0x43, 0xff, 0x70, 0xc5, 0x09, 0xf1, 0x06, 0xa3, 0x50, 0x6c, 0x16, 0x03, 0xad, 0x58, 0x50, + 0x92, 0x90, 0x9a, 0x0e, 0x7e, 0x46, 0xed, 0xe0, 0x95, 0x0c, 0xb3, 0x28, 0xfb, 0x54, 0xff, 0x92, + 0xa7, 0x09, 0x2e, 0x17, 0xb2, 0x79, 0xfc, 0x2e, 0x27, 0xe5, 0x37, 0x38, 0x27, 0x65, 0x84, 0x65, + 0x9e, 0x1d, 0x37, 0xc3, 0x84, 0xc8, 0xbb, 0x3d, 0x8e, 0xbc, 0xdb, 0xbf, 0x5a, 0x79, 0xb7, 0xf5, + 0xf2, 0xfe, 0xf7, 0x13, 0x00, 0xd2, 0x79, 0x4c, 0x77, 0xaa, 0x17, 0x2a, 0x90, 0x93, 0x54, 0xe0, + 0x26, 0xcc, 0x12, 0xf5, 0xc6, 0x7d, 0xd5, 0x35, 0x52, 0x81, 0x09, 0xa9, 0xc9, 0x8f, 0x2d, 0x35, + 0xa3, 0xf7, 0xb4, 0xc9, 0x8b, 0xda, 0xd3, 0xa6, 0x2e, 0x60, 0x4f, 0x9b, 0x3e, 0xdf, 0x23, 0xab, + 0xc2, 0xa8, 0x3d, 0xa0, 0xf2, 0x77, 0x46, 0xb4, 0x48, 0x44, 0x8c, 0xde, 0x4f, 0x88, 0x51, 0x25, + 0x75, 0x57, 0x36, 0x4a, 0x92, 0x3e, 0x1c, 0x25, 0x49, 0x6f, 0xa9, 0x92, 0xb4, 0xac, 0x69, 0xc1, + 0xf3, 0xb1, 0x2c, 0x48, 0x3f, 0xca, 0x25, 0x6f, 0xf2, 0xb2, 0x42, 0x9a, 0xaa, 0xe0, 0xe4, 0x46, + 0x0b, 0xce, 0xc4, 0x05, 0x0a, 0x4e, 0xfe, 0xa2, 0x04, 0x67, 0xf2, 0x02, 0x04, 0x67, 0x6a, 0x84, + 0xe0, 0x54, 0xbe, 0x3d, 0x91, 0xbc, 0xbb, 0x41, 0x6f, 0x43, 0x81, 0xab, 0xb2, 0x58, 0xfe, 0x05, + 0x8d, 0x9a, 0x0b, 0x77, 0x56, 0x90, 0x12, 0xb6, 0x9a, 0x60, 0xcb, 0xa5, 0xd9, 0x6a, 0x2a, 0x9b, + 0x20, 0x45, 0xef, 0xd2, 0x6c, 0x23, 0xce, 0xc7, 0x76, 0xb1, 0x45, 0xdd, 0x65, 0x3e, 0x67, 0x8c, + 0x89, 0xd1, 0x7d, 0x28, 0xc5, 0x82, 0x22, 0xe2, 0x03, 0x19, 0x72, 0x24, 0xae, 0xcb, 0x24, 0x06, + 0x54, 0x17, 0x81, 0xa5, 0x2e, 0xaf, 0x81, 0xe5, 0xc6, 0x95, 0xd3, 0xd1, 0xd3, 0xae, 0x5c, 0x87, + 0xca, 0x94, 0x1d, 0x5f, 0x98, 0x3a, 0x67, 0x7c, 0xe1, 0x8f, 0x0c, 0x28, 0xf1, 0x95, 0xa1, 0x7e, + 0xc2, 0xe7, 0xe9, 0xb2, 0xb0, 0xdd, 0xde, 0xe0, 0xbb, 0x7d, 0xe4, 0x0e, 0x71, 0x8c, 0x72, 0xa1, + 0x14, 0x91, 0xa3, 0x7b, 0x6c, 0x8e, 0x19, 0x6f, 0x8e, 0x8f, 0x32, 0x76, 0xa5, 0x44, 0x64, 0x57, + 0x66, 0x8e, 0x19, 0x2a, 0xdf, 0xcb, 0xc3, 0x12, 0x0f, 0x24, 0x89, 0x70, 0x34, 0x4f, 0x48, 0x78, + 0x1d, 0xe6, 0xda, 0x27, 0xc7, 0xdb, 0x4f, 0xe3, 0xca, 0x99, 0x13, 0x93, 0x80, 0x12, 0x95, 0xa4, + 0x90, 0xa8, 0xff, 0xcc, 0xd0, 0xab, 0x40, 0xb4, 0x0e, 0xa6, 0xe0, 0x8b, 0x52, 0xac, 0xd9, 0xe9, + 0x3d, 0x05, 0x27, 0x67, 0xa7, 0x36, 0x7e, 0x11, 0x46, 0x57, 0xc6, 0xbc, 0x84, 0x6c, 0x28, 0xb1, + 0x5f, 0x9b, 0x2f, 0x1f, 0x61, 0x91, 0xed, 0x78, 0x47, 0x5e, 0x03, 0xed, 0x48, 0x36, 0x24, 0x26, + 0x16, 0x60, 0x93, 0xab, 0x41, 0x4f, 0x75, 0x97, 0xf9, 0xec, 0x2d, 0xd7, 0xbb, 0x63, 0xd4, 0x9d, + 0x64, 0x4d, 0x3e, 0xea, 0x8a, 0x2e, 0xfc, 0xa9, 0xcf, 0x74, 0x28, 0x6e, 0x20, 0x78, 0x62, 0x9f, + 0x38, 0x95, 0xa7, 0x31, 0x2b, 0xf7, 0xc1, 0x4c, 0x76, 0x5c, 0x9f, 0x80, 0xaf, 0xcf, 0xf4, 0x53, + 0xde, 0x81, 0x29, 0x9d, 0x1b, 0x55, 0x8b, 0x12, 0x24, 0xfc, 0x6f, 0x03, 0xae, 0x5a, 0x38, 0x60, + 0x51, 0xd5, 0x8f, 0x9c, 0x10, 0xfb, 0xc7, 0x8e, 0x7f, 0x24, 0x64, 0x24, 0x5e, 0x29, 0x43, 0x59, + 0xa9, 0x2f, 0xa9, 0x2b, 0xc5, 0xa4, 0xf2, 0x9d, 0xc4, 0xc1, 0x59, 0x5f, 0xe7, 0x88, 0xd5, 0xd2, + 0xcf, 0xe2, 0xc4, 0xaf, 0x6a, 0x16, 0x2b, 0xff, 0xc1, 0x9f, 0x27, 0x0e, 0xf5, 0xe8, 0x7f, 0xf7, + 0x4e, 0xe1, 0xb7, 0xed, 0x9d, 0xc2, 0x3f, 0x8a, 0xd7, 0xbc, 0xc4, 0x61, 0xba, 0x1f, 0x1d, 0xc4, + 0x98, 0x69, 0x5e, 0x4b, 0x6d, 0x61, 0xd4, 0x5d, 0xa2, 0x24, 0xaa, 0xbb, 0xc4, 0x6c, 0xdf, 0xfd, + 0xc8, 0xe1, 0xca, 0x0d, 0xe3, 0xcf, 0x74, 0xb7, 0x3a, 0x50, 0x92, 0x2a, 0xd7, 0xc4, 0xf8, 0x37, + 0x54, 0x77, 0x2b, 0xf3, 0x49, 0xa6, 0x6c, 0x1e, 0x3a, 0xa3, 0x7c, 0xb8, 0x51, 0x95, 0xea, 0x8e, + 0x03, 0xff, 0x5e, 0x50, 0x13, 0x2d, 0xb4, 0xda, 0xf2, 0x9e, 0xb2, 0xf5, 0x69, 0x0f, 0xd7, 0x31, + 0x5a, 0xec, 0xed, 0xf2, 0x66, 0x79, 0x37, 0x3a, 0x12, 0x71, 0xdf, 0x6e, 0x41, 0x73, 0x10, 0x12, + 0x69, 0x03, 0xe2, 0xf0, 0xf4, 0x4e, 0xbc, 0xa0, 0xfc, 0x28, 0xb1, 0xa8, 0x5b, 0x86, 0x58, 0x1a, + 0xf9, 0xe2, 0xdf, 0x8d, 0xe2, 0x0d, 0xfc, 0x52, 0x61, 0x41, 0x13, 0x65, 0x10, 0x8d, 0x89, 0xc8, + 0xc4, 0x6d, 0x91, 0x1e, 0xca, 0x02, 0xb5, 0xca, 0x85, 0x99, 0x48, 0x09, 0x52, 0x92, 0x44, 0xdb, + 0x5c, 0x27, 0xf9, 0x9d, 0x07, 0x4f, 0x53, 0x99, 0xa6, 0xdc, 0xab, 0xc9, 0xeb, 0x36, 0x95, 0xca, + 0xd2, 0x70, 0xa2, 0x46, 0x22, 0x83, 0x84, 0x2b, 0xe0, 0xc8, 0x9b, 0xbb, 0x44, 0xde, 0x89, 0xb0, + 0xef, 0x5d, 0x9e, 0x79, 0xcf, 0x4b, 0xe8, 0x91, 0x6a, 0xdf, 0x81, 0x8a, 0xf5, 0x9b, 0x59, 0xe9, + 0x34, 0x23, 0x4c, 0xfa, 0x3d, 0xf9, 0x74, 0xc2, 0xaf, 0x98, 0x97, 0xf5, 0x67, 0x12, 0x71, 0x05, + 0x24, 0x9d, 0x66, 0xe4, 0x00, 0xed, 0xcc, 0xe9, 0x5e, 0x6f, 0xea, 0xb2, 0xfe, 0x66, 0xb3, 0xb3, + 0xfe, 0xb6, 0x74, 0x8e, 0xc2, 0xdc, 0x48, 0xc3, 0xa6, 0x71, 0x05, 0xee, 0xc1, 0xd5, 0xf4, 0x56, + 0xb5, 0x83, 0xfb, 0x5d, 0xb7, 0x7f, 0x48, 0xe3, 0xc5, 0x05, 0x2b, 0x9b, 0x00, 0x6d, 0xc2, 0x35, + 0x65, 0xdb, 0xa4, 0x1b, 0xa9, 0x74, 0xb4, 0x60, 0x4f, 0x46, 0x87, 0xd2, 0x90, 0x23, 0xa5, 0xa6, + 0x01, 0x7a, 0x8d, 0x15, 0x3d, 0x1d, 0x1d, 0x42, 0x81, 0xde, 0x87, 0x57, 0xd2, 0xd8, 0xe8, 0x2d, + 0x86, 0x08, 0x3c, 0x0f, 0x21, 0x39, 0xf7, 0xc6, 0xfc, 0xa7, 0x06, 0xcc, 0xc8, 0xce, 0xba, 0xf6, + 0xb8, 0x78, 0x0d, 0x8a, 0xec, 0x5a, 0x48, 0xe4, 0x13, 0x14, 0xad, 0x18, 0x80, 0xca, 0x30, 0xad, + 0xee, 0xc6, 0xa2, 0x28, 0x45, 0xef, 0xf3, 0x4a, 0xf4, 0x7e, 0x05, 0x0a, 0x75, 0xef, 0x93, 0x3e, + 0xc5, 0x4c, 0x52, 0x4c, 0x54, 0xae, 0x7c, 0xbb, 0x02, 0xa6, 0xd0, 0xed, 0xe8, 0x4d, 0x50, 0xf4, + 0x02, 0xc8, 0x90, 0x5f, 0x00, 0xe9, 0x42, 0x22, 0xb1, 0x2b, 0x35, 0xa1, 0xb8, 0x52, 0xdb, 0xaa, + 0xaa, 0xb1, 0x83, 0xd0, 0x67, 0x74, 0x06, 0x25, 0x7a, 0xea, 0x33, 0x5c, 0xdd, 0x74, 0xdf, 0x33, + 0xf8, 0x5f, 0xb7, 0x57, 0x5d, 0x30, 0x13, 0xf7, 0xbd, 0xe2, 0x32, 0xea, 0xce, 0xd0, 0xa1, 0x26, + 0x99, 0xe4, 0xed, 0x33, 0x55, 0x23, 0x6a, 0xca, 0x47, 0x25, 0xf6, 0xb1, 0xa3, 0x4f, 0x0f, 0xad, + 0x3e, 0xa2, 0x66, 0xf3, 0x18, 0x73, 0xcb, 0xdb, 0x02, 0x8c, 0xbd, 0x2d, 0x48, 0x1b, 0x57, 0xe9, + 0x4c, 0x1b, 0xd7, 0xcc, 0x29, 0x36, 0xae, 0xc4, 0x36, 0x3b, 0x7b, 0xea, 0x6d, 0x36, 0xb5, 0x87, + 0xcc, 0x9d, 0x69, 0x0f, 0x51, 0xcd, 0xfb, 0xe5, 0x53, 0x9a, 0xf7, 0xd4, 0x39, 0xde, 0x3c, 0xcb, + 0x39, 0x3e, 0xc3, 0xd8, 0xcf, 0x9f, 0xd2, 0xd8, 0xa3, 0x0b, 0x37, 0xf6, 0x0b, 0xe7, 0x35, 0xf6, + 0x8b, 0xe7, 0x36, 0xf6, 0x4b, 0xe7, 0x35, 0xf6, 0xcb, 0x23, 0x8d, 0x3d, 0x7a, 0x27, 0x95, 0x9d, + 0x25, 0xb2, 0x24, 0xd8, 0x3d, 0x5a, 0x06, 0x56, 0x73, 0x14, 0x88, 0x73, 0x2f, 0xca, 0xda, 0xa3, + 0x40, 0x9c, 0x8a, 0xf1, 0x55, 0x58, 0x4c, 0xe0, 0xc4, 0x9d, 0x59, 0xea, 0x30, 0x9a, 0xd2, 0x7b, + 0x1d, 0x23, 0x33, 0x01, 0xda, 0x3a, 0xd1, 0x20, 0x35, 0xbe, 0x5a, 0x5b, 0xdc, 0xb1, 0xa5, 0x02, + 0x09, 0xa3, 0x5a, 0xe3, 0xac, 0xac, 0xbd, 0x8c, 0x7a, 0x35, 0x2d, 0xda, 0x6d, 0x71, 0x31, 0x77, + 0xea, 0x16, 0xed, 0x61, 0x2d, 0x72, 0x24, 0xda, 0x82, 0x1b, 0x09, 0x0c, 0x4f, 0xe5, 0x09, 0xaa, + 0x41, 0xe0, 0x1e, 0xf6, 0x71, 0xb7, 0x7c, 0x8d, 0xbd, 0x60, 0x1b, 0x41, 0x86, 0x5a, 0xf0, 0x6a, + 0x72, 0x54, 0x51, 0x4a, 0x4f, 0x54, 0xd7, 0x75, 0x5a, 0xd7, 0x68, 0xc2, 0xcc, 0x23, 0x5f, 0x2c, + 0x29, 0xab, 0x43, 0x8e, 0x7c, 0xb1, 0xbc, 0x6c, 0x66, 0xe4, 0xb4, 0x08, 0x49, 0xbd, 0x91, 0xbe, + 0xf1, 0x4d, 0xd2, 0x64, 0x46, 0xea, 0x59, 0xbc, 0x76, 0x8d, 0xea, 0xea, 0x10, 0x0a, 0xf4, 0x10, + 0xd6, 0xb4, 0xb7, 0xc1, 0x72, 0x6a, 0xd0, 0xab, 0xb4, 0x1f, 0x23, 0xe9, 0xc6, 0xb8, 0x09, 0xaf, + 0x8c, 0x75, 0x13, 0xfe, 0x75, 0x03, 0xae, 0x6b, 0xbb, 0x4c, 0xc3, 0x0c, 0x44, 0xe2, 0x5e, 0xa3, + 0x12, 0xf7, 0xde, 0x50, 0x89, 0x1b, 0x5a, 0x03, 0x13, 0xbc, 0xe1, 0xad, 0xa0, 0x3f, 0xc8, 0x4a, + 0x3a, 0x12, 0xaa, 0x76, 0x93, 0x76, 0xe3, 0xfe, 0xe9, 0xbb, 0xa1, 0x28, 0xdc, 0xd0, 0x36, 0xd0, + 0x37, 0x8c, 0x8c, 0xd0, 0x3e, 0xdd, 0xb2, 0x58, 0x3f, 0x3e, 0x45, 0xfb, 0x51, 0x3d, 0x7d, 0x3f, + 0xe2, 0x3a, 0x58, 0x57, 0x46, 0xb5, 0x84, 0xfe, 0xd8, 0xc8, 0x90, 0xfd, 0x5a, 0x9b, 0x67, 0x62, + 0x95, 0x5f, 0xa7, 0x9d, 0x79, 0xff, 0x2c, 0x93, 0xc2, 0xab, 0x60, 0x7d, 0x19, 0xd1, 0x0e, 0xfa, + 0xa6, 0x01, 0xaf, 0x66, 0x77, 0x57, 0xf4, 0xe6, 0x0d, 0xda, 0x9b, 0xda, 0x19, 0xa7, 0x46, 0xe9, + 0xd0, 0xe8, 0xd6, 0x32, 0x35, 0x5a, 0x6c, 0xbe, 0xb7, 0x86, 0x68, 0xb4, 0xd8, 0x7f, 0xbf, 0x65, + 0x40, 0x65, 0xe8, 0xd0, 0x59, 0x22, 0xda, 0x9b, 0x74, 0x60, 0xf5, 0xb3, 0x4f, 0x33, 0xad, 0x86, + 0x8d, 0x6c, 0x8c, 0xf6, 0xd0, 0xf7, 0x0c, 0xf8, 0xd4, 0xa8, 0x09, 0x60, 0x3d, 0x5b, 0xa7, 0x3d, + 0x7b, 0x70, 0xae, 0x29, 0x97, 0x3a, 0x37, 0x5e, 0xab, 0xe7, 0x0e, 0x5e, 0x7f, 0x0c, 0x4b, 0x5a, + 0xd7, 0xfe, 0x94, 0x71, 0x2a, 0xe5, 0x45, 0x94, 0x54, 0xfd, 0x3d, 0xfa, 0x71, 0xb3, 0x8c, 0xa0, + 0xda, 0xc8, 0xce, 0x3d, 0x80, 0xab, 0x99, 0x0e, 0xc2, 0xa8, 0x8a, 0x0a, 0x72, 0x45, 0xcd, 0x54, + 0x92, 0x80, 0x6c, 0x8a, 0xce, 0x59, 0x95, 0x7d, 0xd6, 0xaa, 0x76, 0x32, 0x24, 0x5e, 0xb1, 0xd6, + 0xa7, 0xaa, 0x71, 0x3b, 0xc3, 0x36, 0x9c, 0x79, 0xb4, 0x16, 0xdc, 0x1c, 0xc7, 0x82, 0x9e, 0xaa, + 0xce, 0x0f, 0xe1, 0xb5, 0x31, 0x0c, 0xe1, 0xa9, 0x04, 0xc5, 0x86, 0xd7, 0xc7, 0xb3, 0x66, 0xa7, + 0xaa, 0x75, 0x17, 0xde, 0x18, 0xd3, 0x94, 0x9c, 0xaa, 0xda, 0x2f, 0xc1, 0xfa, 0xf8, 0x76, 0xe0, + 0x54, 0xa1, 0x9a, 0x26, 0xcb, 0xb7, 0x11, 0xdf, 0x11, 0x3c, 0xc7, 0x77, 0x7a, 0x2a, 0x7f, 0x9d, + 0x83, 0x45, 0xdd, 0x63, 0xc1, 0x21, 0x39, 0xfb, 0x3b, 0xa9, 0xaf, 0x46, 0x6e, 0x8c, 0x7a, 0x7a, + 0xa8, 0x7e, 0x3d, 0x32, 0x75, 0x81, 0x72, 0x21, 0xdf, 0x90, 0x5c, 0xb1, 0x47, 0x7f, 0xe4, 0x71, + 0x58, 0x42, 0x8e, 0x34, 0xa3, 0xf2, 0x5c, 0x7f, 0xdf, 0x00, 0xd8, 0x74, 0x0e, 0x8e, 0x4e, 0x06, + 0xf4, 0x0e, 0x26, 0xeb, 0x82, 0xae, 0xa9, 0xbb, 0xa0, 0x7b, 0x43, 0x79, 0xa7, 0x10, 0x55, 0x32, + 0x3c, 0x9e, 0x74, 0xee, 0x40, 0xde, 0x1f, 0x1a, 0xe2, 0x7e, 0xa9, 0x19, 0xe2, 0x63, 0xed, 0x27, + 0x43, 0x2a, 0x30, 0xc3, 0x73, 0xb4, 0x9f, 0x48, 0xb7, 0x94, 0x0a, 0x8c, 0xd0, 0xd4, 0xf1, 0x53, + 0xe7, 0xa4, 0xc7, 0x69, 0x58, 0x44, 0x4f, 0x81, 0x91, 0x25, 0x6a, 0xf6, 0x43, 0xec, 0xf7, 0x9d, + 0x1e, 0xbf, 0x58, 0x8b, 0xca, 0x95, 0xbf, 0x31, 0xe4, 0x6b, 0x2e, 0xf4, 0x45, 0x98, 0xae, 0x79, + 0xfd, 0x10, 0xd3, 0x2f, 0x6b, 0xa4, 0x93, 0xa2, 0x23, 0xc2, 0x0d, 0x4e, 0xc5, 0x26, 0x46, 0xf0, + 0xac, 0x58, 0xf4, 0x65, 0x5c, 0x84, 0x38, 0x65, 0x8a, 0x4c, 0x3c, 0x1d, 0xf2, 0x44, 0xfd, 0x7e, + 0x7c, 0x9f, 0x86, 0xde, 0x8e, 0xdf, 0x8d, 0xa6, 0x32, 0xc1, 0x04, 0xd1, 0x06, 0xa5, 0x60, 0x1d, + 0x63, 0xd4, 0x2b, 0xef, 0x02, 0xc4, 0xc0, 0x53, 0xdd, 0x03, 0xbf, 0xa1, 0x3c, 0x57, 0x1f, 0xf2, + 0x9e, 0xe6, 0x63, 0x98, 0x4f, 0xbd, 0xdc, 0x40, 0x37, 0x61, 0x96, 0x7d, 0x01, 0x47, 0x3c, 0x06, + 0x61, 0x4c, 0x2a, 0x90, 0x2e, 0x33, 0x67, 0x91, 0xbe, 0x9a, 0xa4, 0xc0, 0xd6, 0x3f, 0x01, 0xd8, + 0x1d, 0x74, 0x9d, 0x90, 0x45, 0x70, 0xaf, 0xc0, 0x82, 0xf2, 0x45, 0x1d, 0x86, 0x32, 0x2f, 0xa1, + 0x25, 0x98, 0x17, 0x5f, 0x4a, 0x6a, 0x75, 0xda, 0x1c, 0x6c, 0xa0, 0x05, 0xb8, 0xbc, 0x1b, 0x60, + 0x9f, 0x0e, 0x9f, 0x03, 0x73, 0x68, 0x16, 0x8a, 0x76, 0x67, 0x9b, 0x17, 0x27, 0x08, 0x6b, 0xf4, + 0xd5, 0xa3, 0x88, 0x35, 0xbf, 0xbe, 0x01, 0xc5, 0xe8, 0x4b, 0xbb, 0xe8, 0x32, 0x94, 0xda, 0x9e, + 0x7f, 0xec, 0xf4, 0x68, 0xd1, 0xbc, 0x84, 0x4c, 0x98, 0xe1, 0x4f, 0x0f, 0x18, 0xc4, 0x58, 0xff, + 0x45, 0x1e, 0x20, 0x7e, 0x69, 0x8e, 0xe6, 0x00, 0xec, 0xce, 0xf6, 0xde, 0xee, 0x4e, 0xbd, 0x6a, + 0x37, 0xcc, 0x4b, 0x08, 0x60, 0xaa, 0xba, 0xb3, 0xd3, 0x68, 0xd7, 0x4d, 0x03, 0x15, 0x20, 0x6f, + 0x35, 0xaa, 0x75, 0x33, 0x87, 0x66, 0xa0, 0x60, 0x5b, 0xbb, 0xed, 0x1a, 0xa1, 0x99, 0x20, 0x95, + 0x3e, 0x68, 0xd8, 0x7b, 0x11, 0x24, 0x8f, 0x4a, 0x30, 0x5d, 0xdb, 0x6e, 0xb7, 0x1b, 0x35, 0xdb, + 0x9c, 0x24, 0x55, 0xf2, 0xc2, 0x9e, 0xb5, 0x6d, 0x4e, 0xa1, 0x79, 0x98, 0x6d, 0x6d, 0x3f, 0xd8, + 0xdb, 0x6a, 0x54, 0x2d, 0x7b, 0xb3, 0x51, 0xb5, 0xcd, 0x69, 0x52, 0x43, 0xad, 0x2d, 0x41, 0x0a, + 0xb4, 0xa3, 0x32, 0xa4, 0x88, 0x10, 0xcc, 0xd5, 0xb6, 0x1a, 0xb5, 0x47, 0x7b, 0x5b, 0xd5, 0x47, + 0x8d, 0xc6, 0x4e, 0xc3, 0x32, 0x81, 0xcc, 0x2b, 0x69, 0xb9, 0xd6, 0xda, 0xed, 0xd8, 0x0d, 0x6b, + 0xaf, 0xde, 0xb0, 0xab, 0xcd, 0x56, 0xc7, 0x2c, 0x11, 0x62, 0x82, 0xe8, 0x6c, 0x55, 0xad, 0xfa, + 0x5e, 0xb3, 0xfd, 0xc1, 0xb6, 0x39, 0x43, 0x2b, 0x68, 0xef, 0x55, 0x5b, 0xad, 0x6d, 0xd2, 0xcb, + 0xbd, 0x66, 0xdd, 0x9c, 0x25, 0x93, 0x28, 0x57, 0xd0, 0xb1, 0x49, 0xff, 0xe7, 0xe8, 0xfc, 0xd3, + 0x19, 0xd8, 0xab, 0xb5, 0xf7, 0x5a, 0xd5, 0xcd, 0x46, 0xcb, 0xbc, 0x8c, 0xca, 0xb0, 0x18, 0x03, + 0x3f, 0xda, 0xb6, 0x1e, 0x71, 0x72, 0x93, 0xd4, 0xbc, 0x53, 0xb5, 0x6b, 0x5b, 0x04, 0xd1, 0xb1, + 0xb7, 0xad, 0x86, 0x39, 0x4f, 0xaa, 0xa8, 0x37, 0x5a, 0x0d, 0x46, 0xcd, 0x80, 0x88, 0x00, 0x77, + 0xac, 0xed, 0x2f, 0x7d, 0x59, 0x1a, 0xd8, 0x02, 0x7a, 0x15, 0xae, 0xf3, 0x7a, 0xdb, 0xdb, 0xed, + 0xbd, 0x27, 0xdb, 0x76, 0xb3, 0xfd, 0x60, 0xcf, 0x6a, 0xec, 0xb4, 0x9a, 0xb5, 0xea, 0x5e, 0x7b, + 0xf7, 0xb1, 0xb9, 0x88, 0x56, 0x61, 0x25, 0x4d, 0x42, 0xc6, 0xd1, 0x6a, 0xda, 0x5f, 0x36, 0x97, + 0xd0, 0x22, 0x98, 0x9d, 0x86, 0xbd, 0x67, 0x35, 0x3e, 0xdc, 0x6d, 0x5a, 0x8d, 0xfa, 0x5e, 0xab, + 0xd3, 0x36, 0x97, 0x09, 0xf4, 0x41, 0x12, 0x7a, 0x45, 0x4c, 0x4d, 0xab, 0x6a, 0x37, 0x3a, 0x36, + 0x85, 0x95, 0xc9, 0x92, 0x50, 0x58, 0xa3, 0x5a, 0x6f, 0x58, 0x64, 0x66, 0xae, 0xd2, 0x25, 0x61, + 0xd3, 0xdd, 0xa8, 0xb6, 0xec, 0x2d, 0x73, 0x85, 0x2c, 0x3a, 0x59, 0x7e, 0xca, 0xf2, 0x0a, 0xba, + 0x0a, 0x4b, 0xbc, 0x4b, 0xad, 0x46, 0xb5, 0xd3, 0xd8, 0xda, 0x6e, 0x71, 0xd6, 0x6b, 0x04, 0x45, + 0x27, 0xbf, 0xb6, 0xd5, 0xa8, 0xef, 0xb6, 0x1a, 0x7b, 0xb5, 0xed, 0xc7, 0x8f, 0xab, 0xed, 0x7a, + 0xc7, 0xbc, 0xbe, 0xde, 0x06, 0x88, 0xbf, 0xcf, 0x44, 0x24, 0x83, 0x88, 0x39, 0x83, 0x98, 0x97, + 0x48, 0x0b, 0xc2, 0xce, 0x99, 0x06, 0x11, 0x5e, 0xaa, 0x34, 0x91, 0x02, 0xcc, 0xf3, 0x0f, 0x92, + 0x59, 0xf8, 0xab, 0xf8, 0x20, 0xc4, 0x5d, 0x73, 0x62, 0x7d, 0x1d, 0x8a, 0xd1, 0xe7, 0x7f, 0x08, + 0x7b, 0x07, 0x87, 0xb4, 0x64, 0x5e, 0x22, 0xec, 0x2c, 0xb8, 0xca, 0x00, 0xc6, 0xfa, 0x3f, 0xe7, + 0x01, 0x89, 0x23, 0x85, 0xa4, 0x9b, 0x44, 0xe2, 0xdd, 0x83, 0x23, 0x59, 0x25, 0xa5, 0xef, 0xac, + 0x44, 0x2a, 0x49, 0x34, 0x35, 0x05, 0xce, 0xa1, 0x65, 0x9a, 0xe7, 0x91, 0x84, 0x4f, 0x90, 0xd6, + 0x1f, 0xe0, 0x30, 0xd2, 0xf4, 0x3c, 0x99, 0x94, 0x84, 0xbd, 0xe1, 0xa8, 0x49, 0xb2, 0x22, 0x1d, + 0xcc, 0x14, 0x92, 0xc3, 0xa6, 0x88, 0xb0, 0xa9, 0x89, 0x3c, 0x1c, 0x33, 0x8d, 0x6e, 0xc0, 0x2b, + 0x1d, 0x1c, 0xa6, 0xef, 0x26, 0x38, 0x41, 0x01, 0xad, 0xc0, 0x32, 0x27, 0x88, 0x82, 0xdb, 0x1c, + 0x57, 0x24, 0x53, 0xc8, 0x7e, 0xf3, 0x59, 0x33, 0x81, 0x0c, 0x4c, 0x80, 0xa2, 0x47, 0x2f, 0x66, + 0x89, 0xac, 0xff, 0x0e, 0xb1, 0x77, 0x3c, 0x47, 0xce, 0x9c, 0x21, 0xbc, 0x16, 0x3e, 0xf6, 0x9e, + 0x8b, 0x37, 0x90, 0xe6, 0x2c, 0xe9, 0xa5, 0x9a, 0x0c, 0xc9, 0x1b, 0x9a, 0x43, 0xd7, 0xe1, 0x2a, + 0xfb, 0xad, 0x09, 0x5a, 0x9b, 0x97, 0xd1, 0x2b, 0x70, 0x25, 0x81, 0x16, 0xbb, 0x01, 0x53, 0x27, + 0x71, 0xea, 0xe1, 0xf5, 0xcd, 0xa3, 0x6b, 0x50, 0x4e, 0xa7, 0xe2, 0x70, 0x2c, 0x42, 0x37, 0x61, + 0x4d, 0x04, 0x71, 0xd3, 0xe1, 0x5d, 0x4e, 0xb5, 0x40, 0x66, 0x8e, 0x05, 0xc0, 0x12, 0x27, 0x10, + 0x4e, 0xb0, 0x88, 0x3e, 0x05, 0xaf, 0x32, 0x02, 0xad, 0x83, 0xc9, 0xc9, 0x96, 0xd6, 0xbf, 0x63, + 0xc0, 0xac, 0x72, 0xdb, 0x44, 0xf4, 0x5a, 0x00, 0x78, 0x36, 0x8a, 0x79, 0x89, 0xac, 0xb8, 0x00, + 0x2a, 0x2f, 0xd9, 0x4d, 0x83, 0x34, 0x94, 0x42, 0x89, 0xf3, 0xa3, 0x85, 0x0f, 0xb0, 0xfb, 0x1c, + 0x77, 0xcd, 0x1c, 0x99, 0xa5, 0x14, 0xd9, 0x07, 0x8e, 0xdb, 0x23, 0xa2, 0x2f, 0xb7, 0x69, 0x9d, + 0xf4, 0xfb, 0xa4, 0xe2, 0xfc, 0xfa, 0xbe, 0xee, 0xbe, 0x8b, 0x2c, 0x93, 0x02, 0x8d, 0xfb, 0x98, + 0xc4, 0x88, 0x9a, 0x8c, 0x14, 0xa6, 0x13, 0x7a, 0x83, 0x01, 0xe9, 0xd5, 0xfa, 0x8f, 0x0c, 0x30, + 0x93, 0xdf, 0x2e, 0x20, 0x5a, 0x54, 0xed, 0x8a, 0xcf, 0x89, 0x99, 0x97, 0x62, 0x61, 0x11, 0x20, + 0x83, 0x48, 0x54, 0x27, 0x74, 0xfc, 0x50, 0x40, 0x72, 0x44, 0x49, 0x48, 0xb5, 0x02, 0x30, 0x41, + 0x6a, 0x79, 0xe4, 0xf6, 0x7a, 0x5f, 0xf1, 0x8e, 0xf7, 0x5d, 0xa2, 0x34, 0x57, 0x60, 0xa1, 0xda, + 0xed, 0x26, 0x45, 0xc8, 0x9c, 0x24, 0x32, 0xce, 0xaa, 0x4f, 0xe1, 0xa6, 0xa8, 0xa6, 0x91, 0x76, + 0x52, 0xa8, 0x69, 0x32, 0x28, 0xd2, 0x60, 0x0a, 0x53, 0x58, 0x7f, 0xac, 0xbc, 0xe9, 0x26, 0x1d, + 0x89, 0x05, 0xc9, 0xbc, 0x44, 0xf7, 0xde, 0xb6, 0x28, 0x1a, 0xa4, 0x58, 0x8b, 0x8a, 0x39, 0xaa, + 0x2b, 0xf4, 0x2a, 0x88, 0x43, 0x26, 0x36, 0x9b, 0x3f, 0xfc, 0xd9, 0xea, 0xa5, 0x1f, 0xfc, 0x7c, + 0xd5, 0xf8, 0xe1, 0xcf, 0x57, 0x8d, 0x9f, 0xfe, 0x7c, 0xf5, 0xd2, 0xdf, 0xfe, 0xdb, 0xaa, 0xf1, + 0x95, 0xbb, 0xd2, 0x3f, 0x88, 0x39, 0x76, 0x42, 0xdf, 0x7d, 0xe1, 0x51, 0xc7, 0x42, 0x14, 0xfa, + 0xf8, 0xf6, 0xe0, 0xe8, 0xf0, 0xf6, 0x60, 0xff, 0x76, 0xec, 0x26, 0xed, 0x4f, 0xd1, 0x6f, 0xbf, + 0xdd, 0xfd, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x1e, 0x8f, 0x93, 0x7c, 0x66, 0x00, 0x00, } func (m *CNStore) Marshal() (dAtA []byte, err error) { @@ -6891,6 +6900,18 @@ func (m *CNStore) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.ViewMetadataIngressReady { + i-- + if m.ViewMetadataIngressReady { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xb0 + } if m.DDLVisibilityBarrierReady { i-- if m.DDLVisibilityBarrierReady { @@ -12398,6 +12419,9 @@ func (m *CNStore) ProtoSize() (n int) { if m.DDLVisibilityBarrierReady { n += 3 } + if m.ViewMetadataIngressReady { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -15275,6 +15299,26 @@ func (m *CNStore) Unmarshal(dAtA []byte) error { } } m.DDLVisibilityBarrierReady = bool(v != 0) + case 22: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ViewMetadataIngressReady", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ViewMetadataIngressReady = bool(v != 0) default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) diff --git a/pkg/pb/logservice/logservice_test.go b/pkg/pb/logservice/logservice_test.go index 30d3f5b21467d..e522248c46bdc 100644 --- a/pkg/pb/logservice/logservice_test.go +++ b/pkg/pb/logservice/logservice_test.go @@ -40,6 +40,7 @@ func TestCNStateUpdate(t *testing.T) { Role: metadata.CNRole_AP, CommandDeliveryAckSupported: true, DDLVisibilityBarrierReady: true, + ViewMetadataIngressReady: true, } tick1 := uint64(100) @@ -53,6 +54,7 @@ func TestCNStateUpdate(t *testing.T) { UpTime: state.Stores[hb1.UUID].UpTime, CommandDeliveryAckSupported: true, DDLVisibilityBarrierReady: true, + ViewMetadataIngressReady: true, }) hb2 := CNStoreHeartbeat{UUID: "cn-b", ServiceAddress: "addr-b", Role: metadata.CNRole_TP} diff --git a/pkg/pb/metadata/metadata.pb.go b/pkg/pb/metadata/metadata.pb.go index 531a212422dac..cdf02d943d4d1 100644 --- a/pkg/pb/metadata/metadata.pb.go +++ b/pkg/pb/metadata/metadata.pb.go @@ -568,10 +568,13 @@ type CNService struct { ViewMetadataObservedEpoch uint64 `protobuf:"varint,15,opt,name=ViewMetadataObservedEpoch,proto3" json:"ViewMetadataObservedEpoch,omitempty"` // DDLVisibilityBarrierReady is published after QueryService is listening. // A CN is not publicly routable until its startup DDL frontier fence completes. - DDLVisibilityBarrierReady bool `protobuf:"varint,16,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + DDLVisibilityBarrierReady bool `protobuf:"varint,16,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` + // ViewMetadataIngressReady is retained in raw control-plane inventory so + // protocol activation can verify withdrawal/publication without routing it. + ViewMetadataIngressReady bool `protobuf:"varint,17,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNService) Reset() { *m = CNService{} } @@ -712,6 +715,13 @@ func (m *CNService) GetDDLVisibilityBarrierReady() bool { return false } +func (m *CNService) GetViewMetadataIngressReady() bool { + if m != nil { + return m.ViewMetadataIngressReady + } + return false +} + // TNService tn service metadata type TNService struct { // ServiceID service ID @@ -902,65 +912,66 @@ func init() { func init() { proto.RegisterFile("metadata.proto", fileDescriptor_56d9f74966f40d04) } var fileDescriptor_56d9f74966f40d04 = []byte{ - // 928 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xc1, 0x6e, 0xdb, 0x46, - 0x10, 0x35, 0x25, 0x99, 0x22, 0x47, 0x8e, 0xca, 0x6c, 0xd0, 0x94, 0x75, 0x03, 0xd9, 0x60, 0x7b, - 0x70, 0x8d, 0x56, 0x4a, 0xdc, 0xa2, 0x28, 0x8a, 0xb6, 0x88, 0x2c, 0x25, 0x8e, 0x03, 0x85, 0x52, - 0x28, 0xca, 0x6d, 0x7a, 0x29, 0x28, 0x71, 0x43, 0x2f, 0x24, 0x71, 0x89, 0xe5, 0xca, 0x89, 0x7e, - 0xa1, 0xc7, 0x5e, 0x7b, 0xe9, 0xb5, 0x7f, 0x92, 0xa3, 0xbf, 0x20, 0x68, 0xdd, 0x1f, 0x09, 0xb8, - 0x24, 0x25, 0x9a, 0x96, 0x1c, 0x5f, 0x72, 0xe2, 0xce, 0xbc, 0x37, 0xb3, 0xf3, 0x66, 0x77, 0x16, - 0x84, 0xea, 0x14, 0x73, 0xc7, 0x75, 0xb8, 0x53, 0x0f, 0x18, 0xe5, 0x14, 0x29, 0xa9, 0xbd, 0xfd, - 0xb5, 0x47, 0xf8, 0xe9, 0x6c, 0x58, 0x1f, 0xd1, 0x69, 0xc3, 0xa3, 0x1e, 0x6d, 0x08, 0xc2, 0x70, - 0xf6, 0x52, 0x58, 0xc2, 0x10, 0xab, 0x38, 0xd0, 0x38, 0x86, 0x5b, 0xb6, 0xd9, 0x3f, 0x75, 0x98, - 0x6b, 0xe1, 0x11, 0x65, 0x2e, 0xd2, 0xa1, 0x2c, 0xcc, 0xe3, 0xb6, 0x2e, 0xed, 0x4a, 0x7b, 0x25, - 0x2b, 0x35, 0x51, 0x0d, 0xa0, 0x43, 0xbd, 0x14, 0x2c, 0x08, 0x30, 0xe3, 0x31, 0xfe, 0x90, 0xa0, - 0x9c, 0xe4, 0x42, 0x47, 0xb9, 0xb4, 0x22, 0x57, 0xe5, 0xe0, 0x93, 0xfa, 0xa2, 0xee, 0x4b, 0xf0, - 0xa1, 0xf2, 0xe6, 0xed, 0xce, 0xc6, 0xf9, 0xdb, 0x1d, 0xc9, 0xca, 0x95, 0x73, 0x0f, 0x54, 0x0b, - 0x07, 0x13, 0x32, 0x72, 0x16, 0x7b, 0x2e, 0x1d, 0x51, 0xb1, 0x4d, 0xd7, 0x65, 0x38, 0x0c, 0xf5, - 0xe2, 0xae, 0xb4, 0xa7, 0x5a, 0xa9, 0x69, 0x9c, 0x40, 0x35, 0x2d, 0xed, 0xbd, 0xc2, 0xf6, 0x41, - 0x33, 0x67, 0xd3, 0x21, 0x66, 0xdd, 0x97, 0x49, 0xea, 0x30, 0xd9, 0xea, 0x8a, 0xdf, 0xf8, 0x53, - 0x02, 0x25, 0x4d, 0x8c, 0x9e, 0xe6, 0x37, 0x49, 0x64, 0xea, 0x4b, 0x99, 0x97, 0xf1, 0x8c, 0xce, - 0x7c, 0x79, 0xd7, 0x0b, 0xbd, 0x07, 0xaa, 0x49, 0xfd, 0x13, 0xca, 0x89, 0xef, 0x09, 0xa9, 0x8a, - 0xb5, 0x74, 0x18, 0xa6, 0x68, 0x3c, 0xa7, 0x0c, 0x23, 0x04, 0xa5, 0xc1, 0x20, 0x91, 0xa8, 0x5a, - 0x62, 0x8d, 0x1a, 0x20, 0x8b, 0x9d, 0x22, 0x55, 0xc5, 0xbd, 0xca, 0xc1, 0xed, 0x2b, 0xa7, 0x70, - 0x58, 0x8a, 0xea, 0xb2, 0x12, 0x9a, 0xd1, 0x8b, 0x35, 0xae, 0x4d, 0x78, 0x3f, 0x97, 0x10, 0x5d, - 0xd5, 0x9b, 0xcb, 0xd8, 0x82, 0x72, 0xeb, 0x9a, 0x0a, 0xbf, 0x80, 0x92, 0x45, 0x27, 0x58, 0xe8, - 0xae, 0x1e, 0x68, 0xcb, 0x74, 0x2d, 0x33, 0xf2, 0x5b, 0x02, 0x35, 0xfe, 0x91, 0x41, 0x6d, 0x99, - 0x7d, 0xcc, 0xce, 0xc8, 0x08, 0x47, 0x2d, 0x49, 0x96, 0x8b, 0x64, 0x4b, 0x07, 0xaa, 0x03, 0xea, - 0xd0, 0xd1, 0x38, 0x71, 0xa4, 0x97, 0xa4, 0x20, 0x68, 0x2b, 0x10, 0xf4, 0x1d, 0xdc, 0xed, 0x91, - 0x00, 0x4f, 0x88, 0x8f, 0x73, 0x31, 0xf1, 0xc5, 0x5a, 0x83, 0x46, 0x43, 0xd1, 0x7f, 0xde, 0x49, - 0xb9, 0x25, 0xc1, 0xcd, 0x78, 0xd0, 0x4f, 0x20, 0x77, 0x9c, 0x21, 0x9e, 0x84, 0xba, 0x2c, 0x5a, - 0xb5, 0x93, 0xd5, 0x96, 0xe4, 0xaa, 0xc7, 0x8c, 0x47, 0x3e, 0x67, 0xf3, 0xb4, 0x6f, 0xb1, 0x0b, - 0x3d, 0x00, 0xf5, 0x17, 0xca, 0xc6, 0x7d, 0xee, 0x70, 0xac, 0x97, 0x45, 0x77, 0xee, 0x2c, 0x33, - 0x2c, 0x20, 0x6b, 0xc9, 0x42, 0x06, 0x6c, 0x3d, 0x9f, 0x61, 0x36, 0x4f, 0x6b, 0x52, 0x44, 0x4d, - 0x97, 0x7c, 0xe8, 0x3e, 0xdc, 0x11, 0x07, 0x93, 0x93, 0xaa, 0x0a, 0xea, 0x2a, 0x08, 0x6d, 0x83, - 0xd2, 0xa2, 0xd3, 0x29, 0xe1, 0xc7, 0x6d, 0x1d, 0x04, 0x6d, 0x61, 0x0b, 0xac, 0x37, 0xb0, 0x29, - 0x77, 0x26, 0x7a, 0x45, 0xdc, 0xdc, 0x85, 0x1d, 0x61, 0xcf, 0xf0, 0x34, 0xc6, 0xb6, 0x62, 0x2c, - 0xb5, 0xd1, 0x13, 0xd8, 0x39, 0x21, 0xf8, 0xd5, 0xb3, 0x44, 0x4e, 0xd3, 0x9d, 0x92, 0x30, 0x24, - 0xd4, 0x3f, 0xc2, 0x3e, 0x66, 0x0e, 0x27, 0xd4, 0xd7, 0x6f, 0x89, 0x90, 0xf7, 0xd1, 0xd0, 0xcf, - 0xb0, 0xbd, 0x92, 0x62, 0x61, 0xc7, 0x9d, 0xeb, 0x55, 0x31, 0x2f, 0xd7, 0x30, 0xd0, 0x8f, 0xf0, - 0x69, 0x16, 0xed, 0x0e, 0x43, 0xcc, 0xce, 0xb0, 0xfb, 0x28, 0xa0, 0xa3, 0x53, 0xfd, 0x23, 0x51, - 0xc3, 0x7a, 0x42, 0x14, 0xdd, 0x6e, 0x77, 0x4e, 0x48, 0x48, 0x86, 0x64, 0x42, 0xf8, 0xfc, 0xd0, - 0x61, 0x8c, 0x60, 0x16, 0x6f, 0xae, 0x89, 0xcd, 0xd7, 0x13, 0xb6, 0x4d, 0xa8, 0x64, 0xce, 0x1f, - 0x69, 0x50, 0x1c, 0xe3, 0x79, 0x72, 0xa1, 0xa3, 0x25, 0xfa, 0x12, 0x36, 0xcf, 0x9c, 0xc9, 0x2c, - 0x9e, 0x8e, 0x4a, 0xf6, 0xfc, 0x45, 0x5c, 0x87, 0x84, 0xdc, 0x8a, 0x19, 0x3f, 0x14, 0xbe, 0x97, - 0x9e, 0x96, 0x94, 0x4d, 0x4d, 0x36, 0xfe, 0x2a, 0x81, 0x6a, 0xdf, 0x70, 0x56, 0xbe, 0x82, 0xdb, - 0xf6, 0x6b, 0x7f, 0xe5, 0xa8, 0x5c, 0x05, 0xd0, 0xb7, 0xf0, 0x71, 0x87, 0x7a, 0xb6, 0x43, 0x26, - 0x2b, 0x07, 0x65, 0x35, 0xb8, 0x66, 0x1e, 0x4b, 0x6b, 0xe7, 0x71, 0xf9, 0x66, 0xc9, 0x37, 0x7a, - 0xb3, 0x32, 0x83, 0x56, 0xce, 0x0f, 0x9a, 0x7d, 0x83, 0x41, 0xfb, 0x30, 0x53, 0xf3, 0x10, 0x3e, - 0x6b, 0xce, 0x38, 0x3d, 0xf6, 0x47, 0x4c, 0x5c, 0x95, 0xc7, 0xd8, 0x1f, 0xe1, 0xfe, 0x2c, 0x08, - 0x28, 0xe3, 0xd8, 0x15, 0x83, 0xa4, 0x58, 0xd7, 0x51, 0x3e, 0xd0, 0xed, 0xf8, 0x1c, 0xd4, 0x05, - 0x8a, 0xee, 0x2e, 0x3a, 0x27, 0xed, 0x16, 0xf7, 0xd4, 0xb4, 0x25, 0xfb, 0x4d, 0xa8, 0x24, 0x72, - 0xec, 0x79, 0x80, 0x91, 0x0c, 0x85, 0x96, 0xa9, 0x6d, 0x44, 0x5f, 0xdb, 0xd4, 0x24, 0x54, 0x86, - 0x62, 0xa7, 0x7b, 0xa4, 0x15, 0x90, 0x0a, 0x9b, 0x3d, 0xab, 0xfb, 0xeb, 0x0b, 0xad, 0x88, 0xaa, - 0x00, 0xbd, 0x17, 0xf6, 0x93, 0xae, 0xf9, 0xfb, 0xa0, 0xfd, 0x58, 0x2b, 0xed, 0xeb, 0x20, 0xc7, - 0x2f, 0xb8, 0x88, 0xea, 0xc5, 0xd1, 0xcd, 0x9e, 0x26, 0xed, 0x3f, 0xcc, 0x3c, 0x6c, 0xa8, 0x02, - 0xe5, 0x81, 0x3f, 0xf6, 0xe9, 0x2b, 0x5f, 0xdb, 0x88, 0x8c, 0x08, 0x21, 0xbe, 0xa7, 0x49, 0x68, - 0x0b, 0x94, 0x36, 0x73, 0x88, 0x1f, 0x59, 0x85, 0x08, 0x12, 0x16, 0x76, 0xb5, 0xe2, 0xe1, 0xd1, - 0xf9, 0x7f, 0x35, 0xe9, 0xcd, 0x45, 0x4d, 0x3a, 0xbf, 0xa8, 0x49, 0xff, 0x5e, 0xd4, 0x36, 0xfe, - 0xfe, 0xbf, 0x26, 0xfd, 0xf6, 0x20, 0xf3, 0xfb, 0x33, 0x75, 0x38, 0x23, 0xaf, 0x29, 0x23, 0x1e, - 0xf1, 0x53, 0xc3, 0xc7, 0x8d, 0x60, 0xec, 0x35, 0x82, 0x61, 0x23, 0xed, 0xd3, 0x50, 0x16, 0x7f, - 0x42, 0xdf, 0xbc, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x83, 0x15, 0xa1, 0x75, 0x54, 0x09, 0x00, 0x00, + // 943 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x51, 0x73, 0xda, 0x46, + 0x10, 0xb6, 0x00, 0x83, 0xb4, 0x38, 0x54, 0xbe, 0x4c, 0x53, 0xd5, 0xcd, 0x60, 0x8f, 0xda, 0x07, + 0xd7, 0xd3, 0x42, 0xe2, 0x76, 0x3a, 0x9d, 0x4c, 0xdb, 0x09, 0x86, 0xc4, 0x21, 0x43, 0x04, 0x11, + 0xc2, 0x6d, 0xfa, 0xd2, 0x11, 0xe8, 0x22, 0xdf, 0x00, 0x77, 0x9a, 0x93, 0x70, 0xc2, 0x5f, 0xe8, + 0x63, 0x5f, 0xfb, 0xd2, 0x9f, 0x93, 0x47, 0xff, 0x82, 0x4c, 0xeb, 0x4e, 0xff, 0x47, 0x47, 0x27, + 0x09, 0x64, 0x19, 0x1c, 0xbf, 0xf8, 0x89, 0xdb, 0xfd, 0xbe, 0xdd, 0xdb, 0x6f, 0xd9, 0xbd, 0x11, + 0x54, 0xa6, 0x38, 0xb0, 0x1d, 0x3b, 0xb0, 0x6b, 0x1e, 0x67, 0x01, 0x43, 0x72, 0x62, 0xef, 0x7c, + 0xed, 0x92, 0xe0, 0x74, 0x36, 0xac, 0x8d, 0xd8, 0xb4, 0xee, 0x32, 0x97, 0xd5, 0x05, 0x61, 0x38, + 0x7b, 0x2d, 0x2c, 0x61, 0x88, 0x53, 0x14, 0xa8, 0xb7, 0xe1, 0x8e, 0x65, 0xf4, 0x4f, 0x6d, 0xee, + 0x98, 0x78, 0xc4, 0xb8, 0x83, 0x34, 0x28, 0x09, 0xb3, 0xdd, 0xd2, 0xa4, 0x3d, 0x69, 0xbf, 0x60, + 0x26, 0x26, 0xaa, 0x02, 0x74, 0x98, 0x9b, 0x80, 0x39, 0x01, 0xa6, 0x3c, 0xfa, 0xef, 0x12, 0x94, + 0xe2, 0x5c, 0xe8, 0x38, 0x93, 0x56, 0xe4, 0x2a, 0x1f, 0x7e, 0x52, 0x5b, 0xd4, 0x7d, 0x09, 0x3e, + 0x92, 0xdf, 0xbd, 0xdf, 0xdd, 0x38, 0x7f, 0xbf, 0x2b, 0x99, 0x99, 0x72, 0xee, 0x83, 0x62, 0x62, + 0x6f, 0x42, 0x46, 0xf6, 0xe2, 0xce, 0xa5, 0x23, 0x2c, 0xb6, 0xe1, 0x38, 0x1c, 0xfb, 0xbe, 0x96, + 0xdf, 0x93, 0xf6, 0x15, 0x33, 0x31, 0xf5, 0x13, 0xa8, 0x24, 0xa5, 0x7d, 0x50, 0xd8, 0x01, 0xa8, + 0xc6, 0x6c, 0x3a, 0xc4, 0xbc, 0xfb, 0x3a, 0x4e, 0xed, 0xc7, 0x57, 0x5d, 0xf1, 0xeb, 0x7f, 0x48, + 0x20, 0x27, 0x89, 0xd1, 0xf3, 0xec, 0x25, 0xb1, 0x4c, 0x6d, 0x29, 0xf3, 0x32, 0x9e, 0xd2, 0x99, + 0x2d, 0xef, 0x7a, 0xa1, 0xf7, 0x41, 0x31, 0x18, 0x3d, 0x61, 0x01, 0xa1, 0xae, 0x90, 0x2a, 0x9b, + 0x4b, 0x87, 0x6e, 0x88, 0xc6, 0x07, 0x8c, 0x63, 0x84, 0xa0, 0x30, 0x18, 0xc4, 0x12, 0x15, 0x53, + 0x9c, 0x51, 0x1d, 0x8a, 0xe2, 0xa6, 0x50, 0x55, 0x7e, 0xbf, 0x7c, 0xb8, 0x7d, 0xe5, 0x5f, 0x38, + 0x2a, 0x84, 0x75, 0x99, 0x31, 0x4d, 0xef, 0x45, 0x1a, 0xd7, 0x26, 0x7c, 0x90, 0x49, 0x88, 0xae, + 0xea, 0xcd, 0x64, 0x6c, 0x42, 0xa9, 0x79, 0x4d, 0x85, 0x5f, 0x40, 0xc1, 0x64, 0x13, 0x2c, 0x74, + 0x57, 0x0e, 0xd5, 0x65, 0xba, 0xa6, 0x11, 0xfa, 0x4d, 0x81, 0xea, 0xff, 0x15, 0x41, 0x69, 0x1a, + 0x7d, 0xcc, 0xcf, 0xc8, 0x08, 0x87, 0x2d, 0x89, 0x8f, 0x8b, 0x64, 0x4b, 0x07, 0xaa, 0x01, 0xea, + 0xb0, 0xd1, 0x38, 0x76, 0x24, 0x43, 0x92, 0x13, 0xb4, 0x15, 0x08, 0xfa, 0x0e, 0xee, 0xf5, 0x88, + 0x87, 0x27, 0x84, 0xe2, 0x4c, 0x4c, 0x34, 0x58, 0x6b, 0xd0, 0x70, 0x29, 0xfa, 0x2f, 0x3b, 0x09, + 0xb7, 0x20, 0xb8, 0x29, 0x0f, 0xfa, 0x11, 0x8a, 0x1d, 0x7b, 0x88, 0x27, 0xbe, 0x56, 0x14, 0xad, + 0xda, 0x4d, 0x6b, 0x8b, 0x73, 0xd5, 0x22, 0xc6, 0x13, 0x1a, 0xf0, 0x79, 0xd2, 0xb7, 0xc8, 0x85, + 0x1e, 0x82, 0xf2, 0x33, 0xe3, 0xe3, 0x7e, 0x60, 0x07, 0x58, 0x2b, 0x89, 0xee, 0xdc, 0x5d, 0x66, + 0x58, 0x40, 0xe6, 0x92, 0x85, 0x74, 0xd8, 0x7a, 0x39, 0xc3, 0x7c, 0x9e, 0xd4, 0x24, 0x8b, 0x9a, + 0x2e, 0xf9, 0xd0, 0x03, 0xb8, 0x2b, 0xfe, 0x98, 0x8c, 0x54, 0x45, 0x50, 0x57, 0x41, 0x68, 0x07, + 0xe4, 0x26, 0x9b, 0x4e, 0x49, 0xd0, 0x6e, 0x69, 0x20, 0x68, 0x0b, 0x5b, 0x60, 0xbd, 0x81, 0xc5, + 0x02, 0x7b, 0xa2, 0x95, 0xc5, 0xe4, 0x2e, 0xec, 0x10, 0x7b, 0x81, 0xa7, 0x11, 0xb6, 0x15, 0x61, + 0x89, 0x8d, 0x9e, 0xc1, 0xee, 0x09, 0xc1, 0x6f, 0x5e, 0xc4, 0x72, 0x1a, 0xce, 0x94, 0xf8, 0x3e, + 0x61, 0xf4, 0x18, 0x53, 0xcc, 0xed, 0x80, 0x30, 0xaa, 0xdd, 0x11, 0x21, 0x1f, 0xa2, 0xa1, 0x9f, + 0x60, 0x67, 0x25, 0xc5, 0xc4, 0xb6, 0x33, 0xd7, 0x2a, 0x62, 0x5f, 0xae, 0x61, 0xa0, 0x1f, 0xe0, + 0xd3, 0x34, 0xda, 0x1d, 0xfa, 0x98, 0x9f, 0x61, 0xe7, 0x89, 0xc7, 0x46, 0xa7, 0xda, 0x47, 0xa2, + 0x86, 0xf5, 0x84, 0x30, 0xba, 0xd5, 0xea, 0x9c, 0x10, 0x9f, 0x0c, 0xc9, 0x84, 0x04, 0xf3, 0x23, + 0x9b, 0x73, 0x82, 0x79, 0x74, 0xb9, 0x2a, 0x2e, 0x5f, 0x4f, 0x40, 0x8f, 0x40, 0x4b, 0xa7, 0x6e, + 0x53, 0x37, 0x6c, 0x78, 0x14, 0xbc, 0x2d, 0x82, 0xd7, 0xe2, 0x3b, 0x06, 0x94, 0x53, 0xb3, 0x83, + 0x54, 0xc8, 0x8f, 0xf1, 0x3c, 0x5e, 0x86, 0xf0, 0x88, 0xbe, 0x84, 0xcd, 0x33, 0x7b, 0x32, 0x8b, + 0x36, 0xab, 0x9c, 0x9e, 0x1d, 0x11, 0xd7, 0x21, 0x7e, 0x60, 0x46, 0x8c, 0x47, 0xb9, 0xef, 0xa5, + 0xe7, 0x05, 0x79, 0x53, 0x2d, 0xea, 0x7f, 0x16, 0x40, 0xb1, 0x6e, 0xb8, 0x67, 0x5f, 0xc1, 0xb6, + 0xf5, 0x96, 0xae, 0x5c, 0xb3, 0xab, 0x00, 0xfa, 0x16, 0x3e, 0xee, 0x30, 0xd7, 0xb2, 0xc9, 0x64, + 0xe5, 0x92, 0xad, 0x06, 0xd7, 0xec, 0x72, 0x61, 0xed, 0x2e, 0x2f, 0xdf, 0xbb, 0xe2, 0x8d, 0xde, + 0xbb, 0xd4, 0x92, 0x96, 0xb2, 0x4b, 0x6a, 0xdd, 0x60, 0x49, 0x6f, 0x67, 0xe3, 0x1e, 0xc3, 0x67, + 0x8d, 0x59, 0xc0, 0xda, 0x74, 0xc4, 0xc5, 0x98, 0x3d, 0xc5, 0x74, 0x84, 0xfb, 0x33, 0xcf, 0x63, + 0x3c, 0xc0, 0x8e, 0x58, 0x42, 0xd9, 0xbc, 0x8e, 0x72, 0x4b, 0xd3, 0xf1, 0x39, 0x28, 0x0b, 0x14, + 0xdd, 0x5b, 0x74, 0x4e, 0xda, 0xcb, 0xef, 0x2b, 0x49, 0x4b, 0x0e, 0x1a, 0x50, 0x8e, 0xe5, 0x58, + 0x73, 0x0f, 0xa3, 0x22, 0xe4, 0x9a, 0x86, 0xba, 0x11, 0xfe, 0x5a, 0x86, 0x2a, 0xa1, 0x12, 0xe4, + 0x3b, 0xdd, 0x63, 0x35, 0x87, 0x14, 0xd8, 0xec, 0x99, 0xdd, 0x5f, 0x5e, 0xa9, 0x79, 0x54, 0x01, + 0xe8, 0xbd, 0xb2, 0x9e, 0x75, 0x8d, 0xdf, 0x06, 0xad, 0xa7, 0x6a, 0xe1, 0x40, 0x83, 0x62, 0xf4, + 0xfa, 0x8b, 0xa8, 0x5e, 0x14, 0xdd, 0xe8, 0xa9, 0xd2, 0xc1, 0xe3, 0xd4, 0xa3, 0x88, 0xca, 0x50, + 0x1a, 0xd0, 0x31, 0x65, 0x6f, 0xa8, 0xba, 0x11, 0x1a, 0x21, 0x42, 0xa8, 0xab, 0x4a, 0x68, 0x0b, + 0xe4, 0x16, 0xb7, 0x09, 0x0d, 0xad, 0x5c, 0x08, 0x09, 0x0b, 0x3b, 0x6a, 0xfe, 0xe8, 0xf8, 0xfc, + 0x9f, 0xaa, 0xf4, 0xee, 0xa2, 0x2a, 0x9d, 0x5f, 0x54, 0xa5, 0xbf, 0x2f, 0xaa, 0x1b, 0x7f, 0xfd, + 0x5b, 0x95, 0x7e, 0x7d, 0x98, 0xfa, 0x74, 0x9a, 0xda, 0x01, 0x27, 0x6f, 0x19, 0x27, 0x2e, 0xa1, + 0x89, 0x41, 0x71, 0xdd, 0x1b, 0xbb, 0x75, 0x6f, 0x58, 0x4f, 0xfa, 0x34, 0x2c, 0x8a, 0xaf, 0xa8, + 0x6f, 0xfe, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x4d, 0xdd, 0x02, 0xc6, 0x90, 0x09, 0x00, 0x00, } func (m *TNShardRecord) Marshal() (dAtA []byte, err error) { @@ -1297,6 +1308,18 @@ func (m *CNService) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.ViewMetadataIngressReady { + i-- + if m.ViewMetadataIngressReady { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x88 + } if m.DDLVisibilityBarrierReady { i-- if m.DDLVisibilityBarrierReady { @@ -1788,6 +1811,9 @@ func (m *CNService) ProtoSize() (n int) { if m.DDLVisibilityBarrierReady { n += 3 } + if m.ViewMetadataIngressReady { + n += 3 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -3161,6 +3187,26 @@ func (m *CNService) Unmarshal(dAtA []byte) error { } } m.DDLVisibilityBarrierReady = bool(v != 0) + case 17: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ViewMetadataIngressReady", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetadata + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ViewMetadataIngressReady = bool(v != 0) default: iNdEx = preIndex skippy, err := skipMetadata(dAtA[iNdEx:]) diff --git a/pkg/pb/query/query.pb.go b/pkg/pb/query/query.pb.go index 64669a7df6fa5..e9776ec16b07b 100644 --- a/pkg/pb/query/query.pb.go +++ b/pkg/pb/query/query.pb.go @@ -663,6 +663,12 @@ var xxx_messageInfo_GetProtocolVersionRequest proto.InternalMessageInfo type GetProtocolVersionResponse struct { // ProtocolVersion is the version of the protocol Version int64 `protobuf:"varint,1,opt,name=Version,proto3" json:"Version,omitempty"` + // DDLVisibilityActivationPrepared means this CN has blocked and drained DDL + // producers before exposing the v35 sender capability. + DDLVisibilityActivationPrepared bool `protobuf:"varint,2,opt,name=DDLVisibilityActivationPrepared,proto3" json:"DDLVisibilityActivationPrepared,omitempty"` + // DDLVisibilityActivationFenced means this CN applied the converged peer + // frontier while every participant's DDL producers were blocked. + DDLVisibilityActivationFenced bool `protobuf:"varint,3,opt,name=DDLVisibilityActivationFenced,proto3" json:"DDLVisibilityActivationFenced,omitempty"` } func (m *GetProtocolVersionResponse) Reset() { *m = GetProtocolVersionResponse{} } @@ -705,9 +711,26 @@ func (m *GetProtocolVersionResponse) GetVersion() int64 { return 0 } +func (m *GetProtocolVersionResponse) GetDDLVisibilityActivationPrepared() bool { + if m != nil { + return m.DDLVisibilityActivationPrepared + } + return false +} + +func (m *GetProtocolVersionResponse) GetDDLVisibilityActivationFenced() bool { + if m != nil { + return m.DDLVisibilityActivationFenced + } + return false +} + type SetProtocolVersionRequest struct { // ProtocolVersion is the version of the protocol Version int64 `protobuf:"varint,1,opt,name=Version,proto3" json:"Version,omitempty"` + // DDLVisibilityActivationTargets is the complete CN set participating in a + // coordinated live activation. It is empty for ordinary version updates. + DDLVisibilityActivationTargets []string `protobuf:"bytes,2,rep,name=DDLVisibilityActivationTargets,proto3" json:"DDLVisibilityActivationTargets,omitempty"` } func (m *SetProtocolVersionRequest) Reset() { *m = SetProtocolVersionRequest{} } @@ -750,6 +773,13 @@ func (m *SetProtocolVersionRequest) GetVersion() int64 { return 0 } +func (m *SetProtocolVersionRequest) GetDDLVisibilityActivationTargets() []string { + if m != nil { + return m.DDLVisibilityActivationTargets + } + return nil +} + type SetProtocolVersionResponse struct { // ProtocolVersion is the version of the protocol Version int64 `protobuf:"varint,1,opt,name=Version,proto3" json:"Version,omitempty"` @@ -5872,280 +5902,284 @@ func init() { func init() { proto.RegisterFile("query.proto", fileDescriptor_5c6ac9b241082464) } var fileDescriptor_5c6ac9b241082464 = []byte{ - // 4356 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5b, 0xcd, 0x73, 0xdb, 0x38, - 0x96, 0x8f, 0xe2, 0x2f, 0xe9, 0x59, 0xb6, 0x69, 0xc4, 0x1f, 0xb4, 0xe3, 0xc8, 0x0e, 0x3b, 0x9d, - 0x38, 0xc9, 0xb4, 0xdd, 0x9b, 0xe9, 0x64, 0xbe, 0x7a, 0xb7, 0x3a, 0x96, 0xe2, 0x44, 0x89, 0x1c, - 0x3b, 0x90, 0xf3, 0x31, 0x3d, 0x55, 0x5d, 0x45, 0x4b, 0xb0, 0xcc, 0xb1, 0x44, 0xaa, 0x49, 0x2a, - 0x6d, 0x77, 0xd5, 0x1e, 0xf7, 0xb2, 0x87, 0xad, 0xf9, 0x13, 0x66, 0x4f, 0xfb, 0x1f, 0x4c, 0xd5, - 0x1e, 0xe7, 0x36, 0xc7, 0x39, 0xec, 0x61, 0x4e, 0xbb, 0x5b, 0xdd, 0x7f, 0xc8, 0x6e, 0x01, 0x04, - 0x48, 0x02, 0x04, 0xa9, 0xfe, 0x9a, 0x8b, 0x8a, 0x78, 0x78, 0xef, 0x07, 0x10, 0x04, 0x1e, 0xde, - 0xef, 0x01, 0x82, 0xd9, 0x2f, 0x47, 0xc4, 0xbf, 0xdc, 0x19, 0xfa, 0x5e, 0xe8, 0xa1, 0x29, 0x56, - 0x58, 0xaf, 0x06, 0xa1, 0x1d, 0x8e, 0x82, 0x48, 0xb8, 0x0e, 0x7d, 0xaf, 0x73, 0xce, 0x9f, 0x2b, - 0xe1, 0x85, 0xcb, 0x1f, 0x17, 0x42, 0x67, 0x40, 0x82, 0xd0, 0x1e, 0x0c, 0x85, 0x80, 0x5a, 0x05, - 0x8e, 0x7b, 0xea, 0x09, 0xc3, 0x61, 0xdf, 0x16, 0xda, 0x1f, 0xf5, 0x9c, 0xf0, 0x6c, 0x74, 0xb2, - 0xd3, 0xf1, 0x06, 0xbb, 0x3d, 0xaf, 0xe7, 0xed, 0x32, 0xf1, 0xc9, 0xe8, 0x94, 0x95, 0x58, 0x81, - 0x3d, 0x71, 0xf5, 0xcd, 0x9e, 0xe7, 0xf5, 0xfa, 0x24, 0xd1, 0x52, 0x1a, 0xb3, 0x6e, 0x41, 0xf5, - 0x15, 0xed, 0x2b, 0x26, 0x5f, 0x8e, 0x48, 0x10, 0xa2, 0x25, 0x98, 0x62, 0x65, 0xb3, 0xb4, 0x55, - 0xda, 0xae, 0xe0, 0xa8, 0x60, 0xbd, 0x84, 0x95, 0xf6, 0x99, 0xf7, 0xd5, 0x91, 0xef, 0x75, 0x48, - 0x10, 0xb4, 0x9c, 0x20, 0x14, 0xfa, 0x2b, 0x30, 0x7d, 0x4c, 0x5c, 0xdb, 0x0d, 0xb9, 0x01, 0x2f, - 0xa1, 0x0d, 0xa8, 0xb4, 0x2f, 0x03, 0x5e, 0x75, 0x75, 0xab, 0xb4, 0x5d, 0xc6, 0x89, 0xc0, 0x7a, - 0x0b, 0x8b, 0xed, 0x4b, 0xb7, 0x53, 0xf7, 0x06, 0x03, 0x27, 0x86, 0xda, 0x83, 0xf9, 0x96, 0x1d, - 0x92, 0x20, 0x8c, 0xc4, 0xc7, 0x6d, 0x06, 0x39, 0xfb, 0x60, 0x69, 0x27, 0xe9, 0xf4, 0xb1, 0x78, - 0xda, 0x9b, 0xfc, 0xcb, 0x7f, 0x6f, 0x5e, 0xc1, 0x8a, 0x85, 0xf5, 0x39, 0xa0, 0x34, 0x70, 0x30, - 0xf4, 0xdc, 0x80, 0xa0, 0x06, 0x2c, 0xd4, 0x47, 0xbe, 0x4f, 0xdc, 0xef, 0x03, 0xad, 0x9a, 0x58, - 0x08, 0x8c, 0xa7, 0x24, 0x94, 0xfa, 0x6c, 0xfd, 0x16, 0x16, 0x53, 0xb2, 0x9f, 0xb4, 0xb9, 0x5d, - 0x58, 0xae, 0x7b, 0x3e, 0x69, 0x8c, 0x06, 0xc3, 0xba, 0xe7, 0x9e, 0x3a, 0xbd, 0xd4, 0x90, 0x3f, - 0xee, 0x84, 0x8e, 0xe7, 0x8a, 0x21, 0x8f, 0x4a, 0x96, 0x09, 0x2b, 0xaa, 0x41, 0xd4, 0x21, 0xeb, - 0x3a, 0xac, 0x3d, 0x25, 0xe1, 0x11, 0xfd, 0xe0, 0x1d, 0xaf, 0xff, 0x86, 0xf8, 0x81, 0xe3, 0xb9, - 0xe2, 0x15, 0x1e, 0xc1, 0xba, 0xae, 0x92, 0xbf, 0x8b, 0x09, 0x33, 0x5c, 0xc4, 0x5a, 0x9b, 0xc0, - 0xa2, 0x68, 0x3d, 0x84, 0xb5, 0x76, 0x1e, 0x68, 0x81, 0xd9, 0x23, 0x58, 0x6f, 0xff, 0x90, 0xe6, - 0x7e, 0x06, 0xf3, 0x78, 0xe4, 0x1e, 0xdb, 0xc1, 0xb9, 0x68, 0x63, 0x1d, 0xca, 0xb4, 0x58, 0xf7, - 0xba, 0x84, 0x29, 0x4f, 0xe1, 0xb8, 0x6c, 0xdd, 0x85, 0x85, 0x58, 0x9b, 0x43, 0xaf, 0xc0, 0x34, - 0x26, 0xc1, 0xa8, 0x1f, 0xcf, 0xd4, 0xa8, 0x44, 0x87, 0x8d, 0xbe, 0xbf, 0x33, 0x24, 0x7d, 0xc7, - 0x25, 0x4d, 0xf7, 0xd4, 0x13, 0x23, 0xb3, 0x0b, 0xab, 0x99, 0x1a, 0x0e, 0xb6, 0x04, 0x53, 0x75, - 0x6f, 0xc4, 0x67, 0xfd, 0x04, 0x8e, 0x0a, 0xd6, 0x9f, 0xd6, 0x60, 0x46, 0xf4, 0x6e, 0x03, 0x2a, - 0xfc, 0xb1, 0xd9, 0x60, 0x5a, 0x93, 0x38, 0x11, 0xa0, 0x1d, 0xa8, 0xd4, 0x07, 0xdd, 0x03, 0x12, - 0x9e, 0x79, 0x5d, 0xb6, 0x3c, 0xe6, 0x1f, 0x18, 0x3b, 0x91, 0x07, 0x89, 0xe5, 0x38, 0x51, 0x41, - 0xbf, 0x90, 0x97, 0xa9, 0x39, 0xc1, 0xe6, 0xd3, 0x35, 0x6e, 0x92, 0xae, 0xc2, 0xf2, 0x7a, 0x7e, - 0x9d, 0xb7, 0x72, 0xcd, 0x49, 0x06, 0x71, 0x83, 0x43, 0xe8, 0x95, 0x70, 0xde, 0xb2, 0x6f, 0xc1, - 0xb5, 0xc7, 0xfd, 0x90, 0xf8, 0x8f, 0x3b, 0x1d, 0xfa, 0xe6, 0x02, 0x73, 0x8a, 0x61, 0xae, 0x73, - 0x4c, 0x8d, 0x06, 0xd6, 0x99, 0xa1, 0xcf, 0x60, 0xe1, 0x85, 0xd3, 0xef, 0xd7, 0x3d, 0x57, 0x4c, - 0x20, 0x73, 0x9a, 0x21, 0xad, 0x70, 0x24, 0xa5, 0x16, 0xab, 0xea, 0xa8, 0x0e, 0xc6, 0xb1, 0x6f, - 0x77, 0x48, 0x7b, 0x68, 0xc7, 0x10, 0x33, 0x0c, 0x62, 0x95, 0x43, 0xa8, 0xd5, 0x38, 0x63, 0x80, - 0x9a, 0x80, 0x9e, 0x92, 0xb0, 0xe5, 0x75, 0xce, 0x53, 0xb3, 0xc0, 0x2c, 0x33, 0x98, 0x35, 0x0e, - 0x93, 0x55, 0xc0, 0x1a, 0x23, 0xb4, 0xcf, 0xfc, 0xc2, 0xf1, 0x85, 0x9b, 0x46, 0xaa, 0x30, 0x24, - 0x33, 0x41, 0x92, 0xeb, 0x71, 0xd6, 0x84, 0x8e, 0x33, 0xf5, 0x2f, 0x76, 0xe7, 0x2c, 0x3d, 0x33, - 0x4d, 0x90, 0xc6, 0x59, 0xa3, 0x81, 0x75, 0x66, 0xe8, 0x97, 0x00, 0xed, 0xcb, 0x8e, 0x1b, 0xb9, - 0x18, 0x73, 0x56, 0xea, 0x4e, 0xc6, 0x1f, 0xe3, 0x94, 0x2e, 0x7a, 0x08, 0x95, 0xd8, 0xcf, 0x99, - 0x55, 0x69, 0x60, 0x55, 0x9f, 0x88, 0x13, 0x4d, 0x74, 0xc4, 0x46, 0x54, 0x59, 0xec, 0xe6, 0x1c, - 0xb3, 0xdf, 0x4a, 0xec, 0xf5, 0x4e, 0x04, 0x6b, 0x6c, 0x29, 0x62, 0xd6, 0x7d, 0x98, 0xf3, 0x12, - 0x62, 0x3b, 0x1f, 0x31, 0x5b, 0x85, 0x1a, 0x30, 0x2f, 0xbb, 0x4d, 0x73, 0x81, 0xa1, 0x6d, 0x88, - 0xf5, 0xa8, 0x73, 0xc2, 0x58, 0xb1, 0x41, 0xbb, 0x30, 0xc3, 0x1d, 0x8e, 0x69, 0x30, 0xf3, 0x65, - 0x6e, 0x2e, 0x3b, 0x2d, 0x2c, 0xb4, 0xd0, 0x6f, 0x61, 0x19, 0x93, 0x81, 0xf7, 0x9e, 0xd0, 0xdf, - 0x90, 0xd0, 0x09, 0x74, 0x6c, 0x9f, 0xf4, 0x89, 0xb9, 0xc8, 0xcc, 0x3f, 0x10, 0xe6, 0x3a, 0x1d, - 0x01, 0xa6, 0x47, 0x40, 0x8f, 0x61, 0x8e, 0x4e, 0x49, 0xb6, 0x33, 0xee, 0x39, 0x6e, 0xd7, 0x44, - 0x0c, 0xf2, 0x7a, 0x6a, 0x0a, 0xc7, 0x75, 0x02, 0x4a, 0xb6, 0x40, 0xcf, 0xc1, 0x78, 0xed, 0x06, - 0xa3, 0x93, 0xa0, 0xe3, 0x3b, 0x27, 0x24, 0xea, 0xd8, 0x35, 0x86, 0x52, 0xe3, 0x28, 0x6a, 0x75, - 0xbc, 0xac, 0xd4, 0x8a, 0xf4, 0x1c, 0x6e, 0xd8, 0xa1, 0x2d, 0xe6, 0xf0, 0x92, 0x76, 0x0e, 0xa7, - 0x34, 0xb0, 0xce, 0x8c, 0xa3, 0xb5, 0x69, 0x88, 0x94, 0x5e, 0x11, 0xcb, 0x2a, 0x9a, 0xaa, 0x81, - 0x75, 0x66, 0xd4, 0x3d, 0xea, 0x9d, 0xbf, 0xb9, 0x22, 0xb9, 0x47, 0xbd, 0x12, 0xce, 0x31, 0xa6, - 0xb0, 0x07, 0x4e, 0xcf, 0xb7, 0x43, 0x42, 0x9d, 0xd4, 0xbe, 0xef, 0x0d, 0x04, 0xec, 0xaa, 0x04, - 0xab, 0x57, 0xc2, 0x39, 0xc6, 0xe8, 0x10, 0x96, 0x52, 0x35, 0xc7, 0x71, 0x5f, 0x4d, 0xe9, 0xfb, - 0xea, 0x54, 0xb0, 0xd6, 0x10, 0x9d, 0x80, 0x89, 0x49, 0xdf, 0xb3, 0xbb, 0x8f, 0x47, 0xa1, 0xd7, - 0x74, 0x3b, 0x3e, 0x19, 0xd0, 0x10, 0x84, 0x8e, 0xb9, 0xb9, 0xc6, 0x40, 0x6f, 0xc7, 0xf3, 0x50, - 0xaf, 0x26, 0xf0, 0x73, 0x71, 0xa8, 0x6b, 0xae, 0x87, 0x7d, 0x4c, 0xec, 0x2e, 0xf1, 0x45, 0x87, - 0xd7, 0x25, 0x0f, 0xa2, 0x56, 0xe3, 0x8c, 0x01, 0x3a, 0x80, 0x85, 0xa7, 0x24, 0xc4, 0x64, 0xd8, - 0x77, 0x3a, 0x76, 0xb4, 0xf3, 0x5e, 0x57, 0x3f, 0x50, 0xba, 0x96, 0xdb, 0x89, 0xd8, 0x4a, 0xa9, - 0xa5, 0x93, 0x08, 0x93, 0x80, 0x84, 0x6d, 0x12, 0xa4, 0xdc, 0x83, 0xb9, 0x21, 0x4d, 0x22, 0x8d, - 0x06, 0xd6, 0x99, 0xa1, 0x16, 0x2c, 0x3e, 0xf5, 0x0e, 0xec, 0x0b, 0xba, 0x4f, 0x06, 0x02, 0xeb, - 0x86, 0xec, 0xec, 0xd5, 0x7a, 0xde, 0xb3, 0xac, 0x21, 0x47, 0x23, 0x83, 0x96, 0x93, 0xf8, 0x54, - 0xb3, 0xa6, 0xa2, 0xc9, 0xf5, 0x29, 0x34, 0xb9, 0x02, 0x7d, 0x01, 0xab, 0xfb, 0x4e, 0x9f, 0xb4, - 0x89, 0xff, 0xde, 0xe9, 0x90, 0xf4, 0x27, 0x33, 0x37, 0xa5, 0xf5, 0x9c, 0xa3, 0xc5, 0x91, 0xf3, - 0x40, 0xd0, 0x00, 0x36, 0xd4, 0xaa, 0x27, 0xef, 0x9d, 0x4e, 0xdc, 0xf1, 0x2d, 0xc9, 0x9b, 0x15, - 0xa9, 0xf2, 0x96, 0x0a, 0xe1, 0xd0, 0x6b, 0x58, 0x3a, 0x20, 0xa1, 0xdd, 0xb5, 0x43, 0x5b, 0x7a, - 0x97, 0x9b, 0xf2, 0x0a, 0xd0, 0xa8, 0x70, 0x78, 0xad, 0x39, 0x3a, 0x04, 0xf4, 0xd4, 0x7b, 0x5a, - 0x3f, 0x22, 0x7e, 0x87, 0x24, 0xd1, 0x8c, 0x25, 0xef, 0xfc, 0x19, 0x05, 0x0e, 0xa9, 0x31, 0xa5, - 0xa1, 0xc4, 0xbe, 0x3d, 0xea, 0x87, 0x4d, 0xf7, 0xf7, 0x24, 0x19, 0x8c, 0x0f, 0x24, 0xc0, 0xac, - 0x02, 0xd6, 0x18, 0xa1, 0xdf, 0xc1, 0x4a, 0x3d, 0xec, 0x1f, 0x78, 0xcc, 0x99, 0x32, 0x07, 0x26, - 0xe0, 0x6e, 0x49, 0x2b, 0x40, 0xaf, 0xc4, 0xfb, 0x98, 0x03, 0x81, 0xbe, 0x80, 0xb5, 0xb7, 0x9e, - 0x7f, 0x1e, 0x0c, 0xed, 0x0e, 0x39, 0x3e, 0xf3, 0x49, 0x70, 0xe6, 0xf5, 0xc5, 0x9e, 0x60, 0x7e, - 0x28, 0xed, 0xaa, 0xb9, 0x7a, 0x38, 0x1f, 0x02, 0x0d, 0xa0, 0x56, 0x0f, 0xfb, 0x47, 0x3e, 0x39, - 0x25, 0x61, 0xe7, 0xec, 0xd0, 0x6d, 0x8b, 0xad, 0x21, 0x6e, 0xe4, 0x36, 0x6b, 0xe4, 0xc3, 0xe4, - 0x25, 0x0a, 0x94, 0xf1, 0x18, 0x30, 0xf4, 0x3b, 0x30, 0x9b, 0xed, 0xfa, 0x51, 0xc3, 0xb7, 0x1d, - 0xb7, 0xee, 0xb9, 0xc1, 0x68, 0x90, 0xf8, 0x9c, 0x3b, 0xac, 0xa1, 0x4d, 0xde, 0x50, 0x9e, 0x1a, - 0xce, 0x05, 0x40, 0x43, 0xb8, 0xd1, 0xec, 0x90, 0x13, 0xe2, 0xf7, 0x78, 0x60, 0xf5, 0xde, 0xee, - 0x3b, 0x5d, 0x3b, 0x8c, 0x27, 0xe1, 0x36, 0x6b, 0xe1, 0x96, 0x68, 0xa1, 0x48, 0x97, 0x7f, 0x96, - 0x62, 0x40, 0xd4, 0x83, 0xf5, 0x03, 0xcf, 0xed, 0x79, 0x8d, 0xbd, 0x7a, 0xdf, 0x61, 0xb3, 0x2b, - 0x74, 0xfc, 0xb8, 0xb9, 0xbb, 0xac, 0xb9, 0x9b, 0x62, 0xce, 0xe7, 0x2a, 0xf2, 0xb6, 0x0a, 0xa0, - 0xac, 0x7d, 0x58, 0xcd, 0x04, 0xfa, 0x9c, 0xe9, 0xdc, 0x87, 0x32, 0x77, 0x77, 0x81, 0x59, 0xda, - 0x9a, 0xd8, 0x9e, 0x7d, 0xb0, 0xb0, 0xc3, 0xd3, 0x1a, 0xc2, 0x0d, 0xc6, 0x0a, 0xd6, 0x9f, 0xd7, - 0xa1, 0x1c, 0x5b, 0xfe, 0xb4, 0x0c, 0x68, 0x09, 0xa6, 0x9e, 0xf8, 0xbe, 0xe7, 0x33, 0xea, 0x53, - 0xc5, 0x51, 0x01, 0xbd, 0xcb, 0xed, 0x38, 0xe7, 0x37, 0xb5, 0x3c, 0x7e, 0x13, 0x69, 0xe1, 0xdc, - 0xf7, 0x3e, 0x84, 0x25, 0x99, 0xaa, 0x70, 0xd8, 0x29, 0xc9, 0xd3, 0xe8, 0x54, 0xb0, 0xd6, 0x90, - 0xee, 0x83, 0x09, 0x6b, 0xe1, 0x60, 0xd3, 0xd2, 0x3e, 0xa8, 0x56, 0xe3, 0x8c, 0x01, 0xe5, 0x15, - 0x29, 0xda, 0xc2, 0x51, 0x66, 0xa4, 0xcd, 0x21, 0x53, 0x8f, 0xb3, 0x26, 0x3c, 0x8a, 0x4a, 0x58, - 0x0b, 0x47, 0x2a, 0xab, 0x51, 0x94, 0xaa, 0x81, 0x75, 0x66, 0x9c, 0x38, 0xc5, 0xd4, 0x85, 0x83, - 0x55, 0x54, 0xe2, 0xa4, 0x28, 0x60, 0x8d, 0x11, 0x1d, 0x76, 0x99, 0xb9, 0x70, 0x30, 0x50, 0x43, - 0xd8, 0x8c, 0x0a, 0xd6, 0x1a, 0xa2, 0x5f, 0x51, 0xce, 0x23, 0xa8, 0x0d, 0xe7, 0x3c, 0x6b, 0x1a, - 0xce, 0xc3, 0x41, 0x52, 0xca, 0xe8, 0x51, 0x96, 0xf4, 0x98, 0x59, 0xd2, 0xc3, 0x0d, 0x53, 0xac, - 0xe7, 0x55, 0x01, 0xeb, 0xb9, 0x59, 0xc0, 0x7a, 0x52, 0xc3, 0xa2, 0x92, 0x94, 0x57, 0x05, 0xb4, - 0xe7, 0x66, 0x01, 0xed, 0x11, 0x90, 0x1a, 0xde, 0xf3, 0x24, 0x87, 0xf7, 0xdc, 0xc8, 0xe1, 0x3d, - 0x1c, 0x4a, 0x25, 0x3e, 0x1f, 0xab, 0xc4, 0x67, 0x45, 0x25, 0x3e, 0xdc, 0x30, 0x66, 0x3e, 0x9f, - 0x17, 0x33, 0x9f, 0x5b, 0xc5, 0xcc, 0x87, 0xa3, 0xe5, 0x50, 0x9f, 0x3d, 0x3d, 0xf5, 0xd9, 0xd0, - 0x53, 0x1f, 0x8e, 0xa5, 0x70, 0x9f, 0x17, 0xb9, 0xdc, 0x67, 0x33, 0x97, 0xfb, 0x88, 0x05, 0x9b, - 0x21, 0x3f, 0xa9, 0xf9, 0x1c, 0xb1, 0x18, 0x3e, 0x9f, 0x97, 0xb4, 0xf3, 0x39, 0xad, 0x82, 0xb5, - 0x86, 0x1c, 0x30, 0x45, 0x64, 0x38, 0xe0, 0xb2, 0x0a, 0x98, 0x51, 0xc1, 0x5a, 0x43, 0xea, 0x42, - 0x73, 0xb2, 0x5c, 0x9c, 0x03, 0xd5, 0xf2, 0x38, 0x90, 0x70, 0xa1, 0x79, 0x49, 0xb2, 0x77, 0xb0, - 0x9a, 0x21, 0x32, 0x1c, 0x79, 0x55, 0x42, 0xce, 0xd1, 0xc2, 0x79, 0xe6, 0x08, 0xc3, 0xb2, 0xc2, - 0x67, 0x38, 0xae, 0x29, 0x7d, 0x6e, 0xad, 0x0e, 0xd6, 0x9b, 0xa2, 0xce, 0x58, 0x2e, 0x74, 0x67, - 0x2c, 0x17, 0xe2, 0x2d, 0xe4, 0x93, 0xa1, 0x7d, 0x58, 0x4c, 0x71, 0x1b, 0xde, 0xe9, 0x75, 0xc9, - 0xb5, 0x64, 0xea, 0x71, 0xd6, 0x04, 0xbd, 0xcc, 0xe3, 0x43, 0xb5, 0x3c, 0x3e, 0x14, 0x19, 0xe6, - 0x11, 0xa2, 0x43, 0x58, 0x92, 0x99, 0x0d, 0xef, 0xda, 0x86, 0x34, 0xab, 0x74, 0x2a, 0x58, 0x6b, - 0x18, 0x45, 0xd4, 0x09, 0xb5, 0xe1, 0x70, 0x37, 0x94, 0x88, 0x5a, 0x55, 0x48, 0x22, 0x6a, 0xb5, - 0x86, 0x03, 0xc6, 0xec, 0x86, 0x03, 0xd6, 0x54, 0x40, 0x45, 0x21, 0x05, 0xa8, 0xd4, 0x20, 0x1b, - 0xcc, 0x2c, 0xa9, 0xe1, 0xb0, 0x9b, 0xd2, 0x72, 0xcf, 0x53, 0xe3, 0xe0, 0xb9, 0x30, 0x34, 0x62, - 0xcc, 0x61, 0x33, 0xbc, 0x9d, 0x2d, 0xc9, 0xe3, 0x15, 0xea, 0x8a, 0x88, 0xb1, 0x50, 0x09, 0xbd, - 0x83, 0x65, 0x85, 0xe0, 0xf0, 0x96, 0x6e, 0xca, 0x0b, 0x43, 0xa7, 0xc3, 0x5b, 0xd0, 0x03, 0x20, - 0x0c, 0xd7, 0x24, 0x9e, 0xc3, 0x71, 0x2d, 0x39, 0x62, 0xc8, 0x6a, 0x70, 0x54, 0x9d, 0x31, 0x8d, - 0x42, 0x24, 0xc2, 0xc3, 0x31, 0x3f, 0x90, 0x30, 0x35, 0x1a, 0x58, 0x67, 0x46, 0xa9, 0x6e, 0x86, - 0xe5, 0x70, 0xc4, 0x5b, 0xd2, 0xda, 0xc8, 0xd1, 0x12, 0x54, 0x37, 0xa7, 0x1a, 0xd9, 0xb0, 0xae, - 0x23, 0x3a, 0xbc, 0x89, 0x0f, 0xa5, 0xbd, 0x38, 0x5f, 0x11, 0x17, 0x80, 0x44, 0x09, 0x1e, 0x37, - 0x3e, 0x1a, 0x8a, 0xc1, 0x6f, 0x2b, 0x09, 0x9e, 0xac, 0x0a, 0xd6, 0x1a, 0xa2, 0x21, 0x6c, 0xe6, - 0x52, 0x26, 0x8e, 0x7d, 0x47, 0xca, 0xf3, 0x8c, 0xd1, 0xc6, 0xe3, 0xe0, 0x28, 0xa3, 0xd4, 0x30, - 0x28, 0xde, 0xd6, 0xb6, 0xc4, 0x28, 0x73, 0xf5, 0x70, 0x3e, 0x04, 0x0a, 0xa0, 0x96, 0x47, 0x9a, - 0x78, 0x23, 0x77, 0x25, 0x46, 0x59, 0xac, 0xcc, 0xbf, 0xf9, 0x18, 0x48, 0xf4, 0x7b, 0xb8, 0xae, - 0x65, 0x4f, 0xbc, 0xc5, 0x7b, 0xac, 0x45, 0xab, 0x88, 0x89, 0x49, 0xcd, 0x15, 0x81, 0x59, 0x4d, - 0xed, 0xd1, 0x0a, 0x3b, 0xed, 0x62, 0x87, 0xa7, 0xcd, 0x2e, 0x3f, 0x74, 0x8a, 0xcb, 0x68, 0x05, - 0xa6, 0xdb, 0x8c, 0x92, 0x31, 0x72, 0x54, 0xc1, 0xbc, 0x64, 0xfd, 0x5a, 0xcf, 0x61, 0x90, 0x05, - 0x55, 0x9b, 0xca, 0xdb, 0xa3, 0x0e, 0xe5, 0x3d, 0x0c, 0xaf, 0x8c, 0x25, 0x99, 0xd5, 0xcc, 0x9c, - 0xc9, 0x50, 0x42, 0xc7, 0x91, 0x38, 0xa1, 0x9b, 0xc0, 0x89, 0x20, 0x7d, 0x74, 0x77, 0x95, 0x91, - 0xbd, 0xd4, 0xd1, 0x5d, 0x96, 0xc8, 0x98, 0x30, 0x23, 0xb7, 0x2e, 0x8a, 0x56, 0x2b, 0x9b, 0x2f, - 0x44, 0x06, 0x4c, 0xd4, 0x07, 0x5d, 0x7e, 0x70, 0x47, 0x1f, 0x99, 0xe4, 0xb4, 0xc7, 0x5a, 0xa2, - 0x92, 0xd3, 0x1e, 0x23, 0x88, 0x17, 0xa1, 0x6f, 0xc7, 0x04, 0x91, 0x16, 0xac, 0x3b, 0x9a, 0x0d, - 0x17, 0x21, 0x98, 0xa4, 0xcf, 0x1c, 0x8f, 0x3d, 0x5b, 0x9f, 0x8e, 0xcb, 0x54, 0xd0, 0x2f, 0x70, - 0x64, 0x87, 0x21, 0xf1, 0x39, 0x13, 0xae, 0xe0, 0xb8, 0x6c, 0x3d, 0x1c, 0xbb, 0xce, 0xb4, 0x8d, - 0xfe, 0x57, 0x29, 0x3f, 0x61, 0x91, 0x1d, 0xee, 0x39, 0x65, 0xb8, 0x99, 0x8f, 0x6a, 0x36, 0xc4, - 0x70, 0xf3, 0x22, 0xad, 0x79, 0xee, 0x9d, 0xbc, 0xb4, 0x07, 0x84, 0x4f, 0x07, 0x51, 0xa4, 0x43, - 0xf4, 0xdc, 0x3b, 0x69, 0x36, 0x18, 0x37, 0x9e, 0xc4, 0x51, 0x01, 0x6d, 0xc3, 0x42, 0x14, 0x4c, - 0xef, 0x13, 0xb7, 0x43, 0x0e, 0xdd, 0xfe, 0x25, 0x23, 0xb9, 0x65, 0xac, 0x8a, 0xd1, 0x6d, 0x98, - 0xc7, 0xc4, 0x25, 0x5f, 0x25, 0x8a, 0xd3, 0x4c, 0x51, 0x91, 0x5a, 0x0f, 0x0b, 0x7c, 0x40, 0xc1, - 0x97, 0x7f, 0x97, 0x3d, 0xc4, 0xd3, 0x7c, 0xf9, 0x25, 0x98, 0xa2, 0x0a, 0x01, 0xff, 0xf6, 0x51, - 0x81, 0x0e, 0x56, 0xec, 0x4e, 0xd9, 0x6b, 0x4f, 0xe0, 0x44, 0x40, 0x67, 0x41, 0x96, 0x03, 0xeb, - 0x3e, 0xc8, 0x92, 0xee, 0x08, 0xd0, 0xfa, 0x5b, 0x09, 0xca, 0x42, 0x96, 0x0c, 0x7c, 0x97, 0x27, - 0x35, 0x44, 0x91, 0x02, 0xbe, 0x20, 0x97, 0xb4, 0x63, 0x13, 0xdb, 0x55, 0xcc, 0x9e, 0xd1, 0xbd, - 0xc8, 0xf2, 0xc0, 0xeb, 0x46, 0x5f, 0x63, 0xfe, 0xc1, 0xfc, 0x0e, 0xbb, 0x07, 0x22, 0xa4, 0x38, - 0xae, 0x47, 0x5b, 0x30, 0xeb, 0x04, 0xd8, 0x76, 0x7b, 0x8c, 0xd0, 0xb0, 0x8f, 0x54, 0xc6, 0x69, - 0x11, 0xba, 0x03, 0x33, 0xcf, 0xbc, 0x7e, 0x97, 0xf8, 0x81, 0x39, 0xc5, 0x72, 0x31, 0x73, 0x11, - 0xd8, 0x5b, 0xdb, 0xa1, 0x4c, 0x1a, 0x8b, 0x5a, 0xaa, 0x48, 0x65, 0x54, 0x71, 0x5a, 0xab, 0xc8, - 0x6b, 0xad, 0x2f, 0xb4, 0x89, 0x00, 0xfa, 0x2a, 0x75, 0xb7, 0x29, 0xc6, 0x9d, 0x3d, 0xa3, 0x9f, - 0x43, 0x55, 0xe8, 0xb5, 0x9c, 0x20, 0x64, 0xaf, 0x39, 0xfb, 0x60, 0x81, 0x7b, 0xbd, 0x18, 0x42, - 0x52, 0xb2, 0xae, 0x69, 0x0e, 0x42, 0xad, 0x33, 0x98, 0x3d, 0xbe, 0x70, 0xbf, 0xdb, 0x88, 0x62, - 0xef, 0xab, 0x78, 0x44, 0xe9, 0x33, 0xba, 0x0f, 0x33, 0x87, 0xc3, 0x90, 0xe5, 0xa3, 0xa2, 0x53, - 0xf0, 0xc5, 0x64, 0x40, 0x79, 0x05, 0x16, 0x1a, 0xd6, 0x7f, 0x96, 0x60, 0x86, 0x37, 0x8e, 0x3e, - 0x83, 0x72, 0xdd, 0x27, 0x76, 0x48, 0x1e, 0x87, 0xfc, 0x3e, 0xc6, 0xfa, 0x4e, 0x74, 0x3d, 0x66, - 0x47, 0x5c, 0x8f, 0x49, 0xdd, 0xca, 0x28, 0x53, 0x4f, 0xfd, 0x87, 0xff, 0xd9, 0x2c, 0xe1, 0xd8, - 0x0a, 0x6d, 0xc1, 0x24, 0x0d, 0x8e, 0xd8, 0xcc, 0x9b, 0x7d, 0x50, 0xdd, 0x09, 0x2f, 0xdc, 0x9d, - 0xe3, 0x0b, 0x97, 0xca, 0x30, 0xab, 0xa1, 0xaf, 0xf2, 0x3a, 0x20, 0xfe, 0xf1, 0x85, 0xcb, 0x3a, - 0x57, 0xc6, 0xa2, 0x88, 0x3e, 0x86, 0x0a, 0x1d, 0x73, 0xda, 0xcb, 0xc0, 0x9c, 0x64, 0x43, 0x87, - 0x44, 0xc6, 0x26, 0x19, 0x0b, 0x9c, 0x28, 0x59, 0x9f, 0xeb, 0xb2, 0x2a, 0xda, 0x2f, 0xf3, 0x31, - 0x1b, 0x4f, 0xe5, 0xc3, 0xcc, 0x27, 0xe8, 0x0c, 0x20, 0xad, 0x62, 0x2d, 0x6b, 0xcf, 0x95, 0xad, - 0x7f, 0x2f, 0x41, 0x25, 0x16, 0x52, 0x87, 0xf7, 0xd2, 0xeb, 0x92, 0xe3, 0xcb, 0x21, 0xe1, 0xcd, - 0xc5, 0x65, 0xba, 0xe5, 0xd0, 0xe7, 0x66, 0x97, 0x2f, 0x43, 0x5e, 0xa2, 0xeb, 0x90, 0x01, 0x30, - 0xa3, 0xc8, 0xfd, 0x24, 0x02, 0xda, 0xf9, 0xd7, 0x01, 0xe9, 0x72, 0xff, 0xc3, 0x9e, 0xa9, 0x6c, - 0xdf, 0x27, 0x51, 0x62, 0x6d, 0x12, 0xb3, 0x67, 0xda, 0xf2, 0x33, 0x27, 0xc4, 0x76, 0xe8, 0x78, - 0xcc, 0xc5, 0x5c, 0xc5, 0x71, 0xd9, 0x7a, 0xa9, 0xcf, 0x10, 0xa1, 0x47, 0x30, 0x17, 0x0b, 0xd9, - 0x30, 0x44, 0xd9, 0xca, 0x38, 0xa9, 0x18, 0x1b, 0xc8, 0x6a, 0x56, 0x1f, 0x36, 0x8a, 0x0e, 0x59, - 0xe9, 0x27, 0x7d, 0xea, 0x7b, 0xa3, 0x61, 0xec, 0x84, 0x45, 0xb1, 0xd8, 0x05, 0x8b, 0xbd, 0x70, - 0x42, 0xde, 0x0b, 0x1f, 0xc2, 0x8d, 0xc2, 0xc4, 0x86, 0x7c, 0xb3, 0x64, 0x4a, 0xdc, 0x2c, 0x79, - 0xce, 0x5e, 0x3a, 0x73, 0x6c, 0xfb, 0x43, 0x3a, 0x67, 0xdd, 0x87, 0x65, 0x6d, 0x1e, 0x84, 0x7e, - 0x09, 0x96, 0x33, 0xe1, 0x53, 0x8b, 0x3e, 0x5b, 0x6d, 0x58, 0xcd, 0x39, 0xe9, 0x45, 0x35, 0x80, - 0x86, 0x1d, 0xda, 0x27, 0x76, 0x40, 0xe2, 0x04, 0x6f, 0x4a, 0x52, 0xd0, 0x83, 0x4f, 0xc0, 0xcc, - 0x4b, 0xa1, 0x14, 0x6c, 0x0f, 0xfb, 0x50, 0x66, 0x5f, 0xee, 0x05, 0xb9, 0xa4, 0x5d, 0x3d, 0xb2, - 0xc3, 0x33, 0xd1, 0x55, 0xfa, 0x4c, 0xa7, 0xe4, 0xe1, 0xe9, 0x69, 0x40, 0xa2, 0xfb, 0x66, 0x13, - 0x98, 0x97, 0xd0, 0x3c, 0x5c, 0x6d, 0x7f, 0xcd, 0xf7, 0x84, 0xab, 0xed, 0xaf, 0xad, 0x47, 0x7c, - 0x8a, 0x32, 0xff, 0x7c, 0x17, 0x26, 0xcf, 0xa9, 0xcf, 0x2e, 0x49, 0xce, 0x4c, 0xd4, 0xf3, 0x78, - 0x8d, 0xa9, 0x58, 0xc7, 0x74, 0x9f, 0x64, 0xaf, 0x1e, 0x77, 0x63, 0x09, 0xa6, 0x9a, 0x6e, 0x97, - 0x5c, 0x88, 0x8f, 0xc5, 0x0a, 0xe8, 0x7e, 0xd2, 0x51, 0xee, 0x2a, 0x54, 0x5c, 0x1c, 0x2b, 0x58, - 0x6f, 0xb5, 0xa7, 0xe3, 0xe8, 0xb3, 0x4c, 0x63, 0xbc, 0x8b, 0x71, 0x7a, 0x4d, 0xae, 0xc5, 0xaa, - 0xba, 0x75, 0x08, 0x8b, 0x62, 0x50, 0x63, 0xf4, 0x9c, 0x0e, 0x1b, 0x30, 0xf1, 0xcc, 0x11, 0xd7, - 0xf4, 0xe8, 0x23, 0x1d, 0x5f, 0xaa, 0xcf, 0x63, 0x29, 0xf6, 0x6c, 0x7d, 0xa1, 0x4f, 0x65, 0xa1, - 0x7d, 0x4d, 0x43, 0xbc, 0xb3, 0x66, 0x92, 0x38, 0x90, 0xeb, 0x71, 0xd6, 0xc4, 0xc2, 0xda, 0x93, - 0x7d, 0xf4, 0x1b, 0xa8, 0xc6, 0xb2, 0x68, 0x18, 0xa2, 0x9c, 0x79, 0x72, 0x4b, 0x32, 0x5d, 0x8d, - 0x25, 0x65, 0xbe, 0x6e, 0xb2, 0x49, 0xaf, 0x07, 0x50, 0x89, 0x85, 0xf1, 0xe5, 0x3c, 0x0d, 0x22, - 0x4e, 0xd4, 0xac, 0x36, 0xcc, 0x1e, 0xf9, 0x64, 0x68, 0xfb, 0xa4, 0x1d, 0x0e, 0xd8, 0x10, 0xb1, - 0x18, 0x8b, 0x4f, 0x41, 0x16, 0x60, 0x19, 0x30, 0xd1, 0x7e, 0xd5, 0x12, 0x51, 0x69, 0xfb, 0x55, - 0x8b, 0x2e, 0x92, 0x23, 0xdb, 0xb7, 0x07, 0xd4, 0xfd, 0x05, 0x7c, 0x38, 0x53, 0x12, 0xab, 0x9f, - 0x77, 0x53, 0x80, 0x4e, 0x67, 0x2a, 0x8a, 0x57, 0x36, 0x2f, 0xa1, 0x4f, 0xe2, 0xeb, 0x7f, 0xd1, - 0xa9, 0xc9, 0x86, 0x3e, 0x89, 0x16, 0xe9, 0x88, 0xcb, 0x81, 0xcf, 0x27, 0xcb, 0x13, 0xc6, 0xa4, - 0xf5, 0x2f, 0x33, 0xb9, 0x29, 0x39, 0xba, 0x4c, 0x1a, 0x7b, 0xfc, 0x6d, 0xae, 0x36, 0xf6, 0xd0, - 0x23, 0xa8, 0xa6, 0x5e, 0x37, 0xe0, 0xbb, 0x8a, 0xd8, 0xb3, 0x52, 0x55, 0x58, 0xd2, 0x43, 0xf7, - 0xc0, 0x68, 0xd9, 0x41, 0xf8, 0xf8, 0xf4, 0x94, 0x74, 0x42, 0xd2, 0x65, 0xfb, 0x77, 0xb4, 0xf8, - 0x32, 0x72, 0xf4, 0x29, 0xcc, 0xd3, 0xfd, 0xb1, 0x45, 0xde, 0x93, 0x7e, 0x7a, 0x67, 0x5c, 0x12, - 0x89, 0xd6, 0x74, 0x25, 0x56, 0x74, 0x51, 0x03, 0x6e, 0xc8, 0x0a, 0xa4, 0x4f, 0xec, 0x80, 0xb4, - 0x47, 0xc3, 0xa1, 0xe7, 0x87, 0xa4, 0xcb, 0xc3, 0xd8, 0x62, 0x25, 0xb4, 0x0f, 0x0b, 0x54, 0xa1, - 0x41, 0x4e, 0x1d, 0x97, 0x74, 0xdf, 0xd8, 0x71, 0xc8, 0xa4, 0x0c, 0xac, 0xac, 0x84, 0x55, 0x23, - 0xf4, 0x4b, 0x58, 0x55, 0x44, 0x4f, 0x2e, 0x78, 0x3f, 0x66, 0x58, 0x3f, 0xf2, 0xaa, 0x69, 0x0f, - 0xda, 0x97, 0x41, 0x48, 0x06, 0x6f, 0x6c, 0xdf, 0xa1, 0xce, 0x30, 0x30, 0xcb, 0xba, 0x1e, 0xc8, - 0x4a, 0x58, 0x35, 0xa2, 0x3d, 0x50, 0x44, 0x71, 0x0f, 0x2a, 0x51, 0x0f, 0x72, 0xaa, 0xd1, 0xa7, - 0xb0, 0xa6, 0x74, 0x0e, 0x93, 0x61, 0xdf, 0xbe, 0x64, 0xb9, 0x6f, 0x60, 0xb6, 0xf9, 0x0a, 0xd4, - 0x5a, 0x01, 0x4e, 0x59, 0xcf, 0x46, 0xd6, 0xb9, 0x0a, 0xe8, 0x19, 0x6c, 0x2a, 0x95, 0x6d, 0xd7, - 0x1e, 0x06, 0x67, 0x5e, 0x78, 0xec, 0x79, 0x2d, 0xdb, 0xef, 0x11, 0x76, 0xf6, 0x52, 0xc6, 0xe3, - 0xd4, 0x28, 0x92, 0xd2, 0xc9, 0x0c, 0xd2, 0x5c, 0x84, 0x34, 0x46, 0x0d, 0x7d, 0x06, 0xd7, 0xf9, - 0x9c, 0xee, 0xd2, 0x49, 0xdd, 0xf2, 0xdc, 0x1e, 0x75, 0x51, 0xf5, 0x33, 0xd2, 0x39, 0x27, 0x5d, - 0x76, 0xee, 0x52, 0xc6, 0x45, 0x2a, 0x34, 0x0e, 0xda, 0xf7, 0x46, 0x6e, 0x34, 0xfd, 0x17, 0xa2, - 0xc3, 0xcf, 0x58, 0x60, 0xfd, 0x71, 0x4a, 0x7f, 0x93, 0x27, 0x77, 0xd1, 0x47, 0x8b, 0xf3, 0x6a, - 0xbc, 0x38, 0xb7, 0x60, 0xb6, 0x4d, 0xc2, 0x37, 0xb6, 0x1f, 0xad, 0xcd, 0x09, 0x46, 0x47, 0xd3, - 0xa2, 0xcc, 0xf2, 0x9d, 0xfc, 0x11, 0xcb, 0x77, 0xea, 0x3b, 0x2f, 0xdf, 0xe9, 0xef, 0xb1, 0x7c, - 0x35, 0x0b, 0x6f, 0xe6, 0x27, 0x5e, 0x78, 0xe5, 0xef, 0xbd, 0xf0, 0x2a, 0x3f, 0xf1, 0xc2, 0x83, - 0x1f, 0xb1, 0xf0, 0x66, 0x7f, 0xd4, 0xc2, 0xab, 0x8e, 0x5b, 0x78, 0xd2, 0x14, 0x9d, 0x53, 0xa7, - 0xe8, 0x9f, 0x4b, 0xf1, 0x19, 0x8b, 0xdc, 0x01, 0xed, 0xc6, 0xb7, 0x05, 0x53, 0x6f, 0xec, 0xfe, - 0x88, 0xf0, 0x78, 0x07, 0x76, 0xd8, 0x5f, 0x16, 0x9e, 0x5c, 0x0c, 0x7d, 0x1c, 0x55, 0xb0, 0xad, - 0xf1, 0xcb, 0x3e, 0xa7, 0x04, 0xf4, 0x91, 0xc5, 0x22, 0xc1, 0x9e, 0xe3, 0x72, 0xa2, 0x1b, 0x15, - 0xe8, 0xfc, 0xe3, 0xf3, 0x91, 0xed, 0x92, 0x2f, 0x68, 0x40, 0x3a, 0xc5, 0xd6, 0x42, 0x46, 0x8e, - 0x6a, 0x30, 0xc9, 0x78, 0xc6, 0x74, 0xba, 0x51, 0x2a, 0xc1, 0x4c, 0x6e, 0xbd, 0x82, 0x39, 0x69, - 0xce, 0x69, 0xbb, 0x1e, 0x07, 0xdc, 0x51, 0x90, 0x1a, 0x15, 0xd8, 0xff, 0x1a, 0x2e, 0xdc, 0x66, - 0x23, 0x5a, 0x5b, 0x55, 0xcc, 0x4b, 0xd6, 0x3f, 0xe4, 0x9c, 0x3c, 0x15, 0xc4, 0xad, 0xbf, 0x81, - 0xcd, 0x31, 0xb7, 0xe7, 0xd2, 0xa1, 0x72, 0x49, 0x0e, 0x95, 0x2d, 0xd8, 0x1a, 0x77, 0xdc, 0x64, - 0x6d, 0xb3, 0x4b, 0x8c, 0x9a, 0xeb, 0x6f, 0xd4, 0x6d, 0xd4, 0x5f, 0x8a, 0x3d, 0xbd, 0xfe, 0x92, - 0xdf, 0x68, 0xd7, 0x1d, 0x0c, 0xe5, 0xdc, 0x68, 0xff, 0x48, 0x7b, 0x51, 0x2e, 0xcf, 0x4d, 0x59, - 0x47, 0xfa, 0x63, 0xa4, 0xfc, 0xc1, 0xa1, 0xf1, 0xd1, 0xe3, 0x51, 0x78, 0xd6, 0x0e, 0x7d, 0xc7, - 0x8d, 0xd2, 0x79, 0x55, 0x9c, 0x92, 0x58, 0xbb, 0x9a, 0xbb, 0x75, 0x94, 0x1e, 0x0a, 0x91, 0xb8, - 0xf9, 0x2f, 0xca, 0xd6, 0xc7, 0xba, 0x83, 0xa7, 0x42, 0x8b, 0x5f, 0x69, 0x2e, 0xdc, 0xa1, 0x5b, - 0x30, 0x27, 0x44, 0x7b, 0x97, 0x21, 0x09, 0xf8, 0xb0, 0xc8, 0x42, 0xeb, 0xd7, 0xba, 0x43, 0xa9, - 0xef, 0x68, 0x7b, 0x96, 0x7b, 0x33, 0x0f, 0xed, 0xf2, 0x79, 0x5d, 0x62, 0x01, 0xde, 0xf5, 0x9c, - 0xe3, 0xa1, 0x64, 0xa2, 0xc7, 0xac, 0xbb, 0xed, 0x7c, 0x4d, 0x38, 0xfb, 0x49, 0x04, 0xd6, 0x45, - 0xfe, 0x49, 0x97, 0x6c, 0x59, 0x52, 0x2c, 0xe9, 0x9b, 0xb0, 0x42, 0xdd, 0x1e, 0xda, 0x1d, 0x27, - 0xbc, 0xe4, 0xd8, 0xb2, 0x90, 0x7e, 0xdd, 0x03, 0x12, 0x04, 0x76, 0x2f, 0x4e, 0x38, 0xf2, 0xa2, - 0x75, 0x58, 0x7c, 0x3b, 0xf0, 0x7b, 0xbf, 0xa8, 0xf5, 0xcf, 0x63, 0x4e, 0xd4, 0xfe, 0xce, 0xef, - 0xf3, 0x89, 0xfe, 0xfa, 0x61, 0x71, 0xab, 0xd6, 0x3f, 0xe6, 0x1c, 0xca, 0x65, 0xbb, 0x53, 0xd2, - 0x74, 0xc7, 0xfa, 0xbf, 0xd2, 0x98, 0x8b, 0x67, 0x63, 0x32, 0xc5, 0xac, 0x73, 0xa1, 0xdd, 0xf7, - 0x7a, 0x31, 0x13, 0x4f, 0x04, 0xb4, 0x96, 0xba, 0x41, 0x76, 0x20, 0x25, 0x12, 0x36, 0xb1, 0x80, - 0x7a, 0x85, 0xe8, 0x02, 0xc4, 0x64, 0x94, 0x6c, 0x8d, 0x2e, 0x35, 0xd4, 0x00, 0x44, 0xc8, 0xd4, - 0x6c, 0xf0, 0xe8, 0x20, 0x25, 0x41, 0x0f, 0x92, 0x61, 0x6a, 0x79, 0x1d, 0x9b, 0x12, 0x90, 0x67, - 0x76, 0x70, 0xc6, 0xfc, 0x74, 0x05, 0x6b, 0xeb, 0xe8, 0x0a, 0x8d, 0xae, 0xcf, 0x34, 0x1b, 0x2c, - 0x5e, 0xae, 0xe0, 0xb8, 0x6c, 0x3d, 0x1b, 0x77, 0xe6, 0x13, 0x65, 0xa6, 0x07, 0xde, 0x7b, 0xd2, - 0x7d, 0xe2, 0x86, 0xbe, 0x13, 0xaf, 0x39, 0x45, 0x6a, 0xed, 0xe8, 0x2e, 0x7a, 0xd2, 0x0f, 0xce, - 0x25, 0xdc, 0x39, 0x88, 0xa2, 0xb5, 0xab, 0x3d, 0xf5, 0x2c, 0x30, 0x68, 0xe9, 0x2e, 0x7e, 0x52, - 0x7f, 0xc9, 0x6f, 0xba, 0xf1, 0xff, 0x1e, 0xf1, 0x4b, 0x6d, 0x82, 0x1d, 0x12, 0x96, 0xa9, 0x8d, - 0xc2, 0xbb, 0x94, 0xc4, 0xba, 0xab, 0x3d, 0x20, 0xd5, 0x66, 0xae, 0xef, 0xe5, 0x5d, 0x13, 0xcd, - 0xa6, 0xd0, 0xad, 0x8f, 0x72, 0x4f, 0x4a, 0xb5, 0xd0, 0x83, 0x82, 0x4b, 0xa2, 0x68, 0x1b, 0x16, - 0xf8, 0x5f, 0xd6, 0xe2, 0xf4, 0x7b, 0xb4, 0x85, 0xa9, 0x62, 0xfa, 0x8d, 0xde, 0xfa, 0x4e, 0x98, - 0x40, 0xf0, 0xc9, 0xa8, 0x48, 0x2d, 0xb7, 0xe8, 0x9c, 0xf5, 0xef, 0xd0, 0xde, 0x1b, 0xfd, 0xa1, - 0x2b, 0xfa, 0x27, 0xa8, 0xa6, 0xe5, 0xdf, 0xe1, 0x3f, 0x7c, 0x92, 0xbe, 0xf5, 0xaf, 0xa5, 0xa2, - 0xeb, 0x9b, 0x63, 0x16, 0xad, 0x05, 0x55, 0xba, 0xa7, 0x12, 0xc6, 0xde, 0xe3, 0x75, 0x2b, 0xc9, - 0x68, 0xa8, 0xc4, 0xd3, 0x8a, 0x4f, 0x2e, 0x3a, 0xfd, 0x51, 0xe0, 0xbc, 0x27, 0x3c, 0xdd, 0x98, - 0x91, 0x5b, 0xbf, 0x28, 0x3c, 0xc1, 0x2c, 0x88, 0x5e, 0xfe, 0x23, 0x89, 0x03, 0xe5, 0x50, 0xf2, - 0x07, 0xc6, 0x81, 0xdb, 0xb0, 0xf0, 0x92, 0x5c, 0x84, 0xc7, 0xbe, 0xed, 0x06, 0x76, 0x94, 0xc7, - 0x88, 0x32, 0xe5, 0xaa, 0x18, 0xed, 0x40, 0x15, 0x8f, 0x5c, 0x3a, 0xda, 0x11, 0xe4, 0x64, 0x06, - 0x52, 0xaa, 0xbf, 0xf7, 0xa7, 0xe9, 0xd4, 0x95, 0x52, 0x54, 0xe1, 0x7f, 0x64, 0x35, 0xae, 0xa0, - 0x6b, 0xb0, 0xa0, 0xdc, 0xf2, 0x34, 0x4a, 0xc8, 0x80, 0x6a, 0xfa, 0x6c, 0xd4, 0xb8, 0x8a, 0xaa, - 0x50, 0x16, 0xc7, 0x94, 0xc6, 0x04, 0x9a, 0x83, 0x4a, 0x7c, 0x64, 0x64, 0x4c, 0xa2, 0x05, 0x98, - 0x4d, 0x9d, 0x93, 0x18, 0x53, 0x68, 0x1e, 0x20, 0xc9, 0xce, 0x1b, 0xd3, 0x14, 0x2f, 0x9d, 0x96, - 0x36, 0x66, 0xa8, 0x46, 0x72, 0x99, 0xd0, 0x28, 0x53, 0xc4, 0xf8, 0x8e, 0xa0, 0x51, 0x41, 0x2b, - 0xba, 0x5b, 0x82, 0x06, 0x50, 0x79, 0xf6, 0xb6, 0x9e, 0x31, 0x8b, 0x90, 0x7a, 0x5f, 0xcf, 0xa8, - 0xa2, 0xd9, 0xf8, 0xf2, 0x9d, 0x31, 0x87, 0xd6, 0x72, 0xee, 0xd5, 0x19, 0xf3, 0x68, 0x51, 0xb9, - 0x16, 0x67, 0x2c, 0xa0, 0xa5, 0xec, 0x2d, 0x37, 0xc3, 0x48, 0xbf, 0x05, 0x65, 0xb3, 0xc6, 0x22, - 0x97, 0xc4, 0x59, 0x30, 0x03, 0xd1, 0xe1, 0x54, 0x6e, 0x7c, 0x19, 0xd7, 0xa8, 0x50, 0x49, 0x2c, - 0x19, 0x4b, 0xb4, 0x59, 0x29, 0x58, 0x36, 0x96, 0xd1, 0x46, 0xfe, 0x2d, 0x2b, 0x63, 0x85, 0x0e, - 0x51, 0x7c, 0x5a, 0x6b, 0xac, 0xf2, 0x96, 0xd2, 0xe1, 0xaa, 0x61, 0xd2, 0x0e, 0xa5, 0x63, 0x4c, - 0x63, 0x8d, 0x7d, 0x8a, 0xc3, 0x83, 0xc7, 0xef, 0x8e, 0xf0, 0x61, 0xbd, 0x6d, 0xac, 0xf3, 0xf2, - 0x93, 0x83, 0x56, 0xf3, 0xa0, 0x79, 0x6c, 0x5c, 0xa7, 0xaf, 0xaa, 0x06, 0x0d, 0xc6, 0x06, 0x1d, - 0x2e, 0x6d, 0x28, 0x61, 0xdc, 0x60, 0xfd, 0x4e, 0x6f, 0xd8, 0x46, 0x8d, 0x7d, 0xff, 0xc3, 0x78, - 0x23, 0x30, 0x36, 0xa9, 0x20, 0xe5, 0x9a, 0x8d, 0x2d, 0xda, 0x59, 0xc5, 0xa9, 0x1a, 0x37, 0xe9, - 0xc7, 0xcc, 0xfa, 0x32, 0xc3, 0xa2, 0x2f, 0x91, 0xf6, 0x15, 0xc6, 0x07, 0xe8, 0x3a, 0xf3, 0xc9, - 0xba, 0x13, 0x64, 0xe3, 0x16, 0x5a, 0x86, 0xc5, 0xcc, 0x81, 0xaa, 0xf1, 0x21, 0x5a, 0x87, 0x15, - 0xfd, 0xbe, 0x68, 0xdc, 0x46, 0xab, 0x70, 0x4d, 0xb3, 0xe0, 0x8d, 0x3b, 0xb4, 0xe9, 0x64, 0x5a, - 0xbe, 0x79, 0x60, 0x6c, 0xdf, 0xfb, 0xb7, 0x92, 0x44, 0x6a, 0x92, 0xec, 0x21, 0x1d, 0x23, 0xa5, - 0x22, 0x62, 0xae, 0xc6, 0x15, 0x74, 0x1f, 0xee, 0x28, 0x55, 0xed, 0x73, 0x67, 0xa8, 0x4b, 0xb5, - 0x19, 0x25, 0xf4, 0x11, 0xdc, 0x55, 0x71, 0x5c, 0x3a, 0x4c, 0x5a, 0xf5, 0xab, 0xf7, 0x7e, 0x06, - 0x4b, 0xba, 0x18, 0x10, 0x01, 0xdd, 0x46, 0x07, 0x1e, 0x5b, 0xd4, 0x65, 0x98, 0x6c, 0x38, 0xc1, - 0xb9, 0x51, 0xda, 0x6b, 0xfd, 0xe5, 0x9b, 0x5a, 0xe9, 0xaf, 0xdf, 0xd4, 0x4a, 0xff, 0xfb, 0x4d, - 0xed, 0xca, 0x1f, 0xbe, 0xad, 0x5d, 0xf9, 0xe3, 0xb7, 0xb5, 0xd2, 0x5f, 0xbf, 0xad, 0x5d, 0xf9, - 0xdb, 0xb7, 0xb5, 0x2b, 0x9f, 0xef, 0xa4, 0xfe, 0x30, 0x3f, 0xb0, 0x43, 0xdf, 0xb9, 0xf0, 0x7c, - 0xa7, 0xe7, 0xb8, 0xa2, 0xe0, 0x92, 0xdd, 0xe1, 0x79, 0x6f, 0x77, 0x78, 0xb2, 0xcb, 0x82, 0xcf, - 0x93, 0x69, 0x76, 0x16, 0xf8, 0xf3, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x21, 0xf5, 0x90, 0x5c, - 0xd0, 0x3f, 0x00, 0x00, + // 4419 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5c, 0x49, 0x73, 0xdb, 0x48, + 0x96, 0x36, 0xb5, 0x92, 0x4f, 0x94, 0x04, 0xa5, 0xb5, 0x40, 0xb2, 0x4c, 0xc9, 0x28, 0x57, 0x59, + 0xb6, 0xbb, 0xa4, 0x1a, 0x75, 0x97, 0x7b, 0xab, 0x99, 0x28, 0x8b, 0xb4, 0x6c, 0xda, 0x94, 0x25, + 0x27, 0xe5, 0xa5, 0xab, 0x23, 0x2a, 0x02, 0x22, 0x53, 0x14, 0xda, 0x24, 0xc0, 0x02, 0x40, 0x97, + 0x54, 0x11, 0x7d, 0x9c, 0xcb, 0x1c, 0x26, 0xfa, 0x27, 0xf4, 0x9c, 0xe6, 0x1f, 0x74, 0xc4, 0x1c, + 0xfb, 0x32, 0xd1, 0xc7, 0x3e, 0xcc, 0xa1, 0x4f, 0x33, 0x13, 0x55, 0x3f, 0x64, 0x26, 0x32, 0x91, + 0x09, 0x20, 0x13, 0x09, 0xb0, 0xb6, 0xbe, 0x38, 0x98, 0x2f, 0xdf, 0xfb, 0x32, 0x91, 0xcb, 0xcb, + 0xb7, 0xc9, 0x30, 0xf7, 0xc5, 0x88, 0xf8, 0x57, 0xbb, 0x43, 0xdf, 0x0b, 0x3d, 0x34, 0xcd, 0x1a, + 0x1b, 0xd5, 0x20, 0xb4, 0xc3, 0x51, 0x10, 0x11, 0x37, 0xa0, 0xef, 0x75, 0xde, 0xf2, 0xdf, 0x95, + 0xf0, 0xd2, 0xe5, 0x3f, 0x17, 0x43, 0x67, 0x40, 0x82, 0xd0, 0x1e, 0x0c, 0x05, 0x81, 0x4a, 0x05, + 0x8e, 0x7b, 0xee, 0x09, 0xc1, 0x61, 0xdf, 0x16, 0xdc, 0x1f, 0xf6, 0x9c, 0xf0, 0x62, 0x74, 0xb6, + 0xdb, 0xf1, 0x06, 0x7b, 0x3d, 0xaf, 0xe7, 0xed, 0x31, 0xf2, 0xd9, 0xe8, 0x9c, 0xb5, 0x58, 0x83, + 0xfd, 0xe2, 0xec, 0x5b, 0x3d, 0xcf, 0xeb, 0xf5, 0x49, 0xc2, 0xa5, 0x0c, 0x66, 0xdd, 0x86, 0xea, + 0x0b, 0x3a, 0x57, 0x4c, 0xbe, 0x18, 0x91, 0x20, 0x44, 0xcb, 0x30, 0xcd, 0xda, 0x66, 0x69, 0xbb, + 0xb4, 0x53, 0xc1, 0x51, 0xc3, 0x7a, 0x0e, 0xab, 0xed, 0x0b, 0xef, 0xcb, 0x13, 0xdf, 0xeb, 0x90, + 0x20, 0x68, 0x39, 0x41, 0x28, 0xf8, 0x57, 0x61, 0xe6, 0x94, 0xb8, 0xb6, 0x1b, 0x72, 0x01, 0xde, + 0x42, 0x9b, 0x50, 0x69, 0x5f, 0x05, 0xbc, 0x6b, 0x62, 0xbb, 0xb4, 0x53, 0xc6, 0x09, 0xc1, 0x7a, + 0x0d, 0x4b, 0xed, 0x2b, 0xb7, 0x53, 0xf7, 0x06, 0x03, 0x27, 0x86, 0x3a, 0x80, 0x85, 0x96, 0x1d, + 0x92, 0x20, 0x8c, 0xc8, 0xa7, 0x6d, 0x06, 0x39, 0xb7, 0xbf, 0xbc, 0x9b, 0x4c, 0xfa, 0x54, 0xfc, + 0x3a, 0x98, 0xfa, 0xcb, 0x7f, 0x6f, 0x5d, 0xc3, 0x8a, 0x84, 0xf5, 0x19, 0xa0, 0x34, 0x70, 0x30, + 0xf4, 0xdc, 0x80, 0xa0, 0x06, 0x2c, 0xd6, 0x47, 0xbe, 0x4f, 0xdc, 0xef, 0x02, 0xad, 0x8a, 0x58, + 0x08, 0x8c, 0xc7, 0x24, 0x94, 0xe6, 0x6c, 0xfd, 0x06, 0x96, 0x52, 0xb4, 0x1f, 0x75, 0xb8, 0x3d, + 0x58, 0xa9, 0x7b, 0x3e, 0x69, 0x8c, 0x06, 0xc3, 0xba, 0xe7, 0x9e, 0x3b, 0xbd, 0xd4, 0x92, 0x3f, + 0xec, 0x84, 0x8e, 0xe7, 0x8a, 0x25, 0x8f, 0x5a, 0x96, 0x09, 0xab, 0xaa, 0x40, 0x34, 0x21, 0xeb, + 0x06, 0xac, 0x3f, 0x26, 0xe1, 0x09, 0xdd, 0xf0, 0x8e, 0xd7, 0x7f, 0x45, 0xfc, 0xc0, 0xf1, 0x5c, + 0xf1, 0x09, 0xff, 0x59, 0x82, 0x0d, 0x5d, 0x2f, 0xff, 0x18, 0x13, 0x66, 0x39, 0x89, 0x0d, 0x37, + 0x89, 0x45, 0x13, 0x3d, 0x81, 0xad, 0x46, 0xa3, 0xf5, 0xca, 0x09, 0x9c, 0x33, 0xa7, 0xef, 0x84, + 0x57, 0x74, 0x1a, 0xef, 0x6c, 0x3a, 0x95, 0x13, 0x9f, 0x0c, 0x6d, 0x9f, 0x74, 0xf9, 0xc6, 0x8f, + 0x63, 0x43, 0x0d, 0xb8, 0x99, 0xc3, 0x72, 0x48, 0xdc, 0x0e, 0xe9, 0x9a, 0x93, 0x0c, 0xa7, 0x98, + 0xc9, 0xfa, 0x3d, 0xac, 0xb7, 0xf3, 0xbe, 0xb2, 0xe0, 0x33, 0x0e, 0xa1, 0x96, 0x83, 0x7b, 0x6a, + 0xfb, 0x3d, 0x12, 0x06, 0xe6, 0xc4, 0xf6, 0xe4, 0x4e, 0x05, 0x8f, 0xe1, 0xb2, 0x1e, 0xc0, 0x46, + 0xfb, 0x7b, 0x2c, 0xa3, 0xf5, 0x13, 0x58, 0xc0, 0x23, 0xf7, 0xd4, 0x0e, 0xde, 0x8a, 0xb9, 0x6e, + 0x40, 0x99, 0x36, 0xeb, 0x5e, 0x97, 0x30, 0xe6, 0x69, 0x1c, 0xb7, 0xad, 0xbb, 0xb0, 0x18, 0x73, + 0x73, 0xe8, 0x55, 0x98, 0xc1, 0x24, 0x18, 0xf5, 0xe3, 0x2b, 0x18, 0xb5, 0xe8, 0x79, 0xa0, 0xfb, + 0xea, 0x0c, 0x49, 0xdf, 0x71, 0x49, 0xd3, 0x3d, 0xf7, 0xc4, 0x96, 0xef, 0xc1, 0x5a, 0xa6, 0x87, + 0x83, 0x2d, 0xc3, 0x74, 0xdd, 0x1b, 0xf1, 0xeb, 0x3c, 0x89, 0xa3, 0x86, 0xf5, 0xa7, 0x75, 0x98, + 0x15, 0xb3, 0xdb, 0x84, 0x0a, 0xff, 0xd9, 0x6c, 0x30, 0xae, 0x29, 0x9c, 0x10, 0xd0, 0x2e, 0x54, + 0xea, 0x83, 0xee, 0x11, 0x09, 0x2f, 0xbc, 0x68, 0xfb, 0x17, 0xf6, 0x8d, 0xdd, 0x48, 0x35, 0xc6, + 0x74, 0x9c, 0xb0, 0xa0, 0x9f, 0xcb, 0xfa, 0x87, 0xed, 0xf4, 0xdc, 0xfe, 0x75, 0x2e, 0x92, 0xee, + 0xc2, 0xb2, 0xa2, 0x7a, 0x99, 0xa7, 0x92, 0xcc, 0x29, 0x06, 0x71, 0x93, 0x43, 0xe8, 0x99, 0x70, + 0x9e, 0x3e, 0x6b, 0xc1, 0xf5, 0x87, 0xfd, 0x90, 0xf8, 0x0f, 0x3b, 0x1d, 0xfa, 0xe5, 0x02, 0x73, + 0x9a, 0x61, 0x6e, 0x70, 0x4c, 0x0d, 0x07, 0xd6, 0x89, 0xa1, 0x4f, 0x61, 0xf1, 0x99, 0xd3, 0xef, + 0xd7, 0x3d, 0x57, 0x1c, 0x44, 0x73, 0x86, 0x21, 0xad, 0x72, 0x24, 0xa5, 0x17, 0xab, 0xec, 0xa8, + 0x0e, 0xc6, 0xa9, 0x6f, 0x77, 0x48, 0x7b, 0x68, 0xc7, 0x10, 0xb3, 0x0c, 0x62, 0x8d, 0x43, 0xa8, + 0xdd, 0x38, 0x23, 0x80, 0x9a, 0x80, 0x1e, 0x93, 0xb0, 0xe5, 0x75, 0xde, 0xa6, 0x4e, 0x81, 0x59, + 0x66, 0x30, 0xeb, 0x1c, 0x26, 0xcb, 0x80, 0x35, 0x42, 0xe8, 0x90, 0x29, 0xbc, 0xd3, 0x4b, 0x37, + 0x8d, 0x54, 0x61, 0x48, 0x66, 0x82, 0x24, 0xf7, 0xe3, 0xac, 0x08, 0x5d, 0x67, 0xaa, 0x38, 0xed, + 0xce, 0x45, 0xfa, 0x64, 0x9a, 0x20, 0xad, 0xb3, 0x86, 0x03, 0xeb, 0xc4, 0xd0, 0x2f, 0x00, 0xda, + 0x57, 0x1d, 0x37, 0xd2, 0x9d, 0xe6, 0x9c, 0x34, 0x9d, 0xcc, 0x43, 0x83, 0x53, 0xbc, 0xe8, 0x63, + 0xa8, 0xc4, 0x0a, 0xdc, 0xac, 0x4a, 0x0b, 0xab, 0x2a, 0x7b, 0x9c, 0x70, 0xa2, 0x13, 0xb6, 0xa2, + 0xca, 0x65, 0x37, 0xe7, 0x99, 0xfc, 0x76, 0x22, 0xaf, 0x57, 0x46, 0x58, 0x23, 0x4b, 0x11, 0xb3, + 0xea, 0xc3, 0x5c, 0x90, 0x10, 0xdb, 0xf9, 0x88, 0xd9, 0x2e, 0xd4, 0x80, 0x05, 0xf9, 0x3d, 0x30, + 0x17, 0x19, 0xda, 0xa6, 0xb8, 0x8f, 0xba, 0xd7, 0x05, 0x2b, 0x32, 0x68, 0x0f, 0x66, 0xb9, 0xc2, + 0x31, 0x0d, 0x26, 0xbe, 0xc2, 0xc5, 0x65, 0xa5, 0x85, 0x05, 0x17, 0xfa, 0x0d, 0xac, 0x60, 0x32, + 0xf0, 0xde, 0x11, 0xfa, 0x6f, 0x48, 0xe8, 0x01, 0x3a, 0xb5, 0xcf, 0xfa, 0xc4, 0x5c, 0x62, 0xe2, + 0xef, 0x09, 0x71, 0x1d, 0x8f, 0x00, 0xd3, 0x23, 0xa0, 0x87, 0x30, 0x4f, 0x8f, 0x24, 0x7b, 0xf2, + 0x0f, 0x1c, 0xb7, 0x6b, 0x22, 0x06, 0x79, 0x23, 0x75, 0x84, 0xe3, 0x3e, 0x01, 0x25, 0x4b, 0xa0, + 0xa7, 0x60, 0xbc, 0x74, 0x83, 0xd1, 0x59, 0xd0, 0xf1, 0x9d, 0x33, 0x12, 0x4d, 0xec, 0x3a, 0x43, + 0xa9, 0x71, 0x14, 0xb5, 0x3b, 0xbe, 0x56, 0x6a, 0x47, 0xfa, 0x0c, 0x37, 0xec, 0xd0, 0x16, 0x67, + 0x78, 0x59, 0x7b, 0x86, 0x53, 0x1c, 0x58, 0x27, 0xc6, 0xd1, 0xda, 0xd4, 0xf6, 0x4b, 0xdf, 0x88, + 0x15, 0x15, 0x4d, 0xe5, 0xc0, 0x3a, 0x31, 0xaa, 0x1e, 0xf5, 0xca, 0xdf, 0x5c, 0x95, 0xd4, 0xa3, + 0x9e, 0x09, 0xe7, 0x08, 0x53, 0xd8, 0x23, 0xa7, 0xe7, 0xdb, 0x21, 0xa1, 0x4a, 0xea, 0xd0, 0xf7, + 0x06, 0x02, 0x76, 0x4d, 0x82, 0xd5, 0x33, 0xe1, 0x1c, 0x61, 0x74, 0x0c, 0xcb, 0xa9, 0x9e, 0xd3, + 0x78, 0xae, 0xa6, 0xb4, 0xbf, 0x3a, 0x16, 0xac, 0x15, 0x44, 0x67, 0x60, 0x62, 0xd2, 0xf7, 0xec, + 0xee, 0xc3, 0x51, 0xe8, 0x35, 0xdd, 0x8e, 0x4f, 0x06, 0xd4, 0xb6, 0xa2, 0x6b, 0x6e, 0xae, 0x33, + 0xd0, 0x0f, 0xe2, 0x73, 0xa8, 0x67, 0x13, 0xf8, 0xb9, 0x38, 0x54, 0x35, 0xd7, 0xc3, 0x3e, 0x26, + 0x76, 0x97, 0xf8, 0x62, 0xc2, 0x1b, 0x92, 0x06, 0x51, 0xbb, 0x71, 0x46, 0x00, 0x1d, 0xc1, 0xe2, + 0x63, 0x12, 0x62, 0x32, 0xec, 0x3b, 0x1d, 0x3b, 0x7a, 0x79, 0x6f, 0xa8, 0x1b, 0x94, 0xee, 0xe5, + 0x72, 0xc2, 0x68, 0x54, 0x7a, 0xe9, 0x21, 0xc2, 0x24, 0x20, 0x61, 0x9b, 0x04, 0x29, 0xf5, 0x60, + 0x6e, 0x4a, 0x87, 0x48, 0xc3, 0x81, 0x75, 0x62, 0xa8, 0x05, 0x4b, 0x8f, 0xbd, 0x23, 0xfb, 0x92, + 0xbe, 0x93, 0x81, 0xc0, 0xba, 0x29, 0x2b, 0x7b, 0xb5, 0x9f, 0xcf, 0x2c, 0x2b, 0xc8, 0xd1, 0xc8, + 0xa0, 0xe5, 0x24, 0x3a, 0xd5, 0xac, 0xa9, 0x68, 0x72, 0x7f, 0x0a, 0x4d, 0xee, 0x40, 0x9f, 0xc3, + 0xda, 0xa1, 0xd3, 0x27, 0x6d, 0xe2, 0xbf, 0x73, 0x3a, 0x24, 0xbd, 0x65, 0xe6, 0x96, 0x74, 0x9f, + 0x73, 0xb8, 0x38, 0x72, 0x1e, 0x08, 0x1a, 0xc0, 0xa6, 0xda, 0xf5, 0xe8, 0x9d, 0xd3, 0x89, 0x27, + 0xbe, 0x2d, 0x69, 0xb3, 0x22, 0x56, 0x3e, 0x52, 0x21, 0x1c, 0x7a, 0x09, 0xcb, 0x47, 0x24, 0xb4, + 0xbb, 0x76, 0x68, 0x4b, 0xdf, 0x72, 0x4b, 0xbe, 0x01, 0x1a, 0x16, 0x0e, 0xaf, 0x15, 0x47, 0xc7, + 0x80, 0x1e, 0x7b, 0x8f, 0xeb, 0x27, 0xc4, 0xef, 0x90, 0xc4, 0x9a, 0xb1, 0xe4, 0x97, 0x3f, 0xc3, + 0xc0, 0x21, 0x35, 0xa2, 0xd4, 0x94, 0x38, 0xb4, 0x47, 0xfd, 0xb0, 0xe9, 0xfe, 0x8e, 0x24, 0x8b, + 0xf1, 0x9e, 0x04, 0x98, 0x65, 0xc0, 0x1a, 0x21, 0xf4, 0x5b, 0x58, 0xad, 0x87, 0xfd, 0x23, 0x8f, + 0x29, 0x53, 0xa6, 0xc0, 0x04, 0xdc, 0x6d, 0xe9, 0x06, 0xe8, 0x99, 0xf8, 0x1c, 0x73, 0x20, 0xd0, + 0xe7, 0xb0, 0xfe, 0xda, 0xf3, 0xdf, 0x06, 0x43, 0xbb, 0x43, 0x4e, 0x2f, 0x7c, 0x12, 0x5c, 0x78, + 0x7d, 0xf1, 0x26, 0x98, 0xef, 0x4b, 0xaf, 0x6a, 0x2e, 0x1f, 0xce, 0x87, 0x40, 0x03, 0xa8, 0xd5, + 0xc3, 0xfe, 0x89, 0x4f, 0xce, 0x49, 0xd8, 0xb9, 0x38, 0x76, 0xdb, 0xe2, 0x69, 0x88, 0x07, 0xf9, + 0x80, 0x0d, 0xf2, 0x7e, 0xf2, 0x11, 0x05, 0xcc, 0x78, 0x0c, 0x18, 0xfa, 0x2d, 0x98, 0xcd, 0x76, + 0xfd, 0xa4, 0xe1, 0xdb, 0x8e, 0x5b, 0xf7, 0xdc, 0x60, 0x34, 0x48, 0x74, 0xce, 0x1d, 0x36, 0xd0, + 0x16, 0x1f, 0x28, 0x8f, 0x0d, 0xe7, 0x02, 0xa0, 0x21, 0xdc, 0x6c, 0x76, 0xc8, 0x19, 0xf1, 0x7b, + 0xdc, 0xb0, 0x7a, 0x67, 0xf7, 0x9d, 0xae, 0x1d, 0xc6, 0x87, 0x70, 0x87, 0x8d, 0x70, 0x5b, 0x8c, + 0x50, 0xc4, 0xcb, 0xb7, 0xa5, 0x18, 0x10, 0xf5, 0x60, 0xe3, 0xc8, 0x73, 0x7b, 0x5e, 0xe3, 0xa0, + 0xde, 0x77, 0xd8, 0xe9, 0x0a, 0x1d, 0x3f, 0x1e, 0xee, 0x2e, 0x1b, 0xee, 0x96, 0x38, 0xf3, 0xb9, + 0x8c, 0x7c, 0xac, 0x02, 0x28, 0xeb, 0x10, 0xd6, 0x32, 0x86, 0x3e, 0xf7, 0x74, 0xee, 0x43, 0x99, + 0xab, 0xbb, 0xc0, 0x2c, 0x6d, 0x4f, 0xee, 0xcc, 0xed, 0x2f, 0xee, 0xf2, 0x78, 0x8d, 0x50, 0x83, + 0x31, 0x83, 0xf5, 0xe7, 0x0d, 0x28, 0xc7, 0x92, 0x3f, 0xae, 0x07, 0xb4, 0x0c, 0xd3, 0x8f, 0x7c, + 0xdf, 0xf3, 0x99, 0xeb, 0x53, 0xc5, 0x51, 0x03, 0xbd, 0xc9, 0x9d, 0x38, 0xf7, 0x6f, 0x6a, 0x79, + 0xfe, 0x4d, 0xc4, 0x85, 0x73, 0xbf, 0xfb, 0x18, 0x96, 0x65, 0x57, 0x85, 0xc3, 0x4e, 0x4b, 0x9a, + 0x46, 0xc7, 0x82, 0xb5, 0x82, 0xf4, 0x1d, 0x4c, 0xbc, 0x16, 0x0e, 0x36, 0x23, 0xbd, 0x83, 0x6a, + 0x37, 0xce, 0x08, 0x50, 0xbf, 0x22, 0xe5, 0xb6, 0x70, 0x94, 0x59, 0xe9, 0x71, 0xc8, 0xf4, 0xe3, + 0xac, 0x08, 0xb7, 0xa2, 0x12, 0xaf, 0x85, 0x23, 0x95, 0x55, 0x2b, 0x4a, 0xe5, 0xc0, 0x3a, 0x31, + 0xee, 0x38, 0xc5, 0xae, 0x0b, 0x07, 0xab, 0xa8, 0x8e, 0x93, 0xc2, 0x80, 0x35, 0x42, 0x74, 0xd9, + 0x65, 0xcf, 0x85, 0x83, 0x81, 0x6a, 0xc2, 0x66, 0x58, 0xb0, 0x56, 0x10, 0xfd, 0x92, 0xfa, 0x3c, + 0xc2, 0xb5, 0xe1, 0x3e, 0xcf, 0xba, 0xc6, 0xe7, 0xe1, 0x20, 0x29, 0x66, 0xf4, 0x20, 0xeb, 0xf4, + 0x98, 0x59, 0xa7, 0x87, 0x0b, 0xa6, 0xbc, 0x9e, 0x17, 0x05, 0x5e, 0xcf, 0xad, 0x02, 0xaf, 0x27, + 0xb5, 0x2c, 0xaa, 0x93, 0xf2, 0xa2, 0xc0, 0xed, 0xb9, 0x55, 0xe0, 0xf6, 0x08, 0x48, 0x8d, 0xdf, + 0xf3, 0x28, 0xc7, 0xef, 0xb9, 0x99, 0xe3, 0xf7, 0x70, 0x28, 0xd5, 0xf1, 0xf9, 0x48, 0x75, 0x7c, + 0x56, 0x55, 0xc7, 0x87, 0x0b, 0xc6, 0x9e, 0xcf, 0x67, 0xc5, 0x9e, 0xcf, 0xed, 0x62, 0xcf, 0x87, + 0xa3, 0xe5, 0xb8, 0x3e, 0x07, 0x7a, 0xd7, 0x67, 0x53, 0xef, 0xfa, 0x70, 0x2c, 0xc5, 0xf7, 0x79, + 0x96, 0xeb, 0xfb, 0x6c, 0xe5, 0xfa, 0x3e, 0xe2, 0xc2, 0x66, 0x9c, 0x9f, 0xd4, 0x79, 0x8e, 0xbc, + 0x18, 0x7e, 0x9e, 0x97, 0xb5, 0xe7, 0x39, 0xcd, 0x82, 0xb5, 0x82, 0x1c, 0x30, 0xe5, 0xc8, 0x70, + 0xc0, 0x15, 0x15, 0x30, 0xc3, 0x82, 0xb5, 0x82, 0x54, 0x85, 0xe6, 0x44, 0xb9, 0xb8, 0x0f, 0x54, + 0xcb, 0xf3, 0x81, 0x84, 0x0a, 0xcd, 0x0b, 0x92, 0xbd, 0x81, 0xb5, 0x8c, 0x23, 0xc3, 0x91, 0xd7, + 0x24, 0xe4, 0x1c, 0x2e, 0x9c, 0x27, 0x8e, 0x30, 0xac, 0x28, 0xfe, 0x0c, 0xc7, 0x35, 0xa5, 0xed, + 0xd6, 0xf2, 0x60, 0xbd, 0x28, 0xea, 0x8c, 0xf5, 0x85, 0xee, 0x8c, 0xf5, 0x85, 0xf8, 0x08, 0xf9, + 0xce, 0xd0, 0x21, 0x2c, 0xa5, 0x7c, 0x1b, 0x3e, 0xe9, 0x0d, 0x49, 0xb5, 0x64, 0xfa, 0x71, 0x56, + 0x04, 0x3d, 0xcf, 0xf3, 0x87, 0x6a, 0x79, 0xfe, 0x50, 0x24, 0x98, 0xe7, 0x10, 0x1d, 0xc3, 0xb2, + 0xec, 0xd9, 0xf0, 0xa9, 0x6d, 0x4a, 0xa7, 0x4a, 0xc7, 0x82, 0xb5, 0x82, 0x91, 0x45, 0x9d, 0xb8, + 0x36, 0x1c, 0xee, 0xa6, 0x62, 0x51, 0xab, 0x0c, 0x89, 0x45, 0xad, 0xf6, 0x70, 0xc0, 0xd8, 0xbb, + 0xe1, 0x80, 0x35, 0x15, 0x50, 0x61, 0x48, 0x01, 0x2a, 0x3d, 0xc8, 0x06, 0x33, 0xeb, 0xd4, 0x70, + 0xd8, 0x2d, 0xe9, 0xba, 0xe7, 0xb1, 0x71, 0xf0, 0x5c, 0x18, 0x6a, 0x31, 0xe6, 0x78, 0x33, 0x7c, + 0x9c, 0x6d, 0x49, 0xe3, 0x15, 0xf2, 0x0a, 0x8b, 0xb1, 0x90, 0x09, 0xbd, 0x81, 0x15, 0xc5, 0xc1, + 0xe1, 0x23, 0xdd, 0x92, 0x2f, 0x86, 0x8e, 0x87, 0x8f, 0xa0, 0x07, 0x40, 0x18, 0xae, 0x4b, 0x7e, + 0x0e, 0xc7, 0xb5, 0x64, 0x8b, 0x21, 0xcb, 0xc1, 0x51, 0x75, 0xc2, 0xd4, 0x0a, 0x91, 0x1c, 0x1e, + 0x8e, 0xf9, 0x9e, 0x84, 0xa9, 0xe1, 0xc0, 0x3a, 0x31, 0xea, 0xea, 0x66, 0xbc, 0x1c, 0x8e, 0x78, + 0x5b, 0xba, 0x1b, 0x39, 0x5c, 0xc2, 0xd5, 0xcd, 0xe9, 0x46, 0x36, 0x6c, 0xe8, 0x1c, 0x1d, 0x3e, + 0xc4, 0xfb, 0xd2, 0x5b, 0x9c, 0xcf, 0x88, 0x0b, 0x40, 0xa2, 0x00, 0x8f, 0x1b, 0xe7, 0xbc, 0x62, + 0xf0, 0x0f, 0x94, 0x00, 0x4f, 0x96, 0x05, 0x6b, 0x05, 0xd1, 0x10, 0xb6, 0x72, 0x5d, 0x26, 0x8e, + 0x7d, 0x47, 0x8a, 0xf3, 0x8c, 0xe1, 0xc6, 0xe3, 0xe0, 0xa8, 0x47, 0xa9, 0xf1, 0xa0, 0xf8, 0x58, + 0x3b, 0x92, 0x47, 0x99, 0xcb, 0x87, 0xf3, 0x21, 0x50, 0x00, 0xb5, 0x3c, 0xa7, 0x89, 0x0f, 0x72, + 0x57, 0xf2, 0x28, 0x8b, 0x99, 0xf9, 0x9e, 0x8f, 0x81, 0x44, 0xbf, 0x83, 0x1b, 0x5a, 0xef, 0x89, + 0x8f, 0x78, 0x8f, 0x8d, 0x68, 0x15, 0x79, 0x62, 0xd2, 0x70, 0x45, 0x60, 0x56, 0x53, 0x9b, 0x5a, + 0x61, 0xd9, 0x2e, 0x96, 0x15, 0x6e, 0x76, 0x79, 0xd2, 0x29, 0x6e, 0xa3, 0x55, 0x98, 0x69, 0x33, + 0x97, 0x8c, 0x39, 0x47, 0x15, 0xcc, 0x5b, 0xd6, 0xaf, 0xf4, 0x3e, 0x0c, 0xb2, 0xa0, 0x6a, 0x53, + 0x7a, 0x7b, 0xd4, 0xa1, 0x7e, 0x0f, 0xc3, 0x2b, 0x63, 0x89, 0x66, 0x35, 0x33, 0x39, 0x19, 0xea, + 0xd0, 0x71, 0x24, 0xee, 0xd0, 0x4d, 0xe2, 0x84, 0x90, 0x4e, 0xdd, 0x4d, 0x30, 0x67, 0x2f, 0x95, + 0xba, 0xcb, 0x3a, 0x32, 0x26, 0xcc, 0xca, 0xa3, 0x8b, 0xa6, 0xd5, 0xca, 0xc6, 0x0b, 0x91, 0x01, + 0x93, 0xf5, 0x41, 0x97, 0x27, 0xee, 0xe8, 0x4f, 0x46, 0x39, 0xef, 0xb1, 0x91, 0x28, 0xe5, 0xbc, + 0xc7, 0x1c, 0xc4, 0xcb, 0xd0, 0xb7, 0x63, 0x07, 0x91, 0x36, 0xac, 0x3b, 0x9a, 0x07, 0x17, 0x21, + 0x98, 0xa2, 0xbf, 0x39, 0x1e, 0xfb, 0x6d, 0x7d, 0x32, 0x2e, 0x52, 0x41, 0x77, 0xe0, 0xc4, 0x0e, + 0x43, 0xe2, 0x73, 0x4f, 0xb8, 0x82, 0xe3, 0xb6, 0xf5, 0xf1, 0xd8, 0x7b, 0xa6, 0x1d, 0xf4, 0xbf, + 0x4a, 0xf9, 0x01, 0x8b, 0xec, 0x72, 0xcf, 0x2b, 0xcb, 0xcd, 0x74, 0x54, 0xb3, 0x21, 0x96, 0x9b, + 0x37, 0x69, 0xcf, 0x53, 0xef, 0xec, 0xb9, 0x3d, 0x20, 0xfc, 0x38, 0x88, 0x26, 0x5d, 0xa2, 0xa7, + 0xde, 0x59, 0xb3, 0xc1, 0x7c, 0xe3, 0x29, 0x1c, 0x35, 0xd0, 0x0e, 0x2c, 0x46, 0xc6, 0x34, 0x4b, + 0x10, 0x1f, 0xbb, 0xfd, 0x2b, 0xe6, 0xe4, 0x96, 0xb1, 0x4a, 0x46, 0x1f, 0xc0, 0x02, 0x26, 0x2e, + 0xf9, 0x32, 0x61, 0x9c, 0x61, 0x8c, 0x0a, 0xd5, 0xfa, 0xb8, 0x40, 0x07, 0x14, 0xec, 0xfc, 0x9b, + 0x6c, 0x12, 0x4f, 0xb3, 0xf3, 0xcb, 0x30, 0x4d, 0x19, 0x02, 0xbe, 0xf7, 0x51, 0x83, 0x2e, 0x56, + 0xac, 0x4e, 0xd9, 0x67, 0x4f, 0xe2, 0x84, 0x40, 0x4f, 0x41, 0xd6, 0x07, 0xd6, 0x6d, 0xc8, 0xb2, + 0x2e, 0x05, 0x68, 0xfd, 0xad, 0x04, 0x65, 0x41, 0x4b, 0x16, 0xbe, 0xcb, 0x83, 0x1a, 0xa2, 0x49, + 0x01, 0x9f, 0x91, 0xab, 0x28, 0x11, 0x5e, 0xc5, 0xec, 0x37, 0xba, 0x17, 0x49, 0x1e, 0x79, 0xdd, + 0x68, 0x37, 0x16, 0xf6, 0x17, 0x76, 0x59, 0x81, 0x8b, 0xa0, 0xe2, 0xb8, 0x1f, 0x6d, 0xc3, 0x9c, + 0x13, 0x60, 0xdb, 0xed, 0x31, 0x87, 0x86, 0x6d, 0x52, 0x19, 0xa7, 0x49, 0xe8, 0x0e, 0xcc, 0x3e, + 0xf1, 0xfa, 0x5d, 0xe2, 0x07, 0xe6, 0x34, 0x8b, 0xc5, 0xcc, 0x47, 0x60, 0xaf, 0x6d, 0x87, 0x7a, + 0xd2, 0x58, 0xf4, 0x52, 0x46, 0x4a, 0xa3, 0x8c, 0x33, 0x5a, 0x46, 0xde, 0x6b, 0x7d, 0xae, 0x0d, + 0x04, 0xd0, 0x4f, 0xa9, 0xbb, 0x4d, 0xb1, 0xee, 0xec, 0x37, 0xfa, 0x29, 0x54, 0x05, 0x5f, 0xcb, + 0x09, 0x42, 0xf6, 0x99, 0x73, 0xfb, 0x8b, 0x5c, 0xeb, 0xc5, 0x10, 0x12, 0x93, 0x75, 0x5d, 0x93, + 0x08, 0xb5, 0x2e, 0x60, 0xee, 0xf4, 0xd2, 0xfd, 0x76, 0x2b, 0x8a, 0xbd, 0x2f, 0xe3, 0x15, 0xa5, + 0xbf, 0xd1, 0x7d, 0x98, 0x3d, 0x1e, 0x86, 0x2c, 0x1e, 0x15, 0x65, 0xc1, 0x97, 0x92, 0x05, 0xe5, + 0x1d, 0x58, 0x70, 0x58, 0xff, 0x51, 0x82, 0x59, 0x3e, 0x38, 0xfa, 0x14, 0xca, 0x75, 0x9f, 0xd8, + 0x21, 0x79, 0x18, 0xf2, 0x42, 0x93, 0x8d, 0xdd, 0xa8, 0xee, 0x67, 0x57, 0xd4, 0xfd, 0xa4, 0xca, + 0x4d, 0xca, 0x54, 0x53, 0xff, 0xe1, 0x7f, 0xb6, 0x4a, 0x38, 0x96, 0x42, 0xdb, 0x30, 0x45, 0x8d, + 0x23, 0x76, 0xf2, 0xe6, 0xf6, 0xab, 0xbb, 0xe1, 0xa5, 0xbb, 0x7b, 0x7a, 0xe9, 0x52, 0x1a, 0x66, + 0x3d, 0xf4, 0x53, 0x5e, 0x06, 0xc4, 0x3f, 0xbd, 0x74, 0x79, 0x31, 0x86, 0x68, 0xa2, 0x8f, 0xa0, + 0x42, 0xd7, 0x9c, 0xce, 0x32, 0x30, 0xa7, 0xd8, 0xd2, 0x21, 0x11, 0xb1, 0x49, 0xd6, 0x02, 0x27, + 0x4c, 0xd6, 0x67, 0xba, 0xa8, 0x8a, 0x76, 0x67, 0x3e, 0x62, 0xeb, 0xa9, 0x6c, 0xcc, 0x42, 0x82, + 0xce, 0x00, 0xd2, 0x2c, 0xd6, 0x8a, 0x36, 0xaf, 0x6c, 0xfd, 0x5b, 0x09, 0x2a, 0x31, 0x91, 0x2a, + 0xbc, 0xe7, 0x5e, 0x97, 0x9c, 0x5e, 0x0d, 0x09, 0x1f, 0x2e, 0x6e, 0xd3, 0x27, 0x87, 0xfe, 0x6e, + 0x76, 0xf9, 0x35, 0xe4, 0x2d, 0x7a, 0x0f, 0x19, 0x00, 0x13, 0x8a, 0xd4, 0x4f, 0x42, 0xa0, 0x93, + 0x7f, 0x19, 0x90, 0x2e, 0xd7, 0x3f, 0xec, 0x37, 0xa5, 0x1d, 0xfa, 0x24, 0x0a, 0xac, 0x4d, 0x61, + 0xf6, 0x9b, 0x8e, 0xfc, 0xc4, 0x09, 0xb1, 0x1d, 0x3a, 0x1e, 0x53, 0x31, 0x13, 0x38, 0x6e, 0x5b, + 0xcf, 0xf5, 0x11, 0x22, 0xf4, 0x00, 0xe6, 0x63, 0x22, 0x5b, 0x86, 0x28, 0x5a, 0x19, 0x07, 0x15, + 0x63, 0x01, 0x99, 0xcd, 0xea, 0xc3, 0x66, 0x51, 0x92, 0x95, 0x6e, 0xe9, 0x63, 0xdf, 0x1b, 0x0d, + 0x63, 0x25, 0x2c, 0x9a, 0xc5, 0x2a, 0x58, 0xbc, 0x85, 0x93, 0xf2, 0x5b, 0xf8, 0x31, 0xdc, 0x2c, + 0x0c, 0x6c, 0xc8, 0x95, 0x25, 0xd3, 0xa2, 0xb2, 0xe4, 0x29, 0xfb, 0xe8, 0x4c, 0xda, 0xf6, 0xfb, + 0x4c, 0xce, 0xba, 0x0f, 0x2b, 0xda, 0x38, 0x08, 0xdd, 0x09, 0x16, 0x33, 0xe1, 0x47, 0x8b, 0xfe, + 0xb6, 0xda, 0xb0, 0x96, 0x93, 0xe9, 0x45, 0x35, 0x80, 0x86, 0x1d, 0xda, 0x67, 0x76, 0x40, 0xe2, + 0x00, 0x6f, 0x8a, 0x52, 0x30, 0x83, 0x9f, 0x81, 0x99, 0x17, 0x42, 0x29, 0x78, 0x1e, 0x0e, 0xa1, + 0xcc, 0x76, 0xee, 0x19, 0xb9, 0xa2, 0x53, 0x3d, 0xb1, 0xc3, 0x0b, 0x31, 0x55, 0xfa, 0x9b, 0x1e, + 0xc9, 0xe3, 0xf3, 0xf3, 0x80, 0x44, 0x85, 0x74, 0x93, 0x98, 0xb7, 0xd0, 0x02, 0x4c, 0xb4, 0xbf, + 0xe2, 0x6f, 0xc2, 0x44, 0xfb, 0x2b, 0xeb, 0x01, 0x3f, 0xa2, 0x4c, 0x3f, 0xdf, 0x85, 0xa9, 0xb7, + 0x54, 0x67, 0x97, 0x24, 0x65, 0x26, 0xfa, 0xb9, 0xbd, 0xc6, 0x58, 0xac, 0x53, 0xfa, 0x4e, 0xb2, + 0x4f, 0x8f, 0xa7, 0xb1, 0x0c, 0xd3, 0x4d, 0xb7, 0x4b, 0x2e, 0xc5, 0x66, 0xb1, 0x06, 0xba, 0x9f, + 0x4c, 0x94, 0xab, 0x0a, 0x15, 0x17, 0xc7, 0x0c, 0xd6, 0x6b, 0x6d, 0x76, 0x1c, 0x7d, 0x9a, 0x19, + 0x8c, 0x4f, 0x31, 0x0e, 0xaf, 0xc9, 0xbd, 0x58, 0x65, 0xb7, 0x8e, 0x61, 0x49, 0x2c, 0x6a, 0x8c, + 0x9e, 0x33, 0x61, 0x03, 0x26, 0x9f, 0x38, 0xa2, 0xfe, 0x90, 0xfe, 0xa4, 0xeb, 0x4b, 0xf9, 0xb9, + 0x2d, 0xc5, 0x7e, 0x5b, 0x9f, 0xeb, 0x43, 0x59, 0xe8, 0x50, 0x33, 0x10, 0x9f, 0xac, 0x99, 0x04, + 0x0e, 0xe4, 0x7e, 0x9c, 0x15, 0xb1, 0xb0, 0x36, 0xb3, 0x8f, 0x7e, 0x0d, 0xd5, 0x98, 0x16, 0x2d, + 0x43, 0x14, 0x33, 0x4f, 0xca, 0x3f, 0xd3, 0xdd, 0x58, 0x62, 0xe6, 0xf7, 0x26, 0x1b, 0xf4, 0xda, + 0x87, 0x4a, 0x4c, 0x8c, 0xab, 0x0e, 0x35, 0x88, 0x38, 0x61, 0xb3, 0xda, 0x30, 0xc7, 0x4b, 0xf1, + 0xda, 0xe1, 0x80, 0x2d, 0x11, 0xb3, 0xb1, 0xf8, 0x11, 0x64, 0x06, 0x96, 0x01, 0x93, 0xed, 0x17, + 0x2d, 0x61, 0x95, 0xb6, 0x5f, 0xb4, 0xe8, 0x25, 0x39, 0xb1, 0x7d, 0x7b, 0x40, 0xd5, 0x5f, 0xc0, + 0x97, 0x33, 0x45, 0xb1, 0xfa, 0x79, 0x95, 0x02, 0xf4, 0x38, 0x53, 0x52, 0x7c, 0xb3, 0x79, 0x0b, + 0xfd, 0x2c, 0xae, 0x6b, 0x8c, 0xb2, 0x26, 0x9b, 0xfa, 0x20, 0x5a, 0xc4, 0x23, 0xaa, 0x1e, 0x9f, + 0x4e, 0x95, 0x27, 0x8d, 0x29, 0xeb, 0x9f, 0x67, 0x73, 0x43, 0x72, 0xf4, 0x9a, 0x34, 0x0e, 0xf8, + 0xd7, 0x4c, 0x34, 0x0e, 0xd0, 0x03, 0xa8, 0xa6, 0x3e, 0x37, 0xe0, 0xaf, 0x8a, 0x78, 0xb3, 0x52, + 0x5d, 0x58, 0xe2, 0x43, 0xf7, 0xc0, 0x68, 0xd9, 0x41, 0xf8, 0xf0, 0xfc, 0x9c, 0x74, 0x42, 0xd2, + 0x65, 0xef, 0x77, 0x74, 0xf9, 0x32, 0x74, 0xf4, 0x09, 0x2c, 0xd0, 0xf7, 0xb1, 0x45, 0xde, 0x91, + 0x7e, 0xfa, 0x65, 0x5c, 0x16, 0x81, 0xd6, 0x74, 0x27, 0x56, 0x78, 0x51, 0x03, 0x6e, 0xca, 0x0c, + 0xa4, 0x4f, 0xec, 0x80, 0xb4, 0x47, 0xc3, 0xa1, 0xe7, 0x87, 0xa4, 0xcb, 0xcd, 0xd8, 0x62, 0x26, + 0x74, 0x08, 0x8b, 0x94, 0xa1, 0x41, 0xce, 0x1d, 0x97, 0x74, 0x5f, 0xd9, 0xb1, 0xc9, 0xa4, 0x2c, + 0xac, 0xcc, 0x84, 0x55, 0x21, 0xf4, 0x0b, 0x58, 0x53, 0x48, 0x8f, 0x2e, 0xf9, 0x3c, 0x66, 0xd9, + 0x3c, 0xf2, 0xba, 0xe9, 0x0c, 0xda, 0x57, 0x41, 0x48, 0x06, 0xaf, 0x6c, 0xdf, 0xa1, 0xca, 0x30, + 0x30, 0xcb, 0xba, 0x19, 0xc8, 0x4c, 0x58, 0x15, 0xa2, 0x33, 0x50, 0x48, 0xf1, 0x0c, 0x2a, 0xd1, + 0x0c, 0x72, 0xba, 0xd1, 0x27, 0xb0, 0xae, 0x4c, 0x0e, 0x93, 0x61, 0xdf, 0xbe, 0x62, 0xb1, 0x6f, + 0x60, 0xb2, 0xf9, 0x0c, 0x54, 0x5a, 0x01, 0x4e, 0x49, 0xcf, 0x45, 0xd2, 0xb9, 0x0c, 0xe8, 0x09, + 0x6c, 0x29, 0x9d, 0x6d, 0xd7, 0x1e, 0x06, 0x17, 0x5e, 0x78, 0xea, 0x79, 0x2d, 0xdb, 0xef, 0x11, + 0x96, 0x7b, 0x29, 0xe3, 0x71, 0x6c, 0x14, 0x49, 0x99, 0x64, 0x06, 0x69, 0x3e, 0x42, 0x1a, 0xc3, + 0x86, 0x3e, 0x85, 0x1b, 0xa2, 0xea, 0x96, 0x1e, 0xea, 0x96, 0xe7, 0xf6, 0xa8, 0x8a, 0xaa, 0x5f, + 0x90, 0xce, 0x5b, 0xd2, 0x65, 0x79, 0x97, 0x32, 0x2e, 0x62, 0xa1, 0x76, 0xd0, 0xa1, 0x37, 0x72, + 0xa3, 0xe3, 0xbf, 0x18, 0x25, 0x3f, 0x63, 0x82, 0xf5, 0xc7, 0x69, 0x7d, 0x25, 0x4f, 0xee, 0xa5, + 0x8f, 0x2e, 0xe7, 0x44, 0x7c, 0x39, 0xb7, 0x61, 0xae, 0x4d, 0xc2, 0x57, 0xb6, 0x1f, 0xdd, 0xcd, + 0x49, 0xe6, 0x8e, 0xa6, 0x49, 0x99, 0xeb, 0x3b, 0xf5, 0x03, 0xae, 0xef, 0xf4, 0xb7, 0xbe, 0xbe, + 0x33, 0xdf, 0xe1, 0xfa, 0x6a, 0x2e, 0xde, 0xec, 0x8f, 0x7c, 0xf1, 0xca, 0xdf, 0xf9, 0xe2, 0x55, + 0x7e, 0xe4, 0x8b, 0x07, 0x3f, 0xe0, 0xe2, 0xcd, 0xfd, 0xa0, 0x8b, 0x57, 0x1d, 0x77, 0xf1, 0xa4, + 0x23, 0x3a, 0xaf, 0x1e, 0xd1, 0x3f, 0x97, 0xe2, 0x1c, 0x8b, 0x3c, 0x01, 0xed, 0xc3, 0xb7, 0x0d, + 0xd3, 0xaf, 0xec, 0xfe, 0x88, 0x70, 0x7b, 0x07, 0x76, 0xd9, 0xdf, 0x62, 0x3c, 0xba, 0x1c, 0xfa, + 0x38, 0xea, 0x60, 0x4f, 0xe3, 0x17, 0x7d, 0xee, 0x12, 0xd0, 0x9f, 0xcc, 0x16, 0x09, 0x0e, 0x1c, + 0x97, 0x3b, 0xba, 0x51, 0x83, 0x9e, 0x3f, 0x7e, 0x1e, 0xd9, 0x2b, 0xf9, 0x8c, 0x1a, 0xa4, 0xd3, + 0xec, 0x2e, 0x64, 0xe8, 0xa8, 0x06, 0x53, 0xcc, 0xcf, 0x98, 0x49, 0x0f, 0x4a, 0x29, 0x98, 0xd1, + 0xad, 0x17, 0x30, 0x2f, 0x9d, 0x39, 0xed, 0xd4, 0x63, 0x83, 0x3b, 0x32, 0x52, 0xa3, 0x06, 0xfb, + 0x83, 0x8d, 0x4b, 0xb7, 0xd9, 0x88, 0xee, 0x56, 0x15, 0xf3, 0x96, 0xf5, 0x0f, 0x39, 0x99, 0xa7, + 0x02, 0xbb, 0xf5, 0xd7, 0xb0, 0x35, 0xa6, 0x7a, 0x2e, 0x6d, 0x2a, 0x97, 0x64, 0x53, 0xd9, 0x82, + 0xed, 0x71, 0xe9, 0x26, 0x6b, 0x87, 0x15, 0x31, 0x6a, 0xca, 0xdf, 0xa8, 0xda, 0xa8, 0x3f, 0x17, + 0x6f, 0x7a, 0xfd, 0x39, 0xaf, 0x68, 0xd7, 0x25, 0x86, 0x72, 0x2a, 0xda, 0x3f, 0xd4, 0x16, 0xca, + 0xe5, 0xa9, 0x29, 0xeb, 0x44, 0x9f, 0x46, 0xca, 0x5f, 0x1c, 0x6a, 0x1f, 0x3d, 0x1c, 0x85, 0x17, + 0xed, 0xd0, 0x77, 0xdc, 0x28, 0x9c, 0x57, 0xc5, 0x29, 0x8a, 0xb5, 0xa7, 0xa9, 0xad, 0xa3, 0xee, + 0xa1, 0x20, 0x89, 0xca, 0x7f, 0xd1, 0xb6, 0x3e, 0xd2, 0x25, 0x9e, 0x0a, 0x25, 0x7e, 0xa9, 0x29, + 0xb8, 0x43, 0xb7, 0x61, 0x5e, 0x90, 0x0e, 0xae, 0x42, 0x12, 0xf0, 0x65, 0x91, 0x89, 0xd6, 0xaf, + 0x74, 0x49, 0xa9, 0x6f, 0x29, 0x7b, 0x91, 0x5b, 0x99, 0x87, 0xf6, 0xf8, 0xb9, 0x2e, 0x31, 0x03, + 0xef, 0x46, 0x4e, 0x7a, 0x28, 0x39, 0xe8, 0xb1, 0xd7, 0xdd, 0x76, 0xbe, 0x22, 0xdc, 0xfb, 0x49, + 0x08, 0xd6, 0x65, 0x7e, 0xa6, 0x4b, 0x96, 0x2c, 0x29, 0x92, 0xf4, 0x4b, 0x58, 0xa3, 0x6e, 0x0f, + 0xed, 0x8e, 0x13, 0x5e, 0x71, 0x6c, 0x99, 0x48, 0x77, 0xf7, 0x88, 0x04, 0x81, 0xdd, 0x8b, 0x03, + 0x8e, 0xbc, 0x69, 0x1d, 0x17, 0x57, 0x07, 0x7e, 0xe7, 0x0f, 0xb5, 0x7e, 0x3f, 0x26, 0xa3, 0xf6, + 0x77, 0xfe, 0x9e, 0x9f, 0xe9, 0xcb, 0x0f, 0x8b, 0x47, 0xb5, 0xfe, 0x31, 0x27, 0x29, 0x97, 0x9d, + 0x4e, 0x49, 0x33, 0x1d, 0xeb, 0xff, 0x4a, 0x63, 0x0a, 0xcf, 0xc6, 0x44, 0x8a, 0xd9, 0xe4, 0x42, + 0xbb, 0xef, 0xf5, 0x62, 0x4f, 0x3c, 0x21, 0xd0, 0x5e, 0xaa, 0x06, 0x59, 0x42, 0x4a, 0x04, 0x6c, + 0x62, 0x02, 0xd5, 0x0a, 0x51, 0x01, 0xc4, 0x54, 0x14, 0x6c, 0x8d, 0x8a, 0x1a, 0x6a, 0x00, 0xc2, + 0x64, 0x6a, 0x36, 0xb8, 0x75, 0x90, 0xa2, 0xa0, 0xfd, 0x64, 0x99, 0x5a, 0x5e, 0x87, 0xfd, 0xf9, + 0xcf, 0x13, 0x3b, 0xb8, 0x60, 0x7a, 0xba, 0x82, 0xb5, 0x7d, 0xf4, 0x86, 0x46, 0xe5, 0x33, 0xcd, + 0x06, 0xb3, 0x97, 0x2b, 0x38, 0x6e, 0x5b, 0x4f, 0xc6, 0xe5, 0x7c, 0xa2, 0xc8, 0xf4, 0xc0, 0x7b, + 0x47, 0xba, 0x8f, 0xdc, 0xd0, 0x77, 0xe2, 0x3b, 0xa7, 0x50, 0xad, 0x5d, 0x5d, 0xa1, 0x27, 0xdd, + 0x70, 0x4e, 0xe1, 0xca, 0x41, 0x34, 0xad, 0x3d, 0x6d, 0xd6, 0xb3, 0x40, 0xa0, 0xa5, 0x2b, 0xfc, + 0xa4, 0xfa, 0x92, 0x57, 0xba, 0xf1, 0xbf, 0x3d, 0xe2, 0x45, 0x6d, 0xc2, 0x3b, 0x24, 0x2c, 0x52, + 0x1b, 0x99, 0x77, 0x29, 0x8a, 0x75, 0x57, 0x9b, 0x20, 0xd5, 0x46, 0xae, 0xef, 0xe5, 0x95, 0x89, + 0x66, 0x43, 0xe8, 0xd6, 0x87, 0xb9, 0x99, 0x52, 0x2d, 0xf4, 0xa0, 0xa0, 0x48, 0x14, 0xed, 0xc0, + 0x22, 0xff, 0x5b, 0xbc, 0x38, 0xfc, 0x1e, 0x3d, 0x61, 0x2a, 0x99, 0xee, 0xd1, 0x6b, 0xdf, 0x09, + 0x13, 0x08, 0x7e, 0x18, 0x15, 0xaa, 0xe5, 0x16, 0xe5, 0x59, 0xff, 0x0e, 0xe3, 0xbd, 0xd2, 0x27, + 0x5d, 0xd1, 0x3f, 0x41, 0x35, 0x4d, 0xff, 0x16, 0x7f, 0x9c, 0x28, 0xf1, 0x5b, 0xff, 0x52, 0x2a, + 0x2a, 0xdf, 0x1c, 0x73, 0x69, 0x2d, 0xa8, 0xd2, 0x37, 0x95, 0x30, 0xef, 0x3d, 0xbe, 0xb7, 0x12, + 0x8d, 0x9a, 0x4a, 0x3c, 0xac, 0xf8, 0xe8, 0xb2, 0xd3, 0x1f, 0x05, 0xce, 0x3b, 0xc2, 0xc3, 0x8d, + 0x19, 0xba, 0xf5, 0xf3, 0xc2, 0x0c, 0x66, 0x81, 0xf5, 0xf2, 0xef, 0x89, 0x1d, 0x28, 0x9b, 0x92, + 0xdf, 0xd3, 0x0e, 0xdc, 0x81, 0xc5, 0xe7, 0xe4, 0x32, 0x3c, 0xf5, 0x6d, 0x37, 0xb0, 0xa3, 0x38, + 0x46, 0x14, 0x29, 0x57, 0xc9, 0x68, 0x17, 0xaa, 0x78, 0xe4, 0xd2, 0xd5, 0x8e, 0x20, 0xa7, 0x32, + 0x90, 0x52, 0xff, 0xbd, 0x3f, 0xcd, 0xa4, 0x4a, 0x4a, 0x51, 0x85, 0xff, 0x85, 0xae, 0x71, 0x0d, + 0x5d, 0x87, 0x45, 0xa5, 0xca, 0xd3, 0x28, 0x21, 0x03, 0xaa, 0xe9, 0xdc, 0xa8, 0x31, 0x81, 0xaa, + 0x50, 0x16, 0x69, 0x4a, 0x63, 0x12, 0xcd, 0x43, 0x25, 0x4e, 0x19, 0x19, 0x53, 0x68, 0x11, 0xe6, + 0x52, 0x79, 0x12, 0x63, 0x1a, 0x2d, 0x00, 0x24, 0xd1, 0x79, 0x63, 0x86, 0xe2, 0xa5, 0xc3, 0xd2, + 0xc6, 0x2c, 0xe5, 0x48, 0x8a, 0x09, 0x8d, 0x32, 0x45, 0x8c, 0x6b, 0x04, 0x8d, 0x0a, 0x5a, 0xd5, + 0x55, 0x09, 0x1a, 0x40, 0xe9, 0xd9, 0x6a, 0x3d, 0x63, 0x0e, 0x21, 0xb5, 0x5e, 0xcf, 0xa8, 0xa2, + 0xb9, 0xb8, 0xf8, 0xce, 0x98, 0x47, 0xeb, 0x39, 0x75, 0x75, 0xc6, 0x02, 0x5a, 0x52, 0xca, 0xe2, + 0x8c, 0x45, 0xb4, 0x9c, 0xad, 0x72, 0x33, 0x8c, 0xf4, 0x57, 0x50, 0x6f, 0xd6, 0x58, 0xe2, 0x94, + 0x38, 0x0a, 0x66, 0x20, 0xba, 0x9c, 0x4a, 0xc5, 0x97, 0x71, 0x9d, 0x12, 0x95, 0xc0, 0x92, 0xb1, + 0x4c, 0x87, 0x95, 0x8c, 0x65, 0x63, 0x05, 0x6d, 0xe6, 0x57, 0x59, 0x19, 0xab, 0x74, 0x89, 0xe2, + 0x6c, 0xad, 0xb1, 0xc6, 0x47, 0x4a, 0x9b, 0xab, 0x86, 0x49, 0x27, 0x94, 0xb6, 0x31, 0x8d, 0x75, + 0xb6, 0x15, 0xc7, 0x47, 0x0f, 0xdf, 0x9c, 0xe0, 0xe3, 0x7a, 0xdb, 0xd8, 0xe0, 0xed, 0x47, 0x47, + 0xad, 0xe6, 0x51, 0xf3, 0xd4, 0xb8, 0x41, 0x3f, 0x55, 0x35, 0x1a, 0x8c, 0x4d, 0xba, 0x5c, 0x5a, + 0x53, 0xc2, 0xb8, 0xc9, 0xe6, 0x9d, 0x7e, 0xb0, 0x8d, 0x1a, 0xdb, 0xff, 0xe3, 0xf8, 0x21, 0x30, + 0xb6, 0x28, 0x21, 0xa5, 0x9a, 0x8d, 0x6d, 0x3a, 0x59, 0x45, 0xa9, 0x1a, 0xb7, 0xe8, 0x66, 0x66, + 0x75, 0x99, 0x61, 0xd1, 0x8f, 0x48, 0xeb, 0x0a, 0xe3, 0x3d, 0x74, 0x83, 0xe9, 0x64, 0x5d, 0x06, + 0xd9, 0xb8, 0x8d, 0x56, 0x60, 0x29, 0x93, 0x50, 0x35, 0xde, 0x47, 0x1b, 0xb0, 0xaa, 0x7f, 0x17, + 0x8d, 0x0f, 0xd0, 0x1a, 0x5c, 0xd7, 0x5c, 0x78, 0xe3, 0x0e, 0x1d, 0x3a, 0x39, 0x96, 0xaf, 0xf6, + 0x8d, 0x9d, 0x7b, 0xff, 0x5a, 0x92, 0x9c, 0x9a, 0x24, 0x7a, 0x48, 0xd7, 0x48, 0xe9, 0x88, 0x3c, + 0x57, 0xe3, 0x1a, 0xba, 0x0f, 0x77, 0x94, 0xae, 0xf6, 0x5b, 0x67, 0xa8, 0x0b, 0xb5, 0x19, 0x25, + 0xf4, 0x21, 0xdc, 0x55, 0x71, 0x5c, 0xba, 0x4c, 0x5a, 0xf6, 0x89, 0x7b, 0x3f, 0x81, 0x65, 0x9d, + 0x0d, 0x88, 0x80, 0x3e, 0xa3, 0x03, 0x8f, 0x5d, 0xea, 0x32, 0x4c, 0x35, 0x9c, 0xe0, 0xad, 0x51, + 0x3a, 0x68, 0xfd, 0xe5, 0xeb, 0x5a, 0xe9, 0xaf, 0x5f, 0xd7, 0x4a, 0xff, 0xfb, 0x75, 0xed, 0xda, + 0x1f, 0xbe, 0xa9, 0x5d, 0xfb, 0xe3, 0x37, 0xb5, 0xd2, 0x5f, 0xbf, 0xa9, 0x5d, 0xfb, 0xdb, 0x37, + 0xb5, 0x6b, 0x9f, 0xed, 0xa6, 0xfe, 0x27, 0x80, 0x81, 0x1d, 0xfa, 0xce, 0xa5, 0xe7, 0x3b, 0x3d, + 0xc7, 0x15, 0x0d, 0x97, 0xec, 0x0d, 0xdf, 0xf6, 0xf6, 0x86, 0x67, 0x7b, 0xcc, 0xf8, 0x3c, 0x9b, + 0x61, 0xb9, 0xc0, 0x9f, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x45, 0x69, 0x3f, 0x5d, 0xa9, + 0x40, 0x00, 0x00, } func (m *QueryRequest) Marshal() (dAtA []byte, err error) { @@ -6436,6 +6470,26 @@ func (m *GetProtocolVersionResponse) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if m.DDLVisibilityActivationFenced { + i-- + if m.DDLVisibilityActivationFenced { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if m.DDLVisibilityActivationPrepared { + i-- + if m.DDLVisibilityActivationPrepared { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } if m.Version != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.Version)) i-- @@ -6464,6 +6518,15 @@ func (m *SetProtocolVersionRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l + if len(m.DDLVisibilityActivationTargets) > 0 { + for iNdEx := len(m.DDLVisibilityActivationTargets) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.DDLVisibilityActivationTargets[iNdEx]) + copy(dAtA[i:], m.DDLVisibilityActivationTargets[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.DDLVisibilityActivationTargets[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } if m.Version != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.Version)) i-- @@ -10787,6 +10850,12 @@ func (m *GetProtocolVersionResponse) ProtoSize() (n int) { if m.Version != 0 { n += 1 + sovQuery(uint64(m.Version)) } + if m.DDLVisibilityActivationPrepared { + n += 2 + } + if m.DDLVisibilityActivationFenced { + n += 2 + } return n } @@ -10799,6 +10868,12 @@ func (m *SetProtocolVersionRequest) ProtoSize() (n int) { if m.Version != 0 { n += 1 + sovQuery(uint64(m.Version)) } + if len(m.DDLVisibilityActivationTargets) > 0 { + for _, s := range m.DDLVisibilityActivationTargets { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } return n } @@ -13156,6 +13231,46 @@ func (m *GetProtocolVersionResponse) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationPrepared", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityActivationPrepared = bool(v != 0) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationFenced", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityActivationFenced = bool(v != 0) default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -13225,6 +13340,38 @@ func (m *SetProtocolVersionRequest) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationTargets", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DDLVisibilityActivationTargets = append(m.DDLVisibilityActivationTargets, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version.go b/pkg/sql/plan/function/ctl/cmd_rpc_version.go index 8435d14ff995d..f51a7737c261b 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version.go @@ -16,6 +16,7 @@ package ctl import ( "context" + "errors" "fmt" "strconv" "strings" @@ -23,6 +24,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/clusterservice" "github.com/matrixorigin/matrixone/pkg/common/moerr" + "github.com/matrixorigin/matrixone/pkg/defines" "github.com/matrixorigin/matrixone/pkg/pb/metadata" querypb "github.com/matrixorigin/matrixone/pkg/pb/query" qclient "github.com/matrixorigin/matrixone/pkg/queryservice/client" @@ -111,18 +113,85 @@ func handleSetProtocolVersion(proc *process.Process, } if service == cn && targets != nil { - versions := make([]string, 0, len(targets)) - for _, target := range targets { - resp, err := transferToCN(qt, target, version) - if err != nil { - return Result{}, err + if version >= defines.MORPCVersion35 { + const maxDDLVisibilityActivationTargets = 1024 + if len(targets) == 0 || len(targets) > maxDDLVisibilityActivationTargets { + return Result{}, moerr.NewInternalErrorNoCtxf( + "DDL visibility activation target count must be between 1 and %d", + maxDDLVisibilityActivationTargets) } - if resp == nil { - return Result{}, moerr.NewInternalErrorNoCtx("no such cn service") + seen := make(map[string]struct{}, len(targets)) + for _, target := range targets { + if target == "" { + return Result{}, moerr.NewInternalErrorNoCtx("DDL visibility activation target is empty") + } + if _, ok := seen[target]; ok { + return Result{}, moerr.NewInternalErrorNoCtxf( + "DDL visibility activation target %s is duplicated", target) + } + seen[target] = struct{}{} } - versions = append(versions, fmt.Sprintf("%s:%d", target, resp.SetProtocolVersion.Version)) + } + if version < defines.MORPCVersion35 { + versions := make([]string, 0, len(targets)) + for _, target := range targets { + resp, sendErr := transferToCN(qt, target, version, nil) + if sendErr != nil { + return Result{}, sendErr + } + if resp == nil || resp.SetProtocolVersion == nil { + if resp != nil { + qt.Release(resp) + } + return Result{}, moerr.NewInternalErrorNoCtx("no such cn service") + } + versions = append(versions, fmt.Sprintf("%s:%d", target, resp.SetProtocolVersion.Version)) + qt.Release(resp) + } + return Result{Method: SetProtocolVersionMethod, Data: strings.Join(versions, ", ")}, nil + } + + // Live v35 activation is a distributed barrier. Dispatch every target + // concurrently so each CN can block local DDL producers before any CN + // waits for the complete Prepared set. + type targetResult struct { + index int + resp *querypb.Response + err error + } + results := make(chan targetResult, len(targets)) + for i, target := range targets { + go func(index int, serviceID string) { + resp, sendErr := transferToCN(qt, serviceID, version, targets) + results <- targetResult{index: index, resp: resp, err: sendErr} + }(i, target) } + versions := make([]string, len(targets)) + var resultErr error + for range targets { + result := <-results + if result.err != nil { + if result.resp != nil { + qt.Release(result.resp) + } + resultErr = errors.Join(resultErr, result.err) + continue + } + if result.resp == nil || result.resp.SetProtocolVersion == nil { + if result.resp != nil { + qt.Release(result.resp) + } + resultErr = errors.Join(resultErr, moerr.NewInternalErrorNoCtx("no such cn service")) + continue + } + versions[result.index] = fmt.Sprintf( + "%s:%d", targets[result.index], result.resp.SetProtocolVersion.Version) + qt.Release(result.resp) + } + if resultErr != nil { + return Result{}, resultErr + } return Result{ Method: SetProtocolVersionMethod, Data: strings.Join(versions, ", "), @@ -187,13 +256,19 @@ func transferToTN(qt qclient.QueryClient, version int64) (Result, error) { }, nil } -func transferToCN(qt qclient.QueryClient, target string, version int64) (resp *querypb.Response, err error) { +func transferToCN( + qt qclient.QueryClient, + target string, + version int64, + activationTargets []string, +) (resp *querypb.Response, err error) { clusterservice.GetMOCluster(qt.ServiceID()).GetCNService( clusterservice.NewServiceIDSelector(target), func(cn metadata.CNService) bool { req := qt.NewRequest(querypb.CmdMethod_SetProtocolVersion) req.SetProtocolVersion = &querypb.SetProtocolVersionRequest{ - Version: version, + Version: version, + DDLVisibilityActivationTargets: append([]string(nil), activationTargets...), } // Live protocol activation may withdraw CN ingress and wait for a // bounded logtail frontier fence before acknowledging the transition. diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go index c908e0fb1d648..2a8a673b241d5 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go @@ -17,6 +17,9 @@ package ctl import ( "context" "fmt" + "strings" + "sync" + "sync/atomic" "testing" "time" @@ -144,16 +147,90 @@ type addressRecordingQueryClient struct { testQClient address string deadline time.Time + request *query.Request } func (c *addressRecordingQueryClient) SendMessage( - ctx context.Context, address string, _ *query.Request, + ctx context.Context, address string, req *query.Request, ) (*query.Response, error) { c.address = address c.deadline, _ = ctx.Deadline() + c.request = req return nil, moerr.NewInternalErrorNoCtx("send error") } +type concurrentProtocolQueryClient struct { + testQClient + started atomic.Int32 + both chan struct{} + mu sync.Mutex + requests [][]string + releases atomic.Int32 +} + +func (c *concurrentProtocolQueryClient) SendMessage( + _ context.Context, + _ string, + req *query.Request, +) (*query.Response, error) { + c.mu.Lock() + c.requests = append(c.requests, + append([]string(nil), req.SetProtocolVersion.DDLVisibilityActivationTargets...)) + c.mu.Unlock() + if c.started.Add(1) == 2 { + close(c.both) + } + <-c.both + return &query.Response{SetProtocolVersion: &query.SetProtocolVersionResponse{ + Version: req.SetProtocolVersion.Version, + }}, nil +} + +func (c *concurrentProtocolQueryClient) NewRequest(method query.CmdMethod) *query.Request { + return &query.Request{CmdMethod: method} +} + +func (c *concurrentProtocolQueryClient) Release(*query.Response) { c.releases.Add(1) } + +func TestHandleSetProtocolVersionDispatchesCompleteTargetSetConcurrently(t *testing.T) { + targets := []string{"activation-cn-1", "activation-cn-2"} + rt := runtime.DefaultRuntime() + runtime.SetupServiceBasedRuntime("", rt) + mc := clusterservice.NewMOCluster( + "", + nil, + 3*time.Second, + clusterservice.WithDisableRefresh(), + clusterservice.WithServices( + []metadata.CNService{ + {ServiceID: targets[0], QueryAddress: "cn-1:6001", WorkState: metadata.WorkState_Working}, + {ServiceID: targets[1], QueryAddress: "cn-2:6001", WorkState: metadata.WorkState_Working}, + }, + nil, + ), + ) + defer mc.Close() + rt.SetGlobalVariables(runtime.ClusterService, mc) + qcli := &concurrentProtocolQueryClient{both: make(chan struct{})} + proc := &process.Process{Base: &process.BaseProcess{QueryClient: qcli}} + + result, err := handleSetProtocolVersion( + proc, cn, strings.Join(targets, ",")+":35", nil) + require.NoError(t, err) + require.Equal(t, "activation-cn-1:35, activation-cn-2:35", result.Data) + require.Equal(t, int32(2), qcli.started.Load()) + require.Equal(t, int32(2), qcli.releases.Load()) + qcli.mu.Lock() + defer qcli.mu.Unlock() + require.Len(t, qcli.requests, 2) + for _, requestTargets := range qcli.requests { + require.Equal(t, targets, requestTargets) + } + + _, err = handleSetProtocolVersion(proc, cn, "activation-cn-1,activation-cn-1:35", nil) + require.ErrorContains(t, err, "duplicated") +} + func TestTransferToCNAllowsActivationFence(t *testing.T) { const serviceID = "activation-cn" rt := runtime.DefaultRuntime() @@ -176,9 +253,11 @@ func TestTransferToCNAllowsActivationFence(t *testing.T) { qcli := &addressRecordingQueryClient{} started := time.Now() - _, err := transferToCN(qcli, serviceID, defines.MORPCVersion35) + _, err := transferToCN(qcli, serviceID, defines.MORPCVersion35, []string{serviceID}) require.Error(t, err) require.Equal(t, "activation-cn:6001", qcli.address) + require.Equal(t, []string{serviceID}, + qcli.request.SetProtocolVersion.DDLVisibilityActivationTargets) require.WithinDuration(t, started.Add(time.Minute), qcli.deadline, time.Second) } diff --git a/proto/logservice.proto b/proto/logservice.proto index 35e34933ddd74..411bae8feb362 100644 --- a/proto/logservice.proto +++ b/proto/logservice.proto @@ -64,6 +64,8 @@ message CNStore { // DDLVisibilityBarrierReady means QueryService can accept the versioned DDL // visibility fence even when public SQL ingress is not admitted yet. bool DDLVisibilityBarrierReady = 21; + // ViewMetadataIngressReady is retained for raw control-plane inventory. + bool ViewMetadataIngressReady = 22; } message TNStore { diff --git a/proto/metadata.proto b/proto/metadata.proto index 1c435c5929aab..3dba3b0932783 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -142,6 +142,9 @@ message CNService { // DDLVisibilityBarrierReady is published after QueryService is listening. // A CN is not publicly routable until its startup DDL frontier fence completes. bool DDLVisibilityBarrierReady = 16; + // ViewMetadataIngressReady is retained in raw control-plane inventory so + // protocol activation can verify withdrawal/publication without routing it. + bool ViewMetadataIngressReady = 17; } // TNService tn service metadata diff --git a/proto/query.proto b/proto/query.proto index 26e040bc4e4a2..c91d60e944141 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -164,11 +164,20 @@ message GetProtocolVersionRequest { message GetProtocolVersionResponse { // ProtocolVersion is the version of the protocol int64 Version = 1; + // DDLVisibilityActivationPrepared means this CN has blocked and drained DDL + // producers before exposing the v35 sender capability. + bool DDLVisibilityActivationPrepared = 2; + // DDLVisibilityActivationFenced means this CN applied the converged peer + // frontier while every participant's DDL producers were blocked. + bool DDLVisibilityActivationFenced = 3; } message SetProtocolVersionRequest { // ProtocolVersion is the version of the protocol int64 Version = 1; + // DDLVisibilityActivationTargets is the complete CN set participating in a + // coordinated live activation. It is empty for ordinary version updates. + repeated string DDLVisibilityActivationTargets = 2; } message SetProtocolVersionResponse { From 6b1e4973834a2d4a4ebe6b654eb21260e12dd082 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Fri, 28 Aug 2026 15:52:29 +0800 Subject: [PATCH 07/34] fix: order activation readiness publication --- pkg/cnservice/server_ddl_visibility.go | 9 +- pkg/cnservice/server_ddl_visibility_test.go | 114 ++++++++++++++++++++ pkg/cnservice/server_heartbeat.go | 5 + pkg/cnservice/types.go | 1 + 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index fadfe0a5df26e..8ebb07c737d7e 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -190,6 +190,12 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets barrierCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) defer cancel() + if !pending { + // A command can arrive after startup fencing but before public listeners + // are started. Restore only the ingress state observed by the first + // activation attempt; retries after a fail-closed withdrawal retain it. + s.ddlVisibilityRestoreIngress.Store(s.viewMetadataIngressReady.Load()) + } s.ddlVisibilityActivationPending.Store(true) s.ddlVisibilityActivationPrepared.Store(false) s.ddlVisibilityActivationFenced.Store(false) @@ -219,7 +225,8 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets if s.ddlVisibilityBarrierClosing.Load() || s.viewMetadataGenerationRevoked.Load() { return moerr.NewServiceUnavailableNoCtx("CN is closing") } - if err := s.setDDLVisibilityIngressLocked(barrierCtx, true); err != nil { + if err := s.setDDLVisibilityIngressLocked( + barrierCtx, s.ddlVisibilityRestoreIngress.Load()); err != nil { cleanupCtx, cleanupCancel := s.newDDLVisibilityBarrierContext(context.Background()) cleanupErr := s.setDDLVisibilityIngressLocked(cleanupCtx, false) cleanupCancel() diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index b3d225886e54f..48888f4055c54 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -17,6 +17,7 @@ package cnservice import ( "context" "errors" + "sync" "sync/atomic" "testing" "time" @@ -190,6 +191,33 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) Close() error { return nil } +type ddlVisibilityHeartbeatOrderClient struct { + logservice.CNHAKeeperClient + mu sync.Mutex + calls int + firstStarted chan struct{} + releaseFirst chan struct{} + completed []logservicepb.CNStoreHeartbeat +} + +func (c *ddlVisibilityHeartbeatOrderClient) SendCNHeartbeat( + _ context.Context, + hb logservicepb.CNStoreHeartbeat, +) (logservicepb.CommandBatch, error) { + c.mu.Lock() + c.calls++ + call := c.calls + c.mu.Unlock() + if call == 1 { + close(c.firstStarted) + <-c.releaseFirst + } + c.mu.Lock() + c.completed = append(c.completed, hb) + c.mu.Unlock() + return logservicepb.CommandBatch{}, errors.New("stop heartbeat after ordering observation") +} + type ddlVisibilityCloseLockService struct { lockservice.LockService closeCalls int @@ -454,6 +482,50 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { require.Len(t, queryClient.requests, 5) } +func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { + const serviceID = "ddl-visibility-pre-start-ingress-test" + const generation = uint64(7) + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion34) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + }}} + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, frontiers: map[string]timestamp.Timestamp{"self:6001": {}}, + } + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + hakeeperClient := &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster} + s := &service{ + cfg: cfg, _hakeeperClient: hakeeperClient, moCluster: cluster, + queryClient: queryClient, _txnClient: mock_frontend.NewMockTxnClient(gomock.NewController(t)), + config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: frontend.NewDDLCommitGate(), + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(false) + + resp := &query.Response{} + require.NoError(t, s.handleSetProtocolVersion(context.Background(), &query.Request{ + SetProtocolVersion: &query.SetProtocolVersionRequest{ + Version: defines.MORPCVersion35, DDLVisibilityActivationTargets: []string{serviceID}, + }, + }, resp, nil)) + require.Equal(t, defines.MORPCVersion35, resp.SetProtocolVersion.Version) + require.False(t, s.viewMetadataIngressReady.Load()) + require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) + require.Len(t, hakeeperClient.heartbeats, 2) + require.False(t, hakeeperClient.heartbeats[0].ViewMetadataIngressReady) + require.False(t, hakeeperClient.heartbeats[1].ViewMetadataIngressReady) + release, err := s.ddlCommitGate.Enter(context.Background()) + require.NoError(t, err) + release() +} + func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T) { const serviceID = "ddl-visibility-live-activation-failure-test" const generation = uint64(7) @@ -798,6 +870,48 @@ func TestWaitForDDLVisibilityBarrierPublicationHonorsCancellation(t *testing.T) require.Equal(t, 1, cluster.refreshCalls) } +func TestPeriodicHeartbeatCannotRepublishStaleIngressDuringActivation(t *testing.T) { + client := &ddlVisibilityHeartbeatOrderClient{ + firstStarted: make(chan struct{}), releaseFirst: make(chan struct{}), + } + cfg := &Config{UUID: "ddl-visibility-heartbeat-order-test"} + cfg.HAKeeper.HeatbeatTimeout.Duration = time.Second + s := &service{ + cfg: cfg, logger: zap.NewNop(), _hakeeperClient: client, + config: util.NewConfigData(nil), + } + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + + heartbeatDone := make(chan struct{}) + go func() { + s.heartbeat(context.Background()) + close(heartbeatDone) + }() + <-client.firstStarted + activationStarted := make(chan struct{}) + activationDone := make(chan struct{}) + go func() { + close(activationStarted) + s.ddlVisibilityBarrierMu.Lock() + s.viewMetadataIngressReady.Store(false) + _, _ = client.SendCNHeartbeat(context.Background(), s.newCNStoreHeartbeat()) + s.ddlVisibilityBarrierMu.Unlock() + close(activationDone) + }() + <-activationStarted + close(client.releaseFirst) + <-heartbeatDone + <-activationDone + + client.mu.Lock() + defer client.mu.Unlock() + require.Len(t, client.completed, 2) + require.True(t, client.completed[0].ViewMetadataIngressReady) + require.False(t, client.completed[1].ViewMetadataIngressReady, + "the activation withdrawal must complete after every older true heartbeat") +} + func TestServiceCloseWithdrawsDDLVisibilityBeforeQueryService(t *testing.T) { state := newDDLVisibilityCloseTestService(t, nil) diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 36a74c6dec32f..7952efa9460fd 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -231,11 +231,16 @@ func (s *service) heartbeat(ctx context.Context) { ctx2, cancel := context.WithTimeoutCause(ctx, s.cfg.HAKeeper.HeatbeatTimeout.Duration, moerr.CauseHeartbeat) defer cancel() + // Snapshot and send readiness under the same owner as startup, activation, + // and shutdown publication. Otherwise an older in-flight true heartbeat can + // arrive after activation has authoritatively published ingress=false. + s.ddlVisibilityBarrierMu.Lock() hb := s.newCNStoreHeartbeat() s.heartbeatInFlight.Store(true) s.notifyCommandPoll() cb, err := s._hakeeperClient.SendCNHeartbeat(ctx2, hb) s.heartbeatInFlight.Store(false) + s.ddlVisibilityBarrierMu.Unlock() if err != nil { s.commandPollNeeded.Store(true) s.notifyCommandPoll() diff --git a/pkg/cnservice/types.go b/pkg/cnservice/types.go index dc40fd316999b..a88a509ee111e 100644 --- a/pkg/cnservice/types.go +++ b/pkg/cnservice/types.go @@ -805,6 +805,7 @@ type service struct { ddlVisibilityActivationPending atomic.Bool ddlVisibilityActivationPrepared atomic.Bool ddlVisibilityActivationFenced atomic.Bool + ddlVisibilityRestoreIngress atomic.Bool ddlVisibilityBarrierMu sync.Mutex ddlCommitGate *frontend.DDLCommitGate viewMetadataGenerationRevoked atomic.Bool From d43ae04db60c584476289f89934b4397bb9f1616 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Fri, 28 Aug 2026 21:59:26 +0800 Subject: [PATCH 08/34] fix: require distributed DDL activation cut --- pkg/cnservice/server_ddl_visibility.go | 5 +- pkg/cnservice/server_ddl_visibility_test.go | 56 +++++++++++++++++++++ pkg/cnservice/types.go | 1 + 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 20b8a35607d34..0d9076155c638 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -191,13 +191,15 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) s.ddlVisibilityActivationPrepared.Store(false) s.ddlVisibilityActivationFenced.Store(false) + s.ddlVisibilityActivationComplete.Store(false) return nil } if !s.ddlVisibilityBarrierPrepared.Load() { rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) return nil } - if current >= defines.MORPCVersion36 && !pending { + if current >= defines.MORPCVersion36 && !pending && + s.ddlVisibilityActivationComplete.Load() { rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) return nil } @@ -259,6 +261,7 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets return errors.Join(err, cleanupErr) } + s.ddlVisibilityActivationComplete.Store(true) s.ddlVisibilityActivationPending.Store(false) s.ddlCommitGate.Unblock() return nil diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index d83c70a7be044..a32f953645d6c 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -323,6 +323,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { require.True(t, s.ddlVisibilityBarrierPrepared.Load()) require.True(t, s.ddlVisibilityActivationPrepared.Load()) require.True(t, s.ddlVisibilityActivationFenced.Load()) + require.False(t, s.ddlVisibilityActivationComplete.Load()) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.Equal(t, 1, cluster.refreshCalls) require.Equal(t, []string{"self:6001", "peer:6001"}, queryClient.requests) @@ -380,6 +381,61 @@ func TestHandleSetProtocolVersionRejectsStaleRecoveryIdentity(t *testing.T) { require.Equal(t, defines.MORPCVersion34, version) } +func TestDefaultV36StillRunsCompleteTargetActivation(t *testing.T) { + const serviceID = "ddl-visibility-default-v36-activation-test" + const generation = uint64(7) + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + targetTS := timestamp.Timestamp{PhysicalTime: 300, LogicalTime: 4} + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ + {ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + ViewMetadataIngressReady: true}, + {ServiceID: "legacy-peer", QueryAddress: "peer:6001", + ViewMetadataAdmissionGeneration: 8, DDLVisibilityBarrierReady: false, + ViewMetadataIngressReady: true}, + }} + cluster.refreshHook = func() { + // The control plane dispatches activation concurrently. Model the legacy + // peer completing its local drain before this CN checks global phases. + cluster.cnServices[1].DDLVisibilityBarrierReady = true + } + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, + frontiers: map[string]timestamp.Timestamp{ + "self:6001": {PhysicalTime: 100}, "peer:6001": targetTS, + }, + protocols: map[string]query.GetProtocolVersionResponse{"peer:6001": { + Version: defines.MORPCVersion36, + DDLVisibilityActivationPrepared: true, DDLVisibilityActivationFenced: true, + }}, + } + ctrl := gomock.NewController(t) + txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS.Next(), nil) + txnClient.EXPECT().SyncLatestCommitTS(targetTS) + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + s := &service{ + cfg: cfg, _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}, + moCluster: cluster, queryClient: queryClient, _txnClient: txnClient, + config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: frontend.NewDDLCommitGate(), + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.ddlVisibilityActivationPrepared.Store(true) + s.ddlVisibilityActivationFenced.Store(true) + s.viewMetadataIngressReady.Store(true) + + require.False(t, s.ddlVisibilityActivationComplete.Load()) + require.NoError(t, s.setProtocolVersion( + context.Background(), defines.MORPCVersion36, []string{serviceID, "legacy-peer"})) + require.True(t, s.ddlVisibilityActivationComplete.Load()) + require.True(t, s.viewMetadataIngressReady.Load()) + require.Contains(t, queryClient.requests, "peer:6001") +} + func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { const serviceID = "ddl-visibility-live-activation-test" const generation = uint64(7) diff --git a/pkg/cnservice/types.go b/pkg/cnservice/types.go index a88a509ee111e..7cf83762fee29 100644 --- a/pkg/cnservice/types.go +++ b/pkg/cnservice/types.go @@ -805,6 +805,7 @@ type service struct { ddlVisibilityActivationPending atomic.Bool ddlVisibilityActivationPrepared atomic.Bool ddlVisibilityActivationFenced atomic.Bool + ddlVisibilityActivationComplete atomic.Bool ddlVisibilityRestoreIngress atomic.Bool ddlVisibilityBarrierMu sync.Mutex ddlCommitGate *frontend.DDLCommitGate From de8c5d607e614c420445aa833fcd24e7fd4b5ff0 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Fri, 28 Aug 2026 22:53:14 +0800 Subject: [PATCH 09/34] fix: fence live background DDL activation --- pkg/cnservice/server_ddl_visibility.go | 10 ++++-- pkg/cnservice/server_ddl_visibility_test.go | 40 +++++++++++++++++++++ pkg/frontend/ddl_commit_gate.go | 35 +++++++++++++++--- pkg/frontend/txn.go | 4 ++- pkg/frontend/txn_test.go | 29 ++++++++++++++- 5 files changed, 109 insertions(+), 9 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 0d9076155c638..2f9dcd0d50de0 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -110,6 +110,9 @@ func (s *service) publishDDLVisibilityIngressAfterStart() error { if err := s.checkViewMetadataGenerationRevoked(); err != nil { return err } + if s.ddlCommitGate != nil { + s.ddlCommitGate.EnablePublicDDL() + } s.viewMetadataIngressReady.Store(true) if err := s.checkViewMetadataGenerationRevoked(); err != nil { return err @@ -227,10 +230,13 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets s.ddlVisibilityActivationPending.Store(true) s.ddlVisibilityActivationPrepared.Store(false) s.ddlVisibilityActivationFenced.Store(false) - if err := s.ddlCommitGate.Block(barrierCtx); err != nil { + // Withdraw routing before waiting for already-admitted old-protocol DDL. + // Block deliberately remains engaged on timeout; ingress must be equally + // fail-closed throughout that retry window. + if err := s.setDDLVisibilityIngressLocked(barrierCtx, false); err != nil { return err } - if err := s.setDDLVisibilityIngressLocked(barrierCtx, false); err != nil { + if err := s.ddlCommitGate.Block(barrierCtx); err != nil { return err } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index a32f953645d6c..d0feeacf54d0e 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -381,6 +381,46 @@ func TestHandleSetProtocolVersionRejectsStaleRecoveryIdentity(t *testing.T) { require.Equal(t, defines.MORPCVersion34, version) } +func TestActivationDrainTimeoutKeepsIngressWithdrawn(t *testing.T) { + const serviceID = "ddl-visibility-drain-timeout-test" + const generation = uint64(7) + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion35) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + ViewMetadataIngressReady: true, + }}} + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = 10 * time.Millisecond + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + gate := frontend.NewDDLCommitGate() + releaseActive, err := gate.Enter(context.Background()) + require.NoError(t, err) + defer releaseActive() + s := &service{ + cfg: cfg, _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}, + moCluster: cluster, queryClient: &ddlVisibilityTestQueryClient{serviceID: serviceID}, + _txnClient: mock_frontend.NewMockTxnClient(gomock.NewController(t)), + config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: gate, + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + + err = s.setProtocolVersion(context.Background(), defines.MORPCVersion36, []string{serviceID}) + require.Error(t, err) + require.True(t, s.ddlVisibilityActivationPending.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) + blockedCtx, cancel := context.WithCancel(context.Background()) + cancel() + _, err = gate.Enter(blockedCtx) + require.Error(t, err) +} + func TestDefaultV36StillRunsCompleteTargetActivation(t *testing.T) { const serviceID = "ddl-visibility-default-v36-activation-test" const generation = uint64(7) diff --git a/pkg/frontend/ddl_commit_gate.go b/pkg/frontend/ddl_commit_gate.go index 95c2f819ceaea..3661a0b0f4864 100644 --- a/pkg/frontend/ddl_commit_gate.go +++ b/pkg/frontend/ddl_commit_gate.go @@ -30,11 +30,12 @@ const DDLCommitGateRuntimeKey = "frontend.ddl-commit-gate" // the gate blocked across RPC attempts; Close wakes blocked sessions during CN // shutdown. type DDLCommitGate struct { - mu sync.Mutex - changed chan struct{} - blocked bool - closed bool - active int + mu sync.Mutex + changed chan struct{} + blocked bool + closed bool + publicDDL bool + active int // enterBlockedHook is a deterministic test hook invoked after Enter observes // a blocked gate and before it waits. Production leaves it nil. enterBlockedHook func() @@ -44,6 +45,15 @@ func NewDDLCommitGate() *DDLCommitGate { return &DDLCommitGate{changed: make(chan struct{})} } +func publicBackgroundDDLBarrierEnabled(serviceID string) bool { + value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(DDLCommitGateRuntimeKey) + if !ok || value == nil { + return false + } + gate, ok := value.(*DDLCommitGate) + return ok && gate.PublicDDLEnabled() +} + func enterDDLCommitGate(ctx context.Context, serviceID string) (func(), error) { value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(DDLCommitGateRuntimeKey) if !ok || value == nil { @@ -56,6 +66,21 @@ func enterDDLCommitGate(ctx context.Context, serviceID string) (func(), error) { return gate.Enter(ctx) } +// EnablePublicDDL marks that public listeners are live. Background sessions +// created on behalf of a client must participate in the cross-CN barrier after +// this point; bootstrap background DDL remains local before it. +func (g *DDLCommitGate) EnablePublicDDL() { + g.mu.Lock() + g.publicDDL = true + g.mu.Unlock() +} + +func (g *DDLCommitGate) PublicDDLEnabled() bool { + g.mu.Lock() + defer g.mu.Unlock() + return g.publicDDL && !g.closed +} + func (g *DDLCommitGate) Enter(ctx context.Context) (func(), error) { for { g.mu.Lock() diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index f21d27a3efaf9..e1804426b39c0 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -936,7 +936,9 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { execCtx.ses.SetTxnId(dumpUUID[:]) return err } - if err == nil && haveDDL && execCtx.ses.GetFromRealUser() && !visibilityTS.IsEmpty() { + if err == nil && haveDDL && !visibilityTS.IsEmpty() && + (execCtx.ses.GetFromRealUser() || + publicBackgroundDDLBarrierEnabled(execCtx.ses.GetService())) { // A fresh proxy connection has no session commit timestamp to carry // across CNs. Do not acknowledge a client DDL until every working CN // has reached the commit, or the observed catalog frontier for a no-op. diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index 30962c2096ac8..79709a69c31e0 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -1250,6 +1250,33 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { require.Nil(t, ses.GetTxnHandler().GetTxn()) }) + t.Run("live client-owned background DDL participates in barrier", func(t *testing.T) { + ses, op, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + ses.SetFromRealUser(false) + gate := NewDDLCommitGate() + gate.EnablePublicDDL() + rt := moruntime.ServiceRuntime(ses.GetService()) + previousGate, hadPreviousGate := rt.GetGlobalVariables(DDLCommitGateRuntimeKey) + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, gate) + t.Cleanup(func() { + if hadPreviousGate { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, previousGate) + } else { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, nil) + } + }) + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.Equal(t, []ddlSyncRequest{ + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + }, qc.requests) + require.Equal(t, 2, qc.releases) + require.Equal(t, txn.TxnStatus_Committed, op.meta.Status) + }) + tests := []struct { name string configure func(*Session, *testTxnOp) @@ -1261,7 +1288,7 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { }, }, { - name: "internal session", + name: "pre-ingress internal session", configure: func(ses *Session, _ *testTxnOp) { ses.SetFromRealUser(false) }, From c11ce76663e45fe90ff71cc59baac663a0f41809 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Fri, 28 Aug 2026 23:28:55 +0800 Subject: [PATCH 10/34] fix: retain DDL barrier eligibility on failure --- pkg/cnservice/server_ddl_visibility.go | 11 +++--- pkg/cnservice/server_ddl_visibility_test.go | 39 +++++++++++++++++++++ pkg/frontend/ddl_commit_gate.go | 20 +++++++++-- pkg/frontend/ddl_commit_gate_test.go | 3 ++ pkg/frontend/txn_test.go | 13 ++++++- 5 files changed, 78 insertions(+), 8 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 2f9dcd0d50de0..2d60e6a9aece9 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -230,13 +230,16 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets s.ddlVisibilityActivationPending.Store(true) s.ddlVisibilityActivationPrepared.Store(false) s.ddlVisibilityActivationFenced.Store(false) - // Withdraw routing before waiting for already-admitted old-protocol DDL. - // Block deliberately remains engaged on timeout; ingress must be equally - // fail-closed throughout that retry window. + // Stop new old-protocol DDL admission before the fallible authoritative + // withdrawal. Both withdrawal and subsequent drain failures deliberately + // leave the gate blocked for a fail-closed retry. + if err := s.ddlCommitGate.BlockNew(); err != nil { + return err + } if err := s.setDDLVisibilityIngressLocked(barrierCtx, false); err != nil { return err } - if err := s.ddlCommitGate.Block(barrierCtx); err != nil { + if err := s.ddlCommitGate.WaitDrained(barrierCtx); err != nil { return err } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index d0feeacf54d0e..884059f54b163 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -381,6 +381,45 @@ func TestHandleSetProtocolVersionRejectsStaleRecoveryIdentity(t *testing.T) { require.Equal(t, defines.MORPCVersion34, version) } +func TestActivationWithdrawalFailureStillBlocksNewDDL(t *testing.T) { + const serviceID = "ddl-visibility-withdrawal-failure-gate-test" + const generation = uint64(7) + withdrawErr := errors.New("injected withdrawal failure") + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion35) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + ViewMetadataIngressReady: true, + }}} + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + gate := frontend.NewDDLCommitGate() + s := &service{ + cfg: cfg, _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{ + cluster: cluster, sendErr: withdrawErr, + }, + moCluster: cluster, queryClient: &ddlVisibilityTestQueryClient{serviceID: serviceID}, + _txnClient: mock_frontend.NewMockTxnClient(gomock.NewController(t)), + config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: gate, + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion36, []string{serviceID}) + require.ErrorIs(t, err, withdrawErr) + require.True(t, cluster.cnServices[0].ViewMetadataIngressReady, + "the injected heartbeat failure leaves authoritative ingress unchanged") + blockedCtx, cancel := context.WithCancel(context.Background()) + cancel() + _, err = gate.Enter(blockedCtx) + require.ErrorIs(t, err, context.Canceled, + "withdrawal failure must not reopen old-protocol DDL admission") +} + func TestActivationDrainTimeoutKeepsIngressWithdrawn(t *testing.T) { const serviceID = "ddl-visibility-drain-timeout-test" const generation = uint64(7) diff --git a/pkg/frontend/ddl_commit_gate.go b/pkg/frontend/ddl_commit_gate.go index 3661a0b0f4864..00577d4b80ab2 100644 --- a/pkg/frontend/ddl_commit_gate.go +++ b/pkg/frontend/ddl_commit_gate.go @@ -78,7 +78,9 @@ func (g *DDLCommitGate) EnablePublicDDL() { func (g *DDLCommitGate) PublicDDLEnabled() bool { g.mu.Lock() defer g.mu.Unlock() - return g.publicDDL && !g.closed + // Close rejects every later Enter, but a DDL transaction admitted before + // shutdown retains the eligibility it had when public listeners were live. + return g.publicDDL } func (g *DDLCommitGate) Enter(ctx context.Context) (func(), error) { @@ -116,16 +118,21 @@ func (g *DDLCommitGate) Enter(ctx context.Context) (func(), error) { } } -func (g *DDLCommitGate) Block(ctx context.Context) error { +func (g *DDLCommitGate) BlockNew() error { g.mu.Lock() + defer g.mu.Unlock() if g.closed { - g.mu.Unlock() return moerr.NewServiceUnavailableNoCtx("DDL commit gate is closed") } if !g.blocked { g.blocked = true g.signalLocked() } + return nil +} + +func (g *DDLCommitGate) WaitDrained(ctx context.Context) error { + g.mu.Lock() for g.active > 0 { changed := g.changed g.mu.Unlock() @@ -144,6 +151,13 @@ func (g *DDLCommitGate) Block(ctx context.Context) error { return nil } +func (g *DDLCommitGate) Block(ctx context.Context) error { + if err := g.BlockNew(); err != nil { + return err + } + return g.WaitDrained(ctx) +} + func (g *DDLCommitGate) Unblock() { g.mu.Lock() if !g.closed && g.blocked { diff --git a/pkg/frontend/ddl_commit_gate_test.go b/pkg/frontend/ddl_commit_gate_test.go index 8a80cd283c9af..2c1ac47f06f42 100644 --- a/pkg/frontend/ddl_commit_gate_test.go +++ b/pkg/frontend/ddl_commit_gate_test.go @@ -63,6 +63,7 @@ func TestDDLCommitGateLinearizesBlockAndCommit(t *testing.T) { func TestDDLCommitGateCancellationAndClose(t *testing.T) { gate := NewDDLCommitGate() + gate.EnablePublicDDL() release, err := gate.Enter(context.Background()) require.NoError(t, err) ctx, cancel := context.WithCancel(context.Background()) @@ -76,6 +77,8 @@ func TestDDLCommitGateCancellationAndClose(t *testing.T) { require.ErrorIs(t, err, context.Canceled) gate.Close() + require.True(t, gate.PublicDDLEnabled(), + "an admitted public background DDL retains shutdown fan-out eligibility") _, err = gate.Enter(context.Background()) require.ErrorContains(t, err, "closed") err = gate.Block(context.Background()) diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index 79709a69c31e0..a1471bd202dbb 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -1268,7 +1268,18 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { } }) - require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + commitEntered := make(chan struct{}) + allowCommit := make(chan struct{}) + op.commitHook = func() { + close(commitEntered) + <-allowCommit + } + commitDone := make(chan error, 1) + go func() { commitDone <- ses.GetTxnHandler().Commit(execCtx) }() + <-commitEntered + gate.Close() + close(allowCommit) + require.NoError(t, <-commitDone) require.Equal(t, []ddlSyncRequest{ {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, From 000e9ce0cf0152b94e2239e517e82796d90047c6 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sat, 29 Aug 2026 13:10:52 +0800 Subject: [PATCH 11/34] fix: keep v36 startup ingress closed until activation --- pkg/cnservice/server_ddl_visibility.go | 31 +++++++++++++-------- pkg/cnservice/server_ddl_visibility_test.go | 21 ++++++++++++-- pkg/cnservice/types.go | 1 + 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 2d60e6a9aece9..7af4d331bb5b1 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -45,12 +45,6 @@ func (s *service) prepareDDLVisibilityBarrier() error { return err } s.ddlVisibilityBarrierPrepared.Store(true) - if ddlVisibilityBarrierSupported(s.cfg.UUID) { - // A v36 startup has no admitted DDL producers and has already applied the - // startup frontier, so it satisfies both live-activation phases. - s.ddlVisibilityActivationPrepared.Store(true) - s.ddlVisibilityActivationFenced.Store(true) - } return nil } @@ -103,13 +97,22 @@ func (s *service) prepareDDLVisibilityBarrierLocked() error { // overwrite this final withdrawal. func (s *service) publishDDLVisibilityIngressAfterStart() error { // Serialize listener-ready publication with startup/activation/shutdown. - // Activation may have sampled ingress=false before listeners became live; - // acquiring the owner lock makes the later publication win that ordering. + // Compiled v36 capability is not evidence that the deployment-wide producer + // cut completed: a default-v36 CN stays fail-closed until its complete-target + // activation succeeds. If activation raced ahead of listener startup, this + // method remains the sole owner that opens ingress after listeners are live. s.ddlVisibilityBarrierMu.Lock() defer s.ddlVisibilityBarrierMu.Unlock() if err := s.checkViewMetadataGenerationRevoked(); err != nil { return err } + s.ddlVisibilityListenersReady.Store(true) + if ddlVisibilityBarrierSupported(s.cfg.UUID) && + !s.ddlVisibilityActivationComplete.Load() { + s.viewMetadataIngressReady.Store(false) + s.notifyHeartbeat() + return nil + } if s.ddlCommitGate != nil { s.ddlCommitGate.EnablePublicDDL() } @@ -222,10 +225,11 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets barrierCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) defer cancel() if !pending { - // A command can arrive after startup fencing but before public listeners - // are started. Restore only the ingress state observed by the first - // activation attempt; retries after a fail-closed withdrawal retain it. - s.ddlVisibilityRestoreIngress.Store(s.viewMetadataIngressReady.Load()) + // A default-v36 process deliberately keeps ingress closed until the + // complete-target cut. Restore ingress when listeners are already live; + // if activation races before listener startup, Start opens it afterward. + s.ddlVisibilityRestoreIngress.Store( + s.viewMetadataIngressReady.Load() || s.ddlVisibilityListenersReady.Load()) } s.ddlVisibilityActivationPending.Store(true) s.ddlVisibilityActivationPrepared.Store(false) @@ -272,6 +276,9 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets s.ddlVisibilityActivationComplete.Store(true) s.ddlVisibilityActivationPending.Store(false) + if s.ddlVisibilityRestoreIngress.Load() { + s.ddlCommitGate.EnablePublicDDL() + } s.ddlCommitGate.Unblock() return nil } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 884059f54b163..922f94ed82cb3 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -321,8 +321,8 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { } require.NoError(t, s.prepareDDLVisibilityBarrier()) require.True(t, s.ddlVisibilityBarrierPrepared.Load()) - require.True(t, s.ddlVisibilityActivationPrepared.Load()) - require.True(t, s.ddlVisibilityActivationFenced.Load()) + require.False(t, s.ddlVisibilityActivationPrepared.Load()) + require.False(t, s.ddlVisibilityActivationFenced.Load()) require.False(t, s.ddlVisibilityActivationComplete.Load()) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.Equal(t, 1, cluster.refreshCalls) @@ -331,6 +331,22 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { require.Equal(t, 2, queryClient.releases) } +func TestDefaultV36StartupKeepsPublicIngressClosedUntilActivation(t *testing.T) { + const serviceID = "ddl-visibility-default-v36-startup-closed-test" + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + gate := frontend.NewDDLCommitGate() + s := &service{cfg: &Config{UUID: serviceID}, ddlCommitGate: gate} + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + + require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) + require.True(t, s.ddlVisibilityListenersReady.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + require.False(t, gate.PublicDDLEnabled()) + require.False(t, s.ddlVisibilityActivationPrepared.Load()) + require.False(t, s.ddlVisibilityActivationFenced.Load()) +} + func TestPrepareDDLVisibilityBarrierRejectsMissingProductionDependencies(t *testing.T) { const serviceID = "ddl-visibility-missing-dependency-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) @@ -512,6 +528,7 @@ func TestDefaultV36StillRunsCompleteTargetActivation(t *testing.T) { context.Background(), defines.MORPCVersion36, []string{serviceID, "legacy-peer"})) require.True(t, s.ddlVisibilityActivationComplete.Load()) require.True(t, s.viewMetadataIngressReady.Load()) + require.True(t, s.ddlCommitGate.PublicDDLEnabled()) require.Contains(t, queryClient.requests, "peer:6001") } diff --git a/pkg/cnservice/types.go b/pkg/cnservice/types.go index 7cf83762fee29..8d93aec3fe47c 100644 --- a/pkg/cnservice/types.go +++ b/pkg/cnservice/types.go @@ -806,6 +806,7 @@ type service struct { ddlVisibilityActivationPrepared atomic.Bool ddlVisibilityActivationFenced atomic.Bool ddlVisibilityActivationComplete atomic.Bool + ddlVisibilityListenersReady atomic.Bool ddlVisibilityRestoreIngress atomic.Bool ddlVisibilityBarrierMu sync.Mutex ddlCommitGate *frontend.DDLCommitGate From e42685498960a34a4f4a2fb721414cecad349517 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sat, 29 Aug 2026 14:41:13 +0800 Subject: [PATCH 12/34] fix: separate default runtime from DDL activation --- pkg/cnservice/server_ddl_visibility.go | 13 +++++++++++++ pkg/cnservice/server_ddl_visibility_test.go | 20 +++++++++++++------- pkg/sql/compile/remoterun_test.go | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 2d84719cde19b..29b63c779a1a2 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -39,6 +39,19 @@ func ddlVisibilityBarrierSupported(serviceID string) bool { // frontier held by the already-published barrier participants before public // SQL ingress can be admitted. func (s *service) prepareDDLVisibilityBarrier() error { + // MORPCLatestVersion describes compiled capability, not deployment-wide + // activation. A fresh upgraded process starts on the last deployed protocol + // so normal ingress remains available until the control plane explicitly + // performs the complete-target v37 cut. Restarting conservatively requires + // reactivation rather than assuming that an earlier distributed cut survived. + rt := moruntime.ServiceRuntime(s.cfg.UUID) + if value, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion); ok { + if version, valid := value.(int64); valid && version >= defines.MORPCVersion37 && + !s.ddlVisibilityActivationComplete.Load() { + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion36) + } + } + s.ddlVisibilityBarrierMu.Lock() defer s.ddlVisibilityBarrierMu.Unlock() if err := s.prepareDDLVisibilityBarrierLocked(); err != nil { diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 7b9d9ab09188a..9188672f07dc1 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -319,11 +319,14 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: 7, } + // Model a restart whose deployment protocol has been explicitly restored to + // v37. Fresh default-runtime startup is covered separately below. + s.ddlVisibilityActivationComplete.Store(true) require.NoError(t, s.prepareDDLVisibilityBarrier()) require.True(t, s.ddlVisibilityBarrierPrepared.Load()) require.False(t, s.ddlVisibilityActivationPrepared.Load()) require.False(t, s.ddlVisibilityActivationFenced.Load()) - require.False(t, s.ddlVisibilityActivationComplete.Load()) + require.True(t, s.ddlVisibilityActivationComplete.Load()) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.Equal(t, 1, cluster.refreshCalls) require.Equal(t, []string{"self:6001", "peer:6001"}, queryClient.requests) @@ -331,18 +334,20 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { require.Equal(t, 2, queryClient.releases) } -func TestDefaultV37StartupKeepsPublicIngressClosedUntilActivation(t *testing.T) { - const serviceID = "ddl-visibility-default-v37-startup-closed-test" +func TestDefaultV37StartupUsesLastDeployedProtocolUntilActivation(t *testing.T) { + const serviceID = "ddl-visibility-default-v37-startup-protocol-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) gate := frontend.NewDDLCommitGate() s := &service{cfg: &Config{UUID: serviceID}, ddlCommitGate: gate} - s.ddlVisibilityBarrierPrepared.Store(true) - s.ddlVisibilityBarrierReady.Store(true) + require.NoError(t, s.prepareDDLVisibilityBarrier()) require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) + version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion36, version) require.True(t, s.ddlVisibilityListenersReady.Load()) - require.False(t, s.viewMetadataIngressReady.Load()) - require.False(t, gate.PublicDDLEnabled()) + require.True(t, s.viewMetadataIngressReady.Load()) + require.True(t, gate.PublicDDLEnabled()) require.False(t, s.ddlVisibilityActivationPrepared.Load()) require.False(t, s.ddlVisibilityActivationFenced.Load()) } @@ -354,6 +359,7 @@ func TestPrepareDDLVisibilityBarrierRejectsMissingProductionDependencies(t *test cfg: &Config{UUID: serviceID}, viewMetadataAdmissionGeneration: 1, } + s.ddlVisibilityActivationComplete.Store(true) err := s.prepareDDLVisibilityBarrier() require.ErrorContains(t, err, "dependencies are unavailable") diff --git a/pkg/sql/compile/remoterun_test.go b/pkg/sql/compile/remoterun_test.go index 9d1bdc2512407..a0b4e3ce00d11 100644 --- a/pkg/sql/compile/remoterun_test.go +++ b/pkg/sql/compile/remoterun_test.go @@ -967,7 +967,7 @@ func TestCrossDomainStringLiteralRemoteProtocolValidation(t *testing.T) { } func TestRemoteExpressionProtocolValidation(t *testing.T) { - require.Equal(t, defines.MORPCVersion36, defines.MORPCLatestVersion, + require.GreaterOrEqual(t, defines.MORPCLatestVersion, defines.MORPCVersion36, "a capability is unavailable after a full rollout unless latest advertises it") proc := testutil.NewProcess(t) From ae22c367fa02a00c5af88a2539f63bf808541f4a Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sat, 29 Aug 2026 19:24:52 +0800 Subject: [PATCH 13/34] test: align DDL activation with protocol v38 --- pkg/queryservice/client/query_client_test.go | 2 +- pkg/sql/plan/function/ctl/cmd_rpc_version_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/queryservice/client/query_client_test.go b/pkg/queryservice/client/query_client_test.go index b3bfd2dca2845..f0673806fb434 100644 --- a/pkg/queryservice/client/query_client_test.go +++ b/pkg/queryservice/client/query_client_test.go @@ -36,7 +36,7 @@ func TestMongoDBClientRetireRequiresProtocolVersion5(t *testing.T) { assert.Equal(t, defines.MORPCVersion5, methodVersions[query.CmdMethod_MongoDBClientRetire]) } -func TestSyncCommitV2RequiresProtocolVersion37(t *testing.T) { +func TestSyncCommitV2RequiresProtocolVersion38(t *testing.T) { assert.Equal(t, defines.MORPCVersion38, methodVersions[query.CmdMethod_SyncCommitV2]) const serviceID = "sync-commit-v2-version-test" diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go index d11b4fe52c1ce..b2b72d061158f 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go @@ -217,9 +217,9 @@ func TestHandleSetProtocolVersionDispatchesCompleteTargetSetConcurrently(t *test proc := &process.Process{Base: &process.BaseProcess{QueryClient: qcli}} result, err := handleSetProtocolVersion( - proc, cn, strings.Join(targets, ",")+":37", nil) + proc, cn, strings.Join(targets, ",")+":38", nil) require.NoError(t, err) - require.Equal(t, "activation-cn-1:37, activation-cn-2:37", result.Data) + require.Equal(t, "activation-cn-1:38, activation-cn-2:38", result.Data) require.Equal(t, int32(2), qcli.started.Load()) require.Equal(t, int32(2), qcli.releases.Load()) qcli.mu.Lock() @@ -229,7 +229,7 @@ func TestHandleSetProtocolVersionDispatchesCompleteTargetSetConcurrently(t *test require.Equal(t, targets, requestTargets) } - _, err = handleSetProtocolVersion(proc, cn, "activation-cn-1,activation-cn-1:37", nil) + _, err = handleSetProtocolVersion(proc, cn, "activation-cn-1,activation-cn-1:38", nil) require.ErrorContains(t, err, "duplicated") } From b8e84b376c3a8ed80e87866afbe8e6b78b25123c Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sat, 29 Aug 2026 20:16:14 +0800 Subject: [PATCH 14/34] fix: durably stage DDL activation fence --- pkg/cnservice/server_ddl_visibility.go | 15 +- pkg/cnservice/server_ddl_visibility_test.go | 155 +++++++++++++++++++- 2 files changed, 165 insertions(+), 5 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 74ae6bbc412f9..172a981da2560 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -50,6 +50,11 @@ func (s *service) prepareDDLVisibilityBarrier() error { if deployedVersion >= defines.MORPCVersion38 { s.ddlVisibilityActivationComplete.Store(true) rt.SetGlobalVariables(moruntime.MOProtocolVersion, deployedVersion) + } else if deployedVersion <= -defines.MORPCVersion38 { + // A provisional marker proves this CN durably fenced its local producers, + // but not that every target committed the same cut. Keep v38 capability so + // retries can converge while startup/public ingress remains fail-closed. + rt.SetGlobalVariables(moruntime.MOProtocolVersion, -deployedVersion) } else if value, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion); ok { if version, valid := value.(int64); valid && version >= defines.MORPCVersion38 { rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion37) @@ -278,6 +283,11 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets if err := s.syncStartupDDLVisibilityFrontier(barrierCtx); err != nil { return err } + // Fenced is a distributed proof. Publish it only after the local provisional + // state is durable, so a persistence failure can never be observed as Fence. + if err := s.persistDDLVisibilityDeployedProtocol(-version); err != nil { + return err + } s.ddlVisibilityActivationFenced.Store(true) if err := s.waitForDDLVisibilityActivationPhase( barrierCtx, activationTargets, true); err != nil { @@ -286,8 +296,9 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets if s.ddlVisibilityBarrierClosing.Load() || s.viewMetadataGenerationRevoked.Load() { return moerr.NewServiceUnavailableNoCtx("CN is closing") } - // Persist the deployed cut before reopening ingress. A restart after this - // point restores v38 and fences its startup frontier before admitting DDL. + // Commit the deployed cut before reopening ingress. A failure leaves the + // durable provisional marker in place; restart therefore remains on v38 but + // fail-closed until a complete-target retry commits the cut. if err := s.persistDDLVisibilityDeployedProtocol(version); err != nil { return err } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index b01e823af8f1d..450b78c38bad5 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -44,6 +44,20 @@ import ( "github.com/matrixorigin/matrixone/pkg/util" ) +type failReplaceMetadataFS struct { + fileservice.ReplaceableFileService + failAt int + calls int +} + +func (f *failReplaceMetadataFS) Replace(ctx context.Context, vector fileservice.IOVector) error { + f.calls++ + if f.calls == f.failAt { + return errors.New("injected metadata replace failure") + } + return f.ReplaceableFileService.Replace(ctx, vector) +} + func newDDLVisibilityMetadataFS(t *testing.T) fileservice.ReplaceableFileService { t.Helper() fs, err := fileservice.NewMemoryFS(defines.LocalFileServiceName, fileservice.DisabledCacheConfig, nil) @@ -321,16 +335,24 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { cfg := &Config{UUID: serviceID} cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + metadataFS := newDDLVisibilityMetadataFS(t) + writer := &service{ + cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS, + } + // Persist with the old process, then construct a distinct service and load + // through the production metadata initialization path. + require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion38)) s := &service{ - cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: newDDLVisibilityMetadataFS(t), + cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS, + logger: zap.NewNop(), moCluster: cluster, queryClient: queryClient, _txnClient: txnClient, _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}, config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: 7, ddlCommitGate: frontend.NewDDLCommitGate(), } - // Model an ordinary process restart after this CN durably joined the v38 cut. - require.NoError(t, s.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion38)) + require.NoError(t, s.initMetadata()) + require.Equal(t, defines.MORPCVersion38, s.metadata.DDLVisibilityDeployedProtocol) require.False(t, s.ddlVisibilityActivationComplete.Load()) require.NoError(t, s.prepareDDLVisibilityBarrier()) require.True(t, s.ddlVisibilityBarrierPrepared.Load()) @@ -368,6 +390,30 @@ func TestDefaultV38StartupUsesLastDeployedProtocolUntilActivation(t *testing.T) require.False(t, s.ddlVisibilityActivationFenced.Load()) } +func TestProvisionalV38RestartRemainsFailClosed(t *testing.T) { + const serviceID = "ddl-visibility-provisional-v38-restart-test" + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + metadataFS := newDDLVisibilityMetadataFS(t) + cfg := &Config{UUID: serviceID} + writer := &service{cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS} + require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(-defines.MORPCVersion38)) + + gate := frontend.NewDDLCommitGate() + restarted := &service{ + cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS, + logger: zap.NewNop(), ddlCommitGate: gate, + } + require.NoError(t, restarted.initMetadata()) + require.NoError(t, restarted.prepareDDLVisibilityBarrier()) + require.NoError(t, restarted.publishDDLVisibilityIngressAfterStart()) + version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion38, version) + require.False(t, restarted.ddlVisibilityActivationComplete.Load()) + require.False(t, restarted.viewMetadataIngressReady.Load()) + require.False(t, gate.PublicDDLEnabled()) +} + func TestPrepareDDLVisibilityBarrierRejectsMissingProductionDependencies(t *testing.T) { const serviceID = "ddl-visibility-missing-dependency-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) @@ -419,6 +465,109 @@ func TestHandleSetProtocolVersionRejectsStaleRecoveryIdentity(t *testing.T) { require.Equal(t, defines.MORPCVersion34, version) } +func TestActivationDoesNotPublishFencedBeforeProvisionalPersistence(t *testing.T) { + const serviceID = "ddl-visibility-provisional-persist-failure-test" + const generation = uint64(7) + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion37) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + ViewMetadataIngressReady: true, + }}} + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, + frontiers: map[string]timestamp.Timestamp{"self:6001": {PhysicalTime: 100}}, + } + txnClient := mock_frontend.NewMockTxnClient(gomock.NewController(t)) + targetTS := timestamp.Timestamp{PhysicalTime: 100} + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS, nil) + txnClient.EXPECT().SyncLatestCommitTS(targetTS) + baseFS := newDDLVisibilityMetadataFS(t) + metadataFS := &failReplaceMetadataFS{ReplaceableFileService: baseFS, failAt: 1} + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + s := &service{ + cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS, + _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}, + moCluster: cluster, queryClient: queryClient, _txnClient: txnClient, + config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: frontend.NewDDLCommitGate(), + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion38, []string{serviceID}) + require.ErrorContains(t, err, "injected metadata replace failure") + require.True(t, s.ddlVisibilityActivationPrepared.Load()) + require.False(t, s.ddlVisibilityActivationFenced.Load()) + require.False(t, s.ddlVisibilityActivationComplete.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + require.Equal(t, int64(0), s.loadDDLVisibilityDeployedProtocol()) +} + +func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing.T) { + const serviceID = "ddl-visibility-committed-persist-failure-test" + const generation = uint64(7) + rt := moruntime.DefaultRuntime() + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion37) + moruntime.SetupServiceBasedRuntime(serviceID, rt) + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, QueryAddress: "self:6001", + ViewMetadataAdmissionGeneration: generation, DDLVisibilityBarrierReady: true, + ViewMetadataIngressReady: true, + }}} + targetTS := timestamp.Timestamp{PhysicalTime: 100} + queryClient := &ddlVisibilityTestQueryClient{ + serviceID: serviceID, + frontiers: map[string]timestamp.Timestamp{"self:6001": targetTS}, + } + txnClient := mock_frontend.NewMockTxnClient(gomock.NewController(t)) + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS, nil) + txnClient.EXPECT().SyncLatestCommitTS(targetTS) + baseFS := newDDLVisibilityMetadataFS(t) + metadataFS := &failReplaceMetadataFS{ReplaceableFileService: baseFS, failAt: 2} + cfg := &Config{UUID: serviceID} + cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond + s := &service{ + cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS, + _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}, + moCluster: cluster, queryClient: queryClient, _txnClient: txnClient, + config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, + ddlCommitGate: frontend.NewDDLCommitGate(), + } + s.ddlVisibilityBarrierPrepared.Store(true) + s.ddlVisibilityBarrierReady.Store(true) + s.viewMetadataIngressReady.Store(true) + + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion38, []string{serviceID}) + require.ErrorContains(t, err, "injected metadata replace failure") + require.True(t, s.ddlVisibilityActivationFenced.Load()) + require.False(t, s.ddlVisibilityActivationComplete.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + require.Equal(t, -defines.MORPCVersion38, s.loadDDLVisibilityDeployedProtocol()) + + // A distinct process reloads the provisional marker through initMetadata and + // must remain a v38, non-routable producer until activation is retried. + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + restarted := &service{ + cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: baseFS, + logger: zap.NewNop(), ddlCommitGate: frontend.NewDDLCommitGate(), + } + require.NoError(t, restarted.initMetadata()) + require.NoError(t, restarted.prepareDDLVisibilityBarrier()) + require.NoError(t, restarted.publishDDLVisibilityIngressAfterStart()) + version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion38, version) + require.False(t, restarted.viewMetadataIngressReady.Load()) + require.False(t, restarted.ddlCommitGate.PublicDDLEnabled()) +} + func TestActivationWithdrawalFailureStillBlocksNewDDL(t *testing.T) { const serviceID = "ddl-visibility-withdrawal-failure-gate-test" const generation = uint64(7) From 234f7021f836c34a8824fd858ce7de412fd246bc Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sat, 29 Aug 2026 20:50:56 +0800 Subject: [PATCH 15/34] fix: persist cluster DDL activation epoch --- pkg/cnservice/server_ddl_visibility.go | 16 + pkg/cnservice/server_ddl_visibility_test.go | 45 +- pkg/cnservice/server_heartbeat.go | 4 + pkg/hakeeper/rsm.go | 10 +- pkg/pb/logservice/logservice.go | 4 + pkg/pb/logservice/logservice.pb.go | 982 ++++++++++++-------- pkg/pb/logservice/logservice_test.go | 35 +- proto/logservice.proto | 12 +- 8 files changed, 685 insertions(+), 423 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 172a981da2560..942655cb2847b 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -46,6 +46,22 @@ func (s *service) prepareDDLVisibilityBarrier() error { // whether this restart can produce v38 DDL. A fresh upgraded process has no // marker and starts on v37 until the complete-target cut persists v38. deployedVersion := s.loadDDLVisibilityDeployedProtocol() + if deployedVersion == 0 && s._hakeeperClient != nil { + ctx, cancel := s.newDDLVisibilityBarrierContext(context.Background()) + details, err := s._hakeeperClient.GetClusterDetails(ctx) + if err != nil { + err = moerr.AttachCause(ctx, err) + cancel() + return err + } + cancel() + if details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion38 { + // Markerless scale-out/replacement after the cluster cut joins v38 as + // provisional. It can synchronize and receive activation RPCs, but it + // cannot publish ingress or produce DDL before joining the exact cut. + deployedVersion = -details.DDLVisibilityDeployedProtocol + } + } rt := moruntime.ServiceRuntime(s.cfg.UUID) if deployedVersion >= defines.MORPCVersion38 { s.ddlVisibilityActivationComplete.Store(true) diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 450b78c38bad5..c7851560c6a3b 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -172,13 +172,22 @@ func activationTestPeerProtocols() map[string]query.GetProtocolVersionResponse { type ddlVisibilityWithdrawalHAKeeperClient struct { logservice.CNHAKeeperClient - cluster *ddlVisibilityTestCluster - queryClosed <-chan struct{} - sendErr error - sendErrors map[int]error - heartbeats []logservicepb.CNStoreHeartbeat - queryClosedBeforeSend bool - closeCalls int + cluster *ddlVisibilityTestCluster + queryClosed <-chan struct{} + sendErr error + sendErrors map[int]error + heartbeats []logservicepb.CNStoreHeartbeat + queryClosedBeforeSend bool + closeCalls int + clusterDeployedProtocol int64 +} + +func (c *ddlVisibilityWithdrawalHAKeeperClient) GetClusterDetails( + context.Context, +) (logservicepb.ClusterDetails, error) { + return logservicepb.ClusterDetails{ + DDLVisibilityDeployedProtocol: c.clusterDeployedProtocol, + }, nil } func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( @@ -390,6 +399,28 @@ func TestDefaultV38StartupUsesLastDeployedProtocolUntilActivation(t *testing.T) require.False(t, s.ddlVisibilityActivationFenced.Load()) } +func TestMarkerlessCNJoinsCommittedClusterFailClosed(t *testing.T) { + const serviceID = "ddl-visibility-markerless-post-cut-test" + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + cluster := &ddlVisibilityTestCluster{} + gate := frontend.NewDDLCommitGate() + s := &service{ + cfg: &Config{UUID: serviceID}, ddlCommitGate: gate, + _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{ + cluster: cluster, clusterDeployedProtocol: defines.MORPCVersion38, + }, + } + + require.NoError(t, s.prepareDDLVisibilityBarrier()) + require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) + version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) + require.Equal(t, defines.MORPCVersion38, version) + require.False(t, s.ddlVisibilityActivationComplete.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + require.False(t, gate.PublicDDLEnabled()) +} + func TestProvisionalV38RestartRemainsFailClosed(t *testing.T) { const serviceID = "ddl-visibility-provisional-v38-restart-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 7952efa9460fd..9ceacbc284a7d 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -22,6 +22,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/common/moerr" "github.com/matrixorigin/matrixone/pkg/common/system" + "github.com/matrixorigin/matrixone/pkg/defines" "github.com/matrixorigin/matrixone/pkg/logservice" "github.com/matrixorigin/matrixone/pkg/logutil" logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" @@ -212,6 +213,9 @@ func (s *service) newCNStoreHeartbeat() logservicepb.CNStoreHeartbeat { ViewMetadataIngressReady: s.viewMetadataIngressReady.Load(), DDLVisibilityBarrierReady: s.ddlVisibilityBarrierReady.Load(), } + if deployed := s.loadDDLVisibilityDeployedProtocol(); deployed >= defines.MORPCVersion38 { + hb.DDLVisibilityDeployedProtocol = deployed + } if s.viewMetadataEpochFence != nil { hb.ViewMetadataObservedEpoch = s.viewMetadataEpochFence.Epoch() } diff --git a/pkg/hakeeper/rsm.go b/pkg/hakeeper/rsm.go index ac3cc734945d5..0ee4b8f49bdea 100644 --- a/pkg/hakeeper/rsm.go +++ b/pkg/hakeeper/rsm.go @@ -1705,10 +1705,11 @@ func (s *stateMachine) handleScheduleCommandQuery(uuid string) *pb.CommandBatch func (s *stateMachine) handleClusterDetailsQuery(cfg Config) *pb.ClusterDetails { cfg.Fill() cd := &pb.ClusterDetails{ - CNStores: make([]pb.CNStore, 0, len(s.state.CNState.Stores)), - TNStores: make([]pb.TNStore, 0, len(s.state.TNState.Stores)), - LogStores: make([]pb.LogStore, 0, len(s.state.LogState.Stores)), - ProxyStores: make([]pb.ProxyStore, 0, len(s.state.ProxyState.Stores)), + CNStores: make([]pb.CNStore, 0, len(s.state.CNState.Stores)), + TNStores: make([]pb.TNStore, 0, len(s.state.TNState.Stores)), + LogStores: make([]pb.LogStore, 0, len(s.state.LogState.Stores)), + ProxyStores: make([]pb.ProxyStore, 0, len(s.state.ProxyState.Stores)), + DDLVisibilityDeployedProtocol: s.state.CNState.DDLVisibilityDeployedProtocol, } if s.viewMetadataAdmissionActive() { cd.ViewMetadataAdmission = &pb.ViewMetadataAdmission{ @@ -1750,6 +1751,7 @@ func (s *stateMachine) handleClusterDetailsQuery(cfg Config) *pb.ClusterDetails ViewMetadataObservedEpoch: info.ViewMetadataObservedEpoch, ViewMetadataAdmissionReady: info.ViewMetadataAdmissionReady, DDLVisibilityBarrierReady: info.DDLVisibilityBarrierReady, + DDLVisibilityDeployedProtocol: info.DDLVisibilityDeployedProtocol, ViewMetadataIngressReady: info.ViewMetadataIngressReady, } cd.CNStores = append(cd.CNStores, n) diff --git a/pkg/pb/logservice/logservice.go b/pkg/pb/logservice/logservice.go index 40c9bdaa8dc44..e6b0b4c3b0cdb 100644 --- a/pkg/pb/logservice/logservice.go +++ b/pkg/pb/logservice/logservice.go @@ -164,6 +164,10 @@ func (s *CNState) Update(hb CNStoreHeartbeat, tick uint64) { storeInfo.ViewMetadataRevalidatedEpoch = hb.ViewMetadataRevalidatedEpoch storeInfo.ViewMetadataIngressReady = hb.ViewMetadataIngressReady storeInfo.DDLVisibilityBarrierReady = hb.DDLVisibilityBarrierReady + storeInfo.DDLVisibilityDeployedProtocol = hb.DDLVisibilityDeployedProtocol + if hb.DDLVisibilityDeployedProtocol > s.DDLVisibilityDeployedProtocol { + s.DDLVisibilityDeployedProtocol = hb.DDLVisibilityDeployedProtocol + } s.Stores[hb.UUID] = storeInfo } diff --git a/pkg/pb/logservice/logservice.pb.go b/pkg/pb/logservice/logservice.pb.go index 142cf6abf721d..e1972e60d0525 100644 --- a/pkg/pb/logservice/logservice.pb.go +++ b/pkg/pb/logservice/logservice.pb.go @@ -534,10 +534,11 @@ type CNStore struct { // visibility fence even when public SQL ingress is not admitted yet. DDLVisibilityBarrierReady bool `protobuf:"varint,21,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` // ViewMetadataIngressReady is retained for raw control-plane inventory. - ViewMetadataIngressReady bool `protobuf:"varint,22,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ViewMetadataIngressReady bool `protobuf:"varint,22,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,23,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNStore) Reset() { *m = CNStore{} } @@ -720,6 +721,13 @@ func (m *CNStore) GetViewMetadataIngressReady() bool { return false } +func (m *CNStore) GetDDLVisibilityDeployedProtocol() int64 { + if m != nil { + return m.DDLVisibilityDeployedProtocol + } + return 0 +} + type TNStore struct { UUID string `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"` ServiceAddress string `protobuf:"bytes,2,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` @@ -1203,11 +1211,14 @@ type CNStoreHeartbeat struct { ViewMetadataRevalidatedEpoch uint64 `protobuf:"varint,23,opt,name=ViewMetadataRevalidatedEpoch,proto3" json:"ViewMetadataRevalidatedEpoch,omitempty"` // ViewMetadataIngressReady is published only after every public CN ingress // listener has started successfully. Admission alone is not routability. - ViewMetadataIngressReady bool `protobuf:"varint,24,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` - DDLVisibilityBarrierReady bool `protobuf:"varint,25,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ViewMetadataIngressReady bool `protobuf:"varint,24,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` + DDLVisibilityBarrierReady bool `protobuf:"varint,25,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` + // DDLVisibilityDeployedProtocol reports only a locally committed deployment + // marker. Provisional activation must never advance the cluster-wide epoch. + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,26,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNStoreHeartbeat) Reset() { *m = CNStoreHeartbeat{} } @@ -1411,6 +1422,13 @@ func (m *CNStoreHeartbeat) GetDDLVisibilityBarrierReady() bool { return false } +func (m *CNStoreHeartbeat) GetDDLVisibilityDeployedProtocol() int64 { + if m != nil { + return m.DDLVisibilityDeployedProtocol + } + return 0 +} + // CNAllocateID is the periodic message sent tp the HAKeeper by CN stores. type CNAllocateID struct { Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -4058,6 +4076,7 @@ type CNStoreInfo struct { ViewMetadataAdmissionReady bool `protobuf:"varint,25,opt,name=ViewMetadataAdmissionReady,proto3" json:"ViewMetadataAdmissionReady,omitempty"` ViewMetadataIngressReady bool `protobuf:"varint,26,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` DDLVisibilityBarrierReady bool `protobuf:"varint,27,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,28,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -4278,13 +4297,24 @@ func (m *CNStoreInfo) GetDDLVisibilityBarrierReady() bool { return false } +func (m *CNStoreInfo) GetDDLVisibilityDeployedProtocol() int64 { + if m != nil { + return m.DDLVisibilityDeployedProtocol + } + return 0 +} + // CNState contains all CN details known to the HAKeeper. type CNState struct { // Stores is keyed by CN store UUID. - Stores map[string]CNStoreInfo `protobuf:"bytes,1,rep,name=Stores,proto3" json:"Stores" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Stores map[string]CNStoreInfo `protobuf:"bytes,1,rep,name=Stores,proto3" json:"Stores" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // DDLVisibilityDeployedProtocol is a monotonic cluster deployment epoch. + // Once a complete-target cut commits, markerless replacement/scale-out CNs + // must join that fence instead of reopening on an older protocol. + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,2,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNState) Reset() { *m = CNState{} } @@ -4327,6 +4357,13 @@ func (m *CNState) GetStores() map[string]CNStoreInfo { return nil } +func (m *CNState) GetDDLVisibilityDeployedProtocol() int64 { + if m != nil { + return m.DDLVisibilityDeployedProtocol + } + return 0 +} + // TNStoreInfo contains information on a TN store. type TNStoreInfo struct { Tick uint64 `protobuf:"varint,1,opt,name=Tick,proto3" json:"Tick,omitempty"` @@ -4756,15 +4793,16 @@ func (m *ProxyHeartbeat) GetViewMetadataObservedEpoch() uint64 { } type ClusterDetails struct { - TNStores []TNStore `protobuf:"bytes,1,rep,name=TNStores,proto3" json:"TNStores"` - CNStores []CNStore `protobuf:"bytes,2,rep,name=CNStores,proto3" json:"CNStores"` - LogStores []LogStore `protobuf:"bytes,3,rep,name=LogStores,proto3" json:"LogStores"` - ProxyStores []ProxyStore `protobuf:"bytes,4,rep,name=ProxyStores,proto3" json:"ProxyStores"` - DeletedStores []DeletedStore `protobuf:"bytes,5,rep,name=DeletedStores,proto3" json:"DeletedStores"` - ViewMetadataAdmission *ViewMetadataAdmission `protobuf:"bytes,6,opt,name=ViewMetadataAdmission,proto3" json:"ViewMetadataAdmission,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + TNStores []TNStore `protobuf:"bytes,1,rep,name=TNStores,proto3" json:"TNStores"` + CNStores []CNStore `protobuf:"bytes,2,rep,name=CNStores,proto3" json:"CNStores"` + LogStores []LogStore `protobuf:"bytes,3,rep,name=LogStores,proto3" json:"LogStores"` + ProxyStores []ProxyStore `protobuf:"bytes,4,rep,name=ProxyStores,proto3" json:"ProxyStores"` + DeletedStores []DeletedStore `protobuf:"bytes,5,rep,name=DeletedStores,proto3" json:"DeletedStores"` + ViewMetadataAdmission *ViewMetadataAdmission `protobuf:"bytes,6,opt,name=ViewMetadataAdmission,proto3" json:"ViewMetadataAdmission,omitempty"` + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,7,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *ClusterDetails) Reset() { *m = ClusterDetails{} } @@ -4842,6 +4880,13 @@ func (m *ClusterDetails) GetViewMetadataAdmission() *ViewMetadataAdmission { return nil } +func (m *ClusterDetails) GetDDLVisibilityDeployedProtocol() int64 { + if m != nil { + return m.DDLVisibilityDeployedProtocol + } + return 0 +} + // ClusterInfo provides a global view of all shards in the cluster. It // describes the logical sharding of the system, rather than physical // distribution of all replicas that belong to those shards. @@ -6500,380 +6545,384 @@ func init() { func init() { proto.RegisterFile("logservice.proto", fileDescriptor_fd1040c5381ab5a7) } var fileDescriptor_fd1040c5381ab5a7 = []byte{ - // 5968 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xdd, 0x6f, 0x1b, 0xd9, - 0x75, 0xb8, 0x87, 0xa2, 0x24, 0xf2, 0x50, 0x92, 0x47, 0x57, 0x1f, 0xa6, 0xb5, 0xb6, 0xac, 0xe5, - 0x3a, 0xbb, 0x5e, 0x65, 0x23, 0xe7, 0x67, 0x67, 0x17, 0x9b, 0xfc, 0x1c, 0xef, 0x52, 0x24, 0xd7, - 0xa2, 0x4d, 0x53, 0xda, 0xe1, 0xc8, 0x9b, 0x04, 0x58, 0x08, 0x23, 0xf1, 0x5a, 0x9e, 0x88, 0xe2, - 0x30, 0x33, 0x23, 0xaf, 0xdd, 0xbe, 0x15, 0x4d, 0x51, 0x34, 0x40, 0xd1, 0x00, 0x41, 0x93, 0x36, - 0x4d, 0xbf, 0xde, 0xfa, 0x94, 0x97, 0xf6, 0x5f, 0x28, 0xf2, 0x54, 0x04, 0x79, 0xcc, 0x43, 0x9a, - 0xa4, 0x2f, 0x05, 0xf2, 0x5a, 0x34, 0xe8, 0x43, 0x81, 0xe2, 0x7e, 0xcd, 0xdc, 0x3b, 0x73, 0x87, - 0xa4, 0x3e, 0x92, 0x36, 0x41, 0x9e, 0xc4, 0x7b, 0x3e, 0xee, 0xe7, 0x39, 0xe7, 0x9e, 0x7b, 0xee, - 0xb9, 0x23, 0x30, 0x7b, 0xde, 0x61, 0x80, 0xfd, 0xe7, 0xee, 0x01, 0xde, 0x18, 0xf8, 0x5e, 0xe8, - 0x21, 0x88, 0x21, 0x2b, 0x9f, 0x39, 0x74, 0xc3, 0x67, 0x27, 0xfb, 0x1b, 0x07, 0xde, 0xf1, 0xed, - 0x43, 0xef, 0xd0, 0xbb, 0x4d, 0x49, 0xf6, 0x4f, 0x9e, 0xd2, 0x12, 0x2d, 0xd0, 0x5f, 0x8c, 0x75, - 0xe5, 0xc6, 0xa1, 0xe7, 0x1d, 0xf6, 0x70, 0x4c, 0x15, 0xba, 0xc7, 0x38, 0x08, 0x9d, 0xe3, 0x01, - 0x27, 0x98, 0x3b, 0xc6, 0xa1, 0xd3, 0x75, 0x42, 0x87, 0x95, 0x2b, 0x3f, 0x28, 0xc0, 0x74, 0xad, - 0xdd, 0x09, 0x3d, 0x1f, 0x23, 0x04, 0xf9, 0xdd, 0xdd, 0x66, 0xbd, 0x6c, 0xac, 0x19, 0xb7, 0x8a, - 0x16, 0xfd, 0x8d, 0x5e, 0x87, 0xb9, 0x0e, 0xeb, 0x4a, 0xb5, 0xdb, 0xf5, 0x71, 0x10, 0x94, 0x73, - 0x14, 0x9b, 0x80, 0xa2, 0x55, 0x80, 0xce, 0x87, 0x2d, 0x41, 0x33, 0x41, 0x69, 0x24, 0x08, 0xda, - 0x00, 0xd4, 0xf2, 0x0e, 0x8e, 0x12, 0x75, 0xe5, 0x29, 0x9d, 0x06, 0x83, 0x6e, 0x42, 0xde, 0xf2, - 0x7a, 0xb8, 0x3c, 0xb5, 0x66, 0xdc, 0x9a, 0xbb, 0x63, 0x6e, 0x44, 0xdd, 0xae, 0xb5, 0x09, 0xdc, - 0xa2, 0x58, 0xd2, 0x63, 0xdb, 0x3d, 0x38, 0x2a, 0x4f, 0xaf, 0x19, 0xb7, 0xf2, 0x16, 0xfd, 0x8d, - 0x3e, 0x0d, 0x93, 0x9d, 0xd0, 0x09, 0x71, 0xb9, 0x40, 0x59, 0x97, 0x36, 0xa4, 0xf9, 0x6d, 0x7b, - 0x5d, 0x4c, 0x91, 0x16, 0xa3, 0x41, 0x5f, 0x84, 0xa9, 0x96, 0xb3, 0x8f, 0x7b, 0x41, 0xb9, 0xb8, - 0x36, 0x71, 0xab, 0x74, 0xe7, 0x86, 0x4c, 0xcd, 0xe7, 0x65, 0x83, 0x51, 0x34, 0xfa, 0xa1, 0xff, - 0x72, 0x33, 0xff, 0x83, 0x9f, 0xdc, 0xb8, 0x64, 0x71, 0x26, 0xf4, 0xff, 0xa0, 0xf8, 0x91, 0xe7, - 0x1f, 0xb1, 0xf6, 0x80, 0xb6, 0xb7, 0x10, 0x77, 0x35, 0x42, 0x59, 0x31, 0x15, 0xaa, 0xc0, 0xcc, - 0x87, 0x27, 0xd8, 0x7f, 0x29, 0xa6, 0xa0, 0x44, 0xa7, 0x40, 0x81, 0xa1, 0x77, 0x00, 0x6a, 0x5e, - 0xff, 0xa9, 0x7b, 0x58, 0x77, 0x42, 0xa7, 0x3c, 0xb3, 0x66, 0xdc, 0x2a, 0xdd, 0x59, 0x56, 0x7a, - 0x16, 0x61, 0x2d, 0x89, 0x12, 0xbd, 0x03, 0x05, 0x0b, 0x07, 0xde, 0x89, 0x7f, 0x80, 0xcb, 0xb3, - 0x94, 0x6b, 0x51, 0xe6, 0x12, 0x38, 0x3e, 0x88, 0x88, 0x16, 0x2d, 0xc3, 0xd4, 0xee, 0xc0, 0x76, - 0x8f, 0x71, 0x79, 0x6e, 0xcd, 0xb8, 0x35, 0x61, 0xf1, 0x12, 0xfa, 0x2c, 0x2c, 0x74, 0x9e, 0x39, - 0x7e, 0x37, 0xb1, 0x6a, 0x97, 0x69, 0x97, 0x75, 0x28, 0xb4, 0x02, 0x85, 0x9a, 0x77, 0x7c, 0xec, - 0x86, 0xcd, 0x7a, 0xd9, 0xa4, 0x64, 0x51, 0x19, 0x7d, 0x00, 0xab, 0x4f, 0x5c, 0xfc, 0xc9, 0x63, - 0x3e, 0x3d, 0xd5, 0xee, 0xb1, 0x1b, 0x04, 0xae, 0xd7, 0xef, 0x9c, 0x0c, 0x06, 0x9e, 0x1f, 0xe2, - 0x6e, 0x79, 0x7e, 0xcd, 0xb8, 0x55, 0xb0, 0x46, 0x50, 0xa1, 0x2d, 0xb8, 0xa1, 0xa5, 0x78, 0x80, - 0xfb, 0xd8, 0x77, 0x42, 0xd7, 0xeb, 0x97, 0x11, 0x95, 0x87, 0x51, 0x64, 0xe8, 0x1e, 0x5c, 0x95, - 0x49, 0xb6, 0xf7, 0xc9, 0x4c, 0xe1, 0x6e, 0x63, 0xe0, 0x1d, 0x3c, 0x2b, 0x2f, 0xd0, 0x3a, 0xb2, - 0x09, 0xd0, 0x7d, 0x58, 0xd1, 0x36, 0x60, 0x61, 0xa7, 0xfb, 0xb2, 0xbc, 0x48, 0xc7, 0x32, 0x84, - 0x82, 0xb4, 0x5e, 0xaf, 0xb7, 0x9e, 0xb8, 0x81, 0xbb, 0xef, 0xf6, 0xdc, 0xf0, 0xe5, 0xa6, 0xe3, - 0xfb, 0x2e, 0xf6, 0x19, 0xfb, 0x12, 0x65, 0xcf, 0x26, 0x40, 0x5f, 0x80, 0xb2, 0x5c, 0x77, 0xb3, - 0x7f, 0x48, 0x16, 0x80, 0x31, 0x2f, 0x53, 0xe6, 0x4c, 0xfc, 0x4a, 0x1b, 0x4a, 0x92, 0x4c, 0x23, - 0x13, 0x26, 0x8e, 0xf0, 0x4b, 0xae, 0xf6, 0xe4, 0x27, 0x7a, 0x13, 0x26, 0x9f, 0x3b, 0xbd, 0x13, - 0x4c, 0x95, 0xbd, 0x24, 0xcb, 0x34, 0xe5, 0x6b, 0xb9, 0x41, 0x68, 0x31, 0x8a, 0x2f, 0xe4, 0xde, - 0x35, 0x1e, 0xe6, 0x0b, 0x93, 0xe6, 0x54, 0xe5, 0x97, 0x13, 0x30, 0x6d, 0x5f, 0x80, 0x29, 0x11, - 0x4a, 0x3d, 0xa1, 0x53, 0xea, 0xfc, 0x18, 0x4a, 0xfd, 0x36, 0x4c, 0x51, 0xd9, 0x0c, 0xca, 0x93, - 0x54, 0xa9, 0xaf, 0xc8, 0xd4, 0x76, 0x9b, 0xe2, 0x9a, 0xfd, 0xa7, 0x9e, 0x50, 0x66, 0x46, 0x8c, - 0xee, 0xc0, 0x62, 0xcb, 0x3b, 0x0c, 0x1d, 0xb7, 0x47, 0x3a, 0x84, 0x7d, 0xd1, 0xcb, 0x29, 0xda, - 0x4b, 0x2d, 0x2e, 0xc3, 0xac, 0x4d, 0x67, 0x9a, 0x35, 0x55, 0xb3, 0x8b, 0x63, 0x6b, 0x76, 0xd2, - 0x6a, 0x80, 0xc6, 0x6a, 0x64, 0x68, 0x6b, 0x29, 0x5b, 0x5b, 0xdf, 0x87, 0x57, 0xaa, 0x27, 0xa1, - 0xd7, 0xec, 0x1f, 0xf8, 0x54, 0xa4, 0x3f, 0xc0, 0xfd, 0x03, 0x1c, 0xab, 0xe3, 0x0c, 0x15, 0xa3, - 0x61, 0x24, 0x0f, 0xf3, 0x85, 0x82, 0x59, 0xac, 0xfc, 0x53, 0x0e, 0x0a, 0x2d, 0xef, 0xf0, 0xff, - 0xc0, 0xd2, 0xdf, 0x23, 0x16, 0x70, 0xd0, 0x73, 0x0f, 0x1c, 0xb1, 0xf8, 0x2b, 0x32, 0x7d, 0xcb, - 0x3b, 0xe4, 0x68, 0x69, 0xfd, 0x23, 0x8e, 0xc4, 0xea, 0x4c, 0x9d, 0xc6, 0xee, 0xb6, 0xbc, 0x03, - 0x87, 0xe8, 0x28, 0x5d, 0xfb, 0x84, 0xdd, 0x15, 0x38, 0xd1, 0x9e, 0x28, 0x57, 0xbe, 0x35, 0x01, - 0x33, 0x64, 0xde, 0x84, 0x40, 0xa2, 0x32, 0x4c, 0xb3, 0x02, 0x9b, 0xbe, 0xbc, 0x25, 0x8a, 0x68, - 0x53, 0x1a, 0x58, 0x8e, 0x0e, 0xec, 0xf5, 0xc4, 0xc0, 0xa2, 0x5a, 0x36, 0x04, 0x21, 0xd5, 0x6e, - 0x69, 0x78, 0x8b, 0x30, 0xc9, 0x4c, 0x1b, 0x9b, 0x5e, 0x56, 0x20, 0x26, 0xbb, 0x85, 0x9d, 0x2e, - 0xf6, 0x9b, 0x75, 0x3a, 0xc5, 0x79, 0x2b, 0x2a, 0xd3, 0xf5, 0xc0, 0xfe, 0x71, 0x79, 0x92, 0xaf, - 0x07, 0xf6, 0x8f, 0xd1, 0xc7, 0x30, 0xdf, 0xf6, 0xfa, 0x4f, 0xbc, 0xd0, 0xed, 0x1f, 0x46, 0x5d, - 0x9a, 0xa2, 0x5d, 0xba, 0x9d, 0xd9, 0xa5, 0x14, 0x07, 0xeb, 0x5b, 0xba, 0xa6, 0x95, 0xff, 0x0f, - 0xb3, 0x0a, 0x8d, 0x6c, 0x9d, 0xf2, 0xcc, 0x3a, 0x2d, 0xca, 0xd6, 0xa9, 0x28, 0x19, 0xa2, 0x95, - 0x3a, 0x2c, 0xeb, 0x5b, 0x3a, 0x4d, 0x2d, 0x95, 0xef, 0x18, 0x30, 0xa7, 0x4a, 0x0a, 0xfa, 0x40, - 0x5d, 0x28, 0x5a, 0x4f, 0xe9, 0x4e, 0x39, 0x6b, 0xbc, 0x9b, 0x05, 0xb2, 0xd2, 0x3f, 0xfc, 0xc9, - 0x0d, 0xc3, 0x52, 0x17, 0xf8, 0x1a, 0x14, 0x45, 0xb5, 0x75, 0xda, 0x70, 0xde, 0x8a, 0x01, 0x68, - 0x0d, 0x4a, 0xcd, 0x20, 0x1a, 0x00, 0x5d, 0xa6, 0x82, 0x25, 0x83, 0x2a, 0x7f, 0x62, 0xc4, 0x5b, - 0x3c, 0xdd, 0x6c, 0x77, 0x76, 0x6d, 0x2f, 0x74, 0x7a, 0x7c, 0x60, 0x51, 0x99, 0x18, 0x8c, 0xda, - 0xce, 0x6e, 0xf5, 0xb9, 0xe3, 0xf6, 0x9c, 0xfd, 0x1e, 0x1b, 0xa4, 0x61, 0x29, 0x30, 0xc2, 0xff, - 0x18, 0x1f, 0x33, 0x7e, 0x26, 0x12, 0x51, 0x99, 0xf0, 0x3f, 0xc6, 0xc7, 0x31, 0x3f, 0x93, 0x0c, - 0x05, 0x56, 0xf9, 0x71, 0x11, 0x4c, 0xee, 0x23, 0x6d, 0x61, 0xc7, 0x0f, 0xf7, 0xb1, 0x13, 0xfe, - 0x06, 0x3a, 0x91, 0x1b, 0x80, 0x6c, 0x27, 0x10, 0xbc, 0x35, 0x1f, 0x3b, 0xc4, 0xf8, 0x4d, 0xd3, - 0xc9, 0xd7, 0x60, 0x52, 0xb6, 0xb8, 0xa0, 0xb1, 0xc5, 0x37, 0x61, 0xb6, 0xd9, 0x77, 0xc3, 0xd8, - 0x39, 0x2c, 0x52, 0x22, 0x15, 0x48, 0xa8, 0x1e, 0x78, 0x41, 0xe0, 0x0e, 0x54, 0xb3, 0xae, 0x02, - 0x49, 0x7b, 0x0c, 0xf0, 0xd0, 0x73, 0xfb, 0xb8, 0x4b, 0x0d, 0x7a, 0xc1, 0x52, 0x60, 0xbf, 0x76, - 0x8f, 0x31, 0x63, 0xaf, 0x99, 0x1b, 0xcf, 0x33, 0xbc, 0x9c, 0xf0, 0x0c, 0x3f, 0x0b, 0x0b, 0xd5, - 0x83, 0x23, 0xdc, 0x25, 0x00, 0xa7, 0xdf, 0xdd, 0x74, 0xc2, 0x83, 0x67, 0xdc, 0x81, 0xcc, 0x5b, - 0x3a, 0x14, 0xd9, 0xb9, 0x38, 0xa4, 0x8e, 0x7b, 0xee, 0x73, 0x32, 0xf3, 0x07, 0x47, 0x49, 0x47, - 0x72, 0x18, 0xc9, 0x18, 0xde, 0x28, 0xba, 0x28, 0x6f, 0x74, 0xe1, 0x02, 0xbc, 0xd1, 0xc5, 0x51, - 0xde, 0x68, 0x62, 0x3c, 0x35, 0x27, 0x74, 0x7a, 0xde, 0x21, 0xdd, 0xae, 0x79, 0x15, 0x4b, 0xb4, - 0x8a, 0x11, 0x54, 0x68, 0x13, 0xae, 0xc9, 0x14, 0x16, 0x7e, 0xea, 0xe3, 0xe0, 0x59, 0x3c, 0x2b, - 0xcc, 0xb7, 0x1c, 0x4a, 0x93, 0xae, 0xe3, 0xb9, 0xd3, 0x73, 0xbb, 0x44, 0x79, 0x58, 0x4f, 0xae, - 0xd0, 0x9e, 0x0c, 0xa5, 0x19, 0xea, 0xdf, 0x96, 0x87, 0xfb, 0xb7, 0xc3, 0x3d, 0xeb, 0xab, 0x23, - 0x3c, 0x6b, 0xee, 0xcd, 0xda, 0x30, 0x53, 0x6b, 0x57, 0x7b, 0x3d, 0xef, 0xc0, 0x09, 0x71, 0xb3, - 0xae, 0x71, 0x92, 0x17, 0x61, 0x92, 0x8a, 0x23, 0xb7, 0xe3, 0xac, 0xc0, 0x2c, 0xfc, 0xd7, 0x4e, - 0x70, 0x40, 0x04, 0x9d, 0x99, 0xb0, 0x18, 0x50, 0xf9, 0xaf, 0x09, 0x98, 0x17, 0x9e, 0xd2, 0x70, - 0x9b, 0xb9, 0x06, 0x25, 0xcb, 0x79, 0x1a, 0xaa, 0x06, 0x53, 0x06, 0x69, 0xac, 0xea, 0x84, 0xd6, - 0xaa, 0xa6, 0xac, 0x4c, 0x5e, 0x67, 0x65, 0xce, 0xe7, 0x39, 0xe9, 0x6d, 0xe8, 0x54, 0xa6, 0x0d, - 0x55, 0xed, 0xd5, 0xf4, 0x99, 0x3c, 0xad, 0xc2, 0xf8, 0x9e, 0x16, 0x91, 0xa6, 0x84, 0x31, 0x88, - 0x25, 0xba, 0xc8, 0xa4, 0x29, 0x0b, 0x3f, 0x86, 0xa5, 0x80, 0x71, 0x2c, 0x45, 0xa5, 0x01, 0x25, - 0xe9, 0xf0, 0x31, 0xc4, 0xd7, 0x1b, 0xea, 0x24, 0x54, 0xbe, 0x3e, 0x09, 0xa6, 0x7d, 0x91, 0xbb, - 0x6e, 0x7c, 0x5c, 0x9a, 0x38, 0xcd, 0x71, 0x49, 0xbf, 0xe4, 0xf9, 0xcc, 0x25, 0xcf, 0x3a, 0x5e, - 0x4d, 0x9e, 0xfa, 0x78, 0x35, 0x35, 0xe6, 0xf1, 0xaa, 0x70, 0xe6, 0xe3, 0x55, 0x71, 0xfc, 0xe3, - 0x15, 0x64, 0x6f, 0x79, 0x44, 0x85, 0xf1, 0xa0, 0xe7, 0xbc, 0xc4, 0xdd, 0x56, 0xd0, 0xa7, 0xfb, - 0x76, 0xde, 0x92, 0x41, 0xe7, 0x3f, 0x80, 0x65, 0x6d, 0x9d, 0xb3, 0x67, 0xde, 0x3a, 0xe7, 0x46, - 0x6e, 0x9d, 0x0f, 0xf3, 0x85, 0x69, 0xb3, 0x50, 0xf9, 0xfe, 0x24, 0x14, 0xac, 0xce, 0x63, 0xe6, - 0xc9, 0x98, 0x30, 0x61, 0x07, 0x9e, 0x70, 0xaf, 0xed, 0xc0, 0x23, 0xd6, 0xb1, 0xd9, 0xef, 0xe2, - 0x17, 0xc2, 0x3a, 0xd2, 0x02, 0xb1, 0x45, 0x2d, 0xec, 0x04, 0x78, 0xcb, 0xeb, 0xb1, 0x13, 0x07, - 0xf3, 0x3b, 0x55, 0x20, 0x59, 0x0e, 0xdb, 0x3f, 0xe9, 0x13, 0xcb, 0x4b, 0x67, 0x8e, 0x3b, 0x9f, - 0x32, 0x0c, 0x3d, 0x84, 0x19, 0xc6, 0xe4, 0x06, 0xa1, 0xe7, 0xbf, 0xe4, 0x36, 0x4b, 0x39, 0x14, - 0x89, 0xde, 0x6d, 0xc8, 0x84, 0xec, 0xe0, 0xa1, 0xf0, 0xb2, 0x85, 0xfa, 0xda, 0x89, 0xeb, 0xb3, - 0xe6, 0xa6, 0xc4, 0x42, 0x45, 0x20, 0xf4, 0x16, 0xcc, 0x7f, 0x54, 0x6d, 0x59, 0xf8, 0xc0, 0x23, - 0xb3, 0x51, 0x77, 0x0f, 0x71, 0x10, 0xf2, 0x63, 0x7e, 0x1a, 0x81, 0x3e, 0x07, 0x4b, 0x12, 0x90, - 0xb6, 0x58, 0xf3, 0x4e, 0xfa, 0x21, 0x95, 0xc8, 0xbc, 0xa5, 0x47, 0x92, 0x85, 0x91, 0x10, 0x35, - 0xef, 0x78, 0xd0, 0xc3, 0x64, 0x3b, 0xec, 0x87, 0xbe, 0x8b, 0x99, 0x4c, 0xe6, 0xad, 0x61, 0x24, - 0x44, 0x5d, 0x24, 0xf4, 0xa6, 0x13, 0x60, 0x32, 0x1c, 0xa0, 0x8c, 0x1a, 0x4c, 0x82, 0xbe, 0xe5, - 0x04, 0x61, 0x2c, 0xa7, 0x1a, 0x0c, 0x7a, 0x08, 0x6b, 0x12, 0x74, 0xdb, 0x77, 0x0f, 0xdd, 0xbe, - 0xd3, 0x53, 0x17, 0x74, 0x86, 0x72, 0x8f, 0xa4, 0x23, 0x82, 0xab, 0x19, 0x0a, 0x15, 0xdc, 0x82, - 0xa5, 0x43, 0xad, 0xbc, 0x07, 0xf3, 0xa9, 0x85, 0x1c, 0x75, 0xae, 0xcb, 0xcb, 0xe7, 0xba, 0x8f, - 0xa1, 0x48, 0xb7, 0xb1, 0x03, 0xcf, 0xef, 0x12, 0x46, 0x32, 0x58, 0xce, 0x48, 0x46, 0xb7, 0x0e, - 0x79, 0xfb, 0xe5, 0x80, 0xf1, 0xcd, 0xa9, 0x66, 0x83, 0xf1, 0x10, 0xac, 0x45, 0x69, 0x88, 0xbd, - 0xa5, 0x26, 0x86, 0x88, 0xef, 0x8c, 0x45, 0x7f, 0x57, 0x7e, 0x9a, 0x03, 0xa0, 0xf5, 0xd3, 0xcd, - 0x9e, 0x90, 0xb4, 0x9d, 0x63, 0x2c, 0x4c, 0x32, 0xf9, 0x2d, 0xdb, 0xfc, 0x9c, 0x6a, 0xf3, 0x79, - 0x77, 0x26, 0xe2, 0xee, 0x94, 0x61, 0xfa, 0xb1, 0xf3, 0xa2, 0xe3, 0xfe, 0x9e, 0x38, 0x7c, 0x89, - 0x22, 0xd9, 0x1f, 0x84, 0x59, 0xae, 0xf3, 0xa3, 0x79, 0x0c, 0xa0, 0x67, 0xf6, 0x76, 0xb3, 0xce, - 0xa5, 0x98, 0xfe, 0x46, 0x9f, 0x83, 0x9c, 0xdd, 0xe1, 0xdb, 0xec, 0xca, 0x06, 0xbb, 0x23, 0xd8, - 0x10, 0x77, 0x04, 0x1b, 0xb6, 0xb8, 0x23, 0x60, 0xc7, 0xd6, 0x3f, 0xfb, 0xd7, 0x1b, 0x86, 0x95, - 0xb3, 0x3b, 0x64, 0xe3, 0x6b, 0xf6, 0x0f, 0x7a, 0x27, 0x5d, 0xdc, 0x78, 0x31, 0x20, 0x9a, 0xc0, - 0x37, 0x21, 0x6e, 0xdf, 0x30, 0x3b, 0xfa, 0x14, 0xac, 0x11, 0x54, 0xc4, 0x45, 0x6e, 0xbc, 0xa0, - 0x14, 0x5b, 0x8e, 0xdf, 0xad, 0x7b, 0x9f, 0xf4, 0x53, 0x15, 0xb1, 0x3d, 0x78, 0x14, 0x59, 0xa5, - 0x02, 0x60, 0x07, 0x9e, 0x98, 0xe1, 0x45, 0x98, 0x64, 0x6a, 0xc5, 0x16, 0x91, 0x15, 0x2a, 0xbf, - 0x30, 0x88, 0xe7, 0x46, 0xf7, 0x47, 0x1a, 0xac, 0xd4, 0xee, 0x8d, 0x77, 0xa1, 0xb8, 0x3d, 0x10, - 0xfe, 0x79, 0x2e, 0x1d, 0x58, 0xaa, 0xb5, 0x29, 0xef, 0xf6, 0xc0, 0x8a, 0xe9, 0xd0, 0x66, 0x74, - 0x59, 0xc0, 0x36, 0xca, 0x9b, 0x9a, 0xcb, 0x02, 0x4a, 0x90, 0x7d, 0x63, 0x70, 0xd1, 0xa1, 0xd7, - 0x4a, 0x0b, 0x4a, 0xb5, 0x76, 0x7c, 0xa2, 0xd4, 0x8d, 0xf5, 0x4d, 0x11, 0x40, 0xcb, 0x65, 0x5f, - 0x50, 0x30, 0x8a, 0xca, 0xcf, 0xf8, 0xdc, 0x39, 0xe1, 0x90, 0xb9, 0x1b, 0xbf, 0xbe, 0xd1, 0x33, - 0x26, 0x1a, 0xfa, 0x35, 0xce, 0xd8, 0x37, 0x0b, 0x30, 0x2d, 0x24, 0x48, 0x71, 0xd6, 0x0d, 0xe1, - 0x69, 0x71, 0x00, 0xda, 0x80, 0xa9, 0xc7, 0x38, 0x7c, 0xe6, 0x75, 0x75, 0x26, 0x81, 0x61, 0xa8, - 0x49, 0xe0, 0x54, 0xe8, 0x9e, 0xac, 0xff, 0x54, 0x95, 0x13, 0xde, 0x47, 0x8c, 0xe5, 0x63, 0x94, - 0xed, 0x45, 0x95, 0x86, 0x98, 0x22, 0x97, 0x8e, 0x2a, 0x7d, 0xe9, 0xce, 0xf5, 0x64, 0x88, 0x49, - 0xf1, 0xfb, 0x2c, 0x85, 0x05, 0xdd, 0x27, 0xc2, 0x10, 0xd7, 0x30, 0x49, 0x6b, 0xb8, 0xa6, 0x91, - 0xd2, 0xb8, 0x02, 0x99, 0x81, 0xf0, 0xdb, 0x12, 0xff, 0x54, 0x9a, 0xdf, 0x4e, 0xf1, 0x4b, 0x0c, - 0xc4, 0xfd, 0x8a, 0xd5, 0x53, 0xe7, 0xd5, 0xc7, 0x58, 0x4b, 0x56, 0xe4, 0x7b, 0xea, 0x59, 0x8b, - 0x3b, 0x6e, 0x65, 0xb5, 0xe3, 0x31, 0xde, 0x52, 0x4f, 0x66, 0xf7, 0x54, 0x7d, 0xe7, 0x51, 0xf5, - 0x72, 0x96, 0x72, 0x5a, 0xaa, 0x75, 0xf8, 0xbc, 0xa2, 0x40, 0x74, 0xb3, 0x4c, 0xb8, 0xc0, 0x12, - 0xda, 0x52, 0x94, 0xed, 0x9e, 0xaa, 0x2c, 0x74, 0xe3, 0xd4, 0x34, 0x2c, 0xf0, 0x96, 0xaa, 0x5a, - 0xef, 0xc1, 0x6c, 0x1d, 0x93, 0x8d, 0x8d, 0x77, 0x87, 0x47, 0x6d, 0xae, 0xca, 0xec, 0x0a, 0x81, - 0xa5, 0xd2, 0xa3, 0x4d, 0x98, 0xdb, 0xf1, 0xbd, 0x17, 0x2f, 0xe3, 0x05, 0x9b, 0xe5, 0x06, 0x5e, - 0xaa, 0x41, 0xa5, 0xb0, 0x12, 0x1c, 0x64, 0x17, 0x4e, 0x06, 0x4c, 0xdb, 0x27, 0xc7, 0xd4, 0x09, - 0xcc, 0x5b, 0x3a, 0x14, 0xda, 0x94, 0xc2, 0xbf, 0xd1, 0x51, 0xec, 0x72, 0xf6, 0x51, 0xcc, 0x4a, - 0x93, 0xd3, 0x39, 0x7f, 0x86, 0x0f, 0x8e, 0xb6, 0xb0, 0xd3, 0x0b, 0x9f, 0xd1, 0x38, 0x4f, 0x72, - 0xce, 0x63, 0xb4, 0x25, 0xd3, 0x22, 0x1b, 0x16, 0x3b, 0x07, 0xcf, 0x70, 0xf7, 0xa4, 0x87, 0xb9, - 0x8b, 0x4a, 0x9d, 0x74, 0x1a, 0xf1, 0x29, 0xdd, 0x59, 0x93, 0xeb, 0xd0, 0xd1, 0x59, 0x5a, 0xee, - 0x8a, 0x07, 0x25, 0xaa, 0x89, 0xc1, 0xc0, 0xeb, 0x07, 0x78, 0xc8, 0xd1, 0x8c, 0x6f, 0xd3, 0x39, - 0x65, 0x9b, 0x16, 0x8e, 0x13, 0xdb, 0xbc, 0x45, 0x71, 0x58, 0x60, 0xbd, 0xb2, 0x01, 0x48, 0x92, - 0x67, 0xa9, 0xdd, 0x0f, 0x5c, 0x5f, 0x32, 0x46, 0xa2, 0x58, 0xf9, 0xcf, 0x3c, 0x0d, 0xd4, 0x31, - 0xb2, 0x8b, 0xb5, 0x5a, 0xd7, 0xa0, 0xd8, 0xf0, 0x7d, 0xcf, 0xaf, 0x79, 0x5d, 0x4c, 0x87, 0x30, - 0x6b, 0xc5, 0x00, 0xe2, 0x8a, 0xd3, 0xc2, 0x63, 0x1c, 0x04, 0xce, 0x21, 0xe6, 0xb1, 0x03, 0x05, - 0x86, 0x56, 0x01, 0x9a, 0xc1, 0x56, 0xf5, 0x11, 0xc6, 0x03, 0xec, 0x53, 0xab, 0x53, 0xb0, 0x24, - 0x08, 0x7a, 0x4f, 0x99, 0x5d, 0x6e, 0x56, 0xae, 0xa4, 0x0c, 0x23, 0x43, 0x73, 0xcb, 0xa8, 0xac, - 0x07, 0x51, 0x34, 0xe9, 0x10, 0xc3, 0x2d, 0x8b, 0xaa, 0x68, 0x12, 0xde, 0x52, 0xa8, 0x89, 0xb4, - 0x51, 0x5b, 0xc3, 0x9b, 0x2f, 0xa4, 0x9b, 0x97, 0xd0, 0x96, 0x4c, 0x4b, 0x54, 0xac, 0xd6, 0x3b, - 0x09, 0x42, 0xec, 0xd7, 0x31, 0x39, 0x9d, 0x06, 0xdc, 0xb8, 0x28, 0x2a, 0xa6, 0x52, 0x58, 0x09, - 0x0e, 0x74, 0x1f, 0x8a, 0xf1, 0xbd, 0x01, 0x68, 0xc4, 0x54, 0x20, 0x99, 0x80, 0xe2, 0xe0, 0xa4, - 0x17, 0x5a, 0x31, 0x0b, 0xba, 0x0f, 0x20, 0x99, 0x46, 0x66, 0x63, 0x56, 0xe5, 0x0a, 0xd2, 0x82, - 0x64, 0x41, 0xc2, 0x3c, 0x12, 0x05, 0xc2, 0x3e, 0xb3, 0x70, 0x33, 0x9a, 0xc9, 0x93, 0xf0, 0x96, - 0x42, 0x5d, 0x79, 0x48, 0xe3, 0x55, 0xcc, 0xff, 0x8d, 0xa6, 0xe5, 0x6d, 0xb2, 0x83, 0x12, 0x48, - 0x50, 0x36, 0xe8, 0xbe, 0xbe, 0x94, 0x5a, 0x4c, 0x82, 0xe5, 0x4b, 0x29, 0x68, 0x2b, 0xaf, 0x29, - 0x0b, 0x41, 0xdc, 0xb7, 0x27, 0x74, 0xdf, 0xe6, 0xee, 0x1b, 0x2d, 0x54, 0x1e, 0xc0, 0xac, 0xed, - 0x04, 0x47, 0xb6, 0xb3, 0xdf, 0xc3, 0xbb, 0x01, 0xf6, 0x89, 0x1a, 0x91, 0xbf, 0xfd, 0xd8, 0x97, - 0x8e, 0xca, 0x04, 0xb7, 0xe3, 0x04, 0xc1, 0x27, 0x9e, 0xdf, 0xe5, 0xc1, 0x8d, 0xa8, 0x5c, 0xf9, - 0x86, 0x41, 0x7a, 0x49, 0xed, 0x96, 0xd6, 0x8d, 0xc9, 0xf6, 0xc5, 0x95, 0xf8, 0xcb, 0x44, 0xf2, - 0x92, 0x26, 0xba, 0x45, 0xcb, 0xcb, 0xb7, 0x68, 0xab, 0x74, 0xef, 0x57, 0x9d, 0x72, 0x09, 0x52, - 0xf9, 0xcb, 0x1c, 0x91, 0xe1, 0xfe, 0x53, 0xf7, 0xb0, 0xf6, 0xcc, 0xe9, 0x1f, 0x62, 0x74, 0x37, - 0xea, 0x1d, 0xbf, 0x4c, 0x5a, 0x50, 0x0f, 0x1c, 0x14, 0x15, 0xcf, 0x20, 0x1b, 0xc7, 0x3d, 0x00, - 0xc6, 0x2e, 0x1d, 0x54, 0xae, 0xa5, 0xe3, 0x1b, 0x31, 0x8d, 0x25, 0xd1, 0x23, 0x1b, 0xe6, 0x9a, - 0x7d, 0x37, 0x74, 0x9d, 0xde, 0x63, 0x7c, 0xbc, 0x8f, 0x7d, 0xe1, 0x95, 0xbd, 0x95, 0x55, 0xc3, - 0x86, 0x4a, 0xce, 0x8e, 0xce, 0x89, 0x3a, 0x56, 0xaa, 0xb0, 0xa0, 0x21, 0x3b, 0xd5, 0x85, 0xdb, - 0x9b, 0x30, 0xdb, 0x79, 0x76, 0x12, 0x76, 0xbd, 0x4f, 0xfa, 0x6c, 0x6b, 0x23, 0x6b, 0x43, 0x7e, - 0x44, 0x4b, 0x26, 0x8a, 0x95, 0x7f, 0x98, 0x84, 0xcb, 0x09, 0x13, 0xae, 0x5d, 0xdd, 0x9b, 0x30, - 0xbb, 0xe9, 0x79, 0x61, 0x10, 0xfa, 0xce, 0x60, 0xe0, 0xf6, 0x0f, 0x69, 0xa3, 0x05, 0x4b, 0x05, - 0x12, 0xd3, 0xc0, 0x63, 0x36, 0x74, 0x42, 0x27, 0xe8, 0x84, 0x2a, 0xa6, 0x41, 0x42, 0x5b, 0x32, - 0x2d, 0xb3, 0x49, 0xf1, 0x54, 0x71, 0x77, 0xad, 0x9c, 0x35, 0x95, 0x96, 0xba, 0xfa, 0xef, 0x25, - 0x46, 0xcc, 0x7d, 0xb5, 0xab, 0xaa, 0x61, 0x90, 0x08, 0xac, 0xc4, 0x0c, 0x3d, 0x82, 0x79, 0x16, - 0x58, 0x93, 0x22, 0x6d, 0xdc, 0xb2, 0x2a, 0x2e, 0x63, 0x8a, 0xc8, 0x4a, 0xf3, 0xa5, 0x5d, 0x91, - 0xe9, 0x53, 0xba, 0x22, 0x8f, 0x60, 0xfe, 0xa1, 0xe7, 0xf6, 0x59, 0x44, 0x99, 0xdb, 0x3f, 0x6e, - 0x68, 0x95, 0xde, 0xa4, 0x88, 0xac, 0x34, 0x1f, 0xda, 0x02, 0x93, 0xd5, 0x4e, 0x7d, 0x15, 0xd6, - 0xa1, 0x62, 0xda, 0x15, 0x4d, 0xd2, 0x58, 0x29, 0x2e, 0xb2, 0xbc, 0xd5, 0x6e, 0x57, 0x68, 0xa1, - 0xce, 0xb7, 0x93, 0xd0, 0x96, 0x4c, 0x4b, 0x2c, 0x7f, 0x24, 0x2a, 0x8c, 0xbb, 0x94, 0xb6, 0xfc, - 0x2a, 0x85, 0x95, 0xe0, 0xa8, 0x60, 0xbd, 0xaf, 0xa2, 0x95, 0xd7, 0x84, 0x24, 0xe6, 0xc6, 0x97, - 0xc4, 0xca, 0x9f, 0xe7, 0x60, 0x39, 0x11, 0xae, 0xb3, 0x1d, 0xff, 0x10, 0x87, 0xf4, 0xea, 0x90, - 0x2f, 0x11, 0x69, 0x84, 0x59, 0xeb, 0xa2, 0xa5, 0xc0, 0x68, 0xb0, 0x4d, 0xa6, 0xc9, 0x31, 0x1a, - 0x19, 0x46, 0xec, 0x6c, 0xe3, 0x05, 0x31, 0x41, 0x6e, 0xc8, 0x6f, 0xa5, 0xa3, 0x32, 0x71, 0x21, - 0x79, 0x7d, 0xb6, 0x7b, 0x8c, 0xbd, 0x93, 0xd0, 0x76, 0x0f, 0x8e, 0x02, 0x6e, 0x1d, 0x75, 0x28, - 0xc2, 0x61, 0x6b, 0x38, 0x98, 0xd1, 0xd4, 0xa1, 0xd0, 0xe7, 0x60, 0xa9, 0x41, 0xcc, 0x85, 0x13, - 0xe2, 0xda, 0x89, 0xef, 0xe3, 0x7e, 0x48, 0x69, 0x02, 0x7e, 0xc3, 0xa0, 0x47, 0x56, 0x6e, 0x6b, - 0xa4, 0x92, 0x0d, 0xc5, 0x0d, 0xe8, 0x05, 0x3b, 0x9b, 0x8e, 0xa8, 0x5c, 0xe9, 0x69, 0x94, 0x0a, - 0xdd, 0x85, 0x3c, 0xd9, 0x6f, 0xb8, 0x95, 0x56, 0x74, 0x42, 0xd9, 0xa8, 0xb8, 0xad, 0xa6, 0xc4, - 0x74, 0x52, 0x9d, 0xe0, 0xa8, 0xee, 0x84, 0xce, 0xbe, 0x13, 0x08, 0x93, 0xa7, 0xc0, 0x88, 0xd5, - 0x53, 0xb5, 0x28, 0xdb, 0xea, 0xbd, 0x95, 0x56, 0x89, 0x21, 0xd4, 0x6f, 0x28, 0x62, 0x9f, 0xed, - 0xcd, 0x56, 0x7e, 0x69, 0x24, 0xa5, 0xfc, 0xac, 0xb7, 0x12, 0xe8, 0x49, 0xc6, 0xde, 0xb2, 0x91, - 0xad, 0x2f, 0xe3, 0xec, 0x2e, 0x44, 0x57, 0xc8, 0x1a, 0xf2, 0x7b, 0x05, 0xfa, 0xfb, 0x22, 0x76, - 0x9c, 0xbf, 0xc8, 0xa9, 0x2e, 0x65, 0x94, 0xe9, 0x62, 0x48, 0x99, 0x2e, 0x5f, 0x64, 0x57, 0xd6, - 0x4e, 0xbf, 0x2b, 0x72, 0x6e, 0x5e, 0x19, 0x72, 0xbe, 0x10, 0x77, 0x4e, 0x82, 0x85, 0x4c, 0xa5, - 0x08, 0xc7, 0xf3, 0x93, 0x81, 0x08, 0xc1, 0xd7, 0x00, 0x38, 0x15, 0x51, 0xb8, 0x3c, 0xad, 0xfa, - 0xfa, 0x90, 0xaa, 0x9b, 0x75, 0x11, 0x2f, 0x88, 0xd9, 0xd0, 0x47, 0xb0, 0xa4, 0xbd, 0x70, 0xe2, - 0x5b, 0xc9, 0xab, 0x72, 0x7d, 0xfa, 0x2c, 0x44, 0x3d, 0x7f, 0xe5, 0xbb, 0xb9, 0x8c, 0x9a, 0x89, - 0x08, 0xec, 0xf8, 0x78, 0xe0, 0xf8, 0x4c, 0x79, 0xc8, 0x8a, 0xc4, 0x00, 0x32, 0xde, 0x46, 0x9f, - 0x68, 0x43, 0x97, 0x6f, 0xb6, 0xa2, 0x98, 0x91, 0x78, 0x74, 0x07, 0x16, 0xa3, 0x5b, 0x5f, 0x9a, - 0x14, 0xc9, 0xc2, 0xed, 0x7c, 0xa9, 0xb5, 0x38, 0xb4, 0x01, 0x48, 0x73, 0xb3, 0xcd, 0x2c, 0x87, - 0x06, 0x43, 0xdc, 0x32, 0xe9, 0x22, 0x9e, 0x85, 0x44, 0x25, 0x08, 0xe9, 0x19, 0xbb, 0x15, 0x66, - 0xe9, 0x1e, 0xac, 0x40, 0x6c, 0x04, 0x19, 0x74, 0x18, 0xe2, 0x2e, 0x0f, 0x71, 0x46, 0xe5, 0xca, - 0x8f, 0x0d, 0xf5, 0x72, 0x3b, 0x9a, 0x1d, 0x61, 0x73, 0x65, 0x5b, 0x69, 0x8c, 0x67, 0x2b, 0x73, - 0xd9, 0xb6, 0xf2, 0x1d, 0x58, 0x8e, 0x75, 0x5e, 0x61, 0x62, 0x73, 0x99, 0x81, 0xcd, 0xb6, 0x98, - 0xf9, 0x61, 0x16, 0xf3, 0xbb, 0x25, 0x28, 0xf1, 0x5e, 0xd0, 0xb3, 0x87, 0xc8, 0xc7, 0x33, 0xa4, - 0x7c, 0xbc, 0xdf, 0xae, 0x64, 0x9e, 0x6a, 0x14, 0xa1, 0x2c, 0x50, 0x35, 0x7c, 0x4d, 0x13, 0x36, - 0xa2, 0x19, 0x6c, 0x63, 0x26, 0x81, 0x17, 0xcf, 0x94, 0x04, 0x0e, 0xfa, 0x14, 0x22, 0xf5, 0xda, - 0xbe, 0x34, 0x4e, 0x72, 0xd0, 0xcc, 0xc8, 0xe4, 0xa0, 0xd9, 0x33, 0x25, 0x07, 0xcd, 0x9d, 0x29, - 0x9d, 0xfc, 0xf2, 0x38, 0xe9, 0xe4, 0xe6, 0x78, 0x49, 0x43, 0xf3, 0x89, 0xa4, 0xa1, 0x11, 0xf7, - 0x98, 0xe8, 0x22, 0x52, 0x80, 0x16, 0x2e, 0x2a, 0x05, 0x68, 0xf1, 0x02, 0x52, 0x80, 0x96, 0xce, - 0x9f, 0x02, 0xb4, 0x7c, 0x21, 0x29, 0x40, 0x57, 0x2e, 0x20, 0x05, 0xa8, 0x3c, 0x46, 0x0a, 0xd0, - 0xf0, 0x04, 0xfb, 0xab, 0x23, 0x13, 0xec, 0x87, 0xa5, 0x10, 0xad, 0x9c, 0x27, 0x85, 0xe8, 0x95, - 0x11, 0x29, 0x44, 0xbf, 0xa2, 0x04, 0xfb, 0xbf, 0x32, 0xd8, 0x5b, 0x1d, 0xfe, 0x70, 0x85, 0x1b, - 0x74, 0x43, 0xff, 0x70, 0xc5, 0x09, 0xf1, 0x06, 0xa3, 0x50, 0x6c, 0x16, 0x03, 0xad, 0x58, 0x50, - 0x92, 0x90, 0x9a, 0x0e, 0x7e, 0x46, 0xed, 0xe0, 0x95, 0x0c, 0xb3, 0x28, 0xfb, 0x54, 0xff, 0x92, - 0xa7, 0x09, 0x2e, 0x17, 0xb2, 0x79, 0xfc, 0x2e, 0x27, 0xe5, 0x37, 0x38, 0x27, 0x65, 0x84, 0x65, - 0x9e, 0x1d, 0x37, 0xc3, 0x84, 0xc8, 0xbb, 0x3d, 0x8e, 0xbc, 0xdb, 0xbf, 0x5a, 0x79, 0xb7, 0xf5, - 0xf2, 0xfe, 0xf7, 0x13, 0x00, 0xd2, 0x79, 0x4c, 0x77, 0xaa, 0x17, 0x2a, 0x90, 0x93, 0x54, 0xe0, - 0x26, 0xcc, 0x12, 0xf5, 0xc6, 0x7d, 0xd5, 0x35, 0x52, 0x81, 0x09, 0xa9, 0xc9, 0x8f, 0x2d, 0x35, - 0xa3, 0xf7, 0xb4, 0xc9, 0x8b, 0xda, 0xd3, 0xa6, 0x2e, 0x60, 0x4f, 0x9b, 0x3e, 0xdf, 0x23, 0xab, - 0xc2, 0xa8, 0x3d, 0xa0, 0xf2, 0x77, 0x46, 0xb4, 0x48, 0x44, 0x8c, 0xde, 0x4f, 0x88, 0x51, 0x25, - 0x75, 0x57, 0x36, 0x4a, 0x92, 0x3e, 0x1c, 0x25, 0x49, 0x6f, 0xa9, 0x92, 0xb4, 0xac, 0x69, 0xc1, - 0xf3, 0xb1, 0x2c, 0x48, 0x3f, 0xca, 0x25, 0x6f, 0xf2, 0xb2, 0x42, 0x9a, 0xaa, 0xe0, 0xe4, 0x46, - 0x0b, 0xce, 0xc4, 0x05, 0x0a, 0x4e, 0xfe, 0xa2, 0x04, 0x67, 0xf2, 0x02, 0x04, 0x67, 0x6a, 0x84, - 0xe0, 0x54, 0xbe, 0x3d, 0x91, 0xbc, 0xbb, 0x41, 0x6f, 0x43, 0x81, 0xab, 0xb2, 0x58, 0xfe, 0x05, - 0x8d, 0x9a, 0x0b, 0x77, 0x56, 0x90, 0x12, 0xb6, 0x9a, 0x60, 0xcb, 0xa5, 0xd9, 0x6a, 0x2a, 0x9b, - 0x20, 0x45, 0xef, 0xd2, 0x6c, 0x23, 0xce, 0xc7, 0x76, 0xb1, 0x45, 0xdd, 0x65, 0x3e, 0x67, 0x8c, - 0x89, 0xd1, 0x7d, 0x28, 0xc5, 0x82, 0x22, 0xe2, 0x03, 0x19, 0x72, 0x24, 0xae, 0xcb, 0x24, 0x06, - 0x54, 0x17, 0x81, 0xa5, 0x2e, 0xaf, 0x81, 0xe5, 0xc6, 0x95, 0xd3, 0xd1, 0xd3, 0xae, 0x5c, 0x87, - 0xca, 0x94, 0x1d, 0x5f, 0x98, 0x3a, 0x67, 0x7c, 0xe1, 0x8f, 0x0c, 0x28, 0xf1, 0x95, 0xa1, 0x7e, - 0xc2, 0xe7, 0xe9, 0xb2, 0xb0, 0xdd, 0xde, 0xe0, 0xbb, 0x7d, 0xe4, 0x0e, 0x71, 0x8c, 0x72, 0xa1, - 0x14, 0x91, 0xa3, 0x7b, 0x6c, 0x8e, 0x19, 0x6f, 0x8e, 0x8f, 0x32, 0x76, 0xa5, 0x44, 0x64, 0x57, - 0x66, 0x8e, 0x19, 0x2a, 0xdf, 0xcb, 0xc3, 0x12, 0x0f, 0x24, 0x89, 0x70, 0x34, 0x4f, 0x48, 0x78, - 0x1d, 0xe6, 0xda, 0x27, 0xc7, 0xdb, 0x4f, 0xe3, 0xca, 0x99, 0x13, 0x93, 0x80, 0x12, 0x95, 0xa4, - 0x90, 0xa8, 0xff, 0xcc, 0xd0, 0xab, 0x40, 0xb4, 0x0e, 0xa6, 0xe0, 0x8b, 0x52, 0xac, 0xd9, 0xe9, - 0x3d, 0x05, 0x27, 0x67, 0xa7, 0x36, 0x7e, 0x11, 0x46, 0x57, 0xc6, 0xbc, 0x84, 0x6c, 0x28, 0xb1, - 0x5f, 0x9b, 0x2f, 0x1f, 0x61, 0x91, 0xed, 0x78, 0x47, 0x5e, 0x03, 0xed, 0x48, 0x36, 0x24, 0x26, - 0x16, 0x60, 0x93, 0xab, 0x41, 0x4f, 0x75, 0x97, 0xf9, 0xec, 0x2d, 0xd7, 0xbb, 0x63, 0xd4, 0x9d, - 0x64, 0x4d, 0x3e, 0xea, 0x8a, 0x2e, 0xfc, 0xa9, 0xcf, 0x74, 0x28, 0x6e, 0x20, 0x78, 0x62, 0x9f, - 0x38, 0x95, 0xa7, 0x31, 0x2b, 0xf7, 0xc1, 0x4c, 0x76, 0x5c, 0x9f, 0x80, 0xaf, 0xcf, 0xf4, 0x53, - 0xde, 0x81, 0x29, 0x9d, 0x1b, 0x55, 0x8b, 0x12, 0x24, 0xfc, 0x6f, 0x03, 0xae, 0x5a, 0x38, 0x60, - 0x51, 0xd5, 0x8f, 0x9c, 0x10, 0xfb, 0xc7, 0x8e, 0x7f, 0x24, 0x64, 0x24, 0x5e, 0x29, 0x43, 0x59, - 0xa9, 0x2f, 0xa9, 0x2b, 0xc5, 0xa4, 0xf2, 0x9d, 0xc4, 0xc1, 0x59, 0x5f, 0xe7, 0x88, 0xd5, 0xd2, - 0xcf, 0xe2, 0xc4, 0xaf, 0x6a, 0x16, 0x2b, 0xff, 0xc1, 0x9f, 0x27, 0x0e, 0xf5, 0xe8, 0x7f, 0xf7, - 0x4e, 0xe1, 0xb7, 0xed, 0x9d, 0xc2, 0x3f, 0x8a, 0xd7, 0xbc, 0xc4, 0x61, 0xba, 0x1f, 0x1d, 0xc4, - 0x98, 0x69, 0x5e, 0x4b, 0x6d, 0x61, 0xd4, 0x5d, 0xa2, 0x24, 0xaa, 0xbb, 0xc4, 0x6c, 0xdf, 0xfd, - 0xc8, 0xe1, 0xca, 0x0d, 0xe3, 0xcf, 0x74, 0xb7, 0x3a, 0x50, 0x92, 0x2a, 0xd7, 0xc4, 0xf8, 0x37, - 0x54, 0x77, 0x2b, 0xf3, 0x49, 0xa6, 0x6c, 0x1e, 0x3a, 0xa3, 0x7c, 0xb8, 0x51, 0x95, 0xea, 0x8e, - 0x03, 0xff, 0x5e, 0x50, 0x13, 0x2d, 0xb4, 0xda, 0xf2, 0x9e, 0xb2, 0xf5, 0x69, 0x0f, 0xd7, 0x31, - 0x5a, 0xec, 0xed, 0xf2, 0x66, 0x79, 0x37, 0x3a, 0x12, 0x71, 0xdf, 0x6e, 0x41, 0x73, 0x10, 0x12, - 0x69, 0x03, 0xe2, 0xf0, 0xf4, 0x4e, 0xbc, 0xa0, 0xfc, 0x28, 0xb1, 0xa8, 0x5b, 0x86, 0x58, 0x1a, - 0xf9, 0xe2, 0xdf, 0x8d, 0xe2, 0x0d, 0xfc, 0x52, 0x61, 0x41, 0x13, 0x65, 0x10, 0x8d, 0x89, 0xc8, - 0xc4, 0x6d, 0x91, 0x1e, 0xca, 0x02, 0xb5, 0xca, 0x85, 0x99, 0x48, 0x09, 0x52, 0x92, 0x44, 0xdb, - 0x5c, 0x27, 0xf9, 0x9d, 0x07, 0x4f, 0x53, 0x99, 0xa6, 0xdc, 0xab, 0xc9, 0xeb, 0x36, 0x95, 0xca, - 0xd2, 0x70, 0xa2, 0x46, 0x22, 0x83, 0x84, 0x2b, 0xe0, 0xc8, 0x9b, 0xbb, 0x44, 0xde, 0x89, 0xb0, - 0xef, 0x5d, 0x9e, 0x79, 0xcf, 0x4b, 0xe8, 0x91, 0x6a, 0xdf, 0x81, 0x8a, 0xf5, 0x9b, 0x59, 0xe9, - 0x34, 0x23, 0x4c, 0xfa, 0x3d, 0xf9, 0x74, 0xc2, 0xaf, 0x98, 0x97, 0xf5, 0x67, 0x12, 0x71, 0x05, - 0x24, 0x9d, 0x66, 0xe4, 0x00, 0xed, 0xcc, 0xe9, 0x5e, 0x6f, 0xea, 0xb2, 0xfe, 0x66, 0xb3, 0xb3, - 0xfe, 0xb6, 0x74, 0x8e, 0xc2, 0xdc, 0x48, 0xc3, 0xa6, 0x71, 0x05, 0xee, 0xc1, 0xd5, 0xf4, 0x56, - 0xb5, 0x83, 0xfb, 0x5d, 0xb7, 0x7f, 0x48, 0xe3, 0xc5, 0x05, 0x2b, 0x9b, 0x00, 0x6d, 0xc2, 0x35, - 0x65, 0xdb, 0xa4, 0x1b, 0xa9, 0x74, 0xb4, 0x60, 0x4f, 0x46, 0x87, 0xd2, 0x90, 0x23, 0xa5, 0xa6, - 0x01, 0x7a, 0x8d, 0x15, 0x3d, 0x1d, 0x1d, 0x42, 0x81, 0xde, 0x87, 0x57, 0xd2, 0xd8, 0xe8, 0x2d, - 0x86, 0x08, 0x3c, 0x0f, 0x21, 0x39, 0xf7, 0xc6, 0xfc, 0xa7, 0x06, 0xcc, 0xc8, 0xce, 0xba, 0xf6, - 0xb8, 0x78, 0x0d, 0x8a, 0xec, 0x5a, 0x48, 0xe4, 0x13, 0x14, 0xad, 0x18, 0x80, 0xca, 0x30, 0xad, - 0xee, 0xc6, 0xa2, 0x28, 0x45, 0xef, 0xf3, 0x4a, 0xf4, 0x7e, 0x05, 0x0a, 0x75, 0xef, 0x93, 0x3e, - 0xc5, 0x4c, 0x52, 0x4c, 0x54, 0xae, 0x7c, 0xbb, 0x02, 0xa6, 0xd0, 0xed, 0xe8, 0x4d, 0x50, 0xf4, - 0x02, 0xc8, 0x90, 0x5f, 0x00, 0xe9, 0x42, 0x22, 0xb1, 0x2b, 0x35, 0xa1, 0xb8, 0x52, 0xdb, 0xaa, - 0xaa, 0xb1, 0x83, 0xd0, 0x67, 0x74, 0x06, 0x25, 0x7a, 0xea, 0x33, 0x5c, 0xdd, 0x74, 0xdf, 0x33, - 0xf8, 0x5f, 0xb7, 0x57, 0x5d, 0x30, 0x13, 0xf7, 0xbd, 0xe2, 0x32, 0xea, 0xce, 0xd0, 0xa1, 0x26, - 0x99, 0xe4, 0xed, 0x33, 0x55, 0x23, 0x6a, 0xca, 0x47, 0x25, 0xf6, 0xb1, 0xa3, 0x4f, 0x0f, 0xad, - 0x3e, 0xa2, 0x66, 0xf3, 0x18, 0x73, 0xcb, 0xdb, 0x02, 0x8c, 0xbd, 0x2d, 0x48, 0x1b, 0x57, 0xe9, - 0x4c, 0x1b, 0xd7, 0xcc, 0x29, 0x36, 0xae, 0xc4, 0x36, 0x3b, 0x7b, 0xea, 0x6d, 0x36, 0xb5, 0x87, - 0xcc, 0x9d, 0x69, 0x0f, 0x51, 0xcd, 0xfb, 0xe5, 0x53, 0x9a, 0xf7, 0xd4, 0x39, 0xde, 0x3c, 0xcb, - 0x39, 0x3e, 0xc3, 0xd8, 0xcf, 0x9f, 0xd2, 0xd8, 0xa3, 0x0b, 0x37, 0xf6, 0x0b, 0xe7, 0x35, 0xf6, - 0x8b, 0xe7, 0x36, 0xf6, 0x4b, 0xe7, 0x35, 0xf6, 0xcb, 0x23, 0x8d, 0x3d, 0x7a, 0x27, 0x95, 0x9d, - 0x25, 0xb2, 0x24, 0xd8, 0x3d, 0x5a, 0x06, 0x56, 0x73, 0x14, 0x88, 0x73, 0x2f, 0xca, 0xda, 0xa3, - 0x40, 0x9c, 0x8a, 0xf1, 0x55, 0x58, 0x4c, 0xe0, 0xc4, 0x9d, 0x59, 0xea, 0x30, 0x9a, 0xd2, 0x7b, - 0x1d, 0x23, 0x33, 0x01, 0xda, 0x3a, 0xd1, 0x20, 0x35, 0xbe, 0x5a, 0x5b, 0xdc, 0xb1, 0xa5, 0x02, - 0x09, 0xa3, 0x5a, 0xe3, 0xac, 0xac, 0xbd, 0x8c, 0x7a, 0x35, 0x2d, 0xda, 0x6d, 0x71, 0x31, 0x77, - 0xea, 0x16, 0xed, 0x61, 0x2d, 0x72, 0x24, 0xda, 0x82, 0x1b, 0x09, 0x0c, 0x4f, 0xe5, 0x09, 0xaa, - 0x41, 0xe0, 0x1e, 0xf6, 0x71, 0xb7, 0x7c, 0x8d, 0xbd, 0x60, 0x1b, 0x41, 0x86, 0x5a, 0xf0, 0x6a, - 0x72, 0x54, 0x51, 0x4a, 0x4f, 0x54, 0xd7, 0x75, 0x5a, 0xd7, 0x68, 0xc2, 0xcc, 0x23, 0x5f, 0x2c, - 0x29, 0xab, 0x43, 0x8e, 0x7c, 0xb1, 0xbc, 0x6c, 0x66, 0xe4, 0xb4, 0x08, 0x49, 0xbd, 0x91, 0xbe, - 0xf1, 0x4d, 0xd2, 0x64, 0x46, 0xea, 0x59, 0xbc, 0x76, 0x8d, 0xea, 0xea, 0x10, 0x0a, 0xf4, 0x10, - 0xd6, 0xb4, 0xb7, 0xc1, 0x72, 0x6a, 0xd0, 0xab, 0xb4, 0x1f, 0x23, 0xe9, 0xc6, 0xb8, 0x09, 0xaf, - 0x8c, 0x75, 0x13, 0xfe, 0x75, 0x03, 0xae, 0x6b, 0xbb, 0x4c, 0xc3, 0x0c, 0x44, 0xe2, 0x5e, 0xa3, - 0x12, 0xf7, 0xde, 0x50, 0x89, 0x1b, 0x5a, 0x03, 0x13, 0xbc, 0xe1, 0xad, 0xa0, 0x3f, 0xc8, 0x4a, - 0x3a, 0x12, 0xaa, 0x76, 0x93, 0x76, 0xe3, 0xfe, 0xe9, 0xbb, 0xa1, 0x28, 0xdc, 0xd0, 0x36, 0xd0, - 0x37, 0x8c, 0x8c, 0xd0, 0x3e, 0xdd, 0xb2, 0x58, 0x3f, 0x3e, 0x45, 0xfb, 0x51, 0x3d, 0x7d, 0x3f, - 0xe2, 0x3a, 0x58, 0x57, 0x46, 0xb5, 0x84, 0xfe, 0xd8, 0xc8, 0x90, 0xfd, 0x5a, 0x9b, 0x67, 0x62, - 0x95, 0x5f, 0xa7, 0x9d, 0x79, 0xff, 0x2c, 0x93, 0xc2, 0xab, 0x60, 0x7d, 0x19, 0xd1, 0x0e, 0xfa, - 0xa6, 0x01, 0xaf, 0x66, 0x77, 0x57, 0xf4, 0xe6, 0x0d, 0xda, 0x9b, 0xda, 0x19, 0xa7, 0x46, 0xe9, - 0xd0, 0xe8, 0xd6, 0x32, 0x35, 0x5a, 0x6c, 0xbe, 0xb7, 0x86, 0x68, 0xb4, 0xd8, 0x7f, 0xbf, 0x65, - 0x40, 0x65, 0xe8, 0xd0, 0x59, 0x22, 0xda, 0x9b, 0x74, 0x60, 0xf5, 0xb3, 0x4f, 0x33, 0xad, 0x86, - 0x8d, 0x6c, 0x8c, 0xf6, 0xd0, 0xf7, 0x0c, 0xf8, 0xd4, 0xa8, 0x09, 0x60, 0x3d, 0x5b, 0xa7, 0x3d, - 0x7b, 0x70, 0xae, 0x29, 0x97, 0x3a, 0x37, 0x5e, 0xab, 0xe7, 0x0e, 0x5e, 0x7f, 0x0c, 0x4b, 0x5a, - 0xd7, 0xfe, 0x94, 0x71, 0x2a, 0xe5, 0x45, 0x94, 0x54, 0xfd, 0x3d, 0xfa, 0x71, 0xb3, 0x8c, 0xa0, - 0xda, 0xc8, 0xce, 0x3d, 0x80, 0xab, 0x99, 0x0e, 0xc2, 0xa8, 0x8a, 0x0a, 0x72, 0x45, 0xcd, 0x54, - 0x92, 0x80, 0x6c, 0x8a, 0xce, 0x59, 0x95, 0x7d, 0xd6, 0xaa, 0x76, 0x32, 0x24, 0x5e, 0xb1, 0xd6, - 0xa7, 0xaa, 0x71, 0x3b, 0xc3, 0x36, 0x9c, 0x79, 0xb4, 0x16, 0xdc, 0x1c, 0xc7, 0x82, 0x9e, 0xaa, - 0xce, 0x0f, 0xe1, 0xb5, 0x31, 0x0c, 0xe1, 0xa9, 0x04, 0xc5, 0x86, 0xd7, 0xc7, 0xb3, 0x66, 0xa7, - 0xaa, 0x75, 0x17, 0xde, 0x18, 0xd3, 0x94, 0x9c, 0xaa, 0xda, 0x2f, 0xc1, 0xfa, 0xf8, 0x76, 0xe0, - 0x54, 0xa1, 0x9a, 0x26, 0xcb, 0xb7, 0x11, 0xdf, 0x11, 0x3c, 0xc7, 0x77, 0x7a, 0x2a, 0x7f, 0x9d, - 0x83, 0x45, 0xdd, 0x63, 0xc1, 0x21, 0x39, 0xfb, 0x3b, 0xa9, 0xaf, 0x46, 0x6e, 0x8c, 0x7a, 0x7a, - 0xa8, 0x7e, 0x3d, 0x32, 0x75, 0x81, 0x72, 0x21, 0xdf, 0x90, 0x5c, 0xb1, 0x47, 0x7f, 0xe4, 0x71, - 0x58, 0x42, 0x8e, 0x34, 0xa3, 0xf2, 0x5c, 0x7f, 0xdf, 0x00, 0xd8, 0x74, 0x0e, 0x8e, 0x4e, 0x06, - 0xf4, 0x0e, 0x26, 0xeb, 0x82, 0xae, 0xa9, 0xbb, 0xa0, 0x7b, 0x43, 0x79, 0xa7, 0x10, 0x55, 0x32, - 0x3c, 0x9e, 0x74, 0xee, 0x40, 0xde, 0x1f, 0x1a, 0xe2, 0x7e, 0xa9, 0x19, 0xe2, 0x63, 0xed, 0x27, - 0x43, 0x2a, 0x30, 0xc3, 0x73, 0xb4, 0x9f, 0x48, 0xb7, 0x94, 0x0a, 0x8c, 0xd0, 0xd4, 0xf1, 0x53, - 0xe7, 0xa4, 0xc7, 0x69, 0x58, 0x44, 0x4f, 0x81, 0x91, 0x25, 0x6a, 0xf6, 0x43, 0xec, 0xf7, 0x9d, - 0x1e, 0xbf, 0x58, 0x8b, 0xca, 0x95, 0xbf, 0x31, 0xe4, 0x6b, 0x2e, 0xf4, 0x45, 0x98, 0xae, 0x79, - 0xfd, 0x10, 0xd3, 0x2f, 0x6b, 0xa4, 0x93, 0xa2, 0x23, 0xc2, 0x0d, 0x4e, 0xc5, 0x26, 0x46, 0xf0, - 0xac, 0x58, 0xf4, 0x65, 0x5c, 0x84, 0x38, 0x65, 0x8a, 0x4c, 0x3c, 0x1d, 0xf2, 0x44, 0xfd, 0x7e, - 0x7c, 0x9f, 0x86, 0xde, 0x8e, 0xdf, 0x8d, 0xa6, 0x32, 0xc1, 0x04, 0xd1, 0x06, 0xa5, 0x60, 0x1d, - 0x63, 0xd4, 0x2b, 0xef, 0x02, 0xc4, 0xc0, 0x53, 0xdd, 0x03, 0xbf, 0xa1, 0x3c, 0x57, 0x1f, 0xf2, - 0x9e, 0xe6, 0x63, 0x98, 0x4f, 0xbd, 0xdc, 0x40, 0x37, 0x61, 0x96, 0x7d, 0x01, 0x47, 0x3c, 0x06, - 0x61, 0x4c, 0x2a, 0x90, 0x2e, 0x33, 0x67, 0x91, 0xbe, 0x9a, 0xa4, 0xc0, 0xd6, 0x3f, 0x01, 0xd8, - 0x1d, 0x74, 0x9d, 0x90, 0x45, 0x70, 0xaf, 0xc0, 0x82, 0xf2, 0x45, 0x1d, 0x86, 0x32, 0x2f, 0xa1, - 0x25, 0x98, 0x17, 0x5f, 0x4a, 0x6a, 0x75, 0xda, 0x1c, 0x6c, 0xa0, 0x05, 0xb8, 0xbc, 0x1b, 0x60, - 0x9f, 0x0e, 0x9f, 0x03, 0x73, 0x68, 0x16, 0x8a, 0x76, 0x67, 0x9b, 0x17, 0x27, 0x08, 0x6b, 0xf4, - 0xd5, 0xa3, 0x88, 0x35, 0xbf, 0xbe, 0x01, 0xc5, 0xe8, 0x4b, 0xbb, 0xe8, 0x32, 0x94, 0xda, 0x9e, - 0x7f, 0xec, 0xf4, 0x68, 0xd1, 0xbc, 0x84, 0x4c, 0x98, 0xe1, 0x4f, 0x0f, 0x18, 0xc4, 0x58, 0xff, - 0x45, 0x1e, 0x20, 0x7e, 0x69, 0x8e, 0xe6, 0x00, 0xec, 0xce, 0xf6, 0xde, 0xee, 0x4e, 0xbd, 0x6a, - 0x37, 0xcc, 0x4b, 0x08, 0x60, 0xaa, 0xba, 0xb3, 0xd3, 0x68, 0xd7, 0x4d, 0x03, 0x15, 0x20, 0x6f, - 0x35, 0xaa, 0x75, 0x33, 0x87, 0x66, 0xa0, 0x60, 0x5b, 0xbb, 0xed, 0x1a, 0xa1, 0x99, 0x20, 0x95, - 0x3e, 0x68, 0xd8, 0x7b, 0x11, 0x24, 0x8f, 0x4a, 0x30, 0x5d, 0xdb, 0x6e, 0xb7, 0x1b, 0x35, 0xdb, - 0x9c, 0x24, 0x55, 0xf2, 0xc2, 0x9e, 0xb5, 0x6d, 0x4e, 0xa1, 0x79, 0x98, 0x6d, 0x6d, 0x3f, 0xd8, - 0xdb, 0x6a, 0x54, 0x2d, 0x7b, 0xb3, 0x51, 0xb5, 0xcd, 0x69, 0x52, 0x43, 0xad, 0x2d, 0x41, 0x0a, - 0xb4, 0xa3, 0x32, 0xa4, 0x88, 0x10, 0xcc, 0xd5, 0xb6, 0x1a, 0xb5, 0x47, 0x7b, 0x5b, 0xd5, 0x47, - 0x8d, 0xc6, 0x4e, 0xc3, 0x32, 0x81, 0xcc, 0x2b, 0x69, 0xb9, 0xd6, 0xda, 0xed, 0xd8, 0x0d, 0x6b, - 0xaf, 0xde, 0xb0, 0xab, 0xcd, 0x56, 0xc7, 0x2c, 0x11, 0x62, 0x82, 0xe8, 0x6c, 0x55, 0xad, 0xfa, - 0x5e, 0xb3, 0xfd, 0xc1, 0xb6, 0x39, 0x43, 0x2b, 0x68, 0xef, 0x55, 0x5b, 0xad, 0x6d, 0xd2, 0xcb, - 0xbd, 0x66, 0xdd, 0x9c, 0x25, 0x93, 0x28, 0x57, 0xd0, 0xb1, 0x49, 0xff, 0xe7, 0xe8, 0xfc, 0xd3, - 0x19, 0xd8, 0xab, 0xb5, 0xf7, 0x5a, 0xd5, 0xcd, 0x46, 0xcb, 0xbc, 0x8c, 0xca, 0xb0, 0x18, 0x03, - 0x3f, 0xda, 0xb6, 0x1e, 0x71, 0x72, 0x93, 0xd4, 0xbc, 0x53, 0xb5, 0x6b, 0x5b, 0x04, 0xd1, 0xb1, - 0xb7, 0xad, 0x86, 0x39, 0x4f, 0xaa, 0xa8, 0x37, 0x5a, 0x0d, 0x46, 0xcd, 0x80, 0x88, 0x00, 0x77, - 0xac, 0xed, 0x2f, 0x7d, 0x59, 0x1a, 0xd8, 0x02, 0x7a, 0x15, 0xae, 0xf3, 0x7a, 0xdb, 0xdb, 0xed, - 0xbd, 0x27, 0xdb, 0x76, 0xb3, 0xfd, 0x60, 0xcf, 0x6a, 0xec, 0xb4, 0x9a, 0xb5, 0xea, 0x5e, 0x7b, - 0xf7, 0xb1, 0xb9, 0x88, 0x56, 0x61, 0x25, 0x4d, 0x42, 0xc6, 0xd1, 0x6a, 0xda, 0x5f, 0x36, 0x97, - 0xd0, 0x22, 0x98, 0x9d, 0x86, 0xbd, 0x67, 0x35, 0x3e, 0xdc, 0x6d, 0x5a, 0x8d, 0xfa, 0x5e, 0xab, - 0xd3, 0x36, 0x97, 0x09, 0xf4, 0x41, 0x12, 0x7a, 0x45, 0x4c, 0x4d, 0xab, 0x6a, 0x37, 0x3a, 0x36, - 0x85, 0x95, 0xc9, 0x92, 0x50, 0x58, 0xa3, 0x5a, 0x6f, 0x58, 0x64, 0x66, 0xae, 0xd2, 0x25, 0x61, - 0xd3, 0xdd, 0xa8, 0xb6, 0xec, 0x2d, 0x73, 0x85, 0x2c, 0x3a, 0x59, 0x7e, 0xca, 0xf2, 0x0a, 0xba, - 0x0a, 0x4b, 0xbc, 0x4b, 0xad, 0x46, 0xb5, 0xd3, 0xd8, 0xda, 0x6e, 0x71, 0xd6, 0x6b, 0x04, 0x45, - 0x27, 0xbf, 0xb6, 0xd5, 0xa8, 0xef, 0xb6, 0x1a, 0x7b, 0xb5, 0xed, 0xc7, 0x8f, 0xab, 0xed, 0x7a, - 0xc7, 0xbc, 0xbe, 0xde, 0x06, 0x88, 0xbf, 0xcf, 0x44, 0x24, 0x83, 0x88, 0x39, 0x83, 0x98, 0x97, - 0x48, 0x0b, 0xc2, 0xce, 0x99, 0x06, 0x11, 0x5e, 0xaa, 0x34, 0x91, 0x02, 0xcc, 0xf3, 0x0f, 0x92, - 0x59, 0xf8, 0xab, 0xf8, 0x20, 0xc4, 0x5d, 0x73, 0x62, 0x7d, 0x1d, 0x8a, 0xd1, 0xe7, 0x7f, 0x08, - 0x7b, 0x07, 0x87, 0xb4, 0x64, 0x5e, 0x22, 0xec, 0x2c, 0xb8, 0xca, 0x00, 0xc6, 0xfa, 0x3f, 0xe7, - 0x01, 0x89, 0x23, 0x85, 0xa4, 0x9b, 0x44, 0xe2, 0xdd, 0x83, 0x23, 0x59, 0x25, 0xa5, 0xef, 0xac, - 0x44, 0x2a, 0x49, 0x34, 0x35, 0x05, 0xce, 0xa1, 0x65, 0x9a, 0xe7, 0x91, 0x84, 0x4f, 0x90, 0xd6, - 0x1f, 0xe0, 0x30, 0xd2, 0xf4, 0x3c, 0x99, 0x94, 0x84, 0xbd, 0xe1, 0xa8, 0x49, 0xb2, 0x22, 0x1d, - 0xcc, 0x14, 0x92, 0xc3, 0xa6, 0x88, 0xb0, 0xa9, 0x89, 0x3c, 0x1c, 0x33, 0x8d, 0x6e, 0xc0, 0x2b, - 0x1d, 0x1c, 0xa6, 0xef, 0x26, 0x38, 0x41, 0x01, 0xad, 0xc0, 0x32, 0x27, 0x88, 0x82, 0xdb, 0x1c, - 0x57, 0x24, 0x53, 0xc8, 0x7e, 0xf3, 0x59, 0x33, 0x81, 0x0c, 0x4c, 0x80, 0xa2, 0x47, 0x2f, 0x66, - 0x89, 0xac, 0xff, 0x0e, 0xb1, 0x77, 0x3c, 0x47, 0xce, 0x9c, 0x21, 0xbc, 0x16, 0x3e, 0xf6, 0x9e, - 0x8b, 0x37, 0x90, 0xe6, 0x2c, 0xe9, 0xa5, 0x9a, 0x0c, 0xc9, 0x1b, 0x9a, 0x43, 0xd7, 0xe1, 0x2a, - 0xfb, 0xad, 0x09, 0x5a, 0x9b, 0x97, 0xd1, 0x2b, 0x70, 0x25, 0x81, 0x16, 0xbb, 0x01, 0x53, 0x27, - 0x71, 0xea, 0xe1, 0xf5, 0xcd, 0xa3, 0x6b, 0x50, 0x4e, 0xa7, 0xe2, 0x70, 0x2c, 0x42, 0x37, 0x61, - 0x4d, 0x04, 0x71, 0xd3, 0xe1, 0x5d, 0x4e, 0xb5, 0x40, 0x66, 0x8e, 0x05, 0xc0, 0x12, 0x27, 0x10, - 0x4e, 0xb0, 0x88, 0x3e, 0x05, 0xaf, 0x32, 0x02, 0xad, 0x83, 0xc9, 0xc9, 0x96, 0xd6, 0xbf, 0x63, - 0xc0, 0xac, 0x72, 0xdb, 0x44, 0xf4, 0x5a, 0x00, 0x78, 0x36, 0x8a, 0x79, 0x89, 0xac, 0xb8, 0x00, - 0x2a, 0x2f, 0xd9, 0x4d, 0x83, 0x34, 0x94, 0x42, 0x89, 0xf3, 0xa3, 0x85, 0x0f, 0xb0, 0xfb, 0x1c, - 0x77, 0xcd, 0x1c, 0x99, 0xa5, 0x14, 0xd9, 0x07, 0x8e, 0xdb, 0x23, 0xa2, 0x2f, 0xb7, 0x69, 0x9d, - 0xf4, 0xfb, 0xa4, 0xe2, 0xfc, 0xfa, 0xbe, 0xee, 0xbe, 0x8b, 0x2c, 0x93, 0x02, 0x8d, 0xfb, 0x98, - 0xc4, 0x88, 0x9a, 0x8c, 0x14, 0xa6, 0x13, 0x7a, 0x83, 0x01, 0xe9, 0xd5, 0xfa, 0x8f, 0x0c, 0x30, - 0x93, 0xdf, 0x2e, 0x20, 0x5a, 0x54, 0xed, 0x8a, 0xcf, 0x89, 0x99, 0x97, 0x62, 0x61, 0x11, 0x20, - 0x83, 0x48, 0x54, 0x27, 0x74, 0xfc, 0x50, 0x40, 0x72, 0x44, 0x49, 0x48, 0xb5, 0x02, 0x30, 0x41, - 0x6a, 0x79, 0xe4, 0xf6, 0x7a, 0x5f, 0xf1, 0x8e, 0xf7, 0x5d, 0xa2, 0x34, 0x57, 0x60, 0xa1, 0xda, - 0xed, 0x26, 0x45, 0xc8, 0x9c, 0x24, 0x32, 0xce, 0xaa, 0x4f, 0xe1, 0xa6, 0xa8, 0xa6, 0x91, 0x76, - 0x52, 0xa8, 0x69, 0x32, 0x28, 0xd2, 0x60, 0x0a, 0x53, 0x58, 0x7f, 0xac, 0xbc, 0xe9, 0x26, 0x1d, - 0x89, 0x05, 0xc9, 0xbc, 0x44, 0xf7, 0xde, 0xb6, 0x28, 0x1a, 0xa4, 0x58, 0x8b, 0x8a, 0x39, 0xaa, - 0x2b, 0xf4, 0x2a, 0x88, 0x43, 0x26, 0x36, 0x9b, 0x3f, 0xfc, 0xd9, 0xea, 0xa5, 0x1f, 0xfc, 0x7c, - 0xd5, 0xf8, 0xe1, 0xcf, 0x57, 0x8d, 0x9f, 0xfe, 0x7c, 0xf5, 0xd2, 0xdf, 0xfe, 0xdb, 0xaa, 0xf1, - 0x95, 0xbb, 0xd2, 0x3f, 0x88, 0x39, 0x76, 0x42, 0xdf, 0x7d, 0xe1, 0x51, 0xc7, 0x42, 0x14, 0xfa, - 0xf8, 0xf6, 0xe0, 0xe8, 0xf0, 0xf6, 0x60, 0xff, 0x76, 0xec, 0x26, 0xed, 0x4f, 0xd1, 0x6f, 0xbf, - 0xdd, 0xfd, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x1e, 0x8f, 0x93, 0x7c, 0x66, 0x00, 0x00, + // 6018 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xdb, 0x6f, 0x1b, 0xd9, + 0x79, 0xb8, 0x87, 0xa4, 0x24, 0xf2, 0xa3, 0x24, 0x8f, 0x8e, 0x2e, 0xa6, 0x65, 0x5b, 0xd6, 0x72, + 0x9d, 0x5d, 0xaf, 0xb2, 0x91, 0xf3, 0xb3, 0xb3, 0x8b, 0x4d, 0x7e, 0x8e, 0x77, 0x29, 0x92, 0x6b, + 0xd1, 0xa6, 0x28, 0xed, 0x70, 0xe4, 0x4d, 0x02, 0x2c, 0x84, 0x11, 0x79, 0x2c, 0x4f, 0x44, 0x72, + 0x98, 0x99, 0x91, 0xd7, 0x6e, 0xdf, 0x8a, 0xa6, 0x28, 0x1a, 0x20, 0x68, 0x80, 0xa0, 0x4d, 0x2f, + 0x69, 0xd3, 0xbe, 0xf5, 0x29, 0x2f, 0xed, 0xbf, 0x50, 0xe4, 0xa9, 0x08, 0xf2, 0x58, 0xa0, 0x69, + 0x76, 0xfb, 0x52, 0x20, 0xaf, 0x45, 0x83, 0x3e, 0x14, 0x28, 0xce, 0x6d, 0xe6, 0x9c, 0xb9, 0x90, + 0xd4, 0xa5, 0x49, 0x13, 0xe4, 0x49, 0x3c, 0xe7, 0x7c, 0xdf, 0xb9, 0x7e, 0xb7, 0xf3, 0x7d, 0xdf, + 0x19, 0x81, 0xde, 0x73, 0x8e, 0x3c, 0xec, 0x3e, 0xb7, 0x3b, 0x78, 0x73, 0xe8, 0x3a, 0xbe, 0x83, + 0x20, 0xac, 0x59, 0xfd, 0xdc, 0x91, 0xed, 0x3f, 0x3b, 0x39, 0xdc, 0xec, 0x38, 0xfd, 0x3b, 0x47, + 0xce, 0x91, 0x73, 0x87, 0x82, 0x1c, 0x9e, 0x3c, 0xa5, 0x25, 0x5a, 0xa0, 0xbf, 0x18, 0xea, 0xea, + 0xcd, 0x23, 0xc7, 0x39, 0xea, 0xe1, 0x10, 0xca, 0xb7, 0xfb, 0xd8, 0xf3, 0xad, 0xfe, 0x90, 0x03, + 0xcc, 0xf7, 0xb1, 0x6f, 0x75, 0x2d, 0xdf, 0x62, 0xe5, 0xf2, 0xb7, 0x0b, 0x30, 0x53, 0x6d, 0xb5, + 0x7d, 0xc7, 0xc5, 0x08, 0x41, 0x6e, 0x7f, 0xbf, 0x51, 0x2b, 0x69, 0xeb, 0xda, 0xed, 0x82, 0x41, + 0x7f, 0xa3, 0xd7, 0x60, 0xbe, 0xcd, 0xa6, 0x52, 0xe9, 0x76, 0x5d, 0xec, 0x79, 0xa5, 0x0c, 0x6d, + 0x8d, 0xd4, 0xa2, 0x35, 0x80, 0xf6, 0x07, 0x4d, 0x01, 0x93, 0xa5, 0x30, 0x52, 0x0d, 0xda, 0x04, + 0xd4, 0x74, 0x3a, 0xc7, 0x91, 0xbe, 0x72, 0x14, 0x2e, 0xa1, 0x05, 0xdd, 0x82, 0x9c, 0xe1, 0xf4, + 0x70, 0x69, 0x7a, 0x5d, 0xbb, 0x3d, 0x7f, 0x57, 0xdf, 0x0c, 0xa6, 0x5d, 0x6d, 0x91, 0x7a, 0x83, + 0xb6, 0x92, 0x19, 0x9b, 0x76, 0xe7, 0xb8, 0x34, 0xb3, 0xae, 0xdd, 0xce, 0x19, 0xf4, 0x37, 0xfa, + 0x2c, 0x4c, 0xb5, 0x7d, 0xcb, 0xc7, 0xa5, 0x3c, 0x45, 0x5d, 0xde, 0x94, 0xf6, 0xb7, 0xe5, 0x74, + 0x31, 0x6d, 0x34, 0x18, 0x0c, 0xfa, 0x32, 0x4c, 0x37, 0xad, 0x43, 0xdc, 0xf3, 0x4a, 0x85, 0xf5, + 0xec, 0xed, 0xe2, 0xdd, 0x9b, 0x32, 0x34, 0xdf, 0x97, 0x4d, 0x06, 0x51, 0x1f, 0xf8, 0xee, 0xcb, + 0xad, 0xdc, 0x8f, 0x7e, 0x7a, 0xf3, 0x92, 0xc1, 0x91, 0xd0, 0xff, 0x83, 0xc2, 0x87, 0x8e, 0x7b, + 0xcc, 0xc6, 0x03, 0x3a, 0xde, 0x62, 0x38, 0xd5, 0xa0, 0xc9, 0x08, 0xa1, 0x50, 0x19, 0x66, 0x3f, + 0x38, 0xc1, 0xee, 0x4b, 0xb1, 0x05, 0x45, 0xba, 0x05, 0x4a, 0x1d, 0x7a, 0x1b, 0xa0, 0xea, 0x0c, + 0x9e, 0xda, 0x47, 0x35, 0xcb, 0xb7, 0x4a, 0xb3, 0xeb, 0xda, 0xed, 0xe2, 0xdd, 0x15, 0x65, 0x66, + 0x41, 0xab, 0x21, 0x41, 0xa2, 0xb7, 0x21, 0x6f, 0x60, 0xcf, 0x39, 0x71, 0x3b, 0xb8, 0x34, 0x47, + 0xb1, 0x96, 0x64, 0x2c, 0xd1, 0xc6, 0x17, 0x11, 0xc0, 0xa2, 0x15, 0x98, 0xde, 0x1f, 0x9a, 0x76, + 0x1f, 0x97, 0xe6, 0xd7, 0xb5, 0xdb, 0x59, 0x83, 0x97, 0xd0, 0xe7, 0x61, 0xb1, 0xfd, 0xcc, 0x72, + 0xbb, 0x91, 0x53, 0xbb, 0x4c, 0xa7, 0x9c, 0xd4, 0x84, 0x56, 0x21, 0x5f, 0x75, 0xfa, 0x7d, 0xdb, + 0x6f, 0xd4, 0x4a, 0x3a, 0x05, 0x0b, 0xca, 0xe8, 0x7d, 0x58, 0x7b, 0x62, 0xe3, 0x8f, 0x77, 0xf8, + 0xf6, 0x54, 0xba, 0x7d, 0xdb, 0xf3, 0x6c, 0x67, 0xd0, 0x3e, 0x19, 0x0e, 0x1d, 0xd7, 0xc7, 0xdd, + 0xd2, 0xc2, 0xba, 0x76, 0x3b, 0x6f, 0x8c, 0x81, 0x42, 0xdb, 0x70, 0x33, 0x11, 0xe2, 0x21, 0x1e, + 0x60, 0xd7, 0xf2, 0x6d, 0x67, 0x50, 0x42, 0x94, 0x1e, 0xc6, 0x81, 0xa1, 0xfb, 0x70, 0x55, 0x06, + 0xd9, 0x3d, 0x24, 0x3b, 0x85, 0xbb, 0xf5, 0xa1, 0xd3, 0x79, 0x56, 0x5a, 0xa4, 0x7d, 0xa4, 0x03, + 0xa0, 0x07, 0xb0, 0x9a, 0x38, 0x80, 0x81, 0xad, 0xee, 0xcb, 0xd2, 0x12, 0x5d, 0xcb, 0x08, 0x08, + 0x32, 0x7a, 0xad, 0xd6, 0x7c, 0x62, 0x7b, 0xf6, 0xa1, 0xdd, 0xb3, 0xfd, 0x97, 0x5b, 0x96, 0xeb, + 0xda, 0xd8, 0x65, 0xe8, 0xcb, 0x14, 0x3d, 0x1d, 0x00, 0x7d, 0x09, 0x4a, 0x72, 0xdf, 0x8d, 0xc1, + 0x11, 0x39, 0x00, 0x86, 0xbc, 0x42, 0x91, 0x53, 0xdb, 0x51, 0x0d, 0x6e, 0x28, 0x1d, 0xd7, 0xf0, + 0xb0, 0xe7, 0xbc, 0xc4, 0xdd, 0x3d, 0x22, 0x12, 0x3a, 0x4e, 0xaf, 0x74, 0x85, 0x92, 0xc1, 0x68, + 0xa0, 0xd5, 0x16, 0x14, 0x25, 0xce, 0x40, 0x3a, 0x64, 0x8f, 0xf1, 0x4b, 0x2e, 0x3c, 0xc8, 0x4f, + 0xf4, 0x06, 0x4c, 0x3d, 0xb7, 0x7a, 0x27, 0x98, 0x8a, 0x8c, 0xa2, 0xcc, 0x19, 0x14, 0xaf, 0x69, + 0x7b, 0xbe, 0xc1, 0x20, 0xbe, 0x94, 0x79, 0x47, 0x7b, 0x94, 0xcb, 0x4f, 0xe9, 0xd3, 0xe5, 0x5f, + 0x64, 0x61, 0xc6, 0xbc, 0x00, 0x81, 0x24, 0x44, 0x43, 0x36, 0x49, 0x34, 0xe4, 0x26, 0x10, 0x0d, + 0x6f, 0xc1, 0x34, 0xa5, 0x70, 0xaf, 0x34, 0x45, 0x45, 0xc3, 0x15, 0x19, 0xda, 0x6c, 0xd1, 0xb6, + 0xc6, 0xe0, 0xa9, 0x23, 0x44, 0x02, 0x03, 0x46, 0x77, 0x61, 0xa9, 0xe9, 0x1c, 0xf9, 0x96, 0xdd, + 0x23, 0x13, 0xc2, 0xae, 0x98, 0xe5, 0x34, 0x9d, 0x65, 0x62, 0x5b, 0x8a, 0x70, 0x9c, 0x49, 0x15, + 0x8e, 0xaa, 0x7c, 0x28, 0x4c, 0x2c, 0x1f, 0xa2, 0xb2, 0x07, 0x12, 0x64, 0x4f, 0x0a, 0xcf, 0x17, + 0xd3, 0x79, 0xfe, 0x3d, 0xb8, 0x56, 0x39, 0xf1, 0x9d, 0xc6, 0xa0, 0xe3, 0x52, 0xc6, 0x78, 0x1f, + 0x0f, 0x3a, 0x38, 0x64, 0xea, 0x59, 0x4a, 0x8c, 0xa3, 0x40, 0x1e, 0xe5, 0xf2, 0x79, 0xbd, 0x50, + 0xfe, 0x87, 0x0c, 0xe4, 0x9b, 0xce, 0xd1, 0xff, 0x81, 0xa3, 0xbf, 0x4f, 0xe4, 0xe8, 0xb0, 0x67, + 0x77, 0x2c, 0x71, 0xf8, 0xab, 0x32, 0x7c, 0xd3, 0x39, 0xe2, 0xcd, 0xd2, 0xf9, 0x07, 0x18, 0x91, + 0xd3, 0x99, 0x3e, 0x8d, 0xf4, 0x6e, 0x3a, 0x1d, 0x8b, 0xf0, 0x1a, 0x3d, 0xfb, 0x88, 0xf4, 0x16, + 0x6d, 0x62, 0x3c, 0x51, 0x2e, 0x7f, 0x37, 0x0b, 0xb3, 0x64, 0xdf, 0x04, 0x41, 0xa2, 0x12, 0xcc, + 0xb0, 0x02, 0xdb, 0xbe, 0x9c, 0x21, 0x8a, 0x68, 0x4b, 0x5a, 0x58, 0x86, 0x2e, 0xec, 0xb5, 0xc8, + 0xc2, 0x82, 0x5e, 0x36, 0x05, 0x20, 0xe5, 0x6e, 0x69, 0x79, 0x4b, 0x30, 0xc5, 0x04, 0x24, 0xdb, + 0x5e, 0x56, 0x20, 0x82, 0xbf, 0x89, 0xad, 0x2e, 0x76, 0x1b, 0x35, 0xba, 0xc5, 0x39, 0x23, 0x28, + 0xd3, 0xf3, 0xc0, 0x6e, 0xbf, 0x34, 0xc5, 0xcf, 0x03, 0xbb, 0x7d, 0xf4, 0x11, 0x2c, 0xb4, 0x9c, + 0xc1, 0x13, 0xc7, 0xb7, 0x07, 0x47, 0xc1, 0x94, 0xa6, 0xe9, 0x94, 0xee, 0xa4, 0x4e, 0x29, 0x86, + 0xc1, 0xe6, 0x16, 0xef, 0x69, 0xf5, 0xff, 0xc3, 0x9c, 0x02, 0x23, 0x4b, 0xa7, 0x1c, 0x93, 0x4e, + 0x4b, 0xb2, 0x74, 0x2a, 0x48, 0x82, 0x68, 0xb5, 0x06, 0x2b, 0xc9, 0x23, 0x9d, 0xa6, 0x97, 0xf2, + 0xf7, 0x34, 0x98, 0x57, 0x29, 0x05, 0xbd, 0xaf, 0x1e, 0x14, 0xed, 0xa7, 0x78, 0xb7, 0x94, 0xb6, + 0xde, 0xad, 0x3c, 0x39, 0xe9, 0x1f, 0xff, 0xf4, 0xa6, 0x66, 0xa8, 0x07, 0x7c, 0x1d, 0x0a, 0xa2, + 0xdb, 0x1a, 0x1d, 0x38, 0x67, 0x84, 0x15, 0x68, 0x1d, 0x8a, 0x0d, 0x2f, 0x58, 0x00, 0x3d, 0xa6, + 0xbc, 0x21, 0x57, 0x95, 0xff, 0x48, 0x0b, 0x0d, 0x05, 0xaa, 0xb2, 0xf7, 0xf6, 0x4d, 0xc7, 0xb7, + 0x7a, 0x7c, 0x61, 0x41, 0x99, 0x08, 0x8c, 0xea, 0xde, 0x7e, 0xe5, 0xb9, 0x65, 0xf7, 0xac, 0xc3, + 0x1e, 0x5b, 0xa4, 0x66, 0x28, 0x75, 0x04, 0x7f, 0x07, 0xf7, 0x19, 0x3e, 0x23, 0x89, 0xa0, 0x4c, + 0xf0, 0x77, 0x70, 0x3f, 0xc4, 0x67, 0x94, 0xa1, 0xd4, 0x95, 0x7f, 0x00, 0xa0, 0x73, 0x4b, 0x6b, + 0x1b, 0x5b, 0xae, 0x7f, 0x88, 0x2d, 0xff, 0xd7, 0xd0, 0x14, 0xdd, 0x04, 0x64, 0x5a, 0x9e, 0xc0, + 0xad, 0xba, 0xd8, 0x22, 0xc2, 0x6f, 0x86, 0x6e, 0x7e, 0x42, 0x4b, 0x4c, 0x16, 0xe7, 0x13, 0x64, + 0xf1, 0x2d, 0x98, 0x6b, 0x0c, 0x6c, 0x3f, 0x34, 0x31, 0x0b, 0x14, 0x48, 0xad, 0x24, 0x50, 0x0f, + 0x1d, 0xcf, 0xb3, 0x87, 0xaa, 0x58, 0x57, 0x2b, 0xc9, 0x78, 0xac, 0xe2, 0x91, 0x63, 0x0f, 0x70, + 0x97, 0x0a, 0xf4, 0xbc, 0xa1, 0xd4, 0xfd, 0xd2, 0xed, 0xce, 0x14, 0x5d, 0x33, 0x3f, 0x99, 0x7d, + 0x79, 0x39, 0x62, 0x5f, 0x7e, 0x1e, 0x16, 0x2b, 0x9d, 0x63, 0xdc, 0x25, 0x15, 0xd6, 0xa0, 0xbb, + 0x65, 0xf9, 0x9d, 0x67, 0xdc, 0x0c, 0xcd, 0x19, 0x49, 0x4d, 0x44, 0x73, 0xf1, 0x9a, 0x1a, 0xee, + 0xd9, 0xcf, 0xc9, 0xce, 0x77, 0x8e, 0xa3, 0xe6, 0xe8, 0x28, 0x90, 0x09, 0x6c, 0x5a, 0x74, 0x51, + 0x36, 0xed, 0xe2, 0x05, 0xd8, 0xb4, 0x4b, 0xe3, 0x6c, 0xda, 0xc8, 0x7a, 0xaa, 0x96, 0x6f, 0xf5, + 0x9c, 0x23, 0xaa, 0xae, 0x79, 0x17, 0xcb, 0xb4, 0x8b, 0x31, 0x50, 0x68, 0x0b, 0xae, 0xcb, 0x10, + 0x06, 0x7e, 0xea, 0x62, 0xef, 0x59, 0xb8, 0x2b, 0xcc, 0x42, 0x1d, 0x09, 0x13, 0xef, 0xe3, 0xb9, + 0xd5, 0xb3, 0xbb, 0x84, 0x79, 0xd8, 0x4c, 0xae, 0xd0, 0x99, 0x8c, 0x84, 0x19, 0x69, 0x25, 0x97, + 0xc6, 0x58, 0xc9, 0x23, 0xed, 0xf3, 0xab, 0xe3, 0xec, 0xf3, 0xb1, 0x36, 0xf6, 0xea, 0x04, 0x36, + 0x36, 0xb7, 0x89, 0x4d, 0x98, 0xad, 0xb6, 0x2a, 0xbd, 0x9e, 0xd3, 0xb1, 0x7c, 0xdc, 0xa8, 0x25, + 0x98, 0xda, 0x4b, 0x30, 0x45, 0x89, 0x9a, 0x6b, 0x03, 0x56, 0x60, 0x7a, 0xe2, 0x1b, 0x27, 0xd8, + 0x23, 0xec, 0xc2, 0x04, 0x61, 0x58, 0x51, 0xfe, 0xaf, 0x2c, 0x2c, 0x08, 0x7b, 0x6b, 0xb4, 0xe4, + 0x5d, 0x87, 0xa2, 0x61, 0x3d, 0xf5, 0x55, 0xb1, 0x2b, 0x57, 0x25, 0xc8, 0xe6, 0x6c, 0xa2, 0x6c, + 0x8e, 0xc9, 0xaa, 0x5c, 0x92, 0xac, 0x3a, 0x9f, 0xfd, 0x95, 0x2c, 0x89, 0xa7, 0x53, 0x25, 0xb1, + 0x2a, 0xf5, 0x66, 0xce, 0x64, 0xaf, 0xe5, 0x27, 0xb7, 0xd7, 0x08, 0x4d, 0x46, 0x44, 0x4a, 0xc8, + 0x17, 0x05, 0x46, 0x93, 0x69, 0xed, 0x13, 0xc8, 0x1b, 0x98, 0x44, 0xde, 0x94, 0xeb, 0x50, 0x94, + 0xae, 0x30, 0x23, 0x2c, 0xc6, 0x91, 0xa6, 0x46, 0xf9, 0x9b, 0x53, 0xa0, 0x9b, 0x17, 0xa9, 0xbb, + 0xc3, 0x4b, 0x57, 0xf6, 0x34, 0x97, 0xae, 0xe4, 0x23, 0xcf, 0xa5, 0x1e, 0x79, 0xda, 0x25, 0x6d, + 0xea, 0xd4, 0x97, 0xb4, 0xe9, 0x09, 0x2f, 0x69, 0xf9, 0x33, 0x5f, 0xd2, 0x0a, 0x93, 0x5f, 0xd2, + 0x20, 0x5d, 0x71, 0x12, 0x16, 0xc6, 0xc3, 0x9e, 0xf5, 0x12, 0x77, 0x9b, 0xde, 0x80, 0x6a, 0xff, + 0x9c, 0x21, 0x57, 0x9d, 0xff, 0x1a, 0x97, 0xa6, 0x80, 0xe7, 0xce, 0xac, 0x80, 0xe7, 0xc7, 0x2a, + 0xe0, 0x47, 0xb9, 0xfc, 0x8c, 0x9e, 0x2f, 0xff, 0x70, 0x0a, 0xf2, 0x46, 0x7b, 0x87, 0xd9, 0x43, + 0x3a, 0x64, 0x4d, 0xcf, 0x11, 0x46, 0xba, 0xe9, 0x39, 0x44, 0x3a, 0x36, 0x06, 0x5d, 0xfc, 0x42, + 0x48, 0x47, 0x5a, 0x20, 0xb2, 0xa8, 0x89, 0x2d, 0x0f, 0x6f, 0x3b, 0x3d, 0x76, 0x6f, 0x61, 0xd6, + 0xab, 0x5a, 0x49, 0x8e, 0xc3, 0x74, 0x4f, 0x06, 0x44, 0xf2, 0xd2, 0x9d, 0xe3, 0x26, 0xac, 0x5c, + 0x87, 0x1e, 0xc1, 0x2c, 0x43, 0xb2, 0x3d, 0xdf, 0x71, 0x5f, 0x72, 0x99, 0xa5, 0x5c, 0xad, 0xc4, + 0xec, 0x36, 0x65, 0x40, 0x76, 0x7d, 0x51, 0x70, 0xd9, 0x41, 0x7d, 0xe3, 0xc4, 0x76, 0xd9, 0x70, + 0xd3, 0xe2, 0xa0, 0x82, 0x2a, 0xf4, 0x26, 0x2c, 0x7c, 0x58, 0x69, 0x1a, 0xb8, 0xe3, 0x90, 0xdd, + 0xa8, 0xd9, 0x47, 0xd8, 0xf3, 0xb9, 0xb3, 0x20, 0xde, 0x80, 0xbe, 0x00, 0xcb, 0x52, 0x25, 0x1d, + 0xb1, 0xea, 0x9c, 0x0c, 0x7c, 0x4a, 0x91, 0x39, 0x23, 0xb9, 0x91, 0x1c, 0x8c, 0xd4, 0x50, 0x75, + 0xfa, 0xc3, 0x1e, 0x26, 0x4a, 0x75, 0xe0, 0xbb, 0x36, 0x66, 0x34, 0x99, 0x33, 0x46, 0x81, 0x10, + 0x76, 0x91, 0x9a, 0xb7, 0x2c, 0x0f, 0x93, 0xe5, 0x00, 0x45, 0x4c, 0x68, 0x89, 0xc0, 0x37, 0x2d, + 0xcf, 0x0f, 0xe9, 0x34, 0xa1, 0x05, 0x3d, 0x82, 0x75, 0xa9, 0x76, 0xd7, 0xb5, 0x8f, 0xec, 0x81, + 0xd5, 0x53, 0x0f, 0x74, 0x96, 0x62, 0x8f, 0x85, 0x23, 0x84, 0x9b, 0xb0, 0x14, 0x4a, 0xb8, 0x79, + 0x23, 0xa9, 0x69, 0xf5, 0x5d, 0x58, 0x88, 0x1d, 0xe4, 0xb8, 0xdb, 0x61, 0x4e, 0xbe, 0x1d, 0x7e, + 0x04, 0x05, 0xaa, 0xc6, 0x3a, 0x8e, 0xdb, 0x25, 0x88, 0x64, 0xb1, 0x1c, 0x91, 0xac, 0x6e, 0x03, + 0x72, 0xe6, 0xcb, 0x21, 0xc3, 0x9b, 0x57, 0xc5, 0x06, 0xc3, 0x21, 0xad, 0x06, 0x85, 0x21, 0xf2, + 0x96, 0x8a, 0x18, 0x42, 0xbe, 0xb3, 0x06, 0xfd, 0x5d, 0xfe, 0x59, 0x06, 0x80, 0xf6, 0x4f, 0x95, + 0x3d, 0x01, 0x69, 0x59, 0x7d, 0x2c, 0x44, 0x32, 0xf9, 0x2d, 0xcb, 0xfc, 0x8c, 0x2a, 0xf3, 0xf9, + 0x74, 0xb2, 0xe1, 0x74, 0x4a, 0x30, 0xb3, 0x63, 0xbd, 0x68, 0xdb, 0xbf, 0x23, 0xae, 0x70, 0xa2, + 0x48, 0xf4, 0x83, 0x10, 0xcb, 0x35, 0x7e, 0xc1, 0x0f, 0x2b, 0xe8, 0xcd, 0xbf, 0xd5, 0xa8, 0x71, + 0x2a, 0xa6, 0xbf, 0xd1, 0x17, 0x20, 0x63, 0xb6, 0xb9, 0x9a, 0x5d, 0xdd, 0x64, 0xf1, 0x8a, 0x4d, + 0x11, 0xaf, 0xd8, 0x34, 0x45, 0xbc, 0x82, 0x5d, 0x7e, 0xff, 0xf8, 0x5f, 0x6f, 0x6a, 0x46, 0xc6, + 0x6c, 0x13, 0xc5, 0xd7, 0x18, 0x74, 0x7a, 0x27, 0x5d, 0x5c, 0x7f, 0x31, 0x24, 0x9c, 0xc0, 0x95, + 0x10, 0x97, 0x6f, 0x98, 0x5d, 0xa0, 0xf2, 0xc6, 0x18, 0x28, 0x62, 0x68, 0xd7, 0x5f, 0x50, 0x88, + 0x6d, 0xcb, 0xed, 0xd6, 0x9c, 0x8f, 0x07, 0xb1, 0x8e, 0x98, 0x0e, 0x1e, 0x07, 0x56, 0x2e, 0x03, + 0x98, 0x9e, 0x23, 0x76, 0x78, 0x09, 0xa6, 0x18, 0x5b, 0xb1, 0x43, 0x64, 0x85, 0xf2, 0xcf, 0x35, + 0x62, 0xb9, 0x51, 0xfd, 0x48, 0x5d, 0x9e, 0x89, 0xba, 0xf1, 0x1e, 0x14, 0x76, 0x87, 0xc2, 0xca, + 0xcf, 0xc4, 0xdd, 0x53, 0xd5, 0x16, 0xc5, 0xdd, 0x1d, 0x1a, 0x21, 0x1c, 0xda, 0x0a, 0x02, 0x17, + 0x4c, 0x51, 0xde, 0x4a, 0x08, 0x5c, 0x50, 0x80, 0xf4, 0xe8, 0xc5, 0x45, 0x3b, 0x70, 0xcb, 0x4d, + 0x28, 0x56, 0x5b, 0xe1, 0xbd, 0x34, 0x69, 0xad, 0x6f, 0x08, 0x37, 0x5c, 0x26, 0x3d, 0x58, 0xc2, + 0x20, 0xca, 0x9f, 0xf0, 0xbd, 0xb3, 0xfc, 0x11, 0x7b, 0x37, 0x79, 0x7f, 0xe3, 0x77, 0x4c, 0x0c, + 0xf4, 0x4b, 0xdc, 0xb1, 0xef, 0xe4, 0x61, 0x46, 0x50, 0x90, 0x62, 0xac, 0x6b, 0xc2, 0xd2, 0xe2, + 0x15, 0x68, 0x13, 0xa6, 0x77, 0xb0, 0xff, 0xcc, 0xe9, 0x26, 0x89, 0x04, 0xd6, 0x42, 0x45, 0x02, + 0x87, 0x42, 0xf7, 0x65, 0xfe, 0xa7, 0xac, 0x1c, 0xb1, 0x3e, 0xc2, 0x56, 0xbe, 0x46, 0x59, 0x5e, + 0x54, 0xa8, 0xa3, 0x2a, 0x30, 0xe9, 0x28, 0xd3, 0x17, 0xef, 0xde, 0x88, 0x3a, 0xaa, 0x14, 0xbb, + 0xcf, 0x50, 0x50, 0xd0, 0x03, 0x42, 0x0c, 0x61, 0x0f, 0x53, 0xb4, 0x87, 0xeb, 0x09, 0x54, 0x1a, + 0x76, 0x20, 0x23, 0x10, 0x7c, 0x53, 0xc2, 0x9f, 0x8e, 0xe3, 0x9b, 0x31, 0x7c, 0x09, 0x81, 0x98, + 0x5f, 0x21, 0x7b, 0x26, 0x59, 0xf5, 0x61, 0xab, 0x21, 0x33, 0xf2, 0x7d, 0xf5, 0xae, 0xc5, 0x0d, + 0xb7, 0x92, 0x3a, 0xf1, 0xb0, 0xdd, 0x50, 0x6f, 0x66, 0xf7, 0x55, 0x7e, 0xe7, 0xbe, 0xf9, 0x52, + 0x1a, 0x73, 0x1a, 0xaa, 0x74, 0xf8, 0xa2, 0xc2, 0x40, 0x54, 0x59, 0x46, 0x4c, 0x60, 0xa9, 0xd9, + 0x50, 0x98, 0xed, 0xbe, 0xca, 0x2c, 0x54, 0x71, 0x26, 0x0c, 0x2c, 0xda, 0x0d, 0x95, 0xb5, 0xde, + 0x85, 0xb9, 0x1a, 0x26, 0x8a, 0x8d, 0x4f, 0x87, 0xfb, 0x7e, 0xae, 0xca, 0xe8, 0x0a, 0x80, 0xa1, + 0xc2, 0xa3, 0x2d, 0x98, 0xdf, 0x73, 0x9d, 0x17, 0x2f, 0xc3, 0x03, 0x9b, 0xe3, 0x02, 0x5e, 0xea, + 0x41, 0x85, 0x30, 0x22, 0x18, 0x44, 0x0b, 0x47, 0xdd, 0xae, 0xad, 0x93, 0x3e, 0x35, 0x02, 0x73, + 0x46, 0x52, 0x13, 0xda, 0x92, 0x9c, 0xc8, 0xc1, 0x55, 0xec, 0x72, 0xfa, 0x55, 0xcc, 0x88, 0x83, + 0xd3, 0x3d, 0x7f, 0x86, 0x3b, 0xc7, 0xdb, 0xd8, 0xea, 0xf9, 0xcf, 0xa8, 0xb7, 0x28, 0xba, 0xe7, + 0x61, 0xb3, 0x21, 0xc3, 0x22, 0x13, 0x96, 0xda, 0x9d, 0x67, 0xb8, 0x7b, 0xd2, 0xc3, 0xdc, 0x44, + 0xa5, 0x46, 0x3a, 0xf5, 0x1b, 0x15, 0xef, 0xae, 0xcb, 0x7d, 0x24, 0xc1, 0x19, 0x89, 0xd8, 0x65, + 0x07, 0x8a, 0x94, 0x13, 0xbd, 0xa1, 0x33, 0xf0, 0xf0, 0x88, 0xab, 0x19, 0x57, 0xd3, 0x19, 0x45, + 0x4d, 0x0b, 0xc3, 0x89, 0x29, 0x6f, 0x51, 0x1c, 0xe5, 0x9e, 0x2f, 0x6f, 0x02, 0x92, 0xe8, 0x59, + 0x1a, 0xf7, 0x7d, 0xdb, 0x95, 0x84, 0x91, 0x28, 0x96, 0xff, 0x33, 0x47, 0xdd, 0x7d, 0x0c, 0xec, + 0x62, 0xa5, 0xd6, 0x75, 0x28, 0xd4, 0x5d, 0xd7, 0x71, 0xab, 0x4e, 0x17, 0xd3, 0x25, 0xcc, 0x19, + 0x61, 0x05, 0x31, 0xc5, 0x69, 0x61, 0x07, 0x7b, 0x9e, 0x75, 0x84, 0xb9, 0xef, 0x40, 0xa9, 0x43, + 0x6b, 0x00, 0x0d, 0x6f, 0xbb, 0xf2, 0x18, 0xe3, 0x21, 0x76, 0xa9, 0xd4, 0xc9, 0x1b, 0x52, 0x0d, + 0x7a, 0x57, 0xd9, 0x5d, 0x2e, 0x56, 0xae, 0xc4, 0x04, 0x23, 0x6b, 0xe6, 0x92, 0x51, 0x39, 0x0f, + 0xc2, 0x68, 0xd2, 0x25, 0x86, 0x4b, 0x16, 0x95, 0xd1, 0xa4, 0x76, 0x43, 0x81, 0x26, 0xd4, 0x46, + 0x65, 0x0d, 0x1f, 0x3e, 0x1f, 0x1f, 0x5e, 0x6a, 0x36, 0x64, 0x58, 0xc2, 0x62, 0xd5, 0xde, 0x89, + 0xe7, 0x63, 0xb7, 0x86, 0xc9, 0xed, 0xd4, 0xe3, 0xc2, 0x45, 0x61, 0x31, 0x15, 0xc2, 0x88, 0x60, + 0xa0, 0x07, 0x50, 0x08, 0xa3, 0x0f, 0x90, 0x40, 0xa6, 0xa2, 0x91, 0x11, 0x28, 0xf6, 0x4e, 0x7a, + 0xbe, 0x11, 0xa2, 0xa0, 0x07, 0x00, 0x92, 0x68, 0x64, 0x32, 0x66, 0x4d, 0xee, 0x20, 0x4e, 0x48, + 0x06, 0x44, 0xc4, 0x23, 0x61, 0x20, 0xec, 0x32, 0x09, 0x37, 0x9b, 0xb0, 0x79, 0x52, 0xbb, 0xa1, + 0x40, 0x97, 0x1f, 0x51, 0x7f, 0x15, 0xb3, 0x7f, 0x83, 0x6d, 0x79, 0x8b, 0x68, 0x50, 0x52, 0xe3, + 0x95, 0x34, 0xaa, 0xd7, 0x97, 0x63, 0x87, 0x49, 0x5a, 0xf9, 0x51, 0x0a, 0xd8, 0xf2, 0xab, 0xca, + 0x41, 0x10, 0xf3, 0xed, 0x09, 0xd5, 0xdb, 0xdc, 0x7c, 0xa3, 0x85, 0xf2, 0x43, 0x98, 0x33, 0x2d, + 0xef, 0xd8, 0xb4, 0x0e, 0x7b, 0x78, 0xdf, 0xc3, 0x2e, 0x61, 0x23, 0xf2, 0x77, 0x10, 0xda, 0xd2, + 0x41, 0x99, 0xb4, 0xed, 0x59, 0x9e, 0xf7, 0xb1, 0xe3, 0x76, 0xb9, 0x73, 0x23, 0x28, 0x97, 0xbf, + 0xa5, 0x91, 0x59, 0x52, 0xb9, 0x95, 0x68, 0xc6, 0xa4, 0xdb, 0xe2, 0x8a, 0xff, 0x25, 0x1b, 0x0d, + 0xf5, 0x04, 0xb1, 0xb8, 0x9c, 0x1c, 0x8b, 0x5b, 0xa3, 0xba, 0x5f, 0x35, 0xca, 0xa5, 0x9a, 0xf2, + 0x9f, 0x67, 0x08, 0x0d, 0x0f, 0x9e, 0xda, 0x47, 0xd5, 0x67, 0xd6, 0xe0, 0x08, 0xa3, 0x7b, 0xc1, + 0xec, 0x78, 0x48, 0x6a, 0x51, 0xbd, 0x70, 0xd0, 0xa6, 0x70, 0x07, 0xd9, 0x3a, 0xee, 0x03, 0x30, + 0x74, 0xe9, 0xa2, 0x72, 0x3d, 0xee, 0xdf, 0x08, 0x61, 0x0c, 0x09, 0x1e, 0x99, 0x30, 0xdf, 0x18, + 0xd8, 0xbe, 0x6d, 0xf5, 0x76, 0x70, 0xff, 0x10, 0xbb, 0xc2, 0x2a, 0x7b, 0x33, 0xad, 0x87, 0x4d, + 0x15, 0x9c, 0x5d, 0x9d, 0x23, 0x7d, 0xac, 0x56, 0x60, 0x31, 0x01, 0xec, 0x54, 0x61, 0xbb, 0x37, + 0x60, 0xae, 0xfd, 0xec, 0xc4, 0xef, 0x3a, 0x1f, 0x0f, 0x98, 0x6a, 0x23, 0x67, 0x43, 0x7e, 0x04, + 0x47, 0x26, 0x8a, 0xe5, 0xbf, 0x9b, 0x82, 0xcb, 0x11, 0x11, 0x9e, 0x78, 0xba, 0xb7, 0x60, 0x6e, + 0xcb, 0x71, 0x7c, 0xcf, 0x77, 0xad, 0xe1, 0xd0, 0x1e, 0x1c, 0xd1, 0x41, 0xf3, 0x86, 0x5a, 0x49, + 0x44, 0x03, 0xf7, 0xd9, 0xd0, 0x0d, 0xcd, 0xd2, 0x0d, 0x55, 0x44, 0x83, 0xd4, 0x6c, 0xc8, 0xb0, + 0x4c, 0x26, 0x85, 0x5b, 0xc5, 0xcd, 0xb5, 0x52, 0xda, 0x56, 0x1a, 0xea, 0xe9, 0xbf, 0x1b, 0x59, + 0x31, 0xb7, 0xd5, 0xae, 0xaa, 0x82, 0x41, 0x02, 0x30, 0x22, 0x3b, 0xf4, 0x18, 0x16, 0x98, 0x63, + 0x4d, 0xf2, 0xb4, 0x71, 0xc9, 0xaa, 0x98, 0x8c, 0x31, 0x20, 0x23, 0x8e, 0x17, 0x37, 0x45, 0x66, + 0x4e, 0x69, 0x8a, 0x3c, 0x86, 0x85, 0x47, 0x8e, 0x3d, 0x60, 0x1e, 0x65, 0x2e, 0xff, 0xb8, 0xa0, + 0x55, 0x66, 0x13, 0x03, 0x32, 0xe2, 0x78, 0x68, 0x1b, 0x74, 0xd6, 0x3b, 0xb5, 0x55, 0xd8, 0x84, + 0x0a, 0x71, 0x53, 0x34, 0x0a, 0x63, 0xc4, 0xb0, 0xc8, 0xf1, 0x56, 0xba, 0x5d, 0xc1, 0x85, 0x49, + 0xb6, 0x9d, 0xd4, 0x6c, 0xc8, 0xb0, 0x44, 0xf2, 0x07, 0xa4, 0xc2, 0xb0, 0x8b, 0x71, 0xc9, 0xaf, + 0x42, 0x18, 0x11, 0x8c, 0x32, 0x4e, 0xb6, 0x55, 0x12, 0xe9, 0x35, 0x42, 0x89, 0x99, 0xc9, 0x29, + 0xb1, 0xfc, 0x27, 0x19, 0x58, 0x89, 0xb8, 0xeb, 0x4c, 0xcb, 0x3d, 0xc2, 0x3e, 0x0d, 0x40, 0xf2, + 0x23, 0x22, 0x83, 0x30, 0x69, 0x5d, 0x30, 0x94, 0x3a, 0xea, 0x6c, 0x93, 0x61, 0x32, 0x0c, 0x46, + 0xae, 0x23, 0x72, 0xb6, 0xfe, 0x82, 0x88, 0x20, 0xdb, 0xe7, 0xb1, 0xed, 0xa0, 0x4c, 0x4c, 0x48, + 0xde, 0x9f, 0x69, 0xf7, 0xb1, 0x73, 0xe2, 0x9b, 0x76, 0xe7, 0xd8, 0xe3, 0xd2, 0x31, 0xa9, 0x89, + 0x60, 0x98, 0x09, 0x18, 0x4c, 0x68, 0x26, 0x35, 0xa1, 0x2f, 0xc0, 0x72, 0x9d, 0x88, 0x0b, 0xcb, + 0xc7, 0xd5, 0x13, 0xd7, 0xc5, 0x03, 0x9f, 0xc2, 0x78, 0x3c, 0xc2, 0x90, 0xdc, 0x58, 0xbe, 0x93, + 0x40, 0x95, 0x6c, 0x29, 0xb6, 0x47, 0xc3, 0xf4, 0x6c, 0x3b, 0x82, 0x72, 0xb9, 0x97, 0xc0, 0x54, + 0xe8, 0x1e, 0xe4, 0x88, 0xbe, 0xe1, 0x52, 0x5a, 0xe1, 0x09, 0x45, 0x51, 0x71, 0x59, 0x4d, 0x81, + 0xe9, 0xa6, 0x5a, 0xde, 0x71, 0xcd, 0xf2, 0xad, 0x43, 0xcb, 0x13, 0x22, 0x4f, 0xa9, 0x23, 0x52, + 0x4f, 0xe5, 0xa2, 0x74, 0xa9, 0xf7, 0x66, 0x9c, 0x25, 0x46, 0x40, 0xbf, 0xae, 0x90, 0x7d, 0xba, + 0x35, 0x5b, 0xfe, 0x85, 0x16, 0xa5, 0xf2, 0xb3, 0x46, 0x25, 0xd0, 0x93, 0x14, 0xdd, 0xb2, 0x99, + 0xce, 0x2f, 0x93, 0x68, 0x17, 0xc2, 0x2b, 0xe4, 0x0c, 0x79, 0x5c, 0x81, 0xfe, 0xbe, 0x08, 0x8d, + 0xf3, 0x67, 0x19, 0xd5, 0xa4, 0x0c, 0xf2, 0x65, 0x34, 0x29, 0x5f, 0xe6, 0xcb, 0x2c, 0xf0, 0x6d, + 0x0d, 0xba, 0x22, 0x73, 0xe7, 0xda, 0x88, 0xfb, 0x85, 0x88, 0x39, 0x09, 0x14, 0xb2, 0x95, 0xc2, + 0x1d, 0xcf, 0x6f, 0x06, 0xc2, 0x05, 0x5f, 0x05, 0xe0, 0x50, 0x84, 0xe1, 0x72, 0xb4, 0xeb, 0x1b, + 0x23, 0xba, 0x6e, 0xd4, 0x84, 0xbf, 0x20, 0x44, 0x43, 0x1f, 0xc2, 0x72, 0x62, 0xc0, 0x89, 0xab, + 0x92, 0x57, 0xe4, 0xfe, 0x92, 0x33, 0x22, 0x93, 0xf1, 0xcb, 0x7f, 0x91, 0x49, 0xe9, 0x99, 0x90, + 0xc0, 0x9e, 0x8b, 0x87, 0x96, 0xcb, 0x98, 0x87, 0x9c, 0x48, 0x58, 0x41, 0xd6, 0x5b, 0x1f, 0x10, + 0x6e, 0xe8, 0x72, 0x65, 0x2b, 0x8a, 0x29, 0xe9, 0x4b, 0x77, 0x61, 0x29, 0x88, 0x1d, 0xd3, 0x04, + 0x4d, 0xe6, 0x6e, 0xe7, 0x47, 0x9d, 0xd8, 0x86, 0x36, 0x01, 0x25, 0xc4, 0xc7, 0x99, 0xe4, 0x48, + 0x68, 0x21, 0x66, 0x99, 0x14, 0xce, 0x67, 0x2e, 0x51, 0xa9, 0x86, 0xcc, 0x8c, 0xc5, 0x96, 0x59, + 0xd2, 0x08, 0x2b, 0x10, 0x19, 0x41, 0x16, 0xed, 0xfb, 0xb8, 0xcb, 0x5d, 0x9c, 0x41, 0xb9, 0xfc, + 0xcf, 0x9a, 0x1a, 0x22, 0x0f, 0x76, 0x47, 0xc8, 0x5c, 0x59, 0x56, 0x6a, 0x93, 0xc9, 0xca, 0x4c, + 0xba, 0xac, 0x7c, 0x1b, 0x56, 0x42, 0x9e, 0x57, 0x90, 0xd8, 0x5e, 0xa6, 0xb4, 0xa6, 0x4b, 0xcc, + 0xdc, 0x28, 0x89, 0xf9, 0x49, 0x11, 0x8a, 0x7c, 0x16, 0xf4, 0xee, 0x21, 0xb2, 0xfa, 0x34, 0x29, + 0xab, 0xef, 0x37, 0x2b, 0x25, 0xa8, 0x12, 0x78, 0x28, 0xf3, 0x94, 0x0d, 0x5f, 0x4d, 0x70, 0x1b, + 0xd1, 0x3c, 0xb8, 0x09, 0x13, 0xd2, 0x0b, 0x67, 0x4a, 0x48, 0x87, 0xe4, 0x44, 0x24, 0x35, 0x6c, + 0x5f, 0x9c, 0x24, 0xc5, 0x68, 0x76, 0x6c, 0x8a, 0xd1, 0xdc, 0x99, 0x52, 0x8c, 0xe6, 0xcf, 0x94, + 0xda, 0x7e, 0x79, 0x92, 0xd4, 0x76, 0x7d, 0xb2, 0xd4, 0xa3, 0x85, 0x48, 0xea, 0xd1, 0x98, 0x38, + 0x26, 0xba, 0x88, 0x44, 0xa2, 0xc5, 0x8b, 0x4a, 0x24, 0x5a, 0xba, 0x80, 0x44, 0xa2, 0xe5, 0xf3, + 0x27, 0x12, 0xad, 0x5c, 0x48, 0x22, 0xd1, 0x95, 0x0b, 0x48, 0x24, 0x2a, 0x4d, 0x90, 0x48, 0x34, + 0x3a, 0xd9, 0xff, 0xea, 0xd8, 0x64, 0xff, 0x51, 0x89, 0x48, 0xab, 0xe7, 0x49, 0x44, 0xba, 0x76, + 0xee, 0x44, 0xa4, 0xeb, 0xbf, 0xba, 0x64, 0xff, 0x4f, 0x35, 0xf6, 0xfa, 0x88, 0x3f, 0xc5, 0xe1, + 0x6a, 0x41, 0x4b, 0x7e, 0x8a, 0x63, 0xf9, 0x78, 0x93, 0x41, 0x28, 0x92, 0x8f, 0x55, 0x8d, 0x5f, + 0x66, 0x66, 0x92, 0x65, 0x1a, 0x50, 0x94, 0x86, 0x48, 0x58, 0xe6, 0xe7, 0xd4, 0x65, 0x5e, 0x49, + 0x11, 0xd1, 0xb2, 0x7d, 0xf7, 0x4f, 0x39, 0x9a, 0x6c, 0x73, 0x21, 0x8a, 0xec, 0xb7, 0xf9, 0x31, + 0xbf, 0xc6, 0xf9, 0x31, 0x63, 0xb4, 0xc4, 0xdc, 0xa4, 0xd9, 0x2e, 0x7f, 0xa9, 0xb1, 0x27, 0x32, + 0x63, 0xb9, 0xc6, 0x1c, 0xc7, 0x35, 0xe7, 0xa3, 0x77, 0x33, 0x99, 0xde, 0xff, 0x36, 0x0b, 0x20, + 0xdd, 0x0d, 0x93, 0x3c, 0x0c, 0x82, 0x05, 0x32, 0x12, 0x0b, 0xdc, 0x82, 0x39, 0x22, 0x24, 0xf0, + 0x40, 0x35, 0xd3, 0xd4, 0xca, 0x08, 0xd5, 0xe4, 0x26, 0xa6, 0x9a, 0xf1, 0xfa, 0x75, 0xea, 0xa2, + 0xf4, 0xeb, 0xf4, 0x05, 0xe8, 0xd7, 0x99, 0xf3, 0x3d, 0x3e, 0xcb, 0x8f, 0xd3, 0x47, 0xe5, 0xbf, + 0xd1, 0x82, 0x43, 0x22, 0x64, 0xf4, 0x5e, 0x84, 0x8c, 0xca, 0xb1, 0xb8, 0xdd, 0x38, 0x4a, 0xfa, + 0x60, 0x1c, 0x25, 0xbd, 0xa9, 0x52, 0xd2, 0x4a, 0xc2, 0x08, 0x8e, 0x8b, 0x65, 0x42, 0xfa, 0x49, + 0x26, 0x1a, 0x55, 0x4c, 0x73, 0xaf, 0xaa, 0x84, 0x93, 0x19, 0x4f, 0x38, 0xd9, 0x0b, 0x24, 0x9c, + 0xdc, 0x45, 0x11, 0xce, 0xd4, 0x05, 0x10, 0xce, 0xf4, 0x18, 0xc2, 0x29, 0xff, 0x4b, 0x36, 0x1a, + 0x47, 0x42, 0x6f, 0x41, 0x9e, 0xb3, 0xb2, 0x38, 0xfe, 0xc5, 0x04, 0x36, 0x17, 0xa6, 0xb5, 0x00, + 0x25, 0x68, 0x55, 0x81, 0x96, 0x89, 0xa3, 0x55, 0x55, 0x34, 0x01, 0x8a, 0xde, 0xa1, 0x99, 0x4f, + 0x1c, 0x8f, 0x69, 0xb1, 0xa5, 0xa4, 0xc4, 0x02, 0x8e, 0x18, 0x02, 0xa3, 0x07, 0x50, 0x0c, 0x09, + 0x45, 0xf8, 0x2a, 0x52, 0xe8, 0x48, 0x84, 0xee, 0x24, 0x04, 0x54, 0x13, 0x4e, 0xae, 0x2e, 0xef, + 0x81, 0xe5, 0xe9, 0x95, 0xe2, 0x9e, 0xdc, 0xae, 0xdc, 0x87, 0x8a, 0x94, 0xee, 0xeb, 0x98, 0x3e, + 0x9f, 0xaf, 0x63, 0xbc, 0x05, 0x33, 0x33, 0x81, 0x05, 0x53, 0xfe, 0x03, 0x0d, 0x8a, 0xfc, 0x7c, + 0xa9, 0xb5, 0xf1, 0x45, 0x7a, 0xb8, 0xcc, 0x66, 0xd0, 0xb8, 0xcd, 0x10, 0x98, 0x66, 0xbc, 0x45, + 0x09, 0x91, 0x05, 0xe0, 0xe8, 0x3e, 0x3b, 0x29, 0x86, 0x9b, 0xe1, 0x7b, 0x15, 0x9a, 0x75, 0xc2, + 0x57, 0x2d, 0x23, 0x87, 0x08, 0xe5, 0xef, 0xe7, 0x60, 0x99, 0xbb, 0xc6, 0x84, 0x83, 0x9d, 0xa7, + 0x58, 0xbc, 0x06, 0xf3, 0xad, 0x93, 0xfe, 0xee, 0xd3, 0xb0, 0x73, 0x66, 0x0a, 0x45, 0x6a, 0x09, + 0x63, 0xd3, 0x9a, 0x60, 0xfe, 0x4c, 0x5d, 0xa8, 0x95, 0x68, 0x03, 0x74, 0x81, 0x17, 0x24, 0x8d, + 0x33, 0x7f, 0x44, 0xac, 0x9e, 0xdc, 0x06, 0x5b, 0xf8, 0x85, 0x1f, 0x04, 0xc1, 0x79, 0x09, 0x99, + 0x50, 0x64, 0xbf, 0xb6, 0x5e, 0x3e, 0xc6, 0x22, 0x7f, 0xf3, 0xae, 0x7c, 0x92, 0x89, 0x2b, 0xd9, + 0x94, 0x90, 0x98, 0xcb, 0x50, 0xee, 0x06, 0x3d, 0x4d, 0x4a, 0x4f, 0x60, 0x6f, 0xdc, 0xde, 0x99, + 0xa0, 0xef, 0x28, 0x6a, 0xf4, 0xb1, 0x5b, 0x90, 0xc2, 0x40, 0x2d, 0xaf, 0x23, 0x11, 0x53, 0xe1, + 0xa9, 0x8a, 0xc2, 0xcf, 0x10, 0x6f, 0x59, 0x7d, 0x00, 0x7a, 0x74, 0xe2, 0xc9, 0x4f, 0x0a, 0x92, + 0x73, 0x17, 0x95, 0xf7, 0x71, 0xca, 0xe4, 0xc6, 0xf5, 0xa2, 0xb8, 0x3d, 0xff, 0x5b, 0x83, 0xab, + 0x06, 0xf6, 0x98, 0x9f, 0xf8, 0x43, 0xcb, 0xc7, 0x6e, 0xdf, 0x72, 0x8f, 0x05, 0x8d, 0x84, 0x27, + 0xa5, 0x29, 0x27, 0xf5, 0x15, 0xf5, 0xa4, 0x18, 0x55, 0xbe, 0x1d, 0x71, 0x05, 0x24, 0xf7, 0x39, + 0xe6, 0xb4, 0x92, 0x77, 0x31, 0xfb, 0xbf, 0xb5, 0x8b, 0xe5, 0xff, 0xe0, 0xcf, 0x36, 0x47, 0xde, + 0x0b, 0x7e, 0xfb, 0xf2, 0xe2, 0x37, 0xed, 0xe5, 0xc5, 0xdf, 0x8b, 0x57, 0xce, 0xc4, 0xec, 0x7a, + 0x10, 0x5c, 0xe7, 0x98, 0x68, 0x5e, 0x8f, 0x29, 0x42, 0x6a, 0x74, 0x51, 0x10, 0xd5, 0xe8, 0x62, + 0xb2, 0xef, 0x41, 0x60, 0xb6, 0x65, 0x46, 0xe1, 0xa7, 0x1a, 0x6d, 0x6d, 0x28, 0x4a, 0x9d, 0x27, + 0x44, 0x2d, 0x36, 0x55, 0xa3, 0x2d, 0xf5, 0xa9, 0xaa, 0x2c, 0x1e, 0xda, 0xe3, 0x2c, 0xc1, 0x71, + 0x9d, 0x26, 0x5d, 0x2a, 0xfe, 0x3d, 0xaf, 0xa6, 0x8e, 0x24, 0x72, 0xcb, 0xbb, 0x8a, 0xea, 0x4b, + 0xbc, 0xa2, 0x87, 0xcd, 0xc2, 0x42, 0x90, 0x95, 0xe5, 0xbd, 0xe0, 0x62, 0xc5, 0x2d, 0xc4, 0xc5, + 0x84, 0xeb, 0x94, 0x48, 0x84, 0x10, 0x57, 0xb0, 0xb7, 0xc3, 0x03, 0xe5, 0x17, 0x92, 0xa5, 0xa4, + 0x63, 0x08, 0xa9, 0x91, 0x1f, 0xfe, 0xbd, 0xc0, 0xf7, 0xc1, 0xc3, 0x24, 0x8b, 0x09, 0x1e, 0x0f, + 0x31, 0x98, 0xf0, 0x92, 0xdc, 0x11, 0x09, 0xaf, 0xcc, 0xf5, 0xac, 0x84, 0x00, 0x45, 0x92, 0x93, + 0x92, 0xf6, 0xda, 0xe2, 0x3c, 0xc9, 0xa3, 0x38, 0x3c, 0xf1, 0x66, 0x86, 0x62, 0xaf, 0x45, 0x03, + 0x88, 0x2a, 0x94, 0x91, 0x80, 0x89, 0xea, 0x91, 0x9c, 0x18, 0xce, 0x80, 0x63, 0x63, 0x91, 0x91, + 0x4c, 0x1a, 0x21, 0xdf, 0xbb, 0xfc, 0x2d, 0x01, 0x2f, 0xa1, 0xc7, 0xaa, 0x7c, 0x07, 0x4a, 0xd6, + 0x6f, 0xa4, 0x25, 0x08, 0x8d, 0x11, 0xe9, 0xf7, 0xe5, 0x3b, 0x0e, 0x0f, 0x9a, 0xaf, 0x24, 0xdf, + 0x6c, 0x44, 0x50, 0x4b, 0xba, 0x13, 0xc9, 0x2e, 0xe7, 0xd9, 0xd3, 0xbd, 0x6a, 0x4d, 0xca, 0x63, + 0x9c, 0x4b, 0xcf, 0x63, 0xdc, 0x4e, 0x32, 0x14, 0xe6, 0xc7, 0x0a, 0xb6, 0x04, 0x53, 0xe0, 0x3e, + 0x5c, 0x8d, 0xab, 0xaa, 0x3d, 0x3c, 0xe8, 0xda, 0x83, 0x23, 0xea, 0x01, 0xcf, 0x1b, 0xe9, 0x00, + 0x68, 0x0b, 0xae, 0x2b, 0x6a, 0x93, 0x2a, 0x52, 0xe9, 0x82, 0xc2, 0x9e, 0xd2, 0x8e, 0x84, 0x21, + 0x17, 0xd3, 0x84, 0x01, 0x68, 0x60, 0x2e, 0x78, 0x52, 0x3b, 0x02, 0x02, 0xbd, 0x07, 0xd7, 0xe2, + 0xad, 0xc1, 0xeb, 0x12, 0xe1, 0x4a, 0x1f, 0x01, 0x72, 0x6e, 0xc5, 0xfc, 0x6d, 0x0d, 0x66, 0x65, + 0x93, 0x3f, 0xf1, 0xd2, 0x79, 0x1d, 0x0a, 0x2c, 0xd0, 0x25, 0x32, 0x24, 0x0a, 0x46, 0x58, 0x81, + 0x4a, 0x30, 0xa3, 0x6a, 0x63, 0x51, 0x94, 0xe2, 0x11, 0x39, 0x25, 0x1e, 0xb1, 0x0a, 0xf9, 0x9a, + 0xf3, 0xf1, 0x80, 0xb6, 0x4c, 0xd1, 0x96, 0xa0, 0x5c, 0xfe, 0xd3, 0x32, 0xe8, 0x82, 0xb7, 0x83, + 0x57, 0x4e, 0xc1, 0x9b, 0x26, 0x4d, 0x7e, 0xd3, 0x94, 0xe4, 0x58, 0x09, 0x4d, 0xa9, 0xac, 0x62, + 0x4a, 0xed, 0xaa, 0xac, 0xc6, 0xae, 0x53, 0x9f, 0x4b, 0x12, 0x28, 0xc1, 0xe3, 0xa5, 0xd1, 0xec, + 0x96, 0xf4, 0x9d, 0x87, 0x5f, 0xb9, 0xbc, 0xea, 0x82, 0x1e, 0x89, 0x60, 0x8b, 0xf0, 0xda, 0xdd, + 0x91, 0x4b, 0x8d, 0x22, 0xc9, 0xea, 0x33, 0xd6, 0x23, 0x6a, 0xc8, 0x57, 0x25, 0xf6, 0x29, 0xa9, + 0xcf, 0x8e, 0xec, 0x3e, 0x80, 0x66, 0xfb, 0x18, 0x62, 0xcb, 0x6a, 0x01, 0x26, 0x56, 0x0b, 0x92, + 0xe2, 0x2a, 0x9e, 0x49, 0x71, 0xcd, 0x9e, 0x42, 0x71, 0x45, 0xd4, 0xec, 0xdc, 0xa9, 0xd5, 0x6c, + 0x4c, 0x87, 0xcc, 0x9f, 0x49, 0x87, 0xa8, 0xe2, 0xfd, 0xf2, 0x29, 0xc5, 0x7b, 0xcc, 0x1b, 0xa0, + 0x9f, 0xc5, 0x1b, 0x90, 0x22, 0xec, 0x17, 0x4e, 0x29, 0xec, 0xd1, 0x85, 0x0b, 0xfb, 0xc5, 0xf3, + 0x0a, 0xfb, 0xa5, 0x73, 0x0b, 0xfb, 0xe5, 0xf3, 0x0a, 0xfb, 0x95, 0xb1, 0xc2, 0x1e, 0xbd, 0x1d, + 0xcb, 0x37, 0x13, 0x79, 0x1f, 0x2c, 0x32, 0x98, 0xd2, 0x9a, 0x70, 0x15, 0x08, 0xb3, 0x49, 0x4a, + 0x89, 0x57, 0x81, 0x30, 0xb9, 0xe4, 0xeb, 0xb0, 0x14, 0x69, 0x13, 0x51, 0xc0, 0xd8, 0x65, 0x34, + 0xc6, 0xf7, 0x49, 0x88, 0x4c, 0x04, 0x24, 0xf6, 0x89, 0x86, 0xb1, 0xf5, 0x55, 0x5b, 0x22, 0x6a, + 0x18, 0x73, 0x24, 0x8c, 0x1b, 0x8d, 0xa3, 0xb2, 0xf1, 0x52, 0xfa, 0x4d, 0x18, 0xd1, 0x6c, 0x89, + 0x50, 0xe3, 0xa9, 0x47, 0x34, 0x47, 0x8d, 0xc8, 0x1b, 0xd1, 0x36, 0xdc, 0x8c, 0xb4, 0xf0, 0xe4, + 0x24, 0xaf, 0xe2, 0x79, 0xf6, 0xd1, 0x00, 0x77, 0x69, 0x8c, 0x32, 0x6f, 0x8c, 0x03, 0x43, 0x4d, + 0x78, 0x25, 0xba, 0xaa, 0x20, 0x49, 0x29, 0xe8, 0xeb, 0x06, 0xed, 0x6b, 0x3c, 0x60, 0xea, 0x95, + 0x2f, 0xa4, 0x94, 0xb5, 0x11, 0x57, 0xbe, 0x90, 0x5e, 0xb6, 0x52, 0xb2, 0x74, 0x04, 0xa5, 0xde, + 0x8c, 0xc7, 0xb0, 0xa3, 0x30, 0xa9, 0xfe, 0x7e, 0xe6, 0xf5, 0x5d, 0xa7, 0xbc, 0x3a, 0x02, 0x02, + 0x3d, 0x82, 0xf5, 0xc4, 0xf8, 0xb6, 0x9c, 0xec, 0xf4, 0x0a, 0x9d, 0xc7, 0x58, 0xb8, 0x09, 0x62, + 0xfb, 0xe5, 0x89, 0x62, 0xfb, 0xdf, 0xd4, 0xe0, 0x46, 0xe2, 0x94, 0xa9, 0x9b, 0x81, 0x50, 0xdc, + 0xab, 0x94, 0xe2, 0xde, 0x1d, 0x49, 0x71, 0x23, 0x7b, 0x60, 0x84, 0x37, 0x7a, 0x14, 0xf4, 0x7b, + 0x69, 0x69, 0x54, 0x82, 0xd5, 0x6e, 0xd1, 0x69, 0x3c, 0x38, 0xfd, 0x34, 0x14, 0x86, 0x1b, 0x39, + 0x06, 0xfa, 0x96, 0x96, 0x12, 0x20, 0xa0, 0x2a, 0x8b, 0xcd, 0xe3, 0x33, 0x74, 0x1e, 0x95, 0xd3, + 0xcf, 0x23, 0xec, 0x83, 0x4d, 0x65, 0xdc, 0x48, 0xe8, 0x0f, 0xb5, 0x14, 0xda, 0xaf, 0xb6, 0x78, + 0x6e, 0x59, 0xe9, 0x35, 0x3a, 0x99, 0xf7, 0xce, 0xb2, 0x29, 0xbc, 0x0b, 0x36, 0x97, 0x31, 0xe3, + 0xa0, 0xef, 0x68, 0xf0, 0x4a, 0xfa, 0x74, 0xc5, 0x6c, 0x5e, 0xa7, 0xb3, 0xa9, 0x9e, 0x71, 0x6b, + 0x94, 0x09, 0x8d, 0x1f, 0x2d, 0x95, 0xa3, 0x85, 0xf2, 0xbd, 0x3d, 0x82, 0xa3, 0x85, 0xfe, 0xfd, + 0xae, 0x06, 0xe5, 0x91, 0x4b, 0x67, 0xa9, 0x75, 0x6f, 0xd0, 0x85, 0xd5, 0xce, 0xbe, 0xcd, 0xb4, + 0x1b, 0xb6, 0xb2, 0x09, 0xc6, 0x43, 0xdf, 0xd7, 0xe0, 0x33, 0xe3, 0x36, 0x80, 0xcd, 0x6c, 0x83, + 0xce, 0xec, 0xe1, 0xb9, 0xb6, 0x5c, 0x9a, 0xdc, 0x64, 0xa3, 0x9e, 0xdb, 0x79, 0xfd, 0x11, 0x2c, + 0x27, 0x9a, 0xf6, 0xa7, 0xf4, 0x53, 0x29, 0x6f, 0xbc, 0xa4, 0xee, 0xef, 0xd3, 0x8f, 0xbe, 0xa5, + 0x38, 0xd5, 0xc6, 0x4e, 0xee, 0x21, 0x5c, 0x4d, 0x35, 0x10, 0xc6, 0x75, 0x94, 0x97, 0x3b, 0x6a, + 0xc4, 0x52, 0x0d, 0x64, 0x51, 0x74, 0xce, 0xae, 0xcc, 0xb3, 0x76, 0xb5, 0x97, 0x42, 0xf1, 0x8a, + 0xb4, 0x3e, 0x55, 0x8f, 0xbb, 0x29, 0xb2, 0xe1, 0xcc, 0xab, 0x35, 0xe0, 0xd6, 0x24, 0x12, 0xf4, + 0x54, 0x7d, 0x7e, 0x00, 0xaf, 0x4e, 0x20, 0x08, 0x4f, 0x45, 0x28, 0x26, 0xbc, 0x36, 0x99, 0x34, + 0x3b, 0x55, 0xaf, 0xfb, 0xf0, 0xfa, 0x84, 0xa2, 0xe4, 0x54, 0xdd, 0x7e, 0x05, 0x36, 0x26, 0x97, + 0x03, 0xa7, 0x72, 0xd5, 0x34, 0x58, 0xd6, 0x8e, 0xf8, 0xbe, 0xe2, 0x39, 0xbe, 0x3c, 0x54, 0xfe, + 0xab, 0x0c, 0x2c, 0x25, 0x3d, 0x7f, 0x1c, 0xf1, 0x0a, 0x61, 0x2f, 0xf6, 0x35, 0xcd, 0xcd, 0x71, + 0x8f, 0x29, 0xd5, 0xaf, 0x6a, 0xc6, 0x02, 0x28, 0x17, 0xf2, 0x6d, 0xcd, 0x55, 0x73, 0xfc, 0xc7, + 0x2f, 0x47, 0xa5, 0xf5, 0x48, 0x3b, 0x2a, 0xef, 0xf5, 0x0f, 0x35, 0x80, 0x2d, 0xab, 0x73, 0x7c, + 0x32, 0xa4, 0x31, 0x98, 0xb4, 0x00, 0x5d, 0x23, 0x29, 0x40, 0xf7, 0xba, 0xf2, 0xf2, 0x22, 0xe8, + 0x64, 0xb4, 0x3f, 0xe9, 0xdc, 0x8e, 0xbc, 0xdf, 0xd7, 0x44, 0x7c, 0xa9, 0xe1, 0xe3, 0x7e, 0xe2, + 0x47, 0x50, 0xca, 0x30, 0xcb, 0xb3, 0xce, 0x9f, 0x48, 0x51, 0x4a, 0xa5, 0x8e, 0xc0, 0xd4, 0xf0, + 0x53, 0xeb, 0xa4, 0xc7, 0x61, 0x98, 0x47, 0x4f, 0xa9, 0x23, 0x47, 0xd4, 0x18, 0xf8, 0xd8, 0x1d, + 0x58, 0x3d, 0x1e, 0x58, 0x0b, 0xca, 0xe5, 0xbf, 0xd6, 0xe4, 0x30, 0x17, 0xfa, 0x32, 0xcc, 0x54, + 0x9d, 0x81, 0x8f, 0xe9, 0xb7, 0x42, 0xe2, 0x69, 0xde, 0x01, 0xe0, 0x26, 0x87, 0x62, 0x1b, 0x23, + 0x70, 0x56, 0x0d, 0xfa, 0xd6, 0x2f, 0x68, 0x38, 0x65, 0xa2, 0x4d, 0xb8, 0x1d, 0xf2, 0x46, 0xfd, + 0x6e, 0x18, 0x4f, 0x43, 0x6f, 0x85, 0x2f, 0x61, 0x63, 0xf9, 0x64, 0x02, 0x68, 0x93, 0x42, 0xb0, + 0x89, 0x31, 0xe8, 0xd5, 0x77, 0x00, 0xc2, 0xca, 0x53, 0xc5, 0x81, 0x5f, 0x57, 0x1e, 0xe0, 0x8f, + 0x78, 0x21, 0xf4, 0x11, 0x2c, 0xc4, 0xde, 0xa2, 0xa0, 0x5b, 0x30, 0xc7, 0xbe, 0xe9, 0x23, 0x9e, + 0xb7, 0x30, 0x24, 0xb5, 0x92, 0x1e, 0x33, 0x47, 0x91, 0xbe, 0x03, 0xa5, 0xd4, 0x6d, 0x7c, 0x0c, + 0xb0, 0x3f, 0xec, 0x5a, 0x3e, 0xf3, 0xe0, 0x5e, 0x81, 0x45, 0xe5, 0x1b, 0x41, 0xac, 0x49, 0xbf, + 0x84, 0x96, 0x61, 0x41, 0x7c, 0xfb, 0xa9, 0xd9, 0x6e, 0xf1, 0x6a, 0x0d, 0x2d, 0xc2, 0xe5, 0x7d, + 0x0f, 0xbb, 0x74, 0xf9, 0xbc, 0x32, 0x83, 0xe6, 0xa0, 0x60, 0xb6, 0x77, 0x79, 0x31, 0x4b, 0x50, + 0x83, 0xef, 0x38, 0x05, 0xa8, 0xb9, 0x8d, 0x4d, 0x28, 0x04, 0x5f, 0x20, 0x46, 0x97, 0xa1, 0xd8, + 0x72, 0xdc, 0xbe, 0xd5, 0xa3, 0x45, 0xfd, 0x12, 0xd2, 0x61, 0x96, 0x3f, 0xa6, 0x60, 0x35, 0xda, + 0xc6, 0xcf, 0x73, 0x00, 0xe1, 0xdb, 0x79, 0x34, 0x0f, 0x60, 0xb6, 0x77, 0x0f, 0xf6, 0xf7, 0x6a, + 0x15, 0xb3, 0xae, 0x5f, 0x42, 0x00, 0xd3, 0x95, 0xbd, 0xbd, 0x7a, 0xab, 0xa6, 0x6b, 0x28, 0x0f, + 0x39, 0xa3, 0x5e, 0xa9, 0xe9, 0x19, 0x34, 0x0b, 0x79, 0xd3, 0xd8, 0x6f, 0x55, 0x09, 0x4c, 0x96, + 0x74, 0xfa, 0xb0, 0x6e, 0x1e, 0x04, 0x35, 0x39, 0x54, 0x84, 0x99, 0xea, 0x6e, 0xab, 0x55, 0xaf, + 0x9a, 0xfa, 0x14, 0xe9, 0x92, 0x17, 0x0e, 0x8c, 0x5d, 0x7d, 0x1a, 0x2d, 0xc0, 0x5c, 0x73, 0xf7, + 0xe1, 0xc1, 0x76, 0xbd, 0x62, 0x98, 0x5b, 0xf5, 0x8a, 0xa9, 0xcf, 0x90, 0x1e, 0xaa, 0x2d, 0xa9, + 0x26, 0x4f, 0x27, 0x2a, 0xd7, 0x14, 0x10, 0x82, 0xf9, 0xea, 0x76, 0xbd, 0xfa, 0xf8, 0x60, 0xbb, + 0xf2, 0xb8, 0x5e, 0xdf, 0xab, 0x1b, 0x3a, 0x90, 0x7d, 0x25, 0x23, 0x57, 0x9b, 0xfb, 0x6d, 0xb3, + 0x6e, 0x1c, 0xd4, 0xea, 0x66, 0xa5, 0xd1, 0x6c, 0xeb, 0x45, 0x02, 0x4c, 0x1a, 0xda, 0xdb, 0x15, + 0xa3, 0x76, 0xd0, 0x68, 0xbd, 0xbf, 0xab, 0xcf, 0xd2, 0x0e, 0x5a, 0x07, 0x95, 0x66, 0x73, 0x97, + 0xcc, 0xf2, 0xa0, 0x51, 0xd3, 0xe7, 0xc8, 0x26, 0xca, 0x1d, 0xb4, 0x4d, 0x32, 0xff, 0x79, 0xba, + 0xff, 0x74, 0x07, 0x0e, 0xaa, 0xad, 0x83, 0x66, 0x65, 0xab, 0xde, 0xd4, 0x2f, 0xa3, 0x12, 0x2c, + 0x85, 0x95, 0x1f, 0xee, 0x1a, 0x8f, 0x39, 0xb8, 0x4e, 0x7a, 0xde, 0xab, 0x98, 0xd5, 0x6d, 0xd2, + 0xd0, 0x36, 0x77, 0x8d, 0xba, 0xbe, 0x40, 0xba, 0xa8, 0xd5, 0x9b, 0x75, 0x06, 0xcd, 0x2a, 0x11, + 0xa9, 0xdc, 0x33, 0x76, 0xbf, 0xf2, 0x55, 0x69, 0x61, 0x8b, 0xe8, 0x15, 0xb8, 0xc1, 0xfb, 0x6d, + 0xed, 0xb6, 0x0e, 0x9e, 0xec, 0x9a, 0x8d, 0xd6, 0xc3, 0x03, 0xa3, 0xbe, 0xd7, 0x6c, 0x54, 0x2b, + 0x07, 0xad, 0xfd, 0x1d, 0x7d, 0x09, 0xad, 0xc1, 0x6a, 0x1c, 0x84, 0xac, 0xa3, 0xd9, 0x30, 0xbf, + 0xaa, 0x2f, 0xa3, 0x25, 0xd0, 0xdb, 0x75, 0xf3, 0xc0, 0xa8, 0x7f, 0xb0, 0xdf, 0x30, 0xea, 0xb5, + 0x83, 0x66, 0xbb, 0xa5, 0xaf, 0x90, 0xda, 0x87, 0xd1, 0xda, 0x2b, 0x62, 0x6b, 0x9a, 0x15, 0xb3, + 0xde, 0x36, 0x69, 0x5d, 0x89, 0x1c, 0x09, 0xad, 0xab, 0x57, 0x6a, 0x75, 0x83, 0xec, 0xcc, 0x55, + 0x7a, 0x24, 0x6c, 0xbb, 0xeb, 0x95, 0xa6, 0xb9, 0xad, 0xaf, 0x92, 0x43, 0x27, 0xc7, 0x4f, 0x51, + 0xae, 0xa1, 0xab, 0xb0, 0xcc, 0xa7, 0xd4, 0xac, 0x57, 0xda, 0xf5, 0xed, 0xdd, 0x26, 0x47, 0xbd, + 0x4e, 0x9a, 0xe8, 0xe6, 0x57, 0xb7, 0xeb, 0xb5, 0xfd, 0x66, 0xfd, 0xa0, 0xba, 0xbb, 0xb3, 0x53, + 0x69, 0xd5, 0xda, 0xfa, 0x8d, 0x8d, 0x16, 0x40, 0xf8, 0xc5, 0x29, 0x42, 0x19, 0x84, 0xcc, 0x59, + 0x8d, 0x7e, 0x89, 0x8c, 0x20, 0xe4, 0x9c, 0xae, 0x11, 0xe2, 0xa5, 0x4c, 0x13, 0x30, 0xc0, 0x02, + 0xff, 0xc4, 0x9a, 0x81, 0xbf, 0x8e, 0x3b, 0x3e, 0xee, 0xea, 0xd9, 0x8d, 0x0d, 0x28, 0x04, 0x1f, + 0x34, 0x22, 0xe8, 0x6d, 0xec, 0xd3, 0x92, 0x7e, 0x89, 0xa0, 0x33, 0xe7, 0x2a, 0xab, 0xd0, 0x36, + 0xfe, 0x31, 0x07, 0x48, 0x5c, 0x29, 0x24, 0xde, 0x24, 0x14, 0x6f, 0x77, 0x8e, 0x65, 0x96, 0x94, + 0xbe, 0x1c, 0x13, 0xb0, 0x24, 0xe1, 0xd4, 0x58, 0x75, 0x06, 0xad, 0xd0, 0x3c, 0x8f, 0x68, 0x7d, + 0x96, 0x8c, 0xfe, 0x10, 0xfb, 0x01, 0xa7, 0xe7, 0xc8, 0xa6, 0x44, 0xe4, 0x0d, 0x6f, 0x9a, 0x22, + 0x27, 0xd2, 0xc6, 0x8c, 0x21, 0x79, 0xdd, 0x34, 0x21, 0x36, 0x35, 0x91, 0x87, 0xb7, 0xcc, 0xa0, + 0x9b, 0x70, 0xad, 0x8d, 0xfd, 0x78, 0x6c, 0x82, 0x03, 0xe4, 0xd1, 0x2a, 0xac, 0x70, 0x80, 0xc0, + 0xb9, 0xcd, 0xdb, 0x0a, 0x64, 0x0b, 0xd9, 0x6f, 0xbe, 0x6b, 0x3a, 0x90, 0x85, 0x89, 0xaa, 0xe0, + 0x19, 0x8f, 0x5e, 0x24, 0xe7, 0xbf, 0x47, 0xe4, 0x1d, 0xcf, 0xb4, 0xd3, 0x67, 0x09, 0xae, 0x81, + 0xfb, 0xce, 0x73, 0xf1, 0xaa, 0x53, 0x9f, 0x23, 0xb3, 0x54, 0x53, 0x2a, 0xf9, 0x40, 0xf3, 0xe8, + 0x06, 0x5c, 0x65, 0xbf, 0x13, 0x9c, 0xd6, 0xfa, 0x65, 0x74, 0x0d, 0xae, 0x44, 0x9a, 0x85, 0x36, + 0x60, 0xec, 0x24, 0x6e, 0x3d, 0xbc, 0xbf, 0x05, 0x74, 0x1d, 0x4a, 0xf1, 0x54, 0x1c, 0xde, 0x8a, + 0xd0, 0x2d, 0x58, 0x17, 0x4e, 0xdc, 0xb8, 0x7b, 0x97, 0x43, 0x2d, 0x92, 0x9d, 0x63, 0x0e, 0xb0, + 0xc8, 0x0d, 0x84, 0x03, 0x2c, 0xa1, 0xcf, 0xc0, 0x2b, 0x0c, 0x20, 0xd1, 0xc0, 0xe4, 0x60, 0xcb, + 0x1b, 0xdf, 0xd3, 0x60, 0x4e, 0x89, 0x36, 0x11, 0xbe, 0x16, 0x15, 0x3c, 0x1b, 0x45, 0xbf, 0x44, + 0x4e, 0x5c, 0x54, 0x2a, 0x6f, 0xf3, 0x75, 0x8d, 0x0c, 0x14, 0x6b, 0x12, 0xf7, 0x47, 0x03, 0x77, + 0xb0, 0xfd, 0x1c, 0x77, 0xf5, 0x0c, 0xd9, 0xa5, 0x18, 0xd8, 0xfb, 0x96, 0xdd, 0x23, 0xa4, 0x2f, + 0x8f, 0x69, 0x9c, 0x0c, 0x06, 0xa4, 0xe3, 0xdc, 0xc6, 0x61, 0x52, 0xbc, 0x8b, 0x1c, 0x93, 0x52, + 0x1b, 0xce, 0x31, 0xda, 0x22, 0x7a, 0xd2, 0x62, 0x2d, 0x6d, 0xdf, 0x19, 0x0e, 0xc9, 0xac, 0x36, + 0x7e, 0xa2, 0x81, 0x1e, 0xfd, 0x1a, 0x03, 0xe1, 0xa2, 0x4a, 0x57, 0x7c, 0x20, 0x4d, 0xbf, 0x14, + 0x12, 0x8b, 0xa8, 0xd2, 0x08, 0x45, 0xb5, 0x7d, 0xcb, 0xf5, 0x45, 0x4d, 0x86, 0x30, 0x09, 0xe9, + 0x56, 0x54, 0x64, 0x49, 0x2f, 0x8f, 0xed, 0x5e, 0xef, 0x6b, 0x4e, 0xff, 0xd0, 0x26, 0x4c, 0x73, + 0x05, 0x16, 0x2b, 0xdd, 0x6e, 0x94, 0x84, 0xf4, 0x29, 0x42, 0xe3, 0xac, 0xfb, 0x58, 0xdb, 0x34, + 0xe5, 0x34, 0x32, 0x4e, 0xac, 0x69, 0x86, 0x2c, 0x8a, 0x0c, 0x18, 0x6b, 0xc9, 0x6f, 0xec, 0x28, + 0xaf, 0xd4, 0xc9, 0x44, 0x42, 0x42, 0xd2, 0x2f, 0x51, 0xdd, 0xdb, 0x12, 0x45, 0x8d, 0x14, 0xab, + 0x41, 0x31, 0x43, 0x79, 0x85, 0x86, 0x82, 0x78, 0x4d, 0x76, 0xab, 0xf1, 0xe3, 0x4f, 0xd6, 0x2e, + 0xfd, 0xe8, 0xd3, 0x35, 0xed, 0xc7, 0x9f, 0xae, 0x69, 0x3f, 0xfb, 0x74, 0xed, 0xd2, 0x0f, 0xfe, + 0x6d, 0x4d, 0xfb, 0xda, 0x3d, 0xe9, 0xdf, 0xef, 0xf4, 0x2d, 0xdf, 0xb5, 0x5f, 0x38, 0xd4, 0xb0, + 0x10, 0x85, 0x01, 0xbe, 0x33, 0x3c, 0x3e, 0xba, 0x33, 0x3c, 0xbc, 0x13, 0x9a, 0x49, 0x87, 0xd3, + 0xf4, 0x6b, 0x76, 0xf7, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x52, 0x89, 0x29, 0xda, 0x67, + 0x00, 0x00, } func (m *CNStore) Marshal() (dAtA []byte, err error) { @@ -6900,6 +6949,13 @@ func (m *CNStore) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityDeployedProtocol != 0 { + i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xb8 + } if m.ViewMetadataIngressReady { i-- if m.ViewMetadataIngressReady { @@ -7494,6 +7550,13 @@ func (m *CNStoreHeartbeat) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityDeployedProtocol != 0 { + i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd0 + } if m.DDLVisibilityBarrierReady { i-- if m.DDLVisibilityBarrierReady { @@ -9924,6 +9987,13 @@ func (m *CNStoreInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityDeployedProtocol != 0 { + i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe0 + } if m.DDLVisibilityBarrierReady { i-- if m.DDLVisibilityBarrierReady { @@ -10190,6 +10260,11 @@ func (m *CNState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityDeployedProtocol != 0 { + i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) + i-- + dAtA[i] = 0x10 + } if len(m.Stores) > 0 { for k := range m.Stores { v := m.Stores[k] @@ -10632,6 +10707,11 @@ func (m *ClusterDetails) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityDeployedProtocol != 0 { + i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) + i-- + dAtA[i] = 0x38 + } if m.ViewMetadataAdmission != nil { { size, err := m.ViewMetadataAdmission.MarshalToSizedBuffer(dAtA[:i]) @@ -12422,6 +12502,9 @@ func (m *CNStore) ProtoSize() (n int) { if m.ViewMetadataIngressReady { n += 3 } + if m.DDLVisibilityDeployedProtocol != 0 { + n += 2 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -12692,6 +12775,9 @@ func (m *CNStoreHeartbeat) ProtoSize() (n int) { if m.DDLVisibilityBarrierReady { n += 3 } + if m.DDLVisibilityDeployedProtocol != 0 { + n += 2 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -13759,6 +13845,9 @@ func (m *CNStoreInfo) ProtoSize() (n int) { if m.DDLVisibilityBarrierReady { n += 3 } + if m.DDLVisibilityDeployedProtocol != 0 { + n += 2 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -13780,6 +13869,9 @@ func (m *CNState) ProtoSize() (n int) { n += mapEntrySize + 1 + sovLogservice(uint64(mapEntrySize)) } } + if m.DDLVisibilityDeployedProtocol != 0 { + n += 1 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -13997,6 +14089,9 @@ func (m *ClusterDetails) ProtoSize() (n int) { l = m.ViewMetadataAdmission.ProtoSize() n += 1 + l + sovLogservice(uint64(l)) } + if m.DDLVisibilityDeployedProtocol != 0 { + n += 1 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -15319,6 +15414,25 @@ func (m *CNStore) Unmarshal(dAtA []byte) error { } } m.ViewMetadataIngressReady = bool(v != 0) + case 23: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityDeployedProtocol", wireType) + } + m.DDLVisibilityDeployedProtocol = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DDLVisibilityDeployedProtocol |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -17203,6 +17317,25 @@ func (m *CNStoreHeartbeat) Unmarshal(dAtA []byte) error { } } m.DDLVisibilityBarrierReady = bool(v != 0) + case 26: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityDeployedProtocol", wireType) + } + m.DDLVisibilityDeployedProtocol = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DDLVisibilityDeployedProtocol |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -24199,6 +24332,25 @@ func (m *CNStoreInfo) Unmarshal(dAtA []byte) error { } } m.DDLVisibilityBarrierReady = bool(v != 0) + case 28: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityDeployedProtocol", wireType) + } + m.DDLVisibilityDeployedProtocol = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DDLVisibilityDeployedProtocol |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -24379,6 +24531,25 @@ func (m *CNState) Unmarshal(dAtA []byte) error { } m.Stores[mapkey] = *mapvalue iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityDeployedProtocol", wireType) + } + m.DDLVisibilityDeployedProtocol = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DDLVisibilityDeployedProtocol |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -25832,6 +26003,25 @@ func (m *ClusterDetails) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityDeployedProtocol", wireType) + } + m.DDLVisibilityDeployedProtocol = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DDLVisibilityDeployedProtocol |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) diff --git a/pkg/pb/logservice/logservice_test.go b/pkg/pb/logservice/logservice_test.go index e522248c46bdc..2dc840d28f317 100644 --- a/pkg/pb/logservice/logservice_test.go +++ b/pkg/pb/logservice/logservice_test.go @@ -35,27 +35,30 @@ func TestCNStateUpdate(t *testing.T) { state := CNState{Stores: map[string]CNStoreInfo{}} hb1 := CNStoreHeartbeat{ - UUID: "cn-a", - ServiceAddress: "addr-a", - Role: metadata.CNRole_AP, - CommandDeliveryAckSupported: true, - DDLVisibilityBarrierReady: true, - ViewMetadataIngressReady: true, + UUID: "cn-a", + ServiceAddress: "addr-a", + Role: metadata.CNRole_AP, + CommandDeliveryAckSupported: true, + DDLVisibilityBarrierReady: true, + DDLVisibilityDeployedProtocol: 38, + ViewMetadataIngressReady: true, } tick1 := uint64(100) state.Update(hb1, tick1) assert.Equal(t, state.Stores[hb1.UUID], CNStoreInfo{ - Tick: tick1, - ServiceAddress: hb1.ServiceAddress, - Role: metadata.CNRole_AP, - WorkState: metadata.WorkState_Working, - Labels: map[string]metadata.LabelList{}, - UpTime: state.Stores[hb1.UUID].UpTime, - CommandDeliveryAckSupported: true, - DDLVisibilityBarrierReady: true, - ViewMetadataIngressReady: true, + Tick: tick1, + ServiceAddress: hb1.ServiceAddress, + Role: metadata.CNRole_AP, + WorkState: metadata.WorkState_Working, + Labels: map[string]metadata.LabelList{}, + UpTime: state.Stores[hb1.UUID].UpTime, + CommandDeliveryAckSupported: true, + DDLVisibilityBarrierReady: true, + DDLVisibilityDeployedProtocol: 38, + ViewMetadataIngressReady: true, }) + assert.Equal(t, int64(38), state.DDLVisibilityDeployedProtocol) hb2 := CNStoreHeartbeat{UUID: "cn-b", ServiceAddress: "addr-b", Role: metadata.CNRole_TP} tick2 := uint64(200) @@ -74,6 +77,8 @@ func TestCNStateUpdate(t *testing.T) { tick3 := uint64(300) state.Update(hb3, tick3) + assert.Equal(t, int64(38), state.DDLVisibilityDeployedProtocol, + "markerless/restarted heartbeats cannot lower the committed cluster epoch") assert.Equal(t, state.Stores[hb3.UUID], CNStoreInfo{ Tick: tick3, ServiceAddress: hb3.ServiceAddress, diff --git a/proto/logservice.proto b/proto/logservice.proto index 411bae8feb362..45b01659edee4 100644 --- a/proto/logservice.proto +++ b/proto/logservice.proto @@ -66,6 +66,7 @@ message CNStore { bool DDLVisibilityBarrierReady = 21; // ViewMetadataIngressReady is retained for raw control-plane inventory. bool ViewMetadataIngressReady = 22; + int64 DDLVisibilityDeployedProtocol = 23; } message TNStore { @@ -170,6 +171,9 @@ message CNStoreHeartbeat { // listener has started successfully. Admission alone is not routability. bool ViewMetadataIngressReady = 24; bool DDLVisibilityBarrierReady = 25; + // DDLVisibilityDeployedProtocol reports only a locally committed deployment + // marker. Provisional activation must never advance the cluster-wide epoch. + int64 DDLVisibilityDeployedProtocol = 26; } // CNAllocateID is the periodic message sent tp the HAKeeper by CN stores. @@ -694,12 +698,17 @@ message CNStoreInfo { bool ViewMetadataAdmissionReady = 25; bool ViewMetadataIngressReady = 26; bool DDLVisibilityBarrierReady = 27; + int64 DDLVisibilityDeployedProtocol = 28; } // CNState contains all CN details known to the HAKeeper. message CNState { - // Stores is keyed by CN store UUID. + // Stores is keyed by CN store UUID. map Stores = 1 [(gogoproto.nullable) = false]; + // DDLVisibilityDeployedProtocol is a monotonic cluster deployment epoch. + // Once a complete-target cut commits, markerless replacement/scale-out CNs + // must join that fence instead of reopening on an older protocol. + int64 DDLVisibilityDeployedProtocol = 2; } @@ -765,6 +774,7 @@ message ClusterDetails { repeated ProxyStore ProxyStores = 4 [(gogoproto.nullable) = false]; repeated DeletedStore DeletedStores = 5 [(gogoproto.nullable) = false]; ViewMetadataAdmission ViewMetadataAdmission = 6; + int64 DDLVisibilityDeployedProtocol = 7; } // ClusterInfo provides a global view of all shards in the cluster. It From b4bf842e6f79520d556cec65d7d96c7672599240 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sat, 29 Aug 2026 21:43:03 +0800 Subject: [PATCH 16/34] fix: gate DDL epoch on HAKeeper capability --- pkg/cnservice/server_ddl_visibility.go | 23 + pkg/cnservice/server_ddl_visibility_test.go | 19 + pkg/hakeeper/rsm.go | 15 +- pkg/logservice/store.go | 17 +- pkg/pb/logservice/logservice.go | 1 + pkg/pb/logservice/logservice.pb.go | 938 +++++++++++--------- pkg/pb/logservice/logservice_test.go | 24 +- proto/logservice.proto | 7 + 8 files changed, 613 insertions(+), 431 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 942655cb2847b..5f8a6390146ba 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -17,6 +17,7 @@ package cnservice import ( "context" "errors" + "fmt" "time" "github.com/matrixorigin/matrixone/pkg/clusterservice" @@ -262,6 +263,9 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets if err != nil { return err } + if err := s.requireDDLVisibilityEpochHAKeeperCapability(ctx); err != nil { + return err + } barrierCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) defer cancel() @@ -353,6 +357,25 @@ func (s *service) persistDDLVisibilityDeployedProtocol(version int64) error { return nil } +func (s *service) requireDDLVisibilityEpochHAKeeperCapability(ctx context.Context) error { + queryCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) + defer cancel() + details, err := s._hakeeperClient.GetClusterDetails(queryCtx) + if err != nil { + return moerr.AttachCause(queryCtx, err) + } + if len(details.LogStores) == 0 { + return moerr.NewInvalidStateNoCtx("DDL visibility activation requires HAKeeper capability inventory") + } + for _, store := range details.LogStores { + if !store.DDLVisibilityDeployedProtocolSupported { + return moerr.NewInvalidStateNoCtx(fmt.Sprintf( + "LogStore %s does not support the durable DDL visibility deployment epoch", store.UUID)) + } + } + return nil +} + func validateDDLVisibilityActivationTargets(serviceID string, targets []string) (map[string]struct{}, error) { result := make(map[string]struct{}, len(targets)) for _, target := range targets { diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index c7851560c6a3b..5065f49369864 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -180,6 +180,7 @@ type ddlVisibilityWithdrawalHAKeeperClient struct { queryClosedBeforeSend bool closeCalls int clusterDeployedProtocol int64 + oldHAKeeperReplica bool } func (c *ddlVisibilityWithdrawalHAKeeperClient) GetClusterDetails( @@ -187,6 +188,9 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) GetClusterDetails( ) (logservicepb.ClusterDetails, error) { return logservicepb.ClusterDetails{ DDLVisibilityDeployedProtocol: c.clusterDeployedProtocol, + LogStores: []logservicepb.LogStore{{ + UUID: "log-1", DDLVisibilityDeployedProtocolSupported: !c.oldHAKeeperReplica, + }}, }, nil } @@ -399,6 +403,21 @@ func TestDefaultV38StartupUsesLastDeployedProtocolUntilActivation(t *testing.T) require.False(t, s.ddlVisibilityActivationFenced.Load()) } +func TestDDLVisibilityEpochHAKeeperCapabilityRejectsOldLeaderView(t *testing.T) { + client := &ddlVisibilityWithdrawalHAKeeperClient{} + s := &service{ + cfg: &Config{}, _hakeeperClient: client, + } + s.cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second + require.NoError(t, s.requireDDLVisibilityEpochHAKeeperCapability(context.Background())) + + // A leader failover to an old RSM returns the additive field as false. The + // activation entry point must interpret that as unsupported, never epoch 0. + client.oldHAKeeperReplica = true + err := s.requireDDLVisibilityEpochHAKeeperCapability(context.Background()) + require.ErrorContains(t, err, "does not support the durable DDL visibility deployment epoch") +} + func TestMarkerlessCNJoinsCommittedClusterFailClosed(t *testing.T) { const serviceID = "ddl-visibility-markerless-post-cut-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) diff --git a/pkg/hakeeper/rsm.go b/pkg/hakeeper/rsm.go index 0ee4b8f49bdea..fdcd5d863fa62 100644 --- a/pkg/hakeeper/rsm.go +++ b/pkg/hakeeper/rsm.go @@ -1782,13 +1782,14 @@ func (s *stateMachine) handleClusterDetailsQuery(cfg Config) *pb.ClusterDetails state = pb.TimeoutState } n := pb.LogStore{ - UUID: uuid, - Tick: info.Tick, - State: state, - ServiceAddress: info.ServiceAddress, - Replicas: info.Replicas, - ConfigData: info.ConfigData, - Locality: info.Locality, + UUID: uuid, + Tick: info.Tick, + State: state, + ServiceAddress: info.ServiceAddress, + Replicas: info.Replicas, + ConfigData: info.ConfigData, + Locality: info.Locality, + DDLVisibilityDeployedProtocolSupported: info.DDLVisibilityDeployedProtocolSupported, } cd.LogStores = append(cd.LogStores, n) } diff --git a/pkg/logservice/store.go b/pkg/logservice/store.go index 57fa5a49008c5..93b44e8c772c9 100644 --- a/pkg/logservice/store.go +++ b/pkg/logservice/store.go @@ -1523,14 +1523,15 @@ func (l *store) hakeeperTick() { func (l *store) getHeartbeatMessage() pb.LogStoreHeartbeat { m := pb.LogStoreHeartbeat{ - UUID: l.id(), - RaftAddress: l.cfg.RaftServiceAddr(), - ServiceAddress: l.cfg.LogServiceServiceAddr(), - GossipAddress: l.cfg.GossipServiceAddr(), - Replicas: make([]pb.LogReplicaInfo, 0), - Locality: l.cfg.getLocality(), - CommandDeliverySupported: true, - ViewMetadataAdmissionSupported: true, + UUID: l.id(), + RaftAddress: l.cfg.RaftServiceAddr(), + ServiceAddress: l.cfg.LogServiceServiceAddr(), + GossipAddress: l.cfg.GossipServiceAddr(), + Replicas: make([]pb.LogReplicaInfo, 0), + Locality: l.cfg.getLocality(), + CommandDeliverySupported: true, + ViewMetadataAdmissionSupported: true, + DDLVisibilityDeployedProtocolSupported: true, } opts := dragonboat.NodeHostInfoOption{ SkipLogInfo: true, diff --git a/pkg/pb/logservice/logservice.go b/pkg/pb/logservice/logservice.go index e6b0b4c3b0cdb..223f483ff7cc4 100644 --- a/pkg/pb/logservice/logservice.go +++ b/pkg/pb/logservice/logservice.go @@ -279,6 +279,7 @@ func (s *LogState) updateStores(hb LogStoreHeartbeat, tick uint64) { storeInfo.Locality = hb.Locality storeInfo.CommandDeliverySupported = hb.CommandDeliverySupported storeInfo.ViewMetadataAdmissionSupported = hb.ViewMetadataAdmissionSupported + storeInfo.DDLVisibilityDeployedProtocolSupported = hb.DDLVisibilityDeployedProtocolSupported s.Stores[hb.UUID] = storeInfo } diff --git a/pkg/pb/logservice/logservice.pb.go b/pkg/pb/logservice/logservice.pb.go index e1972e60d0525..74dcf0d53f4c6 100644 --- a/pkg/pb/logservice/logservice.pb.go +++ b/pkg/pb/logservice/logservice.pb.go @@ -859,16 +859,19 @@ func (m *TNStore) GetAutoIncrEpochFenceSupported() bool { } type LogStore struct { - UUID string `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"` - ServiceAddress string `protobuf:"bytes,2,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` - Tick uint64 `protobuf:"varint,3,opt,name=Tick,proto3" json:"Tick,omitempty"` - State NodeState `protobuf:"varint,4,opt,name=State,proto3,enum=logservice.NodeState" json:"State,omitempty"` - Replicas []LogReplicaInfo `protobuf:"bytes,5,rep,name=Replicas,proto3" json:"Replicas"` - ConfigData *ConfigData `protobuf:"bytes,6,opt,name=ConfigData,proto3" json:"ConfigData,omitempty"` - Locality Locality `protobuf:"bytes,7,opt,name=Locality,proto3" json:"Locality"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + UUID string `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"` + ServiceAddress string `protobuf:"bytes,2,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` + Tick uint64 `protobuf:"varint,3,opt,name=Tick,proto3" json:"Tick,omitempty"` + State NodeState `protobuf:"varint,4,opt,name=State,proto3,enum=logservice.NodeState" json:"State,omitempty"` + Replicas []LogReplicaInfo `protobuf:"bytes,5,rep,name=Replicas,proto3" json:"Replicas"` + ConfigData *ConfigData `protobuf:"bytes,6,opt,name=ConfigData,proto3" json:"ConfigData,omitempty"` + Locality Locality `protobuf:"bytes,7,opt,name=Locality,proto3" json:"Locality"` + // DDLVisibilityDeployedProtocolSupported proves the hosted HAKeeper RSM can + // persist and return the cluster-wide DDL deployment epoch. + DDLVisibilityDeployedProtocolSupported bool `protobuf:"varint,8,opt,name=DDLVisibilityDeployedProtocolSupported,proto3" json:"DDLVisibilityDeployedProtocolSupported,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LogStore) Reset() { *m = LogStore{} } @@ -953,6 +956,13 @@ func (m *LogStore) GetLocality() Locality { return Locality{} } +func (m *LogStore) GetDDLVisibilityDeployedProtocolSupported() bool { + if m != nil { + return m.DDLVisibilityDeployedProtocolSupported + } + return false +} + // LogShardInfo contains information a log shard. type LogShardInfo struct { // ShardID is the ID of a Log shard. @@ -1517,10 +1527,13 @@ type LogStoreHeartbeat struct { CommandDeliverySupported bool `protobuf:"varint,9,opt,name=CommandDeliverySupported,proto3" json:"CommandDeliverySupported,omitempty"` // ViewMetadataAdmissionSupported proves that every HAKeeper RSM hosted by // this LogStore can decode the durable admission update and snapshot fields. - ViewMetadataAdmissionSupported bool `protobuf:"varint,10,opt,name=ViewMetadataAdmissionSupported,proto3" json:"ViewMetadataAdmissionSupported,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ViewMetadataAdmissionSupported bool `protobuf:"varint,10,opt,name=ViewMetadataAdmissionSupported,proto3" json:"ViewMetadataAdmissionSupported,omitempty"` + // This gates the HAKeeper RSM schema used by the durable DDL deployment + // epoch across both voting and non-voting replicas. + DDLVisibilityDeployedProtocolSupported bool `protobuf:"varint,11,opt,name=DDLVisibilityDeployedProtocolSupported,proto3" json:"DDLVisibilityDeployedProtocolSupported,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LogStoreHeartbeat) Reset() { *m = LogStoreHeartbeat{} } @@ -1626,6 +1639,13 @@ func (m *LogStoreHeartbeat) GetViewMetadataAdmissionSupported() bool { return false } +func (m *LogStoreHeartbeat) GetDDLVisibilityDeployedProtocolSupported() bool { + if m != nil { + return m.DDLVisibilityDeployedProtocolSupported + } + return false +} + // TNShardInfo contains information of a launched TN shard. type TNShardInfo struct { // ShardID uniquely identifies a TN shard. Each TN shard manages a Primary @@ -5105,19 +5125,20 @@ func (m *RestoreIDWatermarkRequest) GetLogServiceRecovery() bool { // LogStoreInfo contains information of all replicas found on a Log store. type LogStoreInfo struct { - Tick uint64 `protobuf:"varint,1,opt,name=Tick,proto3" json:"Tick,omitempty"` - RaftAddress string `protobuf:"bytes,2,opt,name=RaftAddress,proto3" json:"RaftAddress,omitempty"` - ServiceAddress string `protobuf:"bytes,3,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` - GossipAddress string `protobuf:"bytes,4,opt,name=GossipAddress,proto3" json:"GossipAddress,omitempty"` - Replicas []LogReplicaInfo `protobuf:"bytes,5,rep,name=Replicas,proto3" json:"Replicas"` - TaskServiceCreated bool `protobuf:"varint,6,opt,name=TaskServiceCreated,proto3" json:"TaskServiceCreated,omitempty"` - ConfigData *ConfigData `protobuf:"bytes,7,opt,name=ConfigData,proto3" json:"ConfigData,omitempty"` - Locality Locality `protobuf:"bytes,8,opt,name=Locality,proto3" json:"Locality"` - CommandDeliverySupported bool `protobuf:"varint,9,opt,name=CommandDeliverySupported,proto3" json:"CommandDeliverySupported,omitempty"` - ViewMetadataAdmissionSupported bool `protobuf:"varint,10,opt,name=ViewMetadataAdmissionSupported,proto3" json:"ViewMetadataAdmissionSupported,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Tick uint64 `protobuf:"varint,1,opt,name=Tick,proto3" json:"Tick,omitempty"` + RaftAddress string `protobuf:"bytes,2,opt,name=RaftAddress,proto3" json:"RaftAddress,omitempty"` + ServiceAddress string `protobuf:"bytes,3,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` + GossipAddress string `protobuf:"bytes,4,opt,name=GossipAddress,proto3" json:"GossipAddress,omitempty"` + Replicas []LogReplicaInfo `protobuf:"bytes,5,rep,name=Replicas,proto3" json:"Replicas"` + TaskServiceCreated bool `protobuf:"varint,6,opt,name=TaskServiceCreated,proto3" json:"TaskServiceCreated,omitempty"` + ConfigData *ConfigData `protobuf:"bytes,7,opt,name=ConfigData,proto3" json:"ConfigData,omitempty"` + Locality Locality `protobuf:"bytes,8,opt,name=Locality,proto3" json:"Locality"` + CommandDeliverySupported bool `protobuf:"varint,9,opt,name=CommandDeliverySupported,proto3" json:"CommandDeliverySupported,omitempty"` + ViewMetadataAdmissionSupported bool `protobuf:"varint,10,opt,name=ViewMetadataAdmissionSupported,proto3" json:"ViewMetadataAdmissionSupported,omitempty"` + DDLVisibilityDeployedProtocolSupported bool `protobuf:"varint,11,opt,name=DDLVisibilityDeployedProtocolSupported,proto3" json:"DDLVisibilityDeployedProtocolSupported,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *LogStoreInfo) Reset() { *m = LogStoreInfo{} } @@ -5223,6 +5244,13 @@ func (m *LogStoreInfo) GetViewMetadataAdmissionSupported() bool { return false } +func (m *LogStoreInfo) GetDDLVisibilityDeployedProtocolSupported() bool { + if m != nil { + return m.DDLVisibilityDeployedProtocolSupported + } + return false +} + type LogState struct { // Shards is keyed by ShardID, it contains details aggregated from all Log // stores. Each pb.LogShardInfo here contains data aggregated from @@ -6545,384 +6573,385 @@ func init() { func init() { proto.RegisterFile("logservice.proto", fileDescriptor_fd1040c5381ab5a7) } var fileDescriptor_fd1040c5381ab5a7 = []byte{ - // 6018 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xdb, 0x6f, 0x1b, 0xd9, - 0x79, 0xb8, 0x87, 0xa4, 0x24, 0xf2, 0xa3, 0x24, 0x8f, 0x8e, 0x2e, 0xa6, 0x65, 0x5b, 0xd6, 0x72, - 0x9d, 0x5d, 0xaf, 0xb2, 0x91, 0xf3, 0xb3, 0xb3, 0x8b, 0x4d, 0x7e, 0x8e, 0x77, 0x29, 0x92, 0x6b, - 0xd1, 0xa6, 0x28, 0xed, 0x70, 0xe4, 0x4d, 0x02, 0x2c, 0x84, 0x11, 0x79, 0x2c, 0x4f, 0x44, 0x72, - 0x98, 0x99, 0x91, 0xd7, 0x6e, 0xdf, 0x8a, 0xa6, 0x28, 0x1a, 0x20, 0x68, 0x80, 0xa0, 0x4d, 0x2f, - 0x69, 0xd3, 0xbe, 0xf5, 0x29, 0x2f, 0xed, 0xbf, 0x50, 0xe4, 0xa9, 0x08, 0xf2, 0x58, 0xa0, 0x69, - 0x76, 0xfb, 0x52, 0x20, 0xaf, 0x45, 0x83, 0x3e, 0x14, 0x28, 0xce, 0x6d, 0xe6, 0x9c, 0xb9, 0x90, - 0xd4, 0xa5, 0x49, 0x13, 0xe4, 0x49, 0x3c, 0xe7, 0x7c, 0xdf, 0xb9, 0x7e, 0xb7, 0xf3, 0x7d, 0xdf, - 0x19, 0x81, 0xde, 0x73, 0x8e, 0x3c, 0xec, 0x3e, 0xb7, 0x3b, 0x78, 0x73, 0xe8, 0x3a, 0xbe, 0x83, - 0x20, 0xac, 0x59, 0xfd, 0xdc, 0x91, 0xed, 0x3f, 0x3b, 0x39, 0xdc, 0xec, 0x38, 0xfd, 0x3b, 0x47, - 0xce, 0x91, 0x73, 0x87, 0x82, 0x1c, 0x9e, 0x3c, 0xa5, 0x25, 0x5a, 0xa0, 0xbf, 0x18, 0xea, 0xea, - 0xcd, 0x23, 0xc7, 0x39, 0xea, 0xe1, 0x10, 0xca, 0xb7, 0xfb, 0xd8, 0xf3, 0xad, 0xfe, 0x90, 0x03, - 0xcc, 0xf7, 0xb1, 0x6f, 0x75, 0x2d, 0xdf, 0x62, 0xe5, 0xf2, 0xb7, 0x0b, 0x30, 0x53, 0x6d, 0xb5, - 0x7d, 0xc7, 0xc5, 0x08, 0x41, 0x6e, 0x7f, 0xbf, 0x51, 0x2b, 0x69, 0xeb, 0xda, 0xed, 0x82, 0x41, - 0x7f, 0xa3, 0xd7, 0x60, 0xbe, 0xcd, 0xa6, 0x52, 0xe9, 0x76, 0x5d, 0xec, 0x79, 0xa5, 0x0c, 0x6d, - 0x8d, 0xd4, 0xa2, 0x35, 0x80, 0xf6, 0x07, 0x4d, 0x01, 0x93, 0xa5, 0x30, 0x52, 0x0d, 0xda, 0x04, - 0xd4, 0x74, 0x3a, 0xc7, 0x91, 0xbe, 0x72, 0x14, 0x2e, 0xa1, 0x05, 0xdd, 0x82, 0x9c, 0xe1, 0xf4, - 0x70, 0x69, 0x7a, 0x5d, 0xbb, 0x3d, 0x7f, 0x57, 0xdf, 0x0c, 0xa6, 0x5d, 0x6d, 0x91, 0x7a, 0x83, - 0xb6, 0x92, 0x19, 0x9b, 0x76, 0xe7, 0xb8, 0x34, 0xb3, 0xae, 0xdd, 0xce, 0x19, 0xf4, 0x37, 0xfa, - 0x2c, 0x4c, 0xb5, 0x7d, 0xcb, 0xc7, 0xa5, 0x3c, 0x45, 0x5d, 0xde, 0x94, 0xf6, 0xb7, 0xe5, 0x74, - 0x31, 0x6d, 0x34, 0x18, 0x0c, 0xfa, 0x32, 0x4c, 0x37, 0xad, 0x43, 0xdc, 0xf3, 0x4a, 0x85, 0xf5, - 0xec, 0xed, 0xe2, 0xdd, 0x9b, 0x32, 0x34, 0xdf, 0x97, 0x4d, 0x06, 0x51, 0x1f, 0xf8, 0xee, 0xcb, - 0xad, 0xdc, 0x8f, 0x7e, 0x7a, 0xf3, 0x92, 0xc1, 0x91, 0xd0, 0xff, 0x83, 0xc2, 0x87, 0x8e, 0x7b, - 0xcc, 0xc6, 0x03, 0x3a, 0xde, 0x62, 0x38, 0xd5, 0xa0, 0xc9, 0x08, 0xa1, 0x50, 0x19, 0x66, 0x3f, - 0x38, 0xc1, 0xee, 0x4b, 0xb1, 0x05, 0x45, 0xba, 0x05, 0x4a, 0x1d, 0x7a, 0x1b, 0xa0, 0xea, 0x0c, - 0x9e, 0xda, 0x47, 0x35, 0xcb, 0xb7, 0x4a, 0xb3, 0xeb, 0xda, 0xed, 0xe2, 0xdd, 0x15, 0x65, 0x66, - 0x41, 0xab, 0x21, 0x41, 0xa2, 0xb7, 0x21, 0x6f, 0x60, 0xcf, 0x39, 0x71, 0x3b, 0xb8, 0x34, 0x47, - 0xb1, 0x96, 0x64, 0x2c, 0xd1, 0xc6, 0x17, 0x11, 0xc0, 0xa2, 0x15, 0x98, 0xde, 0x1f, 0x9a, 0x76, - 0x1f, 0x97, 0xe6, 0xd7, 0xb5, 0xdb, 0x59, 0x83, 0x97, 0xd0, 0xe7, 0x61, 0xb1, 0xfd, 0xcc, 0x72, - 0xbb, 0x91, 0x53, 0xbb, 0x4c, 0xa7, 0x9c, 0xd4, 0x84, 0x56, 0x21, 0x5f, 0x75, 0xfa, 0x7d, 0xdb, - 0x6f, 0xd4, 0x4a, 0x3a, 0x05, 0x0b, 0xca, 0xe8, 0x7d, 0x58, 0x7b, 0x62, 0xe3, 0x8f, 0x77, 0xf8, - 0xf6, 0x54, 0xba, 0x7d, 0xdb, 0xf3, 0x6c, 0x67, 0xd0, 0x3e, 0x19, 0x0e, 0x1d, 0xd7, 0xc7, 0xdd, - 0xd2, 0xc2, 0xba, 0x76, 0x3b, 0x6f, 0x8c, 0x81, 0x42, 0xdb, 0x70, 0x33, 0x11, 0xe2, 0x21, 0x1e, - 0x60, 0xd7, 0xf2, 0x6d, 0x67, 0x50, 0x42, 0x94, 0x1e, 0xc6, 0x81, 0xa1, 0xfb, 0x70, 0x55, 0x06, - 0xd9, 0x3d, 0x24, 0x3b, 0x85, 0xbb, 0xf5, 0xa1, 0xd3, 0x79, 0x56, 0x5a, 0xa4, 0x7d, 0xa4, 0x03, - 0xa0, 0x07, 0xb0, 0x9a, 0x38, 0x80, 0x81, 0xad, 0xee, 0xcb, 0xd2, 0x12, 0x5d, 0xcb, 0x08, 0x08, - 0x32, 0x7a, 0xad, 0xd6, 0x7c, 0x62, 0x7b, 0xf6, 0xa1, 0xdd, 0xb3, 0xfd, 0x97, 0x5b, 0x96, 0xeb, - 0xda, 0xd8, 0x65, 0xe8, 0xcb, 0x14, 0x3d, 0x1d, 0x00, 0x7d, 0x09, 0x4a, 0x72, 0xdf, 0x8d, 0xc1, - 0x11, 0x39, 0x00, 0x86, 0xbc, 0x42, 0x91, 0x53, 0xdb, 0x51, 0x0d, 0x6e, 0x28, 0x1d, 0xd7, 0xf0, - 0xb0, 0xe7, 0xbc, 0xc4, 0xdd, 0x3d, 0x22, 0x12, 0x3a, 0x4e, 0xaf, 0x74, 0x85, 0x92, 0xc1, 0x68, - 0xa0, 0xd5, 0x16, 0x14, 0x25, 0xce, 0x40, 0x3a, 0x64, 0x8f, 0xf1, 0x4b, 0x2e, 0x3c, 0xc8, 0x4f, - 0xf4, 0x06, 0x4c, 0x3d, 0xb7, 0x7a, 0x27, 0x98, 0x8a, 0x8c, 0xa2, 0xcc, 0x19, 0x14, 0xaf, 0x69, - 0x7b, 0xbe, 0xc1, 0x20, 0xbe, 0x94, 0x79, 0x47, 0x7b, 0x94, 0xcb, 0x4f, 0xe9, 0xd3, 0xe5, 0x5f, - 0x64, 0x61, 0xc6, 0xbc, 0x00, 0x81, 0x24, 0x44, 0x43, 0x36, 0x49, 0x34, 0xe4, 0x26, 0x10, 0x0d, - 0x6f, 0xc1, 0x34, 0xa5, 0x70, 0xaf, 0x34, 0x45, 0x45, 0xc3, 0x15, 0x19, 0xda, 0x6c, 0xd1, 0xb6, - 0xc6, 0xe0, 0xa9, 0x23, 0x44, 0x02, 0x03, 0x46, 0x77, 0x61, 0xa9, 0xe9, 0x1c, 0xf9, 0x96, 0xdd, - 0x23, 0x13, 0xc2, 0xae, 0x98, 0xe5, 0x34, 0x9d, 0x65, 0x62, 0x5b, 0x8a, 0x70, 0x9c, 0x49, 0x15, - 0x8e, 0xaa, 0x7c, 0x28, 0x4c, 0x2c, 0x1f, 0xa2, 0xb2, 0x07, 0x12, 0x64, 0x4f, 0x0a, 0xcf, 0x17, - 0xd3, 0x79, 0xfe, 0x3d, 0xb8, 0x56, 0x39, 0xf1, 0x9d, 0xc6, 0xa0, 0xe3, 0x52, 0xc6, 0x78, 0x1f, - 0x0f, 0x3a, 0x38, 0x64, 0xea, 0x59, 0x4a, 0x8c, 0xa3, 0x40, 0x1e, 0xe5, 0xf2, 0x79, 0xbd, 0x50, - 0xfe, 0x87, 0x0c, 0xe4, 0x9b, 0xce, 0xd1, 0xff, 0x81, 0xa3, 0xbf, 0x4f, 0xe4, 0xe8, 0xb0, 0x67, - 0x77, 0x2c, 0x71, 0xf8, 0xab, 0x32, 0x7c, 0xd3, 0x39, 0xe2, 0xcd, 0xd2, 0xf9, 0x07, 0x18, 0x91, - 0xd3, 0x99, 0x3e, 0x8d, 0xf4, 0x6e, 0x3a, 0x1d, 0x8b, 0xf0, 0x1a, 0x3d, 0xfb, 0x88, 0xf4, 0x16, - 0x6d, 0x62, 0x3c, 0x51, 0x2e, 0x7f, 0x37, 0x0b, 0xb3, 0x64, 0xdf, 0x04, 0x41, 0xa2, 0x12, 0xcc, - 0xb0, 0x02, 0xdb, 0xbe, 0x9c, 0x21, 0x8a, 0x68, 0x4b, 0x5a, 0x58, 0x86, 0x2e, 0xec, 0xb5, 0xc8, - 0xc2, 0x82, 0x5e, 0x36, 0x05, 0x20, 0xe5, 0x6e, 0x69, 0x79, 0x4b, 0x30, 0xc5, 0x04, 0x24, 0xdb, - 0x5e, 0x56, 0x20, 0x82, 0xbf, 0x89, 0xad, 0x2e, 0x76, 0x1b, 0x35, 0xba, 0xc5, 0x39, 0x23, 0x28, - 0xd3, 0xf3, 0xc0, 0x6e, 0xbf, 0x34, 0xc5, 0xcf, 0x03, 0xbb, 0x7d, 0xf4, 0x11, 0x2c, 0xb4, 0x9c, - 0xc1, 0x13, 0xc7, 0xb7, 0x07, 0x47, 0xc1, 0x94, 0xa6, 0xe9, 0x94, 0xee, 0xa4, 0x4e, 0x29, 0x86, - 0xc1, 0xe6, 0x16, 0xef, 0x69, 0xf5, 0xff, 0xc3, 0x9c, 0x02, 0x23, 0x4b, 0xa7, 0x1c, 0x93, 0x4e, - 0x4b, 0xb2, 0x74, 0x2a, 0x48, 0x82, 0x68, 0xb5, 0x06, 0x2b, 0xc9, 0x23, 0x9d, 0xa6, 0x97, 0xf2, - 0xf7, 0x34, 0x98, 0x57, 0x29, 0x05, 0xbd, 0xaf, 0x1e, 0x14, 0xed, 0xa7, 0x78, 0xb7, 0x94, 0xb6, - 0xde, 0xad, 0x3c, 0x39, 0xe9, 0x1f, 0xff, 0xf4, 0xa6, 0x66, 0xa8, 0x07, 0x7c, 0x1d, 0x0a, 0xa2, - 0xdb, 0x1a, 0x1d, 0x38, 0x67, 0x84, 0x15, 0x68, 0x1d, 0x8a, 0x0d, 0x2f, 0x58, 0x00, 0x3d, 0xa6, - 0xbc, 0x21, 0x57, 0x95, 0xff, 0x48, 0x0b, 0x0d, 0x05, 0xaa, 0xb2, 0xf7, 0xf6, 0x4d, 0xc7, 0xb7, - 0x7a, 0x7c, 0x61, 0x41, 0x99, 0x08, 0x8c, 0xea, 0xde, 0x7e, 0xe5, 0xb9, 0x65, 0xf7, 0xac, 0xc3, - 0x1e, 0x5b, 0xa4, 0x66, 0x28, 0x75, 0x04, 0x7f, 0x07, 0xf7, 0x19, 0x3e, 0x23, 0x89, 0xa0, 0x4c, - 0xf0, 0x77, 0x70, 0x3f, 0xc4, 0x67, 0x94, 0xa1, 0xd4, 0x95, 0x7f, 0x00, 0xa0, 0x73, 0x4b, 0x6b, - 0x1b, 0x5b, 0xae, 0x7f, 0x88, 0x2d, 0xff, 0xd7, 0xd0, 0x14, 0xdd, 0x04, 0x64, 0x5a, 0x9e, 0xc0, - 0xad, 0xba, 0xd8, 0x22, 0xc2, 0x6f, 0x86, 0x6e, 0x7e, 0x42, 0x4b, 0x4c, 0x16, 0xe7, 0x13, 0x64, - 0xf1, 0x2d, 0x98, 0x6b, 0x0c, 0x6c, 0x3f, 0x34, 0x31, 0x0b, 0x14, 0x48, 0xad, 0x24, 0x50, 0x0f, - 0x1d, 0xcf, 0xb3, 0x87, 0xaa, 0x58, 0x57, 0x2b, 0xc9, 0x78, 0xac, 0xe2, 0x91, 0x63, 0x0f, 0x70, - 0x97, 0x0a, 0xf4, 0xbc, 0xa1, 0xd4, 0xfd, 0xd2, 0xed, 0xce, 0x14, 0x5d, 0x33, 0x3f, 0x99, 0x7d, - 0x79, 0x39, 0x62, 0x5f, 0x7e, 0x1e, 0x16, 0x2b, 0x9d, 0x63, 0xdc, 0x25, 0x15, 0xd6, 0xa0, 0xbb, - 0x65, 0xf9, 0x9d, 0x67, 0xdc, 0x0c, 0xcd, 0x19, 0x49, 0x4d, 0x44, 0x73, 0xf1, 0x9a, 0x1a, 0xee, - 0xd9, 0xcf, 0xc9, 0xce, 0x77, 0x8e, 0xa3, 0xe6, 0xe8, 0x28, 0x90, 0x09, 0x6c, 0x5a, 0x74, 0x51, - 0x36, 0xed, 0xe2, 0x05, 0xd8, 0xb4, 0x4b, 0xe3, 0x6c, 0xda, 0xc8, 0x7a, 0xaa, 0x96, 0x6f, 0xf5, - 0x9c, 0x23, 0xaa, 0xae, 0x79, 0x17, 0xcb, 0xb4, 0x8b, 0x31, 0x50, 0x68, 0x0b, 0xae, 0xcb, 0x10, - 0x06, 0x7e, 0xea, 0x62, 0xef, 0x59, 0xb8, 0x2b, 0xcc, 0x42, 0x1d, 0x09, 0x13, 0xef, 0xe3, 0xb9, - 0xd5, 0xb3, 0xbb, 0x84, 0x79, 0xd8, 0x4c, 0xae, 0xd0, 0x99, 0x8c, 0x84, 0x19, 0x69, 0x25, 0x97, - 0xc6, 0x58, 0xc9, 0x23, 0xed, 0xf3, 0xab, 0xe3, 0xec, 0xf3, 0xb1, 0x36, 0xf6, 0xea, 0x04, 0x36, - 0x36, 0xb7, 0x89, 0x4d, 0x98, 0xad, 0xb6, 0x2a, 0xbd, 0x9e, 0xd3, 0xb1, 0x7c, 0xdc, 0xa8, 0x25, - 0x98, 0xda, 0x4b, 0x30, 0x45, 0x89, 0x9a, 0x6b, 0x03, 0x56, 0x60, 0x7a, 0xe2, 0x1b, 0x27, 0xd8, - 0x23, 0xec, 0xc2, 0x04, 0x61, 0x58, 0x51, 0xfe, 0xaf, 0x2c, 0x2c, 0x08, 0x7b, 0x6b, 0xb4, 0xe4, - 0x5d, 0x87, 0xa2, 0x61, 0x3d, 0xf5, 0x55, 0xb1, 0x2b, 0x57, 0x25, 0xc8, 0xe6, 0x6c, 0xa2, 0x6c, - 0x8e, 0xc9, 0xaa, 0x5c, 0x92, 0xac, 0x3a, 0x9f, 0xfd, 0x95, 0x2c, 0x89, 0xa7, 0x53, 0x25, 0xb1, - 0x2a, 0xf5, 0x66, 0xce, 0x64, 0xaf, 0xe5, 0x27, 0xb7, 0xd7, 0x08, 0x4d, 0x46, 0x44, 0x4a, 0xc8, - 0x17, 0x05, 0x46, 0x93, 0x69, 0xed, 0x13, 0xc8, 0x1b, 0x98, 0x44, 0xde, 0x94, 0xeb, 0x50, 0x94, - 0xae, 0x30, 0x23, 0x2c, 0xc6, 0x91, 0xa6, 0x46, 0xf9, 0x9b, 0x53, 0xa0, 0x9b, 0x17, 0xa9, 0xbb, - 0xc3, 0x4b, 0x57, 0xf6, 0x34, 0x97, 0xae, 0xe4, 0x23, 0xcf, 0xa5, 0x1e, 0x79, 0xda, 0x25, 0x6d, - 0xea, 0xd4, 0x97, 0xb4, 0xe9, 0x09, 0x2f, 0x69, 0xf9, 0x33, 0x5f, 0xd2, 0x0a, 0x93, 0x5f, 0xd2, - 0x20, 0x5d, 0x71, 0x12, 0x16, 0xc6, 0xc3, 0x9e, 0xf5, 0x12, 0x77, 0x9b, 0xde, 0x80, 0x6a, 0xff, - 0x9c, 0x21, 0x57, 0x9d, 0xff, 0x1a, 0x97, 0xa6, 0x80, 0xe7, 0xce, 0xac, 0x80, 0xe7, 0xc7, 0x2a, - 0xe0, 0x47, 0xb9, 0xfc, 0x8c, 0x9e, 0x2f, 0xff, 0x70, 0x0a, 0xf2, 0x46, 0x7b, 0x87, 0xd9, 0x43, - 0x3a, 0x64, 0x4d, 0xcf, 0x11, 0x46, 0xba, 0xe9, 0x39, 0x44, 0x3a, 0x36, 0x06, 0x5d, 0xfc, 0x42, - 0x48, 0x47, 0x5a, 0x20, 0xb2, 0xa8, 0x89, 0x2d, 0x0f, 0x6f, 0x3b, 0x3d, 0x76, 0x6f, 0x61, 0xd6, - 0xab, 0x5a, 0x49, 0x8e, 0xc3, 0x74, 0x4f, 0x06, 0x44, 0xf2, 0xd2, 0x9d, 0xe3, 0x26, 0xac, 0x5c, - 0x87, 0x1e, 0xc1, 0x2c, 0x43, 0xb2, 0x3d, 0xdf, 0x71, 0x5f, 0x72, 0x99, 0xa5, 0x5c, 0xad, 0xc4, - 0xec, 0x36, 0x65, 0x40, 0x76, 0x7d, 0x51, 0x70, 0xd9, 0x41, 0x7d, 0xe3, 0xc4, 0x76, 0xd9, 0x70, - 0xd3, 0xe2, 0xa0, 0x82, 0x2a, 0xf4, 0x26, 0x2c, 0x7c, 0x58, 0x69, 0x1a, 0xb8, 0xe3, 0x90, 0xdd, - 0xa8, 0xd9, 0x47, 0xd8, 0xf3, 0xb9, 0xb3, 0x20, 0xde, 0x80, 0xbe, 0x00, 0xcb, 0x52, 0x25, 0x1d, - 0xb1, 0xea, 0x9c, 0x0c, 0x7c, 0x4a, 0x91, 0x39, 0x23, 0xb9, 0x91, 0x1c, 0x8c, 0xd4, 0x50, 0x75, - 0xfa, 0xc3, 0x1e, 0x26, 0x4a, 0x75, 0xe0, 0xbb, 0x36, 0x66, 0x34, 0x99, 0x33, 0x46, 0x81, 0x10, - 0x76, 0x91, 0x9a, 0xb7, 0x2c, 0x0f, 0x93, 0xe5, 0x00, 0x45, 0x4c, 0x68, 0x89, 0xc0, 0x37, 0x2d, - 0xcf, 0x0f, 0xe9, 0x34, 0xa1, 0x05, 0x3d, 0x82, 0x75, 0xa9, 0x76, 0xd7, 0xb5, 0x8f, 0xec, 0x81, - 0xd5, 0x53, 0x0f, 0x74, 0x96, 0x62, 0x8f, 0x85, 0x23, 0x84, 0x9b, 0xb0, 0x14, 0x4a, 0xb8, 0x79, - 0x23, 0xa9, 0x69, 0xf5, 0x5d, 0x58, 0x88, 0x1d, 0xe4, 0xb8, 0xdb, 0x61, 0x4e, 0xbe, 0x1d, 0x7e, - 0x04, 0x05, 0xaa, 0xc6, 0x3a, 0x8e, 0xdb, 0x25, 0x88, 0x64, 0xb1, 0x1c, 0x91, 0xac, 0x6e, 0x03, - 0x72, 0xe6, 0xcb, 0x21, 0xc3, 0x9b, 0x57, 0xc5, 0x06, 0xc3, 0x21, 0xad, 0x06, 0x85, 0x21, 0xf2, - 0x96, 0x8a, 0x18, 0x42, 0xbe, 0xb3, 0x06, 0xfd, 0x5d, 0xfe, 0x59, 0x06, 0x80, 0xf6, 0x4f, 0x95, - 0x3d, 0x01, 0x69, 0x59, 0x7d, 0x2c, 0x44, 0x32, 0xf9, 0x2d, 0xcb, 0xfc, 0x8c, 0x2a, 0xf3, 0xf9, - 0x74, 0xb2, 0xe1, 0x74, 0x4a, 0x30, 0xb3, 0x63, 0xbd, 0x68, 0xdb, 0xbf, 0x23, 0xae, 0x70, 0xa2, - 0x48, 0xf4, 0x83, 0x10, 0xcb, 0x35, 0x7e, 0xc1, 0x0f, 0x2b, 0xe8, 0xcd, 0xbf, 0xd5, 0xa8, 0x71, - 0x2a, 0xa6, 0xbf, 0xd1, 0x17, 0x20, 0x63, 0xb6, 0xb9, 0x9a, 0x5d, 0xdd, 0x64, 0xf1, 0x8a, 0x4d, - 0x11, 0xaf, 0xd8, 0x34, 0x45, 0xbc, 0x82, 0x5d, 0x7e, 0xff, 0xf8, 0x5f, 0x6f, 0x6a, 0x46, 0xc6, - 0x6c, 0x13, 0xc5, 0xd7, 0x18, 0x74, 0x7a, 0x27, 0x5d, 0x5c, 0x7f, 0x31, 0x24, 0x9c, 0xc0, 0x95, - 0x10, 0x97, 0x6f, 0x98, 0x5d, 0xa0, 0xf2, 0xc6, 0x18, 0x28, 0x62, 0x68, 0xd7, 0x5f, 0x50, 0x88, - 0x6d, 0xcb, 0xed, 0xd6, 0x9c, 0x8f, 0x07, 0xb1, 0x8e, 0x98, 0x0e, 0x1e, 0x07, 0x56, 0x2e, 0x03, - 0x98, 0x9e, 0x23, 0x76, 0x78, 0x09, 0xa6, 0x18, 0x5b, 0xb1, 0x43, 0x64, 0x85, 0xf2, 0xcf, 0x35, - 0x62, 0xb9, 0x51, 0xfd, 0x48, 0x5d, 0x9e, 0x89, 0xba, 0xf1, 0x1e, 0x14, 0x76, 0x87, 0xc2, 0xca, - 0xcf, 0xc4, 0xdd, 0x53, 0xd5, 0x16, 0xc5, 0xdd, 0x1d, 0x1a, 0x21, 0x1c, 0xda, 0x0a, 0x02, 0x17, - 0x4c, 0x51, 0xde, 0x4a, 0x08, 0x5c, 0x50, 0x80, 0xf4, 0xe8, 0xc5, 0x45, 0x3b, 0x70, 0xcb, 0x4d, - 0x28, 0x56, 0x5b, 0xe1, 0xbd, 0x34, 0x69, 0xad, 0x6f, 0x08, 0x37, 0x5c, 0x26, 0x3d, 0x58, 0xc2, - 0x20, 0xca, 0x9f, 0xf0, 0xbd, 0xb3, 0xfc, 0x11, 0x7b, 0x37, 0x79, 0x7f, 0xe3, 0x77, 0x4c, 0x0c, - 0xf4, 0x4b, 0xdc, 0xb1, 0xef, 0xe4, 0x61, 0x46, 0x50, 0x90, 0x62, 0xac, 0x6b, 0xc2, 0xd2, 0xe2, - 0x15, 0x68, 0x13, 0xa6, 0x77, 0xb0, 0xff, 0xcc, 0xe9, 0x26, 0x89, 0x04, 0xd6, 0x42, 0x45, 0x02, - 0x87, 0x42, 0xf7, 0x65, 0xfe, 0xa7, 0xac, 0x1c, 0xb1, 0x3e, 0xc2, 0x56, 0xbe, 0x46, 0x59, 0x5e, - 0x54, 0xa8, 0xa3, 0x2a, 0x30, 0xe9, 0x28, 0xd3, 0x17, 0xef, 0xde, 0x88, 0x3a, 0xaa, 0x14, 0xbb, - 0xcf, 0x50, 0x50, 0xd0, 0x03, 0x42, 0x0c, 0x61, 0x0f, 0x53, 0xb4, 0x87, 0xeb, 0x09, 0x54, 0x1a, - 0x76, 0x20, 0x23, 0x10, 0x7c, 0x53, 0xc2, 0x9f, 0x8e, 0xe3, 0x9b, 0x31, 0x7c, 0x09, 0x81, 0x98, - 0x5f, 0x21, 0x7b, 0x26, 0x59, 0xf5, 0x61, 0xab, 0x21, 0x33, 0xf2, 0x7d, 0xf5, 0xae, 0xc5, 0x0d, - 0xb7, 0x92, 0x3a, 0xf1, 0xb0, 0xdd, 0x50, 0x6f, 0x66, 0xf7, 0x55, 0x7e, 0xe7, 0xbe, 0xf9, 0x52, - 0x1a, 0x73, 0x1a, 0xaa, 0x74, 0xf8, 0xa2, 0xc2, 0x40, 0x54, 0x59, 0x46, 0x4c, 0x60, 0xa9, 0xd9, - 0x50, 0x98, 0xed, 0xbe, 0xca, 0x2c, 0x54, 0x71, 0x26, 0x0c, 0x2c, 0xda, 0x0d, 0x95, 0xb5, 0xde, - 0x85, 0xb9, 0x1a, 0x26, 0x8a, 0x8d, 0x4f, 0x87, 0xfb, 0x7e, 0xae, 0xca, 0xe8, 0x0a, 0x80, 0xa1, - 0xc2, 0xa3, 0x2d, 0x98, 0xdf, 0x73, 0x9d, 0x17, 0x2f, 0xc3, 0x03, 0x9b, 0xe3, 0x02, 0x5e, 0xea, - 0x41, 0x85, 0x30, 0x22, 0x18, 0x44, 0x0b, 0x47, 0xdd, 0xae, 0xad, 0x93, 0x3e, 0x35, 0x02, 0x73, - 0x46, 0x52, 0x13, 0xda, 0x92, 0x9c, 0xc8, 0xc1, 0x55, 0xec, 0x72, 0xfa, 0x55, 0xcc, 0x88, 0x83, - 0xd3, 0x3d, 0x7f, 0x86, 0x3b, 0xc7, 0xdb, 0xd8, 0xea, 0xf9, 0xcf, 0xa8, 0xb7, 0x28, 0xba, 0xe7, - 0x61, 0xb3, 0x21, 0xc3, 0x22, 0x13, 0x96, 0xda, 0x9d, 0x67, 0xb8, 0x7b, 0xd2, 0xc3, 0xdc, 0x44, - 0xa5, 0x46, 0x3a, 0xf5, 0x1b, 0x15, 0xef, 0xae, 0xcb, 0x7d, 0x24, 0xc1, 0x19, 0x89, 0xd8, 0x65, - 0x07, 0x8a, 0x94, 0x13, 0xbd, 0xa1, 0x33, 0xf0, 0xf0, 0x88, 0xab, 0x19, 0x57, 0xd3, 0x19, 0x45, - 0x4d, 0x0b, 0xc3, 0x89, 0x29, 0x6f, 0x51, 0x1c, 0xe5, 0x9e, 0x2f, 0x6f, 0x02, 0x92, 0xe8, 0x59, - 0x1a, 0xf7, 0x7d, 0xdb, 0x95, 0x84, 0x91, 0x28, 0x96, 0xff, 0x33, 0x47, 0xdd, 0x7d, 0x0c, 0xec, - 0x62, 0xa5, 0xd6, 0x75, 0x28, 0xd4, 0x5d, 0xd7, 0x71, 0xab, 0x4e, 0x17, 0xd3, 0x25, 0xcc, 0x19, - 0x61, 0x05, 0x31, 0xc5, 0x69, 0x61, 0x07, 0x7b, 0x9e, 0x75, 0x84, 0xb9, 0xef, 0x40, 0xa9, 0x43, - 0x6b, 0x00, 0x0d, 0x6f, 0xbb, 0xf2, 0x18, 0xe3, 0x21, 0x76, 0xa9, 0xd4, 0xc9, 0x1b, 0x52, 0x0d, - 0x7a, 0x57, 0xd9, 0x5d, 0x2e, 0x56, 0xae, 0xc4, 0x04, 0x23, 0x6b, 0xe6, 0x92, 0x51, 0x39, 0x0f, - 0xc2, 0x68, 0xd2, 0x25, 0x86, 0x4b, 0x16, 0x95, 0xd1, 0xa4, 0x76, 0x43, 0x81, 0x26, 0xd4, 0x46, - 0x65, 0x0d, 0x1f, 0x3e, 0x1f, 0x1f, 0x5e, 0x6a, 0x36, 0x64, 0x58, 0xc2, 0x62, 0xd5, 0xde, 0x89, - 0xe7, 0x63, 0xb7, 0x86, 0xc9, 0xed, 0xd4, 0xe3, 0xc2, 0x45, 0x61, 0x31, 0x15, 0xc2, 0x88, 0x60, - 0xa0, 0x07, 0x50, 0x08, 0xa3, 0x0f, 0x90, 0x40, 0xa6, 0xa2, 0x91, 0x11, 0x28, 0xf6, 0x4e, 0x7a, - 0xbe, 0x11, 0xa2, 0xa0, 0x07, 0x00, 0x92, 0x68, 0x64, 0x32, 0x66, 0x4d, 0xee, 0x20, 0x4e, 0x48, - 0x06, 0x44, 0xc4, 0x23, 0x61, 0x20, 0xec, 0x32, 0x09, 0x37, 0x9b, 0xb0, 0x79, 0x52, 0xbb, 0xa1, - 0x40, 0x97, 0x1f, 0x51, 0x7f, 0x15, 0xb3, 0x7f, 0x83, 0x6d, 0x79, 0x8b, 0x68, 0x50, 0x52, 0xe3, - 0x95, 0x34, 0xaa, 0xd7, 0x97, 0x63, 0x87, 0x49, 0x5a, 0xf9, 0x51, 0x0a, 0xd8, 0xf2, 0xab, 0xca, - 0x41, 0x10, 0xf3, 0xed, 0x09, 0xd5, 0xdb, 0xdc, 0x7c, 0xa3, 0x85, 0xf2, 0x43, 0x98, 0x33, 0x2d, - 0xef, 0xd8, 0xb4, 0x0e, 0x7b, 0x78, 0xdf, 0xc3, 0x2e, 0x61, 0x23, 0xf2, 0x77, 0x10, 0xda, 0xd2, - 0x41, 0x99, 0xb4, 0xed, 0x59, 0x9e, 0xf7, 0xb1, 0xe3, 0x76, 0xb9, 0x73, 0x23, 0x28, 0x97, 0xbf, - 0xa5, 0x91, 0x59, 0x52, 0xb9, 0x95, 0x68, 0xc6, 0xa4, 0xdb, 0xe2, 0x8a, 0xff, 0x25, 0x1b, 0x0d, - 0xf5, 0x04, 0xb1, 0xb8, 0x9c, 0x1c, 0x8b, 0x5b, 0xa3, 0xba, 0x5f, 0x35, 0xca, 0xa5, 0x9a, 0xf2, - 0x9f, 0x67, 0x08, 0x0d, 0x0f, 0x9e, 0xda, 0x47, 0xd5, 0x67, 0xd6, 0xe0, 0x08, 0xa3, 0x7b, 0xc1, - 0xec, 0x78, 0x48, 0x6a, 0x51, 0xbd, 0x70, 0xd0, 0xa6, 0x70, 0x07, 0xd9, 0x3a, 0xee, 0x03, 0x30, - 0x74, 0xe9, 0xa2, 0x72, 0x3d, 0xee, 0xdf, 0x08, 0x61, 0x0c, 0x09, 0x1e, 0x99, 0x30, 0xdf, 0x18, - 0xd8, 0xbe, 0x6d, 0xf5, 0x76, 0x70, 0xff, 0x10, 0xbb, 0xc2, 0x2a, 0x7b, 0x33, 0xad, 0x87, 0x4d, - 0x15, 0x9c, 0x5d, 0x9d, 0x23, 0x7d, 0xac, 0x56, 0x60, 0x31, 0x01, 0xec, 0x54, 0x61, 0xbb, 0x37, - 0x60, 0xae, 0xfd, 0xec, 0xc4, 0xef, 0x3a, 0x1f, 0x0f, 0x98, 0x6a, 0x23, 0x67, 0x43, 0x7e, 0x04, - 0x47, 0x26, 0x8a, 0xe5, 0xbf, 0x9b, 0x82, 0xcb, 0x11, 0x11, 0x9e, 0x78, 0xba, 0xb7, 0x60, 0x6e, - 0xcb, 0x71, 0x7c, 0xcf, 0x77, 0xad, 0xe1, 0xd0, 0x1e, 0x1c, 0xd1, 0x41, 0xf3, 0x86, 0x5a, 0x49, - 0x44, 0x03, 0xf7, 0xd9, 0xd0, 0x0d, 0xcd, 0xd2, 0x0d, 0x55, 0x44, 0x83, 0xd4, 0x6c, 0xc8, 0xb0, - 0x4c, 0x26, 0x85, 0x5b, 0xc5, 0xcd, 0xb5, 0x52, 0xda, 0x56, 0x1a, 0xea, 0xe9, 0xbf, 0x1b, 0x59, - 0x31, 0xb7, 0xd5, 0xae, 0xaa, 0x82, 0x41, 0x02, 0x30, 0x22, 0x3b, 0xf4, 0x18, 0x16, 0x98, 0x63, - 0x4d, 0xf2, 0xb4, 0x71, 0xc9, 0xaa, 0x98, 0x8c, 0x31, 0x20, 0x23, 0x8e, 0x17, 0x37, 0x45, 0x66, - 0x4e, 0x69, 0x8a, 0x3c, 0x86, 0x85, 0x47, 0x8e, 0x3d, 0x60, 0x1e, 0x65, 0x2e, 0xff, 0xb8, 0xa0, - 0x55, 0x66, 0x13, 0x03, 0x32, 0xe2, 0x78, 0x68, 0x1b, 0x74, 0xd6, 0x3b, 0xb5, 0x55, 0xd8, 0x84, - 0x0a, 0x71, 0x53, 0x34, 0x0a, 0x63, 0xc4, 0xb0, 0xc8, 0xf1, 0x56, 0xba, 0x5d, 0xc1, 0x85, 0x49, - 0xb6, 0x9d, 0xd4, 0x6c, 0xc8, 0xb0, 0x44, 0xf2, 0x07, 0xa4, 0xc2, 0xb0, 0x8b, 0x71, 0xc9, 0xaf, - 0x42, 0x18, 0x11, 0x8c, 0x32, 0x4e, 0xb6, 0x55, 0x12, 0xe9, 0x35, 0x42, 0x89, 0x99, 0xc9, 0x29, - 0xb1, 0xfc, 0x27, 0x19, 0x58, 0x89, 0xb8, 0xeb, 0x4c, 0xcb, 0x3d, 0xc2, 0x3e, 0x0d, 0x40, 0xf2, - 0x23, 0x22, 0x83, 0x30, 0x69, 0x5d, 0x30, 0x94, 0x3a, 0xea, 0x6c, 0x93, 0x61, 0x32, 0x0c, 0x46, - 0xae, 0x23, 0x72, 0xb6, 0xfe, 0x82, 0x88, 0x20, 0xdb, 0xe7, 0xb1, 0xed, 0xa0, 0x4c, 0x4c, 0x48, - 0xde, 0x9f, 0x69, 0xf7, 0xb1, 0x73, 0xe2, 0x9b, 0x76, 0xe7, 0xd8, 0xe3, 0xd2, 0x31, 0xa9, 0x89, - 0x60, 0x98, 0x09, 0x18, 0x4c, 0x68, 0x26, 0x35, 0xa1, 0x2f, 0xc0, 0x72, 0x9d, 0x88, 0x0b, 0xcb, - 0xc7, 0xd5, 0x13, 0xd7, 0xc5, 0x03, 0x9f, 0xc2, 0x78, 0x3c, 0xc2, 0x90, 0xdc, 0x58, 0xbe, 0x93, - 0x40, 0x95, 0x6c, 0x29, 0xb6, 0x47, 0xc3, 0xf4, 0x6c, 0x3b, 0x82, 0x72, 0xb9, 0x97, 0xc0, 0x54, - 0xe8, 0x1e, 0xe4, 0x88, 0xbe, 0xe1, 0x52, 0x5a, 0xe1, 0x09, 0x45, 0x51, 0x71, 0x59, 0x4d, 0x81, - 0xe9, 0xa6, 0x5a, 0xde, 0x71, 0xcd, 0xf2, 0xad, 0x43, 0xcb, 0x13, 0x22, 0x4f, 0xa9, 0x23, 0x52, - 0x4f, 0xe5, 0xa2, 0x74, 0xa9, 0xf7, 0x66, 0x9c, 0x25, 0x46, 0x40, 0xbf, 0xae, 0x90, 0x7d, 0xba, - 0x35, 0x5b, 0xfe, 0x85, 0x16, 0xa5, 0xf2, 0xb3, 0x46, 0x25, 0xd0, 0x93, 0x14, 0xdd, 0xb2, 0x99, - 0xce, 0x2f, 0x93, 0x68, 0x17, 0xc2, 0x2b, 0xe4, 0x0c, 0x79, 0x5c, 0x81, 0xfe, 0xbe, 0x08, 0x8d, - 0xf3, 0x67, 0x19, 0xd5, 0xa4, 0x0c, 0xf2, 0x65, 0x34, 0x29, 0x5f, 0xe6, 0xcb, 0x2c, 0xf0, 0x6d, - 0x0d, 0xba, 0x22, 0x73, 0xe7, 0xda, 0x88, 0xfb, 0x85, 0x88, 0x39, 0x09, 0x14, 0xb2, 0x95, 0xc2, - 0x1d, 0xcf, 0x6f, 0x06, 0xc2, 0x05, 0x5f, 0x05, 0xe0, 0x50, 0x84, 0xe1, 0x72, 0xb4, 0xeb, 0x1b, - 0x23, 0xba, 0x6e, 0xd4, 0x84, 0xbf, 0x20, 0x44, 0x43, 0x1f, 0xc2, 0x72, 0x62, 0xc0, 0x89, 0xab, - 0x92, 0x57, 0xe4, 0xfe, 0x92, 0x33, 0x22, 0x93, 0xf1, 0xcb, 0x7f, 0x91, 0x49, 0xe9, 0x99, 0x90, - 0xc0, 0x9e, 0x8b, 0x87, 0x96, 0xcb, 0x98, 0x87, 0x9c, 0x48, 0x58, 0x41, 0xd6, 0x5b, 0x1f, 0x10, - 0x6e, 0xe8, 0x72, 0x65, 0x2b, 0x8a, 0x29, 0xe9, 0x4b, 0x77, 0x61, 0x29, 0x88, 0x1d, 0xd3, 0x04, - 0x4d, 0xe6, 0x6e, 0xe7, 0x47, 0x9d, 0xd8, 0x86, 0x36, 0x01, 0x25, 0xc4, 0xc7, 0x99, 0xe4, 0x48, - 0x68, 0x21, 0x66, 0x99, 0x14, 0xce, 0x67, 0x2e, 0x51, 0xa9, 0x86, 0xcc, 0x8c, 0xc5, 0x96, 0x59, - 0xd2, 0x08, 0x2b, 0x10, 0x19, 0x41, 0x16, 0xed, 0xfb, 0xb8, 0xcb, 0x5d, 0x9c, 0x41, 0xb9, 0xfc, - 0xcf, 0x9a, 0x1a, 0x22, 0x0f, 0x76, 0x47, 0xc8, 0x5c, 0x59, 0x56, 0x6a, 0x93, 0xc9, 0xca, 0x4c, - 0xba, 0xac, 0x7c, 0x1b, 0x56, 0x42, 0x9e, 0x57, 0x90, 0xd8, 0x5e, 0xa6, 0xb4, 0xa6, 0x4b, 0xcc, - 0xdc, 0x28, 0x89, 0xf9, 0x49, 0x11, 0x8a, 0x7c, 0x16, 0xf4, 0xee, 0x21, 0xb2, 0xfa, 0x34, 0x29, - 0xab, 0xef, 0x37, 0x2b, 0x25, 0xa8, 0x12, 0x78, 0x28, 0xf3, 0x94, 0x0d, 0x5f, 0x4d, 0x70, 0x1b, - 0xd1, 0x3c, 0xb8, 0x09, 0x13, 0xd2, 0x0b, 0x67, 0x4a, 0x48, 0x87, 0xe4, 0x44, 0x24, 0x35, 0x6c, - 0x5f, 0x9c, 0x24, 0xc5, 0x68, 0x76, 0x6c, 0x8a, 0xd1, 0xdc, 0x99, 0x52, 0x8c, 0xe6, 0xcf, 0x94, - 0xda, 0x7e, 0x79, 0x92, 0xd4, 0x76, 0x7d, 0xb2, 0xd4, 0xa3, 0x85, 0x48, 0xea, 0xd1, 0x98, 0x38, - 0x26, 0xba, 0x88, 0x44, 0xa2, 0xc5, 0x8b, 0x4a, 0x24, 0x5a, 0xba, 0x80, 0x44, 0xa2, 0xe5, 0xf3, - 0x27, 0x12, 0xad, 0x5c, 0x48, 0x22, 0xd1, 0x95, 0x0b, 0x48, 0x24, 0x2a, 0x4d, 0x90, 0x48, 0x34, - 0x3a, 0xd9, 0xff, 0xea, 0xd8, 0x64, 0xff, 0x51, 0x89, 0x48, 0xab, 0xe7, 0x49, 0x44, 0xba, 0x76, - 0xee, 0x44, 0xa4, 0xeb, 0xbf, 0xba, 0x64, 0xff, 0x4f, 0x35, 0xf6, 0xfa, 0x88, 0x3f, 0xc5, 0xe1, - 0x6a, 0x41, 0x4b, 0x7e, 0x8a, 0x63, 0xf9, 0x78, 0x93, 0x41, 0x28, 0x92, 0x8f, 0x55, 0x8d, 0x5f, - 0x66, 0x66, 0x92, 0x65, 0x1a, 0x50, 0x94, 0x86, 0x48, 0x58, 0xe6, 0xe7, 0xd4, 0x65, 0x5e, 0x49, - 0x11, 0xd1, 0xb2, 0x7d, 0xf7, 0x4f, 0x39, 0x9a, 0x6c, 0x73, 0x21, 0x8a, 0xec, 0xb7, 0xf9, 0x31, - 0xbf, 0xc6, 0xf9, 0x31, 0x63, 0xb4, 0xc4, 0xdc, 0xa4, 0xd9, 0x2e, 0x7f, 0xa9, 0xb1, 0x27, 0x32, - 0x63, 0xb9, 0xc6, 0x1c, 0xc7, 0x35, 0xe7, 0xa3, 0x77, 0x33, 0x99, 0xde, 0xff, 0x36, 0x0b, 0x20, - 0xdd, 0x0d, 0x93, 0x3c, 0x0c, 0x82, 0x05, 0x32, 0x12, 0x0b, 0xdc, 0x82, 0x39, 0x22, 0x24, 0xf0, - 0x40, 0x35, 0xd3, 0xd4, 0xca, 0x08, 0xd5, 0xe4, 0x26, 0xa6, 0x9a, 0xf1, 0xfa, 0x75, 0xea, 0xa2, - 0xf4, 0xeb, 0xf4, 0x05, 0xe8, 0xd7, 0x99, 0xf3, 0x3d, 0x3e, 0xcb, 0x8f, 0xd3, 0x47, 0xe5, 0xbf, - 0xd1, 0x82, 0x43, 0x22, 0x64, 0xf4, 0x5e, 0x84, 0x8c, 0xca, 0xb1, 0xb8, 0xdd, 0x38, 0x4a, 0xfa, - 0x60, 0x1c, 0x25, 0xbd, 0xa9, 0x52, 0xd2, 0x4a, 0xc2, 0x08, 0x8e, 0x8b, 0x65, 0x42, 0xfa, 0x49, - 0x26, 0x1a, 0x55, 0x4c, 0x73, 0xaf, 0xaa, 0x84, 0x93, 0x19, 0x4f, 0x38, 0xd9, 0x0b, 0x24, 0x9c, - 0xdc, 0x45, 0x11, 0xce, 0xd4, 0x05, 0x10, 0xce, 0xf4, 0x18, 0xc2, 0x29, 0xff, 0x4b, 0x36, 0x1a, - 0x47, 0x42, 0x6f, 0x41, 0x9e, 0xb3, 0xb2, 0x38, 0xfe, 0xc5, 0x04, 0x36, 0x17, 0xa6, 0xb5, 0x00, - 0x25, 0x68, 0x55, 0x81, 0x96, 0x89, 0xa3, 0x55, 0x55, 0x34, 0x01, 0x8a, 0xde, 0xa1, 0x99, 0x4f, - 0x1c, 0x8f, 0x69, 0xb1, 0xa5, 0xa4, 0xc4, 0x02, 0x8e, 0x18, 0x02, 0xa3, 0x07, 0x50, 0x0c, 0x09, - 0x45, 0xf8, 0x2a, 0x52, 0xe8, 0x48, 0x84, 0xee, 0x24, 0x04, 0x54, 0x13, 0x4e, 0xae, 0x2e, 0xef, - 0x81, 0xe5, 0xe9, 0x95, 0xe2, 0x9e, 0xdc, 0xae, 0xdc, 0x87, 0x8a, 0x94, 0xee, 0xeb, 0x98, 0x3e, - 0x9f, 0xaf, 0x63, 0xbc, 0x05, 0x33, 0x33, 0x81, 0x05, 0x53, 0xfe, 0x03, 0x0d, 0x8a, 0xfc, 0x7c, - 0xa9, 0xb5, 0xf1, 0x45, 0x7a, 0xb8, 0xcc, 0x66, 0xd0, 0xb8, 0xcd, 0x10, 0x98, 0x66, 0xbc, 0x45, - 0x09, 0x91, 0x05, 0xe0, 0xe8, 0x3e, 0x3b, 0x29, 0x86, 0x9b, 0xe1, 0x7b, 0x15, 0x9a, 0x75, 0xc2, - 0x57, 0x2d, 0x23, 0x87, 0x08, 0xe5, 0xef, 0xe7, 0x60, 0x99, 0xbb, 0xc6, 0x84, 0x83, 0x9d, 0xa7, - 0x58, 0xbc, 0x06, 0xf3, 0xad, 0x93, 0xfe, 0xee, 0xd3, 0xb0, 0x73, 0x66, 0x0a, 0x45, 0x6a, 0x09, - 0x63, 0xd3, 0x9a, 0x60, 0xfe, 0x4c, 0x5d, 0xa8, 0x95, 0x68, 0x03, 0x74, 0x81, 0x17, 0x24, 0x8d, - 0x33, 0x7f, 0x44, 0xac, 0x9e, 0xdc, 0x06, 0x5b, 0xf8, 0x85, 0x1f, 0x04, 0xc1, 0x79, 0x09, 0x99, - 0x50, 0x64, 0xbf, 0xb6, 0x5e, 0x3e, 0xc6, 0x22, 0x7f, 0xf3, 0xae, 0x7c, 0x92, 0x89, 0x2b, 0xd9, - 0x94, 0x90, 0x98, 0xcb, 0x50, 0xee, 0x06, 0x3d, 0x4d, 0x4a, 0x4f, 0x60, 0x6f, 0xdc, 0xde, 0x99, - 0xa0, 0xef, 0x28, 0x6a, 0xf4, 0xb1, 0x5b, 0x90, 0xc2, 0x40, 0x2d, 0xaf, 0x23, 0x11, 0x53, 0xe1, - 0xa9, 0x8a, 0xc2, 0xcf, 0x10, 0x6f, 0x59, 0x7d, 0x00, 0x7a, 0x74, 0xe2, 0xc9, 0x4f, 0x0a, 0x92, - 0x73, 0x17, 0x95, 0xf7, 0x71, 0xca, 0xe4, 0xc6, 0xf5, 0xa2, 0xb8, 0x3d, 0xff, 0x5b, 0x83, 0xab, - 0x06, 0xf6, 0x98, 0x9f, 0xf8, 0x43, 0xcb, 0xc7, 0x6e, 0xdf, 0x72, 0x8f, 0x05, 0x8d, 0x84, 0x27, - 0xa5, 0x29, 0x27, 0xf5, 0x15, 0xf5, 0xa4, 0x18, 0x55, 0xbe, 0x1d, 0x71, 0x05, 0x24, 0xf7, 0x39, - 0xe6, 0xb4, 0x92, 0x77, 0x31, 0xfb, 0xbf, 0xb5, 0x8b, 0xe5, 0xff, 0xe0, 0xcf, 0x36, 0x47, 0xde, - 0x0b, 0x7e, 0xfb, 0xf2, 0xe2, 0x37, 0xed, 0xe5, 0xc5, 0xdf, 0x8b, 0x57, 0xce, 0xc4, 0xec, 0x7a, - 0x10, 0x5c, 0xe7, 0x98, 0x68, 0x5e, 0x8f, 0x29, 0x42, 0x6a, 0x74, 0x51, 0x10, 0xd5, 0xe8, 0x62, - 0xb2, 0xef, 0x41, 0x60, 0xb6, 0x65, 0x46, 0xe1, 0xa7, 0x1a, 0x6d, 0x6d, 0x28, 0x4a, 0x9d, 0x27, - 0x44, 0x2d, 0x36, 0x55, 0xa3, 0x2d, 0xf5, 0xa9, 0xaa, 0x2c, 0x1e, 0xda, 0xe3, 0x2c, 0xc1, 0x71, - 0x9d, 0x26, 0x5d, 0x2a, 0xfe, 0x3d, 0xaf, 0xa6, 0x8e, 0x24, 0x72, 0xcb, 0xbb, 0x8a, 0xea, 0x4b, - 0xbc, 0xa2, 0x87, 0xcd, 0xc2, 0x42, 0x90, 0x95, 0xe5, 0xbd, 0xe0, 0x62, 0xc5, 0x2d, 0xc4, 0xc5, - 0x84, 0xeb, 0x94, 0x48, 0x84, 0x10, 0x57, 0xb0, 0xb7, 0xc3, 0x03, 0xe5, 0x17, 0x92, 0xa5, 0xa4, - 0x63, 0x08, 0xa9, 0x91, 0x1f, 0xfe, 0xbd, 0xc0, 0xf7, 0xc1, 0xc3, 0x24, 0x8b, 0x09, 0x1e, 0x0f, - 0x31, 0x98, 0xf0, 0x92, 0xdc, 0x11, 0x09, 0xaf, 0xcc, 0xf5, 0xac, 0x84, 0x00, 0x45, 0x92, 0x93, - 0x92, 0xf6, 0xda, 0xe2, 0x3c, 0xc9, 0xa3, 0x38, 0x3c, 0xf1, 0x66, 0x86, 0x62, 0xaf, 0x45, 0x03, - 0x88, 0x2a, 0x94, 0x91, 0x80, 0x89, 0xea, 0x91, 0x9c, 0x18, 0xce, 0x80, 0x63, 0x63, 0x91, 0x91, - 0x4c, 0x1a, 0x21, 0xdf, 0xbb, 0xfc, 0x2d, 0x01, 0x2f, 0xa1, 0xc7, 0xaa, 0x7c, 0x07, 0x4a, 0xd6, - 0x6f, 0xa4, 0x25, 0x08, 0x8d, 0x11, 0xe9, 0xf7, 0xe5, 0x3b, 0x0e, 0x0f, 0x9a, 0xaf, 0x24, 0xdf, - 0x6c, 0x44, 0x50, 0x4b, 0xba, 0x13, 0xc9, 0x2e, 0xe7, 0xd9, 0xd3, 0xbd, 0x6a, 0x4d, 0xca, 0x63, - 0x9c, 0x4b, 0xcf, 0x63, 0xdc, 0x4e, 0x32, 0x14, 0xe6, 0xc7, 0x0a, 0xb6, 0x04, 0x53, 0xe0, 0x3e, - 0x5c, 0x8d, 0xab, 0xaa, 0x3d, 0x3c, 0xe8, 0xda, 0x83, 0x23, 0xea, 0x01, 0xcf, 0x1b, 0xe9, 0x00, - 0x68, 0x0b, 0xae, 0x2b, 0x6a, 0x93, 0x2a, 0x52, 0xe9, 0x82, 0xc2, 0x9e, 0xd2, 0x8e, 0x84, 0x21, - 0x17, 0xd3, 0x84, 0x01, 0x68, 0x60, 0x2e, 0x78, 0x52, 0x3b, 0x02, 0x02, 0xbd, 0x07, 0xd7, 0xe2, - 0xad, 0xc1, 0xeb, 0x12, 0xe1, 0x4a, 0x1f, 0x01, 0x72, 0x6e, 0xc5, 0xfc, 0x6d, 0x0d, 0x66, 0x65, - 0x93, 0x3f, 0xf1, 0xd2, 0x79, 0x1d, 0x0a, 0x2c, 0xd0, 0x25, 0x32, 0x24, 0x0a, 0x46, 0x58, 0x81, - 0x4a, 0x30, 0xa3, 0x6a, 0x63, 0x51, 0x94, 0xe2, 0x11, 0x39, 0x25, 0x1e, 0xb1, 0x0a, 0xf9, 0x9a, - 0xf3, 0xf1, 0x80, 0xb6, 0x4c, 0xd1, 0x96, 0xa0, 0x5c, 0xfe, 0xd3, 0x32, 0xe8, 0x82, 0xb7, 0x83, - 0x57, 0x4e, 0xc1, 0x9b, 0x26, 0x4d, 0x7e, 0xd3, 0x94, 0xe4, 0x58, 0x09, 0x4d, 0xa9, 0xac, 0x62, - 0x4a, 0xed, 0xaa, 0xac, 0xc6, 0xae, 0x53, 0x9f, 0x4b, 0x12, 0x28, 0xc1, 0xe3, 0xa5, 0xd1, 0xec, - 0x96, 0xf4, 0x9d, 0x87, 0x5f, 0xb9, 0xbc, 0xea, 0x82, 0x1e, 0x89, 0x60, 0x8b, 0xf0, 0xda, 0xdd, - 0x91, 0x4b, 0x8d, 0x22, 0xc9, 0xea, 0x33, 0xd6, 0x23, 0x6a, 0xc8, 0x57, 0x25, 0xf6, 0x29, 0xa9, - 0xcf, 0x8e, 0xec, 0x3e, 0x80, 0x66, 0xfb, 0x18, 0x62, 0xcb, 0x6a, 0x01, 0x26, 0x56, 0x0b, 0x92, - 0xe2, 0x2a, 0x9e, 0x49, 0x71, 0xcd, 0x9e, 0x42, 0x71, 0x45, 0xd4, 0xec, 0xdc, 0xa9, 0xd5, 0x6c, - 0x4c, 0x87, 0xcc, 0x9f, 0x49, 0x87, 0xa8, 0xe2, 0xfd, 0xf2, 0x29, 0xc5, 0x7b, 0xcc, 0x1b, 0xa0, - 0x9f, 0xc5, 0x1b, 0x90, 0x22, 0xec, 0x17, 0x4e, 0x29, 0xec, 0xd1, 0x85, 0x0b, 0xfb, 0xc5, 0xf3, - 0x0a, 0xfb, 0xa5, 0x73, 0x0b, 0xfb, 0xe5, 0xf3, 0x0a, 0xfb, 0x95, 0xb1, 0xc2, 0x1e, 0xbd, 0x1d, - 0xcb, 0x37, 0x13, 0x79, 0x1f, 0x2c, 0x32, 0x98, 0xd2, 0x9a, 0x70, 0x15, 0x08, 0xb3, 0x49, 0x4a, - 0x89, 0x57, 0x81, 0x30, 0xb9, 0xe4, 0xeb, 0xb0, 0x14, 0x69, 0x13, 0x51, 0xc0, 0xd8, 0x65, 0x34, - 0xc6, 0xf7, 0x49, 0x88, 0x4c, 0x04, 0x24, 0xf6, 0x89, 0x86, 0xb1, 0xf5, 0x55, 0x5b, 0x22, 0x6a, - 0x18, 0x73, 0x24, 0x8c, 0x1b, 0x8d, 0xa3, 0xb2, 0xf1, 0x52, 0xfa, 0x4d, 0x18, 0xd1, 0x6c, 0x89, - 0x50, 0xe3, 0xa9, 0x47, 0x34, 0x47, 0x8d, 0xc8, 0x1b, 0xd1, 0x36, 0xdc, 0x8c, 0xb4, 0xf0, 0xe4, - 0x24, 0xaf, 0xe2, 0x79, 0xf6, 0xd1, 0x00, 0x77, 0x69, 0x8c, 0x32, 0x6f, 0x8c, 0x03, 0x43, 0x4d, - 0x78, 0x25, 0xba, 0xaa, 0x20, 0x49, 0x29, 0xe8, 0xeb, 0x06, 0xed, 0x6b, 0x3c, 0x60, 0xea, 0x95, - 0x2f, 0xa4, 0x94, 0xb5, 0x11, 0x57, 0xbe, 0x90, 0x5e, 0xb6, 0x52, 0xb2, 0x74, 0x04, 0xa5, 0xde, - 0x8c, 0xc7, 0xb0, 0xa3, 0x30, 0xa9, 0xfe, 0x7e, 0xe6, 0xf5, 0x5d, 0xa7, 0xbc, 0x3a, 0x02, 0x02, - 0x3d, 0x82, 0xf5, 0xc4, 0xf8, 0xb6, 0x9c, 0xec, 0xf4, 0x0a, 0x9d, 0xc7, 0x58, 0xb8, 0x09, 0x62, - 0xfb, 0xe5, 0x89, 0x62, 0xfb, 0xdf, 0xd4, 0xe0, 0x46, 0xe2, 0x94, 0xa9, 0x9b, 0x81, 0x50, 0xdc, - 0xab, 0x94, 0xe2, 0xde, 0x1d, 0x49, 0x71, 0x23, 0x7b, 0x60, 0x84, 0x37, 0x7a, 0x14, 0xf4, 0x7b, - 0x69, 0x69, 0x54, 0x82, 0xd5, 0x6e, 0xd1, 0x69, 0x3c, 0x38, 0xfd, 0x34, 0x14, 0x86, 0x1b, 0x39, - 0x06, 0xfa, 0x96, 0x96, 0x12, 0x20, 0xa0, 0x2a, 0x8b, 0xcd, 0xe3, 0x33, 0x74, 0x1e, 0x95, 0xd3, - 0xcf, 0x23, 0xec, 0x83, 0x4d, 0x65, 0xdc, 0x48, 0xe8, 0x0f, 0xb5, 0x14, 0xda, 0xaf, 0xb6, 0x78, - 0x6e, 0x59, 0xe9, 0x35, 0x3a, 0x99, 0xf7, 0xce, 0xb2, 0x29, 0xbc, 0x0b, 0x36, 0x97, 0x31, 0xe3, - 0xa0, 0xef, 0x68, 0xf0, 0x4a, 0xfa, 0x74, 0xc5, 0x6c, 0x5e, 0xa7, 0xb3, 0xa9, 0x9e, 0x71, 0x6b, - 0x94, 0x09, 0x8d, 0x1f, 0x2d, 0x95, 0xa3, 0x85, 0xf2, 0xbd, 0x3d, 0x82, 0xa3, 0x85, 0xfe, 0xfd, - 0xae, 0x06, 0xe5, 0x91, 0x4b, 0x67, 0xa9, 0x75, 0x6f, 0xd0, 0x85, 0xd5, 0xce, 0xbe, 0xcd, 0xb4, - 0x1b, 0xb6, 0xb2, 0x09, 0xc6, 0x43, 0xdf, 0xd7, 0xe0, 0x33, 0xe3, 0x36, 0x80, 0xcd, 0x6c, 0x83, - 0xce, 0xec, 0xe1, 0xb9, 0xb6, 0x5c, 0x9a, 0xdc, 0x64, 0xa3, 0x9e, 0xdb, 0x79, 0xfd, 0x11, 0x2c, - 0x27, 0x9a, 0xf6, 0xa7, 0xf4, 0x53, 0x29, 0x6f, 0xbc, 0xa4, 0xee, 0xef, 0xd3, 0x8f, 0xbe, 0xa5, - 0x38, 0xd5, 0xc6, 0x4e, 0xee, 0x21, 0x5c, 0x4d, 0x35, 0x10, 0xc6, 0x75, 0x94, 0x97, 0x3b, 0x6a, - 0xc4, 0x52, 0x0d, 0x64, 0x51, 0x74, 0xce, 0xae, 0xcc, 0xb3, 0x76, 0xb5, 0x97, 0x42, 0xf1, 0x8a, - 0xb4, 0x3e, 0x55, 0x8f, 0xbb, 0x29, 0xb2, 0xe1, 0xcc, 0xab, 0x35, 0xe0, 0xd6, 0x24, 0x12, 0xf4, - 0x54, 0x7d, 0x7e, 0x00, 0xaf, 0x4e, 0x20, 0x08, 0x4f, 0x45, 0x28, 0x26, 0xbc, 0x36, 0x99, 0x34, - 0x3b, 0x55, 0xaf, 0xfb, 0xf0, 0xfa, 0x84, 0xa2, 0xe4, 0x54, 0xdd, 0x7e, 0x05, 0x36, 0x26, 0x97, - 0x03, 0xa7, 0x72, 0xd5, 0x34, 0x58, 0xd6, 0x8e, 0xf8, 0xbe, 0xe2, 0x39, 0xbe, 0x3c, 0x54, 0xfe, - 0xab, 0x0c, 0x2c, 0x25, 0x3d, 0x7f, 0x1c, 0xf1, 0x0a, 0x61, 0x2f, 0xf6, 0x35, 0xcd, 0xcd, 0x71, - 0x8f, 0x29, 0xd5, 0xaf, 0x6a, 0xc6, 0x02, 0x28, 0x17, 0xf2, 0x6d, 0xcd, 0x55, 0x73, 0xfc, 0xc7, - 0x2f, 0x47, 0xa5, 0xf5, 0x48, 0x3b, 0x2a, 0xef, 0xf5, 0x0f, 0x35, 0x80, 0x2d, 0xab, 0x73, 0x7c, - 0x32, 0xa4, 0x31, 0x98, 0xb4, 0x00, 0x5d, 0x23, 0x29, 0x40, 0xf7, 0xba, 0xf2, 0xf2, 0x22, 0xe8, - 0x64, 0xb4, 0x3f, 0xe9, 0xdc, 0x8e, 0xbc, 0xdf, 0xd7, 0x44, 0x7c, 0xa9, 0xe1, 0xe3, 0x7e, 0xe2, - 0x47, 0x50, 0xca, 0x30, 0xcb, 0xb3, 0xce, 0x9f, 0x48, 0x51, 0x4a, 0xa5, 0x8e, 0xc0, 0xd4, 0xf0, - 0x53, 0xeb, 0xa4, 0xc7, 0x61, 0x98, 0x47, 0x4f, 0xa9, 0x23, 0x47, 0xd4, 0x18, 0xf8, 0xd8, 0x1d, - 0x58, 0x3d, 0x1e, 0x58, 0x0b, 0xca, 0xe5, 0xbf, 0xd6, 0xe4, 0x30, 0x17, 0xfa, 0x32, 0xcc, 0x54, - 0x9d, 0x81, 0x8f, 0xe9, 0xb7, 0x42, 0xe2, 0x69, 0xde, 0x01, 0xe0, 0x26, 0x87, 0x62, 0x1b, 0x23, - 0x70, 0x56, 0x0d, 0xfa, 0xd6, 0x2f, 0x68, 0x38, 0x65, 0xa2, 0x4d, 0xb8, 0x1d, 0xf2, 0x46, 0xfd, - 0x6e, 0x18, 0x4f, 0x43, 0x6f, 0x85, 0x2f, 0x61, 0x63, 0xf9, 0x64, 0x02, 0x68, 0x93, 0x42, 0xb0, - 0x89, 0x31, 0xe8, 0xd5, 0x77, 0x00, 0xc2, 0xca, 0x53, 0xc5, 0x81, 0x5f, 0x57, 0x1e, 0xe0, 0x8f, - 0x78, 0x21, 0xf4, 0x11, 0x2c, 0xc4, 0xde, 0xa2, 0xa0, 0x5b, 0x30, 0xc7, 0xbe, 0xe9, 0x23, 0x9e, - 0xb7, 0x30, 0x24, 0xb5, 0x92, 0x1e, 0x33, 0x47, 0x91, 0xbe, 0x03, 0xa5, 0xd4, 0x6d, 0x7c, 0x0c, - 0xb0, 0x3f, 0xec, 0x5a, 0x3e, 0xf3, 0xe0, 0x5e, 0x81, 0x45, 0xe5, 0x1b, 0x41, 0xac, 0x49, 0xbf, - 0x84, 0x96, 0x61, 0x41, 0x7c, 0xfb, 0xa9, 0xd9, 0x6e, 0xf1, 0x6a, 0x0d, 0x2d, 0xc2, 0xe5, 0x7d, - 0x0f, 0xbb, 0x74, 0xf9, 0xbc, 0x32, 0x83, 0xe6, 0xa0, 0x60, 0xb6, 0x77, 0x79, 0x31, 0x4b, 0x50, - 0x83, 0xef, 0x38, 0x05, 0xa8, 0xb9, 0x8d, 0x4d, 0x28, 0x04, 0x5f, 0x20, 0x46, 0x97, 0xa1, 0xd8, - 0x72, 0xdc, 0xbe, 0xd5, 0xa3, 0x45, 0xfd, 0x12, 0xd2, 0x61, 0x96, 0x3f, 0xa6, 0x60, 0x35, 0xda, - 0xc6, 0xcf, 0x73, 0x00, 0xe1, 0xdb, 0x79, 0x34, 0x0f, 0x60, 0xb6, 0x77, 0x0f, 0xf6, 0xf7, 0x6a, - 0x15, 0xb3, 0xae, 0x5f, 0x42, 0x00, 0xd3, 0x95, 0xbd, 0xbd, 0x7a, 0xab, 0xa6, 0x6b, 0x28, 0x0f, - 0x39, 0xa3, 0x5e, 0xa9, 0xe9, 0x19, 0x34, 0x0b, 0x79, 0xd3, 0xd8, 0x6f, 0x55, 0x09, 0x4c, 0x96, - 0x74, 0xfa, 0xb0, 0x6e, 0x1e, 0x04, 0x35, 0x39, 0x54, 0x84, 0x99, 0xea, 0x6e, 0xab, 0x55, 0xaf, - 0x9a, 0xfa, 0x14, 0xe9, 0x92, 0x17, 0x0e, 0x8c, 0x5d, 0x7d, 0x1a, 0x2d, 0xc0, 0x5c, 0x73, 0xf7, - 0xe1, 0xc1, 0x76, 0xbd, 0x62, 0x98, 0x5b, 0xf5, 0x8a, 0xa9, 0xcf, 0x90, 0x1e, 0xaa, 0x2d, 0xa9, - 0x26, 0x4f, 0x27, 0x2a, 0xd7, 0x14, 0x10, 0x82, 0xf9, 0xea, 0x76, 0xbd, 0xfa, 0xf8, 0x60, 0xbb, - 0xf2, 0xb8, 0x5e, 0xdf, 0xab, 0x1b, 0x3a, 0x90, 0x7d, 0x25, 0x23, 0x57, 0x9b, 0xfb, 0x6d, 0xb3, - 0x6e, 0x1c, 0xd4, 0xea, 0x66, 0xa5, 0xd1, 0x6c, 0xeb, 0x45, 0x02, 0x4c, 0x1a, 0xda, 0xdb, 0x15, - 0xa3, 0x76, 0xd0, 0x68, 0xbd, 0xbf, 0xab, 0xcf, 0xd2, 0x0e, 0x5a, 0x07, 0x95, 0x66, 0x73, 0x97, - 0xcc, 0xf2, 0xa0, 0x51, 0xd3, 0xe7, 0xc8, 0x26, 0xca, 0x1d, 0xb4, 0x4d, 0x32, 0xff, 0x79, 0xba, - 0xff, 0x74, 0x07, 0x0e, 0xaa, 0xad, 0x83, 0x66, 0x65, 0xab, 0xde, 0xd4, 0x2f, 0xa3, 0x12, 0x2c, - 0x85, 0x95, 0x1f, 0xee, 0x1a, 0x8f, 0x39, 0xb8, 0x4e, 0x7a, 0xde, 0xab, 0x98, 0xd5, 0x6d, 0xd2, - 0xd0, 0x36, 0x77, 0x8d, 0xba, 0xbe, 0x40, 0xba, 0xa8, 0xd5, 0x9b, 0x75, 0x06, 0xcd, 0x2a, 0x11, - 0xa9, 0xdc, 0x33, 0x76, 0xbf, 0xf2, 0x55, 0x69, 0x61, 0x8b, 0xe8, 0x15, 0xb8, 0xc1, 0xfb, 0x6d, - 0xed, 0xb6, 0x0e, 0x9e, 0xec, 0x9a, 0x8d, 0xd6, 0xc3, 0x03, 0xa3, 0xbe, 0xd7, 0x6c, 0x54, 0x2b, - 0x07, 0xad, 0xfd, 0x1d, 0x7d, 0x09, 0xad, 0xc1, 0x6a, 0x1c, 0x84, 0xac, 0xa3, 0xd9, 0x30, 0xbf, - 0xaa, 0x2f, 0xa3, 0x25, 0xd0, 0xdb, 0x75, 0xf3, 0xc0, 0xa8, 0x7f, 0xb0, 0xdf, 0x30, 0xea, 0xb5, - 0x83, 0x66, 0xbb, 0xa5, 0xaf, 0x90, 0xda, 0x87, 0xd1, 0xda, 0x2b, 0x62, 0x6b, 0x9a, 0x15, 0xb3, - 0xde, 0x36, 0x69, 0x5d, 0x89, 0x1c, 0x09, 0xad, 0xab, 0x57, 0x6a, 0x75, 0x83, 0xec, 0xcc, 0x55, - 0x7a, 0x24, 0x6c, 0xbb, 0xeb, 0x95, 0xa6, 0xb9, 0xad, 0xaf, 0x92, 0x43, 0x27, 0xc7, 0x4f, 0x51, - 0xae, 0xa1, 0xab, 0xb0, 0xcc, 0xa7, 0xd4, 0xac, 0x57, 0xda, 0xf5, 0xed, 0xdd, 0x26, 0x47, 0xbd, - 0x4e, 0x9a, 0xe8, 0xe6, 0x57, 0xb7, 0xeb, 0xb5, 0xfd, 0x66, 0xfd, 0xa0, 0xba, 0xbb, 0xb3, 0x53, - 0x69, 0xd5, 0xda, 0xfa, 0x8d, 0x8d, 0x16, 0x40, 0xf8, 0xc5, 0x29, 0x42, 0x19, 0x84, 0xcc, 0x59, - 0x8d, 0x7e, 0x89, 0x8c, 0x20, 0xe4, 0x9c, 0xae, 0x11, 0xe2, 0xa5, 0x4c, 0x13, 0x30, 0xc0, 0x02, - 0xff, 0xc4, 0x9a, 0x81, 0xbf, 0x8e, 0x3b, 0x3e, 0xee, 0xea, 0xd9, 0x8d, 0x0d, 0x28, 0x04, 0x1f, - 0x34, 0x22, 0xe8, 0x6d, 0xec, 0xd3, 0x92, 0x7e, 0x89, 0xa0, 0x33, 0xe7, 0x2a, 0xab, 0xd0, 0x36, - 0xfe, 0x31, 0x07, 0x48, 0x5c, 0x29, 0x24, 0xde, 0x24, 0x14, 0x6f, 0x77, 0x8e, 0x65, 0x96, 0x94, - 0xbe, 0x1c, 0x13, 0xb0, 0x24, 0xe1, 0xd4, 0x58, 0x75, 0x06, 0xad, 0xd0, 0x3c, 0x8f, 0x68, 0x7d, - 0x96, 0x8c, 0xfe, 0x10, 0xfb, 0x01, 0xa7, 0xe7, 0xc8, 0xa6, 0x44, 0xe4, 0x0d, 0x6f, 0x9a, 0x22, - 0x27, 0xd2, 0xc6, 0x8c, 0x21, 0x79, 0xdd, 0x34, 0x21, 0x36, 0x35, 0x91, 0x87, 0xb7, 0xcc, 0xa0, - 0x9b, 0x70, 0xad, 0x8d, 0xfd, 0x78, 0x6c, 0x82, 0x03, 0xe4, 0xd1, 0x2a, 0xac, 0x70, 0x80, 0xc0, - 0xb9, 0xcd, 0xdb, 0x0a, 0x64, 0x0b, 0xd9, 0x6f, 0xbe, 0x6b, 0x3a, 0x90, 0x85, 0x89, 0xaa, 0xe0, - 0x19, 0x8f, 0x5e, 0x24, 0xe7, 0xbf, 0x47, 0xe4, 0x1d, 0xcf, 0xb4, 0xd3, 0x67, 0x09, 0xae, 0x81, - 0xfb, 0xce, 0x73, 0xf1, 0xaa, 0x53, 0x9f, 0x23, 0xb3, 0x54, 0x53, 0x2a, 0xf9, 0x40, 0xf3, 0xe8, - 0x06, 0x5c, 0x65, 0xbf, 0x13, 0x9c, 0xd6, 0xfa, 0x65, 0x74, 0x0d, 0xae, 0x44, 0x9a, 0x85, 0x36, - 0x60, 0xec, 0x24, 0x6e, 0x3d, 0xbc, 0xbf, 0x05, 0x74, 0x1d, 0x4a, 0xf1, 0x54, 0x1c, 0xde, 0x8a, - 0xd0, 0x2d, 0x58, 0x17, 0x4e, 0xdc, 0xb8, 0x7b, 0x97, 0x43, 0x2d, 0x92, 0x9d, 0x63, 0x0e, 0xb0, - 0xc8, 0x0d, 0x84, 0x03, 0x2c, 0xa1, 0xcf, 0xc0, 0x2b, 0x0c, 0x20, 0xd1, 0xc0, 0xe4, 0x60, 0xcb, - 0x1b, 0xdf, 0xd3, 0x60, 0x4e, 0x89, 0x36, 0x11, 0xbe, 0x16, 0x15, 0x3c, 0x1b, 0x45, 0xbf, 0x44, - 0x4e, 0x5c, 0x54, 0x2a, 0x6f, 0xf3, 0x75, 0x8d, 0x0c, 0x14, 0x6b, 0x12, 0xf7, 0x47, 0x03, 0x77, - 0xb0, 0xfd, 0x1c, 0x77, 0xf5, 0x0c, 0xd9, 0xa5, 0x18, 0xd8, 0xfb, 0x96, 0xdd, 0x23, 0xa4, 0x2f, - 0x8f, 0x69, 0x9c, 0x0c, 0x06, 0xa4, 0xe3, 0xdc, 0xc6, 0x61, 0x52, 0xbc, 0x8b, 0x1c, 0x93, 0x52, - 0x1b, 0xce, 0x31, 0xda, 0x22, 0x7a, 0xd2, 0x62, 0x2d, 0x6d, 0xdf, 0x19, 0x0e, 0xc9, 0xac, 0x36, - 0x7e, 0xa2, 0x81, 0x1e, 0xfd, 0x1a, 0x03, 0xe1, 0xa2, 0x4a, 0x57, 0x7c, 0x20, 0x4d, 0xbf, 0x14, - 0x12, 0x8b, 0xa8, 0xd2, 0x08, 0x45, 0xb5, 0x7d, 0xcb, 0xf5, 0x45, 0x4d, 0x86, 0x30, 0x09, 0xe9, - 0x56, 0x54, 0x64, 0x49, 0x2f, 0x8f, 0xed, 0x5e, 0xef, 0x6b, 0x4e, 0xff, 0xd0, 0x26, 0x4c, 0x73, - 0x05, 0x16, 0x2b, 0xdd, 0x6e, 0x94, 0x84, 0xf4, 0x29, 0x42, 0xe3, 0xac, 0xfb, 0x58, 0xdb, 0x34, - 0xe5, 0x34, 0x32, 0x4e, 0xac, 0x69, 0x86, 0x2c, 0x8a, 0x0c, 0x18, 0x6b, 0xc9, 0x6f, 0xec, 0x28, - 0xaf, 0xd4, 0xc9, 0x44, 0x42, 0x42, 0xd2, 0x2f, 0x51, 0xdd, 0xdb, 0x12, 0x45, 0x8d, 0x14, 0xab, - 0x41, 0x31, 0x43, 0x79, 0x85, 0x86, 0x82, 0x78, 0x4d, 0x76, 0xab, 0xf1, 0xe3, 0x4f, 0xd6, 0x2e, - 0xfd, 0xe8, 0xd3, 0x35, 0xed, 0xc7, 0x9f, 0xae, 0x69, 0x3f, 0xfb, 0x74, 0xed, 0xd2, 0x0f, 0xfe, - 0x6d, 0x4d, 0xfb, 0xda, 0x3d, 0xe9, 0xdf, 0xef, 0xf4, 0x2d, 0xdf, 0xb5, 0x5f, 0x38, 0xd4, 0xb0, - 0x10, 0x85, 0x01, 0xbe, 0x33, 0x3c, 0x3e, 0xba, 0x33, 0x3c, 0xbc, 0x13, 0x9a, 0x49, 0x87, 0xd3, - 0xf4, 0x6b, 0x76, 0xf7, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x52, 0x89, 0x29, 0xda, 0x67, - 0x00, 0x00, + // 6040 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3d, 0xdd, 0x6f, 0x1b, 0xc9, + 0x7d, 0x5e, 0x92, 0x92, 0xc8, 0x1f, 0x25, 0x79, 0x35, 0xfa, 0x30, 0x2d, 0xdb, 0xb2, 0x8e, 0xe7, + 0xdc, 0xf9, 0x94, 0x8b, 0x9c, 0xda, 0xb9, 0xc3, 0x25, 0x75, 0x7c, 0x47, 0x91, 0x3c, 0x8b, 0x36, + 0x45, 0xe9, 0x96, 0x2b, 0x5f, 0x12, 0xe0, 0x20, 0xac, 0xc8, 0xb1, 0xbc, 0x11, 0xc5, 0x65, 0x76, + 0x57, 0x3e, 0xbb, 0x7d, 0x2b, 0x9a, 0xa2, 0x68, 0xd0, 0xa0, 0x01, 0x82, 0x36, 0xfd, 0x48, 0x9b, + 0xf6, 0xad, 0x4f, 0x79, 0xe9, 0xdf, 0x50, 0xe4, 0xa1, 0x28, 0xd2, 0x3c, 0x16, 0x68, 0x9a, 0x5c, + 0x5f, 0x0a, 0xe4, 0xbd, 0x79, 0x2a, 0x50, 0xcc, 0xd7, 0xee, 0xcc, 0x7e, 0xf0, 0x43, 0x52, 0x93, + 0xa6, 0xb8, 0x27, 0x6b, 0x7e, 0x1f, 0x33, 0xb3, 0x33, 0xbf, 0xaf, 0xf9, 0xcd, 0x6f, 0x68, 0xd0, + 0x7b, 0xce, 0x91, 0x87, 0xdd, 0xe7, 0x76, 0x07, 0x6f, 0x0e, 0x5c, 0xc7, 0x77, 0x10, 0x84, 0x90, + 0xd5, 0xcf, 0x1d, 0xd9, 0xfe, 0xb3, 0xd3, 0xc3, 0xcd, 0x8e, 0x73, 0x72, 0xe7, 0xc8, 0x39, 0x72, + 0xee, 0x50, 0x92, 0xc3, 0xd3, 0xa7, 0xb4, 0x45, 0x1b, 0xf4, 0x2f, 0xc6, 0xba, 0x7a, 0xf3, 0xc8, + 0x71, 0x8e, 0x7a, 0x38, 0xa4, 0xf2, 0xed, 0x13, 0xec, 0xf9, 0xd6, 0xc9, 0x80, 0x13, 0xcc, 0x9f, + 0x60, 0xdf, 0xea, 0x5a, 0xbe, 0xc5, 0xda, 0xe5, 0x6f, 0x17, 0x60, 0xa6, 0xda, 0x6a, 0xfb, 0x8e, + 0x8b, 0x11, 0x82, 0xdc, 0xfe, 0x7e, 0xa3, 0x56, 0xd2, 0xd6, 0xb5, 0xdb, 0x05, 0x83, 0xfe, 0x8d, + 0x5e, 0x83, 0xf9, 0x36, 0x9b, 0x4a, 0xa5, 0xdb, 0x75, 0xb1, 0xe7, 0x95, 0x32, 0x14, 0x1b, 0x81, + 0xa2, 0x35, 0x80, 0xf6, 0x07, 0x4d, 0x41, 0x93, 0xa5, 0x34, 0x12, 0x04, 0x6d, 0x02, 0x6a, 0x3a, + 0x9d, 0xe3, 0x48, 0x5f, 0x39, 0x4a, 0x97, 0x80, 0x41, 0xb7, 0x20, 0x67, 0x38, 0x3d, 0x5c, 0x9a, + 0x5e, 0xd7, 0x6e, 0xcf, 0xdf, 0xd5, 0x37, 0x83, 0x69, 0x57, 0x5b, 0x04, 0x6e, 0x50, 0x2c, 0x99, + 0xb1, 0x69, 0x77, 0x8e, 0x4b, 0x33, 0xeb, 0xda, 0xed, 0x9c, 0x41, 0xff, 0x46, 0x9f, 0x85, 0xa9, + 0xb6, 0x6f, 0xf9, 0xb8, 0x94, 0xa7, 0xac, 0xcb, 0x9b, 0xd2, 0xfa, 0xb6, 0x9c, 0x2e, 0xa6, 0x48, + 0x83, 0xd1, 0xa0, 0x2f, 0xc3, 0x74, 0xd3, 0x3a, 0xc4, 0x3d, 0xaf, 0x54, 0x58, 0xcf, 0xde, 0x2e, + 0xde, 0xbd, 0x29, 0x53, 0xf3, 0x75, 0xd9, 0x64, 0x14, 0xf5, 0xbe, 0xef, 0xbe, 0xdc, 0xca, 0xfd, + 0xe8, 0xa7, 0x37, 0x2f, 0x19, 0x9c, 0x09, 0xfd, 0x16, 0x14, 0x3e, 0x74, 0xdc, 0x63, 0x36, 0x1e, + 0xd0, 0xf1, 0x16, 0xc3, 0xa9, 0x06, 0x28, 0x23, 0xa4, 0x42, 0x65, 0x98, 0xfd, 0xe0, 0x14, 0xbb, + 0x2f, 0xc5, 0x12, 0x14, 0xe9, 0x12, 0x28, 0x30, 0xf4, 0x36, 0x40, 0xd5, 0xe9, 0x3f, 0xb5, 0x8f, + 0x6a, 0x96, 0x6f, 0x95, 0x66, 0xd7, 0xb5, 0xdb, 0xc5, 0xbb, 0x2b, 0xca, 0xcc, 0x02, 0xac, 0x21, + 0x51, 0xa2, 0xb7, 0x21, 0x6f, 0x60, 0xcf, 0x39, 0x75, 0x3b, 0xb8, 0x34, 0x47, 0xb9, 0x96, 0x64, + 0x2e, 0x81, 0xe3, 0x1f, 0x11, 0xd0, 0xa2, 0x15, 0x98, 0xde, 0x1f, 0x98, 0xf6, 0x09, 0x2e, 0xcd, + 0xaf, 0x6b, 0xb7, 0xb3, 0x06, 0x6f, 0xa1, 0xcf, 0xc3, 0x62, 0xfb, 0x99, 0xe5, 0x76, 0x23, 0xbb, + 0x76, 0x99, 0x4e, 0x39, 0x09, 0x85, 0x56, 0x21, 0x5f, 0x75, 0x4e, 0x4e, 0x6c, 0xbf, 0x51, 0x2b, + 0xe9, 0x94, 0x2c, 0x68, 0xa3, 0xf7, 0x61, 0xed, 0x89, 0x8d, 0x3f, 0xde, 0xe1, 0xcb, 0x53, 0xe9, + 0x9e, 0xd8, 0x9e, 0x67, 0x3b, 0xfd, 0xf6, 0xe9, 0x60, 0xe0, 0xb8, 0x3e, 0xee, 0x96, 0x16, 0xd6, + 0xb5, 0xdb, 0x79, 0x63, 0x04, 0x15, 0xda, 0x86, 0x9b, 0x89, 0x14, 0x0f, 0x71, 0x1f, 0xbb, 0x96, + 0x6f, 0x3b, 0xfd, 0x12, 0xa2, 0xf2, 0x30, 0x8a, 0x0c, 0xdd, 0x87, 0xab, 0x32, 0xc9, 0xee, 0x21, + 0x59, 0x29, 0xdc, 0xad, 0x0f, 0x9c, 0xce, 0xb3, 0xd2, 0x22, 0xed, 0x23, 0x9d, 0x00, 0x3d, 0x80, + 0xd5, 0xc4, 0x01, 0x0c, 0x6c, 0x75, 0x5f, 0x96, 0x96, 0xe8, 0xb7, 0x0c, 0xa1, 0x20, 0xa3, 0xd7, + 0x6a, 0xcd, 0x27, 0xb6, 0x67, 0x1f, 0xda, 0x3d, 0xdb, 0x7f, 0xb9, 0x65, 0xb9, 0xae, 0x8d, 0x5d, + 0xc6, 0xbe, 0x4c, 0xd9, 0xd3, 0x09, 0xd0, 0x97, 0xa0, 0x24, 0xf7, 0xdd, 0xe8, 0x1f, 0x91, 0x0d, + 0x60, 0xcc, 0x2b, 0x94, 0x39, 0x15, 0x8f, 0x6a, 0x70, 0x43, 0xe9, 0xb8, 0x86, 0x07, 0x3d, 0xe7, + 0x25, 0xee, 0xee, 0x11, 0x93, 0xd0, 0x71, 0x7a, 0xa5, 0x2b, 0x54, 0x0c, 0x86, 0x13, 0xad, 0xb6, + 0xa0, 0x28, 0x69, 0x06, 0xd2, 0x21, 0x7b, 0x8c, 0x5f, 0x72, 0xe3, 0x41, 0xfe, 0x44, 0x6f, 0xc0, + 0xd4, 0x73, 0xab, 0x77, 0x8a, 0xa9, 0xc9, 0x28, 0xca, 0x9a, 0x41, 0xf9, 0x9a, 0xb6, 0xe7, 0x1b, + 0x8c, 0xe2, 0x4b, 0x99, 0x77, 0xb4, 0x47, 0xb9, 0xfc, 0x94, 0x3e, 0x5d, 0xfe, 0x65, 0x16, 0x66, + 0xcc, 0x0b, 0x30, 0x48, 0xc2, 0x34, 0x64, 0x93, 0x4c, 0x43, 0x6e, 0x0c, 0xd3, 0xf0, 0x16, 0x4c, + 0x53, 0x09, 0xf7, 0x4a, 0x53, 0xd4, 0x34, 0x5c, 0x91, 0xa9, 0xcd, 0x16, 0xc5, 0x35, 0xfa, 0x4f, + 0x1d, 0x61, 0x12, 0x18, 0x31, 0xba, 0x0b, 0x4b, 0x4d, 0xe7, 0xc8, 0xb7, 0xec, 0x1e, 0x99, 0x10, + 0x76, 0xc5, 0x2c, 0xa7, 0xe9, 0x2c, 0x13, 0x71, 0x29, 0xc6, 0x71, 0x26, 0xd5, 0x38, 0xaa, 0xf6, + 0xa1, 0x30, 0xb6, 0x7d, 0x88, 0xda, 0x1e, 0x48, 0xb0, 0x3d, 0x29, 0x3a, 0x5f, 0x4c, 0xd7, 0xf9, + 0xf7, 0xe0, 0x5a, 0xe5, 0xd4, 0x77, 0x1a, 0xfd, 0x8e, 0x4b, 0x15, 0xe3, 0x7d, 0xdc, 0xef, 0xe0, + 0x50, 0xa9, 0x67, 0xa9, 0x30, 0x0e, 0x23, 0x79, 0x94, 0xcb, 0xe7, 0xf5, 0x42, 0xf9, 0x8f, 0xb3, + 0x90, 0x6f, 0x3a, 0x47, 0xff, 0x07, 0xb6, 0xfe, 0x3e, 0xb1, 0xa3, 0x83, 0x9e, 0xdd, 0xb1, 0xc4, + 0xe6, 0xaf, 0xca, 0xf4, 0x4d, 0xe7, 0x88, 0xa3, 0xa5, 0xfd, 0x0f, 0x38, 0x22, 0xbb, 0x33, 0x3d, + 0x89, 0xf5, 0x6e, 0x3a, 0x1d, 0x8b, 0xe8, 0x1a, 0xdd, 0xfb, 0x88, 0xf5, 0x16, 0x38, 0x31, 0x9e, + 0x68, 0xa3, 0x27, 0xf0, 0xda, 0x50, 0x45, 0x0d, 0xb7, 0x22, 0x4f, 0xb7, 0x62, 0x4c, 0xea, 0xf2, + 0x77, 0xb3, 0x30, 0x4b, 0xf6, 0x43, 0x08, 0x3a, 0x2a, 0xc1, 0x0c, 0x6b, 0xb0, 0x6d, 0xc9, 0x19, + 0xa2, 0x89, 0xb6, 0xa4, 0x05, 0xcb, 0xd0, 0x05, 0x7b, 0x2d, 0xb2, 0x60, 0x41, 0x2f, 0x9b, 0x82, + 0x90, 0x5a, 0x0d, 0x69, 0xd9, 0x96, 0x60, 0x8a, 0x19, 0x5e, 0xb6, 0x6d, 0xac, 0x41, 0x1c, 0x4a, + 0x13, 0x5b, 0x5d, 0xec, 0x36, 0x6a, 0x74, 0xeb, 0x72, 0x46, 0xd0, 0xa6, 0xfb, 0x8c, 0xdd, 0x93, + 0xd2, 0x14, 0xdf, 0x67, 0xec, 0x9e, 0xa0, 0x8f, 0x60, 0xa1, 0xe5, 0xf4, 0x9f, 0x38, 0xbe, 0xdd, + 0x3f, 0x0a, 0xa6, 0x34, 0x4d, 0xa7, 0x74, 0x27, 0x75, 0x4a, 0x31, 0x0e, 0x36, 0xb7, 0x78, 0x4f, + 0xab, 0xbf, 0x0d, 0x73, 0x0a, 0x8d, 0x6c, 0xf5, 0x72, 0xcc, 0xea, 0x2d, 0xc9, 0x56, 0xaf, 0x20, + 0x19, 0xb8, 0xd5, 0x1a, 0xac, 0x24, 0x8f, 0x34, 0x49, 0x2f, 0xe5, 0xef, 0x69, 0x30, 0xaf, 0x4a, + 0x20, 0x7a, 0x5f, 0xdd, 0x28, 0xda, 0x4f, 0xf1, 0x6e, 0x29, 0xed, 0x7b, 0xb7, 0xf2, 0x44, 0x82, + 0x7e, 0xfc, 0xd3, 0x9b, 0x9a, 0xa1, 0x6e, 0xf0, 0x75, 0x28, 0x88, 0x6e, 0x6b, 0x74, 0xe0, 0x9c, + 0x11, 0x02, 0xd0, 0x3a, 0x14, 0x1b, 0x5e, 0xf0, 0x01, 0x74, 0x9b, 0xf2, 0x86, 0x0c, 0x2a, 0xff, + 0x91, 0x16, 0x06, 0x20, 0x34, 0x14, 0xd8, 0xdb, 0x37, 0x1d, 0xdf, 0xea, 0xf1, 0x0f, 0x0b, 0xda, + 0xc4, 0x10, 0x55, 0xf7, 0xf6, 0x2b, 0xcf, 0x2d, 0xbb, 0x67, 0x1d, 0xf6, 0xd8, 0x47, 0x6a, 0x86, + 0x02, 0x23, 0xfc, 0x3b, 0xf8, 0x84, 0xf1, 0x33, 0x91, 0x08, 0xda, 0x84, 0x7f, 0x07, 0x9f, 0x84, + 0xfc, 0x4c, 0x32, 0x14, 0x58, 0xf9, 0x07, 0x00, 0x3a, 0x8f, 0xe0, 0xb6, 0xb1, 0xe5, 0xfa, 0x87, + 0xd8, 0xf2, 0x7f, 0x03, 0x43, 0xdc, 0x4d, 0x40, 0xa6, 0xe5, 0x09, 0xde, 0xaa, 0x8b, 0x2d, 0xa2, + 0xc9, 0x33, 0x74, 0xf1, 0x13, 0x30, 0x31, 0x1b, 0x9f, 0x4f, 0xb0, 0xf1, 0xb7, 0x60, 0xae, 0xd1, + 0xb7, 0xfd, 0x30, 0x74, 0x2d, 0x50, 0x22, 0x15, 0x48, 0xa8, 0x1e, 0x3a, 0x9e, 0x67, 0x0f, 0x54, + 0x77, 0xa1, 0x02, 0xc9, 0x78, 0x0c, 0xf0, 0xc8, 0xb1, 0xfb, 0xb8, 0x4b, 0x1d, 0x45, 0xde, 0x50, + 0x60, 0xbf, 0xf2, 0x78, 0x36, 0xc5, 0x87, 0xcd, 0x8f, 0x17, 0xb7, 0x5e, 0x8e, 0xc4, 0xad, 0x9f, + 0x87, 0xc5, 0x4a, 0xe7, 0x18, 0x77, 0x09, 0xc0, 0xea, 0x77, 0xb7, 0x2c, 0xbf, 0xf3, 0x8c, 0x87, + 0xb7, 0x39, 0x23, 0x09, 0x45, 0x3c, 0x22, 0x87, 0xd4, 0x70, 0xcf, 0x7e, 0x4e, 0x56, 0xbe, 0x73, + 0x1c, 0x0d, 0x73, 0x87, 0x91, 0x8c, 0x11, 0x2b, 0xa3, 0x8b, 0x8a, 0x95, 0x17, 0x2f, 0x20, 0x56, + 0x5e, 0x1a, 0x15, 0x2b, 0x47, 0xbe, 0xa7, 0x6a, 0xf9, 0x56, 0xcf, 0x39, 0xa2, 0x61, 0x00, 0xef, + 0x62, 0x99, 0x76, 0x31, 0x82, 0x0a, 0x6d, 0xc1, 0x75, 0x99, 0xc2, 0xc0, 0x4f, 0x5d, 0xec, 0x3d, + 0x0b, 0x57, 0x85, 0x45, 0xbe, 0x43, 0x69, 0xe2, 0x7d, 0x3c, 0xb7, 0x7a, 0x76, 0x97, 0x28, 0x0f, + 0x9b, 0xc9, 0x15, 0x3a, 0x93, 0xa1, 0x34, 0x43, 0xa3, 0xef, 0xd2, 0x88, 0xe8, 0x7b, 0x68, 0xdc, + 0x7f, 0x75, 0x54, 0xdc, 0x3f, 0x32, 0x76, 0x5f, 0x1d, 0x23, 0x76, 0xe7, 0xb1, 0xb6, 0x09, 0xb3, + 0xd5, 0x56, 0xa5, 0xd7, 0x73, 0x3a, 0x96, 0x8f, 0x1b, 0xb5, 0x84, 0x10, 0x7e, 0x09, 0xa6, 0xa8, + 0x50, 0x73, 0x6f, 0xc0, 0x1a, 0xcc, 0x4f, 0x7c, 0xe3, 0x14, 0x7b, 0x44, 0x5d, 0x98, 0x21, 0x0c, + 0x01, 0xe5, 0x7f, 0xc9, 0xc1, 0x82, 0x88, 0xe3, 0x86, 0x5b, 0xde, 0x75, 0x28, 0x1a, 0xd6, 0x53, + 0x5f, 0x35, 0xbb, 0x32, 0x28, 0xc1, 0x36, 0x67, 0x13, 0x6d, 0x73, 0xcc, 0x56, 0xe5, 0x92, 0x6c, + 0xd5, 0xf9, 0xe2, 0xba, 0x64, 0x4b, 0x3c, 0x9d, 0x6a, 0x89, 0x55, 0xab, 0x37, 0x73, 0xa6, 0x38, + 0x30, 0x3f, 0x41, 0x1c, 0xf8, 0x25, 0x28, 0x45, 0x4c, 0x4a, 0xa8, 0x17, 0x05, 0x26, 0x93, 0x69, + 0xf8, 0x31, 0xec, 0x0d, 0x8c, 0x65, 0x6f, 0xc6, 0x8f, 0x45, 0x8b, 0x13, 0xc5, 0xa2, 0x75, 0x28, + 0x4a, 0x47, 0xae, 0x21, 0x91, 0xe8, 0xd0, 0x10, 0xa6, 0xfc, 0xcd, 0x29, 0xd0, 0xcd, 0x8b, 0x8c, + 0x09, 0xc2, 0x43, 0x62, 0x76, 0x92, 0x43, 0x62, 0xb2, 0x28, 0xe5, 0x52, 0x45, 0x29, 0xed, 0x50, + 0x39, 0x35, 0xf1, 0xa1, 0x72, 0x7a, 0xcc, 0x43, 0x65, 0xfe, 0xcc, 0x87, 0xca, 0xc2, 0xf8, 0x87, + 0x4a, 0x48, 0x77, 0xc8, 0xc4, 0x34, 0xe0, 0x41, 0xcf, 0x7a, 0x89, 0xbb, 0x4d, 0xaf, 0x4f, 0xa5, + 0x25, 0x67, 0xc8, 0xa0, 0xf3, 0x1f, 0x3b, 0xd3, 0x1c, 0xfb, 0xdc, 0x99, 0x1d, 0xfb, 0xfc, 0x48, + 0xc7, 0xfe, 0x28, 0x97, 0x9f, 0xd1, 0xf3, 0xe5, 0x1f, 0x4e, 0x41, 0xde, 0x68, 0xef, 0xb0, 0x38, + 0x4b, 0x87, 0xac, 0xe9, 0x39, 0x22, 0xf8, 0x37, 0x3d, 0x87, 0x58, 0xdd, 0x46, 0xbf, 0x8b, 0x5f, + 0x08, 0xab, 0x4b, 0x1b, 0xc4, 0xc6, 0x35, 0xb1, 0xe5, 0xe1, 0x6d, 0xa7, 0xc7, 0xce, 0x43, 0x2c, + 0x2a, 0x56, 0x81, 0x64, 0x3b, 0x4c, 0xf7, 0xb4, 0x4f, 0x2c, 0x3a, 0x5d, 0x39, 0x1e, 0x1a, 0xcb, + 0x30, 0xf4, 0x08, 0x66, 0x19, 0x93, 0xed, 0xf9, 0x8e, 0xfb, 0x92, 0xdb, 0x42, 0xe5, 0xc8, 0x26, + 0x66, 0xb7, 0x29, 0x13, 0xb2, 0x63, 0x91, 0xc2, 0xcb, 0x36, 0xea, 0x1b, 0xa7, 0xb6, 0xcb, 0x86, + 0x9b, 0x16, 0x1b, 0x15, 0x80, 0xd0, 0x9b, 0xb0, 0xf0, 0x61, 0xa5, 0x69, 0xe0, 0x8e, 0x43, 0x56, + 0xa3, 0x66, 0x1f, 0x61, 0xcf, 0xe7, 0xc9, 0x8d, 0x38, 0x02, 0x7d, 0x01, 0x96, 0x25, 0x20, 0x1d, + 0xb1, 0xea, 0x9c, 0xf6, 0x7d, 0x2a, 0x91, 0x39, 0x23, 0x19, 0x49, 0x36, 0x46, 0x42, 0x54, 0x9d, + 0x93, 0x41, 0x0f, 0x13, 0x67, 0xdd, 0xf7, 0x5d, 0x1b, 0x33, 0x99, 0xcc, 0x19, 0xc3, 0x48, 0x88, + 0xba, 0x48, 0xe8, 0x2d, 0xcb, 0xc3, 0xe4, 0x73, 0x80, 0x32, 0x26, 0x60, 0x22, 0xf4, 0x4d, 0xcb, + 0xf3, 0x43, 0x39, 0x4d, 0xc0, 0xa0, 0x47, 0xb0, 0x2e, 0x41, 0x77, 0x5d, 0xfb, 0xc8, 0xee, 0x5b, + 0x3d, 0x75, 0x43, 0x67, 0x29, 0xf7, 0x48, 0x3a, 0x22, 0xb8, 0x09, 0x9f, 0x42, 0x05, 0x37, 0x6f, + 0x24, 0xa1, 0x56, 0xdf, 0x85, 0x85, 0xd8, 0x46, 0x8e, 0x3a, 0x75, 0xe6, 0xe4, 0x53, 0xe7, 0x47, + 0x50, 0xa0, 0xee, 0xb1, 0xe3, 0xb8, 0x5d, 0xc2, 0x48, 0x3e, 0x96, 0x33, 0x92, 0xaf, 0xdb, 0x80, + 0x9c, 0xf9, 0x72, 0xc0, 0xf8, 0xe6, 0x55, 0xb3, 0xc1, 0x78, 0x08, 0xd6, 0xa0, 0x34, 0xc4, 0xde, + 0x52, 0x13, 0x43, 0xc4, 0x77, 0xd6, 0xa0, 0x7f, 0x97, 0x7f, 0x96, 0x01, 0xa0, 0xfd, 0xd3, 0x20, + 0x82, 0x90, 0xb4, 0xac, 0x13, 0x2c, 0x4c, 0x32, 0xf9, 0x5b, 0xb6, 0xf9, 0x19, 0xd5, 0xe6, 0xf3, + 0xe9, 0x64, 0xc3, 0xe9, 0x94, 0x60, 0x66, 0xc7, 0x7a, 0xd1, 0xb6, 0x7f, 0x47, 0x1c, 0x0d, 0x45, + 0x93, 0xf8, 0x07, 0x61, 0x96, 0x6b, 0x3c, 0x71, 0x10, 0x02, 0x68, 0x46, 0xa1, 0xd5, 0xa8, 0x71, + 0x29, 0xa6, 0x7f, 0xa3, 0x2f, 0x40, 0xc6, 0x6c, 0x73, 0xf7, 0xbd, 0xba, 0xc9, 0xee, 0x57, 0x36, + 0xc5, 0xfd, 0xca, 0xa6, 0x29, 0xee, 0x57, 0xd8, 0xa1, 0xfa, 0x4f, 0xfe, 0xfd, 0xa6, 0x66, 0x64, + 0xcc, 0x36, 0x71, 0xa8, 0x8d, 0x7e, 0xa7, 0x77, 0xda, 0xc5, 0xf5, 0x17, 0x03, 0xa2, 0x09, 0xdc, + 0x09, 0x71, 0xfb, 0x86, 0x3d, 0x9e, 0x8c, 0x19, 0x41, 0x45, 0x02, 0xf8, 0xfa, 0x0b, 0x4a, 0xb1, + 0x6d, 0xb9, 0xdd, 0x9a, 0xf3, 0x71, 0x3f, 0xd6, 0x11, 0xf3, 0xed, 0xa3, 0xc8, 0xca, 0x65, 0x00, + 0xd3, 0x73, 0xc4, 0x0a, 0x2f, 0xc1, 0x14, 0x53, 0x2b, 0xb6, 0x89, 0xac, 0x51, 0xfe, 0x85, 0x46, + 0x22, 0x42, 0xea, 0x1f, 0x69, 0x8a, 0x36, 0xd1, 0x37, 0xde, 0x83, 0xc2, 0xee, 0x40, 0x9c, 0x1e, + 0x32, 0xf1, 0x74, 0x5a, 0xb5, 0x45, 0x79, 0x77, 0x07, 0x46, 0x48, 0x87, 0xb6, 0x82, 0x8b, 0x16, + 0xe6, 0x28, 0x6f, 0x25, 0x5c, 0xb4, 0x50, 0x82, 0xf4, 0xdb, 0x96, 0x8b, 0x4e, 0x38, 0x97, 0x9b, + 0x50, 0xac, 0xb6, 0xc2, 0xf3, 0x6e, 0xd2, 0xb7, 0xbe, 0x21, 0xd2, 0x86, 0x99, 0xf4, 0xcb, 0x1d, + 0x46, 0x51, 0xfe, 0x39, 0x5f, 0x3b, 0xcb, 0x1f, 0xb2, 0x76, 0xe3, 0xf7, 0x37, 0x7a, 0xc5, 0xc4, + 0x40, 0xbf, 0xc2, 0x15, 0xfb, 0x4e, 0x1e, 0x66, 0x84, 0x04, 0x29, 0x87, 0x00, 0x4d, 0x44, 0x5a, + 0x1c, 0x80, 0x36, 0x61, 0x7a, 0x07, 0xfb, 0xcf, 0x9c, 0x6e, 0x92, 0x49, 0x60, 0x18, 0x6a, 0x12, + 0x38, 0x15, 0xba, 0x2f, 0xeb, 0x3f, 0x55, 0xe5, 0x48, 0xf4, 0x11, 0x62, 0xf9, 0x37, 0xca, 0xf6, + 0xa2, 0x42, 0x13, 0x60, 0x41, 0x48, 0x47, 0x95, 0xbe, 0x78, 0xf7, 0x46, 0x34, 0x01, 0xa6, 0xc4, + 0x7d, 0x86, 0xc2, 0x82, 0x1e, 0x10, 0x61, 0x08, 0x7b, 0x98, 0xa2, 0x3d, 0x5c, 0x4f, 0x90, 0xd2, + 0xb0, 0x03, 0x99, 0x81, 0xf0, 0x9b, 0x12, 0xff, 0x74, 0x9c, 0xdf, 0x8c, 0xf1, 0x4b, 0x0c, 0x24, + 0xfc, 0x0a, 0xd5, 0x33, 0xe9, 0xb4, 0x10, 0x62, 0x0d, 0x59, 0x91, 0xef, 0xab, 0x67, 0x38, 0x1e, + 0xb8, 0x95, 0xd4, 0x89, 0x87, 0x78, 0x43, 0x3d, 0xf1, 0xdd, 0x57, 0xf5, 0x9d, 0xdf, 0x25, 0x94, + 0xd2, 0x94, 0xd3, 0x50, 0xad, 0xc3, 0x17, 0x15, 0x05, 0xa2, 0xce, 0x32, 0x12, 0x02, 0x4b, 0x68, + 0x43, 0x51, 0xb6, 0xfb, 0xaa, 0xb2, 0x50, 0xc7, 0x99, 0x30, 0xb0, 0xc0, 0x1b, 0xaa, 0x6a, 0xbd, + 0x0b, 0x73, 0x35, 0x4c, 0x1c, 0x1b, 0x9f, 0x0e, 0xcf, 0x29, 0x5d, 0x95, 0xd9, 0x15, 0x02, 0x43, + 0xa5, 0x47, 0x5b, 0x30, 0xbf, 0xe7, 0x3a, 0x2f, 0x5e, 0x86, 0x1b, 0x36, 0xc7, 0x0d, 0xbc, 0xd4, + 0x83, 0x4a, 0x61, 0x44, 0x38, 0x88, 0x17, 0x8e, 0xa6, 0x73, 0x5b, 0xa7, 0x27, 0x34, 0x08, 0xcc, + 0x19, 0x49, 0x28, 0xb4, 0x25, 0x25, 0xa7, 0x83, 0x23, 0xde, 0xe5, 0xf4, 0x23, 0x9e, 0x11, 0x27, + 0xa7, 0x6b, 0xfe, 0x0c, 0x77, 0x8e, 0xb7, 0xb1, 0xd5, 0xf3, 0x9f, 0xd1, 0x2c, 0x54, 0x74, 0xcd, + 0x43, 0xb4, 0x21, 0xd3, 0x22, 0x13, 0x96, 0xda, 0x9d, 0x67, 0xb8, 0x7b, 0xda, 0xc3, 0x3c, 0x44, + 0xa5, 0x41, 0x3a, 0xcd, 0x47, 0x15, 0xef, 0xae, 0xcb, 0x7d, 0x24, 0xd1, 0x19, 0x89, 0xdc, 0x65, + 0x07, 0x8a, 0x54, 0x13, 0xbd, 0x81, 0xd3, 0xf7, 0xf0, 0x90, 0xa3, 0x19, 0x77, 0xd3, 0x19, 0xc5, + 0x4d, 0x8b, 0xc0, 0x89, 0x39, 0x6f, 0xd1, 0x1c, 0x96, 0xf6, 0x2f, 0x6f, 0x02, 0x92, 0xe4, 0x59, + 0x1a, 0xf7, 0x7d, 0xdb, 0x95, 0x8c, 0x91, 0x68, 0x96, 0xff, 0x2b, 0x47, 0xd3, 0x88, 0x8c, 0xec, + 0x62, 0xad, 0xd6, 0x75, 0x28, 0xd4, 0x5d, 0xd7, 0x71, 0xab, 0x4e, 0x17, 0xd3, 0x4f, 0x98, 0x33, + 0x42, 0x00, 0x09, 0xc5, 0x69, 0x63, 0x07, 0x7b, 0x9e, 0x75, 0x84, 0x79, 0x4e, 0x42, 0x81, 0xa1, + 0x35, 0x80, 0x86, 0xb7, 0x5d, 0x79, 0x8c, 0xf1, 0x00, 0xbb, 0xd4, 0xea, 0xe4, 0x0d, 0x09, 0x82, + 0xde, 0x55, 0x56, 0x97, 0x9b, 0x95, 0x2b, 0x31, 0xc3, 0xc8, 0xd0, 0xdc, 0x32, 0x2a, 0xfb, 0x41, + 0x14, 0x4d, 0x3a, 0xc4, 0x70, 0xcb, 0xa2, 0x2a, 0x9a, 0x84, 0x37, 0x14, 0x6a, 0x22, 0x6d, 0xd4, + 0xd6, 0xf0, 0xe1, 0xf3, 0xf1, 0xe1, 0x25, 0xb4, 0x21, 0xd3, 0x12, 0x15, 0xab, 0xf6, 0x4e, 0x3d, + 0x1f, 0xbb, 0x35, 0x4c, 0x4e, 0xa7, 0x1e, 0x37, 0x2e, 0x8a, 0x8a, 0xa9, 0x14, 0x46, 0x84, 0x03, + 0x3d, 0x80, 0x42, 0x78, 0xab, 0x01, 0x09, 0x62, 0x2a, 0x90, 0x4c, 0x40, 0xb1, 0x77, 0xda, 0xf3, + 0x8d, 0x90, 0x05, 0x3d, 0x00, 0x90, 0x4c, 0x23, 0xb3, 0x31, 0x6b, 0x72, 0x07, 0x71, 0x41, 0x32, + 0x20, 0x62, 0x1e, 0x89, 0x02, 0x61, 0x97, 0x59, 0xb8, 0xd9, 0x84, 0xc5, 0x93, 0xf0, 0x86, 0x42, + 0x5d, 0x7e, 0x44, 0xf3, 0x60, 0x2c, 0xfe, 0x0d, 0x96, 0xe5, 0x2d, 0xe2, 0x41, 0x09, 0xc4, 0x2b, + 0x69, 0xd4, 0xaf, 0x2f, 0xc7, 0x36, 0x93, 0x60, 0xf9, 0x56, 0x0a, 0xda, 0xf2, 0xab, 0xca, 0x46, + 0x90, 0xf0, 0xed, 0x09, 0xf5, 0xdb, 0x3c, 0x7c, 0xa3, 0x8d, 0xf2, 0x43, 0x98, 0x33, 0x2d, 0xef, + 0xd8, 0xb4, 0x0e, 0x7b, 0x78, 0xdf, 0xc3, 0x2e, 0x51, 0x23, 0xf2, 0x6f, 0x3f, 0x8c, 0xa5, 0x83, + 0x36, 0xc1, 0xed, 0x59, 0x9e, 0xf7, 0xb1, 0xe3, 0x76, 0x79, 0x72, 0x23, 0x68, 0x97, 0xbf, 0xa5, + 0x91, 0x59, 0x52, 0xbb, 0x95, 0x18, 0xc6, 0xa4, 0xc7, 0xe2, 0x4a, 0xfe, 0x25, 0x1b, 0xbd, 0x42, + 0x0a, 0xee, 0xf8, 0x72, 0xf2, 0x1d, 0xdf, 0x1a, 0xf5, 0xfd, 0x6a, 0x50, 0x2e, 0x41, 0xca, 0x7f, + 0x91, 0x21, 0x32, 0xdc, 0x7f, 0x6a, 0x1f, 0x55, 0x9f, 0x59, 0xfd, 0x23, 0x8c, 0xee, 0x05, 0xb3, + 0xe3, 0x57, 0x5d, 0x8b, 0xea, 0x81, 0x83, 0xa2, 0xc2, 0x15, 0x64, 0xdf, 0x71, 0x1f, 0x80, 0xb1, + 0x4b, 0x07, 0x95, 0xeb, 0xf1, 0xfc, 0x46, 0x48, 0x63, 0x48, 0xf4, 0xc8, 0x84, 0xf9, 0x46, 0xdf, + 0xf6, 0x6d, 0xab, 0xb7, 0x83, 0x4f, 0x0e, 0xb1, 0x2b, 0xa2, 0xb2, 0x37, 0xd3, 0x7a, 0xd8, 0x54, + 0xc9, 0xd9, 0xd1, 0x39, 0xd2, 0xc7, 0x6a, 0x05, 0x16, 0x13, 0xc8, 0x26, 0xba, 0x0e, 0x7c, 0x03, + 0xe6, 0xda, 0xcf, 0x4e, 0xfd, 0xae, 0xf3, 0x71, 0x9f, 0xb9, 0x36, 0xb2, 0x37, 0xe4, 0x8f, 0x60, + 0xcb, 0x44, 0xb3, 0xfc, 0xf7, 0x53, 0x70, 0x39, 0x62, 0xc2, 0x13, 0x77, 0xf7, 0x16, 0xcc, 0x6d, + 0x39, 0x8e, 0xef, 0xf9, 0xae, 0x35, 0x18, 0xd8, 0xfd, 0x23, 0x3a, 0x68, 0xde, 0x50, 0x81, 0xc4, + 0x34, 0xf0, 0x9c, 0x0d, 0x5d, 0xd0, 0x2c, 0x5d, 0x50, 0xc5, 0x34, 0x48, 0x68, 0x43, 0xa6, 0x65, + 0x36, 0x29, 0x5c, 0x2a, 0x1e, 0xae, 0x95, 0xd2, 0x96, 0xd2, 0x50, 0x77, 0xff, 0xdd, 0xc8, 0x17, + 0xf3, 0x58, 0xed, 0xaa, 0x6a, 0x18, 0x24, 0x02, 0x23, 0xb2, 0x42, 0x8f, 0x61, 0x81, 0x25, 0xd6, + 0xa4, 0x4c, 0x1b, 0xb7, 0xac, 0x4a, 0xc8, 0x18, 0x23, 0x32, 0xe2, 0x7c, 0xf1, 0x50, 0x64, 0x66, + 0xc2, 0x50, 0xe4, 0x31, 0x2c, 0x3c, 0x72, 0xec, 0x3e, 0xcb, 0x54, 0x73, 0xfb, 0xc7, 0x0d, 0xad, + 0x32, 0x9b, 0x18, 0x91, 0x11, 0xe7, 0x43, 0xdb, 0xa0, 0xb3, 0xde, 0x69, 0xac, 0xc2, 0x26, 0x54, + 0x88, 0x87, 0xa2, 0x51, 0x1a, 0x23, 0xc6, 0x45, 0xb6, 0xb7, 0xd2, 0xed, 0x0a, 0x2d, 0x4c, 0x8a, + 0xed, 0x24, 0xb4, 0x21, 0xd3, 0x12, 0xcb, 0x1f, 0x88, 0x0a, 0xe3, 0x2e, 0xc6, 0x2d, 0xbf, 0x4a, + 0x61, 0x44, 0x38, 0xca, 0x38, 0x39, 0x56, 0x49, 0x94, 0xd7, 0x88, 0x24, 0x66, 0xc6, 0x97, 0xc4, + 0xf2, 0x9f, 0x66, 0x60, 0x25, 0x92, 0xae, 0x33, 0x2d, 0xf7, 0x08, 0xfb, 0xf4, 0x62, 0x93, 0x6f, + 0x11, 0x19, 0x84, 0x59, 0xeb, 0x82, 0xa1, 0xc0, 0x68, 0xb2, 0x4d, 0xa6, 0xc9, 0x30, 0x1a, 0x19, + 0x46, 0xec, 0x6c, 0xfd, 0x05, 0x31, 0x41, 0xb6, 0xcf, 0xef, 0xcc, 0x83, 0x36, 0x09, 0x21, 0x79, + 0x7f, 0xa6, 0x7d, 0x82, 0x9d, 0x53, 0xdf, 0xb4, 0x3b, 0xc7, 0x1e, 0xb7, 0x8e, 0x49, 0x28, 0xc2, + 0x61, 0x26, 0x70, 0x30, 0xa3, 0x99, 0x84, 0x42, 0x5f, 0x80, 0xe5, 0x3a, 0x31, 0x17, 0x96, 0x8f, + 0xab, 0xa7, 0xae, 0x8b, 0xfb, 0x3e, 0xa5, 0xf1, 0xf8, 0xcd, 0x45, 0x32, 0xb2, 0x7c, 0x27, 0x41, + 0x2a, 0xd9, 0xa7, 0xd8, 0x1e, 0xbd, 0xfe, 0x67, 0xcb, 0x11, 0xb4, 0xcb, 0xbd, 0x04, 0xa5, 0x42, + 0xf7, 0x20, 0x47, 0xfc, 0x0d, 0xb7, 0xd2, 0x8a, 0x4e, 0x28, 0x8e, 0x8a, 0xdb, 0x6a, 0x4a, 0x4c, + 0x17, 0xd5, 0xf2, 0x8e, 0x6b, 0x96, 0x6f, 0x1d, 0x5a, 0x9e, 0x30, 0x79, 0x0a, 0x8c, 0x58, 0x3d, + 0x55, 0x8b, 0xd2, 0xad, 0xde, 0x9b, 0x71, 0x95, 0x18, 0x42, 0xfd, 0xba, 0x22, 0xf6, 0xe9, 0xd1, + 0x6c, 0xf9, 0x97, 0x5a, 0x54, 0xca, 0xcf, 0x7a, 0x2b, 0x81, 0x9e, 0xa4, 0xf8, 0x96, 0xcd, 0x74, + 0x7d, 0x19, 0xc7, 0xbb, 0x10, 0x5d, 0x21, 0x7b, 0xc8, 0xef, 0x15, 0xe8, 0xdf, 0x17, 0xe1, 0x71, + 0xfe, 0x3c, 0xa3, 0x86, 0x94, 0x41, 0x1d, 0x8e, 0x26, 0xd5, 0xe1, 0x7c, 0x99, 0x5d, 0xa8, 0x5b, + 0xfd, 0xae, 0xa8, 0x08, 0xba, 0x36, 0xe4, 0x7c, 0x21, 0xee, 0xb2, 0x04, 0x0b, 0x59, 0x4a, 0x91, + 0x8e, 0xe7, 0x27, 0x03, 0x91, 0x82, 0xaf, 0x02, 0x70, 0x2a, 0xa2, 0x70, 0x39, 0xda, 0xf5, 0x8d, + 0x21, 0x5d, 0x37, 0x6a, 0x22, 0x5f, 0x10, 0xb2, 0xa1, 0x0f, 0x61, 0x39, 0xf1, 0x22, 0x8b, 0xbb, + 0x92, 0x57, 0xe4, 0xfe, 0x92, 0x2b, 0x38, 0x93, 0xf9, 0xcb, 0x7f, 0x99, 0x49, 0xe9, 0x99, 0x88, + 0xc0, 0x9e, 0x8b, 0x07, 0x96, 0xcb, 0x94, 0x87, 0xec, 0x48, 0x08, 0x20, 0xdf, 0x5b, 0xef, 0x13, + 0x6d, 0xe8, 0x72, 0x67, 0x2b, 0x9a, 0x29, 0x65, 0x51, 0x77, 0x61, 0x29, 0xb8, 0x93, 0xa6, 0x05, + 0xa5, 0x2c, 0xdd, 0xce, 0xb7, 0x3a, 0x11, 0x87, 0x36, 0x01, 0x25, 0xdc, 0xbb, 0x33, 0xcb, 0x91, + 0x80, 0x21, 0x61, 0x99, 0x54, 0x26, 0xc0, 0x52, 0xa2, 0x12, 0x84, 0xcc, 0x8c, 0xdd, 0x59, 0xb3, + 0x62, 0x14, 0xd6, 0x20, 0x36, 0x82, 0x7c, 0xb4, 0x1f, 0xd6, 0x9b, 0x05, 0xed, 0xf2, 0xbf, 0x6a, + 0xea, 0xd5, 0x7b, 0xb0, 0x3a, 0xc2, 0xe6, 0xca, 0xb6, 0x52, 0x1b, 0xcf, 0x56, 0x66, 0xd2, 0x6d, + 0xe5, 0xdb, 0xb0, 0x12, 0xea, 0xbc, 0xc2, 0xc4, 0xd6, 0x32, 0x05, 0x9b, 0x6e, 0x31, 0x73, 0xc3, + 0x2c, 0xe6, 0xcf, 0x8b, 0x50, 0xe4, 0xb3, 0xa0, 0x67, 0x0f, 0x51, 0x85, 0xa8, 0x49, 0x55, 0x88, + 0xff, 0xbf, 0x4a, 0x8d, 0x2a, 0x41, 0x86, 0x32, 0x4f, 0xd5, 0xf0, 0xd5, 0x84, 0xb4, 0x11, 0xad, + 0xaf, 0x1b, 0xb3, 0x80, 0xbe, 0x70, 0xa6, 0x02, 0x7a, 0x48, 0x2e, 0x70, 0x52, 0xcb, 0x01, 0x8a, + 0xe3, 0x94, 0x2e, 0xcd, 0x8e, 0x2c, 0x5d, 0x9a, 0x3b, 0x53, 0xe9, 0xd2, 0xfc, 0x99, 0x4a, 0xf1, + 0x2f, 0x8f, 0x53, 0x8a, 0xaf, 0x8f, 0x57, 0xd2, 0xb4, 0x10, 0x29, 0x69, 0x1a, 0x71, 0x8f, 0x89, + 0x2e, 0xa2, 0x40, 0x69, 0xf1, 0xa2, 0x0a, 0x94, 0x96, 0x2e, 0xa0, 0x40, 0x69, 0xf9, 0xfc, 0x05, + 0x4a, 0x2b, 0x17, 0x52, 0xa0, 0x74, 0xe5, 0x02, 0x0a, 0x94, 0x4a, 0x63, 0x14, 0x28, 0x0d, 0x7f, + 0x9c, 0x70, 0x75, 0xe4, 0xe3, 0x84, 0x61, 0x05, 0x4e, 0xab, 0xe7, 0x29, 0x70, 0xba, 0x76, 0xee, + 0x02, 0xa7, 0xeb, 0xbf, 0xbe, 0xc7, 0x09, 0x9f, 0x68, 0xec, 0xb5, 0x14, 0x7f, 0x3a, 0xc4, 0xdd, + 0x82, 0x96, 0xfc, 0x74, 0xc8, 0xf2, 0xf1, 0x26, 0xa3, 0x50, 0x2c, 0x1f, 0x03, 0x8d, 0xfe, 0xcc, + 0xcc, 0x38, 0x9f, 0x69, 0x40, 0x51, 0x1a, 0x22, 0xe1, 0x33, 0x3f, 0xa7, 0x7e, 0xe6, 0x95, 0x14, + 0x13, 0x2d, 0xc7, 0x77, 0xff, 0x9c, 0xa3, 0xc5, 0x36, 0x17, 0xe2, 0xc8, 0x3e, 0xad, 0x8f, 0xf9, + 0x0d, 0xae, 0x8f, 0x19, 0xe1, 0x25, 0xe6, 0xc6, 0xad, 0x76, 0xf9, 0x2b, 0x8d, 0x3d, 0xe9, 0x19, + 0xa9, 0x35, 0xe6, 0x28, 0xad, 0x39, 0x9f, 0xbc, 0x9b, 0xc9, 0xf2, 0xfe, 0x77, 0x59, 0x00, 0xe9, + 0x6c, 0x98, 0x94, 0x61, 0x10, 0x2a, 0x90, 0x91, 0x54, 0xe0, 0x16, 0xcc, 0x11, 0x23, 0x81, 0xfb, + 0x6a, 0x98, 0xa6, 0x02, 0x23, 0x52, 0x93, 0x1b, 0x5b, 0x6a, 0x46, 0xfb, 0xd7, 0xa9, 0x8b, 0xf2, + 0xaf, 0xd3, 0x17, 0xe0, 0x5f, 0x67, 0xce, 0xf7, 0x58, 0x2e, 0x3f, 0xca, 0x1f, 0x95, 0xff, 0x56, + 0x0b, 0x36, 0x89, 0x88, 0xd1, 0x7b, 0x11, 0x31, 0x2a, 0xc7, 0xee, 0xed, 0x46, 0x49, 0xd2, 0x07, + 0xa3, 0x24, 0xe9, 0x4d, 0x55, 0x92, 0x56, 0x12, 0x46, 0x70, 0x5c, 0x2c, 0x0b, 0xd2, 0x4f, 0x32, + 0xd1, 0x5b, 0xc5, 0xb4, 0xf4, 0xaa, 0x2a, 0x38, 0x99, 0xd1, 0x82, 0x93, 0xbd, 0x40, 0xc1, 0xc9, + 0x5d, 0x94, 0xe0, 0x4c, 0x5d, 0x80, 0xe0, 0x4c, 0x8f, 0x10, 0x9c, 0xf2, 0xbf, 0x65, 0xa3, 0xf7, + 0x48, 0xe8, 0x2d, 0xc8, 0x73, 0x55, 0x16, 0xdb, 0xbf, 0x98, 0xa0, 0xe6, 0x22, 0xb4, 0x16, 0xa4, + 0x84, 0xad, 0x2a, 0xd8, 0x32, 0x71, 0xb6, 0xaa, 0xca, 0x26, 0x48, 0xd1, 0x3b, 0xb4, 0xf2, 0x89, + 0xf3, 0x31, 0x2f, 0xb6, 0x94, 0x54, 0x58, 0xc0, 0x19, 0x43, 0x62, 0xf4, 0x00, 0x8a, 0xa1, 0xa0, + 0x88, 0x5c, 0x45, 0x8a, 0x1c, 0x89, 0xab, 0x3b, 0x89, 0x01, 0xd5, 0x44, 0x92, 0xab, 0xcb, 0x7b, + 0x60, 0x75, 0x7a, 0xa5, 0x78, 0x26, 0xb7, 0x2b, 0xf7, 0xa1, 0x32, 0xa5, 0xe7, 0x3a, 0xa6, 0xcf, + 0x97, 0xeb, 0x18, 0x1d, 0xc1, 0xcc, 0x8c, 0x11, 0xc1, 0x94, 0xff, 0x40, 0x83, 0x22, 0xdf, 0x5f, + 0x1a, 0x6d, 0x7c, 0x91, 0x6e, 0x2e, 0x8b, 0x19, 0x34, 0x1e, 0x33, 0x04, 0xa1, 0x19, 0xc7, 0x28, + 0x57, 0x64, 0x01, 0x39, 0xba, 0xcf, 0x76, 0x8a, 0xf1, 0x66, 0xf8, 0x5a, 0x85, 0x61, 0x9d, 0xc8, + 0x55, 0xcb, 0xcc, 0x21, 0x43, 0xf9, 0xfb, 0x39, 0x58, 0xe6, 0xa9, 0x31, 0x91, 0x60, 0xe7, 0x25, + 0x16, 0xaf, 0xc1, 0x7c, 0xeb, 0xf4, 0x64, 0xf7, 0x69, 0xd8, 0x39, 0x0b, 0x85, 0x22, 0x50, 0xa2, + 0xd8, 0x14, 0x12, 0xcc, 0x9f, 0xb9, 0x0b, 0x15, 0x88, 0x36, 0x40, 0x17, 0x7c, 0x41, 0x31, 0x3a, + 0xcb, 0x47, 0xc4, 0xe0, 0xe4, 0x34, 0xd8, 0xc2, 0x2f, 0xfc, 0xe0, 0x12, 0x9c, 0xb7, 0x90, 0x09, + 0x45, 0xf6, 0xd7, 0xd6, 0xcb, 0xc7, 0x58, 0xd4, 0x6f, 0xde, 0x95, 0x77, 0x32, 0xf1, 0x4b, 0x36, + 0x25, 0x26, 0x96, 0x32, 0x94, 0xbb, 0x41, 0x4f, 0x93, 0xca, 0x13, 0xd8, 0xdb, 0xb9, 0x77, 0xc6, + 0xe8, 0x3b, 0xca, 0x1a, 0x7d, 0x44, 0x17, 0x94, 0x30, 0xd0, 0xc8, 0xeb, 0x48, 0xdc, 0xa9, 0xf0, + 0x52, 0x45, 0x91, 0x67, 0x88, 0x63, 0x56, 0x1f, 0x80, 0x1e, 0x9d, 0x78, 0xf2, 0x53, 0x85, 0xe4, + 0xda, 0x45, 0xe5, 0xdd, 0x9d, 0x32, 0xb9, 0x51, 0xbd, 0x28, 0x69, 0xcf, 0xff, 0xd6, 0xe0, 0xaa, + 0x81, 0x3d, 0x96, 0x27, 0xfe, 0xd0, 0xf2, 0xb1, 0x7b, 0x62, 0xb9, 0xc7, 0x42, 0x46, 0xc2, 0x9d, + 0xd2, 0x94, 0x9d, 0xfa, 0x8a, 0xba, 0x53, 0x4c, 0x2a, 0xdf, 0x8e, 0xa4, 0x02, 0x92, 0xfb, 0x1c, + 0xb1, 0x5b, 0xc9, 0xab, 0x98, 0xfd, 0xdf, 0x5a, 0xc5, 0xf2, 0x3f, 0xe5, 0xd8, 0x2b, 0xc3, 0xa1, + 0xe7, 0x82, 0x4f, 0x5f, 0x74, 0x7c, 0xfa, 0xa2, 0x63, 0xbc, 0x17, 0x1d, 0xff, 0x90, 0xe1, 0xaf, + 0xbd, 0x49, 0x38, 0xf7, 0x20, 0x38, 0x26, 0x32, 0x93, 0xbf, 0x1e, 0x73, 0xb0, 0x34, 0x98, 0xa3, + 0x24, 0x6a, 0x30, 0xc7, 0x6c, 0xea, 0x83, 0x20, 0x1c, 0xcc, 0x0c, 0xe3, 0x4f, 0x0d, 0x06, 0xdb, + 0x50, 0x94, 0x3a, 0x4f, 0xb8, 0x0d, 0xd9, 0x54, 0x83, 0xc1, 0xd4, 0xa7, 0xb5, 0xb2, 0xd9, 0x69, + 0x8f, 0x8a, 0x30, 0x47, 0x75, 0x9a, 0x74, 0x58, 0xf9, 0xcf, 0xbc, 0x5a, 0x92, 0x92, 0xa8, 0x85, + 0xef, 0x2a, 0x2e, 0x35, 0xf1, 0xe8, 0x1f, 0xa2, 0x45, 0xe4, 0x21, 0x3b, 0xe1, 0x7b, 0xc1, 0x81, + 0x8d, 0x47, 0x9e, 0x8b, 0x09, 0xc7, 0x34, 0x51, 0x60, 0x21, 0x8e, 0x76, 0x6f, 0x87, 0x1b, 0xca, + 0x0f, 0x3a, 0x4b, 0x49, 0xdb, 0x10, 0x4a, 0x39, 0xdf, 0xfc, 0x7b, 0x41, 0x4e, 0x85, 0x5f, 0xbf, + 0x2c, 0x26, 0x64, 0x52, 0xc4, 0x60, 0x22, 0xfb, 0x72, 0x47, 0x14, 0xd2, 0xb2, 0x94, 0xb6, 0x72, + 0xb5, 0x28, 0x8a, 0xa7, 0x94, 0x72, 0xda, 0x16, 0xd7, 0x75, 0x7e, 0x3b, 0xc4, 0x0b, 0x7a, 0x66, + 0x28, 0xf7, 0x5a, 0xf4, 0x62, 0x52, 0xa5, 0x32, 0x12, 0x38, 0x51, 0x3d, 0x52, 0x6b, 0xc3, 0x15, + 0x7b, 0xe4, 0x1d, 0x67, 0xa4, 0x42, 0x47, 0xf8, 0x8d, 0x2e, 0x7f, 0xa3, 0xc0, 0x5b, 0xe8, 0xb1, + 0xea, 0x37, 0x80, 0x8a, 0xf5, 0x1b, 0x69, 0x85, 0x47, 0x23, 0x5c, 0xc5, 0x7d, 0xf9, 0xec, 0xc4, + 0x2f, 0xe3, 0x57, 0x92, 0x4f, 0x4c, 0xe2, 0xb2, 0x4c, 0x3a, 0x6b, 0xc9, 0xa9, 0xec, 0xd9, 0xc9, + 0x5e, 0xe1, 0x26, 0xd5, 0x47, 0xce, 0xa5, 0xd7, 0x47, 0x6e, 0x27, 0x05, 0x20, 0xf3, 0x23, 0x0d, + 0x66, 0x42, 0x88, 0x71, 0x1f, 0xae, 0xc6, 0x5d, 0xe0, 0x1e, 0xee, 0x77, 0xed, 0xfe, 0x11, 0xcd, + 0xac, 0xe7, 0x8d, 0x74, 0x02, 0xb4, 0x05, 0xd7, 0x15, 0x77, 0x4c, 0x1d, 0xb4, 0x74, 0xf0, 0x61, + 0x4f, 0x7f, 0x87, 0xd2, 0x90, 0x03, 0x6f, 0xc2, 0x00, 0xf4, 0xc2, 0x2f, 0x78, 0x02, 0x3c, 0x84, + 0x02, 0xbd, 0x07, 0xd7, 0xe2, 0xd8, 0xe0, 0xd5, 0x8a, 0x48, 0xd1, 0x0f, 0x21, 0x39, 0xb7, 0xc3, + 0xff, 0xb6, 0x06, 0xb3, 0xf2, 0x51, 0x22, 0xf1, 0x30, 0x7b, 0x1d, 0x0a, 0xec, 0x02, 0x4d, 0x54, + 0x5e, 0x14, 0x8c, 0x10, 0x80, 0x4a, 0x30, 0xa3, 0x7a, 0x79, 0xd1, 0x94, 0xee, 0x39, 0x72, 0xca, + 0x3d, 0xc7, 0x2a, 0xe4, 0x6b, 0xce, 0xc7, 0x7d, 0x8a, 0x99, 0xa2, 0x98, 0xa0, 0x5d, 0xfe, 0xb3, + 0x32, 0xe8, 0x42, 0xb7, 0x83, 0xd7, 0x53, 0xc1, 0x5b, 0x29, 0x4d, 0x7e, 0x2b, 0x95, 0x94, 0xb0, + 0x09, 0x43, 0xb4, 0xac, 0x12, 0xa2, 0xed, 0xaa, 0xaa, 0xc6, 0x8e, 0x69, 0x9f, 0x4b, 0x32, 0x28, + 0xc1, 0xa3, 0xa8, 0xe1, 0xea, 0x96, 0xf4, 0xbb, 0x14, 0xbf, 0x76, 0x7b, 0xd5, 0x05, 0x3d, 0x72, + 0x33, 0x2e, 0xae, 0xed, 0xee, 0x0e, 0xfd, 0xd4, 0x28, 0x93, 0xec, 0x3e, 0x63, 0x3d, 0xa2, 0x86, + 0x7c, 0x04, 0x63, 0x3f, 0xa9, 0xf5, 0xd9, 0xa1, 0xdd, 0x07, 0xd4, 0x6c, 0x1d, 0x43, 0x6e, 0xd9, + 0x2d, 0xc0, 0xd8, 0x6e, 0x41, 0x72, 0x5c, 0xc5, 0x33, 0x39, 0xae, 0xd9, 0x09, 0x1c, 0x57, 0xc4, + 0xcd, 0xce, 0x4d, 0xec, 0x66, 0x63, 0x3e, 0x64, 0xfe, 0x4c, 0x3e, 0x44, 0x35, 0xef, 0x97, 0x27, + 0x34, 0xef, 0xb1, 0x2c, 0x83, 0x7e, 0x96, 0x2c, 0x43, 0x8a, 0xb1, 0x5f, 0x98, 0xd0, 0xd8, 0xa3, + 0x0b, 0x37, 0xf6, 0x8b, 0xe7, 0x35, 0xf6, 0x4b, 0xe7, 0x36, 0xf6, 0xcb, 0xe7, 0x35, 0xf6, 0x2b, + 0x23, 0x8d, 0x3d, 0x7a, 0x3b, 0x56, 0xc7, 0x26, 0xea, 0x49, 0xd8, 0x8d, 0x63, 0x0a, 0x36, 0xe1, + 0x88, 0x11, 0x56, 0xa9, 0x94, 0x12, 0x8f, 0x18, 0x61, 0xd1, 0xca, 0xd7, 0x61, 0x29, 0x82, 0x13, + 0xb7, 0x8b, 0xb1, 0x43, 0x6e, 0x4c, 0xef, 0x93, 0x18, 0x99, 0x09, 0x48, 0xec, 0x13, 0x0d, 0x62, + 0xdf, 0x57, 0x6d, 0x89, 0xdb, 0xc8, 0x58, 0x82, 0x62, 0xd4, 0x68, 0x9c, 0x95, 0x8d, 0x97, 0xd2, + 0x6f, 0xc2, 0x88, 0x66, 0x4b, 0x5c, 0x61, 0x4e, 0x3c, 0xa2, 0x39, 0x6c, 0x44, 0x8e, 0x44, 0xdb, + 0x70, 0x33, 0x82, 0xe1, 0x45, 0x4f, 0x5e, 0xc5, 0xf3, 0xec, 0xa3, 0x3e, 0xee, 0xd2, 0xbb, 0xcf, + 0xbc, 0x31, 0x8a, 0x0c, 0x35, 0xe1, 0x95, 0xe8, 0x57, 0x05, 0xc5, 0x4f, 0x41, 0x5f, 0x37, 0x68, + 0x5f, 0xa3, 0x09, 0x53, 0x8f, 0x92, 0xa1, 0xa4, 0xac, 0x0d, 0x39, 0x4a, 0x86, 0xf2, 0xb2, 0x95, + 0x52, 0xfd, 0x23, 0x24, 0xf5, 0x66, 0xfc, 0x6e, 0x3c, 0x4a, 0x93, 0x7a, 0x8f, 0xc0, 0xb2, 0xc9, + 0xeb, 0x54, 0x57, 0x87, 0x50, 0xa0, 0x47, 0xb0, 0x9e, 0x78, 0x6f, 0x2e, 0x17, 0x51, 0xbd, 0x42, + 0xe7, 0x31, 0x92, 0x6e, 0x8c, 0x9a, 0x81, 0xf2, 0x58, 0x35, 0x03, 0xdf, 0xd4, 0xe0, 0x46, 0xe2, + 0x94, 0x69, 0xfa, 0x82, 0x48, 0xdc, 0xab, 0x54, 0xe2, 0xde, 0x1d, 0x2a, 0x71, 0x43, 0x7b, 0x60, + 0x82, 0x37, 0x7c, 0x14, 0xf4, 0x7b, 0x69, 0xe5, 0x59, 0x42, 0xd5, 0x6e, 0xd1, 0x69, 0x3c, 0x98, + 0x7c, 0x1a, 0x8a, 0xc2, 0x0d, 0x1d, 0x03, 0x7d, 0x4b, 0x4b, 0xb9, 0x78, 0xa0, 0x2e, 0x8b, 0xcd, + 0xe3, 0x33, 0x74, 0x1e, 0x95, 0xc9, 0xe7, 0x11, 0xf6, 0xc1, 0xa6, 0x32, 0x6a, 0x24, 0xf4, 0x87, + 0x5a, 0x8a, 0xec, 0x57, 0x5b, 0xbc, 0x66, 0xad, 0xf4, 0x1a, 0x9d, 0xcc, 0x7b, 0x67, 0x59, 0x14, + 0xde, 0x05, 0x9b, 0xcb, 0x88, 0x71, 0xd0, 0x77, 0x34, 0x78, 0x25, 0x7d, 0xba, 0x62, 0x36, 0xaf, + 0xd3, 0xd9, 0x54, 0xcf, 0xb8, 0x34, 0xca, 0x84, 0x46, 0x8f, 0x96, 0xaa, 0xd1, 0xc2, 0xf9, 0xde, + 0x1e, 0xa2, 0xd1, 0xc2, 0xff, 0x7e, 0x57, 0x83, 0xf2, 0xd0, 0x4f, 0x67, 0x25, 0x7b, 0x6f, 0xd0, + 0x0f, 0xab, 0x9d, 0x7d, 0x99, 0x69, 0x37, 0xec, 0xcb, 0xc6, 0x18, 0x0f, 0x7d, 0x5f, 0x83, 0xcf, + 0x8c, 0x5a, 0x00, 0x36, 0xb3, 0x0d, 0x3a, 0xb3, 0x87, 0xe7, 0x5a, 0x72, 0x69, 0x72, 0xe3, 0x8d, + 0x7a, 0xee, 0xa4, 0xf8, 0x47, 0xb0, 0x9c, 0x18, 0xda, 0x4f, 0x98, 0xa7, 0x52, 0xde, 0x8e, 0x49, + 0xdd, 0xdf, 0xa7, 0x3f, 0x52, 0x97, 0x92, 0x54, 0x1b, 0x39, 0xb9, 0x87, 0x70, 0x35, 0x35, 0x40, + 0x18, 0xd5, 0x51, 0x5e, 0xee, 0xa8, 0x11, 0x2b, 0x61, 0x90, 0x4d, 0xd1, 0x39, 0xbb, 0x32, 0xcf, + 0xda, 0xd5, 0x5e, 0x8a, 0xc4, 0x2b, 0xd6, 0x7a, 0xa2, 0x1e, 0x77, 0x53, 0x6c, 0xc3, 0x99, 0xbf, + 0xd6, 0x80, 0x5b, 0xe3, 0x58, 0xd0, 0x89, 0xfa, 0xfc, 0x00, 0x5e, 0x1d, 0xc3, 0x10, 0x4e, 0x24, + 0x28, 0x26, 0xbc, 0x36, 0x9e, 0x35, 0x9b, 0xa8, 0xd7, 0x7d, 0x78, 0x7d, 0x4c, 0x53, 0x32, 0x51, + 0xb7, 0x5f, 0x81, 0x8d, 0xf1, 0xed, 0xc0, 0x44, 0xa9, 0x9a, 0x06, 0xab, 0x06, 0x12, 0xbf, 0x07, + 0x79, 0x8e, 0x5f, 0x34, 0x2a, 0xff, 0x75, 0x06, 0x96, 0x92, 0x9e, 0x55, 0x0e, 0x79, 0xdd, 0xb0, + 0x17, 0xfb, 0xf5, 0xcf, 0xcd, 0x51, 0x8f, 0x34, 0xd5, 0x5f, 0x01, 0x8d, 0x5d, 0xcc, 0x5c, 0xc8, + 0x6f, 0x81, 0xae, 0x9a, 0xa3, 0x7f, 0xac, 0x73, 0x58, 0xb9, 0x90, 0xb4, 0xa2, 0xf2, 0x5a, 0xff, + 0x50, 0x03, 0xd8, 0xb2, 0x3a, 0xc7, 0xa7, 0x03, 0x7a, 0xb7, 0x93, 0x76, 0xf1, 0xd7, 0x48, 0xba, + 0xf8, 0x7b, 0x5d, 0x79, 0xd1, 0x11, 0x74, 0x32, 0x3c, 0x9f, 0x74, 0xee, 0x44, 0xde, 0xef, 0x6b, + 0xe2, 0xde, 0xaa, 0xe1, 0xe3, 0x93, 0xc4, 0x1f, 0x57, 0x29, 0xc3, 0x2c, 0xaf, 0x66, 0x7f, 0x22, + 0xdd, 0x7e, 0x2a, 0x30, 0x42, 0x53, 0xc3, 0x4f, 0xad, 0xd3, 0x1e, 0xa7, 0x61, 0x19, 0x3d, 0x05, + 0x46, 0xb6, 0xa8, 0xd1, 0xf7, 0xb1, 0xdb, 0xb7, 0x7a, 0xfc, 0xc2, 0x2e, 0x68, 0x97, 0xff, 0x46, + 0x93, 0xaf, 0xcf, 0xd0, 0x97, 0x61, 0xa6, 0xea, 0xf4, 0x7d, 0x4c, 0x7f, 0x83, 0x24, 0x5e, 0x3e, + 0x1e, 0x10, 0x6e, 0x72, 0x2a, 0xb6, 0x30, 0x82, 0x67, 0xd5, 0xa0, 0x6f, 0x08, 0x03, 0xc4, 0x84, + 0x05, 0x3c, 0xe1, 0x72, 0xc8, 0x0b, 0xf5, 0xbb, 0xe1, 0x3d, 0x1d, 0x7a, 0x2b, 0x7c, 0x61, 0x1b, + 0xab, 0x53, 0x13, 0x44, 0x9b, 0x94, 0x82, 0x4d, 0x8c, 0x51, 0xaf, 0xbe, 0x03, 0x10, 0x02, 0x27, + 0xba, 0x5f, 0x7e, 0x5d, 0x79, 0xd8, 0x3f, 0xe4, 0xe5, 0xd1, 0x47, 0xb0, 0x10, 0x7b, 0xe3, 0x82, + 0x6e, 0xc1, 0x1c, 0xfb, 0xad, 0x20, 0xf1, 0x6c, 0x86, 0x31, 0xa9, 0x40, 0xba, 0xcd, 0x9c, 0x45, + 0xfa, 0x7d, 0x29, 0x05, 0xb6, 0xf1, 0x31, 0xc0, 0xfe, 0xa0, 0x6b, 0xf9, 0x2c, 0x83, 0x7b, 0x05, + 0x16, 0x95, 0xdf, 0x1e, 0x62, 0x28, 0xfd, 0x12, 0x5a, 0x86, 0x05, 0xf1, 0x9b, 0x52, 0xcd, 0x76, + 0x8b, 0x83, 0x35, 0xb4, 0x08, 0x97, 0xf7, 0x3d, 0xec, 0xd2, 0xcf, 0xe7, 0xc0, 0x0c, 0x9a, 0x83, + 0x82, 0xd9, 0xde, 0xe5, 0xcd, 0x2c, 0x61, 0x0d, 0x7e, 0x1f, 0x2a, 0x60, 0xcd, 0x6d, 0x6c, 0x42, + 0x21, 0xf8, 0x25, 0x66, 0x74, 0x19, 0x8a, 0x2d, 0xc7, 0x3d, 0xb1, 0x7a, 0xb4, 0xa9, 0x5f, 0x42, + 0x3a, 0xcc, 0xf2, 0x47, 0x1a, 0x0c, 0xa2, 0x6d, 0xfc, 0x22, 0x07, 0x10, 0xbe, 0xc9, 0x47, 0xf3, + 0x00, 0x66, 0x7b, 0xf7, 0x60, 0x7f, 0xaf, 0x56, 0x31, 0xeb, 0xfa, 0x25, 0x04, 0x30, 0x5d, 0xd9, + 0xdb, 0xab, 0xb7, 0x6a, 0xba, 0x86, 0xf2, 0x90, 0x33, 0xea, 0x95, 0x9a, 0x9e, 0x41, 0xb3, 0x90, + 0x37, 0x8d, 0xfd, 0x56, 0x95, 0xd0, 0x64, 0x49, 0xa7, 0x0f, 0xeb, 0xe6, 0x41, 0x00, 0xc9, 0xa1, + 0x22, 0xcc, 0x54, 0x77, 0x5b, 0xad, 0x7a, 0xd5, 0xd4, 0xa7, 0x48, 0x97, 0xbc, 0x71, 0x60, 0xec, + 0xea, 0xd3, 0x68, 0x01, 0xe6, 0x9a, 0xbb, 0x0f, 0x0f, 0xb6, 0xeb, 0x15, 0xc3, 0xdc, 0xaa, 0x57, + 0x4c, 0x7d, 0x86, 0xf4, 0x50, 0x6d, 0x49, 0x90, 0x3c, 0x9d, 0xa8, 0x0c, 0x29, 0x20, 0x04, 0xf3, + 0xd5, 0xed, 0x7a, 0xf5, 0xf1, 0xc1, 0x76, 0xe5, 0x71, 0xbd, 0xbe, 0x57, 0x37, 0x74, 0x20, 0xeb, + 0x4a, 0x46, 0xae, 0x36, 0xf7, 0xdb, 0x66, 0xdd, 0x38, 0xa8, 0xd5, 0xcd, 0x4a, 0xa3, 0xd9, 0xd6, + 0x8b, 0x84, 0x98, 0x20, 0xda, 0xdb, 0x15, 0xa3, 0x76, 0xd0, 0x68, 0xbd, 0xbf, 0xab, 0xcf, 0xd2, + 0x0e, 0x5a, 0x07, 0x95, 0x66, 0x73, 0x97, 0xcc, 0xf2, 0xa0, 0x51, 0xd3, 0xe7, 0xc8, 0x22, 0xca, + 0x1d, 0xb4, 0x4d, 0x32, 0xff, 0x79, 0xba, 0xfe, 0x74, 0x05, 0x0e, 0xaa, 0xad, 0x83, 0x66, 0x65, + 0xab, 0xde, 0xd4, 0x2f, 0xa3, 0x12, 0x2c, 0x85, 0xc0, 0x0f, 0x77, 0x8d, 0xc7, 0x9c, 0x5c, 0x27, + 0x3d, 0xef, 0x55, 0xcc, 0xea, 0x36, 0x41, 0xb4, 0xcd, 0x5d, 0xa3, 0xae, 0x2f, 0x90, 0x2e, 0x6a, + 0xf5, 0x66, 0x9d, 0x51, 0x33, 0x20, 0x22, 0xc0, 0x3d, 0x63, 0xf7, 0x2b, 0x5f, 0x95, 0x3e, 0x6c, + 0x11, 0xbd, 0x02, 0x37, 0x78, 0xbf, 0xad, 0xdd, 0xd6, 0xc1, 0x93, 0x5d, 0xb3, 0xd1, 0x7a, 0x78, + 0x60, 0xd4, 0xf7, 0x9a, 0x8d, 0x6a, 0xe5, 0xa0, 0xb5, 0xbf, 0xa3, 0x2f, 0xa1, 0x35, 0x58, 0x8d, + 0x93, 0x90, 0xef, 0x68, 0x36, 0xcc, 0xaf, 0xea, 0xcb, 0x68, 0x09, 0xf4, 0x76, 0xdd, 0x3c, 0x30, + 0xea, 0x1f, 0xec, 0x37, 0x8c, 0x7a, 0xed, 0xa0, 0xd9, 0x6e, 0xe9, 0x2b, 0x04, 0xfa, 0x30, 0x0a, + 0xbd, 0x22, 0x96, 0xa6, 0x59, 0x31, 0xeb, 0x6d, 0x93, 0xc2, 0x4a, 0x64, 0x4b, 0x28, 0xac, 0x5e, + 0xa9, 0xd5, 0x0d, 0xb2, 0x32, 0x57, 0xe9, 0x96, 0xb0, 0xe5, 0xae, 0x57, 0x9a, 0xe6, 0xb6, 0xbe, + 0x4a, 0x36, 0x9d, 0x6c, 0x3f, 0x65, 0xb9, 0x86, 0xae, 0xc2, 0x32, 0x9f, 0x52, 0xb3, 0x5e, 0x69, + 0xd7, 0xb7, 0x77, 0x9b, 0x9c, 0xf5, 0x3a, 0x41, 0xd1, 0xc5, 0xaf, 0x6e, 0xd7, 0x6b, 0xfb, 0xcd, + 0xfa, 0x41, 0x75, 0x77, 0x67, 0xa7, 0xd2, 0xaa, 0xb5, 0xf5, 0x1b, 0x1b, 0x2d, 0x80, 0xf0, 0x97, + 0xac, 0x88, 0x64, 0x10, 0x31, 0x67, 0x10, 0xfd, 0x12, 0x19, 0x41, 0xd8, 0x39, 0x5d, 0x23, 0xc2, + 0x4b, 0x95, 0x26, 0x50, 0x80, 0x05, 0xfe, 0xd3, 0x6d, 0x06, 0xfe, 0x3a, 0xee, 0xf8, 0xb8, 0xab, + 0x67, 0x37, 0x36, 0xa0, 0x10, 0xfc, 0x50, 0x12, 0x61, 0x6f, 0x63, 0x9f, 0xb6, 0xf4, 0x4b, 0x84, + 0x9d, 0x25, 0x57, 0x19, 0x40, 0xdb, 0xf8, 0xc7, 0x1c, 0x20, 0x71, 0xa4, 0x90, 0x74, 0x93, 0x48, + 0xbc, 0xdd, 0x39, 0x96, 0x55, 0x52, 0xfa, 0x45, 0x9a, 0x40, 0x25, 0x89, 0xa6, 0xc6, 0xc0, 0x19, + 0xb4, 0x42, 0xeb, 0x47, 0xa2, 0xf0, 0x2c, 0x19, 0xfd, 0x21, 0xf6, 0x03, 0x4d, 0xcf, 0x91, 0x45, + 0x89, 0xd8, 0x1b, 0x8e, 0x9a, 0x22, 0x3b, 0xd2, 0xc6, 0x4c, 0x21, 0x39, 0x6c, 0x9a, 0x08, 0x9b, + 0x5a, 0x20, 0xc4, 0x31, 0x33, 0xe8, 0x26, 0x5c, 0x6b, 0x63, 0x3f, 0x7e, 0x37, 0xc1, 0x09, 0xf2, + 0x68, 0x15, 0x56, 0x38, 0x41, 0x90, 0xdc, 0xe6, 0xb8, 0x02, 0x59, 0x42, 0xf6, 0x37, 0x5f, 0x35, + 0x1d, 0xc8, 0x87, 0x09, 0x50, 0xf0, 0x3c, 0x48, 0x2f, 0x92, 0xfd, 0xdf, 0x23, 0xf6, 0x8e, 0x57, + 0xf0, 0xe9, 0xb3, 0x84, 0xd7, 0xc0, 0x27, 0xce, 0x73, 0xf1, 0x5a, 0x54, 0x9f, 0x23, 0xb3, 0x54, + 0x4b, 0x35, 0xf9, 0x40, 0xf3, 0xe8, 0x06, 0x5c, 0x65, 0x7f, 0x27, 0x24, 0xad, 0xf5, 0xcb, 0xe8, + 0x1a, 0x5c, 0x89, 0xa0, 0x85, 0x37, 0x60, 0xea, 0x24, 0x4e, 0x3d, 0xbc, 0xbf, 0x05, 0x74, 0x1d, + 0x4a, 0xf1, 0x12, 0x1f, 0x8e, 0x45, 0xe8, 0x16, 0xac, 0x8b, 0x24, 0x6e, 0x3c, 0xbd, 0xcb, 0xa9, + 0x16, 0xc9, 0xca, 0xb1, 0x04, 0x58, 0xe4, 0x04, 0xc2, 0x09, 0x96, 0xd0, 0x67, 0xe0, 0x15, 0x46, + 0x90, 0x18, 0x60, 0x72, 0xb2, 0xe5, 0x8d, 0xef, 0x69, 0x30, 0xa7, 0xdc, 0x36, 0x11, 0xbd, 0x16, + 0x00, 0x5e, 0xe5, 0xa2, 0x5f, 0x22, 0x3b, 0x2e, 0x80, 0xca, 0x9b, 0x7f, 0x5d, 0x23, 0x03, 0xc5, + 0x50, 0xe2, 0xfc, 0x68, 0xe0, 0x0e, 0xb6, 0x9f, 0xe3, 0xae, 0x9e, 0x21, 0xab, 0x14, 0x23, 0x7b, + 0xdf, 0xb2, 0x7b, 0x44, 0xf4, 0xe5, 0x31, 0x8d, 0xd3, 0x7e, 0x9f, 0x74, 0x9c, 0xdb, 0x38, 0x4c, + 0xba, 0xef, 0x22, 0xdb, 0xa4, 0x40, 0xc3, 0x39, 0x46, 0x31, 0xa2, 0x27, 0x2d, 0x86, 0x69, 0xfb, + 0xce, 0x60, 0x40, 0x66, 0xb5, 0xf1, 0x13, 0x0d, 0xf4, 0xe8, 0xaf, 0x3c, 0x10, 0x2d, 0xaa, 0x74, + 0xc5, 0x0f, 0xaf, 0xe9, 0x97, 0x42, 0x61, 0x11, 0x20, 0x8d, 0x48, 0x54, 0xdb, 0xb7, 0x5c, 0x5f, + 0x40, 0x32, 0x44, 0x49, 0x48, 0xb7, 0x02, 0x90, 0x25, 0xbd, 0x3c, 0xb6, 0x7b, 0xbd, 0xaf, 0x39, + 0x27, 0x87, 0x36, 0x51, 0x9a, 0x2b, 0xb0, 0x58, 0xe9, 0x76, 0xa3, 0x22, 0xa4, 0x4f, 0x11, 0x19, + 0x67, 0xdd, 0xc7, 0x70, 0xd3, 0x54, 0xd3, 0xc8, 0x38, 0x31, 0xd4, 0x0c, 0xf9, 0x28, 0x32, 0x60, + 0x0c, 0x93, 0xdf, 0xd8, 0x51, 0x5e, 0xbf, 0x93, 0x89, 0x84, 0x82, 0xa4, 0x5f, 0xa2, 0xbe, 0xb7, + 0x25, 0x9a, 0x1a, 0x69, 0x56, 0x83, 0x66, 0x86, 0xea, 0x0a, 0xbd, 0x0a, 0xe2, 0x90, 0xec, 0x56, + 0xe3, 0xc7, 0x3f, 0x5f, 0xbb, 0xf4, 0xa3, 0x4f, 0xd6, 0xb4, 0x1f, 0x7f, 0xb2, 0xa6, 0xfd, 0xec, + 0x93, 0xb5, 0x4b, 0x3f, 0xf8, 0x8f, 0x35, 0xed, 0x6b, 0xf7, 0xa4, 0xff, 0x86, 0xe8, 0xc4, 0xf2, + 0x5d, 0xfb, 0x85, 0x43, 0x03, 0x0b, 0xd1, 0xe8, 0xe3, 0x3b, 0x83, 0xe3, 0xa3, 0x3b, 0x83, 0xc3, + 0x3b, 0x61, 0x98, 0x74, 0x38, 0x4d, 0x7f, 0x25, 0xef, 0xde, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, + 0xdd, 0xff, 0x44, 0x7a, 0xe2, 0x68, 0x00, 0x00, } func (m *CNStore) Marshal() (dAtA []byte, err error) { @@ -7282,6 +7311,16 @@ func (m *LogStore) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityDeployedProtocolSupported { + i-- + if m.DDLVisibilityDeployedProtocolSupported { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } { size, err := m.Locality.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -7835,6 +7874,16 @@ func (m *LogStoreHeartbeat) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityDeployedProtocolSupported { + i-- + if m.DDLVisibilityDeployedProtocolSupported { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 + } if m.ViewMetadataAdmissionSupported { i-- if m.ViewMetadataAdmissionSupported { @@ -11028,6 +11077,16 @@ func (m *LogStoreInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityDeployedProtocolSupported { + i-- + if m.DDLVisibilityDeployedProtocolSupported { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 + } if m.ViewMetadataAdmissionSupported { i-- if m.ViewMetadataAdmissionSupported { @@ -12598,6 +12657,9 @@ func (m *LogStore) ProtoSize() (n int) { } l = m.Locality.ProtoSize() n += 1 + l + sovLogservice(uint64(l)) + if m.DDLVisibilityDeployedProtocolSupported { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -12850,6 +12912,9 @@ func (m *LogStoreHeartbeat) ProtoSize() (n int) { if m.ViewMetadataAdmissionSupported { n += 2 } + if m.DDLVisibilityDeployedProtocolSupported { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -14233,6 +14298,9 @@ func (m *LogStoreInfo) ProtoSize() (n int) { if m.ViewMetadataAdmissionSupported { n += 2 } + if m.DDLVisibilityDeployedProtocolSupported { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -16060,6 +16128,26 @@ func (m *LogStore) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityDeployedProtocolSupported", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityDeployedProtocolSupported = bool(v != 0) default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -17812,6 +17900,26 @@ func (m *LogStoreHeartbeat) Unmarshal(dAtA []byte) error { } } m.ViewMetadataAdmissionSupported = bool(v != 0) + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityDeployedProtocolSupported", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityDeployedProtocolSupported = bool(v != 0) default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -27060,6 +27168,26 @@ func (m *LogStoreInfo) Unmarshal(dAtA []byte) error { } } m.ViewMetadataAdmissionSupported = bool(v != 0) + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityDeployedProtocolSupported", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityDeployedProtocolSupported = bool(v != 0) default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) diff --git a/pkg/pb/logservice/logservice_test.go b/pkg/pb/logservice/logservice_test.go index 2dc840d28f317..0116c319e9e3d 100644 --- a/pkg/pb/logservice/logservice_test.go +++ b/pkg/pb/logservice/logservice_test.go @@ -163,11 +163,12 @@ func TestLogStateUpdateStores(t *testing.T) { } hb1 := LogStoreHeartbeat{ - UUID: "log-a", - RaftAddress: "raft-a", - ServiceAddress: "addr-a", - GossipAddress: "gossip-a", - CommandDeliverySupported: true, + UUID: "log-a", + RaftAddress: "raft-a", + ServiceAddress: "addr-a", + GossipAddress: "gossip-a", + CommandDeliverySupported: true, + DDLVisibilityDeployedProtocolSupported: true, Replicas: []LogReplicaInfo{{ LogShardInfo: LogShardInfo{ ShardID: 1, @@ -182,12 +183,13 @@ func TestLogStateUpdateStores(t *testing.T) { tick1 := uint64(100) state.Update(hb1, tick1) assert.Equal(t, state.Stores[hb1.UUID], LogStoreInfo{ - Tick: tick1, - RaftAddress: hb1.RaftAddress, - ServiceAddress: hb1.ServiceAddress, - GossipAddress: hb1.GossipAddress, - Replicas: hb1.Replicas, - CommandDeliverySupported: true, + Tick: tick1, + RaftAddress: hb1.RaftAddress, + ServiceAddress: hb1.ServiceAddress, + GossipAddress: hb1.GossipAddress, + Replicas: hb1.Replicas, + CommandDeliverySupported: true, + DDLVisibilityDeployedProtocolSupported: true, }) hb2 := LogStoreHeartbeat{ diff --git a/proto/logservice.proto b/proto/logservice.proto index 45b01659edee4..1146cca822db7 100644 --- a/proto/logservice.proto +++ b/proto/logservice.proto @@ -98,6 +98,9 @@ message LogStore { repeated LogReplicaInfo Replicas = 5 [(gogoproto.nullable) = false]; ConfigData ConfigData = 6; Locality Locality = 7 [(gogoproto.nullable) = false]; + // DDLVisibilityDeployedProtocolSupported proves the hosted HAKeeper RSM can + // persist and return the cluster-wide DDL deployment epoch. + bool DDLVisibilityDeployedProtocolSupported = 8; } // LogShardInfo contains information a log shard. @@ -211,6 +214,9 @@ message LogStoreHeartbeat { // ViewMetadataAdmissionSupported proves that every HAKeeper RSM hosted by // this LogStore can decode the durable admission update and snapshot fields. bool ViewMetadataAdmissionSupported = 10; + // This gates the HAKeeper RSM schema used by the durable DDL deployment + // epoch across both voting and non-voting replicas. + bool DDLVisibilityDeployedProtocolSupported = 11; }; // TNShardInfo contains information of a launched TN shard. @@ -814,6 +820,7 @@ message LogStoreInfo { Locality Locality = 8 [(gogoproto.nullable) = false]; bool CommandDeliverySupported = 9; bool ViewMetadataAdmissionSupported = 10; + bool DDLVisibilityDeployedProtocolSupported = 11; } message LogState { From 4b6c44a49650ab7d1e61d7d9fb5cada20984ffdf Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sun, 30 Aug 2026 16:25:32 +0800 Subject: [PATCH 17/34] fix: atomically commit DDL activation membership --- pkg/cnservice/server_ddl_visibility.go | 45 +- pkg/cnservice/server_ddl_visibility_test.go | 46 +- pkg/pb/logservice/logservice.go | 32 +- pkg/pb/logservice/logservice.pb.go | 1219 ++++++++++++------- pkg/pb/logservice/logservice_test.go | 71 +- proto/logservice.proto | 10 + 6 files changed, 944 insertions(+), 479 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index db7487fbde765..5ed7f26d1f594 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -24,6 +24,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/common/moerr" moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" "github.com/matrixorigin/matrixone/pkg/defines" + logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" "github.com/matrixorigin/matrixone/pkg/pb/metadata" "github.com/matrixorigin/matrixone/pkg/pb/query" "github.com/matrixorigin/matrixone/pkg/pb/timestamp" @@ -342,7 +343,11 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets // CN may have joined after dispatch; committing without it would reopen an // un-fenced legacy producer. The join either appears here and aborts this cut, // or its atomic ingress heartbeat observes the already committed epoch. - if err := s.revalidateDDLVisibilityActivationMembership(barrierCtx, activationTargets); err != nil { + commitTargets, err := s.revalidateDDLVisibilityActivationMembership(barrierCtx, activationTargets) + if err != nil { + return err + } + if err := s.commitDDLVisibilityClusterEpoch(barrierCtx, version, commitTargets); err != nil { return err } // Commit the deployed cut before reopening ingress. A failure leaves the @@ -374,7 +379,9 @@ func (s *service) loadDDLVisibilityDeployedProtocol() int64 { func (s *service) persistDDLVisibilityDeployedProtocol(version int64) error { if s.metadataFS == nil { - // Focused service tests may omit the local metadata file service. + // Focused service tests may omit the local metadata file service, but the + // process-local state must still model the committed heartbeat that follows. + s.metadata.DDLVisibilityDeployedProtocol = version return nil } previous := s.metadata.DDLVisibilityDeployedProtocol @@ -389,11 +396,12 @@ func (s *service) persistDDLVisibilityDeployedProtocol(version int64) error { func (s *service) revalidateDDLVisibilityActivationMembership( ctx context.Context, targets map[string]struct{}, -) error { +) ([]logservicepb.DDLVisibilityActivationTarget, error) { details, err := s._hakeeperClient.GetClusterDetails(ctx) if err != nil { - return moerr.AttachCause(ctx, err) + return nil, moerr.AttachCause(ctx, err) } + commitTargets := make([]logservicepb.DDLVisibilityActivationTarget, 0, len(targets)) seen := 0 for _, cn := range details.CNStores { if cn.QueryAddress == "" || cn.ViewMetadataAdmissionGeneration == 0 { @@ -401,18 +409,41 @@ func (s *service) revalidateDDLVisibilityActivationMembership( } seen++ if _, ok := targets[cn.UUID]; !ok { - return moerr.NewInvalidStateNoCtx(fmt.Sprintf( + return nil, moerr.NewInvalidStateNoCtx(fmt.Sprintf( "DDL visibility activation membership changed: authoritative CN %s is not fenced", cn.UUID)) } if !cn.DDLVisibilityBarrierReady { - return moerr.NewInvalidStateNoCtx(fmt.Sprintf( + return nil, moerr.NewInvalidStateNoCtx(fmt.Sprintf( "authoritative CN %s does not support the DDL visibility activation receiver", cn.UUID)) } + commitTargets = append(commitTargets, logservicepb.DDLVisibilityActivationTarget{ + ServiceID: cn.UUID, Generation: cn.ViewMetadataAdmissionGeneration, QueryAddress: cn.QueryAddress, + }) } if seen != len(targets) { - return moerr.NewInvalidStateNoCtx(fmt.Sprintf( + return nil, moerr.NewInvalidStateNoCtx(fmt.Sprintf( "DDL visibility activation membership changed: targets=%d authoritative=%d", len(targets), seen)) } + return commitTargets, nil +} + +func (s *service) commitDDLVisibilityClusterEpoch( + ctx context.Context, + version int64, + targets []logservicepb.DDLVisibilityActivationTarget, +) error { + hb := s.newCNStoreHeartbeat() + hb.DDLVisibilityDeployedProtocol = version + hb.DDLVisibilityEpochCommitTargets = append( + []logservicepb.DDLVisibilityActivationTarget(nil), targets...) + batch, err := s._hakeeperClient.SendCNHeartbeat(ctx, hb) + if err != nil { + return moerr.AttachCause(ctx, err) + } + if batch.DDLVisibilityDeployedProtocol < version { + return moerr.NewInvalidStateNoCtx( + "DDL visibility activation membership changed before atomic cluster epoch commit") + } return nil } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 544dfdacea118..f62827e5e18d4 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -232,6 +232,27 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( } } } + if len(hb.DDLVisibilityEpochCommitTargets) > 0 { + targets := make(map[string]logservicepb.DDLVisibilityActivationTarget, + len(hb.DDLVisibilityEpochCommitTargets)) + for _, target := range hb.DDLVisibilityEpochCommitTargets { + targets[target.ServiceID] = target + } + matched := 0 + valid := len(targets) == len(hb.DDLVisibilityEpochCommitTargets) + for _, cn := range c.cluster.cnServices { + if cn.QueryAddress == "" || cn.ViewMetadataAdmissionGeneration == 0 { + continue + } + matched++ + target, ok := targets[cn.ServiceID] + valid = valid && ok && target.Generation == cn.ViewMetadataAdmissionGeneration && + target.QueryAddress == cn.QueryAddress && cn.DDLVisibilityBarrierReady + } + if valid && matched == len(targets) { + c.clusterDeployedProtocol = hb.DDLVisibilityDeployedProtocol + } + } return logservicepb.CommandBatch{ DDLVisibilityDeployedProtocol: c.clusterDeployedProtocol, }, nil @@ -442,7 +463,7 @@ func TestActivationFinalMembershipScanRejectsConcurrentJoin(t *testing.T) { DDLVisibilityBarrierReady: true}, }} s := &service{_hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}} - err := s.revalidateDDLVisibilityActivationMembership( + _, err := s.revalidateDDLVisibilityActivationMembership( context.Background(), map[string]struct{}{"target-cn": {}}) require.ErrorContains(t, err, "authoritative CN joining-cn is not fenced") } @@ -917,11 +938,13 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { query.CmdMethod_GetProtocolVersion, }, queryClient.methods) require.Equal(t, 5, queryClient.releases) - require.Len(t, hakeeperClient.heartbeats, 2) + require.Len(t, hakeeperClient.heartbeats, 3) require.True(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) require.False(t, hakeeperClient.heartbeats[0].ViewMetadataIngressReady) - require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityBarrierReady) - require.True(t, hakeeperClient.heartbeats[1].ViewMetadataIngressReady) + require.NotEmpty(t, hakeeperClient.heartbeats[1].DDLVisibilityEpochCommitTargets) + require.False(t, hakeeperClient.heartbeats[1].ViewMetadataIngressReady) + require.True(t, hakeeperClient.heartbeats[2].DDLVisibilityBarrierReady) + require.True(t, hakeeperClient.heartbeats[2].ViewMetadataIngressReady) require.Equal(t, 5, cluster.refreshCalls) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.True(t, s.viewMetadataIngressReady.Load()) @@ -930,7 +953,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { resp = &query.Response{} require.NoError(t, s.handleSetProtocolVersion(context.Background(), req, resp, nil)) require.Equal(t, defines.MORPCVersion41, resp.SetProtocolVersion.Version) - require.Len(t, hakeeperClient.heartbeats, 2) + require.Len(t, hakeeperClient.heartbeats, 3) require.Equal(t, 5, cluster.refreshCalls) require.Len(t, queryClient.requests, 5) } @@ -977,9 +1000,11 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { require.Equal(t, defines.MORPCVersion41, resp.SetProtocolVersion.Version) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) - require.Len(t, hakeeperClient.heartbeats, 2) + require.Len(t, hakeeperClient.heartbeats, 3) require.False(t, hakeeperClient.heartbeats[0].ViewMetadataIngressReady) + require.NotEmpty(t, hakeeperClient.heartbeats[1].DDLVisibilityEpochCommitTargets) require.False(t, hakeeperClient.heartbeats[1].ViewMetadataIngressReady) + require.False(t, hakeeperClient.heartbeats[2].ViewMetadataIngressReady) release, err := s.ddlCommitGate.Enter(context.Background()) require.NoError(t, err) release() @@ -1134,7 +1159,7 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond publishErr := errors.New("activation publication failed") hakeeperClient := &ddlVisibilityWithdrawalHAKeeperClient{ - cluster: cluster, sendErrors: map[int]error{2: publishErr}, + cluster: cluster, sendErrors: map[int]error{3: publishErr}, } s := &service{ cfg: cfg, @@ -1166,10 +1191,11 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing cancelBlocked() _, gateErr := s.ddlCommitGate.Enter(blockedCtx) require.ErrorIs(t, gateErr, context.Canceled) - require.Len(t, hakeeperClient.heartbeats, 3) + require.Len(t, hakeeperClient.heartbeats, 4) require.True(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) - require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityBarrierReady) - require.True(t, hakeeperClient.heartbeats[2].DDLVisibilityBarrierReady) + require.NotEmpty(t, hakeeperClient.heartbeats[1].DDLVisibilityEpochCommitTargets) + require.True(t, hakeeperClient.heartbeats[2].ViewMetadataIngressReady) + require.False(t, hakeeperClient.heartbeats[3].ViewMetadataIngressReady) require.False(t, s.viewMetadataIngressReady.Load()) require.True(t, cluster.cnServices[0].DDLVisibilityBarrierReady) require.Equal(t, 4, cluster.refreshCalls) diff --git a/pkg/pb/logservice/logservice.go b/pkg/pb/logservice/logservice.go index a19f8c7a90bfd..3277e9dfcef19 100644 --- a/pkg/pb/logservice/logservice.go +++ b/pkg/pb/logservice/logservice.go @@ -171,10 +171,38 @@ func (s *CNState) Update(hb CNStoreHeartbeat, tick uint64) { } storeInfo.DDLVisibilityBarrierReady = hb.DDLVisibilityBarrierReady storeInfo.DDLVisibilityDeployedProtocol = hb.DDLVisibilityDeployedProtocol - if hb.DDLVisibilityDeployedProtocol > s.DDLVisibilityDeployedProtocol { + s.Stores[hb.UUID] = storeInfo + if hb.DDLVisibilityDeployedProtocol > s.DDLVisibilityDeployedProtocol && + len(hb.DDLVisibilityEpochCommitTargets) > 0 && + s.matchesDDLVisibilityEpochCommitTargets(hb.DDLVisibilityEpochCommitTargets) { s.DDLVisibilityDeployedProtocol = hb.DDLVisibilityDeployedProtocol } - s.Stores[hb.UUID] = storeInfo +} + +func (s *CNState) matchesDDLVisibilityEpochCommitTargets(targets []DDLVisibilityActivationTarget) bool { + expected := make(map[string]DDLVisibilityActivationTarget, len(targets)) + for _, target := range targets { + if target.ServiceID == "" || target.Generation == 0 || target.QueryAddress == "" { + return false + } + if _, ok := expected[target.ServiceID]; ok { + return false + } + expected[target.ServiceID] = target + } + seen := 0 + for serviceID, store := range s.Stores { + if store.QueryAddress == "" || store.ViewMetadataAdmissionGeneration == 0 { + continue + } + seen++ + target, ok := expected[serviceID] + if !ok || target.Generation != store.ViewMetadataAdmissionGeneration || + target.QueryAddress != store.QueryAddress || !store.DDLVisibilityBarrierReady { + return false + } + } + return seen == len(expected) } // UpdateLabel updates labels of CN store. diff --git a/pkg/pb/logservice/logservice.pb.go b/pkg/pb/logservice/logservice.pb.go index 4df34f4b6b206..3498437d3cc44 100644 --- a/pkg/pb/logservice/logservice.pb.go +++ b/pkg/pb/logservice/logservice.pb.go @@ -1192,6 +1192,69 @@ func (m *Resource) GetMemAvailable() uint64 { } // CNStoreHeartbeat is the periodic message sent tp the HAKeeper by CN stores. +type DDLVisibilityActivationTarget struct { + ServiceID string `protobuf:"bytes,1,opt,name=ServiceID,proto3" json:"ServiceID,omitempty"` + Generation uint64 `protobuf:"varint,2,opt,name=Generation,proto3" json:"Generation,omitempty"` + QueryAddress string `protobuf:"bytes,3,opt,name=QueryAddress,proto3" json:"QueryAddress,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DDLVisibilityActivationTarget) Reset() { *m = DDLVisibilityActivationTarget{} } +func (m *DDLVisibilityActivationTarget) String() string { return proto.CompactTextString(m) } +func (*DDLVisibilityActivationTarget) ProtoMessage() {} +func (*DDLVisibilityActivationTarget) Descriptor() ([]byte, []int) { + return fileDescriptor_fd1040c5381ab5a7, []int{6} +} +func (m *DDLVisibilityActivationTarget) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DDLVisibilityActivationTarget) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DDLVisibilityActivationTarget.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DDLVisibilityActivationTarget) XXX_Merge(src proto.Message) { + xxx_messageInfo_DDLVisibilityActivationTarget.Merge(m, src) +} +func (m *DDLVisibilityActivationTarget) XXX_Size() int { + return m.ProtoSize() +} +func (m *DDLVisibilityActivationTarget) XXX_DiscardUnknown() { + xxx_messageInfo_DDLVisibilityActivationTarget.DiscardUnknown(m) +} + +var xxx_messageInfo_DDLVisibilityActivationTarget proto.InternalMessageInfo + +func (m *DDLVisibilityActivationTarget) GetServiceID() string { + if m != nil { + return m.ServiceID + } + return "" +} + +func (m *DDLVisibilityActivationTarget) GetGeneration() uint64 { + if m != nil { + return m.Generation + } + return 0 +} + +func (m *DDLVisibilityActivationTarget) GetQueryAddress() string { + if m != nil { + return m.QueryAddress + } + return "" +} + type CNStoreHeartbeat struct { UUID string `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"` ServiceAddress string `protobuf:"bytes,2,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` @@ -1225,17 +1288,20 @@ type CNStoreHeartbeat struct { DDLVisibilityBarrierReady bool `protobuf:"varint,25,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` // DDLVisibilityDeployedProtocol reports only a locally committed deployment // marker. Provisional activation must never advance the cluster-wide epoch. - DDLVisibilityDeployedProtocol int64 `protobuf:"varint,26,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,26,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + // Non-empty only for the transition that atomically validates the complete + // CN membership tuple set and commits DDLVisibilityDeployedProtocol. + DDLVisibilityEpochCommitTargets []DDLVisibilityActivationTarget `protobuf:"bytes,27,rep,name=DDLVisibilityEpochCommitTargets,proto3" json:"DDLVisibilityEpochCommitTargets"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNStoreHeartbeat) Reset() { *m = CNStoreHeartbeat{} } func (m *CNStoreHeartbeat) String() string { return proto.CompactTextString(m) } func (*CNStoreHeartbeat) ProtoMessage() {} func (*CNStoreHeartbeat) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{6} + return fileDescriptor_fd1040c5381ab5a7, []int{7} } func (m *CNStoreHeartbeat) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1439,6 +1505,13 @@ func (m *CNStoreHeartbeat) GetDDLVisibilityDeployedProtocol() int64 { return 0 } +func (m *CNStoreHeartbeat) GetDDLVisibilityEpochCommitTargets() []DDLVisibilityActivationTarget { + if m != nil { + return m.DDLVisibilityEpochCommitTargets + } + return nil +} + // CNAllocateID is the periodic message sent tp the HAKeeper by CN stores. type CNAllocateID struct { Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -1455,7 +1528,7 @@ func (m *CNAllocateID) Reset() { *m = CNAllocateID{} } func (m *CNAllocateID) String() string { return proto.CompactTextString(m) } func (*CNAllocateID) ProtoMessage() {} func (*CNAllocateID) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{7} + return fileDescriptor_fd1040c5381ab5a7, []int{8} } func (m *CNAllocateID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1540,7 +1613,7 @@ func (m *LogStoreHeartbeat) Reset() { *m = LogStoreHeartbeat{} } func (m *LogStoreHeartbeat) String() string { return proto.CompactTextString(m) } func (*LogStoreHeartbeat) ProtoMessage() {} func (*LogStoreHeartbeat) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{8} + return fileDescriptor_fd1040c5381ab5a7, []int{9} } func (m *LogStoreHeartbeat) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1664,7 +1737,7 @@ func (m *TNShardInfo) Reset() { *m = TNShardInfo{} } func (m *TNShardInfo) String() string { return proto.CompactTextString(m) } func (*TNShardInfo) ProtoMessage() {} func (*TNShardInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{9} + return fileDescriptor_fd1040c5381ab5a7, []int{10} } func (m *TNShardInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1739,7 +1812,7 @@ func (m *TNStoreHeartbeat) Reset() { *m = TNStoreHeartbeat{} } func (m *TNStoreHeartbeat) String() string { return proto.CompactTextString(m) } func (*TNStoreHeartbeat) ProtoMessage() {} func (*TNStoreHeartbeat) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{10} + return fileDescriptor_fd1040c5381ab5a7, []int{11} } func (m *TNStoreHeartbeat) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1884,7 +1957,7 @@ func (m *RSMState) Reset() { *m = RSMState{} } func (m *RSMState) String() string { return proto.CompactTextString(m) } func (*RSMState) ProtoMessage() {} func (*RSMState) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{11} + return fileDescriptor_fd1040c5381ab5a7, []int{12} } func (m *RSMState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2018,7 +2091,7 @@ func (m *LogRecord) Reset() { *m = LogRecord{} } func (m *LogRecord) String() string { return proto.CompactTextString(m) } func (*LogRecord) ProtoMessage() {} func (*LogRecord) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{12} + return fileDescriptor_fd1040c5381ab5a7, []int{13} } func (m *LogRecord) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2087,7 +2160,7 @@ func (m *LogRequest) Reset() { *m = LogRequest{} } func (m *LogRequest) String() string { return proto.CompactTextString(m) } func (*LogRequest) ProtoMessage() {} func (*LogRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{13} + return fileDescriptor_fd1040c5381ab5a7, []int{14} } func (m *LogRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2190,7 +2263,7 @@ func (m *TsoRequest) Reset() { *m = TsoRequest{} } func (m *TsoRequest) String() string { return proto.CompactTextString(m) } func (*TsoRequest) ProtoMessage() {} func (*TsoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{14} + return fileDescriptor_fd1040c5381ab5a7, []int{15} } func (m *TsoRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2243,7 +2316,7 @@ func (m *CNStoreLabel) Reset() { *m = CNStoreLabel{} } func (m *CNStoreLabel) String() string { return proto.CompactTextString(m) } func (*CNStoreLabel) ProtoMessage() {} func (*CNStoreLabel) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{15} + return fileDescriptor_fd1040c5381ab5a7, []int{16} } func (m *CNStoreLabel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2307,7 +2380,7 @@ func (m *CNWorkState) Reset() { *m = CNWorkState{} } func (m *CNWorkState) String() string { return proto.CompactTextString(m) } func (*CNWorkState) ProtoMessage() {} func (*CNWorkState) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{16} + return fileDescriptor_fd1040c5381ab5a7, []int{17} } func (m *CNWorkState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2366,7 +2439,7 @@ func (m *CNStateLabel) Reset() { *m = CNStateLabel{} } func (m *CNStateLabel) String() string { return proto.CompactTextString(m) } func (*CNStateLabel) ProtoMessage() {} func (*CNStateLabel) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{17} + return fileDescriptor_fd1040c5381ab5a7, []int{18} } func (m *CNStateLabel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2443,7 +2516,7 @@ func (m *Request) Reset() { *m = Request{} } func (m *Request) String() string { return proto.CompactTextString(m) } func (*Request) ProtoMessage() {} func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{18} + return fileDescriptor_fd1040c5381ab5a7, []int{19} } func (m *Request) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2605,7 +2678,7 @@ func (m *LogResponse) Reset() { *m = LogResponse{} } func (m *LogResponse) String() string { return proto.CompactTextString(m) } func (*LogResponse) ProtoMessage() {} func (*LogResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{19} + return fileDescriptor_fd1040c5381ab5a7, []int{20} } func (m *LogResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2673,7 +2746,7 @@ func (m *AllocateIDResponse) Reset() { *m = AllocateIDResponse{} } func (m *AllocateIDResponse) String() string { return proto.CompactTextString(m) } func (*AllocateIDResponse) ProtoMessage() {} func (*AllocateIDResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{20} + return fileDescriptor_fd1040c5381ab5a7, []int{21} } func (m *AllocateIDResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2731,7 +2804,7 @@ func (m *Response) Reset() { *m = Response{} } func (m *Response) String() string { return proto.CompactTextString(m) } func (*Response) ProtoMessage() {} func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{21} + return fileDescriptor_fd1040c5381ab5a7, []int{22} } func (m *Response) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2855,7 +2928,7 @@ func (m *LogRecordResponse) Reset() { *m = LogRecordResponse{} } func (m *LogRecordResponse) String() string { return proto.CompactTextString(m) } func (*LogRecordResponse) ProtoMessage() {} func (*LogRecordResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{22} + return fileDescriptor_fd1040c5381ab5a7, []int{23} } func (m *LogRecordResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2902,7 +2975,7 @@ func (m *TsoResponse) Reset() { *m = TsoResponse{} } func (m *TsoResponse) String() string { return proto.CompactTextString(m) } func (*TsoResponse) ProtoMessage() {} func (*TsoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{23} + return fileDescriptor_fd1040c5381ab5a7, []int{24} } func (m *TsoResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2952,7 +3025,7 @@ func (m *TaskTableUser) Reset() { *m = TaskTableUser{} } func (m *TaskTableUser) String() string { return proto.CompactTextString(m) } func (*TaskTableUser) ProtoMessage() {} func (*TaskTableUser) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{24} + return fileDescriptor_fd1040c5381ab5a7, []int{25} } func (m *TaskTableUser) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3013,7 +3086,7 @@ func (m *Replica) Reset() { *m = Replica{} } func (m *Replica) String() string { return proto.CompactTextString(m) } func (*Replica) ProtoMessage() {} func (*Replica) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{25} + return fileDescriptor_fd1040c5381ab5a7, []int{26} } func (m *Replica) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3092,7 +3165,7 @@ func (m *ConfigChange) Reset() { *m = ConfigChange{} } func (m *ConfigChange) String() string { return proto.CompactTextString(m) } func (*ConfigChange) ProtoMessage() {} func (*ConfigChange) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{26} + return fileDescriptor_fd1040c5381ab5a7, []int{27} } func (m *ConfigChange) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3154,7 +3227,7 @@ func (m *ShutdownStore) Reset() { *m = ShutdownStore{} } func (m *ShutdownStore) String() string { return proto.CompactTextString(m) } func (*ShutdownStore) ProtoMessage() {} func (*ShutdownStore) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{27} + return fileDescriptor_fd1040c5381ab5a7, []int{28} } func (m *ShutdownStore) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3213,7 +3286,7 @@ func (m *ScheduleCommand) Reset() { *m = ScheduleCommand{} } func (m *ScheduleCommand) String() string { return proto.CompactTextString(m) } func (*ScheduleCommand) ProtoMessage() {} func (*ScheduleCommand) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{28} + return fileDescriptor_fd1040c5381ab5a7, []int{29} } func (m *ScheduleCommand) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3333,7 +3406,7 @@ func (m *ScheduleCommandQuery) Reset() { *m = ScheduleCommandQuery{} } func (m *ScheduleCommandQuery) String() string { return proto.CompactTextString(m) } func (*ScheduleCommandQuery) ProtoMessage() {} func (*ScheduleCommandQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{29} + return fileDescriptor_fd1040c5381ab5a7, []int{30} } func (m *ScheduleCommandQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3401,7 +3474,7 @@ func (m *CommandDeliveryTargets) Reset() { *m = CommandDeliveryTargets{} func (m *CommandDeliveryTargets) String() string { return proto.CompactTextString(m) } func (*CommandDeliveryTargets) ProtoMessage() {} func (*CommandDeliveryTargets) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{30} + return fileDescriptor_fd1040c5381ab5a7, []int{31} } func (m *CommandDeliveryTargets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3483,7 +3556,7 @@ func (m *JoinGossipCluster) Reset() { *m = JoinGossipCluster{} } func (m *JoinGossipCluster) String() string { return proto.CompactTextString(m) } func (*JoinGossipCluster) ProtoMessage() {} func (*JoinGossipCluster) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{31} + return fileDescriptor_fd1040c5381ab5a7, []int{32} } func (m *JoinGossipCluster) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3534,7 +3607,7 @@ func (m *CreateTaskService) Reset() { *m = CreateTaskService{} } func (m *CreateTaskService) String() string { return proto.CompactTextString(m) } func (*CreateTaskService) ProtoMessage() {} func (*CreateTaskService) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{32} + return fileDescriptor_fd1040c5381ab5a7, []int{33} } func (m *CreateTaskService) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3589,7 +3662,7 @@ func (m *DeleteCNStore) Reset() { *m = DeleteCNStore{} } func (m *DeleteCNStore) String() string { return proto.CompactTextString(m) } func (*DeleteCNStore) ProtoMessage() {} func (*DeleteCNStore) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{33} + return fileDescriptor_fd1040c5381ab5a7, []int{34} } func (m *DeleteCNStore) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3637,7 +3710,7 @@ func (m *DeleteProxyStore) Reset() { *m = DeleteProxyStore{} } func (m *DeleteProxyStore) String() string { return proto.CompactTextString(m) } func (*DeleteProxyStore) ProtoMessage() {} func (*DeleteProxyStore) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{34} + return fileDescriptor_fd1040c5381ab5a7, []int{35} } func (m *DeleteProxyStore) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3685,7 +3758,7 @@ func (m *AddLogShard) Reset() { *m = AddLogShard{} } func (m *AddLogShard) String() string { return proto.CompactTextString(m) } func (*AddLogShard) ProtoMessage() {} func (*AddLogShard) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{35} + return fileDescriptor_fd1040c5381ab5a7, []int{36} } func (m *AddLogShard) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3736,7 +3809,7 @@ func (m *BootstrapShard) Reset() { *m = BootstrapShard{} } func (m *BootstrapShard) String() string { return proto.CompactTextString(m) } func (*BootstrapShard) ProtoMessage() {} func (*BootstrapShard) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{36} + return fileDescriptor_fd1040c5381ab5a7, []int{37} } func (m *BootstrapShard) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3823,7 +3896,7 @@ func (m *CommandBatch) Reset() { *m = CommandBatch{} } func (m *CommandBatch) String() string { return proto.CompactTextString(m) } func (*CommandBatch) ProtoMessage() {} func (*CommandBatch) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{37} + return fileDescriptor_fd1040c5381ab5a7, []int{38} } func (m *CommandBatch) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3917,7 +3990,7 @@ func (m *ViewMetadataAdmission) Reset() { *m = ViewMetadataAdmission{} } func (m *ViewMetadataAdmission) String() string { return proto.CompactTextString(m) } func (*ViewMetadataAdmission) ProtoMessage() {} func (*ViewMetadataAdmission) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{38} + return fileDescriptor_fd1040c5381ab5a7, []int{39} } func (m *ViewMetadataAdmission) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4018,7 +4091,7 @@ func (m *ViewMetadataAdmissionTargets) Reset() { *m = ViewMetadataAdmiss func (m *ViewMetadataAdmissionTargets) String() string { return proto.CompactTextString(m) } func (*ViewMetadataAdmissionTargets) ProtoMessage() {} func (*ViewMetadataAdmissionTargets) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{39} + return fileDescriptor_fd1040c5381ab5a7, []int{40} } func (m *ViewMetadataAdmissionTargets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4116,7 +4189,7 @@ func (m *CNStoreInfo) Reset() { *m = CNStoreInfo{} } func (m *CNStoreInfo) String() string { return proto.CompactTextString(m) } func (*CNStoreInfo) ProtoMessage() {} func (*CNStoreInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{40} + return fileDescriptor_fd1040c5381ab5a7, []int{41} } func (m *CNStoreInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4351,7 +4424,7 @@ func (m *CNState) Reset() { *m = CNState{} } func (m *CNState) String() string { return proto.CompactTextString(m) } func (*CNState) ProtoMessage() {} func (*CNState) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{41} + return fileDescriptor_fd1040c5381ab5a7, []int{42} } func (m *CNState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4423,7 +4496,7 @@ func (m *TNStoreInfo) Reset() { *m = TNStoreInfo{} } func (m *TNStoreInfo) String() string { return proto.CompactTextString(m) } func (*TNStoreInfo) ProtoMessage() {} func (*TNStoreInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{42} + return fileDescriptor_fd1040c5381ab5a7, []int{43} } func (m *TNStoreInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4549,7 +4622,7 @@ func (m *TNState) Reset() { *m = TNState{} } func (m *TNState) String() string { return proto.CompactTextString(m) } func (*TNState) ProtoMessage() {} func (*TNState) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{43} + return fileDescriptor_fd1040c5381ab5a7, []int{44} } func (m *TNState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4603,7 +4676,7 @@ func (m *ProxyStore) Reset() { *m = ProxyStore{} } func (m *ProxyStore) String() string { return proto.CompactTextString(m) } func (*ProxyStore) ProtoMessage() {} func (*ProxyStore) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{44} + return fileDescriptor_fd1040c5381ab5a7, []int{45} } func (m *ProxyStore) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4699,7 +4772,7 @@ func (m *ProxyState) Reset() { *m = ProxyState{} } func (m *ProxyState) String() string { return proto.CompactTextString(m) } func (*ProxyState) ProtoMessage() {} func (*ProxyState) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{45} + return fileDescriptor_fd1040c5381ab5a7, []int{46} } func (m *ProxyState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4751,7 +4824,7 @@ func (m *ProxyHeartbeat) Reset() { *m = ProxyHeartbeat{} } func (m *ProxyHeartbeat) String() string { return proto.CompactTextString(m) } func (*ProxyHeartbeat) ProtoMessage() {} func (*ProxyHeartbeat) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{46} + return fileDescriptor_fd1040c5381ab5a7, []int{47} } func (m *ProxyHeartbeat) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4839,7 +4912,7 @@ func (m *ClusterDetails) Reset() { *m = ClusterDetails{} } func (m *ClusterDetails) String() string { return proto.CompactTextString(m) } func (*ClusterDetails) ProtoMessage() {} func (*ClusterDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{47} + return fileDescriptor_fd1040c5381ab5a7, []int{48} } func (m *ClusterDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4932,7 +5005,7 @@ func (m *ClusterInfo) Reset() { *m = ClusterInfo{} } func (m *ClusterInfo) String() string { return proto.CompactTextString(m) } func (*ClusterInfo) ProtoMessage() {} func (*ClusterInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{48} + return fileDescriptor_fd1040c5381ab5a7, []int{49} } func (m *ClusterInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4992,7 +5065,7 @@ func (m *InitialClusterRequest) Reset() { *m = InitialClusterRequest{} } func (m *InitialClusterRequest) String() string { return proto.CompactTextString(m) } func (*InitialClusterRequest) ProtoMessage() {} func (*InitialClusterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{49} + return fileDescriptor_fd1040c5381ab5a7, []int{50} } func (m *InitialClusterRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5083,7 +5156,7 @@ func (m *RestoreIDWatermarkRequest) Reset() { *m = RestoreIDWatermarkReq func (m *RestoreIDWatermarkRequest) String() string { return proto.CompactTextString(m) } func (*RestoreIDWatermarkRequest) ProtoMessage() {} func (*RestoreIDWatermarkRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{50} + return fileDescriptor_fd1040c5381ab5a7, []int{51} } func (m *RestoreIDWatermarkRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5155,7 +5228,7 @@ func (m *LogStoreInfo) Reset() { *m = LogStoreInfo{} } func (m *LogStoreInfo) String() string { return proto.CompactTextString(m) } func (*LogStoreInfo) ProtoMessage() {} func (*LogStoreInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{51} + return fileDescriptor_fd1040c5381ab5a7, []int{52} } func (m *LogStoreInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5280,7 +5353,7 @@ func (m *LogState) Reset() { *m = LogState{} } func (m *LogState) String() string { return proto.CompactTextString(m) } func (*LogState) ProtoMessage() {} func (*LogState) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{52} + return fileDescriptor_fd1040c5381ab5a7, []int{53} } func (m *LogState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5353,7 +5426,7 @@ func (m *CheckerState) Reset() { *m = CheckerState{} } func (m *CheckerState) String() string { return proto.CompactTextString(m) } func (*CheckerState) ProtoMessage() {} func (*CheckerState) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{53} + return fileDescriptor_fd1040c5381ab5a7, []int{54} } func (m *CheckerState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5524,7 +5597,7 @@ func (m *DeletedStore) Reset() { *m = DeletedStore{} } func (m *DeletedStore) String() string { return proto.CompactTextString(m) } func (*DeletedStore) ProtoMessage() {} func (*DeletedStore) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{54} + return fileDescriptor_fd1040c5381ab5a7, []int{55} } func (m *DeletedStore) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5671,7 +5744,7 @@ func (m *HAKeeperRSMState) Reset() { *m = HAKeeperRSMState{} } func (m *HAKeeperRSMState) String() string { return proto.CompactTextString(m) } func (*HAKeeperRSMState) ProtoMessage() {} func (*HAKeeperRSMState) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{55} + return fileDescriptor_fd1040c5381ab5a7, []int{56} } func (m *HAKeeperRSMState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6007,7 +6080,7 @@ func (m *ReplicaInfo) Reset() { *m = ReplicaInfo{} } func (m *ReplicaInfo) String() string { return proto.CompactTextString(m) } func (*ReplicaInfo) ProtoMessage() {} func (*ReplicaInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{56} + return fileDescriptor_fd1040c5381ab5a7, []int{57} } func (m *ReplicaInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6066,7 +6139,7 @@ func (m *ShardInfoQueryResult) Reset() { *m = ShardInfoQueryResult{} } func (m *ShardInfoQueryResult) String() string { return proto.CompactTextString(m) } func (*ShardInfoQueryResult) ProtoMessage() {} func (*ShardInfoQueryResult) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{57} + return fileDescriptor_fd1040c5381ab5a7, []int{58} } func (m *ShardInfoQueryResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6146,7 +6219,7 @@ func (m *BackupData) Reset() { *m = BackupData{} } func (m *BackupData) String() string { return proto.CompactTextString(m) } func (*BackupData) ProtoMessage() {} func (*BackupData) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{58} + return fileDescriptor_fd1040c5381ab5a7, []int{59} } func (m *BackupData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6207,7 +6280,7 @@ func (m *ConfigItem) Reset() { *m = ConfigItem{} } func (m *ConfigItem) String() string { return proto.CompactTextString(m) } func (*ConfigItem) ProtoMessage() {} func (*ConfigItem) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{59} + return fileDescriptor_fd1040c5381ab5a7, []int{60} } func (m *ConfigItem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6277,7 +6350,7 @@ func (m *ConfigData) Reset() { *m = ConfigData{} } func (m *ConfigData) String() string { return proto.CompactTextString(m) } func (*ConfigData) ProtoMessage() {} func (*ConfigData) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{60} + return fileDescriptor_fd1040c5381ab5a7, []int{61} } func (m *ConfigData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6326,7 +6399,7 @@ func (m *Locality) Reset() { *m = Locality{} } func (m *Locality) String() string { return proto.CompactTextString(m) } func (*Locality) ProtoMessage() {} func (*Locality) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{61} + return fileDescriptor_fd1040c5381ab5a7, []int{62} } func (m *Locality) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6373,7 +6446,7 @@ func (m *CheckHealth) Reset() { *m = CheckHealth{} } func (m *CheckHealth) String() string { return proto.CompactTextString(m) } func (*CheckHealth) ProtoMessage() {} func (*CheckHealth) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{62} + return fileDescriptor_fd1040c5381ab5a7, []int{63} } func (m *CheckHealth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6425,7 +6498,7 @@ func (m *ScheduleCommandID) Reset() { *m = ScheduleCommandID{} } func (m *ScheduleCommandID) String() string { return proto.CompactTextString(m) } func (*ScheduleCommandID) ProtoMessage() {} func (*ScheduleCommandID) Descriptor() ([]byte, []int) { - return fileDescriptor_fd1040c5381ab5a7, []int{63} + return fileDescriptor_fd1040c5381ab5a7, []int{64} } func (m *ScheduleCommandID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6488,6 +6561,7 @@ func init() { proto.RegisterMapType((map[uint64]string)(nil), "logservice.LogShardInfo.ReplicasEntry") proto.RegisterType((*LogReplicaInfo)(nil), "logservice.LogReplicaInfo") proto.RegisterType((*Resource)(nil), "logservice.Resource") + proto.RegisterType((*DDLVisibilityActivationTarget)(nil), "logservice.DDLVisibilityActivationTarget") proto.RegisterType((*CNStoreHeartbeat)(nil), "logservice.CNStoreHeartbeat") proto.RegisterType((*CNAllocateID)(nil), "logservice.CNAllocateID") proto.RegisterType((*LogStoreHeartbeat)(nil), "logservice.LogStoreHeartbeat") @@ -6583,385 +6657,389 @@ func init() { func init() { proto.RegisterFile("logservice.proto", fileDescriptor_fd1040c5381ab5a7) } var fileDescriptor_fd1040c5381ab5a7 = []byte{ - // 6046 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xdb, 0x6f, 0x1b, 0xd9, - 0x79, 0xb8, 0x87, 0xa4, 0x24, 0xf2, 0xa3, 0x24, 0x8f, 0x8e, 0x2e, 0xa6, 0x65, 0x5b, 0xd6, 0x72, - 0x9d, 0x5d, 0xaf, 0xb2, 0x91, 0xf3, 0xb3, 0xb3, 0x8b, 0x4d, 0x7e, 0x8e, 0x77, 0x29, 0x92, 0x6b, - 0xd1, 0xa6, 0x28, 0xed, 0x70, 0xe4, 0x4d, 0x02, 0x2c, 0x84, 0x11, 0x79, 0x2c, 0x4f, 0x44, 0x71, - 0x98, 0x99, 0x91, 0xd7, 0x6e, 0xdf, 0x8a, 0xa6, 0x28, 0x1a, 0x34, 0x68, 0x80, 0xa0, 0x0d, 0xda, - 0xa6, 0x4d, 0xfb, 0xd6, 0xa7, 0xbc, 0xf4, 0x6f, 0x28, 0xf2, 0x50, 0x14, 0x69, 0x1e, 0x0b, 0x34, - 0x97, 0xed, 0x4b, 0x81, 0xbc, 0x37, 0x4f, 0x05, 0x8a, 0x73, 0x9b, 0x39, 0x67, 0x2e, 0xbc, 0x48, - 0x4a, 0xd2, 0x14, 0xfb, 0x24, 0x9e, 0x73, 0xbe, 0xef, 0x5c, 0xbf, 0xdb, 0xf9, 0xbe, 0xef, 0x8c, - 0x40, 0xef, 0x39, 0x47, 0x1e, 0x76, 0x9f, 0xdb, 0x1d, 0xbc, 0x39, 0x70, 0x1d, 0xdf, 0x41, 0x10, - 0xd6, 0xac, 0x7e, 0xee, 0xc8, 0xf6, 0x9f, 0x9d, 0x1e, 0x6e, 0x76, 0x9c, 0x93, 0x3b, 0x47, 0xce, - 0x91, 0x73, 0x87, 0x82, 0x1c, 0x9e, 0x3e, 0xa5, 0x25, 0x5a, 0xa0, 0xbf, 0x18, 0xea, 0xea, 0xcd, - 0x23, 0xc7, 0x39, 0xea, 0xe1, 0x10, 0xca, 0xb7, 0x4f, 0xb0, 0xe7, 0x5b, 0x27, 0x03, 0x0e, 0x30, - 0x7f, 0x82, 0x7d, 0xab, 0x6b, 0xf9, 0x16, 0x2b, 0x97, 0xbf, 0x5d, 0x80, 0x99, 0x6a, 0xab, 0xed, - 0x3b, 0x2e, 0x46, 0x08, 0x72, 0xfb, 0xfb, 0x8d, 0x5a, 0x49, 0x5b, 0xd7, 0x6e, 0x17, 0x0c, 0xfa, - 0x1b, 0xbd, 0x06, 0xf3, 0x6d, 0x36, 0x95, 0x4a, 0xb7, 0xeb, 0x62, 0xcf, 0x2b, 0x65, 0x68, 0x6b, - 0xa4, 0x16, 0xad, 0x01, 0xb4, 0x3f, 0x68, 0x0a, 0x98, 0x2c, 0x85, 0x91, 0x6a, 0xd0, 0x26, 0xa0, - 0xa6, 0xd3, 0x39, 0x8e, 0xf4, 0x95, 0xa3, 0x70, 0x09, 0x2d, 0xe8, 0x16, 0xe4, 0x0c, 0xa7, 0x87, - 0x4b, 0xd3, 0xeb, 0xda, 0xed, 0xf9, 0xbb, 0xfa, 0x66, 0x30, 0xed, 0x6a, 0x8b, 0xd4, 0x1b, 0xb4, - 0x95, 0xcc, 0xd8, 0xb4, 0x3b, 0xc7, 0xa5, 0x99, 0x75, 0xed, 0x76, 0xce, 0xa0, 0xbf, 0xd1, 0x67, - 0x61, 0xaa, 0xed, 0x5b, 0x3e, 0x2e, 0xe5, 0x29, 0xea, 0xf2, 0xa6, 0xb4, 0xbf, 0x2d, 0xa7, 0x8b, - 0x69, 0xa3, 0xc1, 0x60, 0xd0, 0x97, 0x61, 0xba, 0x69, 0x1d, 0xe2, 0x9e, 0x57, 0x2a, 0xac, 0x67, - 0x6f, 0x17, 0xef, 0xde, 0x94, 0xa1, 0xf9, 0xbe, 0x6c, 0x32, 0x88, 0x7a, 0xdf, 0x77, 0x5f, 0x6e, - 0xe5, 0x7e, 0xf4, 0xd3, 0x9b, 0x97, 0x0c, 0x8e, 0x84, 0xfe, 0x1f, 0x14, 0x3e, 0x74, 0xdc, 0x63, - 0x36, 0x1e, 0xd0, 0xf1, 0x16, 0xc3, 0xa9, 0x06, 0x4d, 0x46, 0x08, 0x85, 0xca, 0x30, 0xfb, 0xc1, - 0x29, 0x76, 0x5f, 0x8a, 0x2d, 0x28, 0xd2, 0x2d, 0x50, 0xea, 0xd0, 0xdb, 0x00, 0x55, 0xa7, 0xff, - 0xd4, 0x3e, 0xaa, 0x59, 0xbe, 0x55, 0x9a, 0x5d, 0xd7, 0x6e, 0x17, 0xef, 0xae, 0x28, 0x33, 0x0b, - 0x5a, 0x0d, 0x09, 0x12, 0xbd, 0x0d, 0x79, 0x03, 0x7b, 0xce, 0xa9, 0xdb, 0xc1, 0xa5, 0x39, 0x8a, - 0xb5, 0x24, 0x63, 0x89, 0x36, 0xbe, 0x88, 0x00, 0x16, 0xad, 0xc0, 0xf4, 0xfe, 0xc0, 0xb4, 0x4f, - 0x70, 0x69, 0x7e, 0x5d, 0xbb, 0x9d, 0x35, 0x78, 0x09, 0x7d, 0x1e, 0x16, 0xdb, 0xcf, 0x2c, 0xb7, - 0x1b, 0x39, 0xb5, 0xcb, 0x74, 0xca, 0x49, 0x4d, 0x68, 0x15, 0xf2, 0x55, 0xe7, 0xe4, 0xc4, 0xf6, - 0x1b, 0xb5, 0x92, 0x4e, 0xc1, 0x82, 0x32, 0x7a, 0x1f, 0xd6, 0x9e, 0xd8, 0xf8, 0xe3, 0x1d, 0xbe, - 0x3d, 0x95, 0xee, 0x89, 0xed, 0x79, 0xb6, 0xd3, 0x6f, 0x9f, 0x0e, 0x06, 0x8e, 0xeb, 0xe3, 0x6e, - 0x69, 0x61, 0x5d, 0xbb, 0x9d, 0x37, 0x46, 0x40, 0xa1, 0x6d, 0xb8, 0x99, 0x08, 0xf1, 0x10, 0xf7, - 0xb1, 0x6b, 0xf9, 0xb6, 0xd3, 0x2f, 0x21, 0x4a, 0x0f, 0xa3, 0xc0, 0xd0, 0x7d, 0xb8, 0x2a, 0x83, - 0xec, 0x1e, 0x92, 0x9d, 0xc2, 0xdd, 0xfa, 0xc0, 0xe9, 0x3c, 0x2b, 0x2d, 0xd2, 0x3e, 0xd2, 0x01, - 0xd0, 0x03, 0x58, 0x4d, 0x1c, 0xc0, 0xc0, 0x56, 0xf7, 0x65, 0x69, 0x89, 0xae, 0x65, 0x08, 0x04, - 0x19, 0xbd, 0x56, 0x6b, 0x3e, 0xb1, 0x3d, 0xfb, 0xd0, 0xee, 0xd9, 0xfe, 0xcb, 0x2d, 0xcb, 0x75, - 0x6d, 0xec, 0x32, 0xf4, 0x65, 0x8a, 0x9e, 0x0e, 0x80, 0xbe, 0x04, 0x25, 0xb9, 0xef, 0x46, 0xff, - 0x88, 0x1c, 0x00, 0x43, 0x5e, 0xa1, 0xc8, 0xa9, 0xed, 0xa8, 0x06, 0x37, 0x94, 0x8e, 0x6b, 0x78, - 0xd0, 0x73, 0x5e, 0xe2, 0xee, 0x1e, 0x11, 0x09, 0x1d, 0xa7, 0x57, 0xba, 0x42, 0xc9, 0x60, 0x38, - 0xd0, 0x6a, 0x0b, 0x8a, 0x12, 0x67, 0x20, 0x1d, 0xb2, 0xc7, 0xf8, 0x25, 0x17, 0x1e, 0xe4, 0x27, - 0x7a, 0x03, 0xa6, 0x9e, 0x5b, 0xbd, 0x53, 0x4c, 0x45, 0x46, 0x51, 0xe6, 0x0c, 0x8a, 0xd7, 0xb4, - 0x3d, 0xdf, 0x60, 0x10, 0x5f, 0xca, 0xbc, 0xa3, 0x3d, 0xca, 0xe5, 0xa7, 0xf4, 0xe9, 0xf2, 0xaf, - 0xb2, 0x30, 0x63, 0x5e, 0x80, 0x40, 0x12, 0xa2, 0x21, 0x9b, 0x24, 0x1a, 0x72, 0x63, 0x88, 0x86, - 0xb7, 0x60, 0x9a, 0x52, 0xb8, 0x57, 0x9a, 0xa2, 0xa2, 0xe1, 0x8a, 0x0c, 0x6d, 0xb6, 0x68, 0x5b, - 0xa3, 0xff, 0xd4, 0x11, 0x22, 0x81, 0x01, 0xa3, 0xbb, 0xb0, 0xd4, 0x74, 0x8e, 0x7c, 0xcb, 0xee, - 0x91, 0x09, 0x61, 0x57, 0xcc, 0x72, 0x9a, 0xce, 0x32, 0xb1, 0x2d, 0x45, 0x38, 0xce, 0xa4, 0x0a, - 0x47, 0x55, 0x3e, 0x14, 0xc6, 0x96, 0x0f, 0x51, 0xd9, 0x03, 0x09, 0xb2, 0x27, 0x85, 0xe7, 0x8b, - 0xe9, 0x3c, 0xff, 0x1e, 0x5c, 0xab, 0x9c, 0xfa, 0x4e, 0xa3, 0xdf, 0x71, 0x29, 0x63, 0xbc, 0x8f, - 0xfb, 0x1d, 0x1c, 0x32, 0xf5, 0x2c, 0x25, 0xc6, 0x61, 0x20, 0x8f, 0x72, 0xf9, 0xbc, 0x5e, 0x28, - 0xff, 0x69, 0x16, 0xf2, 0x4d, 0xe7, 0xe8, 0x7f, 0xc1, 0xd1, 0xdf, 0x27, 0x72, 0x74, 0xd0, 0xb3, - 0x3b, 0x96, 0x38, 0xfc, 0x55, 0x19, 0xbe, 0xe9, 0x1c, 0xf1, 0x66, 0xe9, 0xfc, 0x03, 0x8c, 0xc8, - 0xe9, 0x4c, 0x4f, 0x22, 0xbd, 0x9b, 0x4e, 0xc7, 0x22, 0xbc, 0x46, 0xcf, 0x3e, 0x22, 0xbd, 0x45, - 0x9b, 0x18, 0x4f, 0x94, 0xd1, 0x13, 0x78, 0x6d, 0x28, 0xa3, 0x86, 0x47, 0x91, 0xa7, 0x47, 0x31, - 0x26, 0x74, 0xf9, 0xbb, 0x59, 0x98, 0x25, 0xe7, 0x21, 0x08, 0x1d, 0x95, 0x60, 0x86, 0x15, 0xd8, - 0xb1, 0xe4, 0x0c, 0x51, 0x44, 0x5b, 0xd2, 0x86, 0x65, 0xe8, 0x86, 0xbd, 0x16, 0xd9, 0xb0, 0xa0, - 0x97, 0x4d, 0x01, 0x48, 0xa5, 0x86, 0xb4, 0x6d, 0x4b, 0x30, 0xc5, 0x04, 0x2f, 0x3b, 0x36, 0x56, - 0x20, 0x0a, 0xa5, 0x89, 0xad, 0x2e, 0x76, 0x1b, 0x35, 0x7a, 0x74, 0x39, 0x23, 0x28, 0xd3, 0x73, - 0xc6, 0xee, 0x49, 0x69, 0x8a, 0x9f, 0x33, 0x76, 0x4f, 0xd0, 0x47, 0xb0, 0xd0, 0x72, 0xfa, 0x4f, - 0x1c, 0xdf, 0xee, 0x1f, 0x05, 0x53, 0x9a, 0xa6, 0x53, 0xba, 0x93, 0x3a, 0xa5, 0x18, 0x06, 0x9b, - 0x5b, 0xbc, 0xa7, 0xd5, 0xff, 0x0f, 0x73, 0x0a, 0x8c, 0x2c, 0xf5, 0x72, 0x4c, 0xea, 0x2d, 0xc9, - 0x52, 0xaf, 0x20, 0x09, 0xb8, 0xd5, 0x1a, 0xac, 0x24, 0x8f, 0x34, 0x49, 0x2f, 0xe5, 0xef, 0x69, - 0x30, 0xaf, 0x52, 0x20, 0x7a, 0x5f, 0x3d, 0x28, 0xda, 0x4f, 0xf1, 0x6e, 0x29, 0x6d, 0xbd, 0x5b, - 0x79, 0x42, 0x41, 0x3f, 0xfe, 0xe9, 0x4d, 0xcd, 0x50, 0x0f, 0xf8, 0x3a, 0x14, 0x44, 0xb7, 0x35, - 0x3a, 0x70, 0xce, 0x08, 0x2b, 0xd0, 0x3a, 0x14, 0x1b, 0x5e, 0xb0, 0x00, 0x7a, 0x4c, 0x79, 0x43, - 0xae, 0x2a, 0xff, 0x89, 0x16, 0x1a, 0x20, 0xd4, 0x14, 0xd8, 0xdb, 0x37, 0x1d, 0xdf, 0xea, 0xf1, - 0x85, 0x05, 0x65, 0x22, 0x88, 0xaa, 0x7b, 0xfb, 0x95, 0xe7, 0x96, 0xdd, 0xb3, 0x0e, 0x7b, 0x6c, - 0x91, 0x9a, 0xa1, 0xd4, 0x11, 0xfc, 0x1d, 0x7c, 0xc2, 0xf0, 0x19, 0x49, 0x04, 0x65, 0x82, 0xbf, - 0x83, 0x4f, 0x42, 0x7c, 0x46, 0x19, 0x4a, 0x5d, 0xf9, 0x07, 0x00, 0x3a, 0xb7, 0xe0, 0xb6, 0xb1, - 0xe5, 0xfa, 0x87, 0xd8, 0xf2, 0x7f, 0x07, 0x4d, 0xdc, 0x4d, 0x40, 0xa6, 0xe5, 0x09, 0xdc, 0xaa, - 0x8b, 0x2d, 0xc2, 0xc9, 0x33, 0x74, 0xf3, 0x13, 0x5a, 0x62, 0x32, 0x3e, 0x9f, 0x20, 0xe3, 0x6f, - 0xc1, 0x5c, 0xa3, 0x6f, 0xfb, 0xa1, 0xe9, 0x5a, 0xa0, 0x40, 0x6a, 0x25, 0x81, 0x7a, 0xe8, 0x78, - 0x9e, 0x3d, 0x50, 0xd5, 0x85, 0x5a, 0x49, 0xc6, 0x63, 0x15, 0x8f, 0x1c, 0xbb, 0x8f, 0xbb, 0x54, - 0x51, 0xe4, 0x0d, 0xa5, 0xee, 0x37, 0x6e, 0xcf, 0xa6, 0xe8, 0xb0, 0xf9, 0xf1, 0xec, 0xd6, 0xcb, - 0x11, 0xbb, 0xf5, 0xf3, 0xb0, 0x58, 0xe9, 0x1c, 0xe3, 0x2e, 0xa9, 0xb0, 0xfa, 0xdd, 0x2d, 0xcb, - 0xef, 0x3c, 0xe3, 0xe6, 0x6d, 0xce, 0x48, 0x6a, 0x22, 0x1a, 0x91, 0xd7, 0xd4, 0x70, 0xcf, 0x7e, - 0x4e, 0x76, 0xbe, 0x73, 0x1c, 0x35, 0x73, 0x87, 0x81, 0x8c, 0x61, 0x2b, 0xa3, 0x8b, 0xb2, 0x95, - 0x17, 0x2f, 0xc0, 0x56, 0x5e, 0x1a, 0x65, 0x2b, 0x47, 0xd6, 0x53, 0xb5, 0x7c, 0xab, 0xe7, 0x1c, - 0x51, 0x33, 0x80, 0x77, 0xb1, 0x4c, 0xbb, 0x18, 0x01, 0x85, 0xb6, 0xe0, 0xba, 0x0c, 0x61, 0xe0, - 0xa7, 0x2e, 0xf6, 0x9e, 0x85, 0xbb, 0xc2, 0x2c, 0xdf, 0xa1, 0x30, 0xf1, 0x3e, 0x9e, 0x5b, 0x3d, - 0xbb, 0x4b, 0x98, 0x87, 0xcd, 0xe4, 0x0a, 0x9d, 0xc9, 0x50, 0x98, 0xa1, 0xd6, 0x77, 0x69, 0x84, - 0xf5, 0x3d, 0xd4, 0xee, 0xbf, 0x3a, 0xca, 0xee, 0x1f, 0x69, 0xbb, 0xaf, 0x8e, 0x61, 0xbb, 0x73, - 0x5b, 0xdb, 0x84, 0xd9, 0x6a, 0xab, 0xd2, 0xeb, 0x39, 0x1d, 0xcb, 0xc7, 0x8d, 0x5a, 0x82, 0x09, - 0xbf, 0x04, 0x53, 0x94, 0xa8, 0xb9, 0x36, 0x60, 0x05, 0xa6, 0x27, 0xbe, 0x71, 0x8a, 0x3d, 0xc2, - 0x2e, 0x4c, 0x10, 0x86, 0x15, 0xe5, 0x7f, 0xcd, 0xc1, 0x82, 0xb0, 0xe3, 0x86, 0x4b, 0xde, 0x75, - 0x28, 0x1a, 0xd6, 0x53, 0x5f, 0x15, 0xbb, 0x72, 0x55, 0x82, 0x6c, 0xce, 0x26, 0xca, 0xe6, 0x98, - 0xac, 0xca, 0x25, 0xc9, 0xaa, 0xf3, 0xd9, 0x75, 0xc9, 0x92, 0x78, 0x3a, 0x55, 0x12, 0xab, 0x52, - 0x6f, 0xe6, 0x4c, 0x76, 0x60, 0x7e, 0x02, 0x3b, 0xf0, 0x4b, 0x50, 0x8a, 0x88, 0x94, 0x90, 0x2f, - 0x0a, 0x8c, 0x26, 0xd3, 0xda, 0xc7, 0x90, 0x37, 0x30, 0x96, 0xbc, 0x19, 0xdf, 0x16, 0x2d, 0x4e, - 0x64, 0x8b, 0xd6, 0xa1, 0x28, 0x5d, 0xb9, 0x86, 0x58, 0xa2, 0x43, 0x4d, 0x98, 0xf2, 0x37, 0xa7, - 0x40, 0x37, 0x2f, 0xd2, 0x26, 0x08, 0x2f, 0x89, 0xd9, 0x49, 0x2e, 0x89, 0xc9, 0xa4, 0x94, 0x4b, - 0x25, 0xa5, 0xb4, 0x4b, 0xe5, 0xd4, 0xc4, 0x97, 0xca, 0xe9, 0x31, 0x2f, 0x95, 0xf9, 0x33, 0x5f, - 0x2a, 0x0b, 0xe3, 0x5f, 0x2a, 0x21, 0x5d, 0x21, 0x13, 0xd1, 0x80, 0x07, 0x3d, 0xeb, 0x25, 0xee, - 0x36, 0xbd, 0x3e, 0xa5, 0x96, 0x9c, 0x21, 0x57, 0x9d, 0xff, 0xda, 0x99, 0xa6, 0xd8, 0xe7, 0xce, - 0xac, 0xd8, 0xe7, 0x47, 0x2a, 0xf6, 0x47, 0xb9, 0xfc, 0x8c, 0x9e, 0x2f, 0xff, 0x70, 0x0a, 0xf2, - 0x46, 0x7b, 0x87, 0xd9, 0x59, 0x3a, 0x64, 0x4d, 0xcf, 0x11, 0xc6, 0xbf, 0xe9, 0x39, 0x44, 0xea, - 0x36, 0xfa, 0x5d, 0xfc, 0x42, 0x48, 0x5d, 0x5a, 0x20, 0x32, 0xae, 0x89, 0x2d, 0x0f, 0x6f, 0x3b, - 0x3d, 0x76, 0x1f, 0x62, 0x56, 0xb1, 0x5a, 0x49, 0x8e, 0xc3, 0x74, 0x4f, 0xfb, 0x44, 0xa2, 0xd3, - 0x9d, 0xe3, 0xa6, 0xb1, 0x5c, 0x87, 0x1e, 0xc1, 0x2c, 0x43, 0xb2, 0x3d, 0xdf, 0x71, 0x5f, 0x72, - 0x59, 0xa8, 0x5c, 0xd9, 0xc4, 0xec, 0x36, 0x65, 0x40, 0x76, 0x2d, 0x52, 0x70, 0xd9, 0x41, 0x7d, - 0xe3, 0xd4, 0x76, 0xd9, 0x70, 0xd3, 0xe2, 0xa0, 0x82, 0x2a, 0xf4, 0x26, 0x2c, 0x7c, 0x58, 0x69, - 0x1a, 0xb8, 0xe3, 0x90, 0xdd, 0xa8, 0xd9, 0x47, 0xd8, 0xf3, 0xb9, 0x73, 0x23, 0xde, 0x80, 0xbe, - 0x00, 0xcb, 0x52, 0x25, 0x1d, 0xb1, 0xea, 0x9c, 0xf6, 0x7d, 0x4a, 0x91, 0x39, 0x23, 0xb9, 0x91, - 0x1c, 0x8c, 0xd4, 0x50, 0x75, 0x4e, 0x06, 0x3d, 0x4c, 0x94, 0x75, 0xdf, 0x77, 0x6d, 0xcc, 0x68, - 0x32, 0x67, 0x0c, 0x03, 0x21, 0xec, 0x22, 0x35, 0x6f, 0x59, 0x1e, 0x26, 0xcb, 0x01, 0x8a, 0x98, - 0xd0, 0x12, 0x81, 0x6f, 0x5a, 0x9e, 0x1f, 0xd2, 0x69, 0x42, 0x0b, 0x7a, 0x04, 0xeb, 0x52, 0xed, - 0xae, 0x6b, 0x1f, 0xd9, 0x7d, 0xab, 0xa7, 0x1e, 0xe8, 0x2c, 0xc5, 0x1e, 0x09, 0x47, 0x08, 0x37, - 0x61, 0x29, 0x94, 0x70, 0xf3, 0x46, 0x52, 0xd3, 0xea, 0xbb, 0xb0, 0x10, 0x3b, 0xc8, 0x51, 0xb7, - 0xce, 0x9c, 0x7c, 0xeb, 0xfc, 0x08, 0x0a, 0x54, 0x3d, 0x76, 0x1c, 0xb7, 0x4b, 0x10, 0xc9, 0x62, - 0x39, 0x22, 0x59, 0xdd, 0x06, 0xe4, 0xcc, 0x97, 0x03, 0x86, 0x37, 0xaf, 0x8a, 0x0d, 0x86, 0x43, - 0x5a, 0x0d, 0x0a, 0x43, 0xe4, 0x2d, 0x15, 0x31, 0x84, 0x7c, 0x67, 0x0d, 0xfa, 0xbb, 0xfc, 0xf3, - 0x0c, 0x00, 0xed, 0x9f, 0x1a, 0x11, 0x04, 0xa4, 0x65, 0x9d, 0x60, 0x21, 0x92, 0xc9, 0x6f, 0x59, - 0xe6, 0x67, 0x54, 0x99, 0xcf, 0xa7, 0x93, 0x0d, 0xa7, 0x53, 0x82, 0x99, 0x1d, 0xeb, 0x45, 0xdb, - 0xfe, 0x3d, 0x71, 0x35, 0x14, 0x45, 0xa2, 0x1f, 0x84, 0x58, 0xae, 0x71, 0xc7, 0x41, 0x58, 0x41, - 0x3d, 0x0a, 0xad, 0x46, 0x8d, 0x53, 0x31, 0xfd, 0x8d, 0xbe, 0x00, 0x19, 0xb3, 0xcd, 0xd5, 0xf7, - 0xea, 0x26, 0x8b, 0xaf, 0x6c, 0x8a, 0xf8, 0xca, 0xa6, 0x29, 0xe2, 0x2b, 0xec, 0x52, 0xfd, 0x67, - 0x3f, 0xbb, 0xa9, 0x19, 0x19, 0xb3, 0x4d, 0x14, 0x6a, 0xa3, 0xdf, 0xe9, 0x9d, 0x76, 0x71, 0xfd, - 0xc5, 0x80, 0x70, 0x02, 0x57, 0x42, 0x5c, 0xbe, 0x61, 0x8f, 0x3b, 0x63, 0x46, 0x40, 0x11, 0x03, - 0xbe, 0xfe, 0x82, 0x42, 0x6c, 0x5b, 0x6e, 0xb7, 0xe6, 0x7c, 0xdc, 0x8f, 0x75, 0xc4, 0x74, 0xfb, - 0x28, 0xb0, 0x72, 0x19, 0xc0, 0xf4, 0x1c, 0xb1, 0xc3, 0x4b, 0x30, 0xc5, 0xd8, 0x8a, 0x1d, 0x22, - 0x2b, 0x94, 0x7f, 0xa9, 0x11, 0x8b, 0x90, 0xea, 0x47, 0xea, 0xa2, 0x4d, 0xd4, 0x8d, 0xf7, 0xa0, - 0xb0, 0x3b, 0x10, 0xb7, 0x87, 0x4c, 0xdc, 0x9d, 0x56, 0x6d, 0x51, 0xdc, 0xdd, 0x81, 0x11, 0xc2, - 0xa1, 0xad, 0x20, 0xd0, 0xc2, 0x14, 0xe5, 0xad, 0x84, 0x40, 0x0b, 0x05, 0x48, 0x8f, 0xb6, 0x5c, - 0xb4, 0xc3, 0xb9, 0xdc, 0x84, 0x62, 0xb5, 0x15, 0xde, 0x77, 0x93, 0xd6, 0xfa, 0x86, 0x70, 0x1b, - 0x66, 0xd2, 0x83, 0x3b, 0x0c, 0xa2, 0xfc, 0x0b, 0xbe, 0x77, 0x96, 0x3f, 0x64, 0xef, 0xc6, 0xef, - 0x6f, 0xf4, 0x8e, 0x89, 0x81, 0x7e, 0x83, 0x3b, 0xf6, 0x9d, 0x3c, 0xcc, 0x08, 0x0a, 0x52, 0x2e, - 0x01, 0x9a, 0xb0, 0xb4, 0x78, 0x05, 0xda, 0x84, 0xe9, 0x1d, 0xec, 0x3f, 0x73, 0xba, 0x49, 0x22, - 0x81, 0xb5, 0x50, 0x91, 0xc0, 0xa1, 0xd0, 0x7d, 0x99, 0xff, 0x29, 0x2b, 0x47, 0xac, 0x8f, 0xb0, - 0x95, 0xaf, 0x51, 0x96, 0x17, 0x15, 0xea, 0x00, 0x0b, 0x4c, 0x3a, 0xca, 0xf4, 0xc5, 0xbb, 0x37, - 0xa2, 0x0e, 0x30, 0xc5, 0xee, 0x33, 0x14, 0x14, 0xf4, 0x80, 0x10, 0x43, 0xd8, 0xc3, 0x14, 0xed, - 0xe1, 0x7a, 0x02, 0x95, 0x86, 0x1d, 0xc8, 0x08, 0x04, 0xdf, 0x94, 0xf0, 0xa7, 0xe3, 0xf8, 0x66, - 0x0c, 0x5f, 0x42, 0x20, 0xe6, 0x57, 0xc8, 0x9e, 0x49, 0xb7, 0x85, 0xb0, 0xd5, 0x90, 0x19, 0xf9, - 0xbe, 0x7a, 0x87, 0xe3, 0x86, 0x5b, 0x49, 0x9d, 0x78, 0xd8, 0x6e, 0xa8, 0x37, 0xbe, 0xfb, 0x2a, - 0xbf, 0xf3, 0x58, 0x42, 0x29, 0x8d, 0x39, 0x0d, 0x55, 0x3a, 0x7c, 0x51, 0x61, 0x20, 0xaa, 0x2c, - 0x23, 0x26, 0xb0, 0xd4, 0x6c, 0x28, 0xcc, 0x76, 0x5f, 0x65, 0x16, 0xaa, 0x38, 0x13, 0x06, 0x16, - 0xed, 0x86, 0xca, 0x5a, 0xef, 0xc2, 0x5c, 0x0d, 0x13, 0xc5, 0xc6, 0xa7, 0xc3, 0x7d, 0x4a, 0x57, - 0x65, 0x74, 0x05, 0xc0, 0x50, 0xe1, 0xd1, 0x16, 0xcc, 0xef, 0xb9, 0xce, 0x8b, 0x97, 0xe1, 0x81, - 0xcd, 0x71, 0x01, 0x2f, 0xf5, 0xa0, 0x42, 0x18, 0x11, 0x0c, 0xa2, 0x85, 0xa3, 0xee, 0xdc, 0xd6, - 0xe9, 0x09, 0x35, 0x02, 0x73, 0x46, 0x52, 0x13, 0xda, 0x92, 0x9c, 0xd3, 0xc1, 0x15, 0xef, 0x72, - 0xfa, 0x15, 0xcf, 0x88, 0x83, 0xd3, 0x3d, 0x7f, 0x86, 0x3b, 0xc7, 0xdb, 0xd8, 0xea, 0xf9, 0xcf, - 0xa8, 0x17, 0x2a, 0xba, 0xe7, 0x61, 0xb3, 0x21, 0xc3, 0x22, 0x13, 0x96, 0xda, 0x9d, 0x67, 0xb8, - 0x7b, 0xda, 0xc3, 0xdc, 0x44, 0xa5, 0x46, 0x3a, 0xf5, 0x47, 0x15, 0xef, 0xae, 0xcb, 0x7d, 0x24, - 0xc1, 0x19, 0x89, 0xd8, 0x65, 0x07, 0x8a, 0x94, 0x13, 0xbd, 0x81, 0xd3, 0xf7, 0xf0, 0x90, 0xab, - 0x19, 0x57, 0xd3, 0x19, 0x45, 0x4d, 0x0b, 0xc3, 0x89, 0x29, 0x6f, 0x51, 0x1c, 0xe6, 0xf6, 0x2f, - 0x6f, 0x02, 0x92, 0xe8, 0x59, 0x1a, 0xf7, 0x7d, 0xdb, 0x95, 0x84, 0x91, 0x28, 0x96, 0xff, 0x2b, - 0x47, 0xdd, 0x88, 0x0c, 0xec, 0x62, 0xa5, 0xd6, 0x75, 0x28, 0xd4, 0x5d, 0xd7, 0x71, 0xab, 0x4e, - 0x17, 0xd3, 0x25, 0xcc, 0x19, 0x61, 0x05, 0x31, 0xc5, 0x69, 0x61, 0x07, 0x7b, 0x9e, 0x75, 0x84, - 0xb9, 0x4f, 0x42, 0xa9, 0x43, 0x6b, 0x00, 0x0d, 0x6f, 0xbb, 0xf2, 0x18, 0xe3, 0x01, 0x76, 0xa9, - 0xd4, 0xc9, 0x1b, 0x52, 0x0d, 0x7a, 0x57, 0xd9, 0x5d, 0x2e, 0x56, 0xae, 0xc4, 0x04, 0x23, 0x6b, - 0xe6, 0x92, 0x51, 0x39, 0x0f, 0xc2, 0x68, 0xd2, 0x25, 0x86, 0x4b, 0x16, 0x95, 0xd1, 0xa4, 0x76, - 0x43, 0x81, 0x26, 0xd4, 0x46, 0x65, 0x0d, 0x1f, 0x3e, 0x1f, 0x1f, 0x5e, 0x6a, 0x36, 0x64, 0x58, - 0xc2, 0x62, 0xd5, 0xde, 0xa9, 0xe7, 0x63, 0xb7, 0x86, 0xc9, 0xed, 0xd4, 0xe3, 0xc2, 0x45, 0x61, - 0x31, 0x15, 0xc2, 0x88, 0x60, 0xa0, 0x07, 0x50, 0x08, 0xa3, 0x1a, 0x90, 0x40, 0xa6, 0xa2, 0x91, - 0x11, 0x28, 0xf6, 0x4e, 0x7b, 0xbe, 0x11, 0xa2, 0xa0, 0x07, 0x00, 0x92, 0x68, 0x64, 0x32, 0x66, - 0x4d, 0xee, 0x20, 0x4e, 0x48, 0x06, 0x44, 0xc4, 0x23, 0x61, 0x20, 0xec, 0x32, 0x09, 0x37, 0x9b, - 0xb0, 0x79, 0x52, 0xbb, 0xa1, 0x40, 0x97, 0x1f, 0x51, 0x3f, 0x18, 0xb3, 0x7f, 0x83, 0x6d, 0x79, - 0x8b, 0x68, 0x50, 0x52, 0xe3, 0x95, 0x34, 0xaa, 0xd7, 0x97, 0x63, 0x87, 0x49, 0x5a, 0xf9, 0x51, - 0x0a, 0xd8, 0xf2, 0xab, 0xca, 0x41, 0x10, 0xf3, 0xed, 0x09, 0xd5, 0xdb, 0xdc, 0x7c, 0xa3, 0x85, - 0xf2, 0x43, 0x98, 0x33, 0x2d, 0xef, 0xd8, 0xb4, 0x0e, 0x7b, 0x78, 0xdf, 0xc3, 0x2e, 0x61, 0x23, - 0xf2, 0xb7, 0x1f, 0xda, 0xd2, 0x41, 0x99, 0xb4, 0xed, 0x59, 0x9e, 0xf7, 0xb1, 0xe3, 0x76, 0xb9, - 0x73, 0x23, 0x28, 0x97, 0xbf, 0xa5, 0x91, 0x59, 0x52, 0xb9, 0x95, 0x68, 0xc6, 0xa4, 0xdb, 0xe2, - 0x8a, 0xff, 0x25, 0x1b, 0x0d, 0x21, 0x05, 0x31, 0xbe, 0x9c, 0x1c, 0xe3, 0x5b, 0xa3, 0xba, 0x5f, - 0x35, 0xca, 0xa5, 0x9a, 0xf2, 0x5f, 0x66, 0x08, 0x0d, 0xf7, 0x9f, 0xda, 0x47, 0xd5, 0x67, 0x56, - 0xff, 0x08, 0xa3, 0x7b, 0xc1, 0xec, 0x78, 0xa8, 0x6b, 0x51, 0xbd, 0x70, 0xd0, 0xa6, 0x70, 0x07, - 0xd9, 0x3a, 0xee, 0x03, 0x30, 0x74, 0xe9, 0xa2, 0x72, 0x3d, 0xee, 0xdf, 0x08, 0x61, 0x0c, 0x09, - 0x1e, 0x99, 0x30, 0xdf, 0xe8, 0xdb, 0xbe, 0x6d, 0xf5, 0x76, 0xf0, 0xc9, 0x21, 0x76, 0x85, 0x55, - 0xf6, 0x66, 0x5a, 0x0f, 0x9b, 0x2a, 0x38, 0xbb, 0x3a, 0x47, 0xfa, 0x58, 0xad, 0xc0, 0x62, 0x02, - 0xd8, 0x44, 0xe1, 0xc0, 0x37, 0x60, 0xae, 0xfd, 0xec, 0xd4, 0xef, 0x3a, 0x1f, 0xf7, 0x99, 0x6a, - 0x23, 0x67, 0x43, 0x7e, 0x04, 0x47, 0x26, 0x8a, 0xe5, 0x7f, 0x98, 0x82, 0xcb, 0x11, 0x11, 0x9e, - 0x78, 0xba, 0xb7, 0x60, 0x6e, 0xcb, 0x71, 0x7c, 0xcf, 0x77, 0xad, 0xc1, 0xc0, 0xee, 0x1f, 0xd1, - 0x41, 0xf3, 0x86, 0x5a, 0x49, 0x44, 0x03, 0xf7, 0xd9, 0xd0, 0x0d, 0xcd, 0xd2, 0x0d, 0x55, 0x44, - 0x83, 0xd4, 0x6c, 0xc8, 0xb0, 0x4c, 0x26, 0x85, 0x5b, 0xc5, 0xcd, 0xb5, 0x52, 0xda, 0x56, 0x1a, - 0xea, 0xe9, 0xbf, 0x1b, 0x59, 0x31, 0xb7, 0xd5, 0xae, 0xaa, 0x82, 0x41, 0x02, 0x30, 0x22, 0x3b, - 0xf4, 0x18, 0x16, 0x98, 0x63, 0x4d, 0xf2, 0xb4, 0x71, 0xc9, 0xaa, 0x98, 0x8c, 0x31, 0x20, 0x23, - 0x8e, 0x17, 0x37, 0x45, 0x66, 0x26, 0x34, 0x45, 0x1e, 0xc3, 0xc2, 0x23, 0xc7, 0xee, 0x33, 0x4f, - 0x35, 0x97, 0x7f, 0x5c, 0xd0, 0x2a, 0xb3, 0x89, 0x01, 0x19, 0x71, 0x3c, 0xb4, 0x0d, 0x3a, 0xeb, - 0x9d, 0xda, 0x2a, 0x6c, 0x42, 0x85, 0xb8, 0x29, 0x1a, 0x85, 0x31, 0x62, 0x58, 0xe4, 0x78, 0x2b, - 0xdd, 0xae, 0xe0, 0xc2, 0x24, 0xdb, 0x4e, 0x6a, 0x36, 0x64, 0x58, 0x22, 0xf9, 0x03, 0x52, 0x61, - 0xd8, 0xc5, 0xb8, 0xe4, 0x57, 0x21, 0x8c, 0x08, 0x46, 0x19, 0x27, 0xdb, 0x2a, 0x89, 0xf4, 0x1a, - 0xa1, 0xc4, 0xcc, 0xf8, 0x94, 0x58, 0xfe, 0xf3, 0x0c, 0xac, 0x44, 0xdc, 0x75, 0xa6, 0xe5, 0x1e, - 0x61, 0x9f, 0x06, 0x36, 0xf9, 0x11, 0x91, 0x41, 0x98, 0xb4, 0x2e, 0x18, 0x4a, 0x1d, 0x75, 0xb6, - 0xc9, 0x30, 0x19, 0x06, 0x23, 0xd7, 0x11, 0x39, 0x5b, 0x7f, 0x41, 0x44, 0x90, 0xed, 0xf3, 0x98, - 0x79, 0x50, 0x26, 0x26, 0x24, 0xef, 0xcf, 0xb4, 0x4f, 0xb0, 0x73, 0xea, 0x9b, 0x76, 0xe7, 0xd8, - 0xe3, 0xd2, 0x31, 0xa9, 0x89, 0x60, 0x98, 0x09, 0x18, 0x4c, 0x68, 0x26, 0x35, 0xa1, 0x2f, 0xc0, - 0x72, 0x9d, 0x88, 0x0b, 0xcb, 0xc7, 0xd5, 0x53, 0xd7, 0xc5, 0x7d, 0x9f, 0xc2, 0x78, 0x3c, 0x72, - 0x91, 0xdc, 0x58, 0xbe, 0x93, 0x40, 0x95, 0x6c, 0x29, 0xb6, 0x47, 0xc3, 0xff, 0x6c, 0x3b, 0x82, - 0x72, 0xb9, 0x97, 0xc0, 0x54, 0xe8, 0x1e, 0xe4, 0x88, 0xbe, 0xe1, 0x52, 0x5a, 0xe1, 0x09, 0x45, - 0x51, 0x71, 0x59, 0x4d, 0x81, 0xe9, 0xa6, 0x5a, 0xde, 0x71, 0xcd, 0xf2, 0xad, 0x43, 0xcb, 0x13, - 0x22, 0x4f, 0xa9, 0x23, 0x52, 0x4f, 0xe5, 0xa2, 0x74, 0xa9, 0xf7, 0x66, 0x9c, 0x25, 0x86, 0x40, - 0xbf, 0xae, 0x90, 0x7d, 0xba, 0x35, 0x5b, 0xfe, 0x95, 0x16, 0xa5, 0xf2, 0xb3, 0x46, 0x25, 0xd0, - 0x93, 0x14, 0xdd, 0xb2, 0x99, 0xce, 0x2f, 0xe3, 0x68, 0x17, 0xc2, 0x2b, 0xe4, 0x0c, 0x79, 0x5c, - 0x81, 0xfe, 0xbe, 0x08, 0x8d, 0xf3, 0xb3, 0x8c, 0x6a, 0x52, 0x06, 0x79, 0x38, 0x9a, 0x94, 0x87, - 0xf3, 0x65, 0x16, 0x50, 0xb7, 0xfa, 0x5d, 0x91, 0x11, 0x74, 0x6d, 0xc8, 0xfd, 0x42, 0xc4, 0xb2, - 0x04, 0x0a, 0xd9, 0x4a, 0xe1, 0x8e, 0xe7, 0x37, 0x03, 0xe1, 0x82, 0xaf, 0x02, 0x70, 0x28, 0xc2, - 0x70, 0x39, 0xda, 0xf5, 0x8d, 0x21, 0x5d, 0x37, 0x6a, 0xc2, 0x5f, 0x10, 0xa2, 0xa1, 0x0f, 0x61, - 0x39, 0x31, 0x90, 0xc5, 0x55, 0xc9, 0x2b, 0x72, 0x7f, 0xc9, 0x19, 0x9c, 0xc9, 0xf8, 0xa3, 0xa3, - 0xb3, 0xd3, 0x63, 0x44, 0x67, 0xcb, 0x7f, 0x95, 0x49, 0x99, 0x1f, 0x21, 0xa4, 0x3d, 0x17, 0x0f, - 0x2c, 0x97, 0xb1, 0x20, 0x39, 0xd7, 0xb0, 0x82, 0xec, 0x5a, 0xbd, 0x4f, 0x78, 0xaa, 0xcb, 0x55, - 0xb6, 0x28, 0xa6, 0x24, 0x57, 0xdd, 0x85, 0xa5, 0x20, 0xb2, 0x4d, 0xd3, 0x52, 0x99, 0xd3, 0x9e, - 0x13, 0x4c, 0x62, 0x1b, 0xda, 0x04, 0x94, 0x10, 0xbd, 0x67, 0xf2, 0x27, 0xa1, 0x85, 0x18, 0x77, - 0x52, 0xb2, 0x01, 0x73, 0xac, 0x4a, 0x35, 0x64, 0x66, 0x2c, 0xf2, 0xcd, 0x52, 0x5a, 0x58, 0x81, - 0x48, 0x1a, 0xb2, 0x68, 0x3f, 0xcc, 0x5a, 0x0b, 0xca, 0xe5, 0x7f, 0xd3, 0xd4, 0x00, 0x7e, 0xb0, - 0x3b, 0x42, 0x72, 0xcb, 0x12, 0x57, 0x1b, 0x4f, 0xe2, 0x66, 0xd2, 0x25, 0xee, 0xdb, 0xb0, 0x12, - 0x4a, 0x0e, 0x05, 0x89, 0xed, 0x65, 0x4a, 0x6b, 0xba, 0xdc, 0xcd, 0x0d, 0x93, 0xbb, 0xbf, 0x28, - 0x42, 0x91, 0xcf, 0x82, 0xde, 0x60, 0x44, 0x2e, 0xa3, 0x26, 0xe5, 0x32, 0xfe, 0xdf, 0x4a, 0x58, - 0xaa, 0x04, 0x7e, 0xce, 0x3c, 0x65, 0xe6, 0x57, 0x13, 0x9c, 0x4f, 0x34, 0x4b, 0x6f, 0xcc, 0x34, - 0xfc, 0xc2, 0x99, 0xd2, 0xf0, 0x21, 0x39, 0x4d, 0x4a, 0x4d, 0x2a, 0x28, 0x8e, 0x93, 0x00, 0x35, - 0x3b, 0x32, 0x01, 0x6a, 0xee, 0x4c, 0x09, 0x50, 0xf3, 0x67, 0x4a, 0xe8, 0xbf, 0x3c, 0x4e, 0x42, - 0xbf, 0x3e, 0x5e, 0x62, 0xd4, 0x42, 0x24, 0x31, 0x6a, 0x44, 0x34, 0x14, 0x5d, 0x44, 0x9a, 0xd3, - 0xe2, 0x45, 0xa5, 0x39, 0x2d, 0x5d, 0x40, 0x9a, 0xd3, 0xf2, 0xf9, 0xd3, 0x9c, 0x56, 0x2e, 0x24, - 0xcd, 0xe9, 0xca, 0x05, 0xa4, 0x39, 0x95, 0xc6, 0x48, 0x73, 0x1a, 0xfe, 0xc4, 0xe1, 0xea, 0xc8, - 0x27, 0x0e, 0xc3, 0xd2, 0xa4, 0x56, 0xcf, 0x93, 0x26, 0x75, 0xed, 0xdc, 0x69, 0x52, 0xd7, 0x7f, - 0x7b, 0x4f, 0x1c, 0x3e, 0xd1, 0xd8, 0x9b, 0x2b, 0xfe, 0x00, 0x89, 0xab, 0x05, 0x2d, 0xf9, 0x01, - 0x92, 0xe5, 0xe3, 0x4d, 0x06, 0xa1, 0x48, 0x3e, 0x56, 0x35, 0x7a, 0x99, 0x99, 0x71, 0x96, 0x69, - 0x40, 0x51, 0x1a, 0x22, 0x61, 0x99, 0x9f, 0x53, 0x97, 0x79, 0x25, 0x45, 0x44, 0xcb, 0x56, 0xe2, - 0xbf, 0xe4, 0x68, 0xca, 0xce, 0x85, 0x28, 0xb2, 0x4f, 0xb3, 0x6c, 0x7e, 0x87, 0xb3, 0x6c, 0x46, - 0x68, 0x89, 0xb9, 0x71, 0x73, 0x66, 0xfe, 0x5a, 0x63, 0x0f, 0x83, 0x46, 0x72, 0x8d, 0x39, 0x8a, - 0x6b, 0xce, 0x47, 0xef, 0x66, 0x32, 0xbd, 0xff, 0x7d, 0x16, 0x40, 0xba, 0x61, 0x26, 0xf9, 0x29, - 0x04, 0x0b, 0x64, 0x24, 0x16, 0xb8, 0x05, 0x73, 0x44, 0x48, 0xe0, 0xbe, 0x6a, 0xa6, 0xa9, 0x95, - 0x11, 0xaa, 0xc9, 0x8d, 0x4d, 0x35, 0xa3, 0xf5, 0xeb, 0xd4, 0x45, 0xe9, 0xd7, 0xe9, 0x0b, 0xd0, - 0xaf, 0x33, 0xe7, 0x7b, 0x72, 0x97, 0x1f, 0xa5, 0x8f, 0xca, 0x7f, 0xa7, 0x05, 0x87, 0x44, 0xc8, - 0xe8, 0xbd, 0x08, 0x19, 0x95, 0x63, 0xd1, 0xbf, 0x51, 0x94, 0xf4, 0xc1, 0x28, 0x4a, 0x7a, 0x53, - 0xa5, 0xa4, 0x95, 0x84, 0x11, 0x1c, 0x17, 0xcb, 0x84, 0xf4, 0x93, 0x4c, 0x34, 0x36, 0x99, 0xe6, - 0xa4, 0x55, 0x09, 0x27, 0x33, 0x9a, 0x70, 0xb2, 0x17, 0x48, 0x38, 0xb9, 0x8b, 0x22, 0x9c, 0xa9, - 0x0b, 0x20, 0x9c, 0xe9, 0x11, 0x84, 0x53, 0xfe, 0xf7, 0x6c, 0x34, 0x1a, 0x85, 0xde, 0x82, 0x3c, - 0x67, 0x65, 0x71, 0xfc, 0x8b, 0x09, 0x6c, 0x2e, 0x4c, 0x6b, 0x01, 0x4a, 0xd0, 0xaa, 0x02, 0x2d, - 0x13, 0x47, 0xab, 0xaa, 0x68, 0x02, 0x14, 0xbd, 0x43, 0xf3, 0xa7, 0x38, 0x1e, 0xd3, 0x62, 0x4b, - 0x49, 0xe9, 0x09, 0x1c, 0x31, 0x04, 0x46, 0x0f, 0xa0, 0x18, 0x12, 0x8a, 0xf0, 0x78, 0xa4, 0xd0, - 0x91, 0x08, 0x00, 0x4a, 0x08, 0xa8, 0x26, 0x5c, 0x65, 0x5d, 0xde, 0x03, 0xcb, 0xf6, 0x2b, 0xc5, - 0xfd, 0xc1, 0x5d, 0xb9, 0x0f, 0x15, 0x29, 0xdd, 0x63, 0x32, 0xfd, 0xeb, 0xf6, 0x98, 0xcc, 0x8c, - 0xe3, 0x31, 0xf9, 0x23, 0x0d, 0x8a, 0xfc, 0x7c, 0xa9, 0xb5, 0xf1, 0x45, 0x7a, 0xb8, 0xcc, 0x66, - 0xd0, 0xb8, 0xcd, 0x10, 0x98, 0x66, 0xbc, 0x45, 0x09, 0xb4, 0x05, 0xe0, 0xe8, 0x3e, 0x3b, 0x29, - 0x86, 0x9b, 0xe1, 0x7b, 0x15, 0x9a, 0x75, 0xc2, 0xe3, 0x2d, 0x23, 0x87, 0x08, 0xe5, 0xef, 0xe7, - 0x60, 0x99, 0x3b, 0xd8, 0x84, 0x9b, 0x9e, 0x27, 0x6a, 0xbc, 0x06, 0xf3, 0xad, 0xd3, 0x93, 0xdd, - 0xa7, 0x61, 0xe7, 0xcc, 0x14, 0x8a, 0xd4, 0x12, 0xc6, 0xa6, 0x35, 0xc1, 0xfc, 0x99, 0xba, 0x50, - 0x2b, 0xd1, 0x06, 0xe8, 0x02, 0x2f, 0x48, 0x69, 0x67, 0xfe, 0x88, 0x58, 0x3d, 0xb9, 0x0d, 0xb6, - 0xf0, 0x0b, 0x3f, 0x08, 0xa5, 0xf3, 0x12, 0x32, 0xa1, 0xc8, 0x7e, 0x6d, 0xbd, 0x7c, 0x8c, 0x45, - 0x16, 0xe8, 0x5d, 0xf9, 0x24, 0x13, 0x57, 0xb2, 0x29, 0x21, 0x31, 0xc7, 0xa3, 0xdc, 0x0d, 0x7a, - 0x9a, 0x94, 0xe4, 0xc0, 0x5e, 0xe0, 0xbd, 0x33, 0x46, 0xdf, 0x51, 0xd4, 0xe8, 0x53, 0xbc, 0x20, - 0x11, 0x82, 0x5a, 0x5e, 0x47, 0x22, 0x32, 0xc3, 0x13, 0x1e, 0x85, 0x9f, 0x21, 0xde, 0xb2, 0xfa, - 0x00, 0xf4, 0xe8, 0xc4, 0x93, 0x1f, 0x3c, 0x24, 0x67, 0x40, 0x2a, 0xaf, 0xf7, 0x94, 0xc9, 0x8d, - 0xea, 0x45, 0x71, 0x9e, 0xfe, 0xb7, 0x06, 0x57, 0x0d, 0xec, 0x31, 0x6f, 0xf3, 0x87, 0x96, 0x8f, - 0xdd, 0x13, 0xcb, 0x3d, 0x16, 0x34, 0x12, 0x9e, 0x94, 0xa6, 0x9c, 0xd4, 0x57, 0xd4, 0x93, 0x62, - 0x54, 0xf9, 0x76, 0xc4, 0x15, 0x90, 0xdc, 0xe7, 0x88, 0xd3, 0x4a, 0xde, 0xc5, 0xec, 0xaf, 0x6b, - 0x17, 0xcb, 0xff, 0x9c, 0x63, 0x6f, 0x15, 0x87, 0xde, 0x0b, 0x3e, 0x7d, 0x17, 0xf2, 0xe9, 0xbb, - 0x90, 0xf1, 0xde, 0x85, 0xfc, 0x63, 0x86, 0xbf, 0x19, 0x27, 0xe6, 0xdc, 0x83, 0xe0, 0x9a, 0xc8, - 0x44, 0xfe, 0x7a, 0x4c, 0xc1, 0x52, 0x63, 0x8e, 0x82, 0xa8, 0xc6, 0x1c, 0x93, 0xa9, 0x0f, 0x02, - 0x73, 0x30, 0x33, 0x0c, 0x3f, 0xd5, 0x18, 0x6c, 0x43, 0x51, 0xea, 0x3c, 0x21, 0xa6, 0xb2, 0xa9, - 0x1a, 0x83, 0xa9, 0x0f, 0x74, 0x65, 0xb1, 0xd3, 0x1e, 0x65, 0x61, 0x8e, 0xea, 0x34, 0xe9, 0xb2, - 0xf2, 0x9f, 0x79, 0x35, 0xb1, 0x25, 0x91, 0x0b, 0xdf, 0x55, 0x54, 0x6a, 0xe2, 0xd5, 0x3f, 0x6c, - 0x16, 0x96, 0x87, 0xac, 0x84, 0xef, 0x05, 0x17, 0x36, 0x6e, 0x79, 0x2e, 0x26, 0x5c, 0xd3, 0x44, - 0x9a, 0x86, 0xb8, 0xda, 0xbd, 0x1d, 0x1e, 0x28, 0xbf, 0xe8, 0x2c, 0x25, 0x1d, 0x43, 0x48, 0xe5, - 0xfc, 0xf0, 0xef, 0x05, 0x3e, 0x15, 0x1e, 0xc4, 0x59, 0x4c, 0xf0, 0xa4, 0x88, 0xc1, 0x84, 0xf7, - 0xe5, 0x8e, 0x48, 0xc7, 0x65, 0x2e, 0x6d, 0x25, 0x40, 0x29, 0x52, 0xb0, 0x94, 0xa4, 0xdc, 0x16, - 0xe7, 0x75, 0x1e, 0x63, 0xe2, 0x69, 0x41, 0x33, 0x14, 0x7b, 0x2d, 0x1a, 0xde, 0x54, 0xa1, 0x8c, - 0x04, 0x4c, 0x54, 0x8f, 0x64, 0xec, 0x70, 0xc6, 0x1e, 0x19, 0x29, 0x8d, 0xe4, 0xf9, 0x08, 0xbd, - 0xd1, 0xe5, 0x2f, 0x1d, 0x78, 0x09, 0x3d, 0x56, 0xf5, 0x06, 0x50, 0xb2, 0x7e, 0x23, 0x2d, 0x7d, - 0x69, 0x84, 0xaa, 0xb8, 0x2f, 0xdf, 0x9d, 0x78, 0x48, 0x7f, 0x25, 0xf9, 0xc6, 0x24, 0x42, 0x6e, - 0xd2, 0x5d, 0x4b, 0x76, 0x65, 0xcf, 0x4e, 0xf6, 0x96, 0x37, 0x29, 0xcb, 0x72, 0x2e, 0x3d, 0xcb, - 0x72, 0x3b, 0xc9, 0x00, 0x99, 0x1f, 0x29, 0x30, 0x13, 0x4c, 0x8c, 0xfb, 0x70, 0x35, 0xae, 0x02, - 0xf7, 0x70, 0xbf, 0x6b, 0xf7, 0x8f, 0xa8, 0x67, 0x3d, 0x6f, 0xa4, 0x03, 0xa0, 0x2d, 0xb8, 0xae, - 0xa8, 0x63, 0xaa, 0xa0, 0xa5, 0x8b, 0x0f, 0x7b, 0x40, 0x3c, 0x14, 0x86, 0x5c, 0x78, 0x13, 0x06, - 0xa0, 0x01, 0xbf, 0xe0, 0x21, 0xf1, 0x10, 0x08, 0xf4, 0x1e, 0x5c, 0x8b, 0xb7, 0x06, 0x6f, 0x5f, - 0x84, 0x8b, 0x7e, 0x08, 0xc8, 0xb9, 0x15, 0xfe, 0xb7, 0x35, 0x98, 0x95, 0xaf, 0x12, 0x89, 0x97, - 0xd9, 0xeb, 0x50, 0x60, 0x01, 0x34, 0x91, 0xbf, 0x51, 0x30, 0xc2, 0x0a, 0x54, 0x82, 0x19, 0x55, - 0xcb, 0x8b, 0xa2, 0x14, 0xe7, 0xc8, 0x29, 0x71, 0x8e, 0x55, 0xc8, 0xd7, 0x9c, 0x8f, 0xfb, 0xb4, - 0x65, 0x8a, 0xb6, 0x04, 0xe5, 0xf2, 0x5f, 0x94, 0x41, 0x17, 0xbc, 0x1d, 0xbc, 0xc1, 0x0a, 0x5e, - 0x5c, 0x69, 0xf2, 0x8b, 0xab, 0x24, 0x87, 0x4d, 0x68, 0xa2, 0x65, 0x15, 0x13, 0x6d, 0x57, 0x65, - 0x35, 0x76, 0x4d, 0xfb, 0x5c, 0x92, 0x40, 0x09, 0x9e, 0x56, 0x0d, 0x67, 0xb7, 0xa4, 0xaf, 0x5b, - 0xfc, 0xd6, 0xe5, 0x55, 0x17, 0xf4, 0x48, 0x7c, 0x5d, 0x84, 0xed, 0xee, 0x0e, 0x5d, 0x6a, 0x14, - 0x49, 0x56, 0x9f, 0xb1, 0x1e, 0x51, 0x43, 0xbe, 0x82, 0xb1, 0x0f, 0x73, 0x7d, 0x76, 0x68, 0xf7, - 0x01, 0x34, 0xdb, 0xc7, 0x10, 0x5b, 0x56, 0x0b, 0x30, 0xb6, 0x5a, 0x90, 0x14, 0x57, 0xf1, 0x4c, - 0x8a, 0x6b, 0x76, 0x02, 0xc5, 0x15, 0x51, 0xb3, 0x73, 0x13, 0xab, 0xd9, 0x98, 0x0e, 0x99, 0x3f, - 0x93, 0x0e, 0x51, 0xc5, 0xfb, 0xe5, 0x09, 0xc5, 0x7b, 0xcc, 0xcb, 0xa0, 0x9f, 0xc5, 0xcb, 0x90, - 0x22, 0xec, 0x17, 0x26, 0x14, 0xf6, 0xe8, 0xc2, 0x85, 0xfd, 0xe2, 0x79, 0x85, 0xfd, 0xd2, 0xb9, - 0x85, 0xfd, 0xf2, 0x79, 0x85, 0xfd, 0xca, 0x48, 0x61, 0x8f, 0xde, 0x8e, 0x65, 0xc3, 0x89, 0x7c, - 0x12, 0x16, 0x71, 0x4c, 0x69, 0x4d, 0xb8, 0x62, 0x84, 0x59, 0x2a, 0xa5, 0xc4, 0x2b, 0x46, 0x98, - 0xb4, 0xf2, 0x75, 0x58, 0x8a, 0xb4, 0x89, 0xe8, 0x62, 0xec, 0x92, 0x1b, 0xe3, 0xfb, 0x24, 0x44, - 0x26, 0x02, 0x12, 0xfb, 0x44, 0x83, 0xd8, 0xfa, 0xaa, 0x2d, 0x11, 0x8d, 0x8c, 0x39, 0x28, 0x46, - 0x8d, 0xc6, 0x51, 0xd9, 0x78, 0x29, 0xfd, 0x26, 0x8c, 0x68, 0xb6, 0x44, 0x08, 0x73, 0xe2, 0x11, - 0xcd, 0x61, 0x23, 0xf2, 0x46, 0xb4, 0x0d, 0x37, 0x23, 0x2d, 0x3c, 0x75, 0xca, 0xab, 0x78, 0x9e, - 0x7d, 0xd4, 0xc7, 0x5d, 0x1a, 0xfb, 0xcc, 0x1b, 0xa3, 0xc0, 0x50, 0x13, 0x5e, 0x89, 0xae, 0x2a, - 0x48, 0xa1, 0x0a, 0xfa, 0xba, 0x41, 0xfb, 0x1a, 0x0d, 0x98, 0x7a, 0x95, 0x0c, 0x29, 0x65, 0x6d, - 0xc8, 0x55, 0x32, 0xa4, 0x97, 0xad, 0x94, 0xec, 0x1f, 0x41, 0xa9, 0x37, 0xe3, 0xb1, 0xf1, 0x28, - 0x4c, 0x6a, 0x1c, 0x81, 0x79, 0x93, 0xd7, 0x29, 0xaf, 0x0e, 0x81, 0x40, 0x8f, 0x60, 0x3d, 0x31, - 0x6e, 0x2e, 0x27, 0x51, 0xbd, 0x42, 0xe7, 0x31, 0x12, 0x6e, 0x8c, 0x9c, 0x81, 0xf2, 0x58, 0x39, - 0x03, 0xdf, 0xd4, 0xe0, 0x46, 0xe2, 0x94, 0xa9, 0xfb, 0x82, 0x50, 0xdc, 0xab, 0x94, 0xe2, 0xde, - 0x1d, 0x4a, 0x71, 0x43, 0x7b, 0x60, 0x84, 0x37, 0x7c, 0x14, 0xf4, 0x07, 0x69, 0xe9, 0x59, 0x82, - 0xd5, 0x6e, 0xd1, 0x69, 0x3c, 0x98, 0x7c, 0x1a, 0x0a, 0xc3, 0x0d, 0x1d, 0x03, 0x7d, 0x4b, 0x4b, - 0x09, 0x3c, 0x50, 0x95, 0xc5, 0xe6, 0xf1, 0x19, 0x3a, 0x8f, 0xca, 0xe4, 0xf3, 0x08, 0xfb, 0x60, - 0x53, 0x19, 0x35, 0x12, 0xfa, 0x63, 0x2d, 0x85, 0xf6, 0xab, 0x2d, 0x9e, 0xb3, 0x56, 0x7a, 0x8d, - 0x4e, 0xe6, 0xbd, 0xb3, 0x6c, 0x0a, 0xef, 0x82, 0xcd, 0x65, 0xc4, 0x38, 0xe8, 0x3b, 0x1a, 0xbc, - 0x92, 0x3e, 0x5d, 0x31, 0x9b, 0xd7, 0xe9, 0x6c, 0xaa, 0x67, 0xdc, 0x1a, 0x65, 0x42, 0xa3, 0x47, - 0x4b, 0xe5, 0x68, 0xa1, 0x7c, 0x6f, 0x0f, 0xe1, 0x68, 0xa1, 0x7f, 0xbf, 0xab, 0x41, 0x79, 0xe8, - 0xd2, 0x59, 0xca, 0xde, 0x1b, 0x74, 0x61, 0xb5, 0xb3, 0x6f, 0x33, 0xed, 0x86, 0xad, 0x6c, 0x8c, - 0xf1, 0xd0, 0xf7, 0x35, 0xf8, 0xcc, 0xa8, 0x0d, 0x60, 0x33, 0xdb, 0xa0, 0x33, 0x7b, 0x78, 0xae, - 0x2d, 0x97, 0x26, 0x37, 0xde, 0xa8, 0xe7, 0x76, 0x8a, 0x7f, 0x04, 0xcb, 0x89, 0xa6, 0xfd, 0x84, - 0x7e, 0x2a, 0xe5, 0x05, 0x9a, 0xd4, 0xfd, 0x7d, 0xfa, 0xa9, 0xbb, 0x14, 0xa7, 0xda, 0xc8, 0xc9, - 0x3d, 0x84, 0xab, 0xa9, 0x06, 0xc2, 0xa8, 0x8e, 0xf2, 0x72, 0x47, 0x8d, 0x58, 0x0a, 0x83, 0x2c, - 0x8a, 0xce, 0xd9, 0x95, 0x79, 0xd6, 0xae, 0xf6, 0x52, 0x28, 0x5e, 0x91, 0xd6, 0x13, 0xf5, 0xb8, - 0x9b, 0x22, 0x1b, 0xce, 0xbc, 0x5a, 0x03, 0x6e, 0x8d, 0x23, 0x41, 0x27, 0xea, 0xf3, 0x03, 0x78, - 0x75, 0x0c, 0x41, 0x38, 0x11, 0xa1, 0x98, 0xf0, 0xda, 0x78, 0xd2, 0x6c, 0xa2, 0x5e, 0xf7, 0xe1, - 0xf5, 0x31, 0x45, 0xc9, 0x44, 0xdd, 0x7e, 0x05, 0x36, 0xc6, 0x97, 0x03, 0x13, 0xb9, 0x6a, 0x1a, - 0x2c, 0x1b, 0x48, 0x7c, 0x55, 0xf2, 0x1c, 0xdf, 0x45, 0x2a, 0xff, 0x4d, 0x06, 0x96, 0x92, 0x1e, - 0x67, 0x0e, 0x79, 0x23, 0xb1, 0x17, 0xfb, 0x86, 0xe8, 0xe6, 0xa8, 0xa7, 0x9e, 0xea, 0xb7, 0x44, - 0x63, 0x81, 0x99, 0x0b, 0xf9, 0xa2, 0xe8, 0xaa, 0x39, 0xfa, 0x93, 0x9f, 0xc3, 0xd2, 0x85, 0xa4, - 0x1d, 0x95, 0xf7, 0xfa, 0x87, 0x1a, 0xc0, 0x96, 0xd5, 0x39, 0x3e, 0x1d, 0xd0, 0xd8, 0x4e, 0x5a, - 0xe0, 0xaf, 0x91, 0x14, 0xf8, 0x7b, 0x5d, 0x79, 0x17, 0x12, 0x74, 0x32, 0xdc, 0x9f, 0x74, 0x6e, - 0x47, 0xde, 0x1f, 0x6a, 0x22, 0x6e, 0xd5, 0xf0, 0xf1, 0x49, 0xe2, 0x27, 0x5a, 0xca, 0x30, 0xcb, - 0xb3, 0xd9, 0x9f, 0x48, 0xd1, 0x4f, 0xa5, 0x8e, 0xc0, 0xd4, 0xf0, 0x53, 0xeb, 0xb4, 0xc7, 0x61, - 0x98, 0x47, 0x4f, 0xa9, 0x23, 0x47, 0xd4, 0xe8, 0xfb, 0xd8, 0xed, 0x5b, 0x3d, 0x1e, 0xb0, 0x0b, - 0xca, 0xe5, 0xbf, 0xd5, 0xe4, 0xf0, 0x19, 0xfa, 0x32, 0xcc, 0x54, 0x9d, 0xbe, 0x8f, 0xe9, 0x97, - 0x4c, 0xe2, 0xe9, 0xe3, 0x01, 0xe0, 0x26, 0x87, 0x62, 0x1b, 0x23, 0x70, 0x56, 0x0d, 0xfa, 0x12, - 0x31, 0x68, 0x98, 0x30, 0x81, 0x27, 0xdc, 0x0e, 0x79, 0xa3, 0x7e, 0x3f, 0x8c, 0xd3, 0xa1, 0xb7, - 0xc2, 0x77, 0xba, 0xb1, 0x3c, 0x35, 0x01, 0xb4, 0x49, 0x21, 0xd8, 0xc4, 0x18, 0xf4, 0xea, 0x3b, - 0x00, 0x61, 0xe5, 0x44, 0xf1, 0xe5, 0xd7, 0x95, 0xcf, 0x03, 0x0c, 0x79, 0xbf, 0xf4, 0x11, 0x2c, - 0xc4, 0x5e, 0xca, 0xa0, 0x5b, 0x30, 0xc7, 0xbe, 0x38, 0x24, 0x1e, 0xdf, 0x30, 0x24, 0xb5, 0x92, - 0x1e, 0x33, 0x47, 0x91, 0xbe, 0x52, 0xa5, 0xd4, 0x6d, 0x7c, 0x0c, 0xb0, 0x3f, 0xe8, 0x5a, 0x3e, - 0xf3, 0xe0, 0x5e, 0x81, 0x45, 0xe5, 0x0b, 0x46, 0xac, 0x49, 0xbf, 0x84, 0x96, 0x61, 0x41, 0x7c, - 0x99, 0xaa, 0xd9, 0x6e, 0xf1, 0x6a, 0x0d, 0x2d, 0xc2, 0xe5, 0x7d, 0x0f, 0xbb, 0x74, 0xf9, 0xbc, - 0x32, 0x83, 0xe6, 0xa0, 0x60, 0xb6, 0x77, 0x79, 0x31, 0x4b, 0x50, 0x83, 0xaf, 0x4c, 0x05, 0xa8, - 0xb9, 0x8d, 0x4d, 0x28, 0x04, 0xdf, 0x73, 0x46, 0x97, 0xa1, 0xd8, 0x72, 0xdc, 0x13, 0xab, 0x47, - 0x8b, 0xfa, 0x25, 0xa4, 0xc3, 0x2c, 0x7f, 0xa4, 0xc1, 0x6a, 0xb4, 0x8d, 0x5f, 0xe6, 0x00, 0xc2, - 0x97, 0xfd, 0x68, 0x1e, 0xc0, 0x6c, 0xef, 0x1e, 0xec, 0xef, 0xd5, 0x2a, 0x66, 0x5d, 0xbf, 0x84, - 0x00, 0xa6, 0x2b, 0x7b, 0x7b, 0xf5, 0x56, 0x4d, 0xd7, 0x50, 0x1e, 0x72, 0x46, 0xbd, 0x52, 0xd3, - 0x33, 0x68, 0x16, 0xf2, 0xa6, 0xb1, 0xdf, 0xaa, 0x12, 0x98, 0x2c, 0xe9, 0xf4, 0x61, 0xdd, 0x3c, - 0x08, 0x6a, 0x72, 0xa8, 0x08, 0x33, 0xd5, 0xdd, 0x56, 0xab, 0x5e, 0x35, 0xf5, 0x29, 0xd2, 0x25, - 0x2f, 0x1c, 0x18, 0xbb, 0xfa, 0x34, 0x5a, 0x80, 0xb9, 0xe6, 0xee, 0xc3, 0x83, 0xed, 0x7a, 0xc5, - 0x30, 0xb7, 0xea, 0x15, 0x53, 0x9f, 0x21, 0x3d, 0x54, 0x5b, 0x52, 0x4d, 0x9e, 0x4e, 0x54, 0xae, - 0x29, 0x20, 0x04, 0xf3, 0xd5, 0xed, 0x7a, 0xf5, 0xf1, 0xc1, 0x76, 0xe5, 0x71, 0xbd, 0xbe, 0x57, - 0x37, 0x74, 0x20, 0xfb, 0x4a, 0x46, 0xae, 0x36, 0xf7, 0xdb, 0x66, 0xdd, 0x38, 0xa8, 0xd5, 0xcd, - 0x4a, 0xa3, 0xd9, 0xd6, 0x8b, 0x04, 0x98, 0x34, 0xb4, 0xb7, 0x2b, 0x46, 0xed, 0xa0, 0xd1, 0x7a, - 0x7f, 0x57, 0x9f, 0xa5, 0x1d, 0xb4, 0x0e, 0x2a, 0xcd, 0xe6, 0x2e, 0x99, 0xe5, 0x41, 0xa3, 0xa6, - 0xcf, 0x91, 0x4d, 0x94, 0x3b, 0x68, 0x9b, 0x64, 0xfe, 0xf3, 0x74, 0xff, 0xe9, 0x0e, 0x1c, 0x54, - 0x5b, 0x07, 0xcd, 0xca, 0x56, 0xbd, 0xa9, 0x5f, 0x46, 0x25, 0x58, 0x0a, 0x2b, 0x3f, 0xdc, 0x35, - 0x1e, 0x73, 0x70, 0x9d, 0xf4, 0xbc, 0x57, 0x31, 0xab, 0xdb, 0xa4, 0xa1, 0x6d, 0xee, 0x1a, 0x75, - 0x7d, 0x81, 0x74, 0x51, 0xab, 0x37, 0xeb, 0x0c, 0x9a, 0x55, 0x22, 0x52, 0xb9, 0x67, 0xec, 0x7e, - 0xe5, 0xab, 0xd2, 0xc2, 0x16, 0xd1, 0x2b, 0x70, 0x83, 0xf7, 0xdb, 0xda, 0x6d, 0x1d, 0x3c, 0xd9, - 0x35, 0x1b, 0xad, 0x87, 0x07, 0x46, 0x7d, 0xaf, 0xd9, 0xa8, 0x56, 0x0e, 0x5a, 0xfb, 0x3b, 0xfa, - 0x12, 0x5a, 0x83, 0xd5, 0x38, 0x08, 0x59, 0x47, 0xb3, 0x61, 0x7e, 0x55, 0x5f, 0x46, 0x4b, 0xa0, - 0xb7, 0xeb, 0xe6, 0x81, 0x51, 0xff, 0x60, 0xbf, 0x61, 0xd4, 0x6b, 0x07, 0xcd, 0x76, 0x4b, 0x5f, - 0x21, 0xb5, 0x0f, 0xa3, 0xb5, 0x57, 0xc4, 0xd6, 0x34, 0x2b, 0x66, 0xbd, 0x6d, 0xd2, 0xba, 0x12, - 0x39, 0x12, 0x5a, 0x57, 0xaf, 0xd4, 0xea, 0x06, 0xd9, 0x99, 0xab, 0xf4, 0x48, 0xd8, 0x76, 0xd7, - 0x2b, 0x4d, 0x73, 0x5b, 0x5f, 0x25, 0x87, 0x4e, 0x8e, 0x9f, 0xa2, 0x5c, 0x43, 0x57, 0x61, 0x99, - 0x4f, 0xa9, 0x59, 0xaf, 0xb4, 0xeb, 0xdb, 0xbb, 0x4d, 0x8e, 0x7a, 0x9d, 0x34, 0xd1, 0xcd, 0xaf, - 0x6e, 0xd7, 0x6b, 0xfb, 0xcd, 0xfa, 0x41, 0x75, 0x77, 0x67, 0xa7, 0xd2, 0xaa, 0xb5, 0xf5, 0x1b, - 0x1b, 0x2d, 0x80, 0xf0, 0x7b, 0x58, 0x84, 0x32, 0x08, 0x99, 0xb3, 0x1a, 0xfd, 0x12, 0x19, 0x41, - 0xc8, 0x39, 0x5d, 0x23, 0xc4, 0x4b, 0x99, 0x26, 0x60, 0x80, 0x05, 0xfe, 0x01, 0x38, 0x03, 0x7f, - 0x1d, 0x77, 0x7c, 0xdc, 0xd5, 0xb3, 0x1b, 0x1b, 0x50, 0x08, 0x3e, 0xb7, 0x44, 0xd0, 0xdb, 0xd8, - 0xa7, 0x25, 0xfd, 0x12, 0x41, 0x67, 0xce, 0x55, 0x56, 0xa1, 0x6d, 0xfc, 0x53, 0x0e, 0x90, 0xb8, - 0x52, 0x48, 0xbc, 0x49, 0x28, 0xde, 0xee, 0x1c, 0xcb, 0x2c, 0x29, 0x7d, 0xd7, 0x26, 0x60, 0x49, - 0xc2, 0xa9, 0xb1, 0xea, 0x0c, 0x5a, 0xa1, 0xf9, 0x23, 0xd1, 0xfa, 0x2c, 0x19, 0xfd, 0x21, 0xf6, - 0x03, 0x4e, 0xcf, 0x91, 0x4d, 0x89, 0xc8, 0x1b, 0xde, 0x34, 0x45, 0x4e, 0xa4, 0x8d, 0x19, 0x43, - 0xf2, 0xba, 0x69, 0x42, 0x6c, 0x6a, 0x82, 0x10, 0x6f, 0x99, 0x41, 0x37, 0xe1, 0x5a, 0x1b, 0xfb, - 0xf1, 0xd8, 0x04, 0x07, 0xc8, 0xa3, 0x55, 0x58, 0xe1, 0x00, 0x81, 0x73, 0x9b, 0xb7, 0x15, 0xc8, - 0x16, 0xb2, 0xdf, 0x7c, 0xd7, 0x74, 0x20, 0x0b, 0x13, 0x55, 0xc1, 0xf3, 0x20, 0xbd, 0x48, 0xce, - 0x7f, 0x8f, 0xc8, 0x3b, 0x9e, 0xc1, 0xa7, 0xcf, 0x12, 0x5c, 0x03, 0x9f, 0x38, 0xcf, 0xc5, 0x9b, - 0x53, 0x7d, 0x8e, 0xcc, 0x52, 0x4d, 0xd5, 0xe4, 0x03, 0xcd, 0xa3, 0x1b, 0x70, 0x95, 0xfd, 0x4e, - 0x70, 0x5a, 0xeb, 0x97, 0xd1, 0x35, 0xb8, 0x12, 0x69, 0x16, 0xda, 0x80, 0xb1, 0x93, 0xb8, 0xf5, - 0xf0, 0xfe, 0x16, 0xd0, 0x75, 0x28, 0xc5, 0x53, 0x7c, 0x78, 0x2b, 0x42, 0xb7, 0x60, 0x5d, 0x38, - 0x71, 0xe3, 0xee, 0x5d, 0x0e, 0xb5, 0x48, 0x76, 0x8e, 0x39, 0xc0, 0x22, 0x37, 0x10, 0x0e, 0xb0, - 0x84, 0x3e, 0x03, 0xaf, 0x30, 0x80, 0x44, 0x03, 0x93, 0x83, 0x2d, 0x6f, 0x7c, 0x4f, 0x83, 0x39, - 0x25, 0xda, 0x44, 0xf8, 0x5a, 0x54, 0xf0, 0x2c, 0x17, 0xfd, 0x12, 0x39, 0x71, 0x51, 0xa9, 0x7c, - 0x39, 0x40, 0xd7, 0xc8, 0x40, 0xb1, 0x26, 0x71, 0x7f, 0x34, 0x70, 0x07, 0xdb, 0xcf, 0x71, 0x57, - 0xcf, 0x90, 0x5d, 0x8a, 0x81, 0xbd, 0x6f, 0xd9, 0x3d, 0x42, 0xfa, 0xf2, 0x98, 0xc6, 0x69, 0xbf, - 0x4f, 0x3a, 0xce, 0x6d, 0x1c, 0x26, 0xc5, 0xbb, 0xc8, 0x31, 0x29, 0xb5, 0xe1, 0x1c, 0xa3, 0x2d, - 0xa2, 0x27, 0x2d, 0xd6, 0xd2, 0xf6, 0x9d, 0xc1, 0x80, 0xcc, 0x6a, 0xe3, 0x27, 0x1a, 0xe8, 0xd1, - 0x6f, 0x45, 0x10, 0x2e, 0xaa, 0x74, 0xc5, 0xe7, 0xdb, 0xf4, 0x4b, 0x21, 0xb1, 0x88, 0x2a, 0x8d, - 0x50, 0x54, 0xdb, 0xb7, 0x5c, 0x5f, 0xd4, 0x64, 0x08, 0x93, 0x90, 0x6e, 0x45, 0x45, 0x96, 0xf4, - 0xf2, 0xd8, 0xee, 0xf5, 0xbe, 0xe6, 0x9c, 0x1c, 0xda, 0x84, 0x69, 0xae, 0xc0, 0x62, 0xa5, 0xdb, - 0x8d, 0x92, 0x90, 0x3e, 0x45, 0x68, 0x9c, 0x75, 0x1f, 0x6b, 0x9b, 0xa6, 0x9c, 0x46, 0xc6, 0x89, - 0x35, 0xcd, 0x90, 0x45, 0x91, 0x01, 0x63, 0x2d, 0xf9, 0x8d, 0x1d, 0xe5, 0x0d, 0x3d, 0x99, 0x48, - 0x48, 0x48, 0xfa, 0x25, 0xaa, 0x7b, 0x5b, 0xa2, 0xa8, 0x91, 0x62, 0x35, 0x28, 0x66, 0x28, 0xaf, - 0xd0, 0x50, 0x10, 0xaf, 0xc9, 0x6e, 0x35, 0x7e, 0xfc, 0x8b, 0xb5, 0x4b, 0x3f, 0xfa, 0x64, 0x4d, - 0xfb, 0xf1, 0x27, 0x6b, 0xda, 0xcf, 0x3f, 0x59, 0xbb, 0xf4, 0x83, 0xff, 0x58, 0xd3, 0xbe, 0x76, - 0x4f, 0xfa, 0x67, 0x46, 0x27, 0x96, 0xef, 0xda, 0x2f, 0x1c, 0x6a, 0x58, 0x88, 0x42, 0x1f, 0xdf, - 0x19, 0x1c, 0x1f, 0xdd, 0x19, 0x1c, 0xde, 0x09, 0xcd, 0xa4, 0xc3, 0x69, 0xfa, 0xad, 0xbd, 0x7b, - 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x75, 0x47, 0x6b, 0x28, 0x69, 0x00, 0x00, + // 6109 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3d, 0x5b, 0x6f, 0x1b, 0xd9, + 0x79, 0x1e, 0x92, 0x92, 0xc8, 0x8f, 0x92, 0x3c, 0x3a, 0xba, 0x98, 0x96, 0x6d, 0x59, 0xcb, 0x75, + 0x76, 0xbd, 0xca, 0x46, 0x4e, 0xed, 0xec, 0x62, 0x93, 0x3a, 0xde, 0xa5, 0x48, 0xae, 0x45, 0x9b, + 0xa6, 0xb4, 0xc3, 0x91, 0x37, 0x09, 0xb0, 0x10, 0x46, 0xe4, 0xb1, 0x3c, 0x11, 0xc5, 0x61, 0x66, + 0x46, 0x5e, 0xab, 0x7d, 0x6a, 0xd1, 0x14, 0x45, 0x83, 0x06, 0x0d, 0x10, 0xb4, 0x41, 0xd3, 0xf4, + 0xf6, 0xd6, 0xa7, 0xbc, 0xf4, 0x37, 0x14, 0x79, 0x28, 0x8a, 0x34, 0x8f, 0x05, 0x9a, 0xcb, 0xf6, + 0xa5, 0x40, 0xde, 0x9b, 0xa7, 0x02, 0xc5, 0xb9, 0xcd, 0x9c, 0x33, 0x17, 0x5e, 0x24, 0x25, 0x69, + 0x8a, 0x3c, 0x89, 0xe7, 0x3b, 0xdf, 0x77, 0xae, 0xdf, 0xed, 0x7c, 0xe7, 0x3b, 0x23, 0xd0, 0x7b, + 0xce, 0xa1, 0x87, 0xdd, 0x17, 0x76, 0x07, 0x6f, 0x0e, 0x5c, 0xc7, 0x77, 0x10, 0x84, 0x90, 0xd5, + 0xcf, 0x1c, 0xda, 0xfe, 0xf3, 0x93, 0x83, 0xcd, 0x8e, 0x73, 0x7c, 0xe7, 0xd0, 0x39, 0x74, 0xee, + 0x50, 0x94, 0x83, 0x93, 0x67, 0xb4, 0x44, 0x0b, 0xf4, 0x17, 0x23, 0x5d, 0xbd, 0x79, 0xe8, 0x38, + 0x87, 0x3d, 0x1c, 0x62, 0xf9, 0xf6, 0x31, 0xf6, 0x7c, 0xeb, 0x78, 0xc0, 0x11, 0xe6, 0x8f, 0xb1, + 0x6f, 0x75, 0x2d, 0xdf, 0x62, 0xe5, 0xf2, 0x37, 0x0b, 0x30, 0x53, 0x6d, 0xb5, 0x7d, 0xc7, 0xc5, + 0x08, 0x41, 0x6e, 0x6f, 0xaf, 0x51, 0x2b, 0x69, 0xeb, 0xda, 0xed, 0x82, 0x41, 0x7f, 0xa3, 0xd7, + 0x60, 0xbe, 0xcd, 0x86, 0x52, 0xe9, 0x76, 0x5d, 0xec, 0x79, 0xa5, 0x0c, 0xad, 0x8d, 0x40, 0xd1, + 0x1a, 0x40, 0xfb, 0x83, 0xa6, 0xc0, 0xc9, 0x52, 0x1c, 0x09, 0x82, 0x36, 0x01, 0x35, 0x9d, 0xce, + 0x51, 0xa4, 0xad, 0x1c, 0xc5, 0x4b, 0xa8, 0x41, 0xb7, 0x20, 0x67, 0x38, 0x3d, 0x5c, 0x9a, 0x5e, + 0xd7, 0x6e, 0xcf, 0xdf, 0xd5, 0x37, 0x83, 0x61, 0x57, 0x5b, 0x04, 0x6e, 0xd0, 0x5a, 0x32, 0x62, + 0xd3, 0xee, 0x1c, 0x95, 0x66, 0xd6, 0xb5, 0xdb, 0x39, 0x83, 0xfe, 0x46, 0x9f, 0x86, 0xa9, 0xb6, + 0x6f, 0xf9, 0xb8, 0x94, 0xa7, 0xa4, 0xcb, 0x9b, 0xd2, 0xfa, 0xb6, 0x9c, 0x2e, 0xa6, 0x95, 0x06, + 0xc3, 0x41, 0x5f, 0x84, 0xe9, 0xa6, 0x75, 0x80, 0x7b, 0x5e, 0xa9, 0xb0, 0x9e, 0xbd, 0x5d, 0xbc, + 0x7b, 0x53, 0xc6, 0xe6, 0xeb, 0xb2, 0xc9, 0x30, 0xea, 0x7d, 0xdf, 0x3d, 0xdd, 0xca, 0xfd, 0xe0, + 0xc7, 0x37, 0x2f, 0x19, 0x9c, 0x08, 0xfd, 0x0e, 0x14, 0x3e, 0x74, 0xdc, 0x23, 0xd6, 0x1f, 0xd0, + 0xfe, 0x16, 0xc3, 0xa1, 0x06, 0x55, 0x46, 0x88, 0x85, 0xca, 0x30, 0xfb, 0xc1, 0x09, 0x76, 0x4f, + 0xc5, 0x12, 0x14, 0xe9, 0x12, 0x28, 0x30, 0xf4, 0x36, 0x40, 0xd5, 0xe9, 0x3f, 0xb3, 0x0f, 0x6b, + 0x96, 0x6f, 0x95, 0x66, 0xd7, 0xb5, 0xdb, 0xc5, 0xbb, 0x2b, 0xca, 0xc8, 0x82, 0x5a, 0x43, 0xc2, + 0x44, 0x6f, 0x43, 0xde, 0xc0, 0x9e, 0x73, 0xe2, 0x76, 0x70, 0x69, 0x8e, 0x52, 0x2d, 0xc9, 0x54, + 0xa2, 0x8e, 0x4f, 0x22, 0xc0, 0x45, 0x2b, 0x30, 0xbd, 0x37, 0x30, 0xed, 0x63, 0x5c, 0x9a, 0x5f, + 0xd7, 0x6e, 0x67, 0x0d, 0x5e, 0x42, 0x9f, 0x85, 0xc5, 0xf6, 0x73, 0xcb, 0xed, 0x46, 0x76, 0xed, + 0x32, 0x1d, 0x72, 0x52, 0x15, 0x5a, 0x85, 0x7c, 0xd5, 0x39, 0x3e, 0xb6, 0xfd, 0x46, 0xad, 0xa4, + 0x53, 0xb4, 0xa0, 0x8c, 0xde, 0x87, 0xb5, 0xa7, 0x36, 0xfe, 0xf8, 0x09, 0x5f, 0x9e, 0x4a, 0xf7, + 0xd8, 0xf6, 0x3c, 0xdb, 0xe9, 0xb7, 0x4f, 0x06, 0x03, 0xc7, 0xf5, 0x71, 0xb7, 0xb4, 0xb0, 0xae, + 0xdd, 0xce, 0x1b, 0x23, 0xb0, 0xd0, 0x36, 0xdc, 0x4c, 0xc4, 0x78, 0x88, 0xfb, 0xd8, 0xb5, 0x7c, + 0xdb, 0xe9, 0x97, 0x10, 0xe5, 0x87, 0x51, 0x68, 0xe8, 0x3e, 0x5c, 0x95, 0x51, 0x76, 0x0e, 0xc8, + 0x4a, 0xe1, 0x6e, 0x7d, 0xe0, 0x74, 0x9e, 0x97, 0x16, 0x69, 0x1b, 0xe9, 0x08, 0xe8, 0x01, 0xac, + 0x26, 0x76, 0x60, 0x60, 0xab, 0x7b, 0x5a, 0x5a, 0xa2, 0x73, 0x19, 0x82, 0x41, 0x7a, 0xaf, 0xd5, + 0x9a, 0x4f, 0x6d, 0xcf, 0x3e, 0xb0, 0x7b, 0xb6, 0x7f, 0xba, 0x65, 0xb9, 0xae, 0x8d, 0x5d, 0x46, + 0xbe, 0x4c, 0xc9, 0xd3, 0x11, 0xd0, 0x17, 0xa0, 0x24, 0xb7, 0xdd, 0xe8, 0x1f, 0x92, 0x0d, 0x60, + 0xc4, 0x2b, 0x94, 0x38, 0xb5, 0x1e, 0xd5, 0xe0, 0x86, 0xd2, 0x70, 0x0d, 0x0f, 0x7a, 0xce, 0x29, + 0xee, 0xee, 0x12, 0x95, 0xd0, 0x71, 0x7a, 0xa5, 0x2b, 0x94, 0x0d, 0x86, 0x23, 0xad, 0xb6, 0xa0, + 0x28, 0x49, 0x06, 0xd2, 0x21, 0x7b, 0x84, 0x4f, 0xb9, 0xf2, 0x20, 0x3f, 0xd1, 0x1b, 0x30, 0xf5, + 0xc2, 0xea, 0x9d, 0x60, 0xaa, 0x32, 0x8a, 0xb2, 0x64, 0x50, 0xba, 0xa6, 0xed, 0xf9, 0x06, 0xc3, + 0xf8, 0x42, 0xe6, 0x1d, 0xed, 0x51, 0x2e, 0x3f, 0xa5, 0x4f, 0x97, 0x7f, 0x91, 0x85, 0x19, 0xf3, + 0x02, 0x14, 0x92, 0x50, 0x0d, 0xd9, 0x24, 0xd5, 0x90, 0x1b, 0x43, 0x35, 0xbc, 0x05, 0xd3, 0x94, + 0xc3, 0xbd, 0xd2, 0x14, 0x55, 0x0d, 0x57, 0x64, 0x6c, 0xb3, 0x45, 0xeb, 0x1a, 0xfd, 0x67, 0x8e, + 0x50, 0x09, 0x0c, 0x19, 0xdd, 0x85, 0xa5, 0xa6, 0x73, 0xe8, 0x5b, 0x76, 0x8f, 0x0c, 0x08, 0xbb, + 0x62, 0x94, 0xd3, 0x74, 0x94, 0x89, 0x75, 0x29, 0xca, 0x71, 0x26, 0x55, 0x39, 0xaa, 0xfa, 0xa1, + 0x30, 0xb6, 0x7e, 0x88, 0xea, 0x1e, 0x48, 0xd0, 0x3d, 0x29, 0x32, 0x5f, 0x4c, 0x97, 0xf9, 0xf7, + 0xe0, 0x5a, 0xe5, 0xc4, 0x77, 0x1a, 0xfd, 0x8e, 0x4b, 0x05, 0xe3, 0x7d, 0xdc, 0xef, 0xe0, 0x50, + 0xa8, 0x67, 0x29, 0x33, 0x0e, 0x43, 0x79, 0x94, 0xcb, 0xe7, 0xf5, 0x42, 0xf9, 0xcf, 0xb2, 0x90, + 0x6f, 0x3a, 0x87, 0xff, 0x07, 0xb6, 0xfe, 0x3e, 0xd1, 0xa3, 0x83, 0x9e, 0xdd, 0xb1, 0xc4, 0xe6, + 0xaf, 0xca, 0xf8, 0x4d, 0xe7, 0x90, 0x57, 0x4b, 0xfb, 0x1f, 0x50, 0x44, 0x76, 0x67, 0x7a, 0x12, + 0xed, 0xdd, 0x74, 0x3a, 0x16, 0x91, 0x35, 0xba, 0xf7, 0x11, 0xed, 0x2d, 0xea, 0x44, 0x7f, 0xa2, + 0x8c, 0x9e, 0xc2, 0x6b, 0x43, 0x05, 0x35, 0xdc, 0x8a, 0x3c, 0xdd, 0x8a, 0x31, 0xb1, 0xcb, 0xdf, + 0xce, 0xc2, 0x2c, 0xd9, 0x0f, 0xc1, 0xe8, 0xa8, 0x04, 0x33, 0xac, 0xc0, 0xb6, 0x25, 0x67, 0x88, + 0x22, 0xda, 0x92, 0x16, 0x2c, 0x43, 0x17, 0xec, 0xb5, 0xc8, 0x82, 0x05, 0xad, 0x6c, 0x0a, 0x44, + 0xaa, 0x35, 0xa4, 0x65, 0x5b, 0x82, 0x29, 0xa6, 0x78, 0xd9, 0xb6, 0xb1, 0x02, 0x31, 0x28, 0x4d, + 0x6c, 0x75, 0xb1, 0xdb, 0xa8, 0xd1, 0xad, 0xcb, 0x19, 0x41, 0x99, 0xee, 0x33, 0x76, 0x8f, 0x4b, + 0x53, 0x7c, 0x9f, 0xb1, 0x7b, 0x8c, 0x3e, 0x82, 0x85, 0x96, 0xd3, 0x7f, 0xea, 0xf8, 0x76, 0xff, + 0x30, 0x18, 0xd2, 0x34, 0x1d, 0xd2, 0x9d, 0xd4, 0x21, 0xc5, 0x28, 0xd8, 0xd8, 0xe2, 0x2d, 0xad, + 0xfe, 0x2e, 0xcc, 0x29, 0x38, 0xb2, 0xd6, 0xcb, 0x31, 0xad, 0xb7, 0x24, 0x6b, 0xbd, 0x82, 0xa4, + 0xe0, 0x56, 0x6b, 0xb0, 0x92, 0xdc, 0xd3, 0x24, 0xad, 0x94, 0xbf, 0xa3, 0xc1, 0xbc, 0xca, 0x81, + 0xe8, 0x7d, 0x75, 0xa3, 0x68, 0x3b, 0xc5, 0xbb, 0xa5, 0xb4, 0xf9, 0x6e, 0xe5, 0x09, 0x07, 0xfd, + 0xf0, 0xc7, 0x37, 0x35, 0x43, 0xdd, 0xe0, 0xeb, 0x50, 0x10, 0xcd, 0xd6, 0x68, 0xc7, 0x39, 0x23, + 0x04, 0xa0, 0x75, 0x28, 0x36, 0xbc, 0x60, 0x02, 0x74, 0x9b, 0xf2, 0x86, 0x0c, 0x2a, 0xff, 0xa9, + 0x16, 0x3a, 0x20, 0xd4, 0x15, 0xd8, 0xdd, 0x33, 0x1d, 0xdf, 0xea, 0xf1, 0x89, 0x05, 0x65, 0xa2, + 0x88, 0xaa, 0xbb, 0x7b, 0x95, 0x17, 0x96, 0xdd, 0xb3, 0x0e, 0x7a, 0x6c, 0x92, 0x9a, 0xa1, 0xc0, + 0x08, 0xfd, 0x13, 0x7c, 0xcc, 0xe8, 0x19, 0x4b, 0x04, 0x65, 0x42, 0xff, 0x04, 0x1f, 0x87, 0xf4, + 0x8c, 0x33, 0x14, 0x58, 0xf9, 0x0f, 0xb4, 0x88, 0x95, 0xab, 0x74, 0x7c, 0xfb, 0x05, 0x35, 0xfc, + 0xa6, 0xe5, 0x1e, 0x62, 0x9f, 0x4c, 0x97, 0x6b, 0x8e, 0x40, 0xd1, 0x84, 0x00, 0xe2, 0xd1, 0x4a, + 0x1e, 0x05, 0x5b, 0x0d, 0x09, 0x12, 0x53, 0xa6, 0xd9, 0xb8, 0x32, 0x2d, 0x7f, 0xb7, 0x08, 0x3a, + 0xf7, 0x22, 0xb7, 0xb1, 0xe5, 0xfa, 0x07, 0xd8, 0xf2, 0x7f, 0x03, 0xdd, 0xec, 0x4d, 0x40, 0xa6, + 0xe5, 0x09, 0xda, 0xaa, 0x8b, 0x2d, 0xa2, 0x4d, 0x66, 0x28, 0x03, 0x24, 0xd4, 0xc4, 0x96, 0x26, + 0x9f, 0x60, 0x67, 0x6e, 0xc1, 0x5c, 0xa3, 0x6f, 0xfb, 0xa1, 0xfb, 0x5c, 0xa0, 0x48, 0x2a, 0x90, + 0x60, 0x3d, 0x74, 0x3c, 0xcf, 0x1e, 0xa8, 0x26, 0x4b, 0x05, 0x92, 0xfe, 0x18, 0xe0, 0x91, 0x63, + 0xf7, 0x71, 0x97, 0x1a, 0xab, 0xbc, 0xa1, 0xc0, 0x7e, 0xe5, 0x3e, 0x75, 0x8a, 0x1d, 0x9d, 0x1f, + 0xcf, 0x77, 0xbe, 0x1c, 0xf1, 0x9d, 0x3f, 0x0b, 0x8b, 0x95, 0xce, 0x11, 0xee, 0x12, 0x80, 0xd5, + 0xef, 0x6e, 0x59, 0x7e, 0xe7, 0x39, 0x77, 0xb1, 0x73, 0x46, 0x52, 0x15, 0xb1, 0xca, 0x1c, 0x52, + 0xc3, 0x3d, 0xfb, 0x05, 0x59, 0xf9, 0xce, 0x51, 0xd4, 0xd5, 0x1e, 0x86, 0x32, 0x86, 0xbf, 0x8e, + 0x2e, 0xca, 0x5f, 0x5f, 0xbc, 0x00, 0x7f, 0x7d, 0x69, 0x94, 0xbf, 0x1e, 0x99, 0x4f, 0xd5, 0xf2, + 0xad, 0x9e, 0x73, 0x48, 0x5d, 0x11, 0xde, 0xc4, 0x32, 0x6d, 0x62, 0x04, 0x16, 0xda, 0x82, 0xeb, + 0x32, 0x86, 0x81, 0x9f, 0xb9, 0xd8, 0x7b, 0x1e, 0xae, 0x0a, 0xf3, 0xbe, 0x87, 0xe2, 0xc4, 0xdb, + 0x78, 0x61, 0xf5, 0xec, 0x2e, 0x11, 0x1e, 0x36, 0x92, 0x2b, 0x74, 0x24, 0x43, 0x71, 0x86, 0x9e, + 0x00, 0x4a, 0x23, 0x4e, 0x00, 0x43, 0xcf, 0x1e, 0x57, 0x47, 0x9d, 0x3d, 0x46, 0x9e, 0x1f, 0x56, + 0xc7, 0x38, 0x3f, 0xa0, 0x53, 0xb8, 0xa9, 0x20, 0xd0, 0x59, 0x31, 0x8e, 0x67, 0x0a, 0xda, 0x2b, + 0x5d, 0xa3, 0x86, 0xfb, 0x0d, 0x59, 0xe0, 0x86, 0xaa, 0x74, 0x2e, 0x85, 0xa3, 0xda, 0xe5, 0x47, + 0x0d, 0x13, 0x66, 0xab, 0xad, 0x4a, 0xaf, 0xe7, 0x74, 0x2c, 0x9f, 0x68, 0xfc, 0xf8, 0x09, 0x66, + 0x09, 0xa6, 0xa8, 0x3c, 0x71, 0xf5, 0xcf, 0x0a, 0xcc, 0x4c, 0x7e, 0xed, 0x04, 0x7b, 0x44, 0x52, + 0x99, 0x0e, 0x0e, 0x01, 0xe5, 0x7f, 0xcb, 0xc1, 0x82, 0x70, 0x63, 0x87, 0x2b, 0xfd, 0x75, 0x28, + 0x1a, 0xd6, 0x33, 0x5f, 0xd5, 0xf8, 0x32, 0x28, 0xc1, 0x2c, 0x64, 0x13, 0xcd, 0x42, 0x4c, 0x4d, + 0xe6, 0x92, 0xd4, 0xe4, 0xf9, 0xdc, 0xda, 0x64, 0x23, 0x30, 0x9d, 0x6a, 0x04, 0x54, 0x85, 0x3b, + 0x73, 0x26, 0x37, 0x38, 0x3f, 0x81, 0x1b, 0xfc, 0x05, 0x28, 0x45, 0xb4, 0x59, 0x28, 0x92, 0x05, + 0x26, 0x0e, 0x69, 0xf5, 0x63, 0xa8, 0x3a, 0x18, 0x4b, 0xd5, 0x8d, 0xef, 0x8a, 0x17, 0x27, 0x72, + 0xc5, 0xeb, 0x50, 0x94, 0x4e, 0x9c, 0x43, 0x1c, 0xf1, 0xa1, 0x1e, 0x5c, 0xf9, 0xeb, 0x53, 0xa0, + 0x9b, 0x17, 0xe9, 0x8e, 0x84, 0x67, 0xe4, 0xec, 0x24, 0x67, 0xe4, 0x64, 0x56, 0xca, 0xa5, 0xb2, + 0x52, 0xda, 0x99, 0x7a, 0x6a, 0xe2, 0x33, 0xf5, 0xf4, 0x98, 0x67, 0xea, 0xfc, 0x99, 0xcf, 0xd4, + 0x85, 0xf1, 0xcf, 0xd4, 0x90, 0xee, 0x0b, 0x10, 0xd5, 0x80, 0x07, 0x3d, 0xeb, 0x14, 0x77, 0x9b, + 0x5e, 0x9f, 0x72, 0x4b, 0xce, 0x90, 0x41, 0xe7, 0x3f, 0x75, 0xa7, 0xf9, 0x14, 0x73, 0x67, 0xf6, + 0x29, 0xe6, 0x47, 0xfa, 0x14, 0x8f, 0x72, 0xf9, 0x19, 0x3d, 0x5f, 0xfe, 0xfe, 0x14, 0xe4, 0x8d, + 0xf6, 0x13, 0xe6, 0xe2, 0xe9, 0x90, 0x35, 0x3d, 0x47, 0x9c, 0x7d, 0x4c, 0xcf, 0x21, 0x5a, 0xb7, + 0xd1, 0xef, 0xe2, 0x97, 0x42, 0xeb, 0xd2, 0x02, 0xd1, 0x71, 0x4d, 0x6c, 0x79, 0x78, 0xdb, 0xe9, + 0xb1, 0xe3, 0x20, 0x3b, 0x14, 0xa8, 0x40, 0xb2, 0x1d, 0xa6, 0x7b, 0xd2, 0x27, 0x1a, 0x9d, 0xae, + 0x1c, 0x3f, 0x19, 0xc8, 0x30, 0xf4, 0x08, 0x66, 0x19, 0x91, 0xed, 0xf9, 0x8e, 0x7b, 0xca, 0x75, + 0xa1, 0x72, 0x62, 0x15, 0xa3, 0xdb, 0x94, 0x11, 0xd9, 0xa9, 0x50, 0xa1, 0x65, 0x1b, 0xf5, 0xb5, + 0x13, 0xdb, 0x65, 0xdd, 0x4d, 0x8b, 0x8d, 0x0a, 0x40, 0xe8, 0x4d, 0x58, 0xf8, 0xb0, 0xd2, 0x34, + 0x70, 0xc7, 0x21, 0xab, 0x51, 0xb3, 0x0f, 0xb1, 0xe7, 0xf3, 0xd8, 0x4e, 0xbc, 0x02, 0x7d, 0x0e, + 0x96, 0x25, 0x20, 0xed, 0xb1, 0xea, 0x9c, 0xf4, 0x7d, 0xca, 0x91, 0x39, 0x23, 0xb9, 0x92, 0x6c, + 0x8c, 0x54, 0x51, 0x75, 0x8e, 0x07, 0x3d, 0x4c, 0xfc, 0x84, 0xbe, 0xef, 0xda, 0x98, 0xf1, 0x64, + 0xce, 0x18, 0x86, 0x42, 0xc4, 0x45, 0xaa, 0xde, 0xb2, 0x3c, 0x4c, 0xa6, 0x03, 0x94, 0x30, 0xa1, + 0x26, 0x82, 0xdf, 0xb4, 0x3c, 0x3f, 0xe4, 0xd3, 0x84, 0x1a, 0xf4, 0x08, 0xd6, 0x25, 0xe8, 0x8e, + 0x6b, 0x1f, 0xda, 0x7d, 0xab, 0xa7, 0x6e, 0xe8, 0x2c, 0xa5, 0x1e, 0x89, 0x47, 0x18, 0x37, 0x61, + 0x2a, 0x94, 0x71, 0xf3, 0x46, 0x52, 0xd5, 0xea, 0xbb, 0xb0, 0x10, 0xdb, 0xc8, 0x51, 0x87, 0xee, + 0x9c, 0x7c, 0xe8, 0xfe, 0x08, 0x0a, 0xd4, 0x3c, 0x76, 0x1c, 0xb7, 0x4b, 0x08, 0xc9, 0x64, 0x39, + 0x21, 0x99, 0xdd, 0x06, 0xe4, 0xcc, 0xd3, 0x01, 0xa3, 0x9b, 0x57, 0xd5, 0x06, 0xa3, 0x21, 0xb5, + 0x06, 0xc5, 0x21, 0xfa, 0x96, 0xaa, 0x18, 0xc2, 0xbe, 0xb3, 0x06, 0xfd, 0x5d, 0xfe, 0x69, 0x06, + 0x80, 0xb6, 0x4f, 0x9d, 0x08, 0x82, 0xd2, 0xb2, 0x8e, 0xb1, 0x50, 0xc9, 0xe4, 0xb7, 0xac, 0xf3, + 0x33, 0xaa, 0xce, 0xe7, 0xc3, 0xc9, 0x86, 0xc3, 0x29, 0xc1, 0xcc, 0x13, 0xeb, 0x65, 0xdb, 0xfe, + 0x3d, 0x71, 0x32, 0x16, 0x45, 0x62, 0x1f, 0x84, 0x5a, 0xae, 0xf1, 0xb8, 0x49, 0x08, 0xa0, 0x01, + 0x95, 0x56, 0xa3, 0xc6, 0xb9, 0x98, 0xfe, 0x46, 0x9f, 0x83, 0x8c, 0xd9, 0xe6, 0xe6, 0x7b, 0x75, + 0x93, 0x5d, 0x2f, 0x6d, 0x8a, 0xeb, 0xa5, 0x4d, 0x53, 0x5c, 0x2f, 0xb1, 0x98, 0xc2, 0x9f, 0xff, + 0xe4, 0xa6, 0x66, 0x64, 0xcc, 0x36, 0x31, 0xa8, 0x8d, 0x7e, 0xa7, 0x77, 0xd2, 0xc5, 0xf5, 0x97, + 0x03, 0x22, 0x09, 0xdc, 0x08, 0x71, 0xfd, 0x86, 0x3d, 0x1e, 0x8b, 0x1a, 0x81, 0x45, 0xce, 0x0e, + 0xf5, 0x97, 0x14, 0x63, 0xdb, 0x72, 0xbb, 0x35, 0xe7, 0xe3, 0x7e, 0xac, 0x21, 0x66, 0xdb, 0x47, + 0xa1, 0x95, 0xcb, 0x00, 0xa6, 0xe7, 0x88, 0x15, 0x5e, 0x82, 0x29, 0x26, 0x56, 0x6c, 0x13, 0x59, + 0xa1, 0xfc, 0x73, 0x8d, 0x78, 0x84, 0xd4, 0x3e, 0xd2, 0x08, 0x75, 0xa2, 0x6d, 0xbc, 0x07, 0x85, + 0x9d, 0x81, 0x1c, 0x16, 0x88, 0x44, 0x13, 0xab, 0x2d, 0x4a, 0xbb, 0x33, 0x30, 0x42, 0x3c, 0xb4, + 0x15, 0xdc, 0x33, 0x31, 0x43, 0x79, 0x2b, 0xe1, 0x9e, 0x89, 0x22, 0xa4, 0x5f, 0x36, 0x5d, 0x74, + 0xbc, 0xbd, 0xdc, 0x84, 0x62, 0xb5, 0x15, 0x1e, 0xb5, 0x93, 0xe6, 0xfa, 0x86, 0x88, 0x9a, 0x66, + 0xd2, 0xef, 0xb6, 0x18, 0x46, 0xf9, 0x67, 0x7c, 0xed, 0x2c, 0x7f, 0xc8, 0xda, 0x8d, 0xdf, 0xde, + 0xe8, 0x15, 0x13, 0x1d, 0xfd, 0x0a, 0x57, 0xec, 0x5b, 0x79, 0x98, 0x11, 0x1c, 0xa4, 0x1c, 0x02, + 0x34, 0xe1, 0x69, 0x71, 0x00, 0xda, 0x84, 0xe9, 0x27, 0xd8, 0x7f, 0xee, 0x74, 0x93, 0x54, 0x02, + 0xab, 0xa1, 0x2a, 0x81, 0x63, 0xa1, 0xfb, 0xb2, 0xfc, 0x53, 0x51, 0x8e, 0x78, 0x1f, 0x61, 0x2d, + 0x9f, 0xa3, 0xac, 0x2f, 0x2a, 0x34, 0xfe, 0x17, 0xb8, 0x74, 0x54, 0xe8, 0x8b, 0x77, 0x6f, 0x44, + 0xe3, 0x7f, 0x8a, 0xdf, 0x67, 0x28, 0x24, 0xe8, 0x01, 0x61, 0x86, 0xb0, 0x85, 0x29, 0xda, 0xc2, + 0xf5, 0x04, 0x2e, 0x0d, 0x1b, 0x90, 0x09, 0x08, 0xbd, 0x29, 0xd1, 0x4f, 0xc7, 0xe9, 0xcd, 0x18, + 0xbd, 0x44, 0x40, 0xdc, 0xaf, 0x50, 0x3c, 0x93, 0x4e, 0x0b, 0x61, 0xad, 0x21, 0x0b, 0xf2, 0x7d, + 0xf5, 0x0c, 0xc7, 0x1d, 0xb7, 0x92, 0x3a, 0xf0, 0xb0, 0xde, 0x50, 0x4f, 0x7c, 0xf7, 0x55, 0x79, + 0xe7, 0x57, 0x29, 0xa5, 0x34, 0xe1, 0x34, 0x54, 0xed, 0xf0, 0x79, 0x45, 0x80, 0xa8, 0xb1, 0x8c, + 0xb8, 0xc0, 0x52, 0xb5, 0xa1, 0x08, 0xdb, 0x7d, 0x55, 0x58, 0xa8, 0xe1, 0x4c, 0xe8, 0x58, 0xd4, + 0x1b, 0xaa, 0x68, 0xbd, 0x0b, 0x73, 0x35, 0x4c, 0x0c, 0x1b, 0x1f, 0x0e, 0x0f, 0x67, 0x5d, 0x55, + 0xce, 0xc9, 0x32, 0x82, 0xa1, 0xe2, 0xa3, 0x2d, 0x98, 0xdf, 0x75, 0x9d, 0x97, 0xa7, 0xe1, 0x86, + 0xcd, 0x71, 0x05, 0x2f, 0xb5, 0xa0, 0x62, 0x18, 0x11, 0x0a, 0x62, 0x85, 0xa3, 0xd1, 0xec, 0xd6, + 0xc9, 0x31, 0x75, 0x02, 0x73, 0x46, 0x52, 0x15, 0xda, 0x92, 0x62, 0xf3, 0xc1, 0x11, 0xef, 0x72, + 0xfa, 0x11, 0xcf, 0x88, 0xa3, 0xd3, 0x35, 0x7f, 0x8e, 0x3b, 0x47, 0xdb, 0xd8, 0xea, 0xf9, 0xcf, + 0x69, 0x00, 0x2c, 0xba, 0xe6, 0x61, 0xb5, 0x21, 0xe3, 0x22, 0x13, 0x96, 0xda, 0x9d, 0xe7, 0xb8, + 0x7b, 0xd2, 0xc3, 0xdc, 0x45, 0xa5, 0x4e, 0x3a, 0x0d, 0x85, 0x15, 0xef, 0xae, 0xcb, 0x6d, 0x24, + 0xe1, 0x19, 0x89, 0xd4, 0x65, 0x07, 0x8a, 0x54, 0x12, 0xbd, 0x81, 0xd3, 0xf7, 0xf0, 0x90, 0xa3, + 0x19, 0x37, 0xd3, 0x19, 0xc5, 0x4c, 0x0b, 0xc7, 0x89, 0x19, 0x6f, 0x51, 0x1c, 0x76, 0xeb, 0x51, + 0xde, 0x04, 0x24, 0xf1, 0xb3, 0xd4, 0xef, 0xfb, 0xb6, 0x2b, 0x29, 0x23, 0x51, 0x2c, 0xff, 0x77, + 0x8e, 0x46, 0x30, 0x19, 0xda, 0xc5, 0x6a, 0xad, 0xeb, 0x50, 0xa8, 0xbb, 0xae, 0xe3, 0x56, 0x9d, + 0x2e, 0xa6, 0x53, 0x98, 0x33, 0x42, 0x00, 0x71, 0xc5, 0x69, 0xe1, 0x09, 0xf6, 0x3c, 0xeb, 0x10, + 0xf3, 0x98, 0x84, 0x02, 0x43, 0x6b, 0x00, 0x0d, 0x6f, 0xbb, 0xf2, 0x18, 0xe3, 0x01, 0x76, 0xa9, + 0xd6, 0xc9, 0x1b, 0x12, 0x04, 0xbd, 0xab, 0xac, 0x2e, 0x57, 0x2b, 0x57, 0x62, 0x8a, 0x91, 0x55, + 0x73, 0xcd, 0xa8, 0xec, 0x07, 0x11, 0x34, 0xe9, 0x10, 0xc3, 0x35, 0x8b, 0x2a, 0x68, 0x52, 0xbd, + 0xa1, 0x60, 0x13, 0x6e, 0xa3, 0xba, 0x86, 0x77, 0x9f, 0x8f, 0x77, 0x2f, 0x55, 0x1b, 0x32, 0x2e, + 0x11, 0xb1, 0x6a, 0xef, 0xc4, 0xf3, 0xb1, 0x5b, 0xc3, 0xe4, 0x74, 0xea, 0x71, 0xe5, 0xa2, 0x88, + 0x98, 0x8a, 0x61, 0x44, 0x28, 0xd0, 0x03, 0x28, 0x84, 0x97, 0x3a, 0x90, 0xc0, 0xa6, 0xa2, 0x92, + 0x31, 0x28, 0xf6, 0x4e, 0x7a, 0xbe, 0x11, 0x92, 0xa0, 0x07, 0x00, 0x92, 0x6a, 0x64, 0x3a, 0x66, + 0x4d, 0x6e, 0x20, 0xce, 0x48, 0x06, 0x44, 0xd4, 0x23, 0x11, 0x20, 0xec, 0x32, 0x0d, 0x37, 0x9b, + 0xb0, 0x78, 0x52, 0xbd, 0xa1, 0x60, 0x97, 0x1f, 0xd1, 0x38, 0x18, 0xf3, 0x7f, 0x83, 0x65, 0x79, + 0x8b, 0x58, 0x50, 0x02, 0xf1, 0x4a, 0x1a, 0xb5, 0xeb, 0xcb, 0xb1, 0xcd, 0x24, 0xb5, 0x7c, 0x2b, + 0x05, 0x6e, 0xf9, 0x55, 0x65, 0x23, 0x88, 0xfb, 0xf6, 0x94, 0xda, 0x6d, 0xee, 0xbe, 0xd1, 0x42, + 0xf9, 0x21, 0xcc, 0x99, 0x96, 0x77, 0x64, 0x5a, 0x07, 0x3d, 0xbc, 0xe7, 0x61, 0x97, 0x88, 0x11, + 0xf9, 0xdb, 0x0f, 0x7d, 0xe9, 0xa0, 0x4c, 0xea, 0x76, 0x2d, 0xcf, 0xfb, 0xd8, 0x71, 0xbb, 0x3c, + 0xb8, 0x11, 0x94, 0xcb, 0xdf, 0xd0, 0xc8, 0x28, 0xa9, 0xde, 0x4a, 0x74, 0x63, 0xd2, 0x7d, 0x71, + 0x25, 0xfe, 0x92, 0x8d, 0xde, 0xa0, 0x05, 0x57, 0x9c, 0x39, 0xf9, 0x8a, 0x73, 0x8d, 0xda, 0x7e, + 0xd5, 0x29, 0x97, 0x20, 0xe5, 0xbf, 0xca, 0x10, 0x1e, 0xee, 0x3f, 0xb3, 0x0f, 0xab, 0xcf, 0xad, + 0xfe, 0x21, 0x46, 0xf7, 0x82, 0xd1, 0xf1, 0x9b, 0xbe, 0x45, 0xf5, 0xc0, 0x41, 0xab, 0xc2, 0x15, + 0x64, 0xf3, 0xb8, 0x0f, 0xc0, 0xc8, 0xa5, 0x83, 0xca, 0xf5, 0x78, 0x7c, 0x23, 0xc4, 0x31, 0x24, + 0x7c, 0x64, 0xc2, 0x7c, 0xa3, 0x6f, 0xfb, 0xb6, 0xd5, 0x7b, 0x82, 0x8f, 0x0f, 0xb0, 0x2b, 0xbc, + 0xb2, 0x37, 0xd3, 0x5a, 0xd8, 0x54, 0xd1, 0xd9, 0xd1, 0x39, 0xd2, 0xc6, 0x6a, 0x05, 0x16, 0x13, + 0xd0, 0x26, 0xba, 0x0d, 0x7d, 0x03, 0xe6, 0xda, 0xcf, 0x4f, 0xfc, 0xae, 0xf3, 0x71, 0x9f, 0x99, + 0x36, 0xb2, 0x37, 0xe4, 0x47, 0xb0, 0x65, 0xa2, 0x58, 0xfe, 0xc7, 0x29, 0xb8, 0x1c, 0x51, 0xe1, + 0x89, 0xbb, 0x7b, 0x0b, 0xe6, 0xb6, 0x1c, 0xc7, 0xf7, 0x7c, 0xd7, 0x1a, 0x0c, 0xec, 0xfe, 0x21, + 0xed, 0x34, 0x6f, 0xa8, 0x40, 0xa2, 0x1a, 0x78, 0xcc, 0x86, 0x2e, 0x68, 0x96, 0x2e, 0xa8, 0xa2, + 0x1a, 0xa4, 0x6a, 0x43, 0xc6, 0x65, 0x3a, 0x29, 0x5c, 0x2a, 0xee, 0xae, 0x95, 0xd2, 0x96, 0xd2, + 0x50, 0x77, 0xff, 0xdd, 0xc8, 0x8c, 0xb9, 0xaf, 0x76, 0x55, 0x55, 0x0c, 0x12, 0x82, 0x11, 0x59, + 0xa1, 0xc7, 0xb0, 0xc0, 0x02, 0x6b, 0x52, 0xa4, 0x8d, 0x6b, 0x56, 0xc5, 0x65, 0x8c, 0x21, 0x19, + 0x71, 0xba, 0xb8, 0x2b, 0x32, 0x33, 0xa1, 0x2b, 0xf2, 0x18, 0x16, 0x1e, 0x39, 0x76, 0x9f, 0x45, + 0xaa, 0xb9, 0xfe, 0xe3, 0x8a, 0x56, 0x19, 0x4d, 0x0c, 0xc9, 0x88, 0xd3, 0xa1, 0x6d, 0xd0, 0x59, + 0xeb, 0xd4, 0x57, 0x61, 0x03, 0x2a, 0xc4, 0x5d, 0xd1, 0x28, 0x8e, 0x11, 0xa3, 0x22, 0xdb, 0x5b, + 0xe9, 0x76, 0x85, 0x14, 0x26, 0xf9, 0x76, 0x52, 0xb5, 0x21, 0xe3, 0x12, 0xcd, 0x1f, 0xb0, 0x0a, + 0xa3, 0x2e, 0xc6, 0x35, 0xbf, 0x8a, 0x61, 0x44, 0x28, 0xca, 0x38, 0xd9, 0x57, 0x49, 0xe4, 0xd7, + 0x08, 0x27, 0x66, 0xc6, 0xe7, 0xc4, 0xf2, 0x5f, 0x64, 0x60, 0x25, 0x12, 0xae, 0xe3, 0x57, 0x24, + 0xf4, 0x8a, 0x9e, 0x6d, 0x11, 0xe9, 0x84, 0x69, 0xeb, 0x82, 0xa1, 0xc0, 0x68, 0xb0, 0x4d, 0xc6, + 0xc9, 0x30, 0x1c, 0x19, 0x46, 0xf4, 0x6c, 0xfd, 0x25, 0x51, 0x41, 0xb6, 0xcf, 0x53, 0x06, 0x82, + 0x32, 0x71, 0x21, 0x79, 0x7b, 0xa6, 0x7d, 0x8c, 0x9d, 0x13, 0xdf, 0xb4, 0x3b, 0x47, 0x1e, 0xd7, + 0x8e, 0x49, 0x55, 0x84, 0xc2, 0x4c, 0xa0, 0x60, 0x4a, 0x33, 0xa9, 0x0a, 0x7d, 0x0e, 0x96, 0xeb, + 0x44, 0x5d, 0x58, 0x3e, 0xae, 0x9e, 0xb8, 0x2e, 0xee, 0xfb, 0x14, 0xc7, 0xe3, 0x37, 0x17, 0xc9, + 0x95, 0xe5, 0x3b, 0x09, 0x5c, 0xc9, 0xa6, 0x62, 0x7b, 0x34, 0xfb, 0x81, 0x2d, 0x47, 0x50, 0x2e, + 0xf7, 0x12, 0x84, 0x0a, 0xdd, 0x83, 0x1c, 0xb1, 0x37, 0x5c, 0x4b, 0x2b, 0x32, 0xa1, 0x18, 0x2a, + 0xae, 0xab, 0x29, 0x32, 0x5d, 0x54, 0xcb, 0x3b, 0xaa, 0x59, 0xbe, 0x75, 0x60, 0x79, 0x42, 0xe5, + 0x29, 0x30, 0xa2, 0xf5, 0x54, 0x29, 0x4a, 0xd7, 0x7a, 0x6f, 0xc6, 0x45, 0x62, 0x08, 0xf6, 0xeb, + 0x0a, 0xdb, 0xa7, 0x7b, 0xb3, 0xe5, 0x5f, 0x68, 0x51, 0x2e, 0x3f, 0xeb, 0xad, 0x04, 0x7a, 0x9a, + 0x62, 0x5b, 0x36, 0xd3, 0xe5, 0x65, 0x1c, 0xeb, 0x42, 0x64, 0x85, 0xec, 0x21, 0xbf, 0x57, 0xa0, + 0xbf, 0x2f, 0xc2, 0xe2, 0xfc, 0x24, 0xa3, 0xba, 0x94, 0x41, 0x1a, 0x92, 0x26, 0xa5, 0x21, 0x7d, + 0x91, 0xdd, 0xe5, 0x5b, 0xfd, 0xae, 0x48, 0x88, 0xba, 0x36, 0xe4, 0x7c, 0x21, 0xee, 0xb2, 0x04, + 0x09, 0x59, 0x4a, 0x11, 0x8e, 0xe7, 0x27, 0x03, 0x11, 0x82, 0xaf, 0x02, 0x70, 0x2c, 0x22, 0x70, + 0x39, 0xda, 0xf4, 0x8d, 0x21, 0x4d, 0x37, 0x6a, 0x22, 0x5e, 0x10, 0x92, 0xa1, 0x0f, 0x61, 0x39, + 0xf1, 0x22, 0x8b, 0x9b, 0x92, 0x57, 0xe4, 0xf6, 0x92, 0x13, 0x58, 0x93, 0xe9, 0x47, 0x5f, 0x0c, + 0x4f, 0x8f, 0x71, 0x31, 0x5c, 0xfe, 0x6e, 0x26, 0x65, 0x7c, 0x84, 0x91, 0x76, 0x5d, 0x3c, 0xb0, + 0x5c, 0x26, 0x82, 0x64, 0x5f, 0x43, 0x00, 0x59, 0xb5, 0x7a, 0x9f, 0xc8, 0x54, 0x97, 0x9b, 0x6c, + 0x51, 0x4c, 0xc9, 0x2d, 0xbb, 0x0b, 0x4b, 0xc1, 0xa5, 0x3a, 0xcd, 0xca, 0x65, 0x41, 0x7b, 0xce, + 0x30, 0x89, 0x75, 0x68, 0x13, 0x50, 0x42, 0xe2, 0x00, 0xd3, 0x3f, 0x09, 0x35, 0x91, 0x2c, 0xa2, + 0xe9, 0x58, 0x16, 0xd1, 0x12, 0x4c, 0xb1, 0x4b, 0x77, 0x96, 0x4d, 0xc3, 0x0a, 0x44, 0xd3, 0x90, + 0x49, 0xfb, 0x61, 0xd2, 0x5e, 0x50, 0x2e, 0xff, 0xbb, 0xa6, 0xe6, 0x0e, 0x04, 0xab, 0x23, 0x34, + 0xb7, 0xac, 0x71, 0xb5, 0xf1, 0x34, 0x6e, 0x26, 0x5d, 0xe3, 0xbe, 0x0d, 0x2b, 0xa1, 0xe6, 0x50, + 0x88, 0xd8, 0x5a, 0xa6, 0xd4, 0xa6, 0xeb, 0xdd, 0xdc, 0x30, 0xbd, 0xfb, 0xb3, 0x22, 0x14, 0xf9, + 0x28, 0xe8, 0x09, 0x46, 0xa4, 0x72, 0x6a, 0x52, 0x2a, 0xe7, 0xff, 0xaf, 0x5c, 0xa9, 0x4a, 0x10, + 0xe7, 0xcc, 0x53, 0x61, 0x7e, 0x35, 0x21, 0xf8, 0x44, 0x93, 0x14, 0xc7, 0x7c, 0x85, 0x50, 0x38, + 0xd3, 0x2b, 0x04, 0x48, 0xce, 0xd0, 0x52, 0x93, 0x0a, 0x8a, 0xe3, 0xe4, 0x5e, 0xcd, 0x8e, 0xcc, + 0xbd, 0x9a, 0x3b, 0x53, 0xee, 0xd5, 0xfc, 0x99, 0xde, 0x33, 0x5c, 0x1e, 0xe7, 0x3d, 0x83, 0x3e, + 0x5e, 0x4e, 0xd6, 0x42, 0x24, 0x27, 0x6b, 0xc4, 0x6d, 0x28, 0xba, 0x88, 0x0c, 0xab, 0xc5, 0x8b, + 0xca, 0xb0, 0x5a, 0xba, 0x80, 0x0c, 0xab, 0xe5, 0xf3, 0x67, 0x58, 0xad, 0x5c, 0x48, 0x86, 0xd5, + 0x95, 0x0b, 0xc8, 0xb0, 0x2a, 0x8d, 0x91, 0x61, 0x35, 0xfc, 0x85, 0xc7, 0xd5, 0x91, 0x2f, 0x3c, + 0x86, 0x65, 0x68, 0xad, 0x9e, 0x27, 0x43, 0xeb, 0xda, 0xb9, 0x33, 0xb4, 0xae, 0xff, 0xfa, 0x5e, + 0x78, 0x7c, 0xa2, 0xb1, 0x27, 0x67, 0xfc, 0xfd, 0x15, 0x37, 0x0b, 0x5a, 0xf2, 0xfb, 0x2b, 0xcb, + 0xc7, 0x9b, 0x0c, 0x43, 0xd1, 0x7c, 0x0c, 0x34, 0x7a, 0x9a, 0x99, 0x71, 0xa6, 0x69, 0x40, 0x51, + 0xea, 0x22, 0x61, 0x9a, 0x9f, 0x51, 0xa7, 0x79, 0x25, 0x45, 0x45, 0xcb, 0x5e, 0xe2, 0xbf, 0xe6, + 0x68, 0xca, 0xce, 0x85, 0x18, 0xb2, 0xdf, 0x66, 0xd9, 0xfc, 0x06, 0x67, 0xd9, 0x8c, 0xb0, 0x12, + 0x73, 0xe3, 0xe6, 0xcc, 0xfc, 0xb5, 0xc6, 0xde, 0x45, 0x8d, 0x94, 0x1a, 0x73, 0x94, 0xd4, 0x9c, + 0x8f, 0xdf, 0xcd, 0x64, 0x7e, 0xff, 0x87, 0x2c, 0x80, 0x74, 0xc2, 0x4c, 0x8a, 0x53, 0x08, 0x11, + 0xc8, 0x48, 0x22, 0x70, 0x0b, 0xe6, 0x88, 0x92, 0xc0, 0x7d, 0xd5, 0x4d, 0x53, 0x81, 0x11, 0xae, + 0xc9, 0x8d, 0xcd, 0x35, 0xa3, 0xed, 0xeb, 0xd4, 0x45, 0xd9, 0xd7, 0xe9, 0x0b, 0xb0, 0xaf, 0x33, + 0xe7, 0x7b, 0x71, 0x98, 0x1f, 0x65, 0x8f, 0xca, 0x7f, 0xaf, 0x05, 0x9b, 0x44, 0xd8, 0xe8, 0xbd, + 0x08, 0x1b, 0x95, 0x63, 0xb7, 0x7f, 0xa3, 0x38, 0xe9, 0x83, 0x51, 0x9c, 0xf4, 0xa6, 0xca, 0x49, + 0x2b, 0x09, 0x3d, 0x38, 0x2e, 0x96, 0x19, 0xe9, 0x47, 0x99, 0xe8, 0xdd, 0x64, 0x5a, 0x90, 0x56, + 0x65, 0x9c, 0xcc, 0x68, 0xc6, 0xc9, 0x5e, 0x20, 0xe3, 0xe4, 0x2e, 0x8a, 0x71, 0xa6, 0x2e, 0x80, + 0x71, 0xa6, 0x47, 0x30, 0x4e, 0xf9, 0x3f, 0xb2, 0xd1, 0xdb, 0x28, 0xf4, 0x16, 0xe4, 0xb9, 0x28, + 0x8b, 0xed, 0x5f, 0x4c, 0x10, 0x73, 0xe1, 0x5a, 0x0b, 0x54, 0x42, 0x56, 0x15, 0x64, 0x99, 0x38, + 0x59, 0x55, 0x25, 0x13, 0xa8, 0xe8, 0x1d, 0x9a, 0x3f, 0xc5, 0xe9, 0x98, 0x15, 0x5b, 0x4a, 0x4a, + 0x4f, 0xe0, 0x84, 0x21, 0x32, 0x7a, 0x00, 0xc5, 0x90, 0x51, 0x44, 0xc4, 0x23, 0x85, 0x8f, 0xc4, + 0x05, 0xa0, 0x44, 0x80, 0x6a, 0x22, 0x54, 0xd6, 0xe5, 0x2d, 0xb0, 0x6c, 0xbf, 0x52, 0x3c, 0x1e, + 0xdc, 0x95, 0xdb, 0x50, 0x89, 0xd2, 0x23, 0x26, 0xd3, 0xbf, 0xec, 0x88, 0xc9, 0xcc, 0x38, 0x11, + 0x93, 0x3f, 0xd6, 0xa0, 0xc8, 0xf7, 0x97, 0x7a, 0x1b, 0x9f, 0xa7, 0x9b, 0xcb, 0x7c, 0x06, 0x8d, + 0xfb, 0x0c, 0x81, 0x6b, 0xc6, 0x6b, 0x94, 0x8b, 0xb6, 0x00, 0x1d, 0xdd, 0x67, 0x3b, 0xc5, 0x68, + 0x33, 0x7c, 0xad, 0x42, 0xb7, 0x4e, 0x44, 0xbc, 0x65, 0xe2, 0x90, 0xa0, 0xfc, 0xbd, 0x1c, 0x2c, + 0xf3, 0x00, 0x9b, 0x08, 0xd3, 0xf3, 0x44, 0x8d, 0xd7, 0x60, 0xbe, 0x75, 0x72, 0xbc, 0xf3, 0x2c, + 0x6c, 0x9c, 0xb9, 0x42, 0x11, 0x28, 0x11, 0x6c, 0x0a, 0x09, 0xc6, 0xcf, 0xcc, 0x85, 0x0a, 0x44, + 0x1b, 0xa0, 0x0b, 0xba, 0x20, 0xa5, 0x9d, 0xc5, 0x23, 0x62, 0x70, 0x72, 0x1a, 0x6c, 0xe1, 0x97, + 0x7e, 0x70, 0x95, 0xce, 0x4b, 0xc8, 0x84, 0x22, 0xfb, 0xb5, 0x75, 0xfa, 0x18, 0x8b, 0x2c, 0xd0, + 0xbb, 0xf2, 0x4e, 0x26, 0xce, 0x64, 0x53, 0x22, 0x62, 0x81, 0x47, 0xb9, 0x19, 0xf4, 0x2c, 0x29, + 0xc9, 0x81, 0x3d, 0x40, 0x7c, 0x67, 0x8c, 0xb6, 0xa3, 0xa4, 0xd1, 0x97, 0x88, 0x41, 0x22, 0x04, + 0xf5, 0xbc, 0x0e, 0xc5, 0xcd, 0x0c, 0x4f, 0x78, 0x14, 0x71, 0x86, 0x78, 0xcd, 0xea, 0x03, 0xd0, + 0xa3, 0x03, 0x4f, 0x7e, 0xf0, 0x90, 0x9c, 0x01, 0xa9, 0x3c, 0x5e, 0x54, 0x06, 0x37, 0xaa, 0x15, + 0x25, 0x78, 0xfa, 0x3f, 0x1a, 0x5c, 0x35, 0xb0, 0xc7, 0xa2, 0xcd, 0x1f, 0x5a, 0x3e, 0x76, 0x8f, + 0x2d, 0xf7, 0x48, 0xf0, 0x48, 0xb8, 0x53, 0x9a, 0xb2, 0x53, 0x5f, 0x52, 0x77, 0x8a, 0x71, 0xe5, + 0xdb, 0x91, 0x50, 0x40, 0x72, 0x9b, 0x23, 0x76, 0x2b, 0x79, 0x15, 0xb3, 0xbf, 0xac, 0x55, 0x2c, + 0xff, 0x4b, 0x8e, 0x3d, 0xd5, 0x1c, 0x7a, 0x2e, 0xf8, 0xed, 0xbb, 0x90, 0xdf, 0xbe, 0x0b, 0x19, + 0xef, 0x5d, 0xc8, 0x3f, 0x65, 0xf8, 0x93, 0x79, 0xe2, 0xce, 0x3d, 0x08, 0x8e, 0x89, 0x4c, 0xe5, + 0xaf, 0xc7, 0x0c, 0x2c, 0x75, 0xe6, 0x28, 0x8a, 0xea, 0xcc, 0x31, 0x9d, 0xfa, 0x20, 0x70, 0x07, + 0x33, 0xc3, 0xe8, 0x53, 0x9d, 0xc1, 0x36, 0x14, 0xa5, 0xc6, 0x13, 0xee, 0x54, 0x36, 0x55, 0x67, + 0x30, 0xf5, 0x7d, 0xb2, 0xac, 0x76, 0xda, 0xa3, 0x3c, 0xcc, 0x51, 0x8d, 0x26, 0x1d, 0x56, 0xfe, + 0x2b, 0xaf, 0x26, 0xb6, 0x24, 0x4a, 0xe1, 0xbb, 0x8a, 0x49, 0x4d, 0x3c, 0xfa, 0x87, 0xd5, 0xc2, + 0xf3, 0x90, 0x8d, 0xf0, 0xbd, 0xe0, 0xc0, 0xc6, 0x3d, 0xcf, 0xc5, 0x84, 0x63, 0x9a, 0x48, 0xd3, + 0x10, 0x47, 0xbb, 0xb7, 0xc3, 0x0d, 0xe5, 0x07, 0x9d, 0xa5, 0xa4, 0x6d, 0x08, 0xb9, 0x9c, 0x6f, + 0xfe, 0xbd, 0x20, 0xa6, 0xc2, 0x2f, 0x71, 0x16, 0x13, 0x22, 0x29, 0xa2, 0x33, 0x11, 0x7d, 0xb9, + 0x23, 0xd2, 0x71, 0x59, 0x48, 0x5b, 0xb9, 0xa0, 0x14, 0x29, 0x58, 0x4a, 0x52, 0x6e, 0x8b, 0xcb, + 0x3a, 0xbf, 0x63, 0xe2, 0x69, 0x41, 0x33, 0x94, 0x7a, 0x2d, 0x7a, 0xbd, 0xa9, 0x62, 0x19, 0x09, + 0x94, 0xa8, 0x1e, 0xc9, 0xd8, 0xe1, 0x82, 0x3d, 0xf2, 0xa6, 0x34, 0x92, 0xe7, 0x23, 0xec, 0x46, + 0x97, 0xbf, 0x74, 0xe0, 0x25, 0xf4, 0x58, 0xb5, 0x1b, 0x10, 0x7f, 0x4d, 0x28, 0x73, 0xc1, 0x08, + 0x53, 0x71, 0x5f, 0x3e, 0x3b, 0xf1, 0x2b, 0xfd, 0x95, 0xe4, 0x13, 0x93, 0xb8, 0x72, 0x93, 0xce, + 0x5a, 0x72, 0x28, 0x7b, 0x76, 0xb2, 0x67, 0xc4, 0x49, 0x59, 0x96, 0x73, 0xe9, 0x59, 0x96, 0xdb, + 0x49, 0x0e, 0xc8, 0xfc, 0x48, 0x85, 0x99, 0xe0, 0x62, 0xdc, 0x87, 0xab, 0x71, 0x13, 0xb8, 0x8b, + 0xfb, 0x5d, 0xbb, 0x7f, 0x48, 0x23, 0xeb, 0x79, 0x23, 0x1d, 0x01, 0x6d, 0xc1, 0x75, 0xc5, 0x1c, + 0x53, 0x03, 0x2d, 0x1d, 0x7c, 0xd8, 0xdb, 0xe5, 0xa1, 0x38, 0xe4, 0xc0, 0x9b, 0xd0, 0x01, 0xbd, + 0xf0, 0x0b, 0xde, 0x30, 0x0f, 0xc1, 0x40, 0xef, 0xc1, 0xb5, 0x78, 0x6d, 0xf0, 0xf6, 0x45, 0x84, + 0xe8, 0x87, 0xa0, 0x9c, 0xdb, 0xe0, 0x7f, 0x53, 0x83, 0x59, 0xf9, 0x28, 0x91, 0x78, 0x98, 0xbd, + 0x0e, 0x05, 0x76, 0x81, 0x26, 0xf2, 0x37, 0x0a, 0x46, 0x08, 0x40, 0x25, 0x98, 0x51, 0xad, 0xbc, + 0x28, 0x4a, 0xf7, 0x1c, 0x39, 0xe5, 0x9e, 0x63, 0x15, 0xf2, 0x35, 0xe7, 0xe3, 0x3e, 0xad, 0x99, + 0xa2, 0x35, 0x41, 0xb9, 0xfc, 0x97, 0x65, 0xd0, 0x85, 0x6c, 0x07, 0x6f, 0xb0, 0x82, 0x17, 0x57, + 0x9a, 0xfc, 0xe2, 0x2a, 0x29, 0x60, 0x13, 0xba, 0x68, 0x59, 0xc5, 0x45, 0xdb, 0x51, 0x45, 0x8d, + 0x1d, 0xd3, 0x3e, 0x93, 0xa4, 0x50, 0x82, 0xa7, 0x55, 0xc3, 0xc5, 0x2d, 0xe9, 0xe3, 0x1e, 0xbf, + 0x76, 0x7d, 0xd5, 0x05, 0x3d, 0x72, 0xbf, 0x2e, 0xae, 0xed, 0xee, 0x0e, 0x9d, 0x6a, 0x94, 0x48, + 0x36, 0x9f, 0xb1, 0x16, 0x51, 0x43, 0x3e, 0x82, 0xb1, 0xef, 0x92, 0x7d, 0x7a, 0x68, 0xf3, 0x01, + 0x36, 0x5b, 0xc7, 0x90, 0x5a, 0x36, 0x0b, 0x30, 0xb6, 0x59, 0x90, 0x0c, 0x57, 0xf1, 0x4c, 0x86, + 0x6b, 0x76, 0x02, 0xc3, 0x15, 0x31, 0xb3, 0x73, 0x13, 0x9b, 0xd9, 0x98, 0x0d, 0x99, 0x3f, 0x93, + 0x0d, 0x51, 0xd5, 0xfb, 0xe5, 0x09, 0xd5, 0x7b, 0x2c, 0xca, 0xa0, 0x9f, 0x25, 0xca, 0x90, 0xa2, + 0xec, 0x17, 0x26, 0x54, 0xf6, 0xe8, 0xc2, 0x95, 0xfd, 0xe2, 0x79, 0x95, 0xfd, 0xd2, 0xb9, 0x95, + 0xfd, 0xf2, 0x79, 0x95, 0xfd, 0xca, 0x48, 0x65, 0x8f, 0xde, 0x8e, 0x65, 0xc3, 0x89, 0x7c, 0x12, + 0x76, 0xe3, 0x98, 0x52, 0x9b, 0x70, 0xc4, 0x08, 0xb3, 0x54, 0x4a, 0x89, 0x47, 0x8c, 0x30, 0x69, + 0xe5, 0xab, 0xb0, 0x14, 0xa9, 0x13, 0xb7, 0x8b, 0xb1, 0x43, 0x6e, 0x4c, 0xee, 0x93, 0x08, 0x99, + 0x0a, 0x48, 0x6c, 0x13, 0x0d, 0x62, 0xf3, 0xab, 0xb6, 0xc4, 0x6d, 0x64, 0x2c, 0x40, 0x31, 0xaa, + 0x37, 0x4e, 0xca, 0xfa, 0x4b, 0x69, 0x37, 0xa1, 0x47, 0xb3, 0x25, 0xae, 0x30, 0x27, 0xee, 0xd1, + 0x1c, 0xd6, 0x23, 0xaf, 0x44, 0xdb, 0x70, 0x33, 0x52, 0xc3, 0x53, 0xa7, 0xbc, 0x8a, 0xe7, 0xd9, + 0x87, 0x7d, 0xdc, 0xa5, 0x77, 0x9f, 0x79, 0x63, 0x14, 0x1a, 0x6a, 0xc2, 0x2b, 0xd1, 0x59, 0x05, + 0x29, 0x54, 0x41, 0x5b, 0x37, 0x68, 0x5b, 0xa3, 0x11, 0x53, 0x8f, 0x92, 0x21, 0xa7, 0xac, 0x0d, + 0x39, 0x4a, 0x86, 0xfc, 0xb2, 0x95, 0x92, 0xfd, 0x23, 0x38, 0xf5, 0x66, 0xfc, 0x6e, 0x3c, 0x8a, + 0x93, 0x7a, 0x8f, 0xc0, 0xa2, 0xc9, 0xeb, 0x54, 0x56, 0x87, 0x60, 0xa0, 0x47, 0xb0, 0x9e, 0x78, + 0x6f, 0x2e, 0x27, 0x51, 0xbd, 0x42, 0xc7, 0x31, 0x12, 0x6f, 0x8c, 0x9c, 0x81, 0xf2, 0x58, 0x39, + 0x03, 0x5f, 0xd7, 0xe0, 0x46, 0xe2, 0x90, 0x69, 0xf8, 0x82, 0x70, 0xdc, 0xab, 0x94, 0xe3, 0xde, + 0x1d, 0xca, 0x71, 0x43, 0x5b, 0x60, 0x8c, 0x37, 0xbc, 0x17, 0xf4, 0x87, 0x69, 0xe9, 0x59, 0x42, + 0xd4, 0x6e, 0xd1, 0x61, 0x3c, 0x98, 0x7c, 0x18, 0x8a, 0xc0, 0x0d, 0xed, 0x03, 0x7d, 0x43, 0x4b, + 0xb9, 0x78, 0xa0, 0x26, 0x8b, 0x8d, 0xe3, 0x53, 0x74, 0x1c, 0x95, 0xc9, 0xc7, 0x11, 0xb6, 0xc1, + 0x86, 0x32, 0xaa, 0x27, 0xf4, 0x27, 0x5a, 0x0a, 0xef, 0x57, 0x5b, 0xe2, 0x43, 0x2f, 0xaf, 0xd1, + 0xc1, 0xbc, 0x77, 0x96, 0x45, 0xe1, 0x4d, 0xb0, 0xb1, 0x8c, 0xe8, 0x07, 0x7d, 0x4b, 0x83, 0x57, + 0xd2, 0x87, 0x2b, 0x46, 0xf3, 0x3a, 0x1d, 0x4d, 0xf5, 0x8c, 0x4b, 0xa3, 0x0c, 0x68, 0x74, 0x6f, + 0xa9, 0x12, 0x2d, 0x8c, 0xef, 0xed, 0x21, 0x12, 0x2d, 0xec, 0xef, 0xb7, 0x35, 0x28, 0x0f, 0x9d, + 0x3a, 0x4b, 0xd9, 0x7b, 0x83, 0x4e, 0xac, 0x76, 0xf6, 0x65, 0xa6, 0xcd, 0xb0, 0x99, 0x8d, 0xd1, + 0x1f, 0xfa, 0x9e, 0x06, 0x9f, 0x1a, 0xb5, 0x00, 0x6c, 0x64, 0x1b, 0x74, 0x64, 0x0f, 0xcf, 0xb5, + 0xe4, 0xd2, 0xe0, 0xc6, 0xeb, 0xf5, 0xdc, 0x41, 0xf1, 0x8f, 0x60, 0x39, 0xd1, 0xb5, 0x9f, 0x30, + 0x4e, 0xa5, 0xbc, 0x40, 0x93, 0x9a, 0xbf, 0x4f, 0xbf, 0xf4, 0x97, 0x12, 0x54, 0x1b, 0x39, 0xb8, + 0x87, 0x70, 0x35, 0xd5, 0x41, 0x18, 0xd5, 0x50, 0x5e, 0x6e, 0xa8, 0x11, 0x4b, 0x61, 0x90, 0x55, + 0xd1, 0x39, 0x9b, 0x32, 0xcf, 0xda, 0xd4, 0x6e, 0x0a, 0xc7, 0x2b, 0xda, 0x7a, 0xa2, 0x16, 0x77, + 0x52, 0x74, 0xc3, 0x99, 0x67, 0x6b, 0xc0, 0xad, 0x71, 0x34, 0xe8, 0x44, 0x6d, 0x7e, 0x00, 0xaf, + 0x8e, 0xa1, 0x08, 0x27, 0x62, 0x14, 0x13, 0x5e, 0x1b, 0x4f, 0x9b, 0x4d, 0xd4, 0xea, 0x1e, 0xbc, + 0x3e, 0xa6, 0x2a, 0x99, 0xa8, 0xd9, 0x2f, 0xc1, 0xc6, 0xf8, 0x7a, 0x60, 0xa2, 0x50, 0x4d, 0x83, + 0x65, 0x03, 0x89, 0x8f, 0x6a, 0x9e, 0xe3, 0xbb, 0x48, 0xe5, 0xbf, 0xc9, 0xc0, 0x52, 0xd2, 0xe3, + 0xcc, 0x21, 0x6f, 0x24, 0x76, 0x63, 0x9f, 0x50, 0xdd, 0x1c, 0xf5, 0xd4, 0x53, 0xfd, 0x94, 0x6a, + 0xec, 0x62, 0xe6, 0x42, 0x3e, 0xa8, 0xba, 0x6a, 0x8e, 0xfe, 0xe2, 0xe9, 0xb0, 0x74, 0x21, 0x69, + 0x45, 0xe5, 0xb5, 0xfe, 0xbe, 0x06, 0xb0, 0x65, 0x75, 0x8e, 0x4e, 0x06, 0xf4, 0x6e, 0x27, 0xed, + 0xe2, 0xaf, 0x91, 0x74, 0xf1, 0xf7, 0xba, 0xf2, 0x2e, 0x24, 0x68, 0x64, 0x78, 0x3c, 0xe9, 0xdc, + 0x81, 0xbc, 0x3f, 0xd2, 0xc4, 0xbd, 0x55, 0xc3, 0xc7, 0xc7, 0x89, 0x9f, 0x68, 0x29, 0xc3, 0x2c, + 0xcf, 0x66, 0x7f, 0x2a, 0xdd, 0x7e, 0x2a, 0x30, 0x82, 0x53, 0xc3, 0xcf, 0xac, 0x93, 0x1e, 0xc7, + 0xe1, 0x5f, 0x0d, 0x95, 0x61, 0x64, 0x8b, 0x1a, 0x7d, 0x1f, 0xbb, 0x7d, 0xab, 0xc7, 0x2f, 0xec, + 0x82, 0x72, 0xf9, 0x6f, 0x35, 0xf9, 0xfa, 0x0c, 0x7d, 0x11, 0x66, 0xaa, 0x4e, 0xdf, 0xc7, 0xf4, + 0x4b, 0x26, 0xf1, 0xf4, 0xf1, 0x00, 0x71, 0x93, 0x63, 0xb1, 0x85, 0x11, 0x34, 0xab, 0x06, 0x7d, + 0x89, 0x18, 0x54, 0x4c, 0x98, 0xc0, 0x13, 0x2e, 0x87, 0xbc, 0x50, 0xbf, 0x1f, 0xde, 0xd3, 0xa1, + 0xb7, 0xc2, 0x77, 0xba, 0xb1, 0x3c, 0x35, 0x81, 0xb4, 0x49, 0x31, 0xd8, 0xc0, 0x18, 0xf6, 0xea, + 0x3b, 0x00, 0x21, 0x70, 0xa2, 0xfb, 0xe5, 0xd7, 0x95, 0xcf, 0x03, 0x0c, 0x79, 0xbf, 0xf4, 0x11, + 0x2c, 0xc4, 0x5e, 0xca, 0xa0, 0x5b, 0x30, 0xc7, 0xbe, 0x38, 0x24, 0x1e, 0xdf, 0x30, 0x22, 0x15, + 0x48, 0xb7, 0x99, 0x93, 0x48, 0x5f, 0xa9, 0x52, 0x60, 0x1b, 0x1f, 0x03, 0xec, 0x0d, 0xba, 0x96, + 0xcf, 0x22, 0xb8, 0x57, 0x60, 0x51, 0xf9, 0x82, 0x11, 0xab, 0xd2, 0x2f, 0xa1, 0x65, 0x58, 0x10, + 0x5f, 0xa6, 0x6a, 0xb6, 0x5b, 0x1c, 0xac, 0xa1, 0x45, 0xb8, 0xbc, 0xe7, 0x61, 0x97, 0x4e, 0x9f, + 0x03, 0x33, 0x68, 0x0e, 0x0a, 0x66, 0x7b, 0x87, 0x17, 0xb3, 0x84, 0x34, 0xf8, 0xca, 0x54, 0x40, + 0x9a, 0xdb, 0xd8, 0x84, 0x42, 0xf0, 0x39, 0x6b, 0x74, 0x19, 0x8a, 0x2d, 0xc7, 0x3d, 0xb6, 0x7a, + 0xb4, 0xa8, 0x5f, 0x42, 0x3a, 0xcc, 0xf2, 0x47, 0x1a, 0x0c, 0xa2, 0x6d, 0xfc, 0x3c, 0x07, 0x10, + 0xbe, 0xec, 0x47, 0xf3, 0x00, 0x66, 0x7b, 0x67, 0x7f, 0x6f, 0xb7, 0x56, 0x31, 0xeb, 0xfa, 0x25, + 0x04, 0x30, 0x5d, 0xd9, 0xdd, 0xad, 0xb7, 0x6a, 0xba, 0x86, 0xf2, 0x90, 0x33, 0xea, 0x95, 0x9a, + 0x9e, 0x41, 0xb3, 0x90, 0x37, 0x8d, 0xbd, 0x56, 0x95, 0xe0, 0x64, 0x49, 0xa3, 0x0f, 0xeb, 0xe6, + 0x7e, 0x00, 0xc9, 0xa1, 0x22, 0xcc, 0x54, 0x77, 0x5a, 0xad, 0x7a, 0xd5, 0xd4, 0xa7, 0x48, 0x93, + 0xbc, 0xb0, 0x6f, 0xec, 0xe8, 0xd3, 0x68, 0x01, 0xe6, 0x9a, 0x3b, 0x0f, 0xf7, 0xb7, 0xeb, 0x15, + 0xc3, 0xdc, 0xaa, 0x57, 0x4c, 0x7d, 0x86, 0xb4, 0x50, 0x6d, 0x49, 0x90, 0x3c, 0x1d, 0xa8, 0x0c, + 0x29, 0x20, 0x04, 0xf3, 0xd5, 0xed, 0x7a, 0xf5, 0xf1, 0xfe, 0x76, 0xe5, 0x71, 0xbd, 0xbe, 0x5b, + 0x37, 0x74, 0x20, 0xeb, 0x4a, 0x7a, 0xae, 0x36, 0xf7, 0xda, 0x66, 0xdd, 0xd8, 0xaf, 0xd5, 0xcd, + 0x4a, 0xa3, 0xd9, 0xd6, 0x8b, 0x04, 0x99, 0x54, 0xb4, 0xb7, 0x2b, 0x46, 0x6d, 0xbf, 0xd1, 0x7a, + 0x7f, 0x47, 0x9f, 0xa5, 0x0d, 0xb4, 0xf6, 0x2b, 0xcd, 0xe6, 0x0e, 0x19, 0xe5, 0x7e, 0xa3, 0xa6, + 0xcf, 0x91, 0x45, 0x94, 0x1b, 0x68, 0x9b, 0x64, 0xfc, 0xf3, 0x74, 0xfd, 0xe9, 0x0a, 0xec, 0x57, + 0x5b, 0xfb, 0xcd, 0xca, 0x56, 0xbd, 0xa9, 0x5f, 0x46, 0x25, 0x58, 0x0a, 0x81, 0x1f, 0xee, 0x18, + 0x8f, 0x39, 0xba, 0x4e, 0x5a, 0xde, 0xad, 0x98, 0xd5, 0x6d, 0x52, 0xd1, 0x36, 0x77, 0x8c, 0xba, + 0xbe, 0x40, 0x9a, 0xa8, 0xd5, 0x9b, 0x75, 0x86, 0xcd, 0x80, 0x88, 0x00, 0x77, 0x8d, 0x9d, 0x2f, + 0x7d, 0x59, 0x9a, 0xd8, 0x22, 0x7a, 0x05, 0x6e, 0xf0, 0x76, 0x5b, 0x3b, 0xad, 0xfd, 0xa7, 0x3b, + 0x66, 0xa3, 0xf5, 0x70, 0xdf, 0xa8, 0xef, 0x36, 0x1b, 0xd5, 0xca, 0x7e, 0x6b, 0xef, 0x89, 0xbe, + 0x84, 0xd6, 0x60, 0x35, 0x8e, 0x42, 0xe6, 0xd1, 0x6c, 0x98, 0x5f, 0xd6, 0x97, 0xd1, 0x12, 0xe8, + 0xed, 0xba, 0xb9, 0x6f, 0xd4, 0x3f, 0xd8, 0x6b, 0x18, 0xf5, 0xda, 0x7e, 0xb3, 0xdd, 0xd2, 0x57, + 0x08, 0xf4, 0x61, 0x14, 0x7a, 0x45, 0x2c, 0x4d, 0xb3, 0x62, 0xd6, 0xdb, 0x26, 0x85, 0x95, 0xc8, + 0x96, 0x50, 0x58, 0xbd, 0x52, 0xab, 0x1b, 0x64, 0x65, 0xae, 0xd2, 0x2d, 0x61, 0xcb, 0x5d, 0xaf, + 0x34, 0xcd, 0x6d, 0x7d, 0x95, 0x6c, 0x3a, 0xd9, 0x7e, 0x4a, 0x72, 0x0d, 0x5d, 0x85, 0x65, 0x3e, + 0xa4, 0x66, 0xbd, 0xd2, 0xae, 0x6f, 0xef, 0x34, 0x39, 0xe9, 0x75, 0x52, 0x45, 0x17, 0xbf, 0xba, + 0x5d, 0xaf, 0xed, 0x35, 0xeb, 0xfb, 0xd5, 0x9d, 0x27, 0x4f, 0x2a, 0xad, 0x5a, 0x5b, 0xbf, 0xb1, + 0xd1, 0x02, 0x08, 0xbf, 0x87, 0x45, 0x38, 0x83, 0xb0, 0x39, 0x83, 0xe8, 0x97, 0x48, 0x0f, 0x42, + 0xcf, 0xe9, 0x1a, 0x61, 0x5e, 0x2a, 0x34, 0x81, 0x00, 0x2c, 0xf0, 0x0f, 0xc0, 0x19, 0xf8, 0xab, + 0xb8, 0xe3, 0xe3, 0xae, 0x9e, 0xdd, 0xd8, 0x80, 0x42, 0xf0, 0xb9, 0x25, 0x42, 0xde, 0xc6, 0x3e, + 0x2d, 0xe9, 0x97, 0x08, 0x39, 0x0b, 0xae, 0x32, 0x80, 0xb6, 0xf1, 0xcf, 0x39, 0x40, 0xe2, 0x48, + 0x21, 0xc9, 0x26, 0xe1, 0x78, 0xbb, 0x73, 0x24, 0x8b, 0xa4, 0xf4, 0x5d, 0x9b, 0x40, 0x24, 0x89, + 0xa4, 0xc6, 0xc0, 0x19, 0xb4, 0x42, 0xf3, 0x47, 0xa2, 0xf0, 0x2c, 0xe9, 0xfd, 0x21, 0xf6, 0x03, + 0x49, 0xcf, 0x91, 0x45, 0x89, 0xe8, 0x1b, 0x5e, 0x35, 0x45, 0x76, 0xa4, 0x8d, 0x99, 0x40, 0x72, + 0xd8, 0x34, 0x61, 0x36, 0x35, 0x41, 0x88, 0xd7, 0xcc, 0xa0, 0x9b, 0x70, 0xad, 0x8d, 0xfd, 0xf8, + 0xdd, 0x04, 0x47, 0xc8, 0xa3, 0x55, 0x58, 0xe1, 0x08, 0x41, 0x70, 0x9b, 0xd7, 0x15, 0xc8, 0x12, + 0xb2, 0xdf, 0x7c, 0xd5, 0x74, 0x20, 0x13, 0x13, 0xa0, 0xe0, 0x79, 0x90, 0x5e, 0x24, 0xfb, 0xbf, + 0x4b, 0xf4, 0x1d, 0xcf, 0xe0, 0xd3, 0x67, 0x09, 0xad, 0x81, 0x8f, 0x9d, 0x17, 0xe2, 0xcd, 0xa9, + 0x3e, 0x47, 0x46, 0xa9, 0xa6, 0x6a, 0xf2, 0x8e, 0xe6, 0xd1, 0x0d, 0xb8, 0xca, 0x7e, 0x27, 0x04, + 0xad, 0xf5, 0xcb, 0xe8, 0x1a, 0x5c, 0x89, 0x54, 0x0b, 0x6b, 0xc0, 0xc4, 0x49, 0x9c, 0x7a, 0x78, + 0x7b, 0x0b, 0xe8, 0x3a, 0x94, 0xe2, 0x29, 0x3e, 0xbc, 0x16, 0xa1, 0x5b, 0xb0, 0x2e, 0x82, 0xb8, + 0xf1, 0xf0, 0x2e, 0xc7, 0x5a, 0x24, 0x2b, 0xc7, 0x02, 0x60, 0x91, 0x13, 0x08, 0x47, 0x58, 0x42, + 0x9f, 0x82, 0x57, 0x18, 0x42, 0xa2, 0x83, 0xc9, 0xd1, 0x96, 0x37, 0xbe, 0xa3, 0xc1, 0x9c, 0x72, + 0xdb, 0x44, 0xe4, 0x5a, 0x00, 0x78, 0x96, 0x8b, 0x7e, 0x89, 0xec, 0xb8, 0x00, 0x2a, 0x5f, 0x0e, + 0xd0, 0x35, 0xd2, 0x51, 0xac, 0x4a, 0x9c, 0x1f, 0x0d, 0xdc, 0xc1, 0xf6, 0x0b, 0xdc, 0xd5, 0x33, + 0x64, 0x95, 0x62, 0x68, 0xef, 0x5b, 0x76, 0x8f, 0xb0, 0xbe, 0xdc, 0xa7, 0x71, 0xd2, 0xef, 0x93, + 0x86, 0x73, 0x1b, 0x07, 0x49, 0xf7, 0x5d, 0x64, 0x9b, 0x14, 0x68, 0x38, 0xc6, 0x68, 0x8d, 0x68, + 0x49, 0x8b, 0xd5, 0xb4, 0x7d, 0x67, 0x30, 0x20, 0xa3, 0xda, 0xf8, 0x91, 0x06, 0x7a, 0xf4, 0x5b, + 0x11, 0x44, 0x8a, 0x2a, 0x5d, 0xf1, 0xf9, 0x36, 0xfd, 0x52, 0xc8, 0x2c, 0x02, 0xa4, 0x11, 0x8e, + 0x6a, 0xfb, 0x96, 0xeb, 0x0b, 0x48, 0x86, 0x08, 0x09, 0x69, 0x56, 0x00, 0xb2, 0xa4, 0x95, 0xc7, + 0x76, 0xaf, 0xf7, 0x15, 0xe7, 0xf8, 0xc0, 0x26, 0x42, 0x73, 0x05, 0x16, 0x2b, 0xdd, 0x6e, 0x94, + 0x85, 0xf4, 0x29, 0xc2, 0xe3, 0xac, 0xf9, 0x58, 0xdd, 0x34, 0x95, 0x34, 0xd2, 0x4f, 0xac, 0x6a, + 0x86, 0x4c, 0x8a, 0x74, 0x18, 0xab, 0xc9, 0x6f, 0x3c, 0x51, 0xde, 0xd0, 0x93, 0x81, 0x84, 0x8c, + 0xa4, 0x5f, 0xa2, 0xb6, 0xb7, 0x25, 0x8a, 0x1a, 0x29, 0x56, 0x83, 0x62, 0x86, 0xca, 0x0a, 0xbd, + 0x0a, 0xe2, 0x90, 0xec, 0x56, 0xe3, 0x87, 0x3f, 0x5b, 0xbb, 0xf4, 0x83, 0x4f, 0xd6, 0xb4, 0x1f, + 0x7e, 0xb2, 0xa6, 0xfd, 0xf4, 0x93, 0xb5, 0x4b, 0x7f, 0xf7, 0x9f, 0x6b, 0xda, 0x57, 0xee, 0x49, + 0xff, 0xcb, 0xe9, 0xd8, 0xf2, 0x5d, 0xfb, 0xa5, 0x43, 0x1d, 0x0b, 0x51, 0xe8, 0xe3, 0x3b, 0x83, + 0xa3, 0xc3, 0x3b, 0x83, 0x83, 0x3b, 0xa1, 0x9b, 0x74, 0x30, 0x4d, 0xbf, 0xb5, 0x77, 0xef, 0x7f, + 0x03, 0x00, 0x00, 0xff, 0xff, 0x37, 0x2c, 0xf3, 0x79, 0x27, 0x6a, 0x00, 0x00, } func (m *CNStore) Marshal() (dAtA []byte, err error) { @@ -7575,6 +7653,52 @@ func (m *Resource) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *DDLVisibilityActivationTarget) Marshal() (dAtA []byte, err error) { + size := m.ProtoSize() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DDLVisibilityActivationTarget) MarshalTo(dAtA []byte) (int, error) { + size := m.ProtoSize() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DDLVisibilityActivationTarget) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.QueryAddress) > 0 { + i -= len(m.QueryAddress) + copy(dAtA[i:], m.QueryAddress) + i = encodeVarintLogservice(dAtA, i, uint64(len(m.QueryAddress))) + i-- + dAtA[i] = 0x1a + } + if m.Generation != 0 { + i = encodeVarintLogservice(dAtA, i, uint64(m.Generation)) + i-- + dAtA[i] = 0x10 + } + if len(m.ServiceID) > 0 { + i -= len(m.ServiceID) + copy(dAtA[i:], m.ServiceID) + i = encodeVarintLogservice(dAtA, i, uint64(len(m.ServiceID))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *CNStoreHeartbeat) Marshal() (dAtA []byte, err error) { size := m.ProtoSize() dAtA = make([]byte, size) @@ -7599,6 +7723,22 @@ func (m *CNStoreHeartbeat) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.DDLVisibilityEpochCommitTargets) > 0 { + for iNdEx := len(m.DDLVisibilityEpochCommitTargets) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DDLVisibilityEpochCommitTargets[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLogservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xda + } + } if m.DDLVisibilityDeployedProtocol != 0 { i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) i-- @@ -12765,6 +12905,29 @@ func (m *Resource) ProtoSize() (n int) { return n } +func (m *DDLVisibilityActivationTarget) ProtoSize() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ServiceID) + if l > 0 { + n += 1 + l + sovLogservice(uint64(l)) + } + if m.Generation != 0 { + n += 1 + sovLogservice(uint64(m.Generation)) + } + l = len(m.QueryAddress) + if l > 0 { + n += 1 + l + sovLogservice(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *CNStoreHeartbeat) ProtoSize() (n int) { if m == nil { return 0 @@ -12855,6 +13018,12 @@ func (m *CNStoreHeartbeat) ProtoSize() (n int) { if m.DDLVisibilityDeployedProtocol != 0 { n += 2 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) } + if len(m.DDLVisibilityEpochCommitTargets) > 0 { + for _, e := range m.DDLVisibilityEpochCommitTargets { + l = e.ProtoSize() + n += 2 + l + sovLogservice(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -16783,6 +16952,140 @@ func (m *Resource) Unmarshal(dAtA []byte) error { } return nil } +func (m *DDLVisibilityActivationTarget) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DDLVisibilityActivationTarget: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DDLVisibilityActivationTarget: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ServiceID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ServiceID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Generation", wireType) + } + m.Generation = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Generation |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QueryAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.QueryAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLogservice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthLogservice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *CNStoreHeartbeat) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -17442,6 +17745,40 @@ func (m *CNStoreHeartbeat) Unmarshal(dAtA []byte) error { break } } + case 27: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityEpochCommitTargets", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DDLVisibilityEpochCommitTargets = append(m.DDLVisibilityEpochCommitTargets, DDLVisibilityActivationTarget{}) + if err := m.DDLVisibilityEpochCommitTargets[len(m.DDLVisibilityEpochCommitTargets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) diff --git a/pkg/pb/logservice/logservice_test.go b/pkg/pb/logservice/logservice_test.go index 5c013a37d2840..f9b1c8287d3a0 100644 --- a/pkg/pb/logservice/logservice_test.go +++ b/pkg/pb/logservice/logservice_test.go @@ -35,28 +35,35 @@ func TestCNStateUpdate(t *testing.T) { state := CNState{Stores: map[string]CNStoreInfo{}} hb1 := CNStoreHeartbeat{ - UUID: "cn-a", - ServiceAddress: "addr-a", - Role: metadata.CNRole_AP, - CommandDeliveryAckSupported: true, - DDLVisibilityBarrierReady: true, - DDLVisibilityDeployedProtocol: 38, - ViewMetadataIngressReady: true, + UUID: "cn-a", + ServiceAddress: "addr-a", + QueryAddress: "query-a", + Role: metadata.CNRole_AP, + CommandDeliveryAckSupported: true, + DDLVisibilityBarrierReady: true, + DDLVisibilityDeployedProtocol: 38, + ViewMetadataAdmissionGeneration: 1, + ViewMetadataIngressReady: true, + DDLVisibilityEpochCommitTargets: []DDLVisibilityActivationTarget{{ + ServiceID: "cn-a", Generation: 1, QueryAddress: "query-a", + }}, } tick1 := uint64(100) state.Update(hb1, tick1) assert.Equal(t, state.Stores[hb1.UUID], CNStoreInfo{ - Tick: tick1, - ServiceAddress: hb1.ServiceAddress, - Role: metadata.CNRole_AP, - WorkState: metadata.WorkState_Working, - Labels: map[string]metadata.LabelList{}, - UpTime: state.Stores[hb1.UUID].UpTime, - CommandDeliveryAckSupported: true, - DDLVisibilityBarrierReady: true, - DDLVisibilityDeployedProtocol: 38, - ViewMetadataIngressReady: true, + Tick: tick1, + ServiceAddress: hb1.ServiceAddress, + QueryAddress: hb1.QueryAddress, + Role: metadata.CNRole_AP, + WorkState: metadata.WorkState_Working, + Labels: map[string]metadata.LabelList{}, + UpTime: state.Stores[hb1.UUID].UpTime, + CommandDeliveryAckSupported: true, + DDLVisibilityBarrierReady: true, + DDLVisibilityDeployedProtocol: 38, + ViewMetadataAdmissionGeneration: 1, + ViewMetadataIngressReady: true, }) assert.Equal(t, int64(38), state.DDLVisibilityDeployedProtocol) @@ -529,14 +536,40 @@ func TestCNWorkStateUpdate(t *testing.T) { }) } +func TestCNStateAtomicallyRejectsEpochCommitAfterMarkerlessJoin(t *testing.T) { + state := NewCNState() + state.Update(CNStoreHeartbeat{ + UUID: "target-cn", QueryAddress: "target:6001", ViewMetadataAdmissionGeneration: 1, + DDLVisibilityBarrierReady: true, + }, 1) + commitTargets := []DDLVisibilityActivationTarget{{ + ServiceID: "target-cn", Generation: 1, QueryAddress: "target:6001", + }} + + // This join lands after the CN-side final scan but before the replicated + // epoch commit. The same RSM transition must see it and reject the stale set. + state.Update(CNStoreHeartbeat{ + UUID: "joining-cn", QueryAddress: "joining:6001", ViewMetadataAdmissionGeneration: 2, + DDLVisibilityBarrierReady: true, ViewMetadataIngressReady: true, + }, 2) + state.Update(CNStoreHeartbeat{ + UUID: "target-cn", QueryAddress: "target:6001", ViewMetadataAdmissionGeneration: 1, + DDLVisibilityBarrierReady: true, DDLVisibilityDeployedProtocol: 41, + DDLVisibilityEpochCommitTargets: commitTargets, + }, 3) + + assert.Equal(t, int64(0), state.DDLVisibilityDeployedProtocol) + assert.True(t, state.Stores["joining-cn"].ViewMetadataIngressReady) +} + func TestCNStateRejectsMarkerlessIngressAfterCommittedDDLCut(t *testing.T) { state := NewCNState() - state.DDLVisibilityDeployedProtocol = 40 + state.DDLVisibilityDeployedProtocol = 41 state.Update(CNStoreHeartbeat{ UUID: "markerless-cn", ViewMetadataIngressReady: true, }, 1) assert.False(t, state.Stores["markerless-cn"].ViewMetadataIngressReady) - assert.Equal(t, int64(40), state.DDLVisibilityDeployedProtocol) + assert.Equal(t, int64(41), state.DDLVisibilityDeployedProtocol) } func TestCNStateLabelPatch(t *testing.T) { diff --git a/proto/logservice.proto b/proto/logservice.proto index 826d983f70390..610bf5c8afe04 100644 --- a/proto/logservice.proto +++ b/proto/logservice.proto @@ -142,6 +142,12 @@ message Resource { } // CNStoreHeartbeat is the periodic message sent tp the HAKeeper by CN stores. +message DDLVisibilityActivationTarget { + string ServiceID = 1; + uint64 Generation = 2; + string QueryAddress = 3; +} + message CNStoreHeartbeat { string UUID = 1; string ServiceAddress = 2; @@ -177,6 +183,10 @@ message CNStoreHeartbeat { // DDLVisibilityDeployedProtocol reports only a locally committed deployment // marker. Provisional activation must never advance the cluster-wide epoch. int64 DDLVisibilityDeployedProtocol = 26; + // Non-empty only for the transition that atomically validates the complete + // CN membership tuple set and commits DDLVisibilityDeployedProtocol. + repeated DDLVisibilityActivationTarget DDLVisibilityEpochCommitTargets = 27 + [(gogoproto.nullable) = false]; } // CNAllocateID is the periodic message sent tp the HAKeeper by CN stores. From 7eb451dbed047a7318216d5ff31da09d8417c213 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sun, 30 Aug 2026 19:49:35 +0800 Subject: [PATCH 18/34] fix: preserve DDL rollout baseline and reject rollback --- .../CLAUDE_cross_cn_ddl_visibility_fence.md | 188 ++++++++++++++++++ pkg/cnservice/server_ddl_visibility.go | 23 ++- pkg/cnservice/server_ddl_visibility_test.go | 33 ++- .../issue_277xx_ddl_consistency_test.go | 13 ++ 4 files changed, 246 insertions(+), 11 deletions(-) create mode 100644 docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md new file mode 100644 index 0000000000000..e0de77eba3063 --- /dev/null +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -0,0 +1,188 @@ +# Cross-CN DDL Visibility Fence + +- Status: **Approved** +- Revision: 1 +- Approval: user approval recorded in the PR implementation session on 2026-08-30 +- Owning issue: #27743 +- Implementation PR: #27756 +- Protocol version: MORPC v41 + +## 1. Classification and motivation + +This change is a distributed-protocol feature rather than a narrow local fix. It crosses frontend transaction commit, CN lifecycle and query RPC, cluster membership, HAKeeper replicated state, protobuf compatibility, and proxy admission. It changes persistent state, wire contracts, mixed-version rollout, restart, and rollback behavior; therefore it requires design approval. + +Issue #27743 demonstrates a missing catalog-visibility invariant: a DDL can commit on CN A while CN B admits a fresh snapshot before applying the corresponding catalog logtail. The client then observes `no such table` or equivalent stale-catalog behavior. + +## 2. Invariant and success criteria + +### Safety invariant + +After the v41 deployment epoch is committed, every CN capable of public DDL production must satisfy both conditions: + +1. its runtime protocol is at least v41, so DDL commit performs `SyncCommitV2` fan-out; and +2. it belongs to the exact generation/address membership set atomically committed by HAKeeper, or it remains fail-closed until it joins a later exact cut. + +Before a CN opens public ingress, its local catalog frontier must be at least the maximum frontier reported by all participants in the applicable cut. + +### Negation + +It is unsafe for any public or already-connected CN to commit DDL below v41 while another public CN can admit a snapshot that has not applied that commit. + +### Measurable criteria + +- A create on CN0 followed immediately by a first read/load on CN1 succeeds without explicit `SYNCCOMMIT`. +- Markerless startup preserves the current-main v40 baseline before the v41 cut. +- No local downgrade below v41 is accepted after the monotonic v41 epoch is committed. +- Membership change between final scan and epoch commit rejects the old target set atomically. +- Restart, timeout, persistence failure, response loss, and leader failover remain fail-closed. + +## 3. State ownership + +| State | Owner | Persistence | Meaning | +|---|---|---|---| +| Compiled latest protocol | binary/runtime | binary | Receiver/sender code capability only | +| Local deployed protocol | CN metadata file | durable local FS | This CN completed or provisionally entered a cut | +| Cluster deployed epoch | HAKeeper CNState | replicated snapshot/log | Monotonic cluster-wide committed cut | +| Admission generation/address | HAKeeper CNState | replicated snapshot/log | Identity of one CN incarnation | +| Prepared/Fenced/Complete | CN service | process-local plus local marker | Progress of the active attempt | +| Public DDL gate | frontend `DDLCommitGate` | process-local | Whether new public/background DDL may enter | +| Proxy ingress readiness | CN heartbeat/HAKeeper | replicated latest state | Whether new routed sessions may enter | + +HAKeeper is the first owner of cluster epoch and membership linearization. CN local metadata is not authoritative for cluster membership. + +## 4. Protocol states + +A CN is in one of these logical states: + +1. **Baseline v40**: v41 not deployed; existing v38-v40 contracts remain active. Public ingress may be open. +2. **Withdrawing**: activation blocks new DDL, withdraws ingress, and drains active DDL. +3. **Prepared v41**: local old-protocol producers are drained; runtime can receive v41 RPCs. +4. **Provisionally fenced**: local frontier synchronization completed and `-41` is durable; ingress remains closed. +5. **Cluster committed**: HAKeeper atomically validated exact `(serviceID, generation, queryAddress)` membership and advanced epoch to 41. +6. **Locally committed**: CN persisted `41`; only then may it republish ingress and unblock DDL. +7. **Markerless post-cut**: no local marker but HAKeeper epoch is 41; runtime remains v41 and ingress/DDL remain closed until a complete retry. + +The cluster epoch commit is the linearization point. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members and receiver capability, and advances the epoch only on exact equality. A join before this transition invalidates the target set; a join after it observes epoch 41 and is rejected as ingress-ready. + +## 5. End-to-end flow + +### First rollout + +1. All LogStore/HAKeeper replicas advertise support for the epoch schema. +2. Every CN runs v41-capable code but markerless CNs keep protocol baseline v40. +3. `mo_ctl SetProtocolVersion` refreshes raw authoritative CN membership. +4. The requested set must exactly match all eligible CN tuples and each target must advertise the v41 receiver/barrier capability. +5. Targets concurrently withdraw ingress, block and drain DDL, enter Prepared, synchronize the maximum catalog frontier, and durably enter provisional Fenced. +6. Each target confirms all exact targets are Fenced. +7. HAKeeper atomically validates tuples and commits epoch 41. +8. Each CN persists local committed 41, republishes ingress if listeners are live, and unblocks public DDL. + +### Steady-state DDL + +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, protocol v41 triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable QueryService. + +### Scale-out and replacement + +A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes before the cluster commit, it becomes authoritative membership and invalidates any old target proof. If it linearizes after commit, HAKeeper forces ingress false and returns epoch 41. It never becomes a public v40 producer after the cut. + +## 6. Failure, retry, and lifecycle behavior + +- **Withdrawal failure or drain timeout**: ingress and DDL gate remain closed; retry uses raw QueryService identity. +- **Frontier RPC/application failure**: CN remains Prepared or provisional and closed. +- **Provisional persistence failure**: Fenced is never published. +- **Atomic epoch membership rejection**: epoch does not advance; all targets remain closed for retry with a refreshed set. +- **Epoch response loss**: epoch may be committed, but local marker remains provisional and ingress closed; retry learns the committed epoch. +- **Committed local persistence failure**: cluster epoch remains committed; this CN remains closed and restarts from provisional state. +- **Ingress publication uncertainty**: perform a bounded cleanup withdrawal; never assume publication failed. +- **Restart**: committed marker runs startup frontier synchronization before opening; provisional or markerless post-cut starts v41 fail-closed. +- **Shutdown**: stop periodic heartbeat publication, then withdraw ingress/barrier state before stopping QueryService. +- **Leader failover**: activation is gated until every voting and non-voting LogStore advertises epoch-schema capability, so any eligible HAKeeper leader preserves the field. + +Retries are idempotent for the same generation and target set. Replacement generations or addresses are rejected before local state mutation. + +## 7. Compatibility, rollout, downgrade, and rollback + +### Mixed-version baseline + +Current main already deploys v40 semantics. A fresh v41-capable process without a DDL marker therefore remains at v40, not v37. The v41 DDL state is separate from unrelated v38-v40 capabilities. + +### Rollout order + +1. Upgrade all voting and non-voting LogStores/HAKeeper replicas. +2. Upgrade every CN; verify barrier receiver capability in raw inventory. +3. Invoke one exact complete-target v41 activation. +4. Verify epoch 41 and all eligible CN ingress/committed markers. + +### Downgrade policy + +Before epoch 41, ordinary protocol changes at or below v40 remain possible. After epoch 41, local downgrade below v41 is rejected. A safe rollback would require a separately designed atomic cluster rollback that withdraws and drains every DDL producer before lowering the epoch; this revision deliberately does not implement epoch rollback. + +Binary rollback after epoch 41 is unsupported until such a rollback protocol exists. Operators must restore forward to a v41-capable binary. + +## 8. Proxy and direct ingress + +Proxy routing consumes HAKeeper admission/readiness and therefore excludes fail-closed CNs. Direct SQL listeners are additionally protected by the local `DDLCommitGate`; suppressing proxy routing alone is insufficient because existing and direct sessions survive routing changes. Listener-ready and ingress-ready are separate lifecycle facts. + +## 9. Performance and capacity + +Let `N` be eligible CN count. + +- Activation performs O(N) membership validation, phase RPCs, and frontier collection. It is an operator-triggered bounded transition, not a per-statement hot path. Target count is capped at 1024. +- DDL commit fan-out is O(N) RPCs and O(N) response ownership. DDL is low frequency relative to DML; no unbounded queue or background worker is introduced. +- Requests are bounded by existing discovery/RPC contexts. Target maps and response slices are released after each operation. +- Expected added DDL latency is the slowest required CN frontier application plus network fan-out. Rollout acceptance should record N-CN p50/p95 for representative 3-CN and larger staging clusters; no latency claim is made without that evidence. + +## 10. Observability and operations + +Required diagnostic state is available through protocol-version RPCs, CN heartbeat inventory, local deployed marker, HAKeeper cluster epoch, admission generation/address, barrier readiness, and ingress readiness. Activation errors identify missing targets, stale generation/address, unsupported HAKeeper replicas, membership drift, persistence failure, or frontier timeout. + +Follow-up metrics should count activation attempts/failures by phase and DDL fan-out latency/failures. Until those metrics land, logs and `mo_ctl` inventory are the operational source. + +## 11. Security and abuse bounds + +The protocol adds no tenant data exposure and uses internal QueryService/HAKeeper channels. Exact generation/address checks prevent stale incarnation control. The 1024-target cap and bounded contexts limit operator-triggered amplification. Existing authorization for `mo_ctl` remains the trust boundary. + +## 12. Alternatives + +### A. Periodic or statement-local sleeps + +Rejected: timing does not establish catalog visibility, is flaky, and adds unconditional latency. + +### B. Read HAKeeper epoch once at startup + +Rejected: a join can race the final commit after the read. Re-reading at ingress remains TOCTOU unless join and commit share one replicated ordering. + +### C. Always use latest compiled scalar protocol + +Rejected: compiled capability is not proof that every producer completed the distributed cut. + +### D. Separate DDL feature epoch from the shared MORPC scalar + +Architecturally clean and avoids scalar coupling, but still requires the same membership/ingress linearization and broader API migration. This revision retains MORPC v41 as the sender/receiver capability gate while storing deployment completion separately. + +### E. TN-only global catalog barrier on every new transaction + +Could provide a stronger generic read contract, but materially changes every transaction admission path and latency. The selected approach scopes cost to DDL and activation while preserving the required immediate cross-CN visibility. + +## 13. Validation matrix + +| Contract | Deterministic evidence | +|---|---| +| v40 baseline preserved | markerless default-v41 startup UT | +| post-cut downgrade rejected | completed-v41 downgrade UT | +| exact authoritative targets | ctl raw-membership omission/capability UT | +| join/commit atomicity | CNState RSM ordering UT: final scan, join, stale commit | +| HAKeeper failover compatibility | old capability view rejection UT | +| provisional/committed persistence | injected Replace failures plus distinct-service restart UT | +| startup and live frontier fencing | mock frontier/application ordering UT and race runs | +| automatic public behavior | two-CN embedded create on CN0 followed immediately by first CN1 read without `SYNCCOMMIT` | +| cancellation and publication uncertainty | bounded timeout, stale heartbeat, cleanup withdrawal UTs | + +## 14. Decision log and open items + +- Chosen linearization point: HAKeeper replicated heartbeat transition with exact tuple proof. +- Chosen baseline: preserve current-main v40 before v41 activation. +- Chosen downgrade behavior: reject after monotonic epoch commit. +- Chosen direct-ingress protection: local DDL gate in addition to proxy admission. +- Non-blocking follow-up: add dedicated activation/fan-out metrics and publish N-CN staging latency evidence. +- Design gate: revision 1 was explicitly approved on 2026-08-30; no blocking design item remains. diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 5ed7f26d1f594..9b48c02fd1036 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -46,7 +46,8 @@ func (s *service) prepareDDLVisibilityBarrier() error { // MORPCLatestVersion describes compiled capability, not deployment-wide // activation. Restore the durable per-CN deployed protocol before deciding // whether this restart can produce v41 DDL. A fresh upgraded process has no - // marker and starts on v37 until the complete-target cut persists v41. + // marker and preserves the already-deployed v40 baseline until the + // complete-target cut persists v41. deployedVersion := s.loadDDLVisibilityDeployedProtocol() if deployedVersion == 0 && s._hakeeperClient != nil { ctx, cancel := s.newDDLVisibilityBarrierContext(context.Background()) @@ -75,7 +76,7 @@ func (s *service) prepareDDLVisibilityBarrier() error { rt.SetGlobalVariables(moruntime.MOProtocolVersion, -deployedVersion) } else if value, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion); ok { if version, valid := value.(int64); valid && version >= defines.MORPCVersion41 { - rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion37) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) } } @@ -256,6 +257,24 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets if pending { return moerr.NewInvalidStateNoCtx("cannot downgrade during DDL visibility activation") } + deployed := s.loadDDLVisibilityDeployedProtocol() + clusterCommitted := s.ddlVisibilityActivationComplete.Load() || + deployed >= defines.MORPCVersion41 || deployed <= -defines.MORPCVersion41 + if !clusterCommitted && s._hakeeperClient != nil { + queryCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) + details, err := s._hakeeperClient.GetClusterDetails(queryCtx) + if err != nil { + err = moerr.AttachCause(queryCtx, err) + cancel() + return err + } + cancel() + clusterCommitted = details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion41 + } + if clusterCommitted { + return moerr.NewInvalidStateNoCtx( + "cannot downgrade after the DDL visibility cluster epoch is committed") + } if err := s.persistDDLVisibilityDeployedProtocol(version); err != nil { return err } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index f62827e5e18d4..018fe2deeaff5 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -432,7 +432,7 @@ func TestDefaultV41StartupUsesLastDeployedProtocolUntilActivation(t *testing.T) require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion37, version) + require.Equal(t, defines.MORPCVersion40, version) require.True(t, s.ddlVisibilityListenersReady.Load()) require.True(t, s.viewMetadataIngressReady.Load()) require.True(t, gate.PublicDDLEnabled()) @@ -593,7 +593,7 @@ func TestActivationDoesNotPublishFencedBeforeProvisionalPersistence(t *testing.T const serviceID = "ddl-visibility-provisional-persist-failure-test" const generation = uint64(7) rt := moruntime.DefaultRuntime() - rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion37) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) moruntime.SetupServiceBasedRuntime(serviceID, rt) cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ ServiceID: serviceID, QueryAddress: "self:6001", @@ -637,7 +637,7 @@ func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing const serviceID = "ddl-visibility-committed-persist-failure-test" const generation = uint64(7) rt := moruntime.DefaultRuntime() - rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion37) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) moruntime.SetupServiceBasedRuntime(serviceID, rt) cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ ServiceID: serviceID, QueryAddress: "self:6001", @@ -1307,7 +1307,7 @@ func TestValidateDDLVisibilityActivationTargets(t *testing.T) { require.Equal(t, map[string]struct{}{"self": {}, "peer": {}}, targets) } -func TestSetProtocolVersionDowngradeAndPendingGuard(t *testing.T) { +func TestSetProtocolVersionDowngradeGuards(t *testing.T) { const serviceID = "ddl-visibility-downgrade-test" rt := moruntime.DefaultRuntime() rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion41) @@ -1316,17 +1316,32 @@ func TestSetProtocolVersionDowngradeAndPendingGuard(t *testing.T) { s.ddlVisibilityBarrierPrepared.Store(true) s.ddlVisibilityActivationPrepared.Store(true) s.ddlVisibilityActivationFenced.Store(true) + s.ddlVisibilityActivationComplete.Store(true) - require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil)) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion40, nil) + require.ErrorContains(t, err, "cannot downgrade after the DDL visibility cluster epoch is committed") version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) + require.Equal(t, defines.MORPCVersion41, version) + + s.ddlVisibilityActivationComplete.Store(false) + s._hakeeperClient = &ddlVisibilityWithdrawalHAKeeperClient{ + clusterDeployedProtocol: defines.MORPCVersion41, + } + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) + err = s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil) + require.ErrorContains(t, err, "cannot downgrade after the DDL visibility cluster epoch is committed") + + s._hakeeperClient = nil + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) + require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil)) + version, ok = rt.GetGlobalVariables(moruntime.MOProtocolVersion) + require.True(t, ok) require.Equal(t, defines.MORPCVersion34, version) - require.False(t, s.ddlVisibilityActivationPrepared.Load()) - require.False(t, s.ddlVisibilityActivationFenced.Load()) s.ddlVisibilityActivationPending.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil) - require.ErrorContains(t, err, "cannot downgrade") + err = s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil) + require.ErrorContains(t, err, "cannot downgrade during DDL visibility activation") } func TestWaitForDDLVisibilityActivationPhaseRejectsInvalidInventory(t *testing.T) { diff --git a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go index 4cbd9eca72679..c6fbdeb795af1 100644 --- a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go +++ b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go @@ -42,6 +42,19 @@ func TestIssue277xxDDLConsistency(t *testing.T) { db1 := openIssue277xxDB(t, cn1.GetServiceConfig().CN.Frontend.Port) defer db1.Close() + t.Run("27743 automatic cross-CN DDL visibility", func(t *testing.T) { + const database = "issue_27743_automatic_ddl_visibility" + resetIssue277xxDatabase(t, ctx, db0, database) + defer execSQLMaybe(t, ctx, db0, "drop database if exists `"+database+"`") + + // Do not issue SYNCCOMMIT or retry the read. The v41 DDL commit contract + // must make the first fresh CN1 snapshot observe CN0's CREATE TABLE. + execSQLRequire(t, ctx, db0, + "create table `"+database+"`.`t` (id int primary key, payload varchar(32))") + require.Equal(t, 0, queryIssue277xxInt(t, ctx, db1, + "select count(*) from `"+database+"`.`t`")) + }) + t.Run("27735 qualified alter drop index without default database", func(t *testing.T) { const database = "issue_27735_qualified_drop" resetIssue277xxDatabase(t, ctx, db0, database) From 8425ba332af541f11e8091258a8c0e4dd6c8be00 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Sun, 30 Aug 2026 22:26:55 +0800 Subject: [PATCH 19/34] fix: bind DDL activation proof to CN incarnation --- .../CLAUDE_cross_cn_ddl_visibility_fence.md | 15 +- pkg/cnservice/server_ddl_visibility.go | 154 +- pkg/cnservice/server_ddl_visibility_test.go | 168 ++- pkg/cnservice/server_heartbeat.go | 9 +- pkg/cnservice/server_query.go | 8 + pkg/cnservice/types.go | 1 + pkg/frontend/ddl_commit_gate.go | 48 +- pkg/frontend/ddl_commit_gate_test.go | 12 + pkg/frontend/txn.go | 3 + pkg/hakeeper/rsm.go | 3 + pkg/pb/logservice/logservice.go | 6 +- pkg/pb/logservice/logservice.pb.go | 1244 +++++++++++------ pkg/pb/logservice/logservice_test.go | 34 +- .../issue_277xx_ddl_consistency_test.go | 30 + proto/logservice.proto | 10 + 15 files changed, 1159 insertions(+), 586 deletions(-) diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index e0de77eba3063..b22a5be6ff79c 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -1,7 +1,7 @@ # Cross-CN DDL Visibility Fence - Status: **Approved** -- Revision: 1 +- Revision: 2 - Approval: user approval recorded in the PR implementation session on 2026-08-30 - Owning issue: #27743 - Implementation PR: #27756 @@ -44,7 +44,8 @@ It is unsafe for any public or already-connected CN to commit DDL below v41 whil | Local deployed protocol | CN metadata file | durable local FS | This CN completed or provisionally entered a cut | | Cluster deployed epoch | HAKeeper CNState | replicated snapshot/log | Monotonic cluster-wide committed cut | | Admission generation/address | HAKeeper CNState | replicated snapshot/log | Identity of one CN incarnation | -| Prepared/Fenced/Complete | CN service | process-local plus local marker | Progress of the active attempt | +| Prepared/Fenced/Complete | CN service and HAKeeper CNState | heartbeat-replicated phase proof plus local marker | Progress bound to one authoritative CN incarnation | +| Last committed DDL frontier | DDLCommitGate and HAKeeper CNState | monotonic process state replicated by heartbeat | Catalog frontier produced by that CN, excluding unrelated/no-op snapshot timestamps | | Public DDL gate | frontend `DDLCommitGate` | process-local | Whether new public/background DDL may enter | | Proxy ingress readiness | CN heartbeat/HAKeeper | replicated latest state | Whether new routed sessions may enter | @@ -62,7 +63,7 @@ A CN is in one of these logical states: 6. **Locally committed**: CN persisted `41`; only then may it republish ingress and unblock DDL. 7. **Markerless post-cut**: no local marker but HAKeeper epoch is 41; runtime remains v41 and ingress/DDL remain closed until a complete retry. -The cluster epoch commit is the linearization point. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members and receiver capability, and advances the epoch only on exact equality. A join before this transition invalidates the target set; a join after it observes epoch 41 and is rejected as ingress-ready. +The cluster epoch commit is the linearization point. Prepared, Fenced, and the last committed DDL frontier are published through each incarnation's heartbeat. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members, exact generation/address, receiver capability, and that each current incarnation itself published Prepared and Fenced, then advances the epoch only on exact equality. A replacement cannot reuse an older incarnation's Fenced proof. A join before this transition invalidates the target set; a join after it observes epoch 41 and is rejected as ingress-ready. ## 5. End-to-end flow @@ -72,9 +73,9 @@ The cluster epoch commit is the linearization point. The commit heartbeat contai 2. Every CN runs v41-capable code but markerless CNs keep protocol baseline v40. 3. `mo_ctl SetProtocolVersion` refreshes raw authoritative CN membership. 4. The requested set must exactly match all eligible CN tuples and each target must advertise the v41 receiver/barrier capability. -5. Targets concurrently withdraw ingress, block and drain DDL, enter Prepared, synchronize the maximum catalog frontier, and durably enter provisional Fenced. -6. Each target confirms all exact targets are Fenced. -7. HAKeeper atomically validates tuples and commits epoch 41. +5. Targets concurrently withdraw ingress, block and drain DDL, then heartbeat Prepared together with their monotonic last committed DDL frontier. +6. Each target reads the replicated HAKeeper phase/frontier inventory, applies every remote producer frontier, durably enters provisional Fenced, and heartbeats Fenced. This avoids cyclic QueryService control RPCs while every target is already serving a long-running activation RPC. +7. Each target confirms all exact current incarnations are Fenced in HAKeeper; HAKeeper atomically revalidates those tuple-bound proofs and commits epoch 41. 8. Each CN persists local committed 41, republishes ingress if listeners are live, and unblocks public DDL. ### Steady-state DDL @@ -127,7 +128,7 @@ Proxy routing consumes HAKeeper admission/readiness and therefore excludes fail- Let `N` be eligible CN count. -- Activation performs O(N) membership validation, phase RPCs, and frontier collection. It is an operator-triggered bounded transition, not a per-statement hot path. Target count is capped at 1024. +- Activation performs O(N) membership validation and scans heartbeat-replicated phase/frontier state. It is an operator-triggered bounded transition, not a per-statement hot path. Target count is capped at 1024. - DDL commit fan-out is O(N) RPCs and O(N) response ownership. DDL is low frequency relative to DML; no unbounded queue or background worker is introduced. - Requests are bounded by existing discovery/RPC contexts. Target maps and response slices are released after each operation. - Expected added DDL latency is the slowest required CN frontier application plus network fan-out. Rollout acceptance should record N-CN p50/p95 for representative 3-CN and larger staging clusters; no latency claim is made without that evidence. diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 9b48c02fd1036..4b7554d785413 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -26,7 +26,6 @@ import ( "github.com/matrixorigin/matrixone/pkg/defines" logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" "github.com/matrixorigin/matrixone/pkg/pb/metadata" - "github.com/matrixorigin/matrixone/pkg/pb/query" "github.com/matrixorigin/matrixone/pkg/pb/timestamp" "github.com/matrixorigin/matrixone/pkg/util/file" "github.com/matrixorigin/matrixone/pkg/util/protoc" @@ -196,6 +195,8 @@ func (s *service) withdrawDDLVisibilityBarrier() error { } func (s *service) withdrawDDLVisibilityBarrierLocked(ctx context.Context) error { + s.ddlVisibilityHeartbeatMu.Lock() + defer s.ddlVisibilityHeartbeatMu.Unlock() s.viewMetadataIngressReady.Store(false) s.ddlVisibilityBarrierReady.Store(false) if s.viewMetadataAdmissionGeneration == 0 { @@ -338,6 +339,9 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets // acts as the distributed Prepared signal queried by every other target. rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) s.ddlVisibilityActivationPrepared.Store(true) + if err := s.publishDDLVisibilityActivationPhaseLocked(barrierCtx); err != nil { + return err + } if err := s.waitForDDLVisibilityActivationPhase( barrierCtx, activationTargets, false); err != nil { return err @@ -351,6 +355,9 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets return err } s.ddlVisibilityActivationFenced.Store(true) + if err := s.publishDDLVisibilityActivationPhaseLocked(barrierCtx); err != nil { + return err + } if err := s.waitForDDLVisibilityActivationPhase( barrierCtx, activationTargets, true); err != nil { return err @@ -505,9 +512,12 @@ func validateDDLVisibilityActivationTargets(serviceID string, targets []string) } func (s *service) setDDLVisibilityIngressLocked(ctx context.Context, ready bool) error { + s.ddlVisibilityHeartbeatMu.Lock() s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(ready) - if _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { + _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) + s.ddlVisibilityHeartbeatMu.Unlock() + if err != nil { return moerr.AttachCause(ctx, err) } return s.waitForDDLVisibilityIngress( @@ -554,75 +564,55 @@ func (s *service) waitForDDLVisibilityIngress( } } +func (s *service) publishDDLVisibilityActivationPhaseLocked(ctx context.Context) error { + s.ddlVisibilityHeartbeatMu.Lock() + defer s.ddlVisibilityHeartbeatMu.Unlock() + _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) + if err != nil { + return moerr.AttachCause(ctx, err) + } + return nil +} + func (s *service) waitForDDLVisibilityActivationPhase( ctx context.Context, targets map[string]struct{}, requireFenced bool, ) error { - refresher, ok := s.moCluster.(clusterservice.AuthoritativeRefresher) - if !ok { - return moerr.NewInternalErrorNoCtx( - "CN cluster service does not support authoritative DDL visibility refresh") + if s._hakeeperClient == nil { + return moerr.NewInternalErrorNoCtx("HAKeeper client is unavailable during DDL visibility activation") } + var lastErr error for { allReady := true - addresses := make(map[string]string, len(targets)) - if err := refresher.Refresh(ctx); err != nil { + seen := make(map[string]struct{}, len(targets)) + details, err := s._hakeeperClient.GetClusterDetails(ctx) + if err != nil { + lastErr = err allReady = false - } else if err := clusterservice.GetCNServiceRawWithContext( - ctx, - s.moCluster, - clusterservice.NewSelector(), - func(cn metadata.CNService) bool { - if !cn.DDLVisibilityBarrierReady { - return true + } else { + for _, cn := range details.CNStores { + _, expected := targets[cn.UUID] + if cn.QueryAddress == "" || cn.ViewMetadataAdmissionGeneration == 0 { + if expected { + return moerr.NewInvalidStateNoCtxf( + "DDL visibility activation target %s has no authoritative identity", cn.UUID) + } + continue } - if _, expected := targets[cn.ServiceID]; !expected { - allReady = false - return true + if !expected { + return moerr.NewInvalidStateNoCtxf( + "DDL visibility activation target set omits authoritative CN %s", cn.UUID) } - addresses[cn.ServiceID] = cn.QueryAddress - return true - }); err != nil { - return err - } - if len(addresses) != len(targets) { - allReady = false - } - for serviceID := range targets { - if !allReady { - break - } - if serviceID == s.cfg.UUID { - if !s.ddlVisibilityActivationPrepared.Load() || - (requireFenced && !s.ddlVisibilityActivationFenced.Load()) { + seen[cn.UUID] = struct{}{} + if !cn.DDLVisibilityActivationPrepared || + (requireFenced && !cn.DDLVisibilityActivationFenced) { allReady = false } - continue - } - address := addresses[serviceID] - if address == "" { - return moerr.NewInternalErrorNoCtxf( - "DDL visibility activation target %s has no query address", serviceID) - } - req := s.queryClient.NewRequest(query.CmdMethod_GetProtocolVersion) - resp, err := s.queryClient.SendMessage(ctx, address, req) - if err != nil { - allReady = false - break - } - if resp == nil || resp.GetProtocolVersion == nil { - if resp != nil { - s.queryClient.Release(resp) - } - return moerr.NewInternalErrorNoCtxf( - "missing protocol activation response from CN %s", serviceID) } - phase := resp.GetProtocolVersion - allReady = phase.Version >= defines.MORPCVersion41 && - phase.DDLVisibilityActivationPrepared && - (!requireFenced || phase.DDLVisibilityActivationFenced) - s.queryClient.Release(resp) + } + if len(seen) != len(targets) { + allReady = false } if allReady { return nil @@ -630,9 +620,10 @@ func (s *service) waitForDDLVisibilityActivationPhase( if err := waitDDLVisibilityRetry(ctx, s.ddlVisibilityBarrierRetryInterval()); err != nil { return moerr.NewInternalErrorf( context.Background(), - "DDL visibility activation fenced=%t did not converge before deadline: %v", + "DDL visibility activation fenced=%t did not converge before deadline: %v (last error: %v)", requireFenced, - err) + err, + lastErr) } } } @@ -750,43 +741,24 @@ func (s *service) waitForDDLVisibilityBarrierPublication( } func (s *service) syncStartupDDLVisibilityFrontier(ctx context.Context) error { - addresses := make([]string, 0, 4) - err := clusterservice.GetCNServiceRawWithContext( - ctx, - s.moCluster, - clusterservice.NewSelector(), - func(cn metadata.CNService) bool { - if cn.DDLVisibilityBarrierReady { - addresses = append(addresses, cn.QueryAddress) - } - return true - }) + if s._hakeeperClient == nil { + return moerr.NewInternalErrorNoCtx("HAKeeper client is unavailable during DDL visibility frontier sync") + } + details, err := s._hakeeperClient.GetClusterDetails(ctx) if err != nil { - return err + return moerr.AttachCause(ctx, err) } - maxTS := timestamp.Timestamp{} - for _, address := range addresses { - if address == "" { - return moerr.NewInternalErrorNoCtx( - "barrier-ready CN has no query address during DDL visibility startup fence") - } - req := s.queryClient.NewRequest(query.CmdMethod_GetCommit) - resp, err := s.queryClient.SendMessage(ctx, address, req) - if err != nil { - return err - } - if resp == nil { - return moerr.NewInternalErrorf(ctx, "empty DDL frontier response from CN %s", address) - } - if resp.GetCommit == nil { - s.queryClient.Release(resp) - return moerr.NewInternalErrorf(ctx, "missing DDL frontier response from CN %s", address) + for _, cn := range details.CNStores { + if s.cfg != nil && cn.UUID == s.cfg.UUID { + // The drained producer already observes its own committed DDL. Waiting + // only on remote frontiers avoids depending on the control RPC that is + // currently executing on this CN. + continue } - if maxTS.Less(resp.GetCommit.CurrentCommitTS) { - maxTS = resp.GetCommit.CurrentCommitTS + if cn.DDLVisibilityBarrierReady && maxTS.Less(cn.DDLVisibilityFrontier) { + maxTS = cn.DDLVisibilityFrontier } - s.queryClient.Release(resp) } if maxTS.IsEmpty() { return nil diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 018fe2deeaff5..b4dcf64ae4c7e 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -69,6 +69,10 @@ type ddlVisibilityTestCluster struct { cnServices []metadata.CNService refreshCalls int refreshHook func() + phaseMu sync.Mutex + phases map[string]query.GetProtocolVersionResponse + frontiers map[string]timestamp.Timestamp + phaseHook func(string) query.GetProtocolVersionResponse } func (c *ddlVisibilityTestCluster) GetCNService( @@ -141,6 +145,9 @@ func (c *ddlVisibilityTestQueryClient) SendMessage( c.requests = append(c.requests, address) c.methods = append(c.methods, req.CmdMethod) if req.CmdMethod == query.CmdMethod_GetProtocolVersion { + if req.GetProtocolVersion == nil { + return nil, errors.New("missing GetProtocolVersion request payload") + } if c.nilProtocol[address] { return &query.Response{}, nil } @@ -193,11 +200,25 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) GetClusterDetails( }}, } if c.cluster != nil { + c.cluster.phaseMu.Lock() + defer c.cluster.phaseMu.Unlock() for _, cn := range c.cluster.cnServices { + phase, ok := c.cluster.phases[cn.ServiceID] + if c.cluster.phaseHook != nil && len(c.cluster.phases) > 0 { + phase = c.cluster.phaseHook(cn.QueryAddress) + ok = true + } + if !ok { + phase.DDLVisibilityActivationPrepared = cn.DDLVisibilityBarrierReady + phase.DDLVisibilityActivationFenced = cn.DDLVisibilityBarrierReady + } details.CNStores = append(details.CNStores, logservicepb.CNStore{ UUID: cn.ServiceID, QueryAddress: cn.QueryAddress, ViewMetadataAdmissionGeneration: cn.ViewMetadataAdmissionGeneration, DDLVisibilityBarrierReady: cn.DDLVisibilityBarrierReady, + DDLVisibilityActivationPrepared: phase.DDLVisibilityActivationPrepared, + DDLVisibilityActivationFenced: phase.DDLVisibilityActivationFenced, + DDLVisibilityFrontier: c.cluster.frontiers[cn.ServiceID], }) } } @@ -220,6 +241,22 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( if c.sendErr != nil { return logservicepb.CommandBatch{}, c.sendErr } + if c.cluster != nil { + c.cluster.phaseMu.Lock() + if c.cluster.phases == nil { + c.cluster.phases = make(map[string]query.GetProtocolVersionResponse) + } + c.cluster.phases[hb.UUID] = query.GetProtocolVersionResponse{ + Version: hb.DDLVisibilityDeployedProtocol, + DDLVisibilityActivationPrepared: hb.DDLVisibilityActivationPrepared, + DDLVisibilityActivationFenced: hb.DDLVisibilityActivationFenced, + } + if c.cluster.frontiers == nil { + c.cluster.frontiers = make(map[string]timestamp.Timestamp) + } + c.cluster.frontiers[hb.UUID] = hb.DDLVisibilityFrontier + c.cluster.phaseMu.Unlock() + } for i := range c.cluster.cnServices { cn := &c.cluster.cnServices[i] if cn.ServiceID == hb.UUID { @@ -370,7 +407,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { ServiceID: "peer", QueryAddress: "peer:6001", ViewMetadataAdmissionGeneration: 9, DDLVisibilityBarrierReady: true, }, - }} + }, frontiers: map[string]timestamp.Timestamp{"peer": targetTS}} queryClient := &ddlVisibilityTestQueryClient{ serviceID: serviceID, frontiers: map[string]timestamp.Timestamp{ @@ -411,9 +448,9 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { require.True(t, s.ddlVisibilityActivationComplete.Load()) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.Equal(t, 1, cluster.refreshCalls) - require.Equal(t, []string{"self:6001", "peer:6001"}, queryClient.requests) - require.Equal(t, []query.CmdMethod{query.CmdMethod_GetCommit, query.CmdMethod_GetCommit}, queryClient.methods) - require.Equal(t, 2, queryClient.releases) + require.Empty(t, queryClient.requests) + require.Empty(t, queryClient.methods) + require.Zero(t, queryClient.releases) require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) @@ -605,9 +642,6 @@ func TestActivationDoesNotPublishFencedBeforeProvisionalPersistence(t *testing.T frontiers: map[string]timestamp.Timestamp{"self:6001": {PhysicalTime: 100}}, } txnClient := mock_frontend.NewMockTxnClient(gomock.NewController(t)) - targetTS := timestamp.Timestamp{PhysicalTime: 100} - txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS, nil) - txnClient.EXPECT().SyncLatestCommitTS(targetTS) baseFS := newDDLVisibilityMetadataFS(t) metadataFS := &failReplaceMetadataFS{ReplaceableFileService: baseFS, failAt: 1} cfg := &Config{UUID: serviceID} @@ -650,8 +684,6 @@ func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing frontiers: map[string]timestamp.Timestamp{"self:6001": targetTS}, } txnClient := mock_frontend.NewMockTxnClient(gomock.NewController(t)) - txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS, nil) - txnClient.EXPECT().SyncLatestCommitTS(targetTS) baseFS := newDDLVisibilityMetadataFS(t) metadataFS := &failReplaceMetadataFS{ReplaceableFileService: baseFS, failAt: 2} cfg := &Config{UUID: serviceID} @@ -783,7 +815,7 @@ func TestDefaultV41StillRunsCompleteTargetActivation(t *testing.T) { {ServiceID: "legacy-peer", QueryAddress: "peer:6001", ViewMetadataAdmissionGeneration: 8, DDLVisibilityBarrierReady: false, ViewMetadataIngressReady: true}, - }} + }, frontiers: map[string]timestamp.Timestamp{"legacy-peer": targetTS}} cluster.refreshHook = func() { // The control plane dispatches activation concurrently. Model the legacy // peer completing its local drain before this CN checks global phases. @@ -826,7 +858,7 @@ func TestDefaultV41StillRunsCompleteTargetActivation(t *testing.T) { require.Equal(t, defines.MORPCVersion41, s.loadDDLVisibilityDeployedProtocol()) require.True(t, s.viewMetadataIngressReady.Load()) require.True(t, s.ddlCommitGate.PublicDDLEnabled()) - require.Contains(t, queryClient.requests, "peer:6001") + require.Empty(t, queryClient.requests) } func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { @@ -846,6 +878,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { ViewMetadataAdmissionGeneration: 9, DDLVisibilityBarrierReady: true, }, }} + cluster.frontiers = map[string]timestamp.Timestamp{"peer": targetTS} var peerReady atomic.Bool var protocolObserved atomic.Bool firstProtocol := make(chan struct{}) @@ -867,6 +900,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { } }, } + cluster.phaseHook = queryClient.protocolFn ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).DoAndReturn( @@ -927,25 +961,18 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) require.Equal(t, defines.MORPCVersion41, version) - require.Equal(t, []string{ - "peer:6001", "peer:6001", "self:6001", "peer:6001", "peer:6001", - }, queryClient.requests) - require.Equal(t, []query.CmdMethod{ - query.CmdMethod_GetProtocolVersion, - query.CmdMethod_GetProtocolVersion, - query.CmdMethod_GetCommit, - query.CmdMethod_GetCommit, - query.CmdMethod_GetProtocolVersion, - }, queryClient.methods) - require.Equal(t, 5, queryClient.releases) - require.Len(t, hakeeperClient.heartbeats, 3) - require.True(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) + require.Empty(t, queryClient.requests) + require.Empty(t, queryClient.methods) + require.Zero(t, queryClient.releases) + require.Len(t, hakeeperClient.heartbeats, 5) require.False(t, hakeeperClient.heartbeats[0].ViewMetadataIngressReady) - require.NotEmpty(t, hakeeperClient.heartbeats[1].DDLVisibilityEpochCommitTargets) - require.False(t, hakeeperClient.heartbeats[1].ViewMetadataIngressReady) - require.True(t, hakeeperClient.heartbeats[2].DDLVisibilityBarrierReady) - require.True(t, hakeeperClient.heartbeats[2].ViewMetadataIngressReady) - require.Equal(t, 5, cluster.refreshCalls) + require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityActivationPrepared) + require.False(t, hakeeperClient.heartbeats[1].DDLVisibilityActivationFenced) + require.True(t, hakeeperClient.heartbeats[2].DDLVisibilityActivationFenced) + require.NotEmpty(t, hakeeperClient.heartbeats[3].DDLVisibilityEpochCommitTargets) + require.False(t, hakeeperClient.heartbeats[3].ViewMetadataIngressReady) + require.True(t, hakeeperClient.heartbeats[4].ViewMetadataIngressReady) + require.Equal(t, 2, cluster.refreshCalls) require.True(t, s.ddlVisibilityBarrierReady.Load()) require.True(t, s.viewMetadataIngressReady.Load()) @@ -953,9 +980,9 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { resp = &query.Response{} require.NoError(t, s.handleSetProtocolVersion(context.Background(), req, resp, nil)) require.Equal(t, defines.MORPCVersion41, resp.SetProtocolVersion.Version) - require.Len(t, hakeeperClient.heartbeats, 3) - require.Equal(t, 5, cluster.refreshCalls) - require.Len(t, queryClient.requests, 5) + require.Len(t, hakeeperClient.heartbeats, 5) + require.Equal(t, 2, cluster.refreshCalls) + require.Empty(t, queryClient.requests) } func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { @@ -1000,11 +1027,12 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { require.Equal(t, defines.MORPCVersion41, resp.SetProtocolVersion.Version) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) - require.Len(t, hakeeperClient.heartbeats, 3) + require.Len(t, hakeeperClient.heartbeats, 5) require.False(t, hakeeperClient.heartbeats[0].ViewMetadataIngressReady) - require.NotEmpty(t, hakeeperClient.heartbeats[1].DDLVisibilityEpochCommitTargets) - require.False(t, hakeeperClient.heartbeats[1].ViewMetadataIngressReady) - require.False(t, hakeeperClient.heartbeats[2].ViewMetadataIngressReady) + require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityActivationPrepared) + require.True(t, hakeeperClient.heartbeats[2].DDLVisibilityActivationFenced) + require.NotEmpty(t, hakeeperClient.heartbeats[3].DDLVisibilityEpochCommitTargets) + require.False(t, hakeeperClient.heartbeats[4].ViewMetadataIngressReady) release, err := s.ddlCommitGate.Enter(context.Background()) require.NoError(t, err) release() @@ -1035,6 +1063,7 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { DDLVisibilityActivationPrepared: true, DDLVisibilityActivationFenced: true, } } + cluster.phaseHook = queryClient.protocolFn activationDone := make(chan error, 1) go func() { activationDone <- s.handleSetProtocolVersion(context.Background(), &query.Request{ @@ -1074,6 +1103,7 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T {ServiceID: "peer", QueryAddress: "peer:6001", ViewMetadataAdmissionGeneration: 8, DDLVisibilityBarrierReady: true}, }} + cluster.frontiers = map[string]timestamp.Timestamp{"peer": targetTS} queryClient := &ddlVisibilityTestQueryClient{ serviceID: serviceID, frontiers: map[string]timestamp.Timestamp{ @@ -1122,8 +1152,9 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T cancelBlocked() _, gateErr := s.ddlCommitGate.Enter(blockedCtx) require.ErrorIs(t, gateErr, context.Canceled) - require.Len(t, hakeeperClient.heartbeats, 1) + require.Len(t, hakeeperClient.heartbeats, 2) require.True(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) + require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityActivationPrepared) require.False(t, s.viewMetadataIngressReady.Load()) require.True(t, cluster.cnServices[0].DDLVisibilityBarrierReady) } @@ -1143,6 +1174,7 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing {ServiceID: "peer", QueryAddress: "peer:6001", ViewMetadataAdmissionGeneration: 8, DDLVisibilityBarrierReady: true}, }} + cluster.frontiers = map[string]timestamp.Timestamp{"peer": targetTS} queryClient := &ddlVisibilityTestQueryClient{ serviceID: serviceID, frontiers: map[string]timestamp.Timestamp{ @@ -1159,7 +1191,7 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond publishErr := errors.New("activation publication failed") hakeeperClient := &ddlVisibilityWithdrawalHAKeeperClient{ - cluster: cluster, sendErrors: map[int]error{3: publishErr}, + cluster: cluster, sendErrors: map[int]error{5: publishErr}, } s := &service{ cfg: cfg, @@ -1191,14 +1223,16 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing cancelBlocked() _, gateErr := s.ddlCommitGate.Enter(blockedCtx) require.ErrorIs(t, gateErr, context.Canceled) - require.Len(t, hakeeperClient.heartbeats, 4) + require.Len(t, hakeeperClient.heartbeats, 6) require.True(t, hakeeperClient.heartbeats[0].DDLVisibilityBarrierReady) - require.NotEmpty(t, hakeeperClient.heartbeats[1].DDLVisibilityEpochCommitTargets) - require.True(t, hakeeperClient.heartbeats[2].ViewMetadataIngressReady) - require.False(t, hakeeperClient.heartbeats[3].ViewMetadataIngressReady) + require.True(t, hakeeperClient.heartbeats[1].DDLVisibilityActivationPrepared) + require.True(t, hakeeperClient.heartbeats[2].DDLVisibilityActivationFenced) + require.NotEmpty(t, hakeeperClient.heartbeats[3].DDLVisibilityEpochCommitTargets) + require.True(t, hakeeperClient.heartbeats[4].ViewMetadataIngressReady) + require.False(t, hakeeperClient.heartbeats[5].ViewMetadataIngressReady) require.False(t, s.viewMetadataIngressReady.Load()) require.True(t, cluster.cnServices[0].DDLVisibilityBarrierReady) - require.Equal(t, 4, cluster.refreshCalls) + require.Equal(t, 2, cluster.refreshCalls) } func TestSetProtocolVersionBeforeBarrierPreparationDefersToStartupFence(t *testing.T) { @@ -1346,10 +1380,11 @@ func TestSetProtocolVersionDowngradeGuards(t *testing.T) { func TestWaitForDDLVisibilityActivationPhaseRejectsInvalidInventory(t *testing.T) { const serviceID = "activation-phase-inventory-test" - newService := func(cluster *ddlVisibilityTestCluster, queryClient *ddlVisibilityTestQueryClient) *service { + newService := func(cluster *ddlVisibilityTestCluster) *service { cfg := &Config{UUID: serviceID} cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond - s := &service{cfg: cfg, moCluster: cluster, queryClient: queryClient} + s := &service{cfg: cfg, moCluster: cluster, + _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}} s.ddlVisibilityActivationPrepared.Store(true) s.ddlVisibilityActivationFenced.Store(true) return s @@ -1361,35 +1396,23 @@ func TestWaitForDDLVisibilityActivationPhaseRejectsInvalidInventory(t *testing.T {ServiceID: serviceID, DDLVisibilityBarrierReady: true}, {ServiceID: "peer", DDLVisibilityBarrierReady: true}, }} - s := newService(cluster, &ddlVisibilityTestQueryClient{}) + s := newService(cluster) err := s.waitForDDLVisibilityActivationPhase(context.Background(), targets, false) - require.ErrorContains(t, err, "has no query address") + require.ErrorContains(t, err, "has no authoritative identity") }) - t.Run("protocol response is required", func(t *testing.T) { + t.Run("target list must include every barrier participant", func(t *testing.T) { cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ - {ServiceID: serviceID, QueryAddress: "self:6001", DDLVisibilityBarrierReady: true}, + {ServiceID: serviceID, QueryAddress: "self:6001", ViewMetadataAdmissionGeneration: 7, + DDLVisibilityBarrierReady: true}, {ServiceID: "peer", QueryAddress: "peer:6001", ViewMetadataAdmissionGeneration: 8, DDLVisibilityBarrierReady: true}, + {ServiceID: "extra", QueryAddress: "extra:6001", ViewMetadataAdmissionGeneration: 9, + DDLVisibilityBarrierReady: true}, }} - s := newService(cluster, &ddlVisibilityTestQueryClient{ - nilProtocol: map[string]bool{"peer:6001": true}, - }) + s := newService(cluster) err := s.waitForDDLVisibilityActivationPhase(context.Background(), targets, false) - require.ErrorContains(t, err, "missing protocol activation response") - }) - - t.Run("target list must include every barrier participant", func(t *testing.T) { - cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{ - {ServiceID: serviceID, DDLVisibilityBarrierReady: true}, - {ServiceID: "peer", DDLVisibilityBarrierReady: true}, - {ServiceID: "extra", DDLVisibilityBarrierReady: true}, - }} - s := newService(cluster, &ddlVisibilityTestQueryClient{}) - ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) - defer cancel() - err := s.waitForDDLVisibilityActivationPhase(ctx, targets, false) - require.ErrorContains(t, err, "did not converge") + require.ErrorContains(t, err, "omits authoritative CN") }) } @@ -1447,10 +1470,10 @@ func TestPeriodicHeartbeatCannotRepublishStaleIngressDuringActivation(t *testing activationDone := make(chan struct{}) go func() { close(activationStarted) - s.ddlVisibilityBarrierMu.Lock() + s.ddlVisibilityHeartbeatMu.Lock() s.viewMetadataIngressReady.Store(false) _, _ = client.SendCNHeartbeat(context.Background(), s.newCNStoreHeartbeat()) - s.ddlVisibilityBarrierMu.Unlock() + s.ddlVisibilityHeartbeatMu.Unlock() close(activationDone) }() <-activationStarted @@ -1551,9 +1574,12 @@ func TestSyncStartupDDLVisibilityFrontierAllowsEmptyFrontier(t *testing.T) { serviceID: serviceID, frontiers: map[string]timestamp.Timestamp{"self:6001": {}}, } - s := &service{moCluster: cluster, queryClient: queryClient} + s := &service{ + cfg: &Config{UUID: serviceID}, moCluster: cluster, queryClient: queryClient, + _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}, + } require.NoError(t, s.syncStartupDDLVisibilityFrontier(context.Background())) - require.Equal(t, []string{"self:6001"}, queryClient.requests) - require.Equal(t, 1, queryClient.releases) + require.Empty(t, queryClient.requests) + require.Zero(t, queryClient.releases) } diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 6487e0d3a457f..391b37a37a1f7 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -212,6 +212,11 @@ func (s *service) newCNStoreHeartbeat() logservicepb.CNStoreHeartbeat { ViewMetadataCatalogFencedEpoch: s.viewMetadataCatalogFencedEpoch.Load(), ViewMetadataIngressReady: s.viewMetadataIngressReady.Load(), DDLVisibilityBarrierReady: s.ddlVisibilityBarrierReady.Load(), + DDLVisibilityActivationPrepared: s.ddlVisibilityActivationPrepared.Load(), + DDLVisibilityActivationFenced: s.ddlVisibilityActivationFenced.Load(), + } + if s.ddlCommitGate != nil { + hb.DDLVisibilityFrontier = s.ddlCommitGate.LatestDDLFrontier() } if deployed := s.loadDDLVisibilityDeployedProtocol(); deployed >= defines.MORPCVersion41 { hb.DDLVisibilityDeployedProtocol = deployed @@ -238,13 +243,13 @@ func (s *service) heartbeat(ctx context.Context) { // Snapshot and send readiness under the same owner as startup, activation, // and shutdown publication. Otherwise an older in-flight true heartbeat can // arrive after activation has authoritatively published ingress=false. - s.ddlVisibilityBarrierMu.Lock() + s.ddlVisibilityHeartbeatMu.Lock() hb := s.newCNStoreHeartbeat() s.heartbeatInFlight.Store(true) s.notifyCommandPoll() cb, err := s._hakeeperClient.SendCNHeartbeat(ctx2, hb) s.heartbeatInFlight.Store(false) - s.ddlVisibilityBarrierMu.Unlock() + s.ddlVisibilityHeartbeatMu.Unlock() if err != nil { s.commandPollNeeded.Store(true) s.notifyCommandPoll() diff --git a/pkg/cnservice/server_query.go b/pkg/cnservice/server_query.go index 5f437eaa707a9..7f69eba0aa484 100644 --- a/pkg/cnservice/server_query.go +++ b/pkg/cnservice/server_query.go @@ -503,7 +503,15 @@ func (s *service) handleGetTxnInfo(ctx context.Context, req *query.Request, resp return nil } +const DDLVisibilitySyncCommitFaultPoint = "ddl_visibility_sync_commit_error" + func (s *service) handleSyncCommit(ctx context.Context, req *query.Request, resp *query.Response, _ *morpc.Buffer) error { + if _, msg, injected := fault.TriggerFault(DDLVisibilitySyncCommitFaultPoint); injected { + if msg == "" { + msg = DDLVisibilitySyncCommitFaultPoint + } + return moerr.NewInternalErrorNoCtxf("injected DDL visibility sync commit error: %s", msg) + } targetTS := req.SycnCommit.LatestCommitTS if _, err := s._txnClient.WaitLogTailAppliedAt(ctx, targetTS); err != nil { return err diff --git a/pkg/cnservice/types.go b/pkg/cnservice/types.go index 8d93aec3fe47c..07e5636498e7e 100644 --- a/pkg/cnservice/types.go +++ b/pkg/cnservice/types.go @@ -809,6 +809,7 @@ type service struct { ddlVisibilityListenersReady atomic.Bool ddlVisibilityRestoreIngress atomic.Bool ddlVisibilityBarrierMu sync.Mutex + ddlVisibilityHeartbeatMu sync.Mutex ddlCommitGate *frontend.DDLCommitGate viewMetadataGenerationRevoked atomic.Bool viewMetadataRevocationOnce sync.Once diff --git a/pkg/frontend/ddl_commit_gate.go b/pkg/frontend/ddl_commit_gate.go index 00577d4b80ab2..3257e7dcf1728 100644 --- a/pkg/frontend/ddl_commit_gate.go +++ b/pkg/frontend/ddl_commit_gate.go @@ -17,9 +17,11 @@ package frontend import ( "context" "sync" + "sync/atomic" "github.com/matrixorigin/matrixone/pkg/common/moerr" moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/pb/timestamp" ) const DDLCommitGateRuntimeKey = "frontend.ddl-commit-gate" @@ -30,12 +32,13 @@ const DDLCommitGateRuntimeKey = "frontend.ddl-commit-gate" // the gate blocked across RPC attempts; Close wakes blocked sessions during CN // shutdown. type DDLCommitGate struct { - mu sync.Mutex - changed chan struct{} - blocked bool - closed bool - publicDDL bool - active int + mu sync.Mutex + changed chan struct{} + blocked bool + closed bool + publicDDL bool + active int + ddlFrontier atomic.Pointer[timestamp.Timestamp] // enterBlockedHook is a deterministic test hook invoked after Enter observes // a blocked gate and before it waits. Production leaves it nil. enterBlockedHook func() @@ -45,6 +48,29 @@ func NewDDLCommitGate() *DDLCommitGate { return &DDLCommitGate{changed: make(chan struct{})} } +func (g *DDLCommitGate) RecordDDLFrontier(ts timestamp.Timestamp) { + if ts.IsEmpty() { + return + } + candidate := ts + for { + current := g.ddlFrontier.Load() + if current != nil && current.GreaterEq(ts) { + return + } + if g.ddlFrontier.CompareAndSwap(current, &candidate) { + return + } + } +} + +func (g *DDLCommitGate) LatestDDLFrontier() timestamp.Timestamp { + if current := g.ddlFrontier.Load(); current != nil { + return *current + } + return timestamp.Timestamp{} +} + func publicBackgroundDDLBarrierEnabled(serviceID string) bool { value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(DDLCommitGateRuntimeKey) if !ok || value == nil { @@ -54,6 +80,16 @@ func publicBackgroundDDLBarrierEnabled(serviceID string) bool { return ok && gate.PublicDDLEnabled() } +func recordDDLCommitFrontier(serviceID string, ts timestamp.Timestamp) { + value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(DDLCommitGateRuntimeKey) + if !ok || value == nil { + return + } + if gate, ok := value.(*DDLCommitGate); ok { + gate.RecordDDLFrontier(ts) + } +} + func enterDDLCommitGate(ctx context.Context, serviceID string) (func(), error) { value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(DDLCommitGateRuntimeKey) if !ok || value == nil { diff --git a/pkg/frontend/ddl_commit_gate_test.go b/pkg/frontend/ddl_commit_gate_test.go index 2c1ac47f06f42..d2a57edcf8eb4 100644 --- a/pkg/frontend/ddl_commit_gate_test.go +++ b/pkg/frontend/ddl_commit_gate_test.go @@ -18,6 +18,7 @@ import ( "context" "testing" + "github.com/matrixorigin/matrixone/pkg/pb/timestamp" "github.com/stretchr/testify/require" ) @@ -61,6 +62,17 @@ func TestDDLCommitGateLinearizesBlockAndCommit(t *testing.T) { require.NoError(t, <-enterDone) } +func TestDDLCommitGateTracksOnlyMonotonicDDLFrontier(t *testing.T) { + gate := NewDDLCommitGate() + older := timestamp.Timestamp{PhysicalTime: 100} + newer := timestamp.Timestamp{PhysicalTime: 200} + + require.True(t, gate.LatestDDLFrontier().IsEmpty()) + gate.RecordDDLFrontier(newer) + gate.RecordDDLFrontier(older) + require.Equal(t, newer, gate.LatestDDLFrontier()) +} + func TestDDLCommitGateCancellationAndClose(t *testing.T) { gate := NewDDLCommitGate() gate.EnablePublicDDL() diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index cf2c6e964e7e3..db09c40da0f5f 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -1037,6 +1037,9 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { owner.rollbackTempTableTransaction(tempTxnKey) } } + if haveDDL && !commitTs.IsEmpty() && (err == nil || commitResultUnknown) { + recordDDLCommitFrontier(execCtx.ses.GetService(), commitTs) + } if commitResultUnknown { // ErrTxnUnknown is terminal for this frontend handle. The operator // has already finalized its workspace non-destructively; retaining it diff --git a/pkg/hakeeper/rsm.go b/pkg/hakeeper/rsm.go index fdcd5d863fa62..2505faae693ea 100644 --- a/pkg/hakeeper/rsm.go +++ b/pkg/hakeeper/rsm.go @@ -1752,6 +1752,9 @@ func (s *stateMachine) handleClusterDetailsQuery(cfg Config) *pb.ClusterDetails ViewMetadataAdmissionReady: info.ViewMetadataAdmissionReady, DDLVisibilityBarrierReady: info.DDLVisibilityBarrierReady, DDLVisibilityDeployedProtocol: info.DDLVisibilityDeployedProtocol, + DDLVisibilityActivationPrepared: info.DDLVisibilityActivationPrepared, + DDLVisibilityActivationFenced: info.DDLVisibilityActivationFenced, + DDLVisibilityFrontier: info.DDLVisibilityFrontier, ViewMetadataIngressReady: info.ViewMetadataIngressReady, } cd.CNStores = append(cd.CNStores, n) diff --git a/pkg/pb/logservice/logservice.go b/pkg/pb/logservice/logservice.go index 3277e9dfcef19..99a693f2c7a27 100644 --- a/pkg/pb/logservice/logservice.go +++ b/pkg/pb/logservice/logservice.go @@ -171,6 +171,9 @@ func (s *CNState) Update(hb CNStoreHeartbeat, tick uint64) { } storeInfo.DDLVisibilityBarrierReady = hb.DDLVisibilityBarrierReady storeInfo.DDLVisibilityDeployedProtocol = hb.DDLVisibilityDeployedProtocol + storeInfo.DDLVisibilityActivationPrepared = hb.DDLVisibilityActivationPrepared + storeInfo.DDLVisibilityActivationFenced = hb.DDLVisibilityActivationFenced + storeInfo.DDLVisibilityFrontier = hb.DDLVisibilityFrontier s.Stores[hb.UUID] = storeInfo if hb.DDLVisibilityDeployedProtocol > s.DDLVisibilityDeployedProtocol && len(hb.DDLVisibilityEpochCommitTargets) > 0 && @@ -198,7 +201,8 @@ func (s *CNState) matchesDDLVisibilityEpochCommitTargets(targets []DDLVisibility seen++ target, ok := expected[serviceID] if !ok || target.Generation != store.ViewMetadataAdmissionGeneration || - target.QueryAddress != store.QueryAddress || !store.DDLVisibilityBarrierReady { + target.QueryAddress != store.QueryAddress || !store.DDLVisibilityBarrierReady || + !store.DDLVisibilityActivationPrepared || !store.DDLVisibilityActivationFenced { return false } } diff --git a/pkg/pb/logservice/logservice.pb.go b/pkg/pb/logservice/logservice.pb.go index 3498437d3cc44..292aaf1ec4b91 100644 --- a/pkg/pb/logservice/logservice.pb.go +++ b/pkg/pb/logservice/logservice.pb.go @@ -15,6 +15,7 @@ import ( proto "github.com/gogo/protobuf/proto" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" metadata "github.com/matrixorigin/matrixone/pkg/pb/metadata" + timestamp "github.com/matrixorigin/matrixone/pkg/pb/timestamp" _ "google.golang.org/protobuf/types/known/timestamppb" ) @@ -534,11 +535,14 @@ type CNStore struct { // visibility fence even when public SQL ingress is not admitted yet. DDLVisibilityBarrierReady bool `protobuf:"varint,21,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` // ViewMetadataIngressReady is retained for raw control-plane inventory. - ViewMetadataIngressReady bool `protobuf:"varint,22,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` - DDLVisibilityDeployedProtocol int64 `protobuf:"varint,23,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ViewMetadataIngressReady bool `protobuf:"varint,22,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,23,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + DDLVisibilityActivationPrepared bool `protobuf:"varint,24,opt,name=DDLVisibilityActivationPrepared,proto3" json:"DDLVisibilityActivationPrepared,omitempty"` + DDLVisibilityActivationFenced bool `protobuf:"varint,25,opt,name=DDLVisibilityActivationFenced,proto3" json:"DDLVisibilityActivationFenced,omitempty"` + DDLVisibilityFrontier timestamp.Timestamp `protobuf:"bytes,26,opt,name=DDLVisibilityFrontier,proto3" json:"DDLVisibilityFrontier"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNStore) Reset() { *m = CNStore{} } @@ -728,6 +732,27 @@ func (m *CNStore) GetDDLVisibilityDeployedProtocol() int64 { return 0 } +func (m *CNStore) GetDDLVisibilityActivationPrepared() bool { + if m != nil { + return m.DDLVisibilityActivationPrepared + } + return false +} + +func (m *CNStore) GetDDLVisibilityActivationFenced() bool { + if m != nil { + return m.DDLVisibilityActivationFenced + } + return false +} + +func (m *CNStore) GetDDLVisibilityFrontier() timestamp.Timestamp { + if m != nil { + return m.DDLVisibilityFrontier + } + return timestamp.Timestamp{} +} + type TNStore struct { UUID string `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"` ServiceAddress string `protobuf:"bytes,2,opt,name=ServiceAddress,proto3" json:"ServiceAddress,omitempty"` @@ -1292,6 +1317,9 @@ type CNStoreHeartbeat struct { // Non-empty only for the transition that atomically validates the complete // CN membership tuple set and commits DDLVisibilityDeployedProtocol. DDLVisibilityEpochCommitTargets []DDLVisibilityActivationTarget `protobuf:"bytes,27,rep,name=DDLVisibilityEpochCommitTargets,proto3" json:"DDLVisibilityEpochCommitTargets"` + DDLVisibilityActivationPrepared bool `protobuf:"varint,28,opt,name=DDLVisibilityActivationPrepared,proto3" json:"DDLVisibilityActivationPrepared,omitempty"` + DDLVisibilityActivationFenced bool `protobuf:"varint,29,opt,name=DDLVisibilityActivationFenced,proto3" json:"DDLVisibilityActivationFenced,omitempty"` + DDLVisibilityFrontier timestamp.Timestamp `protobuf:"bytes,30,opt,name=DDLVisibilityFrontier,proto3" json:"DDLVisibilityFrontier"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1512,6 +1540,27 @@ func (m *CNStoreHeartbeat) GetDDLVisibilityEpochCommitTargets() []DDLVisibilityA return nil } +func (m *CNStoreHeartbeat) GetDDLVisibilityActivationPrepared() bool { + if m != nil { + return m.DDLVisibilityActivationPrepared + } + return false +} + +func (m *CNStoreHeartbeat) GetDDLVisibilityActivationFenced() bool { + if m != nil { + return m.DDLVisibilityActivationFenced + } + return false +} + +func (m *CNStoreHeartbeat) GetDDLVisibilityFrontier() timestamp.Timestamp { + if m != nil { + return m.DDLVisibilityFrontier + } + return timestamp.Timestamp{} +} + // CNAllocateID is the periodic message sent tp the HAKeeper by CN stores. type CNAllocateID struct { Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` @@ -4169,20 +4218,23 @@ type CNStoreInfo struct { // CommandDeliveryAckSupported reports whether this CN can use the // non-destructive acknowledged schedule-command protocol. It is copied // from CNStoreHeartbeat so HAKeeper can gate activation and admission. - CommandDeliveryAckSupported bool `protobuf:"varint,18,opt,name=CommandDeliveryAckSupported,proto3" json:"CommandDeliveryAckSupported,omitempty"` - ViewMetadataAdmissionSupported bool `protobuf:"varint,19,opt,name=ViewMetadataAdmissionSupported,proto3" json:"ViewMetadataAdmissionSupported,omitempty"` - ViewMetadataAdmissionGeneration uint64 `protobuf:"varint,20,opt,name=ViewMetadataAdmissionGeneration,proto3" json:"ViewMetadataAdmissionGeneration,omitempty"` - ViewMetadataObservedEpoch uint64 `protobuf:"varint,21,opt,name=ViewMetadataObservedEpoch,proto3" json:"ViewMetadataObservedEpoch,omitempty"` - ViewMetadataCatalogFencedEpoch uint64 `protobuf:"varint,22,opt,name=ViewMetadataCatalogFencedEpoch,proto3" json:"ViewMetadataCatalogFencedEpoch,omitempty"` - ViewMetadataRefreshSupported bool `protobuf:"varint,23,opt,name=ViewMetadataRefreshSupported,proto3" json:"ViewMetadataRefreshSupported,omitempty"` - ViewMetadataRevalidatedEpoch uint64 `protobuf:"varint,24,opt,name=ViewMetadataRevalidatedEpoch,proto3" json:"ViewMetadataRevalidatedEpoch,omitempty"` - ViewMetadataAdmissionReady bool `protobuf:"varint,25,opt,name=ViewMetadataAdmissionReady,proto3" json:"ViewMetadataAdmissionReady,omitempty"` - ViewMetadataIngressReady bool `protobuf:"varint,26,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` - DDLVisibilityBarrierReady bool `protobuf:"varint,27,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` - DDLVisibilityDeployedProtocol int64 `protobuf:"varint,28,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + CommandDeliveryAckSupported bool `protobuf:"varint,18,opt,name=CommandDeliveryAckSupported,proto3" json:"CommandDeliveryAckSupported,omitempty"` + ViewMetadataAdmissionSupported bool `protobuf:"varint,19,opt,name=ViewMetadataAdmissionSupported,proto3" json:"ViewMetadataAdmissionSupported,omitempty"` + ViewMetadataAdmissionGeneration uint64 `protobuf:"varint,20,opt,name=ViewMetadataAdmissionGeneration,proto3" json:"ViewMetadataAdmissionGeneration,omitempty"` + ViewMetadataObservedEpoch uint64 `protobuf:"varint,21,opt,name=ViewMetadataObservedEpoch,proto3" json:"ViewMetadataObservedEpoch,omitempty"` + ViewMetadataCatalogFencedEpoch uint64 `protobuf:"varint,22,opt,name=ViewMetadataCatalogFencedEpoch,proto3" json:"ViewMetadataCatalogFencedEpoch,omitempty"` + ViewMetadataRefreshSupported bool `protobuf:"varint,23,opt,name=ViewMetadataRefreshSupported,proto3" json:"ViewMetadataRefreshSupported,omitempty"` + ViewMetadataRevalidatedEpoch uint64 `protobuf:"varint,24,opt,name=ViewMetadataRevalidatedEpoch,proto3" json:"ViewMetadataRevalidatedEpoch,omitempty"` + ViewMetadataAdmissionReady bool `protobuf:"varint,25,opt,name=ViewMetadataAdmissionReady,proto3" json:"ViewMetadataAdmissionReady,omitempty"` + ViewMetadataIngressReady bool `protobuf:"varint,26,opt,name=ViewMetadataIngressReady,proto3" json:"ViewMetadataIngressReady,omitempty"` + DDLVisibilityBarrierReady bool `protobuf:"varint,27,opt,name=DDLVisibilityBarrierReady,proto3" json:"DDLVisibilityBarrierReady,omitempty"` + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,28,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + DDLVisibilityActivationPrepared bool `protobuf:"varint,29,opt,name=DDLVisibilityActivationPrepared,proto3" json:"DDLVisibilityActivationPrepared,omitempty"` + DDLVisibilityActivationFenced bool `protobuf:"varint,30,opt,name=DDLVisibilityActivationFenced,proto3" json:"DDLVisibilityActivationFenced,omitempty"` + DDLVisibilityFrontier timestamp.Timestamp `protobuf:"bytes,31,opt,name=DDLVisibilityFrontier,proto3" json:"DDLVisibilityFrontier"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNStoreInfo) Reset() { *m = CNStoreInfo{} } @@ -4407,6 +4459,27 @@ func (m *CNStoreInfo) GetDDLVisibilityDeployedProtocol() int64 { return 0 } +func (m *CNStoreInfo) GetDDLVisibilityActivationPrepared() bool { + if m != nil { + return m.DDLVisibilityActivationPrepared + } + return false +} + +func (m *CNStoreInfo) GetDDLVisibilityActivationFenced() bool { + if m != nil { + return m.DDLVisibilityActivationFenced + } + return false +} + +func (m *CNStoreInfo) GetDDLVisibilityFrontier() timestamp.Timestamp { + if m != nil { + return m.DDLVisibilityFrontier + } + return timestamp.Timestamp{} +} + // CNState contains all CN details known to the HAKeeper. type CNState struct { // Stores is keyed by CN store UUID. @@ -6657,389 +6730,395 @@ func init() { func init() { proto.RegisterFile("logservice.proto", fileDescriptor_fd1040c5381ab5a7) } var fileDescriptor_fd1040c5381ab5a7 = []byte{ - // 6109 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3d, 0x5b, 0x6f, 0x1b, 0xd9, - 0x79, 0x1e, 0x92, 0x92, 0xc8, 0x8f, 0x92, 0x3c, 0x3a, 0xba, 0x98, 0x96, 0x6d, 0x59, 0xcb, 0x75, - 0x76, 0xbd, 0xca, 0x46, 0x4e, 0xed, 0xec, 0x62, 0x93, 0x3a, 0xde, 0xa5, 0x48, 0xae, 0x45, 0x9b, - 0xa6, 0xb4, 0xc3, 0x91, 0x37, 0x09, 0xb0, 0x10, 0x46, 0xe4, 0xb1, 0x3c, 0x11, 0xc5, 0x61, 0x66, - 0x46, 0x5e, 0xab, 0x7d, 0x6a, 0xd1, 0x14, 0x45, 0x83, 0x06, 0x0d, 0x10, 0xb4, 0x41, 0xd3, 0xf4, - 0xf6, 0xd6, 0xa7, 0xbc, 0xf4, 0x37, 0x14, 0x79, 0x28, 0x8a, 0x34, 0x8f, 0x05, 0x9a, 0xcb, 0xf6, - 0xa5, 0x40, 0xde, 0x9b, 0xa7, 0x02, 0xc5, 0xb9, 0xcd, 0x9c, 0x33, 0x17, 0x5e, 0x24, 0x25, 0x69, - 0x8a, 0x3c, 0x89, 0xe7, 0x3b, 0xdf, 0x77, 0xae, 0xdf, 0xed, 0x7c, 0xe7, 0x3b, 0x23, 0xd0, 0x7b, - 0xce, 0xa1, 0x87, 0xdd, 0x17, 0x76, 0x07, 0x6f, 0x0e, 0x5c, 0xc7, 0x77, 0x10, 0x84, 0x90, 0xd5, - 0xcf, 0x1c, 0xda, 0xfe, 0xf3, 0x93, 0x83, 0xcd, 0x8e, 0x73, 0x7c, 0xe7, 0xd0, 0x39, 0x74, 0xee, - 0x50, 0x94, 0x83, 0x93, 0x67, 0xb4, 0x44, 0x0b, 0xf4, 0x17, 0x23, 0x5d, 0xbd, 0x79, 0xe8, 0x38, - 0x87, 0x3d, 0x1c, 0x62, 0xf9, 0xf6, 0x31, 0xf6, 0x7c, 0xeb, 0x78, 0xc0, 0x11, 0xe6, 0x8f, 0xb1, - 0x6f, 0x75, 0x2d, 0xdf, 0x62, 0xe5, 0xf2, 0x37, 0x0b, 0x30, 0x53, 0x6d, 0xb5, 0x7d, 0xc7, 0xc5, - 0x08, 0x41, 0x6e, 0x6f, 0xaf, 0x51, 0x2b, 0x69, 0xeb, 0xda, 0xed, 0x82, 0x41, 0x7f, 0xa3, 0xd7, - 0x60, 0xbe, 0xcd, 0x86, 0x52, 0xe9, 0x76, 0x5d, 0xec, 0x79, 0xa5, 0x0c, 0xad, 0x8d, 0x40, 0xd1, - 0x1a, 0x40, 0xfb, 0x83, 0xa6, 0xc0, 0xc9, 0x52, 0x1c, 0x09, 0x82, 0x36, 0x01, 0x35, 0x9d, 0xce, - 0x51, 0xa4, 0xad, 0x1c, 0xc5, 0x4b, 0xa8, 0x41, 0xb7, 0x20, 0x67, 0x38, 0x3d, 0x5c, 0x9a, 0x5e, - 0xd7, 0x6e, 0xcf, 0xdf, 0xd5, 0x37, 0x83, 0x61, 0x57, 0x5b, 0x04, 0x6e, 0xd0, 0x5a, 0x32, 0x62, - 0xd3, 0xee, 0x1c, 0x95, 0x66, 0xd6, 0xb5, 0xdb, 0x39, 0x83, 0xfe, 0x46, 0x9f, 0x86, 0xa9, 0xb6, - 0x6f, 0xf9, 0xb8, 0x94, 0xa7, 0xa4, 0xcb, 0x9b, 0xd2, 0xfa, 0xb6, 0x9c, 0x2e, 0xa6, 0x95, 0x06, - 0xc3, 0x41, 0x5f, 0x84, 0xe9, 0xa6, 0x75, 0x80, 0x7b, 0x5e, 0xa9, 0xb0, 0x9e, 0xbd, 0x5d, 0xbc, - 0x7b, 0x53, 0xc6, 0xe6, 0xeb, 0xb2, 0xc9, 0x30, 0xea, 0x7d, 0xdf, 0x3d, 0xdd, 0xca, 0xfd, 0xe0, - 0xc7, 0x37, 0x2f, 0x19, 0x9c, 0x08, 0xfd, 0x0e, 0x14, 0x3e, 0x74, 0xdc, 0x23, 0xd6, 0x1f, 0xd0, - 0xfe, 0x16, 0xc3, 0xa1, 0x06, 0x55, 0x46, 0x88, 0x85, 0xca, 0x30, 0xfb, 0xc1, 0x09, 0x76, 0x4f, - 0xc5, 0x12, 0x14, 0xe9, 0x12, 0x28, 0x30, 0xf4, 0x36, 0x40, 0xd5, 0xe9, 0x3f, 0xb3, 0x0f, 0x6b, - 0x96, 0x6f, 0x95, 0x66, 0xd7, 0xb5, 0xdb, 0xc5, 0xbb, 0x2b, 0xca, 0xc8, 0x82, 0x5a, 0x43, 0xc2, - 0x44, 0x6f, 0x43, 0xde, 0xc0, 0x9e, 0x73, 0xe2, 0x76, 0x70, 0x69, 0x8e, 0x52, 0x2d, 0xc9, 0x54, - 0xa2, 0x8e, 0x4f, 0x22, 0xc0, 0x45, 0x2b, 0x30, 0xbd, 0x37, 0x30, 0xed, 0x63, 0x5c, 0x9a, 0x5f, - 0xd7, 0x6e, 0x67, 0x0d, 0x5e, 0x42, 0x9f, 0x85, 0xc5, 0xf6, 0x73, 0xcb, 0xed, 0x46, 0x76, 0xed, - 0x32, 0x1d, 0x72, 0x52, 0x15, 0x5a, 0x85, 0x7c, 0xd5, 0x39, 0x3e, 0xb6, 0xfd, 0x46, 0xad, 0xa4, - 0x53, 0xb4, 0xa0, 0x8c, 0xde, 0x87, 0xb5, 0xa7, 0x36, 0xfe, 0xf8, 0x09, 0x5f, 0x9e, 0x4a, 0xf7, - 0xd8, 0xf6, 0x3c, 0xdb, 0xe9, 0xb7, 0x4f, 0x06, 0x03, 0xc7, 0xf5, 0x71, 0xb7, 0xb4, 0xb0, 0xae, - 0xdd, 0xce, 0x1b, 0x23, 0xb0, 0xd0, 0x36, 0xdc, 0x4c, 0xc4, 0x78, 0x88, 0xfb, 0xd8, 0xb5, 0x7c, - 0xdb, 0xe9, 0x97, 0x10, 0xe5, 0x87, 0x51, 0x68, 0xe8, 0x3e, 0x5c, 0x95, 0x51, 0x76, 0x0e, 0xc8, - 0x4a, 0xe1, 0x6e, 0x7d, 0xe0, 0x74, 0x9e, 0x97, 0x16, 0x69, 0x1b, 0xe9, 0x08, 0xe8, 0x01, 0xac, - 0x26, 0x76, 0x60, 0x60, 0xab, 0x7b, 0x5a, 0x5a, 0xa2, 0x73, 0x19, 0x82, 0x41, 0x7a, 0xaf, 0xd5, - 0x9a, 0x4f, 0x6d, 0xcf, 0x3e, 0xb0, 0x7b, 0xb6, 0x7f, 0xba, 0x65, 0xb9, 0xae, 0x8d, 0x5d, 0x46, - 0xbe, 0x4c, 0xc9, 0xd3, 0x11, 0xd0, 0x17, 0xa0, 0x24, 0xb7, 0xdd, 0xe8, 0x1f, 0x92, 0x0d, 0x60, - 0xc4, 0x2b, 0x94, 0x38, 0xb5, 0x1e, 0xd5, 0xe0, 0x86, 0xd2, 0x70, 0x0d, 0x0f, 0x7a, 0xce, 0x29, - 0xee, 0xee, 0x12, 0x95, 0xd0, 0x71, 0x7a, 0xa5, 0x2b, 0x94, 0x0d, 0x86, 0x23, 0xad, 0xb6, 0xa0, - 0x28, 0x49, 0x06, 0xd2, 0x21, 0x7b, 0x84, 0x4f, 0xb9, 0xf2, 0x20, 0x3f, 0xd1, 0x1b, 0x30, 0xf5, - 0xc2, 0xea, 0x9d, 0x60, 0xaa, 0x32, 0x8a, 0xb2, 0x64, 0x50, 0xba, 0xa6, 0xed, 0xf9, 0x06, 0xc3, - 0xf8, 0x42, 0xe6, 0x1d, 0xed, 0x51, 0x2e, 0x3f, 0xa5, 0x4f, 0x97, 0x7f, 0x91, 0x85, 0x19, 0xf3, - 0x02, 0x14, 0x92, 0x50, 0x0d, 0xd9, 0x24, 0xd5, 0x90, 0x1b, 0x43, 0x35, 0xbc, 0x05, 0xd3, 0x94, - 0xc3, 0xbd, 0xd2, 0x14, 0x55, 0x0d, 0x57, 0x64, 0x6c, 0xb3, 0x45, 0xeb, 0x1a, 0xfd, 0x67, 0x8e, - 0x50, 0x09, 0x0c, 0x19, 0xdd, 0x85, 0xa5, 0xa6, 0x73, 0xe8, 0x5b, 0x76, 0x8f, 0x0c, 0x08, 0xbb, - 0x62, 0x94, 0xd3, 0x74, 0x94, 0x89, 0x75, 0x29, 0xca, 0x71, 0x26, 0x55, 0x39, 0xaa, 0xfa, 0xa1, - 0x30, 0xb6, 0x7e, 0x88, 0xea, 0x1e, 0x48, 0xd0, 0x3d, 0x29, 0x32, 0x5f, 0x4c, 0x97, 0xf9, 0xf7, - 0xe0, 0x5a, 0xe5, 0xc4, 0x77, 0x1a, 0xfd, 0x8e, 0x4b, 0x05, 0xe3, 0x7d, 0xdc, 0xef, 0xe0, 0x50, - 0xa8, 0x67, 0x29, 0x33, 0x0e, 0x43, 0x79, 0x94, 0xcb, 0xe7, 0xf5, 0x42, 0xf9, 0xcf, 0xb2, 0x90, - 0x6f, 0x3a, 0x87, 0xff, 0x07, 0xb6, 0xfe, 0x3e, 0xd1, 0xa3, 0x83, 0x9e, 0xdd, 0xb1, 0xc4, 0xe6, - 0xaf, 0xca, 0xf8, 0x4d, 0xe7, 0x90, 0x57, 0x4b, 0xfb, 0x1f, 0x50, 0x44, 0x76, 0x67, 0x7a, 0x12, - 0xed, 0xdd, 0x74, 0x3a, 0x16, 0x91, 0x35, 0xba, 0xf7, 0x11, 0xed, 0x2d, 0xea, 0x44, 0x7f, 0xa2, - 0x8c, 0x9e, 0xc2, 0x6b, 0x43, 0x05, 0x35, 0xdc, 0x8a, 0x3c, 0xdd, 0x8a, 0x31, 0xb1, 0xcb, 0xdf, - 0xce, 0xc2, 0x2c, 0xd9, 0x0f, 0xc1, 0xe8, 0xa8, 0x04, 0x33, 0xac, 0xc0, 0xb6, 0x25, 0x67, 0x88, - 0x22, 0xda, 0x92, 0x16, 0x2c, 0x43, 0x17, 0xec, 0xb5, 0xc8, 0x82, 0x05, 0xad, 0x6c, 0x0a, 0x44, - 0xaa, 0x35, 0xa4, 0x65, 0x5b, 0x82, 0x29, 0xa6, 0x78, 0xd9, 0xb6, 0xb1, 0x02, 0x31, 0x28, 0x4d, - 0x6c, 0x75, 0xb1, 0xdb, 0xa8, 0xd1, 0xad, 0xcb, 0x19, 0x41, 0x99, 0xee, 0x33, 0x76, 0x8f, 0x4b, - 0x53, 0x7c, 0x9f, 0xb1, 0x7b, 0x8c, 0x3e, 0x82, 0x85, 0x96, 0xd3, 0x7f, 0xea, 0xf8, 0x76, 0xff, - 0x30, 0x18, 0xd2, 0x34, 0x1d, 0xd2, 0x9d, 0xd4, 0x21, 0xc5, 0x28, 0xd8, 0xd8, 0xe2, 0x2d, 0xad, - 0xfe, 0x2e, 0xcc, 0x29, 0x38, 0xb2, 0xd6, 0xcb, 0x31, 0xad, 0xb7, 0x24, 0x6b, 0xbd, 0x82, 0xa4, - 0xe0, 0x56, 0x6b, 0xb0, 0x92, 0xdc, 0xd3, 0x24, 0xad, 0x94, 0xbf, 0xa3, 0xc1, 0xbc, 0xca, 0x81, - 0xe8, 0x7d, 0x75, 0xa3, 0x68, 0x3b, 0xc5, 0xbb, 0xa5, 0xb4, 0xf9, 0x6e, 0xe5, 0x09, 0x07, 0xfd, - 0xf0, 0xc7, 0x37, 0x35, 0x43, 0xdd, 0xe0, 0xeb, 0x50, 0x10, 0xcd, 0xd6, 0x68, 0xc7, 0x39, 0x23, - 0x04, 0xa0, 0x75, 0x28, 0x36, 0xbc, 0x60, 0x02, 0x74, 0x9b, 0xf2, 0x86, 0x0c, 0x2a, 0xff, 0xa9, - 0x16, 0x3a, 0x20, 0xd4, 0x15, 0xd8, 0xdd, 0x33, 0x1d, 0xdf, 0xea, 0xf1, 0x89, 0x05, 0x65, 0xa2, - 0x88, 0xaa, 0xbb, 0x7b, 0x95, 0x17, 0x96, 0xdd, 0xb3, 0x0e, 0x7a, 0x6c, 0x92, 0x9a, 0xa1, 0xc0, - 0x08, 0xfd, 0x13, 0x7c, 0xcc, 0xe8, 0x19, 0x4b, 0x04, 0x65, 0x42, 0xff, 0x04, 0x1f, 0x87, 0xf4, - 0x8c, 0x33, 0x14, 0x58, 0xf9, 0x0f, 0xb4, 0x88, 0x95, 0xab, 0x74, 0x7c, 0xfb, 0x05, 0x35, 0xfc, - 0xa6, 0xe5, 0x1e, 0x62, 0x9f, 0x4c, 0x97, 0x6b, 0x8e, 0x40, 0xd1, 0x84, 0x00, 0xe2, 0xd1, 0x4a, - 0x1e, 0x05, 0x5b, 0x0d, 0x09, 0x12, 0x53, 0xa6, 0xd9, 0xb8, 0x32, 0x2d, 0x7f, 0xb7, 0x08, 0x3a, - 0xf7, 0x22, 0xb7, 0xb1, 0xe5, 0xfa, 0x07, 0xd8, 0xf2, 0x7f, 0x03, 0xdd, 0xec, 0x4d, 0x40, 0xa6, - 0xe5, 0x09, 0xda, 0xaa, 0x8b, 0x2d, 0xa2, 0x4d, 0x66, 0x28, 0x03, 0x24, 0xd4, 0xc4, 0x96, 0x26, - 0x9f, 0x60, 0x67, 0x6e, 0xc1, 0x5c, 0xa3, 0x6f, 0xfb, 0xa1, 0xfb, 0x5c, 0xa0, 0x48, 0x2a, 0x90, - 0x60, 0x3d, 0x74, 0x3c, 0xcf, 0x1e, 0xa8, 0x26, 0x4b, 0x05, 0x92, 0xfe, 0x18, 0xe0, 0x91, 0x63, - 0xf7, 0x71, 0x97, 0x1a, 0xab, 0xbc, 0xa1, 0xc0, 0x7e, 0xe5, 0x3e, 0x75, 0x8a, 0x1d, 0x9d, 0x1f, - 0xcf, 0x77, 0xbe, 0x1c, 0xf1, 0x9d, 0x3f, 0x0b, 0x8b, 0x95, 0xce, 0x11, 0xee, 0x12, 0x80, 0xd5, - 0xef, 0x6e, 0x59, 0x7e, 0xe7, 0x39, 0x77, 0xb1, 0x73, 0x46, 0x52, 0x15, 0xb1, 0xca, 0x1c, 0x52, - 0xc3, 0x3d, 0xfb, 0x05, 0x59, 0xf9, 0xce, 0x51, 0xd4, 0xd5, 0x1e, 0x86, 0x32, 0x86, 0xbf, 0x8e, - 0x2e, 0xca, 0x5f, 0x5f, 0xbc, 0x00, 0x7f, 0x7d, 0x69, 0x94, 0xbf, 0x1e, 0x99, 0x4f, 0xd5, 0xf2, - 0xad, 0x9e, 0x73, 0x48, 0x5d, 0x11, 0xde, 0xc4, 0x32, 0x6d, 0x62, 0x04, 0x16, 0xda, 0x82, 0xeb, - 0x32, 0x86, 0x81, 0x9f, 0xb9, 0xd8, 0x7b, 0x1e, 0xae, 0x0a, 0xf3, 0xbe, 0x87, 0xe2, 0xc4, 0xdb, - 0x78, 0x61, 0xf5, 0xec, 0x2e, 0x11, 0x1e, 0x36, 0x92, 0x2b, 0x74, 0x24, 0x43, 0x71, 0x86, 0x9e, - 0x00, 0x4a, 0x23, 0x4e, 0x00, 0x43, 0xcf, 0x1e, 0x57, 0x47, 0x9d, 0x3d, 0x46, 0x9e, 0x1f, 0x56, - 0xc7, 0x38, 0x3f, 0xa0, 0x53, 0xb8, 0xa9, 0x20, 0xd0, 0x59, 0x31, 0x8e, 0x67, 0x0a, 0xda, 0x2b, - 0x5d, 0xa3, 0x86, 0xfb, 0x0d, 0x59, 0xe0, 0x86, 0xaa, 0x74, 0x2e, 0x85, 0xa3, 0xda, 0xe5, 0x47, - 0x0d, 0x13, 0x66, 0xab, 0xad, 0x4a, 0xaf, 0xe7, 0x74, 0x2c, 0x9f, 0x68, 0xfc, 0xf8, 0x09, 0x66, - 0x09, 0xa6, 0xa8, 0x3c, 0x71, 0xf5, 0xcf, 0x0a, 0xcc, 0x4c, 0x7e, 0xed, 0x04, 0x7b, 0x44, 0x52, - 0x99, 0x0e, 0x0e, 0x01, 0xe5, 0x7f, 0xcb, 0xc1, 0x82, 0x70, 0x63, 0x87, 0x2b, 0xfd, 0x75, 0x28, - 0x1a, 0xd6, 0x33, 0x5f, 0xd5, 0xf8, 0x32, 0x28, 0xc1, 0x2c, 0x64, 0x13, 0xcd, 0x42, 0x4c, 0x4d, - 0xe6, 0x92, 0xd4, 0xe4, 0xf9, 0xdc, 0xda, 0x64, 0x23, 0x30, 0x9d, 0x6a, 0x04, 0x54, 0x85, 0x3b, - 0x73, 0x26, 0x37, 0x38, 0x3f, 0x81, 0x1b, 0xfc, 0x05, 0x28, 0x45, 0xb4, 0x59, 0x28, 0x92, 0x05, - 0x26, 0x0e, 0x69, 0xf5, 0x63, 0xa8, 0x3a, 0x18, 0x4b, 0xd5, 0x8d, 0xef, 0x8a, 0x17, 0x27, 0x72, - 0xc5, 0xeb, 0x50, 0x94, 0x4e, 0x9c, 0x43, 0x1c, 0xf1, 0xa1, 0x1e, 0x5c, 0xf9, 0xeb, 0x53, 0xa0, - 0x9b, 0x17, 0xe9, 0x8e, 0x84, 0x67, 0xe4, 0xec, 0x24, 0x67, 0xe4, 0x64, 0x56, 0xca, 0xa5, 0xb2, - 0x52, 0xda, 0x99, 0x7a, 0x6a, 0xe2, 0x33, 0xf5, 0xf4, 0x98, 0x67, 0xea, 0xfc, 0x99, 0xcf, 0xd4, - 0x85, 0xf1, 0xcf, 0xd4, 0x90, 0xee, 0x0b, 0x10, 0xd5, 0x80, 0x07, 0x3d, 0xeb, 0x14, 0x77, 0x9b, - 0x5e, 0x9f, 0x72, 0x4b, 0xce, 0x90, 0x41, 0xe7, 0x3f, 0x75, 0xa7, 0xf9, 0x14, 0x73, 0x67, 0xf6, - 0x29, 0xe6, 0x47, 0xfa, 0x14, 0x8f, 0x72, 0xf9, 0x19, 0x3d, 0x5f, 0xfe, 0xfe, 0x14, 0xe4, 0x8d, - 0xf6, 0x13, 0xe6, 0xe2, 0xe9, 0x90, 0x35, 0x3d, 0x47, 0x9c, 0x7d, 0x4c, 0xcf, 0x21, 0x5a, 0xb7, - 0xd1, 0xef, 0xe2, 0x97, 0x42, 0xeb, 0xd2, 0x02, 0xd1, 0x71, 0x4d, 0x6c, 0x79, 0x78, 0xdb, 0xe9, - 0xb1, 0xe3, 0x20, 0x3b, 0x14, 0xa8, 0x40, 0xb2, 0x1d, 0xa6, 0x7b, 0xd2, 0x27, 0x1a, 0x9d, 0xae, - 0x1c, 0x3f, 0x19, 0xc8, 0x30, 0xf4, 0x08, 0x66, 0x19, 0x91, 0xed, 0xf9, 0x8e, 0x7b, 0xca, 0x75, - 0xa1, 0x72, 0x62, 0x15, 0xa3, 0xdb, 0x94, 0x11, 0xd9, 0xa9, 0x50, 0xa1, 0x65, 0x1b, 0xf5, 0xb5, - 0x13, 0xdb, 0x65, 0xdd, 0x4d, 0x8b, 0x8d, 0x0a, 0x40, 0xe8, 0x4d, 0x58, 0xf8, 0xb0, 0xd2, 0x34, - 0x70, 0xc7, 0x21, 0xab, 0x51, 0xb3, 0x0f, 0xb1, 0xe7, 0xf3, 0xd8, 0x4e, 0xbc, 0x02, 0x7d, 0x0e, - 0x96, 0x25, 0x20, 0xed, 0xb1, 0xea, 0x9c, 0xf4, 0x7d, 0xca, 0x91, 0x39, 0x23, 0xb9, 0x92, 0x6c, - 0x8c, 0x54, 0x51, 0x75, 0x8e, 0x07, 0x3d, 0x4c, 0xfc, 0x84, 0xbe, 0xef, 0xda, 0x98, 0xf1, 0x64, - 0xce, 0x18, 0x86, 0x42, 0xc4, 0x45, 0xaa, 0xde, 0xb2, 0x3c, 0x4c, 0xa6, 0x03, 0x94, 0x30, 0xa1, - 0x26, 0x82, 0xdf, 0xb4, 0x3c, 0x3f, 0xe4, 0xd3, 0x84, 0x1a, 0xf4, 0x08, 0xd6, 0x25, 0xe8, 0x8e, - 0x6b, 0x1f, 0xda, 0x7d, 0xab, 0xa7, 0x6e, 0xe8, 0x2c, 0xa5, 0x1e, 0x89, 0x47, 0x18, 0x37, 0x61, - 0x2a, 0x94, 0x71, 0xf3, 0x46, 0x52, 0xd5, 0xea, 0xbb, 0xb0, 0x10, 0xdb, 0xc8, 0x51, 0x87, 0xee, - 0x9c, 0x7c, 0xe8, 0xfe, 0x08, 0x0a, 0xd4, 0x3c, 0x76, 0x1c, 0xb7, 0x4b, 0x08, 0xc9, 0x64, 0x39, - 0x21, 0x99, 0xdd, 0x06, 0xe4, 0xcc, 0xd3, 0x01, 0xa3, 0x9b, 0x57, 0xd5, 0x06, 0xa3, 0x21, 0xb5, - 0x06, 0xc5, 0x21, 0xfa, 0x96, 0xaa, 0x18, 0xc2, 0xbe, 0xb3, 0x06, 0xfd, 0x5d, 0xfe, 0x69, 0x06, - 0x80, 0xb6, 0x4f, 0x9d, 0x08, 0x82, 0xd2, 0xb2, 0x8e, 0xb1, 0x50, 0xc9, 0xe4, 0xb7, 0xac, 0xf3, - 0x33, 0xaa, 0xce, 0xe7, 0xc3, 0xc9, 0x86, 0xc3, 0x29, 0xc1, 0xcc, 0x13, 0xeb, 0x65, 0xdb, 0xfe, - 0x3d, 0x71, 0x32, 0x16, 0x45, 0x62, 0x1f, 0x84, 0x5a, 0xae, 0xf1, 0xb8, 0x49, 0x08, 0xa0, 0x01, - 0x95, 0x56, 0xa3, 0xc6, 0xb9, 0x98, 0xfe, 0x46, 0x9f, 0x83, 0x8c, 0xd9, 0xe6, 0xe6, 0x7b, 0x75, - 0x93, 0x5d, 0x2f, 0x6d, 0x8a, 0xeb, 0xa5, 0x4d, 0x53, 0x5c, 0x2f, 0xb1, 0x98, 0xc2, 0x9f, 0xff, - 0xe4, 0xa6, 0x66, 0x64, 0xcc, 0x36, 0x31, 0xa8, 0x8d, 0x7e, 0xa7, 0x77, 0xd2, 0xc5, 0xf5, 0x97, - 0x03, 0x22, 0x09, 0xdc, 0x08, 0x71, 0xfd, 0x86, 0x3d, 0x1e, 0x8b, 0x1a, 0x81, 0x45, 0xce, 0x0e, - 0xf5, 0x97, 0x14, 0x63, 0xdb, 0x72, 0xbb, 0x35, 0xe7, 0xe3, 0x7e, 0xac, 0x21, 0x66, 0xdb, 0x47, - 0xa1, 0x95, 0xcb, 0x00, 0xa6, 0xe7, 0x88, 0x15, 0x5e, 0x82, 0x29, 0x26, 0x56, 0x6c, 0x13, 0x59, - 0xa1, 0xfc, 0x73, 0x8d, 0x78, 0x84, 0xd4, 0x3e, 0xd2, 0x08, 0x75, 0xa2, 0x6d, 0xbc, 0x07, 0x85, - 0x9d, 0x81, 0x1c, 0x16, 0x88, 0x44, 0x13, 0xab, 0x2d, 0x4a, 0xbb, 0x33, 0x30, 0x42, 0x3c, 0xb4, - 0x15, 0xdc, 0x33, 0x31, 0x43, 0x79, 0x2b, 0xe1, 0x9e, 0x89, 0x22, 0xa4, 0x5f, 0x36, 0x5d, 0x74, - 0xbc, 0xbd, 0xdc, 0x84, 0x62, 0xb5, 0x15, 0x1e, 0xb5, 0x93, 0xe6, 0xfa, 0x86, 0x88, 0x9a, 0x66, - 0xd2, 0xef, 0xb6, 0x18, 0x46, 0xf9, 0x67, 0x7c, 0xed, 0x2c, 0x7f, 0xc8, 0xda, 0x8d, 0xdf, 0xde, - 0xe8, 0x15, 0x13, 0x1d, 0xfd, 0x0a, 0x57, 0xec, 0x5b, 0x79, 0x98, 0x11, 0x1c, 0xa4, 0x1c, 0x02, - 0x34, 0xe1, 0x69, 0x71, 0x00, 0xda, 0x84, 0xe9, 0x27, 0xd8, 0x7f, 0xee, 0x74, 0x93, 0x54, 0x02, - 0xab, 0xa1, 0x2a, 0x81, 0x63, 0xa1, 0xfb, 0xb2, 0xfc, 0x53, 0x51, 0x8e, 0x78, 0x1f, 0x61, 0x2d, - 0x9f, 0xa3, 0xac, 0x2f, 0x2a, 0x34, 0xfe, 0x17, 0xb8, 0x74, 0x54, 0xe8, 0x8b, 0x77, 0x6f, 0x44, - 0xe3, 0x7f, 0x8a, 0xdf, 0x67, 0x28, 0x24, 0xe8, 0x01, 0x61, 0x86, 0xb0, 0x85, 0x29, 0xda, 0xc2, - 0xf5, 0x04, 0x2e, 0x0d, 0x1b, 0x90, 0x09, 0x08, 0xbd, 0x29, 0xd1, 0x4f, 0xc7, 0xe9, 0xcd, 0x18, - 0xbd, 0x44, 0x40, 0xdc, 0xaf, 0x50, 0x3c, 0x93, 0x4e, 0x0b, 0x61, 0xad, 0x21, 0x0b, 0xf2, 0x7d, - 0xf5, 0x0c, 0xc7, 0x1d, 0xb7, 0x92, 0x3a, 0xf0, 0xb0, 0xde, 0x50, 0x4f, 0x7c, 0xf7, 0x55, 0x79, - 0xe7, 0x57, 0x29, 0xa5, 0x34, 0xe1, 0x34, 0x54, 0xed, 0xf0, 0x79, 0x45, 0x80, 0xa8, 0xb1, 0x8c, - 0xb8, 0xc0, 0x52, 0xb5, 0xa1, 0x08, 0xdb, 0x7d, 0x55, 0x58, 0xa8, 0xe1, 0x4c, 0xe8, 0x58, 0xd4, - 0x1b, 0xaa, 0x68, 0xbd, 0x0b, 0x73, 0x35, 0x4c, 0x0c, 0x1b, 0x1f, 0x0e, 0x0f, 0x67, 0x5d, 0x55, - 0xce, 0xc9, 0x32, 0x82, 0xa1, 0xe2, 0xa3, 0x2d, 0x98, 0xdf, 0x75, 0x9d, 0x97, 0xa7, 0xe1, 0x86, - 0xcd, 0x71, 0x05, 0x2f, 0xb5, 0xa0, 0x62, 0x18, 0x11, 0x0a, 0x62, 0x85, 0xa3, 0xd1, 0xec, 0xd6, - 0xc9, 0x31, 0x75, 0x02, 0x73, 0x46, 0x52, 0x15, 0xda, 0x92, 0x62, 0xf3, 0xc1, 0x11, 0xef, 0x72, - 0xfa, 0x11, 0xcf, 0x88, 0xa3, 0xd3, 0x35, 0x7f, 0x8e, 0x3b, 0x47, 0xdb, 0xd8, 0xea, 0xf9, 0xcf, - 0x69, 0x00, 0x2c, 0xba, 0xe6, 0x61, 0xb5, 0x21, 0xe3, 0x22, 0x13, 0x96, 0xda, 0x9d, 0xe7, 0xb8, - 0x7b, 0xd2, 0xc3, 0xdc, 0x45, 0xa5, 0x4e, 0x3a, 0x0d, 0x85, 0x15, 0xef, 0xae, 0xcb, 0x6d, 0x24, - 0xe1, 0x19, 0x89, 0xd4, 0x65, 0x07, 0x8a, 0x54, 0x12, 0xbd, 0x81, 0xd3, 0xf7, 0xf0, 0x90, 0xa3, - 0x19, 0x37, 0xd3, 0x19, 0xc5, 0x4c, 0x0b, 0xc7, 0x89, 0x19, 0x6f, 0x51, 0x1c, 0x76, 0xeb, 0x51, - 0xde, 0x04, 0x24, 0xf1, 0xb3, 0xd4, 0xef, 0xfb, 0xb6, 0x2b, 0x29, 0x23, 0x51, 0x2c, 0xff, 0x77, - 0x8e, 0x46, 0x30, 0x19, 0xda, 0xc5, 0x6a, 0xad, 0xeb, 0x50, 0xa8, 0xbb, 0xae, 0xe3, 0x56, 0x9d, - 0x2e, 0xa6, 0x53, 0x98, 0x33, 0x42, 0x00, 0x71, 0xc5, 0x69, 0xe1, 0x09, 0xf6, 0x3c, 0xeb, 0x10, - 0xf3, 0x98, 0x84, 0x02, 0x43, 0x6b, 0x00, 0x0d, 0x6f, 0xbb, 0xf2, 0x18, 0xe3, 0x01, 0x76, 0xa9, - 0xd6, 0xc9, 0x1b, 0x12, 0x04, 0xbd, 0xab, 0xac, 0x2e, 0x57, 0x2b, 0x57, 0x62, 0x8a, 0x91, 0x55, - 0x73, 0xcd, 0xa8, 0xec, 0x07, 0x11, 0x34, 0xe9, 0x10, 0xc3, 0x35, 0x8b, 0x2a, 0x68, 0x52, 0xbd, - 0xa1, 0x60, 0x13, 0x6e, 0xa3, 0xba, 0x86, 0x77, 0x9f, 0x8f, 0x77, 0x2f, 0x55, 0x1b, 0x32, 0x2e, - 0x11, 0xb1, 0x6a, 0xef, 0xc4, 0xf3, 0xb1, 0x5b, 0xc3, 0xe4, 0x74, 0xea, 0x71, 0xe5, 0xa2, 0x88, - 0x98, 0x8a, 0x61, 0x44, 0x28, 0xd0, 0x03, 0x28, 0x84, 0x97, 0x3a, 0x90, 0xc0, 0xa6, 0xa2, 0x92, - 0x31, 0x28, 0xf6, 0x4e, 0x7a, 0xbe, 0x11, 0x92, 0xa0, 0x07, 0x00, 0x92, 0x6a, 0x64, 0x3a, 0x66, - 0x4d, 0x6e, 0x20, 0xce, 0x48, 0x06, 0x44, 0xd4, 0x23, 0x11, 0x20, 0xec, 0x32, 0x0d, 0x37, 0x9b, - 0xb0, 0x78, 0x52, 0xbd, 0xa1, 0x60, 0x97, 0x1f, 0xd1, 0x38, 0x18, 0xf3, 0x7f, 0x83, 0x65, 0x79, - 0x8b, 0x58, 0x50, 0x02, 0xf1, 0x4a, 0x1a, 0xb5, 0xeb, 0xcb, 0xb1, 0xcd, 0x24, 0xb5, 0x7c, 0x2b, - 0x05, 0x6e, 0xf9, 0x55, 0x65, 0x23, 0x88, 0xfb, 0xf6, 0x94, 0xda, 0x6d, 0xee, 0xbe, 0xd1, 0x42, - 0xf9, 0x21, 0xcc, 0x99, 0x96, 0x77, 0x64, 0x5a, 0x07, 0x3d, 0xbc, 0xe7, 0x61, 0x97, 0x88, 0x11, - 0xf9, 0xdb, 0x0f, 0x7d, 0xe9, 0xa0, 0x4c, 0xea, 0x76, 0x2d, 0xcf, 0xfb, 0xd8, 0x71, 0xbb, 0x3c, - 0xb8, 0x11, 0x94, 0xcb, 0xdf, 0xd0, 0xc8, 0x28, 0xa9, 0xde, 0x4a, 0x74, 0x63, 0xd2, 0x7d, 0x71, - 0x25, 0xfe, 0x92, 0x8d, 0xde, 0xa0, 0x05, 0x57, 0x9c, 0x39, 0xf9, 0x8a, 0x73, 0x8d, 0xda, 0x7e, - 0xd5, 0x29, 0x97, 0x20, 0xe5, 0xbf, 0xca, 0x10, 0x1e, 0xee, 0x3f, 0xb3, 0x0f, 0xab, 0xcf, 0xad, - 0xfe, 0x21, 0x46, 0xf7, 0x82, 0xd1, 0xf1, 0x9b, 0xbe, 0x45, 0xf5, 0xc0, 0x41, 0xab, 0xc2, 0x15, - 0x64, 0xf3, 0xb8, 0x0f, 0xc0, 0xc8, 0xa5, 0x83, 0xca, 0xf5, 0x78, 0x7c, 0x23, 0xc4, 0x31, 0x24, - 0x7c, 0x64, 0xc2, 0x7c, 0xa3, 0x6f, 0xfb, 0xb6, 0xd5, 0x7b, 0x82, 0x8f, 0x0f, 0xb0, 0x2b, 0xbc, - 0xb2, 0x37, 0xd3, 0x5a, 0xd8, 0x54, 0xd1, 0xd9, 0xd1, 0x39, 0xd2, 0xc6, 0x6a, 0x05, 0x16, 0x13, - 0xd0, 0x26, 0xba, 0x0d, 0x7d, 0x03, 0xe6, 0xda, 0xcf, 0x4f, 0xfc, 0xae, 0xf3, 0x71, 0x9f, 0x99, - 0x36, 0xb2, 0x37, 0xe4, 0x47, 0xb0, 0x65, 0xa2, 0x58, 0xfe, 0xc7, 0x29, 0xb8, 0x1c, 0x51, 0xe1, - 0x89, 0xbb, 0x7b, 0x0b, 0xe6, 0xb6, 0x1c, 0xc7, 0xf7, 0x7c, 0xd7, 0x1a, 0x0c, 0xec, 0xfe, 0x21, - 0xed, 0x34, 0x6f, 0xa8, 0x40, 0xa2, 0x1a, 0x78, 0xcc, 0x86, 0x2e, 0x68, 0x96, 0x2e, 0xa8, 0xa2, - 0x1a, 0xa4, 0x6a, 0x43, 0xc6, 0x65, 0x3a, 0x29, 0x5c, 0x2a, 0xee, 0xae, 0x95, 0xd2, 0x96, 0xd2, - 0x50, 0x77, 0xff, 0xdd, 0xc8, 0x8c, 0xb9, 0xaf, 0x76, 0x55, 0x55, 0x0c, 0x12, 0x82, 0x11, 0x59, - 0xa1, 0xc7, 0xb0, 0xc0, 0x02, 0x6b, 0x52, 0xa4, 0x8d, 0x6b, 0x56, 0xc5, 0x65, 0x8c, 0x21, 0x19, - 0x71, 0xba, 0xb8, 0x2b, 0x32, 0x33, 0xa1, 0x2b, 0xf2, 0x18, 0x16, 0x1e, 0x39, 0x76, 0x9f, 0x45, - 0xaa, 0xb9, 0xfe, 0xe3, 0x8a, 0x56, 0x19, 0x4d, 0x0c, 0xc9, 0x88, 0xd3, 0xa1, 0x6d, 0xd0, 0x59, - 0xeb, 0xd4, 0x57, 0x61, 0x03, 0x2a, 0xc4, 0x5d, 0xd1, 0x28, 0x8e, 0x11, 0xa3, 0x22, 0xdb, 0x5b, - 0xe9, 0x76, 0x85, 0x14, 0x26, 0xf9, 0x76, 0x52, 0xb5, 0x21, 0xe3, 0x12, 0xcd, 0x1f, 0xb0, 0x0a, - 0xa3, 0x2e, 0xc6, 0x35, 0xbf, 0x8a, 0x61, 0x44, 0x28, 0xca, 0x38, 0xd9, 0x57, 0x49, 0xe4, 0xd7, - 0x08, 0x27, 0x66, 0xc6, 0xe7, 0xc4, 0xf2, 0x5f, 0x64, 0x60, 0x25, 0x12, 0xae, 0xe3, 0x57, 0x24, - 0xf4, 0x8a, 0x9e, 0x6d, 0x11, 0xe9, 0x84, 0x69, 0xeb, 0x82, 0xa1, 0xc0, 0x68, 0xb0, 0x4d, 0xc6, - 0xc9, 0x30, 0x1c, 0x19, 0x46, 0xf4, 0x6c, 0xfd, 0x25, 0x51, 0x41, 0xb6, 0xcf, 0x53, 0x06, 0x82, - 0x32, 0x71, 0x21, 0x79, 0x7b, 0xa6, 0x7d, 0x8c, 0x9d, 0x13, 0xdf, 0xb4, 0x3b, 0x47, 0x1e, 0xd7, - 0x8e, 0x49, 0x55, 0x84, 0xc2, 0x4c, 0xa0, 0x60, 0x4a, 0x33, 0xa9, 0x0a, 0x7d, 0x0e, 0x96, 0xeb, - 0x44, 0x5d, 0x58, 0x3e, 0xae, 0x9e, 0xb8, 0x2e, 0xee, 0xfb, 0x14, 0xc7, 0xe3, 0x37, 0x17, 0xc9, - 0x95, 0xe5, 0x3b, 0x09, 0x5c, 0xc9, 0xa6, 0x62, 0x7b, 0x34, 0xfb, 0x81, 0x2d, 0x47, 0x50, 0x2e, - 0xf7, 0x12, 0x84, 0x0a, 0xdd, 0x83, 0x1c, 0xb1, 0x37, 0x5c, 0x4b, 0x2b, 0x32, 0xa1, 0x18, 0x2a, - 0xae, 0xab, 0x29, 0x32, 0x5d, 0x54, 0xcb, 0x3b, 0xaa, 0x59, 0xbe, 0x75, 0x60, 0x79, 0x42, 0xe5, - 0x29, 0x30, 0xa2, 0xf5, 0x54, 0x29, 0x4a, 0xd7, 0x7a, 0x6f, 0xc6, 0x45, 0x62, 0x08, 0xf6, 0xeb, - 0x0a, 0xdb, 0xa7, 0x7b, 0xb3, 0xe5, 0x5f, 0x68, 0x51, 0x2e, 0x3f, 0xeb, 0xad, 0x04, 0x7a, 0x9a, - 0x62, 0x5b, 0x36, 0xd3, 0xe5, 0x65, 0x1c, 0xeb, 0x42, 0x64, 0x85, 0xec, 0x21, 0xbf, 0x57, 0xa0, - 0xbf, 0x2f, 0xc2, 0xe2, 0xfc, 0x24, 0xa3, 0xba, 0x94, 0x41, 0x1a, 0x92, 0x26, 0xa5, 0x21, 0x7d, - 0x91, 0xdd, 0xe5, 0x5b, 0xfd, 0xae, 0x48, 0x88, 0xba, 0x36, 0xe4, 0x7c, 0x21, 0xee, 0xb2, 0x04, - 0x09, 0x59, 0x4a, 0x11, 0x8e, 0xe7, 0x27, 0x03, 0x11, 0x82, 0xaf, 0x02, 0x70, 0x2c, 0x22, 0x70, - 0x39, 0xda, 0xf4, 0x8d, 0x21, 0x4d, 0x37, 0x6a, 0x22, 0x5e, 0x10, 0x92, 0xa1, 0x0f, 0x61, 0x39, - 0xf1, 0x22, 0x8b, 0x9b, 0x92, 0x57, 0xe4, 0xf6, 0x92, 0x13, 0x58, 0x93, 0xe9, 0x47, 0x5f, 0x0c, - 0x4f, 0x8f, 0x71, 0x31, 0x5c, 0xfe, 0x6e, 0x26, 0x65, 0x7c, 0x84, 0x91, 0x76, 0x5d, 0x3c, 0xb0, - 0x5c, 0x26, 0x82, 0x64, 0x5f, 0x43, 0x00, 0x59, 0xb5, 0x7a, 0x9f, 0xc8, 0x54, 0x97, 0x9b, 0x6c, - 0x51, 0x4c, 0xc9, 0x2d, 0xbb, 0x0b, 0x4b, 0xc1, 0xa5, 0x3a, 0xcd, 0xca, 0x65, 0x41, 0x7b, 0xce, - 0x30, 0x89, 0x75, 0x68, 0x13, 0x50, 0x42, 0xe2, 0x00, 0xd3, 0x3f, 0x09, 0x35, 0x91, 0x2c, 0xa2, - 0xe9, 0x58, 0x16, 0xd1, 0x12, 0x4c, 0xb1, 0x4b, 0x77, 0x96, 0x4d, 0xc3, 0x0a, 0x44, 0xd3, 0x90, - 0x49, 0xfb, 0x61, 0xd2, 0x5e, 0x50, 0x2e, 0xff, 0xbb, 0xa6, 0xe6, 0x0e, 0x04, 0xab, 0x23, 0x34, - 0xb7, 0xac, 0x71, 0xb5, 0xf1, 0x34, 0x6e, 0x26, 0x5d, 0xe3, 0xbe, 0x0d, 0x2b, 0xa1, 0xe6, 0x50, - 0x88, 0xd8, 0x5a, 0xa6, 0xd4, 0xa6, 0xeb, 0xdd, 0xdc, 0x30, 0xbd, 0xfb, 0xb3, 0x22, 0x14, 0xf9, - 0x28, 0xe8, 0x09, 0x46, 0xa4, 0x72, 0x6a, 0x52, 0x2a, 0xe7, 0xff, 0xaf, 0x5c, 0xa9, 0x4a, 0x10, - 0xe7, 0xcc, 0x53, 0x61, 0x7e, 0x35, 0x21, 0xf8, 0x44, 0x93, 0x14, 0xc7, 0x7c, 0x85, 0x50, 0x38, - 0xd3, 0x2b, 0x04, 0x48, 0xce, 0xd0, 0x52, 0x93, 0x0a, 0x8a, 0xe3, 0xe4, 0x5e, 0xcd, 0x8e, 0xcc, - 0xbd, 0x9a, 0x3b, 0x53, 0xee, 0xd5, 0xfc, 0x99, 0xde, 0x33, 0x5c, 0x1e, 0xe7, 0x3d, 0x83, 0x3e, - 0x5e, 0x4e, 0xd6, 0x42, 0x24, 0x27, 0x6b, 0xc4, 0x6d, 0x28, 0xba, 0x88, 0x0c, 0xab, 0xc5, 0x8b, - 0xca, 0xb0, 0x5a, 0xba, 0x80, 0x0c, 0xab, 0xe5, 0xf3, 0x67, 0x58, 0xad, 0x5c, 0x48, 0x86, 0xd5, - 0x95, 0x0b, 0xc8, 0xb0, 0x2a, 0x8d, 0x91, 0x61, 0x35, 0xfc, 0x85, 0xc7, 0xd5, 0x91, 0x2f, 0x3c, - 0x86, 0x65, 0x68, 0xad, 0x9e, 0x27, 0x43, 0xeb, 0xda, 0xb9, 0x33, 0xb4, 0xae, 0xff, 0xfa, 0x5e, - 0x78, 0x7c, 0xa2, 0xb1, 0x27, 0x67, 0xfc, 0xfd, 0x15, 0x37, 0x0b, 0x5a, 0xf2, 0xfb, 0x2b, 0xcb, - 0xc7, 0x9b, 0x0c, 0x43, 0xd1, 0x7c, 0x0c, 0x34, 0x7a, 0x9a, 0x99, 0x71, 0xa6, 0x69, 0x40, 0x51, - 0xea, 0x22, 0x61, 0x9a, 0x9f, 0x51, 0xa7, 0x79, 0x25, 0x45, 0x45, 0xcb, 0x5e, 0xe2, 0xbf, 0xe6, - 0x68, 0xca, 0xce, 0x85, 0x18, 0xb2, 0xdf, 0x66, 0xd9, 0xfc, 0x06, 0x67, 0xd9, 0x8c, 0xb0, 0x12, - 0x73, 0xe3, 0xe6, 0xcc, 0xfc, 0xb5, 0xc6, 0xde, 0x45, 0x8d, 0x94, 0x1a, 0x73, 0x94, 0xd4, 0x9c, - 0x8f, 0xdf, 0xcd, 0x64, 0x7e, 0xff, 0x87, 0x2c, 0x80, 0x74, 0xc2, 0x4c, 0x8a, 0x53, 0x08, 0x11, - 0xc8, 0x48, 0x22, 0x70, 0x0b, 0xe6, 0x88, 0x92, 0xc0, 0x7d, 0xd5, 0x4d, 0x53, 0x81, 0x11, 0xae, - 0xc9, 0x8d, 0xcd, 0x35, 0xa3, 0xed, 0xeb, 0xd4, 0x45, 0xd9, 0xd7, 0xe9, 0x0b, 0xb0, 0xaf, 0x33, - 0xe7, 0x7b, 0x71, 0x98, 0x1f, 0x65, 0x8f, 0xca, 0x7f, 0xaf, 0x05, 0x9b, 0x44, 0xd8, 0xe8, 0xbd, - 0x08, 0x1b, 0x95, 0x63, 0xb7, 0x7f, 0xa3, 0x38, 0xe9, 0x83, 0x51, 0x9c, 0xf4, 0xa6, 0xca, 0x49, - 0x2b, 0x09, 0x3d, 0x38, 0x2e, 0x96, 0x19, 0xe9, 0x47, 0x99, 0xe8, 0xdd, 0x64, 0x5a, 0x90, 0x56, - 0x65, 0x9c, 0xcc, 0x68, 0xc6, 0xc9, 0x5e, 0x20, 0xe3, 0xe4, 0x2e, 0x8a, 0x71, 0xa6, 0x2e, 0x80, - 0x71, 0xa6, 0x47, 0x30, 0x4e, 0xf9, 0x3f, 0xb2, 0xd1, 0xdb, 0x28, 0xf4, 0x16, 0xe4, 0xb9, 0x28, - 0x8b, 0xed, 0x5f, 0x4c, 0x10, 0x73, 0xe1, 0x5a, 0x0b, 0x54, 0x42, 0x56, 0x15, 0x64, 0x99, 0x38, - 0x59, 0x55, 0x25, 0x13, 0xa8, 0xe8, 0x1d, 0x9a, 0x3f, 0xc5, 0xe9, 0x98, 0x15, 0x5b, 0x4a, 0x4a, - 0x4f, 0xe0, 0x84, 0x21, 0x32, 0x7a, 0x00, 0xc5, 0x90, 0x51, 0x44, 0xc4, 0x23, 0x85, 0x8f, 0xc4, - 0x05, 0xa0, 0x44, 0x80, 0x6a, 0x22, 0x54, 0xd6, 0xe5, 0x2d, 0xb0, 0x6c, 0xbf, 0x52, 0x3c, 0x1e, - 0xdc, 0x95, 0xdb, 0x50, 0x89, 0xd2, 0x23, 0x26, 0xd3, 0xbf, 0xec, 0x88, 0xc9, 0xcc, 0x38, 0x11, - 0x93, 0x3f, 0xd6, 0xa0, 0xc8, 0xf7, 0x97, 0x7a, 0x1b, 0x9f, 0xa7, 0x9b, 0xcb, 0x7c, 0x06, 0x8d, - 0xfb, 0x0c, 0x81, 0x6b, 0xc6, 0x6b, 0x94, 0x8b, 0xb6, 0x00, 0x1d, 0xdd, 0x67, 0x3b, 0xc5, 0x68, - 0x33, 0x7c, 0xad, 0x42, 0xb7, 0x4e, 0x44, 0xbc, 0x65, 0xe2, 0x90, 0xa0, 0xfc, 0xbd, 0x1c, 0x2c, - 0xf3, 0x00, 0x9b, 0x08, 0xd3, 0xf3, 0x44, 0x8d, 0xd7, 0x60, 0xbe, 0x75, 0x72, 0xbc, 0xf3, 0x2c, - 0x6c, 0x9c, 0xb9, 0x42, 0x11, 0x28, 0x11, 0x6c, 0x0a, 0x09, 0xc6, 0xcf, 0xcc, 0x85, 0x0a, 0x44, - 0x1b, 0xa0, 0x0b, 0xba, 0x20, 0xa5, 0x9d, 0xc5, 0x23, 0x62, 0x70, 0x72, 0x1a, 0x6c, 0xe1, 0x97, - 0x7e, 0x70, 0x95, 0xce, 0x4b, 0xc8, 0x84, 0x22, 0xfb, 0xb5, 0x75, 0xfa, 0x18, 0x8b, 0x2c, 0xd0, - 0xbb, 0xf2, 0x4e, 0x26, 0xce, 0x64, 0x53, 0x22, 0x62, 0x81, 0x47, 0xb9, 0x19, 0xf4, 0x2c, 0x29, - 0xc9, 0x81, 0x3d, 0x40, 0x7c, 0x67, 0x8c, 0xb6, 0xa3, 0xa4, 0xd1, 0x97, 0x88, 0x41, 0x22, 0x04, - 0xf5, 0xbc, 0x0e, 0xc5, 0xcd, 0x0c, 0x4f, 0x78, 0x14, 0x71, 0x86, 0x78, 0xcd, 0xea, 0x03, 0xd0, - 0xa3, 0x03, 0x4f, 0x7e, 0xf0, 0x90, 0x9c, 0x01, 0xa9, 0x3c, 0x5e, 0x54, 0x06, 0x37, 0xaa, 0x15, - 0x25, 0x78, 0xfa, 0x3f, 0x1a, 0x5c, 0x35, 0xb0, 0xc7, 0xa2, 0xcd, 0x1f, 0x5a, 0x3e, 0x76, 0x8f, - 0x2d, 0xf7, 0x48, 0xf0, 0x48, 0xb8, 0x53, 0x9a, 0xb2, 0x53, 0x5f, 0x52, 0x77, 0x8a, 0x71, 0xe5, - 0xdb, 0x91, 0x50, 0x40, 0x72, 0x9b, 0x23, 0x76, 0x2b, 0x79, 0x15, 0xb3, 0xbf, 0xac, 0x55, 0x2c, - 0xff, 0x4b, 0x8e, 0x3d, 0xd5, 0x1c, 0x7a, 0x2e, 0xf8, 0xed, 0xbb, 0x90, 0xdf, 0xbe, 0x0b, 0x19, - 0xef, 0x5d, 0xc8, 0x3f, 0x65, 0xf8, 0x93, 0x79, 0xe2, 0xce, 0x3d, 0x08, 0x8e, 0x89, 0x4c, 0xe5, - 0xaf, 0xc7, 0x0c, 0x2c, 0x75, 0xe6, 0x28, 0x8a, 0xea, 0xcc, 0x31, 0x9d, 0xfa, 0x20, 0x70, 0x07, - 0x33, 0xc3, 0xe8, 0x53, 0x9d, 0xc1, 0x36, 0x14, 0xa5, 0xc6, 0x13, 0xee, 0x54, 0x36, 0x55, 0x67, - 0x30, 0xf5, 0x7d, 0xb2, 0xac, 0x76, 0xda, 0xa3, 0x3c, 0xcc, 0x51, 0x8d, 0x26, 0x1d, 0x56, 0xfe, - 0x2b, 0xaf, 0x26, 0xb6, 0x24, 0x4a, 0xe1, 0xbb, 0x8a, 0x49, 0x4d, 0x3c, 0xfa, 0x87, 0xd5, 0xc2, - 0xf3, 0x90, 0x8d, 0xf0, 0xbd, 0xe0, 0xc0, 0xc6, 0x3d, 0xcf, 0xc5, 0x84, 0x63, 0x9a, 0x48, 0xd3, - 0x10, 0x47, 0xbb, 0xb7, 0xc3, 0x0d, 0xe5, 0x07, 0x9d, 0xa5, 0xa4, 0x6d, 0x08, 0xb9, 0x9c, 0x6f, - 0xfe, 0xbd, 0x20, 0xa6, 0xc2, 0x2f, 0x71, 0x16, 0x13, 0x22, 0x29, 0xa2, 0x33, 0x11, 0x7d, 0xb9, - 0x23, 0xd2, 0x71, 0x59, 0x48, 0x5b, 0xb9, 0xa0, 0x14, 0x29, 0x58, 0x4a, 0x52, 0x6e, 0x8b, 0xcb, - 0x3a, 0xbf, 0x63, 0xe2, 0x69, 0x41, 0x33, 0x94, 0x7a, 0x2d, 0x7a, 0xbd, 0xa9, 0x62, 0x19, 0x09, - 0x94, 0xa8, 0x1e, 0xc9, 0xd8, 0xe1, 0x82, 0x3d, 0xf2, 0xa6, 0x34, 0x92, 0xe7, 0x23, 0xec, 0x46, - 0x97, 0xbf, 0x74, 0xe0, 0x25, 0xf4, 0x58, 0xb5, 0x1b, 0x10, 0x7f, 0x4d, 0x28, 0x73, 0xc1, 0x08, - 0x53, 0x71, 0x5f, 0x3e, 0x3b, 0xf1, 0x2b, 0xfd, 0x95, 0xe4, 0x13, 0x93, 0xb8, 0x72, 0x93, 0xce, - 0x5a, 0x72, 0x28, 0x7b, 0x76, 0xb2, 0x67, 0xc4, 0x49, 0x59, 0x96, 0x73, 0xe9, 0x59, 0x96, 0xdb, - 0x49, 0x0e, 0xc8, 0xfc, 0x48, 0x85, 0x99, 0xe0, 0x62, 0xdc, 0x87, 0xab, 0x71, 0x13, 0xb8, 0x8b, - 0xfb, 0x5d, 0xbb, 0x7f, 0x48, 0x23, 0xeb, 0x79, 0x23, 0x1d, 0x01, 0x6d, 0xc1, 0x75, 0xc5, 0x1c, - 0x53, 0x03, 0x2d, 0x1d, 0x7c, 0xd8, 0xdb, 0xe5, 0xa1, 0x38, 0xe4, 0xc0, 0x9b, 0xd0, 0x01, 0xbd, - 0xf0, 0x0b, 0xde, 0x30, 0x0f, 0xc1, 0x40, 0xef, 0xc1, 0xb5, 0x78, 0x6d, 0xf0, 0xf6, 0x45, 0x84, - 0xe8, 0x87, 0xa0, 0x9c, 0xdb, 0xe0, 0x7f, 0x53, 0x83, 0x59, 0xf9, 0x28, 0x91, 0x78, 0x98, 0xbd, - 0x0e, 0x05, 0x76, 0x81, 0x26, 0xf2, 0x37, 0x0a, 0x46, 0x08, 0x40, 0x25, 0x98, 0x51, 0xad, 0xbc, - 0x28, 0x4a, 0xf7, 0x1c, 0x39, 0xe5, 0x9e, 0x63, 0x15, 0xf2, 0x35, 0xe7, 0xe3, 0x3e, 0xad, 0x99, - 0xa2, 0x35, 0x41, 0xb9, 0xfc, 0x97, 0x65, 0xd0, 0x85, 0x6c, 0x07, 0x6f, 0xb0, 0x82, 0x17, 0x57, - 0x9a, 0xfc, 0xe2, 0x2a, 0x29, 0x60, 0x13, 0xba, 0x68, 0x59, 0xc5, 0x45, 0xdb, 0x51, 0x45, 0x8d, - 0x1d, 0xd3, 0x3e, 0x93, 0xa4, 0x50, 0x82, 0xa7, 0x55, 0xc3, 0xc5, 0x2d, 0xe9, 0xe3, 0x1e, 0xbf, - 0x76, 0x7d, 0xd5, 0x05, 0x3d, 0x72, 0xbf, 0x2e, 0xae, 0xed, 0xee, 0x0e, 0x9d, 0x6a, 0x94, 0x48, - 0x36, 0x9f, 0xb1, 0x16, 0x51, 0x43, 0x3e, 0x82, 0xb1, 0xef, 0x92, 0x7d, 0x7a, 0x68, 0xf3, 0x01, - 0x36, 0x5b, 0xc7, 0x90, 0x5a, 0x36, 0x0b, 0x30, 0xb6, 0x59, 0x90, 0x0c, 0x57, 0xf1, 0x4c, 0x86, - 0x6b, 0x76, 0x02, 0xc3, 0x15, 0x31, 0xb3, 0x73, 0x13, 0x9b, 0xd9, 0x98, 0x0d, 0x99, 0x3f, 0x93, - 0x0d, 0x51, 0xd5, 0xfb, 0xe5, 0x09, 0xd5, 0x7b, 0x2c, 0xca, 0xa0, 0x9f, 0x25, 0xca, 0x90, 0xa2, - 0xec, 0x17, 0x26, 0x54, 0xf6, 0xe8, 0xc2, 0x95, 0xfd, 0xe2, 0x79, 0x95, 0xfd, 0xd2, 0xb9, 0x95, - 0xfd, 0xf2, 0x79, 0x95, 0xfd, 0xca, 0x48, 0x65, 0x8f, 0xde, 0x8e, 0x65, 0xc3, 0x89, 0x7c, 0x12, - 0x76, 0xe3, 0x98, 0x52, 0x9b, 0x70, 0xc4, 0x08, 0xb3, 0x54, 0x4a, 0x89, 0x47, 0x8c, 0x30, 0x69, - 0xe5, 0xab, 0xb0, 0x14, 0xa9, 0x13, 0xb7, 0x8b, 0xb1, 0x43, 0x6e, 0x4c, 0xee, 0x93, 0x08, 0x99, - 0x0a, 0x48, 0x6c, 0x13, 0x0d, 0x62, 0xf3, 0xab, 0xb6, 0xc4, 0x6d, 0x64, 0x2c, 0x40, 0x31, 0xaa, - 0x37, 0x4e, 0xca, 0xfa, 0x4b, 0x69, 0x37, 0xa1, 0x47, 0xb3, 0x25, 0xae, 0x30, 0x27, 0xee, 0xd1, - 0x1c, 0xd6, 0x23, 0xaf, 0x44, 0xdb, 0x70, 0x33, 0x52, 0xc3, 0x53, 0xa7, 0xbc, 0x8a, 0xe7, 0xd9, - 0x87, 0x7d, 0xdc, 0xa5, 0x77, 0x9f, 0x79, 0x63, 0x14, 0x1a, 0x6a, 0xc2, 0x2b, 0xd1, 0x59, 0x05, - 0x29, 0x54, 0x41, 0x5b, 0x37, 0x68, 0x5b, 0xa3, 0x11, 0x53, 0x8f, 0x92, 0x21, 0xa7, 0xac, 0x0d, - 0x39, 0x4a, 0x86, 0xfc, 0xb2, 0x95, 0x92, 0xfd, 0x23, 0x38, 0xf5, 0x66, 0xfc, 0x6e, 0x3c, 0x8a, - 0x93, 0x7a, 0x8f, 0xc0, 0xa2, 0xc9, 0xeb, 0x54, 0x56, 0x87, 0x60, 0xa0, 0x47, 0xb0, 0x9e, 0x78, - 0x6f, 0x2e, 0x27, 0x51, 0xbd, 0x42, 0xc7, 0x31, 0x12, 0x6f, 0x8c, 0x9c, 0x81, 0xf2, 0x58, 0x39, - 0x03, 0x5f, 0xd7, 0xe0, 0x46, 0xe2, 0x90, 0x69, 0xf8, 0x82, 0x70, 0xdc, 0xab, 0x94, 0xe3, 0xde, - 0x1d, 0xca, 0x71, 0x43, 0x5b, 0x60, 0x8c, 0x37, 0xbc, 0x17, 0xf4, 0x87, 0x69, 0xe9, 0x59, 0x42, - 0xd4, 0x6e, 0xd1, 0x61, 0x3c, 0x98, 0x7c, 0x18, 0x8a, 0xc0, 0x0d, 0xed, 0x03, 0x7d, 0x43, 0x4b, - 0xb9, 0x78, 0xa0, 0x26, 0x8b, 0x8d, 0xe3, 0x53, 0x74, 0x1c, 0x95, 0xc9, 0xc7, 0x11, 0xb6, 0xc1, - 0x86, 0x32, 0xaa, 0x27, 0xf4, 0x27, 0x5a, 0x0a, 0xef, 0x57, 0x5b, 0xe2, 0x43, 0x2f, 0xaf, 0xd1, - 0xc1, 0xbc, 0x77, 0x96, 0x45, 0xe1, 0x4d, 0xb0, 0xb1, 0x8c, 0xe8, 0x07, 0x7d, 0x4b, 0x83, 0x57, - 0xd2, 0x87, 0x2b, 0x46, 0xf3, 0x3a, 0x1d, 0x4d, 0xf5, 0x8c, 0x4b, 0xa3, 0x0c, 0x68, 0x74, 0x6f, - 0xa9, 0x12, 0x2d, 0x8c, 0xef, 0xed, 0x21, 0x12, 0x2d, 0xec, 0xef, 0xb7, 0x35, 0x28, 0x0f, 0x9d, - 0x3a, 0x4b, 0xd9, 0x7b, 0x83, 0x4e, 0xac, 0x76, 0xf6, 0x65, 0xa6, 0xcd, 0xb0, 0x99, 0x8d, 0xd1, - 0x1f, 0xfa, 0x9e, 0x06, 0x9f, 0x1a, 0xb5, 0x00, 0x6c, 0x64, 0x1b, 0x74, 0x64, 0x0f, 0xcf, 0xb5, - 0xe4, 0xd2, 0xe0, 0xc6, 0xeb, 0xf5, 0xdc, 0x41, 0xf1, 0x8f, 0x60, 0x39, 0xd1, 0xb5, 0x9f, 0x30, - 0x4e, 0xa5, 0xbc, 0x40, 0x93, 0x9a, 0xbf, 0x4f, 0xbf, 0xf4, 0x97, 0x12, 0x54, 0x1b, 0x39, 0xb8, - 0x87, 0x70, 0x35, 0xd5, 0x41, 0x18, 0xd5, 0x50, 0x5e, 0x6e, 0xa8, 0x11, 0x4b, 0x61, 0x90, 0x55, - 0xd1, 0x39, 0x9b, 0x32, 0xcf, 0xda, 0xd4, 0x6e, 0x0a, 0xc7, 0x2b, 0xda, 0x7a, 0xa2, 0x16, 0x77, - 0x52, 0x74, 0xc3, 0x99, 0x67, 0x6b, 0xc0, 0xad, 0x71, 0x34, 0xe8, 0x44, 0x6d, 0x7e, 0x00, 0xaf, - 0x8e, 0xa1, 0x08, 0x27, 0x62, 0x14, 0x13, 0x5e, 0x1b, 0x4f, 0x9b, 0x4d, 0xd4, 0xea, 0x1e, 0xbc, - 0x3e, 0xa6, 0x2a, 0x99, 0xa8, 0xd9, 0x2f, 0xc1, 0xc6, 0xf8, 0x7a, 0x60, 0xa2, 0x50, 0x4d, 0x83, - 0x65, 0x03, 0x89, 0x8f, 0x6a, 0x9e, 0xe3, 0xbb, 0x48, 0xe5, 0xbf, 0xc9, 0xc0, 0x52, 0xd2, 0xe3, - 0xcc, 0x21, 0x6f, 0x24, 0x76, 0x63, 0x9f, 0x50, 0xdd, 0x1c, 0xf5, 0xd4, 0x53, 0xfd, 0x94, 0x6a, - 0xec, 0x62, 0xe6, 0x42, 0x3e, 0xa8, 0xba, 0x6a, 0x8e, 0xfe, 0xe2, 0xe9, 0xb0, 0x74, 0x21, 0x69, - 0x45, 0xe5, 0xb5, 0xfe, 0xbe, 0x06, 0xb0, 0x65, 0x75, 0x8e, 0x4e, 0x06, 0xf4, 0x6e, 0x27, 0xed, - 0xe2, 0xaf, 0x91, 0x74, 0xf1, 0xf7, 0xba, 0xf2, 0x2e, 0x24, 0x68, 0x64, 0x78, 0x3c, 0xe9, 0xdc, - 0x81, 0xbc, 0x3f, 0xd2, 0xc4, 0xbd, 0x55, 0xc3, 0xc7, 0xc7, 0x89, 0x9f, 0x68, 0x29, 0xc3, 0x2c, - 0xcf, 0x66, 0x7f, 0x2a, 0xdd, 0x7e, 0x2a, 0x30, 0x82, 0x53, 0xc3, 0xcf, 0xac, 0x93, 0x1e, 0xc7, - 0xe1, 0x5f, 0x0d, 0x95, 0x61, 0x64, 0x8b, 0x1a, 0x7d, 0x1f, 0xbb, 0x7d, 0xab, 0xc7, 0x2f, 0xec, - 0x82, 0x72, 0xf9, 0x6f, 0x35, 0xf9, 0xfa, 0x0c, 0x7d, 0x11, 0x66, 0xaa, 0x4e, 0xdf, 0xc7, 0xf4, - 0x4b, 0x26, 0xf1, 0xf4, 0xf1, 0x00, 0x71, 0x93, 0x63, 0xb1, 0x85, 0x11, 0x34, 0xab, 0x06, 0x7d, - 0x89, 0x18, 0x54, 0x4c, 0x98, 0xc0, 0x13, 0x2e, 0x87, 0xbc, 0x50, 0xbf, 0x1f, 0xde, 0xd3, 0xa1, - 0xb7, 0xc2, 0x77, 0xba, 0xb1, 0x3c, 0x35, 0x81, 0xb4, 0x49, 0x31, 0xd8, 0xc0, 0x18, 0xf6, 0xea, - 0x3b, 0x00, 0x21, 0x70, 0xa2, 0xfb, 0xe5, 0xd7, 0x95, 0xcf, 0x03, 0x0c, 0x79, 0xbf, 0xf4, 0x11, - 0x2c, 0xc4, 0x5e, 0xca, 0xa0, 0x5b, 0x30, 0xc7, 0xbe, 0x38, 0x24, 0x1e, 0xdf, 0x30, 0x22, 0x15, - 0x48, 0xb7, 0x99, 0x93, 0x48, 0x5f, 0xa9, 0x52, 0x60, 0x1b, 0x1f, 0x03, 0xec, 0x0d, 0xba, 0x96, - 0xcf, 0x22, 0xb8, 0x57, 0x60, 0x51, 0xf9, 0x82, 0x11, 0xab, 0xd2, 0x2f, 0xa1, 0x65, 0x58, 0x10, - 0x5f, 0xa6, 0x6a, 0xb6, 0x5b, 0x1c, 0xac, 0xa1, 0x45, 0xb8, 0xbc, 0xe7, 0x61, 0x97, 0x4e, 0x9f, - 0x03, 0x33, 0x68, 0x0e, 0x0a, 0x66, 0x7b, 0x87, 0x17, 0xb3, 0x84, 0x34, 0xf8, 0xca, 0x54, 0x40, - 0x9a, 0xdb, 0xd8, 0x84, 0x42, 0xf0, 0x39, 0x6b, 0x74, 0x19, 0x8a, 0x2d, 0xc7, 0x3d, 0xb6, 0x7a, - 0xb4, 0xa8, 0x5f, 0x42, 0x3a, 0xcc, 0xf2, 0x47, 0x1a, 0x0c, 0xa2, 0x6d, 0xfc, 0x3c, 0x07, 0x10, - 0xbe, 0xec, 0x47, 0xf3, 0x00, 0x66, 0x7b, 0x67, 0x7f, 0x6f, 0xb7, 0x56, 0x31, 0xeb, 0xfa, 0x25, - 0x04, 0x30, 0x5d, 0xd9, 0xdd, 0xad, 0xb7, 0x6a, 0xba, 0x86, 0xf2, 0x90, 0x33, 0xea, 0x95, 0x9a, - 0x9e, 0x41, 0xb3, 0x90, 0x37, 0x8d, 0xbd, 0x56, 0x95, 0xe0, 0x64, 0x49, 0xa3, 0x0f, 0xeb, 0xe6, - 0x7e, 0x00, 0xc9, 0xa1, 0x22, 0xcc, 0x54, 0x77, 0x5a, 0xad, 0x7a, 0xd5, 0xd4, 0xa7, 0x48, 0x93, - 0xbc, 0xb0, 0x6f, 0xec, 0xe8, 0xd3, 0x68, 0x01, 0xe6, 0x9a, 0x3b, 0x0f, 0xf7, 0xb7, 0xeb, 0x15, - 0xc3, 0xdc, 0xaa, 0x57, 0x4c, 0x7d, 0x86, 0xb4, 0x50, 0x6d, 0x49, 0x90, 0x3c, 0x1d, 0xa8, 0x0c, - 0x29, 0x20, 0x04, 0xf3, 0xd5, 0xed, 0x7a, 0xf5, 0xf1, 0xfe, 0x76, 0xe5, 0x71, 0xbd, 0xbe, 0x5b, - 0x37, 0x74, 0x20, 0xeb, 0x4a, 0x7a, 0xae, 0x36, 0xf7, 0xda, 0x66, 0xdd, 0xd8, 0xaf, 0xd5, 0xcd, - 0x4a, 0xa3, 0xd9, 0xd6, 0x8b, 0x04, 0x99, 0x54, 0xb4, 0xb7, 0x2b, 0x46, 0x6d, 0xbf, 0xd1, 0x7a, - 0x7f, 0x47, 0x9f, 0xa5, 0x0d, 0xb4, 0xf6, 0x2b, 0xcd, 0xe6, 0x0e, 0x19, 0xe5, 0x7e, 0xa3, 0xa6, - 0xcf, 0x91, 0x45, 0x94, 0x1b, 0x68, 0x9b, 0x64, 0xfc, 0xf3, 0x74, 0xfd, 0xe9, 0x0a, 0xec, 0x57, - 0x5b, 0xfb, 0xcd, 0xca, 0x56, 0xbd, 0xa9, 0x5f, 0x46, 0x25, 0x58, 0x0a, 0x81, 0x1f, 0xee, 0x18, - 0x8f, 0x39, 0xba, 0x4e, 0x5a, 0xde, 0xad, 0x98, 0xd5, 0x6d, 0x52, 0xd1, 0x36, 0x77, 0x8c, 0xba, - 0xbe, 0x40, 0x9a, 0xa8, 0xd5, 0x9b, 0x75, 0x86, 0xcd, 0x80, 0x88, 0x00, 0x77, 0x8d, 0x9d, 0x2f, - 0x7d, 0x59, 0x9a, 0xd8, 0x22, 0x7a, 0x05, 0x6e, 0xf0, 0x76, 0x5b, 0x3b, 0xad, 0xfd, 0xa7, 0x3b, - 0x66, 0xa3, 0xf5, 0x70, 0xdf, 0xa8, 0xef, 0x36, 0x1b, 0xd5, 0xca, 0x7e, 0x6b, 0xef, 0x89, 0xbe, - 0x84, 0xd6, 0x60, 0x35, 0x8e, 0x42, 0xe6, 0xd1, 0x6c, 0x98, 0x5f, 0xd6, 0x97, 0xd1, 0x12, 0xe8, - 0xed, 0xba, 0xb9, 0x6f, 0xd4, 0x3f, 0xd8, 0x6b, 0x18, 0xf5, 0xda, 0x7e, 0xb3, 0xdd, 0xd2, 0x57, - 0x08, 0xf4, 0x61, 0x14, 0x7a, 0x45, 0x2c, 0x4d, 0xb3, 0x62, 0xd6, 0xdb, 0x26, 0x85, 0x95, 0xc8, - 0x96, 0x50, 0x58, 0xbd, 0x52, 0xab, 0x1b, 0x64, 0x65, 0xae, 0xd2, 0x2d, 0x61, 0xcb, 0x5d, 0xaf, - 0x34, 0xcd, 0x6d, 0x7d, 0x95, 0x6c, 0x3a, 0xd9, 0x7e, 0x4a, 0x72, 0x0d, 0x5d, 0x85, 0x65, 0x3e, - 0xa4, 0x66, 0xbd, 0xd2, 0xae, 0x6f, 0xef, 0x34, 0x39, 0xe9, 0x75, 0x52, 0x45, 0x17, 0xbf, 0xba, - 0x5d, 0xaf, 0xed, 0x35, 0xeb, 0xfb, 0xd5, 0x9d, 0x27, 0x4f, 0x2a, 0xad, 0x5a, 0x5b, 0xbf, 0xb1, - 0xd1, 0x02, 0x08, 0xbf, 0x87, 0x45, 0x38, 0x83, 0xb0, 0x39, 0x83, 0xe8, 0x97, 0x48, 0x0f, 0x42, - 0xcf, 0xe9, 0x1a, 0x61, 0x5e, 0x2a, 0x34, 0x81, 0x00, 0x2c, 0xf0, 0x0f, 0xc0, 0x19, 0xf8, 0xab, - 0xb8, 0xe3, 0xe3, 0xae, 0x9e, 0xdd, 0xd8, 0x80, 0x42, 0xf0, 0xb9, 0x25, 0x42, 0xde, 0xc6, 0x3e, - 0x2d, 0xe9, 0x97, 0x08, 0x39, 0x0b, 0xae, 0x32, 0x80, 0xb6, 0xf1, 0xcf, 0x39, 0x40, 0xe2, 0x48, - 0x21, 0xc9, 0x26, 0xe1, 0x78, 0xbb, 0x73, 0x24, 0x8b, 0xa4, 0xf4, 0x5d, 0x9b, 0x40, 0x24, 0x89, - 0xa4, 0xc6, 0xc0, 0x19, 0xb4, 0x42, 0xf3, 0x47, 0xa2, 0xf0, 0x2c, 0xe9, 0xfd, 0x21, 0xf6, 0x03, - 0x49, 0xcf, 0x91, 0x45, 0x89, 0xe8, 0x1b, 0x5e, 0x35, 0x45, 0x76, 0xa4, 0x8d, 0x99, 0x40, 0x72, - 0xd8, 0x34, 0x61, 0x36, 0x35, 0x41, 0x88, 0xd7, 0xcc, 0xa0, 0x9b, 0x70, 0xad, 0x8d, 0xfd, 0xf8, - 0xdd, 0x04, 0x47, 0xc8, 0xa3, 0x55, 0x58, 0xe1, 0x08, 0x41, 0x70, 0x9b, 0xd7, 0x15, 0xc8, 0x12, - 0xb2, 0xdf, 0x7c, 0xd5, 0x74, 0x20, 0x13, 0x13, 0xa0, 0xe0, 0x79, 0x90, 0x5e, 0x24, 0xfb, 0xbf, - 0x4b, 0xf4, 0x1d, 0xcf, 0xe0, 0xd3, 0x67, 0x09, 0xad, 0x81, 0x8f, 0x9d, 0x17, 0xe2, 0xcd, 0xa9, - 0x3e, 0x47, 0x46, 0xa9, 0xa6, 0x6a, 0xf2, 0x8e, 0xe6, 0xd1, 0x0d, 0xb8, 0xca, 0x7e, 0x27, 0x04, - 0xad, 0xf5, 0xcb, 0xe8, 0x1a, 0x5c, 0x89, 0x54, 0x0b, 0x6b, 0xc0, 0xc4, 0x49, 0x9c, 0x7a, 0x78, - 0x7b, 0x0b, 0xe8, 0x3a, 0x94, 0xe2, 0x29, 0x3e, 0xbc, 0x16, 0xa1, 0x5b, 0xb0, 0x2e, 0x82, 0xb8, - 0xf1, 0xf0, 0x2e, 0xc7, 0x5a, 0x24, 0x2b, 0xc7, 0x02, 0x60, 0x91, 0x13, 0x08, 0x47, 0x58, 0x42, - 0x9f, 0x82, 0x57, 0x18, 0x42, 0xa2, 0x83, 0xc9, 0xd1, 0x96, 0x37, 0xbe, 0xa3, 0xc1, 0x9c, 0x72, - 0xdb, 0x44, 0xe4, 0x5a, 0x00, 0x78, 0x96, 0x8b, 0x7e, 0x89, 0xec, 0xb8, 0x00, 0x2a, 0x5f, 0x0e, - 0xd0, 0x35, 0xd2, 0x51, 0xac, 0x4a, 0x9c, 0x1f, 0x0d, 0xdc, 0xc1, 0xf6, 0x0b, 0xdc, 0xd5, 0x33, - 0x64, 0x95, 0x62, 0x68, 0xef, 0x5b, 0x76, 0x8f, 0xb0, 0xbe, 0xdc, 0xa7, 0x71, 0xd2, 0xef, 0x93, - 0x86, 0x73, 0x1b, 0x07, 0x49, 0xf7, 0x5d, 0x64, 0x9b, 0x14, 0x68, 0x38, 0xc6, 0x68, 0x8d, 0x68, - 0x49, 0x8b, 0xd5, 0xb4, 0x7d, 0x67, 0x30, 0x20, 0xa3, 0xda, 0xf8, 0x91, 0x06, 0x7a, 0xf4, 0x5b, - 0x11, 0x44, 0x8a, 0x2a, 0x5d, 0xf1, 0xf9, 0x36, 0xfd, 0x52, 0xc8, 0x2c, 0x02, 0xa4, 0x11, 0x8e, - 0x6a, 0xfb, 0x96, 0xeb, 0x0b, 0x48, 0x86, 0x08, 0x09, 0x69, 0x56, 0x00, 0xb2, 0xa4, 0x95, 0xc7, - 0x76, 0xaf, 0xf7, 0x15, 0xe7, 0xf8, 0xc0, 0x26, 0x42, 0x73, 0x05, 0x16, 0x2b, 0xdd, 0x6e, 0x94, - 0x85, 0xf4, 0x29, 0xc2, 0xe3, 0xac, 0xf9, 0x58, 0xdd, 0x34, 0x95, 0x34, 0xd2, 0x4f, 0xac, 0x6a, - 0x86, 0x4c, 0x8a, 0x74, 0x18, 0xab, 0xc9, 0x6f, 0x3c, 0x51, 0xde, 0xd0, 0x93, 0x81, 0x84, 0x8c, - 0xa4, 0x5f, 0xa2, 0xb6, 0xb7, 0x25, 0x8a, 0x1a, 0x29, 0x56, 0x83, 0x62, 0x86, 0xca, 0x0a, 0xbd, - 0x0a, 0xe2, 0x90, 0xec, 0x56, 0xe3, 0x87, 0x3f, 0x5b, 0xbb, 0xf4, 0x83, 0x4f, 0xd6, 0xb4, 0x1f, - 0x7e, 0xb2, 0xa6, 0xfd, 0xf4, 0x93, 0xb5, 0x4b, 0x7f, 0xf7, 0x9f, 0x6b, 0xda, 0x57, 0xee, 0x49, - 0xff, 0xcb, 0xe9, 0xd8, 0xf2, 0x5d, 0xfb, 0xa5, 0x43, 0x1d, 0x0b, 0x51, 0xe8, 0xe3, 0x3b, 0x83, - 0xa3, 0xc3, 0x3b, 0x83, 0x83, 0x3b, 0xa1, 0x9b, 0x74, 0x30, 0x4d, 0xbf, 0xb5, 0x77, 0xef, 0x7f, - 0x03, 0x00, 0x00, 0xff, 0xff, 0x37, 0x2c, 0xf3, 0x79, 0x27, 0x6a, 0x00, 0x00, + // 6194 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xdb, 0x6f, 0x1b, 0xd9, + 0x79, 0xb8, 0x87, 0xa4, 0x24, 0xea, 0xa3, 0x24, 0x8f, 0x8e, 0x2e, 0xa6, 0x65, 0x5b, 0xd6, 0x72, + 0x9d, 0x5d, 0xaf, 0xb2, 0x91, 0xf3, 0xb3, 0xb3, 0x8b, 0x4d, 0x7e, 0x8e, 0x77, 0x29, 0x92, 0xb6, + 0x68, 0xd3, 0x94, 0x76, 0x38, 0xf2, 0x26, 0x01, 0x16, 0xc2, 0x88, 0x3c, 0x96, 0x27, 0xa2, 0x38, + 0xcc, 0xcc, 0xc8, 0x97, 0xf6, 0xa9, 0x45, 0x53, 0x14, 0x0d, 0x5a, 0x34, 0x40, 0xd0, 0x06, 0x6d, + 0xd3, 0xdb, 0x5b, 0x9f, 0xf2, 0xd2, 0xff, 0xa0, 0x40, 0x91, 0x87, 0xa2, 0x48, 0xf3, 0x58, 0xa0, + 0xb9, 0x6c, 0x5f, 0x0a, 0xe4, 0xa5, 0x4f, 0xcd, 0x53, 0x80, 0xe2, 0xdc, 0x66, 0xce, 0x99, 0x0b, + 0x87, 0xba, 0x24, 0x4d, 0x8a, 0x3c, 0x89, 0xe7, 0x9c, 0xef, 0x3b, 0xd7, 0xef, 0x7e, 0xbe, 0x33, + 0x02, 0xbd, 0xef, 0x1c, 0x78, 0xd8, 0x7d, 0x6e, 0x77, 0xf1, 0xc6, 0xd0, 0x75, 0x7c, 0x07, 0x41, + 0x58, 0xb3, 0xf2, 0x99, 0x03, 0xdb, 0x7f, 0x76, 0xbc, 0xbf, 0xd1, 0x75, 0x8e, 0x6e, 0x1d, 0x38, + 0x07, 0xce, 0x2d, 0x0a, 0xb2, 0x7f, 0xfc, 0x94, 0x96, 0x68, 0x81, 0xfe, 0x62, 0xa8, 0x2b, 0xd7, + 0x0f, 0x1c, 0xe7, 0xa0, 0x8f, 0x43, 0x28, 0xdf, 0x3e, 0xc2, 0x9e, 0x6f, 0x1d, 0x0d, 0x39, 0xc0, + 0xdc, 0x11, 0xf6, 0xad, 0x9e, 0xe5, 0x5b, 0xbc, 0x7c, 0x31, 0x02, 0x50, 0xf9, 0x2f, 0x80, 0xa9, + 0x5a, 0xbb, 0xe3, 0x3b, 0x2e, 0x46, 0x08, 0x0a, 0xbb, 0xbb, 0xcd, 0x7a, 0x59, 0x5b, 0xd3, 0x6e, + 0x4e, 0x1b, 0xf4, 0x37, 0x7a, 0x03, 0xe6, 0x3a, 0x6c, 0x6e, 0xd5, 0x5e, 0xcf, 0xc5, 0x9e, 0x57, + 0xce, 0xd1, 0xd6, 0x48, 0x2d, 0x5a, 0x05, 0xe8, 0x7c, 0xd8, 0x12, 0x30, 0x79, 0x0a, 0x23, 0xd5, + 0xa0, 0x0d, 0x40, 0x2d, 0xa7, 0x7b, 0x18, 0xe9, 0xab, 0x40, 0xe1, 0x12, 0x5a, 0xd0, 0x0d, 0x28, + 0x18, 0x4e, 0x1f, 0x97, 0x27, 0xd7, 0xb4, 0x9b, 0x73, 0xb7, 0xf5, 0x8d, 0x60, 0x1d, 0xb5, 0x36, + 0xa9, 0x37, 0x68, 0x2b, 0x99, 0xb1, 0x69, 0x77, 0x0f, 0xcb, 0x53, 0x6b, 0xda, 0xcd, 0x82, 0x41, + 0x7f, 0xa3, 0x4f, 0xc3, 0x44, 0xc7, 0xb7, 0x7c, 0x5c, 0x2e, 0x52, 0xd4, 0xa5, 0x0d, 0x69, 0xc3, + 0xdb, 0x4e, 0x0f, 0xd3, 0x46, 0x83, 0xc1, 0xa0, 0x2f, 0xc2, 0x64, 0xcb, 0xda, 0xc7, 0x7d, 0xaf, + 0x3c, 0xbd, 0x96, 0xbf, 0x59, 0xba, 0x7d, 0x5d, 0x86, 0xe6, 0xfb, 0xb2, 0xc1, 0x20, 0x1a, 0x03, + 0xdf, 0x7d, 0xb5, 0x59, 0xf8, 0xde, 0x0f, 0xaf, 0x5f, 0x30, 0x38, 0x12, 0xfa, 0x7f, 0x30, 0xfd, + 0x91, 0xe3, 0x1e, 0xb2, 0xf1, 0x80, 0x8e, 0xb7, 0x10, 0x4e, 0x35, 0x68, 0x32, 0x42, 0x28, 0x54, + 0x81, 0x99, 0x0f, 0x8f, 0xb1, 0xfb, 0x4a, 0x6c, 0x41, 0x89, 0x6e, 0x81, 0x52, 0x87, 0xde, 0x05, + 0xa8, 0x39, 0x83, 0xa7, 0xf6, 0x41, 0xdd, 0xf2, 0xad, 0xf2, 0xcc, 0x9a, 0x76, 0xb3, 0x74, 0x7b, + 0x59, 0x99, 0x59, 0xd0, 0x6a, 0x48, 0x90, 0xe8, 0x5d, 0x28, 0x1a, 0xd8, 0x73, 0x8e, 0xdd, 0x2e, + 0x2e, 0xcf, 0x52, 0xac, 0x45, 0x19, 0x4b, 0xb4, 0xf1, 0x45, 0x04, 0xb0, 0x68, 0x19, 0x26, 0x77, + 0x87, 0xa6, 0x7d, 0x84, 0xcb, 0x73, 0x6b, 0xda, 0xcd, 0xbc, 0xc1, 0x4b, 0xe8, 0xb3, 0xb0, 0xd0, + 0x79, 0x66, 0xb9, 0xbd, 0xc8, 0xa9, 0x5d, 0xa4, 0x53, 0x4e, 0x6a, 0x42, 0x2b, 0x50, 0xac, 0x39, + 0x47, 0x47, 0xb6, 0xdf, 0xac, 0x97, 0x75, 0x0a, 0x16, 0x94, 0xd1, 0x7d, 0x58, 0x7d, 0x62, 0xe3, + 0x17, 0x8f, 0xf9, 0xf6, 0x54, 0x7b, 0x47, 0xb6, 0xe7, 0xd9, 0xce, 0xa0, 0x73, 0x3c, 0x1c, 0x3a, + 0xae, 0x8f, 0x7b, 0xe5, 0xf9, 0x35, 0xed, 0x66, 0xd1, 0xc8, 0x80, 0x42, 0x5b, 0x70, 0x3d, 0x11, + 0xe2, 0x01, 0x1e, 0x60, 0xd7, 0xf2, 0x6d, 0x67, 0x50, 0x46, 0x94, 0x1e, 0xb2, 0xc0, 0xd0, 0x5d, + 0xb8, 0x2c, 0x83, 0x6c, 0xef, 0x93, 0x9d, 0xc2, 0xbd, 0xc6, 0xd0, 0xe9, 0x3e, 0x2b, 0x2f, 0xd0, + 0x3e, 0xd2, 0x01, 0xd0, 0x3d, 0x58, 0x49, 0x1c, 0xc0, 0xc0, 0x56, 0xef, 0x55, 0x79, 0x91, 0xae, + 0x65, 0x04, 0x04, 0x19, 0xbd, 0x5e, 0x6f, 0x3d, 0xb1, 0x3d, 0x7b, 0xdf, 0xee, 0xdb, 0xfe, 0xab, + 0x4d, 0xcb, 0x75, 0x6d, 0xec, 0x32, 0xf4, 0x25, 0x8a, 0x9e, 0x0e, 0x80, 0xbe, 0x00, 0x65, 0xb9, + 0xef, 0xe6, 0xe0, 0x80, 0x1c, 0x00, 0x43, 0x5e, 0xa6, 0xc8, 0xa9, 0xed, 0xa8, 0x0e, 0xd7, 0x94, + 0x8e, 0xeb, 0x78, 0xd8, 0x77, 0x5e, 0xe1, 0xde, 0x0e, 0x11, 0x09, 0x5d, 0xa7, 0x5f, 0xbe, 0x44, + 0xc9, 0x60, 0x34, 0x10, 0x39, 0x07, 0x05, 0xa0, 0xda, 0xf5, 0xed, 0xe7, 0x74, 0x63, 0x77, 0x5c, + 0x3c, 0xb4, 0x5c, 0xdc, 0x2b, 0x97, 0xe9, 0x44, 0xb2, 0xc0, 0x62, 0xf3, 0x09, 0x41, 0xee, 0xe3, + 0x41, 0x17, 0xf7, 0xca, 0x97, 0x69, 0x3f, 0xa3, 0x81, 0xd0, 0x0e, 0x2c, 0x29, 0x00, 0xf7, 0x5d, + 0x67, 0xe0, 0xdb, 0xd8, 0x2d, 0xaf, 0x70, 0x56, 0x08, 0x65, 0x9f, 0x29, 0x7e, 0x71, 0x56, 0x48, + 0x46, 0x5c, 0x69, 0x43, 0x49, 0xe2, 0x7d, 0xa4, 0x43, 0xfe, 0x10, 0xbf, 0xe2, 0xe2, 0x91, 0xfc, + 0x44, 0x6f, 0xc1, 0xc4, 0x73, 0xab, 0x7f, 0x8c, 0xa9, 0x50, 0x2c, 0xc9, 0xbc, 0x4f, 0xf1, 0x5a, + 0xb6, 0xe7, 0x1b, 0x0c, 0xe2, 0x0b, 0xb9, 0xf7, 0xb4, 0x87, 0x85, 0xe2, 0x84, 0x3e, 0x59, 0xf9, + 0x59, 0x1e, 0xa6, 0xcc, 0x73, 0x10, 0xb9, 0x42, 0xf8, 0xe5, 0x93, 0x84, 0x5f, 0x61, 0x0c, 0xe1, + 0xf7, 0x0e, 0x4c, 0x52, 0x1e, 0xf6, 0xca, 0x13, 0x54, 0xf8, 0x5d, 0x92, 0xa1, 0xcd, 0x36, 0x6d, + 0x6b, 0x0e, 0x9e, 0x3a, 0x42, 0xe8, 0x31, 0x60, 0x74, 0x1b, 0x16, 0x5b, 0xce, 0x81, 0x6f, 0xd9, + 0x7d, 0x32, 0x21, 0xec, 0x8a, 0x59, 0x4e, 0xd2, 0x59, 0x26, 0xb6, 0xa5, 0x88, 0xff, 0xa9, 0x54, + 0xf1, 0xaf, 0x4a, 0xc0, 0xe9, 0xb1, 0x25, 0x60, 0x54, 0xba, 0x42, 0x82, 0x74, 0x4d, 0x91, 0x6a, + 0xa5, 0x74, 0xa9, 0xf6, 0x01, 0x5c, 0xa9, 0x1e, 0xfb, 0x4e, 0x73, 0xd0, 0x75, 0x29, 0xeb, 0x53, + 0x82, 0x0b, 0xc5, 0xd6, 0x0c, 0xa5, 0xce, 0x51, 0x20, 0x0f, 0x0b, 0xc5, 0xa2, 0x3e, 0x5d, 0xf9, + 0xa3, 0x3c, 0x14, 0x5b, 0xce, 0xc1, 0xaf, 0xc0, 0xd1, 0xdf, 0x25, 0x9a, 0x62, 0xd8, 0xb7, 0xbb, + 0x96, 0x38, 0xfc, 0x15, 0x19, 0xbe, 0xe5, 0x1c, 0xf0, 0x66, 0xe9, 0xfc, 0x03, 0x8c, 0xc8, 0xe9, + 0x4c, 0x9e, 0x44, 0x3f, 0xb5, 0x9c, 0xae, 0x45, 0x78, 0x8c, 0x9e, 0x7d, 0x44, 0x3f, 0x89, 0x36, + 0x31, 0x9e, 0x28, 0xa3, 0x27, 0xf0, 0xc6, 0x48, 0x51, 0x14, 0x1e, 0x45, 0x91, 0x1e, 0xc5, 0x98, + 0xd0, 0x95, 0x6f, 0xe5, 0x61, 0x86, 0x9c, 0x87, 0x20, 0x74, 0x54, 0x86, 0x29, 0x56, 0x60, 0xc7, + 0x52, 0x30, 0x44, 0x11, 0x6d, 0x4a, 0x1b, 0x96, 0xa3, 0x1b, 0xf6, 0x46, 0x64, 0xc3, 0x82, 0x5e, + 0x36, 0x04, 0x20, 0x95, 0x1a, 0xd2, 0xb6, 0x2d, 0xc2, 0x04, 0x53, 0x2d, 0xec, 0xd8, 0x58, 0x81, + 0xa8, 0xcc, 0x16, 0xb6, 0x7a, 0xd8, 0x6d, 0xd6, 0xe9, 0xd1, 0x15, 0x8c, 0xa0, 0x4c, 0xcf, 0x19, + 0xbb, 0x47, 0xe5, 0x09, 0x7e, 0xce, 0xd8, 0x3d, 0x42, 0x1f, 0xc3, 0x7c, 0xdb, 0x19, 0x3c, 0x71, + 0x7c, 0x7b, 0x70, 0x10, 0x4c, 0x69, 0x92, 0x4e, 0xe9, 0x56, 0xea, 0x94, 0x62, 0x18, 0x6c, 0x6e, + 0xf1, 0x9e, 0x56, 0xfe, 0x3f, 0xcc, 0x2a, 0x30, 0xb2, 0xd4, 0x2b, 0x30, 0xa9, 0xb7, 0x28, 0x4b, + 0xbd, 0x69, 0x49, 0xc0, 0xad, 0xd4, 0x61, 0x39, 0x79, 0xa4, 0x93, 0xf4, 0x52, 0xf9, 0xb6, 0x06, + 0x73, 0x2a, 0x05, 0xa2, 0xfb, 0xea, 0x41, 0xd1, 0x7e, 0x4a, 0xb7, 0xcb, 0x69, 0xeb, 0xdd, 0x2c, + 0x12, 0x0a, 0xfa, 0xfe, 0x0f, 0xaf, 0x6b, 0x86, 0x7a, 0xc0, 0x57, 0x61, 0x5a, 0x74, 0x5b, 0xa7, + 0x03, 0x17, 0x8c, 0xb0, 0x02, 0xad, 0x41, 0xa9, 0xe9, 0x05, 0x0b, 0xa0, 0xc7, 0x54, 0x34, 0xe4, + 0xaa, 0xca, 0x1f, 0x6a, 0xa1, 0x89, 0x45, 0x8d, 0x9d, 0x9d, 0x5d, 0xd3, 0xf1, 0xad, 0x3e, 0x5f, + 0x58, 0x50, 0x26, 0x82, 0xa8, 0xb6, 0xb3, 0x5b, 0x7d, 0x6e, 0xd9, 0x7d, 0x6b, 0xbf, 0xcf, 0x16, + 0xa9, 0x19, 0x4a, 0x1d, 0xc1, 0x7f, 0x8c, 0x8f, 0x18, 0x3e, 0x23, 0x89, 0xa0, 0x4c, 0xf0, 0x1f, + 0xe3, 0xa3, 0x10, 0x9f, 0x51, 0x86, 0x52, 0x57, 0xf9, 0x1d, 0x2d, 0x55, 0x6f, 0x9a, 0x96, 0x7b, + 0x80, 0x7d, 0xb2, 0x5c, 0x2e, 0x39, 0x02, 0x41, 0x13, 0x56, 0x10, 0x9b, 0x5d, 0xb2, 0x99, 0xd8, + 0x6e, 0x48, 0x35, 0x31, 0x61, 0x9a, 0x8f, 0x0b, 0xd3, 0xca, 0xcf, 0x67, 0x40, 0xe7, 0x76, 0xf2, + 0x16, 0xb6, 0x5c, 0x7f, 0x1f, 0x5b, 0xfe, 0xaf, 0xa1, 0x23, 0xb1, 0x01, 0xc8, 0xb4, 0x3c, 0x81, + 0x5b, 0x73, 0xb1, 0x45, 0xa4, 0xc9, 0x14, 0x25, 0x80, 0x84, 0x96, 0xd8, 0xd6, 0x14, 0x13, 0xf4, + 0xcc, 0x0d, 0x98, 0x6d, 0x0e, 0x6c, 0x3f, 0x74, 0x10, 0xa6, 0x29, 0x90, 0x5a, 0x49, 0xa0, 0x1e, + 0x38, 0x9e, 0x67, 0x0f, 0x55, 0x95, 0xa5, 0x56, 0x92, 0xf1, 0x58, 0xc5, 0x43, 0xc7, 0x1e, 0xe0, + 0x1e, 0x55, 0x56, 0x45, 0x43, 0xa9, 0xfb, 0xa5, 0x7b, 0x0d, 0x29, 0x7a, 0x74, 0x6e, 0x3c, 0xef, + 0xe0, 0x62, 0xc4, 0x3b, 0xf8, 0x2c, 0x2c, 0x54, 0xbb, 0x87, 0xb8, 0x47, 0x2a, 0xac, 0x41, 0x6f, + 0xd3, 0xf2, 0xbb, 0xcf, 0xb8, 0x13, 0x51, 0x30, 0x92, 0x9a, 0x88, 0x56, 0xe6, 0x35, 0x75, 0xdc, + 0xb7, 0x9f, 0x93, 0x9d, 0xef, 0x1e, 0x46, 0x9d, 0x89, 0x51, 0x20, 0x63, 0x78, 0x24, 0xe8, 0xbc, + 0x3c, 0x92, 0x85, 0x73, 0xf0, 0x48, 0x16, 0xb3, 0x3c, 0x92, 0xc8, 0x7a, 0x6a, 0x96, 0x6f, 0xf5, + 0x9d, 0x03, 0x66, 0x1e, 0xb3, 0x2e, 0x96, 0x68, 0x17, 0x19, 0x50, 0x68, 0x13, 0xae, 0xca, 0x10, + 0x06, 0x7e, 0xea, 0x62, 0xef, 0x59, 0xb8, 0x2b, 0xcc, 0xbf, 0x18, 0x09, 0x13, 0xef, 0xe3, 0xb9, + 0xd5, 0xb7, 0x7b, 0x84, 0x79, 0xd8, 0x4c, 0x2e, 0xd1, 0x99, 0x8c, 0x84, 0x19, 0xe9, 0xe3, 0x94, + 0x33, 0x7c, 0x9c, 0x91, 0xde, 0xd5, 0xe5, 0x2c, 0xef, 0x2a, 0xd3, 0x43, 0x5a, 0x19, 0xc7, 0x43, + 0x7a, 0x15, 0xf1, 0x90, 0xe8, 0xaa, 0x18, 0xc5, 0x33, 0x01, 0xed, 0x95, 0xaf, 0x50, 0xc5, 0xfd, + 0x96, 0xcc, 0x70, 0x23, 0x45, 0x3a, 0xe7, 0xc2, 0xac, 0x7e, 0xc7, 0x71, 0xce, 0xae, 0x9e, 0x93, + 0x73, 0x76, 0xed, 0x4c, 0xce, 0xd9, 0xea, 0x29, 0x9d, 0x33, 0xee, 0x4c, 0x99, 0x30, 0x53, 0x6b, + 0x57, 0xfb, 0x7d, 0xa7, 0x6b, 0xf9, 0x44, 0xa7, 0xc5, 0x7d, 0xb4, 0x45, 0x98, 0xa0, 0x12, 0x83, + 0x2b, 0x38, 0x56, 0x60, 0x86, 0xc0, 0xd7, 0x8e, 0xb1, 0x47, 0x64, 0x11, 0xd3, 0x32, 0x61, 0x45, + 0xe5, 0x5f, 0x0b, 0x30, 0x2f, 0x0c, 0xf5, 0xd1, 0x6a, 0x6d, 0x0d, 0x4a, 0x86, 0xf5, 0xd4, 0x57, + 0x75, 0x9a, 0x5c, 0x95, 0xa0, 0xf8, 0xf2, 0x89, 0x8a, 0x2f, 0xa6, 0x08, 0x0a, 0x49, 0x8a, 0xe0, + 0x6c, 0x86, 0x7b, 0xb2, 0x9a, 0x9b, 0x4c, 0x55, 0x73, 0xaa, 0x4a, 0x99, 0x3a, 0x95, 0xa1, 0x5f, + 0x3c, 0x81, 0xa1, 0xff, 0x05, 0x28, 0x47, 0xe4, 0x75, 0x28, 0x74, 0xa6, 0x19, 0xc3, 0xa7, 0xb5, + 0x8f, 0x21, 0xcc, 0x61, 0x2c, 0x61, 0x3e, 0xbe, 0xb3, 0x51, 0x3a, 0x91, 0xb3, 0xd1, 0x80, 0x92, + 0xe4, 0x53, 0x8f, 0x70, 0x35, 0x46, 0xda, 0xa8, 0x95, 0xaf, 0x4f, 0x80, 0x6e, 0x9e, 0xa7, 0xc1, + 0x15, 0x46, 0x01, 0xf2, 0x27, 0x89, 0x02, 0x24, 0x93, 0x52, 0x21, 0x95, 0x94, 0xd2, 0xa2, 0x06, + 0x13, 0x27, 0x8e, 0x1a, 0x4c, 0x8e, 0x19, 0x35, 0x28, 0x9e, 0x3a, 0x6a, 0x30, 0x3d, 0x7e, 0xd4, + 0x00, 0xd2, 0xad, 0x1d, 0x22, 0x1a, 0xf0, 0xb0, 0x6f, 0xbd, 0xc2, 0xbd, 0x96, 0x37, 0xa0, 0xd4, + 0x52, 0x30, 0xe4, 0xaa, 0xb3, 0xc7, 0x15, 0xd2, 0xac, 0xa6, 0xd9, 0x53, 0x5b, 0x4d, 0x73, 0x99, + 0x56, 0xd3, 0xc3, 0x42, 0x71, 0x4a, 0x2f, 0x56, 0xbe, 0x3b, 0x01, 0x45, 0xa3, 0xf3, 0x98, 0x19, + 0xb1, 0x3a, 0xe4, 0x4d, 0xcf, 0x11, 0xde, 0x9d, 0xe9, 0x39, 0x44, 0xea, 0x36, 0x07, 0x3d, 0xfc, + 0x52, 0x48, 0x5d, 0x5a, 0x20, 0x32, 0xae, 0x85, 0x2d, 0x0f, 0x6f, 0x39, 0x7d, 0xe6, 0xf0, 0x32, + 0xb7, 0x47, 0xad, 0x24, 0xc7, 0x61, 0xba, 0xc7, 0x03, 0x22, 0xd1, 0xe9, 0xce, 0x71, 0xdf, 0x47, + 0xae, 0x43, 0x0f, 0x61, 0x86, 0x21, 0xd9, 0x9e, 0xef, 0xb8, 0xaf, 0xb8, 0x2c, 0x54, 0x7c, 0x72, + 0x31, 0xbb, 0x0d, 0x19, 0x90, 0xf9, 0xbd, 0x0a, 0x2e, 0x3b, 0xa8, 0xaf, 0x1d, 0xdb, 0x2e, 0x1b, + 0x6e, 0x52, 0x1c, 0x54, 0x50, 0x85, 0xde, 0x86, 0xf9, 0x8f, 0xaa, 0x2d, 0x03, 0x77, 0x1d, 0xb2, + 0x1b, 0x75, 0xfb, 0x00, 0x7b, 0x3e, 0x8f, 0x5e, 0xc5, 0x1b, 0xd0, 0xe7, 0x60, 0x49, 0xaa, 0xa4, + 0x23, 0xd6, 0x9c, 0xe3, 0x81, 0x4f, 0x29, 0xb2, 0x60, 0x24, 0x37, 0x92, 0x83, 0x91, 0x1a, 0x6a, + 0xce, 0xd1, 0xb0, 0x8f, 0x89, 0x25, 0x34, 0xf0, 0x5d, 0x1b, 0x33, 0x9a, 0x2c, 0x18, 0xa3, 0x40, + 0x08, 0xbb, 0x48, 0xcd, 0x9b, 0x96, 0x87, 0xc9, 0x72, 0x80, 0x22, 0x26, 0xb4, 0x44, 0xe0, 0x5b, + 0x96, 0xe7, 0x87, 0x74, 0x9a, 0xd0, 0x82, 0x1e, 0xc2, 0x9a, 0x54, 0xbb, 0xed, 0xda, 0x07, 0xf6, + 0xc0, 0xea, 0xab, 0x07, 0x3a, 0x43, 0xb1, 0x33, 0xe1, 0x08, 0xe1, 0x26, 0x2c, 0x85, 0x12, 0x6e, + 0xd1, 0x48, 0x6a, 0x5a, 0x79, 0x1f, 0xe6, 0x63, 0x07, 0x99, 0x15, 0x56, 0x28, 0xc8, 0x61, 0x85, + 0x8f, 0x61, 0x9a, 0xaa, 0xc7, 0xae, 0xe3, 0xf6, 0x08, 0x22, 0x59, 0x2c, 0x47, 0x24, 0xab, 0x5b, + 0x87, 0x82, 0xf9, 0x6a, 0xc8, 0xf0, 0xe6, 0x54, 0xb1, 0xc1, 0x70, 0x48, 0xab, 0x41, 0x61, 0x88, + 0xbc, 0xa5, 0x22, 0x86, 0x90, 0xef, 0x8c, 0x41, 0x7f, 0x57, 0x7e, 0x9c, 0x03, 0xa0, 0xfd, 0x53, + 0x23, 0x82, 0x80, 0xb4, 0xad, 0x23, 0x2c, 0x44, 0x32, 0xf9, 0x2d, 0xcb, 0xfc, 0x9c, 0x2a, 0xf3, + 0xf9, 0x74, 0xf2, 0xe1, 0x74, 0xca, 0x30, 0xf5, 0xd8, 0x7a, 0xd9, 0xb1, 0x7f, 0x4b, 0xf8, 0xfe, + 0xa2, 0x48, 0xf4, 0x83, 0x10, 0xcb, 0x75, 0x1e, 0x19, 0x0a, 0x2b, 0x68, 0xc8, 0xa8, 0xdd, 0xac, + 0x73, 0x2a, 0xa6, 0xbf, 0xd1, 0xe7, 0x20, 0x67, 0x76, 0xb8, 0xfa, 0x5e, 0xd9, 0x60, 0x77, 0x86, + 0x1b, 0xe2, 0xce, 0x50, 0xb2, 0xb7, 0x68, 0xd4, 0xe4, 0x4f, 0x7e, 0x74, 0x5d, 0x33, 0x72, 0x66, + 0x87, 0x28, 0xd4, 0xe6, 0xa0, 0xdb, 0x3f, 0xee, 0xe1, 0xc6, 0xcb, 0x21, 0xe1, 0x04, 0xae, 0x84, + 0xb8, 0x7c, 0xc3, 0x1e, 0x8f, 0xb6, 0x65, 0x40, 0x11, 0x53, 0xb4, 0xf1, 0x92, 0x42, 0x6c, 0x59, + 0x6e, 0xaf, 0xee, 0xbc, 0x18, 0xc4, 0x3a, 0x62, 0xba, 0x3d, 0x0b, 0xac, 0x52, 0x01, 0x30, 0x3d, + 0x47, 0xec, 0xf0, 0x22, 0x4c, 0x30, 0xb6, 0x62, 0x87, 0xc8, 0x0a, 0x95, 0x9f, 0x6a, 0xc4, 0x22, + 0xa4, 0xfa, 0x91, 0xc6, 0xe0, 0x13, 0x75, 0xe3, 0x1d, 0x98, 0xde, 0x1e, 0xca, 0x81, 0x8f, 0x48, + 0xbc, 0xb4, 0xd6, 0xa6, 0xb8, 0xdb, 0x43, 0x23, 0x84, 0x43, 0x9b, 0xc1, 0x5d, 0x21, 0x53, 0x94, + 0x37, 0x12, 0xee, 0x0a, 0x29, 0x40, 0xfa, 0x85, 0xe1, 0x79, 0xdf, 0x28, 0x54, 0x5a, 0x50, 0xaa, + 0xb5, 0xc3, 0x60, 0x42, 0xd2, 0x5a, 0xdf, 0x12, 0x71, 0xe1, 0x5c, 0xfa, 0xfd, 0x24, 0x83, 0xa8, + 0xfc, 0x84, 0xef, 0x9d, 0xe5, 0x8f, 0xd8, 0xbb, 0xf1, 0xfb, 0xcb, 0xde, 0x31, 0x31, 0xd0, 0x2f, + 0x71, 0xc7, 0xbe, 0x59, 0x84, 0x29, 0x41, 0x41, 0x8a, 0x13, 0xa0, 0x09, 0x4b, 0x8b, 0x57, 0xa0, + 0x0d, 0x98, 0x7c, 0x8c, 0xfd, 0x67, 0x4e, 0x2f, 0x49, 0x24, 0xb0, 0x16, 0x2a, 0x12, 0x38, 0x14, + 0xba, 0x2b, 0xf3, 0x3f, 0x65, 0xe5, 0x88, 0xf5, 0x11, 0xb6, 0xf2, 0x35, 0xca, 0xf2, 0xa2, 0x4a, + 0x23, 0x9c, 0x81, 0x49, 0x47, 0x99, 0xbe, 0x74, 0xfb, 0x5a, 0x34, 0xc2, 0xa9, 0xd8, 0x7d, 0x86, + 0x82, 0x82, 0xee, 0x11, 0x62, 0x08, 0x7b, 0x98, 0xa0, 0x3d, 0x5c, 0x4d, 0xa0, 0xd2, 0xb0, 0x03, + 0x19, 0x81, 0xe0, 0x9b, 0x12, 0xfe, 0x64, 0x1c, 0xdf, 0x8c, 0xe1, 0x4b, 0x08, 0xc4, 0xfc, 0x0a, + 0xd9, 0x33, 0xc9, 0x5b, 0x08, 0x5b, 0x0d, 0x99, 0x91, 0xef, 0xaa, 0x3e, 0x1c, 0x37, 0xdc, 0xca, + 0xea, 0xc4, 0xc3, 0x76, 0x43, 0xf5, 0xf8, 0xee, 0xaa, 0xfc, 0xce, 0x2f, 0x8b, 0xca, 0x69, 0xcc, + 0x69, 0xa8, 0xd2, 0xe1, 0xf3, 0x0a, 0x03, 0x51, 0x65, 0x19, 0x31, 0x81, 0xa5, 0x66, 0x43, 0x61, + 0xb6, 0xbb, 0x2a, 0xb3, 0x50, 0xc5, 0x99, 0x30, 0xb0, 0x68, 0x37, 0x54, 0xd6, 0x7a, 0x1f, 0x66, + 0xeb, 0x98, 0x28, 0x36, 0x3e, 0x1d, 0x1e, 0xb0, 0xbb, 0xac, 0x44, 0x02, 0x64, 0x00, 0x43, 0x85, + 0x47, 0x9b, 0x30, 0xb7, 0xe3, 0x3a, 0x2f, 0x5f, 0x85, 0x07, 0x36, 0xcb, 0x05, 0xbc, 0xd4, 0x83, + 0x0a, 0x61, 0x44, 0x30, 0x88, 0x16, 0x8e, 0xc6, 0xeb, 0xdb, 0xc7, 0x47, 0xd4, 0x08, 0x2c, 0x18, + 0x49, 0x4d, 0x68, 0x53, 0xba, 0x7d, 0x08, 0x5c, 0xbc, 0x8b, 0xe9, 0x2e, 0x9e, 0x11, 0x07, 0xa7, + 0x7b, 0xfe, 0x0c, 0x77, 0x0f, 0xb7, 0xb0, 0xd5, 0xf7, 0x9f, 0xd1, 0x10, 0x5f, 0x74, 0xcf, 0xc3, + 0x66, 0x43, 0x86, 0x45, 0x26, 0x2c, 0x76, 0xba, 0xcf, 0x70, 0xef, 0xb8, 0x8f, 0xb9, 0x89, 0x4a, + 0x8d, 0x74, 0x1a, 0xec, 0x2b, 0xdd, 0x5e, 0x93, 0xfb, 0x48, 0x82, 0x33, 0x12, 0xb1, 0x2b, 0x0e, + 0x94, 0x28, 0x27, 0x7a, 0x43, 0x67, 0xe0, 0xe1, 0x11, 0xae, 0x19, 0x57, 0xd3, 0x39, 0x45, 0x4d, + 0x0b, 0xc3, 0x89, 0x29, 0x6f, 0x51, 0x1c, 0x75, 0xaf, 0x53, 0xd9, 0x00, 0x24, 0xd1, 0xb3, 0x34, + 0xee, 0x7d, 0xdb, 0x95, 0x84, 0x91, 0x28, 0x56, 0xfe, 0xbb, 0x40, 0x63, 0xb4, 0x0c, 0xec, 0x7c, + 0xa5, 0xd6, 0x55, 0x98, 0x6e, 0xb8, 0xae, 0xe3, 0xd6, 0x9c, 0x1e, 0xa6, 0x4b, 0x98, 0x35, 0xc2, + 0x0a, 0x62, 0x8a, 0xd3, 0xc2, 0x63, 0xec, 0x79, 0xd6, 0x01, 0xe6, 0x31, 0x09, 0xa5, 0x0e, 0xad, + 0x02, 0x34, 0xbd, 0xad, 0xea, 0x23, 0x8c, 0x87, 0xd8, 0xa5, 0x52, 0xa7, 0x68, 0x48, 0x35, 0xe8, + 0x7d, 0x65, 0x77, 0xb9, 0x58, 0xb9, 0x14, 0x13, 0x8c, 0xac, 0x99, 0x4b, 0x46, 0xe5, 0x3c, 0x08, + 0xa3, 0x49, 0x4e, 0x0c, 0x97, 0x2c, 0x2a, 0xa3, 0x49, 0xed, 0x86, 0x02, 0x4d, 0xa8, 0x8d, 0xca, + 0x1a, 0x3e, 0x7c, 0x31, 0x3e, 0xbc, 0xd4, 0x6c, 0xc8, 0xb0, 0x84, 0xc5, 0x6a, 0xfd, 0x63, 0xcf, + 0xc7, 0x6e, 0x1d, 0x13, 0xef, 0xd4, 0xe3, 0xc2, 0x45, 0x61, 0x31, 0x15, 0xc2, 0x88, 0x60, 0xa0, + 0x7b, 0x30, 0x1d, 0x5e, 0x5b, 0x41, 0x02, 0x99, 0x8a, 0x46, 0x46, 0xa0, 0xd8, 0x3b, 0xee, 0xfb, + 0x46, 0x88, 0x82, 0xee, 0x01, 0x48, 0xa2, 0x91, 0xc9, 0x98, 0x55, 0xb9, 0x83, 0x38, 0x21, 0x19, + 0x10, 0x11, 0x8f, 0x84, 0x81, 0xb0, 0xcb, 0x24, 0xdc, 0x4c, 0xc2, 0xe6, 0x49, 0xed, 0x86, 0x02, + 0x5d, 0x79, 0x48, 0xe3, 0x60, 0xcc, 0xfe, 0x0d, 0xb6, 0xe5, 0x1d, 0xa2, 0x41, 0x49, 0x8d, 0x57, + 0xd6, 0xa8, 0x5e, 0x5f, 0x8a, 0x1d, 0x26, 0x69, 0xe5, 0x47, 0x29, 0x60, 0x2b, 0xaf, 0x2b, 0x07, + 0x41, 0xcc, 0xb7, 0x27, 0x54, 0x6f, 0x73, 0xf3, 0x8d, 0x16, 0x2a, 0x0f, 0x60, 0xd6, 0xb4, 0xbc, + 0x43, 0xd3, 0xda, 0xef, 0xe3, 0x5d, 0x0f, 0xbb, 0x84, 0x8d, 0xc8, 0xdf, 0x41, 0x68, 0x4b, 0x07, + 0x65, 0xd2, 0xb6, 0x63, 0x79, 0xde, 0x0b, 0xc7, 0xed, 0xf1, 0xe0, 0x46, 0x50, 0xae, 0x7c, 0x43, + 0x23, 0xb3, 0xa4, 0x72, 0x2b, 0xd1, 0x8c, 0x49, 0xb7, 0xc5, 0x95, 0xf8, 0x4b, 0x3e, 0x7a, 0x47, + 0x18, 0x5c, 0xe2, 0x16, 0xe4, 0x4b, 0xdc, 0x55, 0xaa, 0xfb, 0x55, 0xa3, 0x5c, 0xaa, 0xa9, 0xfc, + 0x79, 0x8e, 0xd0, 0xf0, 0xe0, 0xa9, 0x7d, 0x50, 0x7b, 0x66, 0x0d, 0x0e, 0x30, 0xba, 0x13, 0xcc, + 0x8e, 0xdf, 0x65, 0x2e, 0xa8, 0x0e, 0x07, 0x6d, 0x0a, 0x77, 0x90, 0xad, 0xe3, 0x2e, 0x00, 0x43, + 0x97, 0x1c, 0x95, 0xab, 0xf1, 0xf8, 0x46, 0x08, 0x63, 0x48, 0xf0, 0xc8, 0x84, 0xb9, 0xe6, 0xc0, + 0xf6, 0x6d, 0xab, 0xff, 0x18, 0x1f, 0xed, 0x63, 0x57, 0x58, 0x65, 0x6f, 0xa7, 0xf5, 0xb0, 0xa1, + 0x82, 0x33, 0xd7, 0x39, 0xd2, 0xc7, 0x4a, 0x15, 0x16, 0x12, 0xc0, 0x4e, 0x74, 0xdf, 0xfb, 0x16, + 0xcc, 0x76, 0x9e, 0x1d, 0xfb, 0x3d, 0xe7, 0xc5, 0x80, 0xa9, 0x36, 0x72, 0x36, 0xe4, 0x47, 0x70, + 0x64, 0xa2, 0x58, 0xf9, 0xfb, 0x09, 0xb8, 0x18, 0x11, 0xe1, 0x89, 0xa7, 0x7b, 0x03, 0x66, 0x37, + 0x1d, 0xc7, 0xf7, 0x7c, 0xd7, 0x1a, 0x0e, 0xed, 0xc1, 0x01, 0x1d, 0xb4, 0x68, 0xa8, 0x95, 0x44, + 0x34, 0xf0, 0x98, 0x0d, 0xdd, 0xd0, 0x3c, 0xdd, 0x50, 0x45, 0x34, 0x48, 0xcd, 0x86, 0x0c, 0xcb, + 0x64, 0x52, 0xb8, 0x55, 0xdc, 0x5c, 0x2b, 0xa7, 0x6d, 0xa5, 0xa1, 0x9e, 0xfe, 0xfb, 0x91, 0x15, + 0x73, 0x5b, 0xed, 0xb2, 0x2a, 0x18, 0x24, 0x00, 0x23, 0xb2, 0x43, 0x8f, 0x60, 0x9e, 0x05, 0xd6, + 0xa4, 0x48, 0x1b, 0x97, 0xac, 0x8a, 0xc9, 0x18, 0x03, 0x32, 0xe2, 0x78, 0x71, 0x53, 0x64, 0xea, + 0x84, 0xa6, 0xc8, 0x23, 0x98, 0x7f, 0xe8, 0xd8, 0x03, 0x16, 0xa9, 0xe6, 0xf2, 0x8f, 0x0b, 0x5a, + 0x65, 0x36, 0x31, 0x20, 0x23, 0x8e, 0x87, 0xb6, 0x40, 0x67, 0xbd, 0x53, 0x5b, 0x85, 0x4d, 0x68, + 0x3a, 0x6e, 0x8a, 0x46, 0x61, 0x8c, 0x18, 0x16, 0x39, 0xde, 0x6a, 0xaf, 0x27, 0xb8, 0x30, 0xc9, + 0xb6, 0x93, 0x9a, 0x0d, 0x19, 0x96, 0x48, 0xfe, 0x80, 0x54, 0x18, 0x76, 0x29, 0x2e, 0xf9, 0x55, + 0x08, 0x23, 0x82, 0x51, 0xc1, 0xc9, 0xb6, 0x4a, 0x22, 0xbd, 0x46, 0x28, 0x31, 0x37, 0x3e, 0x25, + 0x56, 0xfe, 0x34, 0x07, 0xcb, 0x91, 0x70, 0x9d, 0xb8, 0x04, 0xaa, 0x04, 0xa6, 0x31, 0x19, 0x84, + 0x49, 0xeb, 0x69, 0x43, 0xa9, 0xa3, 0xc1, 0x36, 0x19, 0x26, 0xc7, 0x60, 0xe4, 0x3a, 0x22, 0x67, + 0x1b, 0x2f, 0x89, 0x08, 0xb2, 0x7d, 0x9e, 0x14, 0x11, 0x94, 0x89, 0x09, 0xc9, 0xfb, 0x33, 0xed, + 0x23, 0xec, 0x1c, 0xfb, 0xa6, 0xdd, 0x3d, 0xf4, 0xb8, 0x74, 0x4c, 0x6a, 0x22, 0x18, 0x66, 0x02, + 0x06, 0x13, 0x9a, 0x49, 0x4d, 0xe8, 0x73, 0xb0, 0xd4, 0x20, 0xe2, 0xc2, 0xf2, 0x71, 0xed, 0xd8, + 0x75, 0xf1, 0xc0, 0xa7, 0x30, 0x1e, 0xbf, 0xb9, 0x48, 0x6e, 0xac, 0xdc, 0x4a, 0xa0, 0x4a, 0xb6, + 0x14, 0xdb, 0xa3, 0xf9, 0x1d, 0x6c, 0x3b, 0x82, 0x72, 0xa5, 0x9f, 0xc0, 0x54, 0xe8, 0x0e, 0x14, + 0x88, 0xbe, 0xe1, 0x52, 0x5a, 0xe1, 0x09, 0x45, 0x51, 0x71, 0x59, 0x4d, 0x81, 0xe9, 0xa6, 0x5a, + 0xde, 0x61, 0xdd, 0xf2, 0xad, 0x7d, 0xcb, 0x13, 0x22, 0x4f, 0xa9, 0x23, 0x52, 0x4f, 0xe5, 0xa2, + 0x74, 0xa9, 0xf7, 0x76, 0x9c, 0x25, 0x46, 0x40, 0xbf, 0xa9, 0x90, 0x7d, 0xba, 0x35, 0x5b, 0xf9, + 0x99, 0x16, 0xa5, 0xf2, 0xd3, 0xde, 0x4a, 0xa0, 0x27, 0x29, 0xba, 0x65, 0x23, 0x9d, 0x5f, 0xc6, + 0xd1, 0x2e, 0x84, 0x57, 0xc8, 0x19, 0xf2, 0x7b, 0x05, 0xfa, 0xfb, 0x3c, 0x34, 0xce, 0x8f, 0x72, + 0xaa, 0x49, 0x19, 0x24, 0x5a, 0x69, 0x52, 0xa2, 0xd5, 0x17, 0x59, 0xb6, 0x82, 0x35, 0xe8, 0x89, + 0x94, 0xaf, 0x2b, 0x23, 0xfc, 0x0b, 0x71, 0x97, 0x25, 0x50, 0xc8, 0x56, 0x8a, 0x70, 0x3c, 0xf7, + 0x0c, 0x44, 0x08, 0xbe, 0x06, 0xc0, 0xa1, 0x08, 0xc3, 0x15, 0x68, 0xd7, 0xd7, 0x46, 0x74, 0xdd, + 0xac, 0x8b, 0x78, 0x41, 0x88, 0x86, 0x3e, 0x82, 0xa5, 0xc4, 0x8b, 0x2c, 0xae, 0x4a, 0x5e, 0x93, + 0xfb, 0x4b, 0x4e, 0x42, 0x4e, 0xc6, 0xcf, 0xbe, 0xfa, 0x9e, 0x1c, 0xe3, 0xea, 0xbb, 0xf2, 0x17, + 0xb9, 0x94, 0xf9, 0x11, 0x42, 0x62, 0x77, 0xcb, 0x8c, 0x05, 0xc9, 0xb9, 0x86, 0x15, 0x64, 0xd7, + 0x1a, 0x03, 0xc2, 0x53, 0x3d, 0xae, 0xb2, 0x45, 0x31, 0x25, 0x7b, 0xee, 0x36, 0x2c, 0x06, 0x69, + 0x03, 0x34, 0xb3, 0x9a, 0x05, 0xed, 0x39, 0xc1, 0x24, 0xb6, 0xa1, 0x0d, 0x40, 0x09, 0xa9, 0x11, + 0x4c, 0xfe, 0x24, 0xb4, 0x44, 0xf2, 0xa4, 0x26, 0x63, 0x79, 0x52, 0x8b, 0x30, 0xc1, 0xd2, 0x0a, + 0x58, 0xbe, 0x10, 0x2b, 0x10, 0x49, 0x43, 0x16, 0xed, 0x87, 0x69, 0x89, 0x41, 0xb9, 0xf2, 0x6f, + 0x9a, 0x9a, 0x1d, 0x11, 0xec, 0x8e, 0x90, 0xdc, 0xb2, 0xc4, 0xd5, 0xc6, 0x93, 0xb8, 0xb9, 0x74, + 0x89, 0xfb, 0x2e, 0x2c, 0x87, 0x92, 0x43, 0x41, 0x62, 0x7b, 0x99, 0xd2, 0x9a, 0x2e, 0x77, 0x0b, + 0xa3, 0xe4, 0xee, 0x3f, 0xce, 0x42, 0x89, 0xcf, 0x82, 0x7a, 0x30, 0x22, 0x59, 0x55, 0x93, 0x92, + 0x55, 0xff, 0x6f, 0x65, 0x83, 0x55, 0x83, 0x38, 0x67, 0x91, 0x32, 0xf3, 0xeb, 0x09, 0xc1, 0x27, + 0x9a, 0x86, 0x39, 0xe6, 0x4b, 0x92, 0xe9, 0x53, 0xbd, 0x24, 0x81, 0xe4, 0x1c, 0x34, 0x35, 0xa9, + 0xa0, 0x34, 0x4e, 0x76, 0xd9, 0x4c, 0x66, 0x76, 0xd9, 0xec, 0xa9, 0xb2, 0xcb, 0xe6, 0x4e, 0xf5, + 0x26, 0xe5, 0xe2, 0x38, 0x6f, 0x52, 0xf4, 0xf1, 0xb2, 0xce, 0xe6, 0x23, 0x59, 0x67, 0x19, 0xb7, + 0xa1, 0xe8, 0x3c, 0x72, 0xc8, 0x16, 0xce, 0x2b, 0x87, 0x6c, 0xf1, 0x1c, 0x72, 0xc8, 0x96, 0xce, + 0x9e, 0x43, 0xb6, 0x7c, 0x2e, 0x39, 0x64, 0x97, 0xce, 0x21, 0x87, 0xac, 0x3c, 0x46, 0x0e, 0xd9, + 0xe8, 0x57, 0x3a, 0x97, 0x33, 0x5f, 0xe9, 0x8c, 0xca, 0x41, 0x5b, 0x39, 0x4b, 0x0e, 0xda, 0x95, + 0x33, 0xe7, 0xa0, 0x5d, 0x3d, 0xa7, 0x57, 0x3a, 0xd7, 0xce, 0x29, 0x11, 0x6c, 0xf5, 0x4c, 0x89, + 0x60, 0xd7, 0x7f, 0xb5, 0x5e, 0xe9, 0x7c, 0xa2, 0xb1, 0x87, 0x91, 0xfc, 0x95, 0x20, 0x57, 0x7c, + 0x5a, 0xf2, 0x2b, 0x41, 0xcb, 0xc7, 0x1b, 0x0c, 0x42, 0x91, 0xed, 0xac, 0x2a, 0xfb, 0x20, 0x73, + 0x63, 0x1c, 0xe4, 0x8a, 0x01, 0x25, 0x69, 0x88, 0x84, 0x65, 0x7e, 0x46, 0x5d, 0xe6, 0xa5, 0x14, + 0x25, 0x24, 0xdb, 0xc1, 0xff, 0x52, 0xa0, 0x49, 0x49, 0xe7, 0xa2, 0xaa, 0x7f, 0x93, 0x47, 0xf4, + 0x6b, 0x9c, 0x47, 0x94, 0xa1, 0x07, 0x67, 0xc7, 0xcd, 0x0a, 0xfa, 0x4b, 0x8d, 0xbd, 0x6d, 0xcb, + 0xe4, 0x1a, 0x33, 0x8b, 0x6b, 0xce, 0x46, 0xef, 0x66, 0x32, 0xbd, 0xff, 0x5d, 0x1e, 0x40, 0xf2, + 0xa1, 0x93, 0x22, 0x31, 0x82, 0x05, 0x72, 0x12, 0x0b, 0xdc, 0x80, 0x59, 0x22, 0x24, 0xf0, 0x40, + 0x35, 0x44, 0xd5, 0xca, 0x08, 0xd5, 0x14, 0xc6, 0xa6, 0x9a, 0x6c, 0x0b, 0x62, 0xe2, 0xbc, 0x2c, + 0x88, 0xc9, 0x73, 0xb0, 0x20, 0xa6, 0xce, 0xf6, 0x2e, 0xb6, 0x98, 0xa5, 0x71, 0x2b, 0x7f, 0xab, + 0x05, 0x87, 0x44, 0xc8, 0xe8, 0x83, 0x08, 0x19, 0x55, 0x62, 0xf7, 0x9b, 0x59, 0x94, 0xf4, 0x61, + 0x16, 0x25, 0xbd, 0xad, 0x52, 0xd2, 0x72, 0xc2, 0x08, 0x8e, 0x8b, 0x65, 0x42, 0xfa, 0x41, 0x2e, + 0x7a, 0xfb, 0x9a, 0x16, 0x86, 0x56, 0x09, 0x27, 0x97, 0x4d, 0x38, 0xf9, 0x73, 0x24, 0x9c, 0xc2, + 0x79, 0x11, 0xce, 0xc4, 0x39, 0x10, 0xce, 0x64, 0x06, 0xe1, 0x54, 0xfe, 0x3d, 0x1f, 0xbd, 0x6f, + 0x43, 0xef, 0x40, 0x91, 0xb3, 0xb2, 0x38, 0xfe, 0x85, 0x04, 0x36, 0x17, 0xce, 0x83, 0x00, 0x25, + 0x68, 0x35, 0x81, 0x96, 0x8b, 0xa3, 0xd5, 0x54, 0x34, 0x01, 0x8a, 0xde, 0xa3, 0x19, 0x62, 0x1c, + 0x8f, 0x69, 0xb1, 0xc5, 0xa4, 0x04, 0x0c, 0x8e, 0x18, 0x02, 0xa3, 0x7b, 0x50, 0x0a, 0x09, 0x45, + 0xc4, 0x74, 0x52, 0xe8, 0x48, 0x5c, 0x71, 0x4a, 0x08, 0xa8, 0x2e, 0x82, 0x81, 0x3d, 0xde, 0x03, + 0xcb, 0x67, 0x2c, 0xc7, 0x23, 0xde, 0x3d, 0xb9, 0x0f, 0x15, 0x29, 0x3d, 0x26, 0x34, 0xf9, 0x8b, + 0x8e, 0x09, 0x4d, 0x8d, 0x13, 0x13, 0xfa, 0x7d, 0x0d, 0x4a, 0xfc, 0x7c, 0xa9, 0xb5, 0xf1, 0x79, + 0x7a, 0xb8, 0xcc, 0x66, 0xd0, 0xb8, 0xcd, 0x10, 0x98, 0x66, 0xbc, 0x45, 0xb9, 0x4a, 0x0c, 0xc0, + 0xd1, 0x5d, 0x76, 0x52, 0x0c, 0x37, 0xc7, 0xf7, 0x2a, 0x34, 0xeb, 0x44, 0x4c, 0x5f, 0x46, 0x0e, + 0x11, 0x2a, 0xdf, 0x29, 0xc0, 0x12, 0x0f, 0x21, 0x8a, 0x8b, 0x08, 0x9e, 0x8a, 0xf2, 0x06, 0xcc, + 0xb5, 0x8f, 0x8f, 0xb6, 0x9f, 0x86, 0x9d, 0x33, 0x53, 0x28, 0x52, 0x4b, 0x18, 0x9b, 0xd6, 0x04, + 0xf3, 0x67, 0xea, 0x42, 0xad, 0x44, 0xeb, 0xa0, 0x0b, 0xbc, 0x20, 0x69, 0x9f, 0x45, 0x5c, 0x62, + 0xf5, 0xc4, 0xdf, 0x6d, 0xe3, 0x97, 0x7e, 0x90, 0x2c, 0xc0, 0x4b, 0xc8, 0x84, 0x12, 0xfb, 0xb5, + 0xf9, 0xea, 0x11, 0x16, 0x79, 0xae, 0xb7, 0xe5, 0x93, 0x4c, 0x5c, 0xc9, 0x86, 0x84, 0xc4, 0x42, + 0xab, 0x72, 0x37, 0xe8, 0x69, 0x52, 0x1a, 0x07, 0x7b, 0x44, 0xfa, 0xde, 0x18, 0x7d, 0x47, 0x51, + 0xa3, 0xaf, 0x49, 0x83, 0x54, 0x0f, 0x6a, 0x79, 0x1d, 0x88, 0xbb, 0x27, 0x9e, 0xd2, 0x29, 0x22, + 0x29, 0xf1, 0x96, 0x95, 0x7b, 0xa0, 0x47, 0x27, 0x9e, 0xfc, 0xa4, 0x23, 0x39, 0xc7, 0x53, 0x79, + 0x80, 0xaa, 0x4c, 0x2e, 0xab, 0x17, 0x25, 0x3c, 0xfc, 0x73, 0x0d, 0x2e, 0x1b, 0xd8, 0x63, 0xf1, + 0xf4, 0x8f, 0x2c, 0x1f, 0xbb, 0x47, 0x96, 0x7b, 0x28, 0x68, 0x24, 0x3c, 0x29, 0x4d, 0x39, 0xa9, + 0x2f, 0xa9, 0x27, 0xc5, 0xa8, 0xf2, 0xdd, 0x48, 0xb0, 0x23, 0xb9, 0xcf, 0x8c, 0xd3, 0x4a, 0xde, + 0xc5, 0xfc, 0x2f, 0x6a, 0x17, 0x2b, 0xff, 0x5c, 0x60, 0xcf, 0x6d, 0x47, 0xfa, 0x05, 0xbf, 0x79, + 0xf9, 0xf2, 0x9b, 0x97, 0x2f, 0xe3, 0xbd, 0x7c, 0xf9, 0x87, 0x1c, 0xff, 0xec, 0x01, 0x31, 0xe7, + 0xee, 0x05, 0x6e, 0x22, 0x13, 0xf9, 0x6b, 0x31, 0x05, 0x4b, 0x8d, 0x39, 0x0a, 0xa2, 0x1a, 0x73, + 0x4c, 0xa6, 0xde, 0x0b, 0xcc, 0xc1, 0xdc, 0x28, 0xfc, 0x54, 0x63, 0xb0, 0x03, 0x25, 0xa9, 0xf3, + 0x84, 0x5b, 0xa3, 0x0d, 0xd5, 0x18, 0x4c, 0x7d, 0x63, 0x2e, 0x8b, 0x9d, 0x4e, 0x96, 0x85, 0x99, + 0xd5, 0x69, 0x92, 0xb3, 0xf2, 0x9f, 0x45, 0x35, 0x75, 0x27, 0x91, 0x0b, 0xdf, 0x57, 0x54, 0x6a, + 0xa2, 0xeb, 0x1f, 0x36, 0x0b, 0xcb, 0x43, 0x56, 0xc2, 0x77, 0x02, 0x87, 0x8d, 0x5b, 0x9e, 0x0b, + 0x09, 0x6e, 0x9a, 0x48, 0x44, 0x11, 0xae, 0xdd, 0xbb, 0xe1, 0x81, 0x72, 0x47, 0x67, 0x31, 0xe9, + 0x18, 0x42, 0x2a, 0xe7, 0x87, 0x7f, 0x27, 0x88, 0xa9, 0xf0, 0x6b, 0xaa, 0x85, 0x84, 0x48, 0x8a, + 0x18, 0x4c, 0x44, 0x5f, 0x6e, 0x89, 0x84, 0x63, 0x16, 0xb4, 0x57, 0xae, 0x60, 0x45, 0x92, 0x99, + 0x92, 0x76, 0xdc, 0xe6, 0xbc, 0xce, 0x6f, 0xd1, 0x78, 0xe2, 0xd3, 0x14, 0xc5, 0x5e, 0x8d, 0x5e, + 0xe0, 0xaa, 0x50, 0x46, 0x02, 0x26, 0x6a, 0x44, 0x72, 0x92, 0x38, 0x63, 0x67, 0xde, 0x05, 0x47, + 0x32, 0x99, 0x84, 0xde, 0xe8, 0xf1, 0xb7, 0x1c, 0xbc, 0x84, 0x1e, 0xa9, 0x7a, 0x03, 0xe2, 0x2f, + 0x42, 0x65, 0x2a, 0xc8, 0x50, 0x15, 0x77, 0x65, 0xdf, 0x89, 0x27, 0x2d, 0x2c, 0x27, 0x7b, 0x4c, + 0xe2, 0x52, 0x51, 0xf2, 0xb5, 0xe4, 0x60, 0xfd, 0xcc, 0xc9, 0x9e, 0x82, 0x27, 0xe5, 0x91, 0xce, + 0xa6, 0xe7, 0x91, 0x6e, 0x25, 0x19, 0x20, 0x73, 0x99, 0x02, 0x33, 0xc1, 0xc4, 0xb8, 0x0b, 0x97, + 0xe3, 0x2a, 0x70, 0x07, 0x0f, 0x7a, 0xf6, 0xe0, 0x80, 0xde, 0x1d, 0x14, 0x8d, 0x74, 0x00, 0xb4, + 0x09, 0x57, 0x15, 0x75, 0x4c, 0x15, 0xb4, 0xe4, 0xf8, 0xb0, 0xf7, 0xe7, 0x23, 0x61, 0x88, 0xc3, + 0x9b, 0x30, 0x80, 0x88, 0xae, 0xb2, 0x77, 0xe8, 0x23, 0x20, 0xd0, 0x07, 0x70, 0x25, 0xde, 0x1a, + 0xbc, 0xee, 0x11, 0x97, 0x10, 0x23, 0x40, 0xce, 0xac, 0xf0, 0xff, 0x58, 0x83, 0x19, 0xd9, 0x95, + 0x48, 0x74, 0x66, 0xaf, 0xc2, 0x34, 0xbb, 0x22, 0x14, 0x19, 0x2a, 0xd3, 0x46, 0x58, 0x81, 0xca, + 0x30, 0xa5, 0x6a, 0x79, 0x51, 0x94, 0x6e, 0x72, 0x0a, 0xca, 0x4d, 0xce, 0x0a, 0x14, 0xeb, 0xce, + 0x8b, 0x01, 0x6d, 0x99, 0xa0, 0x2d, 0x41, 0xb9, 0xf2, 0x67, 0x15, 0xd0, 0x05, 0x6f, 0x07, 0xaf, + 0xcc, 0x82, 0x37, 0x65, 0x9a, 0xfc, 0xa6, 0x2c, 0x29, 0x60, 0x13, 0x9a, 0x68, 0x79, 0xc5, 0x44, + 0xdb, 0x56, 0x59, 0x8d, 0xb9, 0x69, 0x9f, 0x49, 0x12, 0x28, 0xc1, 0xe3, 0xb1, 0xd1, 0xec, 0x96, + 0xf4, 0x81, 0x96, 0xff, 0x75, 0x79, 0xd5, 0x03, 0x3d, 0x92, 0x41, 0x20, 0x2e, 0x26, 0x6f, 0x8f, + 0x5c, 0x6a, 0x14, 0x49, 0x56, 0x9f, 0xb1, 0x1e, 0x51, 0x53, 0x76, 0xc1, 0xd8, 0xd7, 0xf3, 0x3e, + 0x3d, 0xb2, 0xfb, 0x00, 0x9a, 0xed, 0x63, 0x88, 0x2d, 0xab, 0x05, 0x18, 0x5b, 0x2d, 0x48, 0x8a, + 0xab, 0x74, 0x2a, 0xc5, 0x35, 0x73, 0x02, 0xc5, 0x15, 0x51, 0xb3, 0xb3, 0x27, 0x56, 0xb3, 0x31, + 0x1d, 0x32, 0x77, 0x2a, 0x1d, 0xa2, 0x8a, 0xf7, 0x8b, 0x27, 0x14, 0xef, 0xb1, 0x28, 0x83, 0x7e, + 0x9a, 0x28, 0x43, 0x8a, 0xb0, 0x9f, 0x3f, 0xa1, 0xb0, 0x47, 0xe7, 0x2e, 0xec, 0x17, 0xce, 0x2a, + 0xec, 0x17, 0xcf, 0x2c, 0xec, 0x97, 0xce, 0x2a, 0xec, 0x97, 0x33, 0x85, 0x3d, 0x7a, 0x37, 0x96, + 0xef, 0x27, 0x32, 0x66, 0xd8, 0x9d, 0x6a, 0x4a, 0x6b, 0x82, 0x8b, 0x11, 0xe6, 0xe1, 0x94, 0x13, + 0x5d, 0x8c, 0x30, 0x2d, 0xe7, 0xab, 0xb0, 0x18, 0x69, 0x13, 0xf7, 0xa7, 0x31, 0x27, 0x37, 0xc6, + 0xf7, 0x49, 0x88, 0x4c, 0x04, 0x24, 0xf6, 0x89, 0x86, 0xb1, 0xf5, 0xd5, 0xda, 0xe2, 0xbe, 0x35, + 0x16, 0xa0, 0xc8, 0x1a, 0x8d, 0xa3, 0xb2, 0xf1, 0x52, 0xfa, 0x4d, 0x18, 0xd1, 0x6c, 0x8b, 0x4b, + 0xda, 0x13, 0x8f, 0x68, 0x8e, 0x1a, 0x91, 0x37, 0xa2, 0x2d, 0xb8, 0x1e, 0x69, 0xe1, 0xc9, 0x61, + 0x5e, 0xd5, 0xf3, 0xec, 0x83, 0x41, 0xf8, 0x79, 0x8e, 0x0c, 0x30, 0xd4, 0x82, 0xd7, 0xa2, 0xab, + 0x0a, 0x92, 0xc4, 0x82, 0xbe, 0xd8, 0x0d, 0x6f, 0x36, 0x60, 0xaa, 0x2b, 0x19, 0x52, 0xca, 0xea, + 0x08, 0x57, 0x32, 0xa4, 0x97, 0xcd, 0x94, 0xfc, 0x26, 0x41, 0xa9, 0xd7, 0xe3, 0xb7, 0xff, 0x51, + 0x98, 0xd4, 0x7b, 0x04, 0x16, 0x4d, 0x5e, 0xa3, 0xbc, 0x3a, 0x02, 0x02, 0x3d, 0x84, 0xb5, 0xc4, + 0xcc, 0x00, 0x39, 0x4d, 0xec, 0x35, 0x3a, 0x8f, 0x4c, 0xb8, 0x31, 0xb2, 0x22, 0x2a, 0x63, 0x65, + 0x45, 0x7c, 0x5d, 0x83, 0x6b, 0x89, 0x53, 0xa6, 0xe1, 0x0b, 0x42, 0x71, 0xaf, 0x53, 0x8a, 0x7b, + 0x7f, 0x24, 0xc5, 0x8d, 0xec, 0x81, 0x11, 0xde, 0xe8, 0x51, 0xd0, 0xef, 0xa6, 0x25, 0xa0, 0x09, + 0x56, 0xbb, 0x41, 0xa7, 0x71, 0xef, 0xe4, 0xd3, 0x50, 0x18, 0x6e, 0xe4, 0x18, 0xe8, 0x1b, 0x5a, + 0xca, 0xc5, 0x03, 0x55, 0x59, 0x6c, 0x1e, 0x9f, 0xa2, 0xf3, 0xa8, 0x9e, 0x7c, 0x1e, 0x61, 0x1f, + 0x6c, 0x2a, 0x59, 0x23, 0xa1, 0x3f, 0xd0, 0x52, 0x68, 0xbf, 0xd6, 0x16, 0x1f, 0xeb, 0x79, 0x83, + 0x4e, 0xe6, 0x83, 0xd3, 0x6c, 0x0a, 0xef, 0x82, 0xcd, 0x25, 0x63, 0x1c, 0xf4, 0x4d, 0x0d, 0x5e, + 0x4b, 0x9f, 0xae, 0x98, 0xcd, 0x9b, 0x74, 0x36, 0xb5, 0x53, 0x6e, 0x8d, 0x32, 0xa1, 0xec, 0xd1, + 0x52, 0x39, 0x5a, 0x28, 0xdf, 0x9b, 0x23, 0x38, 0x5a, 0xe8, 0xdf, 0x6f, 0x69, 0x50, 0x19, 0xb9, + 0x74, 0x96, 0x94, 0xf8, 0x16, 0x5d, 0x58, 0xfd, 0xf4, 0xdb, 0x4c, 0xbb, 0x61, 0x2b, 0x1b, 0x63, + 0x3c, 0xf4, 0x1d, 0x0d, 0x3e, 0x95, 0xb5, 0x01, 0x6c, 0x66, 0xeb, 0x74, 0x66, 0x0f, 0xce, 0xb4, + 0xe5, 0xd2, 0xe4, 0xc6, 0x1b, 0xf5, 0xcc, 0x41, 0xf1, 0x8f, 0x61, 0x29, 0xd1, 0xb4, 0x3f, 0x61, + 0x9c, 0x4a, 0x79, 0x63, 0x27, 0x75, 0x7f, 0x97, 0x7e, 0xad, 0x31, 0x25, 0xa8, 0x96, 0x39, 0xb9, + 0x07, 0x70, 0x39, 0xd5, 0x40, 0xc8, 0xea, 0xa8, 0x28, 0x77, 0xd4, 0x8c, 0xa5, 0x30, 0xc8, 0xa2, + 0xe8, 0x8c, 0x5d, 0x99, 0xa7, 0xed, 0x6a, 0x27, 0x85, 0xe2, 0x15, 0x69, 0x7d, 0xa2, 0x1e, 0xb7, + 0x53, 0x64, 0xc3, 0xa9, 0x57, 0x6b, 0xc0, 0x8d, 0x71, 0x24, 0xe8, 0x89, 0xfa, 0xfc, 0x10, 0x5e, + 0x1f, 0x43, 0x10, 0x9e, 0x88, 0x50, 0x4c, 0x78, 0x63, 0x3c, 0x69, 0x76, 0xa2, 0x5e, 0x77, 0xe1, + 0xcd, 0x31, 0x45, 0xc9, 0x89, 0xba, 0xfd, 0x12, 0xac, 0x8f, 0x2f, 0x07, 0x4e, 0x14, 0xaa, 0x69, + 0xb2, 0x6c, 0x20, 0xf1, 0x61, 0xd4, 0x33, 0x7c, 0xf9, 0xa9, 0xf2, 0x57, 0x39, 0x58, 0x4c, 0x7a, + 0x7e, 0x3a, 0xe2, 0x15, 0xc8, 0x4e, 0xec, 0x33, 0xb8, 0x1b, 0x59, 0x8f, 0x59, 0xd5, 0xcf, 0xe1, + 0xc6, 0x2e, 0x66, 0xce, 0xe5, 0xa3, 0xb8, 0x2b, 0x66, 0xf6, 0x57, 0x6b, 0x47, 0xa5, 0x0b, 0x49, + 0x3b, 0x2a, 0xef, 0xf5, 0x77, 0x35, 0x80, 0x4d, 0xab, 0x7b, 0x78, 0x3c, 0xa4, 0x77, 0x3b, 0x69, + 0x17, 0x7f, 0xcd, 0xa4, 0x8b, 0xbf, 0x37, 0x95, 0x97, 0x2f, 0x41, 0x27, 0xa3, 0xe3, 0x49, 0x67, + 0x0e, 0xe4, 0xfd, 0x9e, 0x26, 0xee, 0xad, 0x9a, 0x3e, 0x3e, 0x4a, 0xfc, 0x08, 0x4d, 0x05, 0x66, + 0x78, 0xbe, 0xfe, 0x13, 0xe9, 0xf6, 0x53, 0xa9, 0x23, 0x30, 0x75, 0xfc, 0xd4, 0x3a, 0xee, 0x73, + 0x18, 0xfe, 0xe5, 0x57, 0xb9, 0x8e, 0x1c, 0x51, 0x73, 0xe0, 0x63, 0x77, 0x60, 0xf5, 0xf9, 0x85, + 0x5d, 0x50, 0xae, 0xfc, 0xb5, 0x26, 0x5f, 0x9f, 0xa1, 0x2f, 0xc2, 0x54, 0xcd, 0x19, 0xf8, 0x98, + 0x7e, 0xab, 0x25, 0x9e, 0x20, 0x1f, 0x00, 0x6e, 0x70, 0x28, 0xb6, 0x31, 0x02, 0x67, 0xc5, 0xa0, + 0x6f, 0x2d, 0x83, 0x86, 0x13, 0x26, 0xf0, 0x84, 0xdb, 0x21, 0x6f, 0xd4, 0x6f, 0x87, 0xf7, 0x74, + 0xe8, 0x9d, 0xf0, 0x25, 0x72, 0x2c, 0x4f, 0x4d, 0x00, 0x6d, 0x50, 0x08, 0x36, 0x31, 0x06, 0xbd, + 0xf2, 0x1e, 0x40, 0x58, 0x79, 0xa2, 0xfb, 0xe5, 0x37, 0x95, 0x0f, 0x20, 0x8c, 0x78, 0xa1, 0xf5, + 0x31, 0xcc, 0xc7, 0xde, 0x02, 0xa1, 0x1b, 0x30, 0xcb, 0xbe, 0xa9, 0x24, 0x9e, 0x17, 0x31, 0x24, + 0xb5, 0x92, 0x1e, 0x33, 0x47, 0x91, 0xbe, 0xc3, 0xa5, 0xd4, 0xad, 0xbf, 0x00, 0xd8, 0x1d, 0xf6, + 0x2c, 0x9f, 0x45, 0x70, 0x2f, 0xc1, 0x82, 0xf2, 0x8d, 0x26, 0xd6, 0xa4, 0x5f, 0x40, 0x4b, 0x30, + 0x2f, 0xbe, 0xbd, 0xd5, 0xea, 0xb4, 0x79, 0xb5, 0x86, 0x16, 0xe0, 0xe2, 0xae, 0x87, 0x5d, 0xba, + 0x7c, 0x5e, 0x99, 0x43, 0xb3, 0x30, 0x6d, 0x76, 0xb6, 0x79, 0x31, 0x4f, 0x50, 0x83, 0xef, 0x68, + 0x05, 0xa8, 0x85, 0xf5, 0x0d, 0x98, 0x0e, 0x3e, 0x49, 0x8e, 0x2e, 0x42, 0xa9, 0xed, 0xb8, 0x47, + 0x56, 0x9f, 0x16, 0xf5, 0x0b, 0x48, 0x87, 0x19, 0xfe, 0x0c, 0x85, 0xd5, 0x68, 0xeb, 0x3f, 0x2d, + 0x00, 0x84, 0xdf, 0x2e, 0x40, 0x73, 0x00, 0x66, 0x67, 0x7b, 0x6f, 0x77, 0xa7, 0x5e, 0x35, 0x1b, + 0xfa, 0x05, 0x04, 0x30, 0x59, 0xdd, 0xd9, 0x69, 0xb4, 0xeb, 0xba, 0x86, 0x8a, 0x50, 0x30, 0x1a, + 0xd5, 0xba, 0x9e, 0x43, 0x33, 0x50, 0x34, 0x8d, 0xdd, 0x76, 0x8d, 0xc0, 0xe4, 0x49, 0xa7, 0x0f, + 0x1a, 0xe6, 0x5e, 0x50, 0x53, 0x40, 0x25, 0x98, 0xaa, 0x6d, 0xb7, 0xdb, 0x8d, 0x9a, 0xa9, 0x4f, + 0x90, 0x2e, 0x79, 0x61, 0xcf, 0xd8, 0xd6, 0x27, 0xd1, 0x3c, 0xcc, 0xb6, 0xb6, 0x1f, 0xec, 0x6d, + 0x35, 0xaa, 0x86, 0xb9, 0xd9, 0xa8, 0x9a, 0xfa, 0x14, 0xe9, 0xa1, 0xd6, 0x96, 0x6a, 0x8a, 0x74, + 0xa2, 0x72, 0xcd, 0x34, 0x42, 0x30, 0x57, 0xdb, 0x6a, 0xd4, 0x1e, 0xed, 0x6d, 0x55, 0x1f, 0x35, + 0x1a, 0x3b, 0x0d, 0x43, 0x07, 0xb2, 0xaf, 0x64, 0xe4, 0x5a, 0x6b, 0xb7, 0x63, 0x36, 0x8c, 0xbd, + 0x7a, 0xc3, 0xac, 0x36, 0x5b, 0x1d, 0xbd, 0x44, 0x80, 0x49, 0x43, 0x67, 0xab, 0x6a, 0xd4, 0xf7, + 0x9a, 0xed, 0xfb, 0xdb, 0xfa, 0x0c, 0xed, 0xa0, 0xbd, 0x57, 0x6d, 0xb5, 0xb6, 0xc9, 0x2c, 0xf7, + 0x9a, 0x75, 0x7d, 0x96, 0x6c, 0xa2, 0xdc, 0x41, 0xc7, 0x24, 0xf3, 0x9f, 0xa3, 0xfb, 0x4f, 0x77, + 0x60, 0xaf, 0xd6, 0xde, 0x6b, 0x55, 0x37, 0x1b, 0x2d, 0xfd, 0x22, 0x2a, 0xc3, 0x62, 0x58, 0xf9, + 0xd1, 0xb6, 0xf1, 0x88, 0x83, 0xeb, 0xa4, 0xe7, 0x9d, 0xaa, 0x59, 0xdb, 0x22, 0x0d, 0x1d, 0x73, + 0xdb, 0x68, 0xe8, 0xf3, 0xa4, 0x8b, 0x7a, 0xa3, 0xd5, 0x60, 0xd0, 0xac, 0x12, 0x91, 0xca, 0x1d, + 0x63, 0xfb, 0x4b, 0x5f, 0x96, 0x16, 0xb6, 0x80, 0x5e, 0x83, 0x6b, 0xbc, 0xdf, 0xf6, 0x76, 0x7b, + 0xef, 0xc9, 0xb6, 0xd9, 0x6c, 0x3f, 0xd8, 0x33, 0x1a, 0x3b, 0xad, 0x66, 0xad, 0xba, 0xd7, 0xde, + 0x7d, 0xac, 0x2f, 0xa2, 0x55, 0x58, 0x89, 0x83, 0x90, 0x75, 0xb4, 0x9a, 0xe6, 0x97, 0xf5, 0x25, + 0xb4, 0x08, 0x7a, 0xa7, 0x61, 0xee, 0x19, 0x8d, 0x0f, 0x77, 0x9b, 0x46, 0xa3, 0xbe, 0xd7, 0xea, + 0xb4, 0xf5, 0x65, 0x52, 0xfb, 0x20, 0x5a, 0x7b, 0x49, 0x6c, 0x4d, 0xab, 0x6a, 0x36, 0x3a, 0x26, + 0xad, 0x2b, 0x93, 0x23, 0xa1, 0x75, 0x8d, 0x6a, 0xbd, 0x61, 0x90, 0x9d, 0xb9, 0x4c, 0x8f, 0x84, + 0x6d, 0x77, 0xa3, 0xda, 0x32, 0xb7, 0xf4, 0x15, 0x72, 0xe8, 0xe4, 0xf8, 0x29, 0xca, 0x15, 0x74, + 0x19, 0x96, 0xf8, 0x94, 0x5a, 0x8d, 0x6a, 0xa7, 0xb1, 0xb5, 0xdd, 0xe2, 0xa8, 0x57, 0x49, 0x13, + 0xdd, 0xfc, 0xda, 0x56, 0xa3, 0xbe, 0xdb, 0x6a, 0xec, 0xd5, 0xb6, 0x1f, 0x3f, 0xae, 0xb6, 0xeb, + 0x1d, 0xfd, 0xda, 0x7a, 0x1b, 0x20, 0xfc, 0xe2, 0x17, 0xa1, 0x0c, 0x42, 0xe6, 0xac, 0x46, 0xbf, + 0x40, 0x46, 0x10, 0x72, 0x4e, 0xd7, 0x08, 0xf1, 0x52, 0xa6, 0x09, 0x18, 0x60, 0x9e, 0x7f, 0xe2, + 0xce, 0xc0, 0x5f, 0xc5, 0x5d, 0x1f, 0xf7, 0xf4, 0xfc, 0xfa, 0x3a, 0x4c, 0x07, 0x1f, 0x94, 0x22, + 0xe8, 0x1d, 0xec, 0xd3, 0x92, 0x7e, 0x81, 0xa0, 0xb3, 0xe0, 0x2a, 0xab, 0xd0, 0xd6, 0xff, 0xa9, + 0x00, 0x48, 0xb8, 0x14, 0x12, 0x6f, 0x12, 0x8a, 0xb7, 0xbb, 0x87, 0x32, 0x4b, 0x4a, 0x5f, 0xee, + 0x09, 0x58, 0x92, 0x70, 0x6a, 0xac, 0x3a, 0x87, 0x96, 0x69, 0xfe, 0x48, 0xb4, 0x3e, 0x4f, 0x46, + 0x7f, 0x80, 0xfd, 0x80, 0xd3, 0x0b, 0x64, 0x53, 0x22, 0xf2, 0x86, 0x37, 0x4d, 0x90, 0x13, 0xe9, + 0x60, 0xc6, 0x90, 0xbc, 0x6e, 0x92, 0x10, 0x9b, 0x9a, 0x20, 0xc4, 0x5b, 0xa6, 0xd0, 0x75, 0xb8, + 0xd2, 0xc1, 0x7e, 0xfc, 0x6e, 0x82, 0x03, 0x14, 0xd1, 0x0a, 0x2c, 0x73, 0x80, 0x20, 0xb8, 0xcd, + 0xdb, 0xa6, 0xc9, 0x16, 0xb2, 0xdf, 0x7c, 0xd7, 0x74, 0x20, 0x0b, 0x13, 0x55, 0xc1, 0x03, 0x28, + 0xbd, 0x44, 0xce, 0x7f, 0x87, 0xc8, 0x3b, 0x9e, 0xc1, 0xa7, 0xcf, 0x10, 0x5c, 0x03, 0x1f, 0x39, + 0xcf, 0xc5, 0xab, 0x5a, 0x7d, 0x96, 0xcc, 0x52, 0x4d, 0xd5, 0xe4, 0x03, 0xcd, 0xa1, 0x6b, 0x70, + 0x99, 0xfd, 0x4e, 0x08, 0x5a, 0xeb, 0x17, 0xd1, 0x15, 0xb8, 0x14, 0x69, 0x16, 0xda, 0x80, 0xb1, + 0x93, 0xf0, 0x7a, 0x78, 0x7f, 0xf3, 0xe8, 0x2a, 0x94, 0xe3, 0x29, 0x3e, 0xbc, 0x15, 0xa1, 0x1b, + 0xb0, 0x26, 0x82, 0xb8, 0xf1, 0xf0, 0x2e, 0x87, 0x5a, 0x20, 0x3b, 0xc7, 0x02, 0x60, 0x11, 0x0f, + 0x84, 0x03, 0x2c, 0xa2, 0x4f, 0xc1, 0x6b, 0x0c, 0x20, 0xd1, 0xc0, 0xe4, 0x60, 0x4b, 0xeb, 0xdf, + 0xd6, 0x60, 0x56, 0xb9, 0x6d, 0x22, 0x7c, 0x2d, 0x2a, 0x78, 0x96, 0x8b, 0x7e, 0x81, 0x9c, 0xb8, + 0xa8, 0x54, 0xbe, 0x8d, 0xa0, 0x6b, 0x64, 0xa0, 0x58, 0x93, 0xf0, 0x1f, 0x0d, 0xdc, 0xc5, 0xf6, + 0x73, 0xdc, 0xd3, 0x73, 0x64, 0x97, 0x62, 0x60, 0xf7, 0x2d, 0xbb, 0x4f, 0x48, 0x5f, 0x1e, 0xd3, + 0x38, 0x1e, 0x0c, 0x48, 0xc7, 0x85, 0xf5, 0xfd, 0xa4, 0xfb, 0x2e, 0x72, 0x4c, 0x4a, 0x6d, 0x38, + 0xc7, 0x68, 0x8b, 0xe8, 0x49, 0x8b, 0xb5, 0x74, 0x7c, 0x67, 0x38, 0x24, 0xb3, 0x5a, 0xff, 0x81, + 0x06, 0x7a, 0xf4, 0x6b, 0x18, 0x84, 0x8b, 0xaa, 0x3d, 0xf1, 0x81, 0x3a, 0xfd, 0x42, 0x48, 0x2c, + 0xa2, 0x4a, 0x23, 0x14, 0xd5, 0xf1, 0x2d, 0xd7, 0x17, 0x35, 0x39, 0xc2, 0x24, 0xa4, 0x5b, 0x51, + 0x91, 0x27, 0xbd, 0x3c, 0xb2, 0xfb, 0xfd, 0xaf, 0x38, 0x47, 0xfb, 0x36, 0x61, 0x9a, 0x4b, 0xb0, + 0x50, 0xed, 0xf5, 0xa2, 0x24, 0xa4, 0x4f, 0x10, 0x1a, 0x67, 0xdd, 0xc7, 0xda, 0x26, 0x29, 0xa7, + 0x91, 0x71, 0x62, 0x4d, 0x53, 0x64, 0x51, 0x64, 0xc0, 0x58, 0x4b, 0x71, 0xfd, 0xb1, 0xf2, 0x95, + 0x00, 0x32, 0x91, 0x90, 0x90, 0xf4, 0x0b, 0x54, 0xf7, 0xb6, 0x45, 0x51, 0x23, 0xc5, 0x5a, 0x50, + 0xcc, 0x51, 0x5e, 0xa1, 0x57, 0x41, 0xbc, 0x26, 0xbf, 0xd9, 0xfc, 0xfe, 0x4f, 0x56, 0x2f, 0x7c, + 0xef, 0x93, 0x55, 0xed, 0xfb, 0x9f, 0xac, 0x6a, 0x3f, 0xfe, 0x64, 0xf5, 0xc2, 0xdf, 0xfc, 0xc7, + 0xaa, 0xf6, 0x95, 0x3b, 0xd2, 0xbf, 0x20, 0x3b, 0xb2, 0x7c, 0xd7, 0x7e, 0xe9, 0x50, 0xc3, 0x42, + 0x14, 0x06, 0xf8, 0xd6, 0xf0, 0xf0, 0xe0, 0xd6, 0x70, 0xff, 0x56, 0x68, 0x26, 0xed, 0x4f, 0xd2, + 0xaf, 0x09, 0xde, 0xf9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0xe9, 0x02, 0x2f, 0xde, 0x6c, + 0x00, 0x00, } func (m *CNStore) Marshal() (dAtA []byte, err error) { @@ -7066,6 +7145,42 @@ func (m *CNStore) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.DDLVisibilityFrontier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLogservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd2 + if m.DDLVisibilityActivationFenced { + i-- + if m.DDLVisibilityActivationFenced { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc8 + } + if m.DDLVisibilityActivationPrepared { + i-- + if m.DDLVisibilityActivationPrepared { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc0 + } if m.DDLVisibilityDeployedProtocol != 0 { i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) i-- @@ -7723,6 +7838,42 @@ func (m *CNStoreHeartbeat) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.DDLVisibilityFrontier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLogservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xf2 + if m.DDLVisibilityActivationFenced { + i-- + if m.DDLVisibilityActivationFenced { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe8 + } + if m.DDLVisibilityActivationPrepared { + i-- + if m.DDLVisibilityActivationPrepared { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe0 + } if len(m.DDLVisibilityEpochCommitTargets) > 0 { for iNdEx := len(m.DDLVisibilityEpochCommitTargets) - 1; iNdEx >= 0; iNdEx-- { { @@ -8500,12 +8651,12 @@ func (m *LogRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x40 } - n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.TS, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.TS):]) - if err13 != nil { - return 0, err13 + n15, err15 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.TS, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.TS):]) + if err15 != nil { + return 0, err15 } - i -= n13 - i = encodeVarintLogservice(dAtA, i, uint64(n13)) + i -= n15 + i = encodeVarintLogservice(dAtA, i, uint64(n15)) i-- dAtA[i] = 0x3a if m.TNID != 0 { @@ -10191,6 +10342,42 @@ func (m *CNStoreInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.DDLVisibilityFrontier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLogservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xfa + if m.DDLVisibilityActivationFenced { + i-- + if m.DDLVisibilityActivationFenced { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xf0 + } + if m.DDLVisibilityActivationPrepared { + i-- + if m.DDLVisibilityActivationPrepared { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe8 + } if m.DDLVisibilityDeployedProtocol != 0 { i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) i-- @@ -12719,6 +12906,14 @@ func (m *CNStore) ProtoSize() (n int) { if m.DDLVisibilityDeployedProtocol != 0 { n += 2 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) } + if m.DDLVisibilityActivationPrepared { + n += 3 + } + if m.DDLVisibilityActivationFenced { + n += 3 + } + l = m.DDLVisibilityFrontier.ProtoSize() + n += 2 + l + sovLogservice(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -13024,6 +13219,14 @@ func (m *CNStoreHeartbeat) ProtoSize() (n int) { n += 2 + l + sovLogservice(uint64(l)) } } + if m.DDLVisibilityActivationPrepared { + n += 3 + } + if m.DDLVisibilityActivationFenced { + n += 3 + } + l = m.DDLVisibilityFrontier.ProtoSize() + n += 2 + l + sovLogservice(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -14100,6 +14303,14 @@ func (m *CNStoreInfo) ProtoSize() (n int) { if m.DDLVisibilityDeployedProtocol != 0 { n += 2 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) } + if m.DDLVisibilityActivationPrepared { + n += 3 + } + if m.DDLVisibilityActivationFenced { + n += 3 + } + l = m.DDLVisibilityFrontier.ProtoSize() + n += 2 + l + sovLogservice(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -15688,6 +15899,79 @@ func (m *CNStore) Unmarshal(dAtA []byte) error { break } } + case 24: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationPrepared", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityActivationPrepared = bool(v != 0) + case 25: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationFenced", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityActivationFenced = bool(v != 0) + case 26: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityFrontier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DDLVisibilityFrontier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -17779,6 +18063,79 @@ func (m *CNStoreHeartbeat) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 28: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationPrepared", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityActivationPrepared = bool(v != 0) + case 29: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationFenced", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityActivationFenced = bool(v != 0) + case 30: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityFrontier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DDLVisibilityFrontier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -24833,6 +25190,79 @@ func (m *CNStoreInfo) Unmarshal(dAtA []byte) error { break } } + case 29: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationPrepared", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityActivationPrepared = bool(v != 0) + case 30: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityActivationFenced", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.DDLVisibilityActivationFenced = bool(v != 0) + case 31: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityFrontier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DDLVisibilityFrontier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) diff --git a/pkg/pb/logservice/logservice_test.go b/pkg/pb/logservice/logservice_test.go index f9b1c8287d3a0..74537e2bc6181 100644 --- a/pkg/pb/logservice/logservice_test.go +++ b/pkg/pb/logservice/logservice_test.go @@ -41,6 +41,8 @@ func TestCNStateUpdate(t *testing.T) { Role: metadata.CNRole_AP, CommandDeliveryAckSupported: true, DDLVisibilityBarrierReady: true, + DDLVisibilityActivationPrepared: true, + DDLVisibilityActivationFenced: true, DDLVisibilityDeployedProtocol: 38, ViewMetadataAdmissionGeneration: 1, ViewMetadataIngressReady: true, @@ -61,6 +63,8 @@ func TestCNStateUpdate(t *testing.T) { UpTime: state.Stores[hb1.UUID].UpTime, CommandDeliveryAckSupported: true, DDLVisibilityBarrierReady: true, + DDLVisibilityActivationPrepared: true, + DDLVisibilityActivationFenced: true, DDLVisibilityDeployedProtocol: 38, ViewMetadataAdmissionGeneration: 1, ViewMetadataIngressReady: true, @@ -540,7 +544,8 @@ func TestCNStateAtomicallyRejectsEpochCommitAfterMarkerlessJoin(t *testing.T) { state := NewCNState() state.Update(CNStoreHeartbeat{ UUID: "target-cn", QueryAddress: "target:6001", ViewMetadataAdmissionGeneration: 1, - DDLVisibilityBarrierReady: true, + DDLVisibilityBarrierReady: true, DDLVisibilityActivationPrepared: true, + DDLVisibilityActivationFenced: true, }, 1) commitTargets := []DDLVisibilityActivationTarget{{ ServiceID: "target-cn", Generation: 1, QueryAddress: "target:6001", @@ -562,6 +567,33 @@ func TestCNStateAtomicallyRejectsEpochCommitAfterMarkerlessJoin(t *testing.T) { assert.True(t, state.Stores["joining-cn"].ViewMetadataIngressReady) } +func TestCNStateAtomicallyRejectsEpochCommitFromUnfencedReplacement(t *testing.T) { + state := NewCNState() + state.Update(CNStoreHeartbeat{ + UUID: "target-cn", QueryAddress: "old:6001", ViewMetadataAdmissionGeneration: 1, + DDLVisibilityBarrierReady: true, DDLVisibilityActivationPrepared: true, + DDLVisibilityActivationFenced: true, + }, 1) + + // Replacement occurs after the old generation supplied Fenced. Even if the + // CN-side revalidation observes the new tuple, that tuple has no phase proof. + state.Update(CNStoreHeartbeat{ + UUID: "target-cn", QueryAddress: "new:6001", ViewMetadataAdmissionGeneration: 2, + DDLVisibilityBarrierReady: true, ViewMetadataIngressReady: true, + }, 2) + state.Update(CNStoreHeartbeat{ + UUID: "target-cn", QueryAddress: "new:6001", ViewMetadataAdmissionGeneration: 2, + DDLVisibilityBarrierReady: true, ViewMetadataIngressReady: true, + DDLVisibilityDeployedProtocol: 41, + DDLVisibilityEpochCommitTargets: []DDLVisibilityActivationTarget{{ + ServiceID: "target-cn", Generation: 2, QueryAddress: "new:6001", + }}, + }, 3) + + assert.Equal(t, int64(0), state.DDLVisibilityDeployedProtocol) + assert.True(t, state.Stores["target-cn"].ViewMetadataIngressReady) +} + func TestCNStateRejectsMarkerlessIngressAfterCommittedDDLCut(t *testing.T) { state := NewCNState() state.DDLVisibilityDeployedProtocol = 41 diff --git a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go index c6fbdeb795af1..7bce33bd18460 100644 --- a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go +++ b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go @@ -24,7 +24,9 @@ import ( "time" mysql "github.com/go-sql-driver/mysql" + "github.com/matrixorigin/matrixone/pkg/cnservice" "github.com/matrixorigin/matrixone/pkg/embed" + "github.com/matrixorigin/matrixone/pkg/util/fault" "github.com/stretchr/testify/require" ) @@ -44,9 +46,37 @@ func TestIssue277xxDDLConsistency(t *testing.T) { t.Run("27743 automatic cross-CN DDL visibility", func(t *testing.T) { const database = "issue_27743_automatic_ddl_visibility" + targets := cn0.ServiceID() + "," + cn1.ServiceID() + var activation string + require.NoError(t, db0.QueryRowContext(ctx, + "select mo_ctl('cn', 'SetProtocolVersion', ?)", targets+":41").Scan(&activation)) + require.Contains(t, activation, cn0.ServiceID()+":41") + require.Contains(t, activation, cn1.ServiceID()+":41") + // SetProtocolVersion returns success only after both target RPCs report + // v41 and HAKeeper acknowledges the atomically committed v41 epoch. + resetIssue277xxDatabase(t, ctx, db0, database) defer execSQLMaybe(t, ctx, db0, "drop database if exists `"+database+"`") + // Prove this public path actually executes SyncCommitV2: an injected + // receiver failure must make CREATE fail after v41 activation. + require.True(t, fault.Enable()) + defer fault.Disable() + faultPointRemoved := false + defer func() { + if !faultPointRemoved { + _, _ = fault.RemoveFaultPoint(context.Background(), cnservice.DDLVisibilitySyncCommitFaultPoint) + } + }() + require.NoError(t, fault.AddFaultPoint(ctx, + cnservice.DDLVisibilitySyncCommitFaultPoint, "1:1::", "return", 0, "expected", false)) + _, err := db0.ExecContext(ctx, + "create table `"+database+"`.`must_fail_sync` (id int primary key)") + require.ErrorContains(t, err, "injected DDL visibility sync commit error") + _, removeErr := fault.RemoveFaultPoint(ctx, cnservice.DDLVisibilitySyncCommitFaultPoint) + require.NoError(t, removeErr) + faultPointRemoved = true + // Do not issue SYNCCOMMIT or retry the read. The v41 DDL commit contract // must make the first fresh CN1 snapshot observe CN0's CREATE TABLE. execSQLRequire(t, ctx, db0, diff --git a/proto/logservice.proto b/proto/logservice.proto index 610bf5c8afe04..173ae0e1d879d 100644 --- a/proto/logservice.proto +++ b/proto/logservice.proto @@ -22,6 +22,7 @@ option go_package = "github.com/matrixorigin/matrixone/pkg/pb/logservice"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; import "google/protobuf/timestamp.proto"; import "metadata.proto"; +import "timestamp.proto"; option (gogoproto.goproto_enum_prefix_all) = false; option (gogoproto.sizer_all) = false; @@ -67,6 +68,9 @@ message CNStore { // ViewMetadataIngressReady is retained for raw control-plane inventory. bool ViewMetadataIngressReady = 22; int64 DDLVisibilityDeployedProtocol = 23; + bool DDLVisibilityActivationPrepared = 24; + bool DDLVisibilityActivationFenced = 25; + timestamp.Timestamp DDLVisibilityFrontier = 26 [(gogoproto.nullable) = false]; } message TNStore { @@ -187,6 +191,9 @@ message CNStoreHeartbeat { // CN membership tuple set and commits DDLVisibilityDeployedProtocol. repeated DDLVisibilityActivationTarget DDLVisibilityEpochCommitTargets = 27 [(gogoproto.nullable) = false]; + bool DDLVisibilityActivationPrepared = 28; + bool DDLVisibilityActivationFenced = 29; + timestamp.Timestamp DDLVisibilityFrontier = 30 [(gogoproto.nullable) = false]; } // CNAllocateID is the periodic message sent tp the HAKeeper by CN stores. @@ -718,6 +725,9 @@ message CNStoreInfo { bool ViewMetadataIngressReady = 26; bool DDLVisibilityBarrierReady = 27; int64 DDLVisibilityDeployedProtocol = 28; + bool DDLVisibilityActivationPrepared = 29; + bool DDLVisibilityActivationFenced = 30; + timestamp.Timestamp DDLVisibilityFrontier = 31 [(gogoproto.nullable) = false]; } // CNState contains all CN details known to the HAKeeper. From 5461bdabbab06a2cb72e4a2493ecdb5c0a67615e Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Mon, 31 Aug 2026 22:31:27 +0800 Subject: [PATCH 20/34] fix: preserve DDL frontier across CN replacement --- CLAUDE_TODO_2026-08-29.md | 59 ++ .../CLAUDE_cross_cn_ddl_visibility_fence.md | 66 +- pkg/cnservice/server_ddl_visibility.go | 63 +- pkg/cnservice/server_ddl_visibility_test.go | 161 ++-- pkg/cnservice/server_heartbeat.go | 2 +- pkg/cnservice/server_query.go | 2 +- pkg/defines/const.go | 88 +- pkg/frontend/txn.go | 4 +- pkg/hakeeper/rsm.go | 1 + pkg/pb/logservice/logservice.go | 3 + pkg/pb/logservice/logservice.pb.go | 894 ++++++++++-------- pkg/pb/logservice/logservice_test.go | 9 +- pkg/queryservice/client/query_client.go | 2 +- pkg/queryservice/client/query_client_test.go | 4 +- pkg/sql/plan/function/ctl/cmd_rpc_version.go | 10 +- .../plan/function/ctl/cmd_rpc_version_test.go | 10 +- .../issue_277xx_ddl_consistency_test.go | 12 +- proto/logservice.proto | 4 + 18 files changed, 807 insertions(+), 587 deletions(-) create mode 100644 CLAUDE_TODO_2026-08-29.md diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md new file mode 100644 index 0000000000000..bcef0b6477f1c --- /dev/null +++ b/CLAUDE_TODO_2026-08-29.md @@ -0,0 +1,59 @@ + +## P1 provisional/committed 持久化(追加) + +- 在发布 Fenced 前持久化 provisional v38;失败则绝不发布 Fenced。 +- 全体 provisional Fence 收敛后持久化 committed v38;失败保持 ingress/DDL fail-closed。 +- restart 对 committed 执行 startup frontier fence 后开放;对 provisional 恢复 v38 capability 但保持 ingress/public DDL 关闭,等待完整 activation retry。 +- restart regression 必须创建新 service 并调用 initMetadata(),另覆盖 provisional/committed persist failure。 + +## 2026-08-30:最新主干冲突与 review comments + +1. Merge 最新 `mo/main`,保留主干 v38/v39 语义,将 DDL visibility protocol 完整迁移到下一个版本 v40。 +2. 在 ctl dispatch 前读取 raw CN inventory,要求 activation target 精确覆盖全部仍可能公开产出 DDL 的 CN,并校验 generation/address 与 receiver capability。 +3. 在 startup ingress publication 前重新读取权威 cluster epoch,关闭 markerless join 与最终 epoch commit 之间的 TOCTOU;若 cut 已提交则转为 v40 fail-closed,不能开放 ingress。 +4. 增加版本兼容、遗漏 legacy producer、markerless join/commit 交错回归;执行相关 UT、race、vet、自审后 push,并 resolve threads/request re-review。 + +## 2026-08-30:再次解决主干冲突 + +1. Merge 最新 `mo/main`,按主干协议版本与生成文件保留双方语义。 +2. 重新生成受影响生成文件,运行冲突闭包测试与 `git diff --check`。 +3. Push PR 分支并确认恢复 mergeable。 + +## 2026-08-30:原子 membership/epoch commit + +1. 将 activation target 的 service ID、generation、query address 作为 epoch commit proof 传入 HAKeeper heartbeat transition。 +2. HAKeeper RSM 在同一 transition 内按 raw CNState 精确校验 membership/capability tuple;仅校验成功时推进 cluster epoch。 +3. CN 必须先获得 RSM 返回的 committed epoch,再持久化本地 committed marker 和开放 ingress;拒绝时保持 provisional/fail-closed。 +4. 增加 final scan 后、epoch commit 前 markerless join 的确定性回归,并运行相关 UT/race/vet。 + +## 2026-08-30:frontend txn 测试冲突 + +1. 合并最新 `mo/main`,在 `pkg/frontend/txn_test.go` 同时保留 DDL sync 回归与主干 panic rollback 回归。 +2. 运行 frontend 冲突闭包测试、vet 和 diff check,随后 push。 + +## 2026-08-30:最新 deep-review P1 与设计 gate + +1. markerless 首次升级 CN 保留当前主干已部署协议 baseline(至少 v40),仅将 v41 DDL activation 状态保持未完成/fail-closed,不回退共享 scalar 到 v37。 +2. HAKeeper monotonic epoch 已达 v41 后拒绝任何局部低版本 downgrade,避免现有会话继续作为无 fan-out DDL producer。 +3. 增加 baseline preservation、post-cut downgrade rejection 回归。 +4. 新增稳定版本化设计文档,说明状态机、rollout/rollback、direct/proxy ingress、复杂度/延迟、观测与恢复;补充确定性 two-CN 自动 DDL create/read 公共路径测试。 +5. 合并最新主干,执行相关 UT/race/vet/self-review,push 并请求 re-review。 + +## 2026-08-30:v41 公共路径回归与最新 review + +1. 查询并分析 PR 最新 inline/general review comment,更新变更闭包与验收条件。 +2. 修复 two-CN 公共路径测试发现的生产激活协调阻塞:保持 activation/startup/shutdown 串行所有权,同时允许心跳在长阶段等待期间发布 Prepared/Fenced 状态,避免用重试或弱化断言掩盖问题。 +3. 通过生产 `mo_ctl SetProtocolVersion` 激活精确 CN 集合,并用故障注入证明 CREATE DDL 实际经过 v41 `SyncCommitV2`,随后验证另一 CN 首次读取可见。 +4. 补齐心跳/RSM/超时/并发 UT,运行生成、focused/owning package、race、vet、embedded topology 与 self-review;通过后 commit/push、处理 review thread 并请求 re-review。 + +## 2026-08-30:处理新一轮 review comments + +1. 获取 exact-head 最新 review 与 unresolved threads,逐条复现并确认根因。 +2. 对确认问题做最小完整修复,补充对应确定性 UT/拓扑回归。 +3. 运行受影响 owning package、race、vet、生成文件与 diff 检查。 +4. commit/push,逐条英文回复并 resolve,重新请求 review。 + +进度(2026-08-31): +- 已将 DDL frontier 提升为 HAKeeper RSM 中独立于 CN store 生命周期的单调集群最大值;activation/restart 先从 txn client 重建 durable high-water mark,再发布并同步该全局值。 +- 已增加 producer replacement/store removal 不得清空 frontier 的 RSM 回归,以及 replacement 后 activation 仍等待旧 frontier 的 CN 回归。 +- 按用户决定不再等待其他并发 PR:本 PR 固定使用当前无人占用的 MORPC v43,并为两个已在 review 的并发 owner 预留 v41/v42;同步更新实现、测试、设计与生产路径回归。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index b22a5be6ff79c..719f8f1e7844e 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -1,11 +1,11 @@ # Cross-CN DDL Visibility Fence - Status: **Approved** -- Revision: 2 +- Revision: 3 - Approval: user approval recorded in the PR implementation session on 2026-08-30 - Owning issue: #27743 - Implementation PR: #27756 -- Protocol version: MORPC v41 +- Protocol version: MORPC v43 ## 1. Classification and motivation @@ -17,22 +17,22 @@ Issue #27743 demonstrates a missing catalog-visibility invariant: a DDL can comm ### Safety invariant -After the v41 deployment epoch is committed, every CN capable of public DDL production must satisfy both conditions: +After the v43 deployment epoch is committed, every CN capable of public DDL production must satisfy both conditions: -1. its runtime protocol is at least v41, so DDL commit performs `SyncCommitV2` fan-out; and +1. its runtime protocol is at least v43, so DDL commit performs `SyncCommitV2` fan-out; and 2. it belongs to the exact generation/address membership set atomically committed by HAKeeper, or it remains fail-closed until it joins a later exact cut. Before a CN opens public ingress, its local catalog frontier must be at least the maximum frontier reported by all participants in the applicable cut. ### Negation -It is unsafe for any public or already-connected CN to commit DDL below v41 while another public CN can admit a snapshot that has not applied that commit. +It is unsafe for any public or already-connected CN to commit DDL below v43 while another public CN can admit a snapshot that has not applied that commit. ### Measurable criteria - A create on CN0 followed immediately by a first read/load on CN1 succeeds without explicit `SYNCCOMMIT`. -- Markerless startup preserves the current-main v40 baseline before the v41 cut. -- No local downgrade below v41 is accepted after the monotonic v41 epoch is committed. +- Markerless startup preserves the current-main v40 baseline before the v43 cut. +- No local downgrade below v43 is accepted after the monotonic v43 epoch is committed. - Membership change between final scan and epoch commit rejects the old target set atomically. - Restart, timeout, persistence failure, response loss, and leader failover remain fail-closed. @@ -45,7 +45,7 @@ It is unsafe for any public or already-connected CN to commit DDL below v41 whil | Cluster deployed epoch | HAKeeper CNState | replicated snapshot/log | Monotonic cluster-wide committed cut | | Admission generation/address | HAKeeper CNState | replicated snapshot/log | Identity of one CN incarnation | | Prepared/Fenced/Complete | CN service and HAKeeper CNState | heartbeat-replicated phase proof plus local marker | Progress bound to one authoritative CN incarnation | -| Last committed DDL frontier | DDLCommitGate and HAKeeper CNState | monotonic process state replicated by heartbeat | Catalog frontier produced by that CN, excluding unrelated/no-op snapshot timestamps | +| Last committed DDL frontier | DDLCommitGate and HAKeeper CNState | monotonic cluster-lifetime maximum replicated in HAKeeper state | Durable activation high-water mark that survives CN restart, replacement, and store removal | | Public DDL gate | frontend `DDLCommitGate` | process-local | Whether new public/background DDL may enter | | Proxy ingress readiness | CN heartbeat/HAKeeper | replicated latest state | Whether new routed sessions may enter | @@ -55,36 +55,36 @@ HAKeeper is the first owner of cluster epoch and membership linearization. CN lo A CN is in one of these logical states: -1. **Baseline v40**: v41 not deployed; existing v38-v40 contracts remain active. Public ingress may be open. +1. **Baseline v40**: v43 not deployed; existing v38-v40 contracts remain active. Public ingress may be open. 2. **Withdrawing**: activation blocks new DDL, withdraws ingress, and drains active DDL. -3. **Prepared v41**: local old-protocol producers are drained; runtime can receive v41 RPCs. -4. **Provisionally fenced**: local frontier synchronization completed and `-41` is durable; ingress remains closed. -5. **Cluster committed**: HAKeeper atomically validated exact `(serviceID, generation, queryAddress)` membership and advanced epoch to 41. -6. **Locally committed**: CN persisted `41`; only then may it republish ingress and unblock DDL. -7. **Markerless post-cut**: no local marker but HAKeeper epoch is 41; runtime remains v41 and ingress/DDL remain closed until a complete retry. +3. **Prepared v43**: local old-protocol producers are drained; runtime can receive v43 RPCs. +4. **Provisionally fenced**: local frontier synchronization completed and `-43` is durable; ingress remains closed. +5. **Cluster committed**: HAKeeper atomically validated exact `(serviceID, generation, queryAddress)` membership and advanced epoch to 43. +6. **Locally committed**: CN persisted `43`; only then may it republish ingress and unblock DDL. +7. **Markerless post-cut**: no local marker but HAKeeper epoch is 43; runtime remains v43 and ingress/DDL remain closed until a complete retry. -The cluster epoch commit is the linearization point. Prepared, Fenced, and the last committed DDL frontier are published through each incarnation's heartbeat. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members, exact generation/address, receiver capability, and that each current incarnation itself published Prepared and Fenced, then advances the epoch only on exact equality. A replacement cannot reuse an older incarnation's Fenced proof. A join before this transition invalidates the target set; a join after it observes epoch 41 and is rejected as ingress-ready. +The cluster epoch commit is the linearization point. Prepared, Fenced, and the last committed DDL frontier are published through each incarnation's heartbeat. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members, exact generation/address, receiver capability, and that each current incarnation itself published Prepared and Fenced, then advances the epoch only on exact equality. A replacement cannot reuse an older incarnation's Fenced proof. A join before this transition invalidates the target set; a join after it observes epoch 43 and is rejected as ingress-ready. ## 5. End-to-end flow ### First rollout 1. All LogStore/HAKeeper replicas advertise support for the epoch schema. -2. Every CN runs v41-capable code but markerless CNs keep protocol baseline v40. +2. Every CN runs v43-capable code but markerless CNs keep protocol baseline v40. 3. `mo_ctl SetProtocolVersion` refreshes raw authoritative CN membership. -4. The requested set must exactly match all eligible CN tuples and each target must advertise the v41 receiver/barrier capability. -5. Targets concurrently withdraw ingress, block and drain DDL, then heartbeat Prepared together with their monotonic last committed DDL frontier. -6. Each target reads the replicated HAKeeper phase/frontier inventory, applies every remote producer frontier, durably enters provisional Fenced, and heartbeats Fenced. This avoids cyclic QueryService control RPCs while every target is already serving a long-running activation RPC. -7. Each target confirms all exact current incarnations are Fenced in HAKeeper; HAKeeper atomically revalidates those tuple-bound proofs and commits epoch 41. -8. Each CN persists local committed 41, republishes ingress if listeners are live, and unblocks public DDL. +4. The requested set must exactly match all eligible CN tuples and each target must advertise the v43 receiver/barrier capability. +5. Targets concurrently withdraw ingress, block and drain DDL, capture their reconstructed latest committed timestamp, then heartbeat Prepared together with that frontier. HAKeeper advances a cluster-lifetime maximum and never lowers it when an incarnation restarts, is replaced, or is removed. +6. Each target reads and applies the replicated cluster-lifetime frontier, durably enters provisional Fenced, and heartbeats Fenced. This avoids cyclic QueryService control RPCs while every target is already serving a long-running activation RPC. +7. Each target confirms all exact current incarnations are Fenced in HAKeeper; HAKeeper atomically revalidates those tuple-bound proofs and commits epoch 43. +8. Each CN persists local committed 43, republishes ingress if listeners are live, and unblocks public DDL. ### Steady-state DDL -A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, protocol v41 triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable QueryService. +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, protocol v43 triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable QueryService. ### Scale-out and replacement -A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes before the cluster commit, it becomes authoritative membership and invalidates any old target proof. If it linearizes after commit, HAKeeper forces ingress false and returns epoch 41. It never becomes a public v40 producer after the cut. +A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes before the cluster commit, it becomes authoritative membership and invalidates any old target proof. If it linearizes after commit, HAKeeper forces ingress false and returns epoch 43. It never becomes a public v40 producer after the cut. ## 6. Failure, retry, and lifecycle behavior @@ -95,7 +95,7 @@ A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes - **Epoch response loss**: epoch may be committed, but local marker remains provisional and ingress closed; retry learns the committed epoch. - **Committed local persistence failure**: cluster epoch remains committed; this CN remains closed and restarts from provisional state. - **Ingress publication uncertainty**: perform a bounded cleanup withdrawal; never assume publication failed. -- **Restart**: committed marker runs startup frontier synchronization before opening; provisional or markerless post-cut starts v41 fail-closed. +- **Restart**: committed marker runs startup frontier synchronization before opening; provisional or markerless post-cut starts v43 fail-closed. - **Shutdown**: stop periodic heartbeat publication, then withdraw ingress/barrier state before stopping QueryService. - **Leader failover**: activation is gated until every voting and non-voting LogStore advertises epoch-schema capability, so any eligible HAKeeper leader preserves the field. @@ -105,20 +105,20 @@ Retries are idempotent for the same generation and target set. Replacement gener ### Mixed-version baseline -Current main already deploys v40 semantics. A fresh v41-capable process without a DDL marker therefore remains at v40, not v37. The v41 DDL state is separate from unrelated v38-v40 capabilities. +Current main already deploys v40 semantics. A fresh v43-capable process without a DDL marker therefore remains at v40, not v37. The v43 DDL state is separate from unrelated v38-v40 capabilities. ### Rollout order 1. Upgrade all voting and non-voting LogStores/HAKeeper replicas. 2. Upgrade every CN; verify barrier receiver capability in raw inventory. -3. Invoke one exact complete-target v41 activation. -4. Verify epoch 41 and all eligible CN ingress/committed markers. +3. Invoke one exact complete-target v43 activation. +4. Verify epoch 43 and all eligible CN ingress/committed markers. ### Downgrade policy -Before epoch 41, ordinary protocol changes at or below v40 remain possible. After epoch 41, local downgrade below v41 is rejected. A safe rollback would require a separately designed atomic cluster rollback that withdraws and drains every DDL producer before lowering the epoch; this revision deliberately does not implement epoch rollback. +Before epoch 43, ordinary protocol changes at or below v40 remain possible. After epoch 43, local downgrade below v43 is rejected. A safe rollback would require a separately designed atomic cluster rollback that withdraws and drains every DDL producer before lowering the epoch; this revision deliberately does not implement epoch rollback. -Binary rollback after epoch 41 is unsupported until such a rollback protocol exists. Operators must restore forward to a v41-capable binary. +Binary rollback after epoch 43 is unsupported until such a rollback protocol exists. Operators must restore forward to a v43-capable binary. ## 8. Proxy and direct ingress @@ -159,7 +159,7 @@ Rejected: compiled capability is not proof that every producer completed the dis ### D. Separate DDL feature epoch from the shared MORPC scalar -Architecturally clean and avoids scalar coupling, but still requires the same membership/ingress linearization and broader API migration. This revision retains MORPC v41 as the sender/receiver capability gate while storing deployment completion separately. +Architecturally clean and avoids scalar coupling, but still requires the same membership/ingress linearization and broader API migration. This revision retains MORPC v43 as the sender/receiver capability gate while storing deployment completion separately. ### E. TN-only global catalog barrier on every new transaction @@ -169,8 +169,8 @@ Could provide a stronger generic read contract, but materially changes every tra | Contract | Deterministic evidence | |---|---| -| v40 baseline preserved | markerless default-v41 startup UT | -| post-cut downgrade rejected | completed-v41 downgrade UT | +| v40 baseline preserved | markerless default-v43 startup UT | +| post-cut downgrade rejected | completed-v43 downgrade UT | | exact authoritative targets | ctl raw-membership omission/capability UT | | join/commit atomicity | CNState RSM ordering UT: final scan, join, stale commit | | HAKeeper failover compatibility | old capability view rejection UT | @@ -182,7 +182,7 @@ Could provide a stronger generic read contract, but materially changes every tra ## 14. Decision log and open items - Chosen linearization point: HAKeeper replicated heartbeat transition with exact tuple proof. -- Chosen baseline: preserve current-main v40 before v41 activation. +- Chosen baseline: preserve current-main v40 before v43 activation. - Chosen downgrade behavior: reject after monotonic epoch commit. - Chosen direct-ingress protection: local DDL gate in addition to proxy admission. - Non-blocking follow-up: add dedicated activation/fan-out metrics and publish N-CN staging latency evidence. diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 4b7554d785413..4c78e3820c46e 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -26,7 +26,6 @@ import ( "github.com/matrixorigin/matrixone/pkg/defines" logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" "github.com/matrixorigin/matrixone/pkg/pb/metadata" - "github.com/matrixorigin/matrixone/pkg/pb/timestamp" "github.com/matrixorigin/matrixone/pkg/util/file" "github.com/matrixorigin/matrixone/pkg/util/protoc" ) @@ -34,19 +33,19 @@ import ( func ddlVisibilityBarrierSupported(serviceID string) bool { value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) version, valid := value.(int64) - return ok && valid && version >= defines.MORPCVersion41 + return ok && valid && version >= defines.MORPCVersion43 } // prepareDDLVisibilityBarrier publishes this CN only after QueryService is -// listening. With protocol v41 active, it then catches up to the largest +// listening. With protocol v43 active, it then catches up to the largest // frontier held by the already-published barrier participants before public // SQL ingress can be admitted. func (s *service) prepareDDLVisibilityBarrier() error { // MORPCLatestVersion describes compiled capability, not deployment-wide // activation. Restore the durable per-CN deployed protocol before deciding - // whether this restart can produce v41 DDL. A fresh upgraded process has no + // whether this restart can produce v43 DDL. A fresh upgraded process has no // marker and preserves the already-deployed v40 baseline until the - // complete-target cut persists v41. + // complete-target cut persists v43. deployedVersion := s.loadDDLVisibilityDeployedProtocol() if deployedVersion == 0 && s._hakeeperClient != nil { ctx, cancel := s.newDDLVisibilityBarrierContext(context.Background()) @@ -57,24 +56,24 @@ func (s *service) prepareDDLVisibilityBarrier() error { return err } cancel() - if details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion41 { - // Markerless scale-out/replacement after the cluster cut joins v41 as + if details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion43 { + // Markerless scale-out/replacement after the cluster cut joins v43 as // provisional. It can synchronize and receive activation RPCs, but it // cannot publish ingress or produce DDL before joining the exact cut. deployedVersion = -details.DDLVisibilityDeployedProtocol } } rt := moruntime.ServiceRuntime(s.cfg.UUID) - if deployedVersion >= defines.MORPCVersion41 { + if deployedVersion >= defines.MORPCVersion43 { s.ddlVisibilityActivationComplete.Store(true) rt.SetGlobalVariables(moruntime.MOProtocolVersion, deployedVersion) - } else if deployedVersion <= -defines.MORPCVersion41 { + } else if deployedVersion <= -defines.MORPCVersion43 { // A provisional marker proves this CN durably fenced its local producers, - // but not that every target committed the same cut. Keep v41 capability so + // but not that every target committed the same cut. Keep v43 capability so // retries can converge while startup/public ingress remains fail-closed. rt.SetGlobalVariables(moruntime.MOProtocolVersion, -deployedVersion) } else if value, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion); ok { - if version, valid := value.(int64); valid && version >= defines.MORPCVersion41 { + if version, valid := value.(int64); valid && version >= defines.MORPCVersion43 { rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) } } @@ -113,6 +112,7 @@ func (s *service) prepareDDLVisibilityBarrierLocked() error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() + s.ddlCommitGate.RecordDDLFrontier(s._txnClient.GetLatestCommitTS()) // Startup owns this mutex, so relying on the periodic heartbeat (which uses // the same mutex to order readiness snapshots) would deadlock publication. // Publish the startup barrier directly before waiting for its authoritative @@ -137,8 +137,8 @@ func (s *service) prepareDDLVisibilityBarrierLocked() error { // overwrite this final withdrawal. func (s *service) publishDDLVisibilityIngressAfterStart() error { // Serialize listener-ready publication with startup/activation/shutdown. - // Compiled v41 capability is not evidence that the deployment-wide producer - // cut completed: a default-v41 CN stays fail-closed until its complete-target + // Compiled v43 capability is not evidence that the deployment-wide producer + // cut completed: a default-v43 CN stays fail-closed until its complete-target // activation succeeds. If activation raced ahead of listener startup, this // method remains the sole owner that opens ingress after listeners are live. s.ddlVisibilityBarrierMu.Lock() @@ -168,7 +168,7 @@ func (s *service) publishDDLVisibilityIngressAfterStart() error { return err } cancel() - if batch.DDLVisibilityDeployedProtocol >= defines.MORPCVersion41 { + if batch.DDLVisibilityDeployedProtocol >= defines.MORPCVersion43 { moruntime.ServiceRuntime(s.cfg.UUID).SetGlobalVariables( moruntime.MOProtocolVersion, batch.DDLVisibilityDeployedProtocol) s.viewMetadataIngressReady.Store(false) @@ -235,7 +235,7 @@ func (s *service) ddlVisibilityBarrierRetryInterval() time.Duration { // Every target CN blocks and drains local DDL before publishing Prepared. Once // all targets are prepared, no v34 DDL producer exists; each CN applies the // converged frontier and publishes Fenced. A CN releases its DDL gate only after -// every target is fenced, at which point all later DDL uses the v41 fan-out and +// every target is fenced, at which point all later DDL uses the v43 fan-out and // every still-fencing receiver remains barrier-reachable. func (s *service) setProtocolVersion(ctx context.Context, version int64, targets []string) error { s.ddlVisibilityBarrierMu.Lock() @@ -254,13 +254,13 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets return moerr.NewInternalError(ctx, "invalid protocol version") } pending := s.ddlVisibilityActivationPending.Load() - if version < defines.MORPCVersion41 { + if version < defines.MORPCVersion43 { if pending { return moerr.NewInvalidStateNoCtx("cannot downgrade during DDL visibility activation") } deployed := s.loadDDLVisibilityDeployedProtocol() clusterCommitted := s.ddlVisibilityActivationComplete.Load() || - deployed >= defines.MORPCVersion41 || deployed <= -defines.MORPCVersion41 + deployed >= defines.MORPCVersion43 || deployed <= -defines.MORPCVersion43 if !clusterCommitted && s._hakeeperClient != nil { queryCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) details, err := s._hakeeperClient.GetClusterDetails(queryCtx) @@ -270,7 +270,7 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets return err } cancel() - clusterCommitted = details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion41 + clusterCommitted = details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion43 } if clusterCommitted { return moerr.NewInvalidStateNoCtx( @@ -289,7 +289,7 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) return nil } - if current >= defines.MORPCVersion41 && !pending && + if current >= defines.MORPCVersion43 && !pending && s.ddlVisibilityActivationComplete.Load() { rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) return nil @@ -313,7 +313,7 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets barrierCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) defer cancel() if !pending { - // A default-v41 process deliberately keeps ingress closed until the + // A default-v43 process deliberately keeps ingress closed until the // complete-target cut. Restore ingress when listeners are already live; // if activation races before listener startup, Start opens it afterward. s.ddlVisibilityRestoreIngress.Store( @@ -334,8 +334,12 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets if err := s.ddlCommitGate.WaitDrained(barrierCtx); err != nil { return err } + // Capture a durable committed high-water mark after every local DDL producer + // is drained. A restarted incarnation's txn client reconstructs a frontier + // at or beyond DDL committed by its predecessor. + s.ddlCommitGate.RecordDDLFrontier(s._txnClient.GetLatestCommitTS()) - // Version 41 is visible only after the local pre-v41 producers are drained. It + // Version 43 is visible only after the local pre-v43 producers are drained. It // acts as the distributed Prepared signal queried by every other target. rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) s.ddlVisibilityActivationPrepared.Store(true) @@ -377,7 +381,7 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets return err } // Commit the deployed cut before reopening ingress. A failure leaves the - // durable provisional marker in place; restart therefore remains on v41 but + // durable provisional marker in place; restart therefore remains on v43 but // fail-closed until a complete-target retry commits the cut. if err := s.persistDDLVisibilityDeployedProtocol(version); err != nil { return err @@ -748,18 +752,9 @@ func (s *service) syncStartupDDLVisibilityFrontier(ctx context.Context) error { if err != nil { return moerr.AttachCause(ctx, err) } - maxTS := timestamp.Timestamp{} - for _, cn := range details.CNStores { - if s.cfg != nil && cn.UUID == s.cfg.UUID { - // The drained producer already observes its own committed DDL. Waiting - // only on remote frontiers avoids depending on the control RPC that is - // currently executing on this CN. - continue - } - if cn.DDLVisibilityBarrierReady && maxTS.Less(cn.DDLVisibilityFrontier) { - maxTS = cn.DDLVisibilityFrontier - } - } + // HAKeeper retains this maximum independently of current CN membership, so + // producer restart/replacement/removal cannot erase a committed DDL fact. + maxTS := details.DDLVisibilityFrontier if maxTS.IsEmpty() { return nil } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index b4dcf64ae4c7e..1c63a8d77578f 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -66,13 +66,14 @@ func newDDLVisibilityMetadataFS(t *testing.T) fileservice.ReplaceableFileService } type ddlVisibilityTestCluster struct { - cnServices []metadata.CNService - refreshCalls int - refreshHook func() - phaseMu sync.Mutex - phases map[string]query.GetProtocolVersionResponse - frontiers map[string]timestamp.Timestamp - phaseHook func(string) query.GetProtocolVersionResponse + cnServices []metadata.CNService + refreshCalls int + refreshHook func() + phaseMu sync.Mutex + phases map[string]query.GetProtocolVersionResponse + frontiers map[string]timestamp.Timestamp + globalFrontier timestamp.Timestamp + phaseHook func(string) query.GetProtocolVersionResponse } func (c *ddlVisibilityTestCluster) GetCNService( @@ -170,7 +171,7 @@ func (*ddlVisibilityTestQueryClient) Close() error { return nil } func activationTestPeerProtocols() map[string]query.GetProtocolVersionResponse { return map[string]query.GetProtocolVersionResponse{ "peer:6001": { - Version: defines.MORPCVersion41, + Version: defines.MORPCVersion43, DDLVisibilityActivationPrepared: true, DDLVisibilityActivationFenced: true, }, @@ -202,6 +203,12 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) GetClusterDetails( if c.cluster != nil { c.cluster.phaseMu.Lock() defer c.cluster.phaseMu.Unlock() + details.DDLVisibilityFrontier = c.cluster.globalFrontier + for _, frontier := range c.cluster.frontiers { + if details.DDLVisibilityFrontier.Less(frontier) { + details.DDLVisibilityFrontier = frontier + } + } for _, cn := range c.cluster.cnServices { phase, ok := c.cluster.phases[cn.ServiceID] if c.cluster.phaseHook != nil && len(c.cluster.phases) > 0 { @@ -255,6 +262,9 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( c.cluster.frontiers = make(map[string]timestamp.Timestamp) } c.cluster.frontiers[hb.UUID] = hb.DDLVisibilityFrontier + if c.cluster.globalFrontier.Less(hb.DDLVisibilityFrontier) { + c.cluster.globalFrontier = hb.DDLVisibilityFrontier + } c.cluster.phaseMu.Unlock() } for i := range c.cluster.cnServices { @@ -263,7 +273,7 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( cn.ViewMetadataAdmissionGeneration = hb.ViewMetadataAdmissionGeneration cn.DDLVisibilityBarrierReady = hb.DDLVisibilityBarrierReady cn.ViewMetadataIngressReady = hb.ViewMetadataIngressReady - if c.clusterDeployedProtocol >= defines.MORPCVersion41 && + if c.clusterDeployedProtocol >= defines.MORPCVersion43 && hb.DDLVisibilityDeployedProtocol < c.clusterDeployedProtocol { cn.ViewMetadataIngressReady = false } @@ -417,6 +427,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { } ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().GetLatestCommitTS().Return(targetTS).AnyTimes() txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS.Next(), nil) txnClient.EXPECT().SyncLatestCommitTS(targetTS) @@ -428,7 +439,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { } // Persist with the old process, then construct a distinct service and load // through the production metadata initialization path. - require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion41)) + require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion43)) s := &service{ cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS, logger: zap.NewNop(), @@ -439,7 +450,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { ddlCommitGate: frontend.NewDDLCommitGate(), } require.NoError(t, s.initMetadata()) - require.Equal(t, defines.MORPCVersion41, s.metadata.DDLVisibilityDeployedProtocol) + require.Equal(t, defines.MORPCVersion43, s.metadata.DDLVisibilityDeployedProtocol) require.False(t, s.ddlVisibilityActivationComplete.Load()) require.NoError(t, s.prepareDDLVisibilityBarrier()) require.True(t, s.ddlVisibilityBarrierPrepared.Load()) @@ -454,13 +465,13 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.True(t, s.viewMetadataIngressReady.Load()) require.True(t, s.ddlCommitGate.PublicDDLEnabled()) } -func TestDefaultV41StartupUsesLastDeployedProtocolUntilActivation(t *testing.T) { - const serviceID = "ddl-visibility-default-v41-startup-protocol-test" +func TestDefaultV43StartupUsesLastDeployedProtocolUntilActivation(t *testing.T) { + const serviceID = "ddl-visibility-default-v43-startup-protocol-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) gate := frontend.NewDDLCommitGate() s := &service{cfg: &Config{UUID: serviceID}, ddlCommitGate: gate} @@ -519,11 +530,11 @@ func TestMarkerlessCNIngressHandshakeLinearizesWithCommittedCut(t *testing.T) { // The startup read precedes the cut, but the atomic ingress heartbeat lands // after it. HAKeeper must reject ingress and return the committed epoch. require.NoError(t, s.prepareDDLVisibilityBarrier()) - client.clusterDeployedProtocol = defines.MORPCVersion41 + client.clusterDeployedProtocol = defines.MORPCVersion43 require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) require.False(t, gate.PublicDDLEnabled()) @@ -537,7 +548,7 @@ func TestMarkerlessCNJoinsCommittedClusterFailClosed(t *testing.T) { s := &service{ cfg: &Config{UUID: serviceID}, ddlCommitGate: gate, config: util.NewConfigData(nil), _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{ - cluster: cluster, clusterDeployedProtocol: defines.MORPCVersion41, + cluster: cluster, clusterDeployedProtocol: defines.MORPCVersion43, }, } @@ -545,19 +556,19 @@ func TestMarkerlessCNJoinsCommittedClusterFailClosed(t *testing.T) { require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.False(t, s.ddlVisibilityActivationComplete.Load()) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, gate.PublicDDLEnabled()) } -func TestProvisionalV41RestartRemainsFailClosed(t *testing.T) { - const serviceID = "ddl-visibility-provisional-v41-restart-test" +func TestProvisionalV43RestartRemainsFailClosed(t *testing.T) { + const serviceID = "ddl-visibility-provisional-v43-restart-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) metadataFS := newDDLVisibilityMetadataFS(t) cfg := &Config{UUID: serviceID} writer := &service{cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS} - require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(-defines.MORPCVersion41)) + require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(-defines.MORPCVersion43)) gate := frontend.NewDDLCommitGate() restarted := &service{ @@ -569,7 +580,7 @@ func TestProvisionalV41RestartRemainsFailClosed(t *testing.T) { require.NoError(t, restarted.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.False(t, restarted.ddlVisibilityActivationComplete.Load()) require.False(t, restarted.viewMetadataIngressReady.Load()) require.False(t, gate.PublicDDLEnabled()) @@ -582,7 +593,7 @@ func TestPrepareDDLVisibilityBarrierRejectsMissingProductionDependencies(t *test cfg: &Config{UUID: serviceID}, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: newDDLVisibilityMetadataFS(t), viewMetadataAdmissionGeneration: 1, } - require.NoError(t, s.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion41)) + require.NoError(t, s.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion43)) err := s.prepareDDLVisibilityBarrier() require.ErrorContains(t, err, "dependencies are unavailable") @@ -615,7 +626,7 @@ func TestHandleSetProtocolVersionRejectsStaleRecoveryIdentity(t *testing.T) { } err := s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion41, DDLVisibilityActivationTargets: []string{serviceID}, + Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID}, DDLVisibilityTargetGeneration: generation + 1, DDLVisibilityTargetQueryAddress: "stale:6001", }, @@ -642,6 +653,7 @@ func TestActivationDoesNotPublishFencedBeforeProvisionalPersistence(t *testing.T frontiers: map[string]timestamp.Timestamp{"self:6001": {PhysicalTime: 100}}, } txnClient := mock_frontend.NewMockTxnClient(gomock.NewController(t)) + txnClient.EXPECT().GetLatestCommitTS().Return(timestamp.Timestamp{}) baseFS := newDDLVisibilityMetadataFS(t) metadataFS := &failReplaceMetadataFS{ReplaceableFileService: baseFS, failAt: 1} cfg := &Config{UUID: serviceID} @@ -658,7 +670,7 @@ func TestActivationDoesNotPublishFencedBeforeProvisionalPersistence(t *testing.T s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion41, []string{serviceID}) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion43, []string{serviceID}) require.ErrorContains(t, err, "injected metadata replace failure") require.True(t, s.ddlVisibilityActivationPrepared.Load()) require.False(t, s.ddlVisibilityActivationFenced.Load()) @@ -684,6 +696,7 @@ func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing frontiers: map[string]timestamp.Timestamp{"self:6001": targetTS}, } txnClient := mock_frontend.NewMockTxnClient(gomock.NewController(t)) + txnClient.EXPECT().GetLatestCommitTS().Return(targetTS) baseFS := newDDLVisibilityMetadataFS(t) metadataFS := &failReplaceMetadataFS{ReplaceableFileService: baseFS, failAt: 2} cfg := &Config{UUID: serviceID} @@ -700,15 +713,15 @@ func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion41, []string{serviceID}) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion43, []string{serviceID}) require.ErrorContains(t, err, "injected metadata replace failure") require.True(t, s.ddlVisibilityActivationFenced.Load()) require.False(t, s.ddlVisibilityActivationComplete.Load()) require.False(t, s.viewMetadataIngressReady.Load()) - require.Equal(t, -defines.MORPCVersion41, s.loadDDLVisibilityDeployedProtocol()) + require.Equal(t, -defines.MORPCVersion43, s.loadDDLVisibilityDeployedProtocol()) // A distinct process reloads the provisional marker through initMetadata and - // must remain a v41, non-routable producer until activation is retried. + // must remain a v43, non-routable producer until activation is retried. moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) restarted := &service{ cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: baseFS, @@ -719,7 +732,7 @@ func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing require.NoError(t, restarted.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.False(t, restarted.viewMetadataIngressReady.Load()) require.False(t, restarted.ddlCommitGate.PublicDDLEnabled()) } @@ -752,7 +765,7 @@ func TestActivationWithdrawalFailureStillBlocksNewDDL(t *testing.T) { s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion41, []string{serviceID}) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion43, []string{serviceID}) require.ErrorIs(t, err, withdrawErr) require.True(t, cluster.cnServices[0].ViewMetadataIngressReady, "the injected heartbeat failure leaves authoritative ingress unchanged") @@ -792,7 +805,7 @@ func TestActivationDrainTimeoutKeepsIngressWithdrawn(t *testing.T) { s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) - err = s.setProtocolVersion(context.Background(), defines.MORPCVersion41, []string{serviceID}) + err = s.setProtocolVersion(context.Background(), defines.MORPCVersion43, []string{serviceID}) require.Error(t, err) require.True(t, s.ddlVisibilityActivationPending.Load()) require.False(t, s.viewMetadataIngressReady.Load()) @@ -803,8 +816,8 @@ func TestActivationDrainTimeoutKeepsIngressWithdrawn(t *testing.T) { require.Error(t, err) } -func TestDefaultV41StillRunsCompleteTargetActivation(t *testing.T) { - const serviceID = "ddl-visibility-default-v41-activation-test" +func TestDefaultV43StillRunsCompleteTargetActivation(t *testing.T) { + const serviceID = "ddl-visibility-default-v43-activation-test" const generation = uint64(7) moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) targetTS := timestamp.Timestamp{PhysicalTime: 300, LogicalTime: 4} @@ -827,12 +840,13 @@ func TestDefaultV41StillRunsCompleteTargetActivation(t *testing.T) { "self:6001": {PhysicalTime: 100}, "peer:6001": targetTS, }, protocols: map[string]query.GetProtocolVersionResponse{"peer:6001": { - Version: defines.MORPCVersion41, + Version: defines.MORPCVersion43, DDLVisibilityActivationPrepared: true, DDLVisibilityActivationFenced: true, }}, } ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().GetLatestCommitTS().Return(targetTS).AnyTimes() txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS.Next(), nil) txnClient.EXPECT().SyncLatestCommitTS(targetTS) cfg := &Config{UUID: serviceID} @@ -853,9 +867,9 @@ func TestDefaultV41StillRunsCompleteTargetActivation(t *testing.T) { require.False(t, s.ddlVisibilityActivationComplete.Load()) require.NoError(t, s.setProtocolVersion( - context.Background(), defines.MORPCVersion41, []string{serviceID, "legacy-peer"})) + context.Background(), defines.MORPCVersion43, []string{serviceID, "legacy-peer"})) require.True(t, s.ddlVisibilityActivationComplete.Load()) - require.Equal(t, defines.MORPCVersion41, s.loadDDLVisibilityDeployedProtocol()) + require.Equal(t, defines.MORPCVersion43, s.loadDDLVisibilityDeployedProtocol()) require.True(t, s.viewMetadataIngressReady.Load()) require.True(t, s.ddlCommitGate.PublicDDLEnabled()) require.Empty(t, queryClient.requests) @@ -894,7 +908,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { } ready := peerReady.Load() return query.GetProtocolVersionResponse{ - Version: defines.MORPCVersion41, + Version: defines.MORPCVersion43, DDLVisibilityActivationPrepared: ready, DDLVisibilityActivationFenced: ready, } @@ -903,14 +917,15 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { cluster.phaseHook = queryClient.protocolFn ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().GetLatestCommitTS().Return(targetTS).AnyTimes() txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).DoAndReturn( func(context.Context, timestamp.Timestamp) (timestamp.Timestamp, error) { version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version, - "sender capability must be v41 after every local v34 DDL producer is drained") + require.Equal(t, defines.MORPCVersion43, version, + "sender capability must be v43 after every local v34 DDL producer is drained") require.True(t, cluster.cnServices[0].DDLVisibilityBarrierReady, - "the transitioning CN must remain reachable by v41 DDL fan-out") + "the transitioning CN must remain reachable by v43 DDL fan-out") require.False(t, cluster.cnServices[0].ViewMetadataIngressReady, "the transitioning CN must not accept new proxy sessions before the fence") return targetTS.Next(), nil @@ -936,7 +951,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { s.viewMetadataIngressReady.Store(true) req := &query.Request{SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion41, + Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", @@ -957,10 +972,10 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { releaseDDL, err := ddlCommitGate.Enter(context.Background()) require.NoError(t, err, "activation must release DDL producers after global convergence") releaseDDL() - require.Equal(t, defines.MORPCVersion41, resp.SetProtocolVersion.Version) + require.Equal(t, defines.MORPCVersion43, resp.SetProtocolVersion.Version) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.Empty(t, queryClient.requests) require.Empty(t, queryClient.methods) require.Zero(t, queryClient.releases) @@ -979,7 +994,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { // Repeating an already-active version must not withdraw or re-run the fence. resp = &query.Response{} require.NoError(t, s.handleSetProtocolVersion(context.Background(), req, resp, nil)) - require.Equal(t, defines.MORPCVersion41, resp.SetProtocolVersion.Version) + require.Equal(t, defines.MORPCVersion43, resp.SetProtocolVersion.Version) require.Len(t, hakeeperClient.heartbeats, 5) require.Equal(t, 2, cluster.refreshCalls) require.Empty(t, queryClient.requests) @@ -1006,9 +1021,11 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { cfg.HAKeeper.DiscoveryTimeout.Duration = time.Second cfg.HAKeeper.HeatbeatInterval.Duration = time.Millisecond hakeeperClient := &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster} + txnClient := mock_frontend.NewMockTxnClient(gomock.NewController(t)) + txnClient.EXPECT().GetLatestCommitTS().Return(timestamp.Timestamp{}).AnyTimes() s := &service{ cfg: cfg, _hakeeperClient: hakeeperClient, moCluster: cluster, - queryClient: queryClient, _txnClient: mock_frontend.NewMockTxnClient(gomock.NewController(t)), + queryClient: queryClient, _txnClient: txnClient, config: util.NewConfigData(nil), viewMetadataAdmissionGeneration: generation, ddlCommitGate: frontend.NewDDLCommitGate(), } @@ -1019,12 +1036,12 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { resp := &query.Response{} require.NoError(t, s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion41, + Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", }, }, resp, nil)) - require.Equal(t, defines.MORPCVersion41, resp.SetProtocolVersion.Version) + require.Equal(t, defines.MORPCVersion43, resp.SetProtocolVersion.Version) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) require.Len(t, hakeeperClient.heartbeats, 5) @@ -1059,7 +1076,7 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { <-allowPhase } return query.GetProtocolVersionResponse{ - Version: defines.MORPCVersion41, + Version: defines.MORPCVersion43, DDLVisibilityActivationPrepared: true, DDLVisibilityActivationFenced: true, } } @@ -1068,7 +1085,7 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { go func() { activationDone <- s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion41, + Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", }, @@ -1113,6 +1130,7 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T } ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().GetLatestCommitTS().Return(targetTS) syncErr := errors.New("logtail activation sync failed") txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(timestamp.Timestamp{}, syncErr) cfg := &Config{UUID: serviceID} @@ -1136,7 +1154,7 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T resp := &query.Response{} err := s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion41, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, + Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", }, }, resp, nil) @@ -1144,7 +1162,7 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T require.Nil(t, resp.SetProtocolVersion) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.True(t, s.ddlVisibilityActivationPending.Load()) require.True(t, s.ddlVisibilityActivationPrepared.Load()) require.False(t, s.ddlVisibilityActivationFenced.Load()) @@ -1184,6 +1202,7 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing } ctrl := gomock.NewController(t) txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().GetLatestCommitTS().Return(targetTS).AnyTimes() txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS.Next(), nil) txnClient.EXPECT().SyncLatestCommitTS(targetTS) cfg := &Config{UUID: serviceID} @@ -1209,14 +1228,14 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing err := s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion41, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, + Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", }, }, &query.Response{}, nil) require.ErrorIs(t, err, publishErr) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.True(t, s.ddlVisibilityActivationPending.Load()) require.True(t, s.ddlVisibilityActivationFenced.Load()) blockedCtx, cancelBlocked := context.WithCancel(context.Background()) @@ -1242,10 +1261,10 @@ func TestSetProtocolVersionBeforeBarrierPreparationDefersToStartupFence(t *testi moruntime.SetupServiceBasedRuntime(serviceID, rt) s := &service{cfg: &Config{UUID: serviceID}} - require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion41, nil)) + require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion43, nil)) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) require.False(t, s.ddlVisibilityBarrierPrepared.Load()) require.False(t, s.ddlVisibilityBarrierReady.Load()) } @@ -1287,7 +1306,7 @@ func TestInitQueryCommandHandlerOverridesProtocolActivation(t *testing.T) { require.True(t, ok) resp := &query.Response{} err := handler(context.Background(), &query.Request{ - SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion41}, + SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion43}, }, resp, nil) require.ErrorContains(t, err, "CN is closing") require.Nil(t, resp.SetProtocolVersion) @@ -1305,7 +1324,7 @@ func TestSetProtocolVersionRejectsActivationDuringClose(t *testing.T) { s.ddlVisibilityBarrierPrepared.Store(true) s.ddlVisibilityBarrierClosing.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion41, nil) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion43, nil) require.ErrorContains(t, err, "CN is closing") version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) @@ -1344,7 +1363,7 @@ func TestValidateDDLVisibilityActivationTargets(t *testing.T) { func TestSetProtocolVersionDowngradeGuards(t *testing.T) { const serviceID = "ddl-visibility-downgrade-test" rt := moruntime.DefaultRuntime() - rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion41) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion43) moruntime.SetupServiceBasedRuntime(serviceID, rt) s := &service{cfg: &Config{UUID: serviceID}} s.ddlVisibilityBarrierPrepared.Store(true) @@ -1356,11 +1375,11 @@ func TestSetProtocolVersionDowngradeGuards(t *testing.T) { require.ErrorContains(t, err, "cannot downgrade after the DDL visibility cluster epoch is committed") version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion41, version) + require.Equal(t, defines.MORPCVersion43, version) s.ddlVisibilityActivationComplete.Store(false) s._hakeeperClient = &ddlVisibilityWithdrawalHAKeeperClient{ - clusterDeployedProtocol: defines.MORPCVersion41, + clusterDeployedProtocol: defines.MORPCVersion43, } rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) err = s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil) @@ -1564,6 +1583,28 @@ func TestWaitForDDLVisibilityBarrierWithdrawalHonorsCancellation(t *testing.T) { require.Equal(t, 1, cluster.refreshCalls) } +func TestSyncStartupDDLVisibilityFrontierSurvivesProducerReplacement(t *testing.T) { + const serviceID = "ddl-visibility-durable-frontier-test" + oldFrontier := timestamp.Timestamp{PhysicalTime: 300} + cluster := &ddlVisibilityTestCluster{ + cnServices: []metadata.CNService{{ + ServiceID: "replaced-producer", QueryAddress: "new:6001", + ViewMetadataAdmissionGeneration: 2, DDLVisibilityBarrierReady: true, + }}, + globalFrontier: oldFrontier, + } + ctrl := gomock.NewController(t) + txnClient := mock_frontend.NewMockTxnClient(ctrl) + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), oldFrontier).Return(oldFrontier, nil) + txnClient.EXPECT().SyncLatestCommitTS(oldFrontier) + s := &service{ + cfg: &Config{UUID: serviceID}, _txnClient: txnClient, + _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster}, + } + + require.NoError(t, s.syncStartupDDLVisibilityFrontier(context.Background())) +} + func TestSyncStartupDDLVisibilityFrontierAllowsEmptyFrontier(t *testing.T) { const serviceID = "ddl-visibility-empty-frontier-test" cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 391b37a37a1f7..4cecfba8e8502 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -218,7 +218,7 @@ func (s *service) newCNStoreHeartbeat() logservicepb.CNStoreHeartbeat { if s.ddlCommitGate != nil { hb.DDLVisibilityFrontier = s.ddlCommitGate.LatestDDLFrontier() } - if deployed := s.loadDDLVisibilityDeployedProtocol(); deployed >= defines.MORPCVersion41 { + if deployed := s.loadDDLVisibilityDeployedProtocol(); deployed >= defines.MORPCVersion43 { hb.DDLVisibilityDeployedProtocol = deployed } if s.viewMetadataEpochFence != nil { diff --git a/pkg/cnservice/server_query.go b/pkg/cnservice/server_query.go index 7f69eba0aa484..f86554064d4f9 100644 --- a/pkg/cnservice/server_query.go +++ b/pkg/cnservice/server_query.go @@ -245,7 +245,7 @@ func (s *service) handleSetProtocolVersion( return moerr.NewInternalError(ctx, "bad request") } version := req.SetProtocolVersion.Version - if version >= defines.MORPCVersion41 && + if version >= defines.MORPCVersion43 && len(req.SetProtocolVersion.DDLVisibilityActivationTargets) > 0 { expectedGeneration := req.SetProtocolVersion.DDLVisibilityTargetGeneration expectedAddress := req.SetProtocolVersion.DDLVisibilityTargetQueryAddress diff --git a/pkg/defines/const.go b/pkg/defines/const.go index 8574a5fd3fdc8..94e7b0bcf957e 100644 --- a/pkg/defines/const.go +++ b/pkg/defines/const.go @@ -35,49 +35,51 @@ const ( ) const ( - MORPCMinVersion int64 = math.MinInt64 - MORPCVersion1 int64 = 1 - MORPCVersion2 int64 = 2 - MORPCVersion3 int64 = 3 // start from 1.3.0 - MORPCVersion4 int64 = 4 // start from 2.0.1 - MORPCVersion5 int64 = 5 // assignment-aware CHAR/VARCHAR casts - MORPCVersion6 int64 = 6 // ordered aggregate pipeline configuration - MORPCVersion7 int64 = 7 // structured CHECK constraint metadata and enforcement - MORPCVersion8 int64 = 8 // versioned exact runtime-filter key contract - MORPCVersion9 int64 = 9 // AUTO_INCREMENT epoch-fenced commit - MORPCVersion10 int64 = 10 // bounded Sorted64 membership-filter wire format - MORPCVersion11 int64 = 11 // persisted appendable-object abort metadata - MORPCVersion12 int64 = 12 // prepared-parameter provenance in remote process metadata and aggregate trailers - MORPCVersion13 int64 = 13 // lossless v2 prefix-index metadata - MORPCVersion14 int64 = 14 // utf8mb4 text MIN/MAX collation semantics - MORPCVersion15 int64 = 15 // CHECK metadata in rename-column alter requests - MORPCVersion16 int64 = 16 // information_schema CHECK_CONSTRAINTS table function - MORPCVersion17 int64 = 17 // ordered-set percentile aggregate IDs - MORPCVersion18 int64 = 18 // prepared-parameter binary-string metadata - MORPCVersion19 int64 = 19 // remote bounded partition Top-N operator - MORPCVersion20 int64 = 20 // target-aware multi-table UPDATE pipeline fields - MORPCVersion21 int64 = 21 // lookup-only RIGHT DEDUP for proven-unique insert input - MORPCVersion22 int64 = 22 // typed user-defined variable migration - MORPCVersion23 int64 = 23 // explicit-text runtime string provenance - MORPCVersion24 int64 = 24 // per-target affected-row selectors for repeated physical UPDATE targets - MORPCVersion25 int64 = 25 // UPDATE changed-row counting - MORPCVersion26 int64 = 26 // statement LAST_INSERT_ID in remote terminal results - MORPCVersion27 int64 = 27 // native ASOF join pipeline fields and semantics - MORPCVersion28 int64 = 28 // owner-local lock snapshots and table-scoped remote unlock - MORPCVersion29 int64 = 29 // FOUND_ROWS connection migration state - MORPCVersion30 int64 = 30 // prepared numeric-prefix common-type casts - MORPCVersion31 int64 = 31 // batched multi-table remote transaction unlock - MORPCVersion32 int64 = 32 // cross-transaction logical-plan generation snapshot - MORPCVersion33 int64 = 33 // stable complete-key distributed string shuffle hash - MORPCVersion34 int64 = 34 // correct persisted unsigned-column metadata - MORPCVersion35 int64 = 35 // scaled variance state with exact numeric origins - MORPCVersion36 int64 = 36 // prepared JSON comparison execution and exact parameter types - MORPCVersion37 int64 = 37 // independent prepared-parameter string source - MORPCVersion38 int64 = 38 // session temporary-table connection migration - MORPCVersion39 int64 = 39 // linearizable TN-ordered logtail read barrier - MORPCVersion40 int64 = 40 // PAD SPACE comparison casts and set-operation equality keys - MORPCVersion41 int64 = 41 // cancellable cross-CN DDL visibility fence - MORPCLatestVersion = MORPCVersion41 + MORPCMinVersion int64 = math.MinInt64 + MORPCVersion1 int64 = 1 + MORPCVersion2 int64 = 2 + MORPCVersion3 int64 = 3 // start from 1.3.0 + MORPCVersion4 int64 = 4 // start from 2.0.1 + MORPCVersion5 int64 = 5 // assignment-aware CHAR/VARCHAR casts + MORPCVersion6 int64 = 6 // ordered aggregate pipeline configuration + MORPCVersion7 int64 = 7 // structured CHECK constraint metadata and enforcement + MORPCVersion8 int64 = 8 // versioned exact runtime-filter key contract + MORPCVersion9 int64 = 9 // AUTO_INCREMENT epoch-fenced commit + MORPCVersion10 int64 = 10 // bounded Sorted64 membership-filter wire format + MORPCVersion11 int64 = 11 // persisted appendable-object abort metadata + MORPCVersion12 int64 = 12 // prepared-parameter provenance in remote process metadata and aggregate trailers + MORPCVersion13 int64 = 13 // lossless v2 prefix-index metadata + MORPCVersion14 int64 = 14 // utf8mb4 text MIN/MAX collation semantics + MORPCVersion15 int64 = 15 // CHECK metadata in rename-column alter requests + MORPCVersion16 int64 = 16 // information_schema CHECK_CONSTRAINTS table function + MORPCVersion17 int64 = 17 // ordered-set percentile aggregate IDs + MORPCVersion18 int64 = 18 // prepared-parameter binary-string metadata + MORPCVersion19 int64 = 19 // remote bounded partition Top-N operator + MORPCVersion20 int64 = 20 // target-aware multi-table UPDATE pipeline fields + MORPCVersion21 int64 = 21 // lookup-only RIGHT DEDUP for proven-unique insert input + MORPCVersion22 int64 = 22 // typed user-defined variable migration + MORPCVersion23 int64 = 23 // explicit-text runtime string provenance + MORPCVersion24 int64 = 24 // per-target affected-row selectors for repeated physical UPDATE targets + MORPCVersion25 int64 = 25 // UPDATE changed-row counting + MORPCVersion26 int64 = 26 // statement LAST_INSERT_ID in remote terminal results + MORPCVersion27 int64 = 27 // native ASOF join pipeline fields and semantics + MORPCVersion28 int64 = 28 // owner-local lock snapshots and table-scoped remote unlock + MORPCVersion29 int64 = 29 // FOUND_ROWS connection migration state + MORPCVersion30 int64 = 30 // prepared numeric-prefix common-type casts + MORPCVersion31 int64 = 31 // batched multi-table remote transaction unlock + MORPCVersion32 int64 = 32 // cross-transaction logical-plan generation snapshot + MORPCVersion33 int64 = 33 // stable complete-key distributed string shuffle hash + MORPCVersion34 int64 = 34 // correct persisted unsigned-column metadata + MORPCVersion35 int64 = 35 // scaled variance state with exact numeric origins + MORPCVersion36 int64 = 36 // prepared JSON comparison execution and exact parameter types + MORPCVersion37 int64 = 37 // independent prepared-parameter string source + MORPCVersion38 int64 = 38 // session temporary-table connection migration + MORPCVersion39 int64 = 39 // linearizable TN-ordered logtail read barrier + MORPCVersion40 int64 = 40 // PAD SPACE comparison casts and set-operation equality keys + // Versions 41 and 42 are reserved for the two concurrent MORPC owners that + // were already under review when this capability was allocated. + MORPCVersion43 int64 = 43 // cancellable cross-CN DDL visibility fence + MORPCLatestVersion = MORPCVersion43 ) // DefaultLockWaitTimeoutSeconds is shared by the frontend default and by diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index db09c40da0f5f..425de819fdee4 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -1073,7 +1073,7 @@ type ddlVisibilityTarget struct { // DDL sender refreshes membership again after fan-out and repeats if any ready // generation changed. A failed target is retried only after authoritative // revalidation proves that exact generation/address tuple has departed. -// Protocol v41 is a deployment gate: mixed-version +// Protocol v43 is a deployment gate: mixed-version // clusters retain legacy behavior without invoking an old receiver's fatal // SyncCommit path. func syncDDLCommitToBarrierReadyCNs( @@ -1089,7 +1089,7 @@ func syncDDLCommitToBarrierReadyCNs( qc := pu.QueryClient protocol, ok := moruntime.ServiceRuntime(qc.ServiceID()).GetGlobalVariables(moruntime.MOProtocolVersion) protocolVersion, valid := protocol.(int64) - if !ok || !valid || protocolVersion < defines.MORPCVersion41 { + if !ok || !valid || protocolVersion < defines.MORPCVersion43 { return nil } cluster := clusterservice.GetMOCluster(qc.ServiceID()) diff --git a/pkg/hakeeper/rsm.go b/pkg/hakeeper/rsm.go index 2505faae693ea..5c685d6c998fc 100644 --- a/pkg/hakeeper/rsm.go +++ b/pkg/hakeeper/rsm.go @@ -1710,6 +1710,7 @@ func (s *stateMachine) handleClusterDetailsQuery(cfg Config) *pb.ClusterDetails LogStores: make([]pb.LogStore, 0, len(s.state.LogState.Stores)), ProxyStores: make([]pb.ProxyStore, 0, len(s.state.ProxyState.Stores)), DDLVisibilityDeployedProtocol: s.state.CNState.DDLVisibilityDeployedProtocol, + DDLVisibilityFrontier: s.state.CNState.DDLVisibilityFrontier, } if s.viewMetadataAdmissionActive() { cd.ViewMetadataAdmission = &pb.ViewMetadataAdmission{ diff --git a/pkg/pb/logservice/logservice.go b/pkg/pb/logservice/logservice.go index 99a693f2c7a27..d613df4b70d67 100644 --- a/pkg/pb/logservice/logservice.go +++ b/pkg/pb/logservice/logservice.go @@ -175,6 +175,9 @@ func (s *CNState) Update(hb CNStoreHeartbeat, tick uint64) { storeInfo.DDLVisibilityActivationFenced = hb.DDLVisibilityActivationFenced storeInfo.DDLVisibilityFrontier = hb.DDLVisibilityFrontier s.Stores[hb.UUID] = storeInfo + if s.DDLVisibilityFrontier.Less(hb.DDLVisibilityFrontier) { + s.DDLVisibilityFrontier = hb.DDLVisibilityFrontier + } if hb.DDLVisibilityDeployedProtocol > s.DDLVisibilityDeployedProtocol && len(hb.DDLVisibilityEpochCommitTargets) > 0 && s.matchesDDLVisibilityEpochCommitTargets(hb.DDLVisibilityEpochCommitTargets) { diff --git a/pkg/pb/logservice/logservice.pb.go b/pkg/pb/logservice/logservice.pb.go index 292aaf1ec4b91..385582e1b4d66 100644 --- a/pkg/pb/logservice/logservice.pb.go +++ b/pkg/pb/logservice/logservice.pb.go @@ -4487,10 +4487,13 @@ type CNState struct { // DDLVisibilityDeployedProtocol is a monotonic cluster deployment epoch. // Once a complete-target cut commits, markerless replacement/scale-out CNs // must join that fence instead of reopening on an older protocol. - DDLVisibilityDeployedProtocol int64 `protobuf:"varint,2,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,2,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + // DDLVisibilityFrontier is the monotonic cluster-lifetime maximum committed + // DDL timestamp. It survives CN restart, replacement, and store removal. + DDLVisibilityFrontier timestamp.Timestamp `protobuf:"bytes,3,opt,name=DDLVisibilityFrontier,proto3" json:"DDLVisibilityFrontier"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CNState) Reset() { *m = CNState{} } @@ -4540,6 +4543,13 @@ func (m *CNState) GetDDLVisibilityDeployedProtocol() int64 { return 0 } +func (m *CNState) GetDDLVisibilityFrontier() timestamp.Timestamp { + if m != nil { + return m.DDLVisibilityFrontier + } + return timestamp.Timestamp{} +} + // TNStoreInfo contains information on a TN store. type TNStoreInfo struct { Tick uint64 `protobuf:"varint,1,opt,name=Tick,proto3" json:"Tick,omitempty"` @@ -4976,6 +4986,7 @@ type ClusterDetails struct { DeletedStores []DeletedStore `protobuf:"bytes,5,rep,name=DeletedStores,proto3" json:"DeletedStores"` ViewMetadataAdmission *ViewMetadataAdmission `protobuf:"bytes,6,opt,name=ViewMetadataAdmission,proto3" json:"ViewMetadataAdmission,omitempty"` DDLVisibilityDeployedProtocol int64 `protobuf:"varint,7,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + DDLVisibilityFrontier timestamp.Timestamp `protobuf:"bytes,8,opt,name=DDLVisibilityFrontier,proto3" json:"DDLVisibilityFrontier"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -5063,6 +5074,13 @@ func (m *ClusterDetails) GetDDLVisibilityDeployedProtocol() int64 { return 0 } +func (m *ClusterDetails) GetDDLVisibilityFrontier() timestamp.Timestamp { + if m != nil { + return m.DDLVisibilityFrontier + } + return timestamp.Timestamp{} +} + // ClusterInfo provides a global view of all shards in the cluster. It // describes the logical sharding of the system, rather than physical // distribution of all replicas that belong to those shards. @@ -6730,395 +6748,395 @@ func init() { func init() { proto.RegisterFile("logservice.proto", fileDescriptor_fd1040c5381ab5a7) } var fileDescriptor_fd1040c5381ab5a7 = []byte{ - // 6194 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xdb, 0x6f, 0x1b, 0xd9, - 0x79, 0xb8, 0x87, 0xa4, 0x24, 0xea, 0xa3, 0x24, 0x8f, 0x8e, 0x2e, 0xa6, 0x65, 0x5b, 0xd6, 0x72, - 0x9d, 0x5d, 0xaf, 0xb2, 0x91, 0xf3, 0xb3, 0xb3, 0x8b, 0x4d, 0x7e, 0x8e, 0x77, 0x29, 0x92, 0xb6, - 0x68, 0xd3, 0x94, 0x76, 0x38, 0xf2, 0x26, 0x01, 0x16, 0xc2, 0x88, 0x3c, 0x96, 0x27, 0xa2, 0x38, - 0xcc, 0xcc, 0xc8, 0x97, 0xf6, 0xa9, 0x45, 0x53, 0x14, 0x0d, 0x5a, 0x34, 0x40, 0xd0, 0x06, 0x6d, - 0xd3, 0xdb, 0x5b, 0x9f, 0xf2, 0xd2, 0xff, 0xa0, 0x40, 0x91, 0x87, 0xa2, 0x48, 0xf3, 0x58, 0xa0, - 0xb9, 0x6c, 0x5f, 0x0a, 0xe4, 0xa5, 0x4f, 0xcd, 0x53, 0x80, 0xe2, 0xdc, 0x66, 0xce, 0x99, 0x0b, - 0x87, 0xba, 0x24, 0x4d, 0x8a, 0x3c, 0x89, 0xe7, 0x9c, 0xef, 0x3b, 0xd7, 0xef, 0x7e, 0xbe, 0x33, - 0x02, 0xbd, 0xef, 0x1c, 0x78, 0xd8, 0x7d, 0x6e, 0x77, 0xf1, 0xc6, 0xd0, 0x75, 0x7c, 0x07, 0x41, - 0x58, 0xb3, 0xf2, 0x99, 0x03, 0xdb, 0x7f, 0x76, 0xbc, 0xbf, 0xd1, 0x75, 0x8e, 0x6e, 0x1d, 0x38, - 0x07, 0xce, 0x2d, 0x0a, 0xb2, 0x7f, 0xfc, 0x94, 0x96, 0x68, 0x81, 0xfe, 0x62, 0xa8, 0x2b, 0xd7, - 0x0f, 0x1c, 0xe7, 0xa0, 0x8f, 0x43, 0x28, 0xdf, 0x3e, 0xc2, 0x9e, 0x6f, 0x1d, 0x0d, 0x39, 0xc0, - 0xdc, 0x11, 0xf6, 0xad, 0x9e, 0xe5, 0x5b, 0xbc, 0x7c, 0x31, 0x02, 0x50, 0xf9, 0x2f, 0x80, 0xa9, - 0x5a, 0xbb, 0xe3, 0x3b, 0x2e, 0x46, 0x08, 0x0a, 0xbb, 0xbb, 0xcd, 0x7a, 0x59, 0x5b, 0xd3, 0x6e, - 0x4e, 0x1b, 0xf4, 0x37, 0x7a, 0x03, 0xe6, 0x3a, 0x6c, 0x6e, 0xd5, 0x5e, 0xcf, 0xc5, 0x9e, 0x57, - 0xce, 0xd1, 0xd6, 0x48, 0x2d, 0x5a, 0x05, 0xe8, 0x7c, 0xd8, 0x12, 0x30, 0x79, 0x0a, 0x23, 0xd5, - 0xa0, 0x0d, 0x40, 0x2d, 0xa7, 0x7b, 0x18, 0xe9, 0xab, 0x40, 0xe1, 0x12, 0x5a, 0xd0, 0x0d, 0x28, - 0x18, 0x4e, 0x1f, 0x97, 0x27, 0xd7, 0xb4, 0x9b, 0x73, 0xb7, 0xf5, 0x8d, 0x60, 0x1d, 0xb5, 0x36, - 0xa9, 0x37, 0x68, 0x2b, 0x99, 0xb1, 0x69, 0x77, 0x0f, 0xcb, 0x53, 0x6b, 0xda, 0xcd, 0x82, 0x41, - 0x7f, 0xa3, 0x4f, 0xc3, 0x44, 0xc7, 0xb7, 0x7c, 0x5c, 0x2e, 0x52, 0xd4, 0xa5, 0x0d, 0x69, 0xc3, - 0xdb, 0x4e, 0x0f, 0xd3, 0x46, 0x83, 0xc1, 0xa0, 0x2f, 0xc2, 0x64, 0xcb, 0xda, 0xc7, 0x7d, 0xaf, - 0x3c, 0xbd, 0x96, 0xbf, 0x59, 0xba, 0x7d, 0x5d, 0x86, 0xe6, 0xfb, 0xb2, 0xc1, 0x20, 0x1a, 0x03, - 0xdf, 0x7d, 0xb5, 0x59, 0xf8, 0xde, 0x0f, 0xaf, 0x5f, 0x30, 0x38, 0x12, 0xfa, 0x7f, 0x30, 0xfd, - 0x91, 0xe3, 0x1e, 0xb2, 0xf1, 0x80, 0x8e, 0xb7, 0x10, 0x4e, 0x35, 0x68, 0x32, 0x42, 0x28, 0x54, - 0x81, 0x99, 0x0f, 0x8f, 0xb1, 0xfb, 0x4a, 0x6c, 0x41, 0x89, 0x6e, 0x81, 0x52, 0x87, 0xde, 0x05, - 0xa8, 0x39, 0x83, 0xa7, 0xf6, 0x41, 0xdd, 0xf2, 0xad, 0xf2, 0xcc, 0x9a, 0x76, 0xb3, 0x74, 0x7b, - 0x59, 0x99, 0x59, 0xd0, 0x6a, 0x48, 0x90, 0xe8, 0x5d, 0x28, 0x1a, 0xd8, 0x73, 0x8e, 0xdd, 0x2e, - 0x2e, 0xcf, 0x52, 0xac, 0x45, 0x19, 0x4b, 0xb4, 0xf1, 0x45, 0x04, 0xb0, 0x68, 0x19, 0x26, 0x77, - 0x87, 0xa6, 0x7d, 0x84, 0xcb, 0x73, 0x6b, 0xda, 0xcd, 0xbc, 0xc1, 0x4b, 0xe8, 0xb3, 0xb0, 0xd0, - 0x79, 0x66, 0xb9, 0xbd, 0xc8, 0xa9, 0x5d, 0xa4, 0x53, 0x4e, 0x6a, 0x42, 0x2b, 0x50, 0xac, 0x39, - 0x47, 0x47, 0xb6, 0xdf, 0xac, 0x97, 0x75, 0x0a, 0x16, 0x94, 0xd1, 0x7d, 0x58, 0x7d, 0x62, 0xe3, - 0x17, 0x8f, 0xf9, 0xf6, 0x54, 0x7b, 0x47, 0xb6, 0xe7, 0xd9, 0xce, 0xa0, 0x73, 0x3c, 0x1c, 0x3a, - 0xae, 0x8f, 0x7b, 0xe5, 0xf9, 0x35, 0xed, 0x66, 0xd1, 0xc8, 0x80, 0x42, 0x5b, 0x70, 0x3d, 0x11, - 0xe2, 0x01, 0x1e, 0x60, 0xd7, 0xf2, 0x6d, 0x67, 0x50, 0x46, 0x94, 0x1e, 0xb2, 0xc0, 0xd0, 0x5d, - 0xb8, 0x2c, 0x83, 0x6c, 0xef, 0x93, 0x9d, 0xc2, 0xbd, 0xc6, 0xd0, 0xe9, 0x3e, 0x2b, 0x2f, 0xd0, - 0x3e, 0xd2, 0x01, 0xd0, 0x3d, 0x58, 0x49, 0x1c, 0xc0, 0xc0, 0x56, 0xef, 0x55, 0x79, 0x91, 0xae, - 0x65, 0x04, 0x04, 0x19, 0xbd, 0x5e, 0x6f, 0x3d, 0xb1, 0x3d, 0x7b, 0xdf, 0xee, 0xdb, 0xfe, 0xab, - 0x4d, 0xcb, 0x75, 0x6d, 0xec, 0x32, 0xf4, 0x25, 0x8a, 0x9e, 0x0e, 0x80, 0xbe, 0x00, 0x65, 0xb9, - 0xef, 0xe6, 0xe0, 0x80, 0x1c, 0x00, 0x43, 0x5e, 0xa6, 0xc8, 0xa9, 0xed, 0xa8, 0x0e, 0xd7, 0x94, - 0x8e, 0xeb, 0x78, 0xd8, 0x77, 0x5e, 0xe1, 0xde, 0x0e, 0x11, 0x09, 0x5d, 0xa7, 0x5f, 0xbe, 0x44, - 0xc9, 0x60, 0x34, 0x10, 0x39, 0x07, 0x05, 0xa0, 0xda, 0xf5, 0xed, 0xe7, 0x74, 0x63, 0x77, 0x5c, - 0x3c, 0xb4, 0x5c, 0xdc, 0x2b, 0x97, 0xe9, 0x44, 0xb2, 0xc0, 0x62, 0xf3, 0x09, 0x41, 0xee, 0xe3, - 0x41, 0x17, 0xf7, 0xca, 0x97, 0x69, 0x3f, 0xa3, 0x81, 0xd0, 0x0e, 0x2c, 0x29, 0x00, 0xf7, 0x5d, - 0x67, 0xe0, 0xdb, 0xd8, 0x2d, 0xaf, 0x70, 0x56, 0x08, 0x65, 0x9f, 0x29, 0x7e, 0x71, 0x56, 0x48, - 0x46, 0x5c, 0x69, 0x43, 0x49, 0xe2, 0x7d, 0xa4, 0x43, 0xfe, 0x10, 0xbf, 0xe2, 0xe2, 0x91, 0xfc, - 0x44, 0x6f, 0xc1, 0xc4, 0x73, 0xab, 0x7f, 0x8c, 0xa9, 0x50, 0x2c, 0xc9, 0xbc, 0x4f, 0xf1, 0x5a, - 0xb6, 0xe7, 0x1b, 0x0c, 0xe2, 0x0b, 0xb9, 0xf7, 0xb4, 0x87, 0x85, 0xe2, 0x84, 0x3e, 0x59, 0xf9, - 0x59, 0x1e, 0xa6, 0xcc, 0x73, 0x10, 0xb9, 0x42, 0xf8, 0xe5, 0x93, 0x84, 0x5f, 0x61, 0x0c, 0xe1, - 0xf7, 0x0e, 0x4c, 0x52, 0x1e, 0xf6, 0xca, 0x13, 0x54, 0xf8, 0x5d, 0x92, 0xa1, 0xcd, 0x36, 0x6d, - 0x6b, 0x0e, 0x9e, 0x3a, 0x42, 0xe8, 0x31, 0x60, 0x74, 0x1b, 0x16, 0x5b, 0xce, 0x81, 0x6f, 0xd9, - 0x7d, 0x32, 0x21, 0xec, 0x8a, 0x59, 0x4e, 0xd2, 0x59, 0x26, 0xb6, 0xa5, 0x88, 0xff, 0xa9, 0x54, - 0xf1, 0xaf, 0x4a, 0xc0, 0xe9, 0xb1, 0x25, 0x60, 0x54, 0xba, 0x42, 0x82, 0x74, 0x4d, 0x91, 0x6a, - 0xa5, 0x74, 0xa9, 0xf6, 0x01, 0x5c, 0xa9, 0x1e, 0xfb, 0x4e, 0x73, 0xd0, 0x75, 0x29, 0xeb, 0x53, - 0x82, 0x0b, 0xc5, 0xd6, 0x0c, 0xa5, 0xce, 0x51, 0x20, 0x0f, 0x0b, 0xc5, 0xa2, 0x3e, 0x5d, 0xf9, - 0xa3, 0x3c, 0x14, 0x5b, 0xce, 0xc1, 0xaf, 0xc0, 0xd1, 0xdf, 0x25, 0x9a, 0x62, 0xd8, 0xb7, 0xbb, - 0x96, 0x38, 0xfc, 0x15, 0x19, 0xbe, 0xe5, 0x1c, 0xf0, 0x66, 0xe9, 0xfc, 0x03, 0x8c, 0xc8, 0xe9, - 0x4c, 0x9e, 0x44, 0x3f, 0xb5, 0x9c, 0xae, 0x45, 0x78, 0x8c, 0x9e, 0x7d, 0x44, 0x3f, 0x89, 0x36, - 0x31, 0x9e, 0x28, 0xa3, 0x27, 0xf0, 0xc6, 0x48, 0x51, 0x14, 0x1e, 0x45, 0x91, 0x1e, 0xc5, 0x98, - 0xd0, 0x95, 0x6f, 0xe5, 0x61, 0x86, 0x9c, 0x87, 0x20, 0x74, 0x54, 0x86, 0x29, 0x56, 0x60, 0xc7, - 0x52, 0x30, 0x44, 0x11, 0x6d, 0x4a, 0x1b, 0x96, 0xa3, 0x1b, 0xf6, 0x46, 0x64, 0xc3, 0x82, 0x5e, - 0x36, 0x04, 0x20, 0x95, 0x1a, 0xd2, 0xb6, 0x2d, 0xc2, 0x04, 0x53, 0x2d, 0xec, 0xd8, 0x58, 0x81, - 0xa8, 0xcc, 0x16, 0xb6, 0x7a, 0xd8, 0x6d, 0xd6, 0xe9, 0xd1, 0x15, 0x8c, 0xa0, 0x4c, 0xcf, 0x19, - 0xbb, 0x47, 0xe5, 0x09, 0x7e, 0xce, 0xd8, 0x3d, 0x42, 0x1f, 0xc3, 0x7c, 0xdb, 0x19, 0x3c, 0x71, - 0x7c, 0x7b, 0x70, 0x10, 0x4c, 0x69, 0x92, 0x4e, 0xe9, 0x56, 0xea, 0x94, 0x62, 0x18, 0x6c, 0x6e, - 0xf1, 0x9e, 0x56, 0xfe, 0x3f, 0xcc, 0x2a, 0x30, 0xb2, 0xd4, 0x2b, 0x30, 0xa9, 0xb7, 0x28, 0x4b, - 0xbd, 0x69, 0x49, 0xc0, 0xad, 0xd4, 0x61, 0x39, 0x79, 0xa4, 0x93, 0xf4, 0x52, 0xf9, 0xb6, 0x06, - 0x73, 0x2a, 0x05, 0xa2, 0xfb, 0xea, 0x41, 0xd1, 0x7e, 0x4a, 0xb7, 0xcb, 0x69, 0xeb, 0xdd, 0x2c, - 0x12, 0x0a, 0xfa, 0xfe, 0x0f, 0xaf, 0x6b, 0x86, 0x7a, 0xc0, 0x57, 0x61, 0x5a, 0x74, 0x5b, 0xa7, - 0x03, 0x17, 0x8c, 0xb0, 0x02, 0xad, 0x41, 0xa9, 0xe9, 0x05, 0x0b, 0xa0, 0xc7, 0x54, 0x34, 0xe4, - 0xaa, 0xca, 0x1f, 0x6a, 0xa1, 0x89, 0x45, 0x8d, 0x9d, 0x9d, 0x5d, 0xd3, 0xf1, 0xad, 0x3e, 0x5f, - 0x58, 0x50, 0x26, 0x82, 0xa8, 0xb6, 0xb3, 0x5b, 0x7d, 0x6e, 0xd9, 0x7d, 0x6b, 0xbf, 0xcf, 0x16, - 0xa9, 0x19, 0x4a, 0x1d, 0xc1, 0x7f, 0x8c, 0x8f, 0x18, 0x3e, 0x23, 0x89, 0xa0, 0x4c, 0xf0, 0x1f, - 0xe3, 0xa3, 0x10, 0x9f, 0x51, 0x86, 0x52, 0x57, 0xf9, 0x1d, 0x2d, 0x55, 0x6f, 0x9a, 0x96, 0x7b, - 0x80, 0x7d, 0xb2, 0x5c, 0x2e, 0x39, 0x02, 0x41, 0x13, 0x56, 0x10, 0x9b, 0x5d, 0xb2, 0x99, 0xd8, - 0x6e, 0x48, 0x35, 0x31, 0x61, 0x9a, 0x8f, 0x0b, 0xd3, 0xca, 0xcf, 0x67, 0x40, 0xe7, 0x76, 0xf2, - 0x16, 0xb6, 0x5c, 0x7f, 0x1f, 0x5b, 0xfe, 0xaf, 0xa1, 0x23, 0xb1, 0x01, 0xc8, 0xb4, 0x3c, 0x81, - 0x5b, 0x73, 0xb1, 0x45, 0xa4, 0xc9, 0x14, 0x25, 0x80, 0x84, 0x96, 0xd8, 0xd6, 0x14, 0x13, 0xf4, - 0xcc, 0x0d, 0x98, 0x6d, 0x0e, 0x6c, 0x3f, 0x74, 0x10, 0xa6, 0x29, 0x90, 0x5a, 0x49, 0xa0, 0x1e, - 0x38, 0x9e, 0x67, 0x0f, 0x55, 0x95, 0xa5, 0x56, 0x92, 0xf1, 0x58, 0xc5, 0x43, 0xc7, 0x1e, 0xe0, - 0x1e, 0x55, 0x56, 0x45, 0x43, 0xa9, 0xfb, 0xa5, 0x7b, 0x0d, 0x29, 0x7a, 0x74, 0x6e, 0x3c, 0xef, - 0xe0, 0x62, 0xc4, 0x3b, 0xf8, 0x2c, 0x2c, 0x54, 0xbb, 0x87, 0xb8, 0x47, 0x2a, 0xac, 0x41, 0x6f, - 0xd3, 0xf2, 0xbb, 0xcf, 0xb8, 0x13, 0x51, 0x30, 0x92, 0x9a, 0x88, 0x56, 0xe6, 0x35, 0x75, 0xdc, - 0xb7, 0x9f, 0x93, 0x9d, 0xef, 0x1e, 0x46, 0x9d, 0x89, 0x51, 0x20, 0x63, 0x78, 0x24, 0xe8, 0xbc, - 0x3c, 0x92, 0x85, 0x73, 0xf0, 0x48, 0x16, 0xb3, 0x3c, 0x92, 0xc8, 0x7a, 0x6a, 0x96, 0x6f, 0xf5, - 0x9d, 0x03, 0x66, 0x1e, 0xb3, 0x2e, 0x96, 0x68, 0x17, 0x19, 0x50, 0x68, 0x13, 0xae, 0xca, 0x10, - 0x06, 0x7e, 0xea, 0x62, 0xef, 0x59, 0xb8, 0x2b, 0xcc, 0xbf, 0x18, 0x09, 0x13, 0xef, 0xe3, 0xb9, - 0xd5, 0xb7, 0x7b, 0x84, 0x79, 0xd8, 0x4c, 0x2e, 0xd1, 0x99, 0x8c, 0x84, 0x19, 0xe9, 0xe3, 0x94, - 0x33, 0x7c, 0x9c, 0x91, 0xde, 0xd5, 0xe5, 0x2c, 0xef, 0x2a, 0xd3, 0x43, 0x5a, 0x19, 0xc7, 0x43, - 0x7a, 0x15, 0xf1, 0x90, 0xe8, 0xaa, 0x18, 0xc5, 0x33, 0x01, 0xed, 0x95, 0xaf, 0x50, 0xc5, 0xfd, - 0x96, 0xcc, 0x70, 0x23, 0x45, 0x3a, 0xe7, 0xc2, 0xac, 0x7e, 0xc7, 0x71, 0xce, 0xae, 0x9e, 0x93, - 0x73, 0x76, 0xed, 0x4c, 0xce, 0xd9, 0xea, 0x29, 0x9d, 0x33, 0xee, 0x4c, 0x99, 0x30, 0x53, 0x6b, - 0x57, 0xfb, 0x7d, 0xa7, 0x6b, 0xf9, 0x44, 0xa7, 0xc5, 0x7d, 0xb4, 0x45, 0x98, 0xa0, 0x12, 0x83, - 0x2b, 0x38, 0x56, 0x60, 0x86, 0xc0, 0xd7, 0x8e, 0xb1, 0x47, 0x64, 0x11, 0xd3, 0x32, 0x61, 0x45, - 0xe5, 0x5f, 0x0b, 0x30, 0x2f, 0x0c, 0xf5, 0xd1, 0x6a, 0x6d, 0x0d, 0x4a, 0x86, 0xf5, 0xd4, 0x57, - 0x75, 0x9a, 0x5c, 0x95, 0xa0, 0xf8, 0xf2, 0x89, 0x8a, 0x2f, 0xa6, 0x08, 0x0a, 0x49, 0x8a, 0xe0, - 0x6c, 0x86, 0x7b, 0xb2, 0x9a, 0x9b, 0x4c, 0x55, 0x73, 0xaa, 0x4a, 0x99, 0x3a, 0x95, 0xa1, 0x5f, - 0x3c, 0x81, 0xa1, 0xff, 0x05, 0x28, 0x47, 0xe4, 0x75, 0x28, 0x74, 0xa6, 0x19, 0xc3, 0xa7, 0xb5, - 0x8f, 0x21, 0xcc, 0x61, 0x2c, 0x61, 0x3e, 0xbe, 0xb3, 0x51, 0x3a, 0x91, 0xb3, 0xd1, 0x80, 0x92, - 0xe4, 0x53, 0x8f, 0x70, 0x35, 0x46, 0xda, 0xa8, 0x95, 0xaf, 0x4f, 0x80, 0x6e, 0x9e, 0xa7, 0xc1, - 0x15, 0x46, 0x01, 0xf2, 0x27, 0x89, 0x02, 0x24, 0x93, 0x52, 0x21, 0x95, 0x94, 0xd2, 0xa2, 0x06, - 0x13, 0x27, 0x8e, 0x1a, 0x4c, 0x8e, 0x19, 0x35, 0x28, 0x9e, 0x3a, 0x6a, 0x30, 0x3d, 0x7e, 0xd4, - 0x00, 0xd2, 0xad, 0x1d, 0x22, 0x1a, 0xf0, 0xb0, 0x6f, 0xbd, 0xc2, 0xbd, 0x96, 0x37, 0xa0, 0xd4, - 0x52, 0x30, 0xe4, 0xaa, 0xb3, 0xc7, 0x15, 0xd2, 0xac, 0xa6, 0xd9, 0x53, 0x5b, 0x4d, 0x73, 0x99, - 0x56, 0xd3, 0xc3, 0x42, 0x71, 0x4a, 0x2f, 0x56, 0xbe, 0x3b, 0x01, 0x45, 0xa3, 0xf3, 0x98, 0x19, - 0xb1, 0x3a, 0xe4, 0x4d, 0xcf, 0x11, 0xde, 0x9d, 0xe9, 0x39, 0x44, 0xea, 0x36, 0x07, 0x3d, 0xfc, - 0x52, 0x48, 0x5d, 0x5a, 0x20, 0x32, 0xae, 0x85, 0x2d, 0x0f, 0x6f, 0x39, 0x7d, 0xe6, 0xf0, 0x32, - 0xb7, 0x47, 0xad, 0x24, 0xc7, 0x61, 0xba, 0xc7, 0x03, 0x22, 0xd1, 0xe9, 0xce, 0x71, 0xdf, 0x47, - 0xae, 0x43, 0x0f, 0x61, 0x86, 0x21, 0xd9, 0x9e, 0xef, 0xb8, 0xaf, 0xb8, 0x2c, 0x54, 0x7c, 0x72, - 0x31, 0xbb, 0x0d, 0x19, 0x90, 0xf9, 0xbd, 0x0a, 0x2e, 0x3b, 0xa8, 0xaf, 0x1d, 0xdb, 0x2e, 0x1b, - 0x6e, 0x52, 0x1c, 0x54, 0x50, 0x85, 0xde, 0x86, 0xf9, 0x8f, 0xaa, 0x2d, 0x03, 0x77, 0x1d, 0xb2, - 0x1b, 0x75, 0xfb, 0x00, 0x7b, 0x3e, 0x8f, 0x5e, 0xc5, 0x1b, 0xd0, 0xe7, 0x60, 0x49, 0xaa, 0xa4, - 0x23, 0xd6, 0x9c, 0xe3, 0x81, 0x4f, 0x29, 0xb2, 0x60, 0x24, 0x37, 0x92, 0x83, 0x91, 0x1a, 0x6a, - 0xce, 0xd1, 0xb0, 0x8f, 0x89, 0x25, 0x34, 0xf0, 0x5d, 0x1b, 0x33, 0x9a, 0x2c, 0x18, 0xa3, 0x40, - 0x08, 0xbb, 0x48, 0xcd, 0x9b, 0x96, 0x87, 0xc9, 0x72, 0x80, 0x22, 0x26, 0xb4, 0x44, 0xe0, 0x5b, - 0x96, 0xe7, 0x87, 0x74, 0x9a, 0xd0, 0x82, 0x1e, 0xc2, 0x9a, 0x54, 0xbb, 0xed, 0xda, 0x07, 0xf6, - 0xc0, 0xea, 0xab, 0x07, 0x3a, 0x43, 0xb1, 0x33, 0xe1, 0x08, 0xe1, 0x26, 0x2c, 0x85, 0x12, 0x6e, - 0xd1, 0x48, 0x6a, 0x5a, 0x79, 0x1f, 0xe6, 0x63, 0x07, 0x99, 0x15, 0x56, 0x28, 0xc8, 0x61, 0x85, - 0x8f, 0x61, 0x9a, 0xaa, 0xc7, 0xae, 0xe3, 0xf6, 0x08, 0x22, 0x59, 0x2c, 0x47, 0x24, 0xab, 0x5b, - 0x87, 0x82, 0xf9, 0x6a, 0xc8, 0xf0, 0xe6, 0x54, 0xb1, 0xc1, 0x70, 0x48, 0xab, 0x41, 0x61, 0x88, - 0xbc, 0xa5, 0x22, 0x86, 0x90, 0xef, 0x8c, 0x41, 0x7f, 0x57, 0x7e, 0x9c, 0x03, 0xa0, 0xfd, 0x53, - 0x23, 0x82, 0x80, 0xb4, 0xad, 0x23, 0x2c, 0x44, 0x32, 0xf9, 0x2d, 0xcb, 0xfc, 0x9c, 0x2a, 0xf3, - 0xf9, 0x74, 0xf2, 0xe1, 0x74, 0xca, 0x30, 0xf5, 0xd8, 0x7a, 0xd9, 0xb1, 0x7f, 0x4b, 0xf8, 0xfe, - 0xa2, 0x48, 0xf4, 0x83, 0x10, 0xcb, 0x75, 0x1e, 0x19, 0x0a, 0x2b, 0x68, 0xc8, 0xa8, 0xdd, 0xac, - 0x73, 0x2a, 0xa6, 0xbf, 0xd1, 0xe7, 0x20, 0x67, 0x76, 0xb8, 0xfa, 0x5e, 0xd9, 0x60, 0x77, 0x86, - 0x1b, 0xe2, 0xce, 0x50, 0xb2, 0xb7, 0x68, 0xd4, 0xe4, 0x4f, 0x7e, 0x74, 0x5d, 0x33, 0x72, 0x66, - 0x87, 0x28, 0xd4, 0xe6, 0xa0, 0xdb, 0x3f, 0xee, 0xe1, 0xc6, 0xcb, 0x21, 0xe1, 0x04, 0xae, 0x84, - 0xb8, 0x7c, 0xc3, 0x1e, 0x8f, 0xb6, 0x65, 0x40, 0x11, 0x53, 0xb4, 0xf1, 0x92, 0x42, 0x6c, 0x59, - 0x6e, 0xaf, 0xee, 0xbc, 0x18, 0xc4, 0x3a, 0x62, 0xba, 0x3d, 0x0b, 0xac, 0x52, 0x01, 0x30, 0x3d, - 0x47, 0xec, 0xf0, 0x22, 0x4c, 0x30, 0xb6, 0x62, 0x87, 0xc8, 0x0a, 0x95, 0x9f, 0x6a, 0xc4, 0x22, - 0xa4, 0xfa, 0x91, 0xc6, 0xe0, 0x13, 0x75, 0xe3, 0x1d, 0x98, 0xde, 0x1e, 0xca, 0x81, 0x8f, 0x48, - 0xbc, 0xb4, 0xd6, 0xa6, 0xb8, 0xdb, 0x43, 0x23, 0x84, 0x43, 0x9b, 0xc1, 0x5d, 0x21, 0x53, 0x94, - 0x37, 0x12, 0xee, 0x0a, 0x29, 0x40, 0xfa, 0x85, 0xe1, 0x79, 0xdf, 0x28, 0x54, 0x5a, 0x50, 0xaa, - 0xb5, 0xc3, 0x60, 0x42, 0xd2, 0x5a, 0xdf, 0x12, 0x71, 0xe1, 0x5c, 0xfa, 0xfd, 0x24, 0x83, 0xa8, - 0xfc, 0x84, 0xef, 0x9d, 0xe5, 0x8f, 0xd8, 0xbb, 0xf1, 0xfb, 0xcb, 0xde, 0x31, 0x31, 0xd0, 0x2f, - 0x71, 0xc7, 0xbe, 0x59, 0x84, 0x29, 0x41, 0x41, 0x8a, 0x13, 0xa0, 0x09, 0x4b, 0x8b, 0x57, 0xa0, - 0x0d, 0x98, 0x7c, 0x8c, 0xfd, 0x67, 0x4e, 0x2f, 0x49, 0x24, 0xb0, 0x16, 0x2a, 0x12, 0x38, 0x14, - 0xba, 0x2b, 0xf3, 0x3f, 0x65, 0xe5, 0x88, 0xf5, 0x11, 0xb6, 0xf2, 0x35, 0xca, 0xf2, 0xa2, 0x4a, - 0x23, 0x9c, 0x81, 0x49, 0x47, 0x99, 0xbe, 0x74, 0xfb, 0x5a, 0x34, 0xc2, 0xa9, 0xd8, 0x7d, 0x86, - 0x82, 0x82, 0xee, 0x11, 0x62, 0x08, 0x7b, 0x98, 0xa0, 0x3d, 0x5c, 0x4d, 0xa0, 0xd2, 0xb0, 0x03, - 0x19, 0x81, 0xe0, 0x9b, 0x12, 0xfe, 0x64, 0x1c, 0xdf, 0x8c, 0xe1, 0x4b, 0x08, 0xc4, 0xfc, 0x0a, - 0xd9, 0x33, 0xc9, 0x5b, 0x08, 0x5b, 0x0d, 0x99, 0x91, 0xef, 0xaa, 0x3e, 0x1c, 0x37, 0xdc, 0xca, - 0xea, 0xc4, 0xc3, 0x76, 0x43, 0xf5, 0xf8, 0xee, 0xaa, 0xfc, 0xce, 0x2f, 0x8b, 0xca, 0x69, 0xcc, - 0x69, 0xa8, 0xd2, 0xe1, 0xf3, 0x0a, 0x03, 0x51, 0x65, 0x19, 0x31, 0x81, 0xa5, 0x66, 0x43, 0x61, - 0xb6, 0xbb, 0x2a, 0xb3, 0x50, 0xc5, 0x99, 0x30, 0xb0, 0x68, 0x37, 0x54, 0xd6, 0x7a, 0x1f, 0x66, - 0xeb, 0x98, 0x28, 0x36, 0x3e, 0x1d, 0x1e, 0xb0, 0xbb, 0xac, 0x44, 0x02, 0x64, 0x00, 0x43, 0x85, - 0x47, 0x9b, 0x30, 0xb7, 0xe3, 0x3a, 0x2f, 0x5f, 0x85, 0x07, 0x36, 0xcb, 0x05, 0xbc, 0xd4, 0x83, - 0x0a, 0x61, 0x44, 0x30, 0x88, 0x16, 0x8e, 0xc6, 0xeb, 0xdb, 0xc7, 0x47, 0xd4, 0x08, 0x2c, 0x18, - 0x49, 0x4d, 0x68, 0x53, 0xba, 0x7d, 0x08, 0x5c, 0xbc, 0x8b, 0xe9, 0x2e, 0x9e, 0x11, 0x07, 0xa7, - 0x7b, 0xfe, 0x0c, 0x77, 0x0f, 0xb7, 0xb0, 0xd5, 0xf7, 0x9f, 0xd1, 0x10, 0x5f, 0x74, 0xcf, 0xc3, - 0x66, 0x43, 0x86, 0x45, 0x26, 0x2c, 0x76, 0xba, 0xcf, 0x70, 0xef, 0xb8, 0x8f, 0xb9, 0x89, 0x4a, - 0x8d, 0x74, 0x1a, 0xec, 0x2b, 0xdd, 0x5e, 0x93, 0xfb, 0x48, 0x82, 0x33, 0x12, 0xb1, 0x2b, 0x0e, - 0x94, 0x28, 0x27, 0x7a, 0x43, 0x67, 0xe0, 0xe1, 0x11, 0xae, 0x19, 0x57, 0xd3, 0x39, 0x45, 0x4d, - 0x0b, 0xc3, 0x89, 0x29, 0x6f, 0x51, 0x1c, 0x75, 0xaf, 0x53, 0xd9, 0x00, 0x24, 0xd1, 0xb3, 0x34, - 0xee, 0x7d, 0xdb, 0x95, 0x84, 0x91, 0x28, 0x56, 0xfe, 0xbb, 0x40, 0x63, 0xb4, 0x0c, 0xec, 0x7c, - 0xa5, 0xd6, 0x55, 0x98, 0x6e, 0xb8, 0xae, 0xe3, 0xd6, 0x9c, 0x1e, 0xa6, 0x4b, 0x98, 0x35, 0xc2, - 0x0a, 0x62, 0x8a, 0xd3, 0xc2, 0x63, 0xec, 0x79, 0xd6, 0x01, 0xe6, 0x31, 0x09, 0xa5, 0x0e, 0xad, - 0x02, 0x34, 0xbd, 0xad, 0xea, 0x23, 0x8c, 0x87, 0xd8, 0xa5, 0x52, 0xa7, 0x68, 0x48, 0x35, 0xe8, - 0x7d, 0x65, 0x77, 0xb9, 0x58, 0xb9, 0x14, 0x13, 0x8c, 0xac, 0x99, 0x4b, 0x46, 0xe5, 0x3c, 0x08, - 0xa3, 0x49, 0x4e, 0x0c, 0x97, 0x2c, 0x2a, 0xa3, 0x49, 0xed, 0x86, 0x02, 0x4d, 0xa8, 0x8d, 0xca, - 0x1a, 0x3e, 0x7c, 0x31, 0x3e, 0xbc, 0xd4, 0x6c, 0xc8, 0xb0, 0x84, 0xc5, 0x6a, 0xfd, 0x63, 0xcf, - 0xc7, 0x6e, 0x1d, 0x13, 0xef, 0xd4, 0xe3, 0xc2, 0x45, 0x61, 0x31, 0x15, 0xc2, 0x88, 0x60, 0xa0, - 0x7b, 0x30, 0x1d, 0x5e, 0x5b, 0x41, 0x02, 0x99, 0x8a, 0x46, 0x46, 0xa0, 0xd8, 0x3b, 0xee, 0xfb, - 0x46, 0x88, 0x82, 0xee, 0x01, 0x48, 0xa2, 0x91, 0xc9, 0x98, 0x55, 0xb9, 0x83, 0x38, 0x21, 0x19, - 0x10, 0x11, 0x8f, 0x84, 0x81, 0xb0, 0xcb, 0x24, 0xdc, 0x4c, 0xc2, 0xe6, 0x49, 0xed, 0x86, 0x02, - 0x5d, 0x79, 0x48, 0xe3, 0x60, 0xcc, 0xfe, 0x0d, 0xb6, 0xe5, 0x1d, 0xa2, 0x41, 0x49, 0x8d, 0x57, - 0xd6, 0xa8, 0x5e, 0x5f, 0x8a, 0x1d, 0x26, 0x69, 0xe5, 0x47, 0x29, 0x60, 0x2b, 0xaf, 0x2b, 0x07, - 0x41, 0xcc, 0xb7, 0x27, 0x54, 0x6f, 0x73, 0xf3, 0x8d, 0x16, 0x2a, 0x0f, 0x60, 0xd6, 0xb4, 0xbc, - 0x43, 0xd3, 0xda, 0xef, 0xe3, 0x5d, 0x0f, 0xbb, 0x84, 0x8d, 0xc8, 0xdf, 0x41, 0x68, 0x4b, 0x07, - 0x65, 0xd2, 0xb6, 0x63, 0x79, 0xde, 0x0b, 0xc7, 0xed, 0xf1, 0xe0, 0x46, 0x50, 0xae, 0x7c, 0x43, - 0x23, 0xb3, 0xa4, 0x72, 0x2b, 0xd1, 0x8c, 0x49, 0xb7, 0xc5, 0x95, 0xf8, 0x4b, 0x3e, 0x7a, 0x47, - 0x18, 0x5c, 0xe2, 0x16, 0xe4, 0x4b, 0xdc, 0x55, 0xaa, 0xfb, 0x55, 0xa3, 0x5c, 0xaa, 0xa9, 0xfc, - 0x79, 0x8e, 0xd0, 0xf0, 0xe0, 0xa9, 0x7d, 0x50, 0x7b, 0x66, 0x0d, 0x0e, 0x30, 0xba, 0x13, 0xcc, - 0x8e, 0xdf, 0x65, 0x2e, 0xa8, 0x0e, 0x07, 0x6d, 0x0a, 0x77, 0x90, 0xad, 0xe3, 0x2e, 0x00, 0x43, - 0x97, 0x1c, 0x95, 0xab, 0xf1, 0xf8, 0x46, 0x08, 0x63, 0x48, 0xf0, 0xc8, 0x84, 0xb9, 0xe6, 0xc0, - 0xf6, 0x6d, 0xab, 0xff, 0x18, 0x1f, 0xed, 0x63, 0x57, 0x58, 0x65, 0x6f, 0xa7, 0xf5, 0xb0, 0xa1, - 0x82, 0x33, 0xd7, 0x39, 0xd2, 0xc7, 0x4a, 0x15, 0x16, 0x12, 0xc0, 0x4e, 0x74, 0xdf, 0xfb, 0x16, - 0xcc, 0x76, 0x9e, 0x1d, 0xfb, 0x3d, 0xe7, 0xc5, 0x80, 0xa9, 0x36, 0x72, 0x36, 0xe4, 0x47, 0x70, - 0x64, 0xa2, 0x58, 0xf9, 0xfb, 0x09, 0xb8, 0x18, 0x11, 0xe1, 0x89, 0xa7, 0x7b, 0x03, 0x66, 0x37, - 0x1d, 0xc7, 0xf7, 0x7c, 0xd7, 0x1a, 0x0e, 0xed, 0xc1, 0x01, 0x1d, 0xb4, 0x68, 0xa8, 0x95, 0x44, - 0x34, 0xf0, 0x98, 0x0d, 0xdd, 0xd0, 0x3c, 0xdd, 0x50, 0x45, 0x34, 0x48, 0xcd, 0x86, 0x0c, 0xcb, - 0x64, 0x52, 0xb8, 0x55, 0xdc, 0x5c, 0x2b, 0xa7, 0x6d, 0xa5, 0xa1, 0x9e, 0xfe, 0xfb, 0x91, 0x15, - 0x73, 0x5b, 0xed, 0xb2, 0x2a, 0x18, 0x24, 0x00, 0x23, 0xb2, 0x43, 0x8f, 0x60, 0x9e, 0x05, 0xd6, - 0xa4, 0x48, 0x1b, 0x97, 0xac, 0x8a, 0xc9, 0x18, 0x03, 0x32, 0xe2, 0x78, 0x71, 0x53, 0x64, 0xea, - 0x84, 0xa6, 0xc8, 0x23, 0x98, 0x7f, 0xe8, 0xd8, 0x03, 0x16, 0xa9, 0xe6, 0xf2, 0x8f, 0x0b, 0x5a, - 0x65, 0x36, 0x31, 0x20, 0x23, 0x8e, 0x87, 0xb6, 0x40, 0x67, 0xbd, 0x53, 0x5b, 0x85, 0x4d, 0x68, - 0x3a, 0x6e, 0x8a, 0x46, 0x61, 0x8c, 0x18, 0x16, 0x39, 0xde, 0x6a, 0xaf, 0x27, 0xb8, 0x30, 0xc9, - 0xb6, 0x93, 0x9a, 0x0d, 0x19, 0x96, 0x48, 0xfe, 0x80, 0x54, 0x18, 0x76, 0x29, 0x2e, 0xf9, 0x55, - 0x08, 0x23, 0x82, 0x51, 0xc1, 0xc9, 0xb6, 0x4a, 0x22, 0xbd, 0x46, 0x28, 0x31, 0x37, 0x3e, 0x25, - 0x56, 0xfe, 0x34, 0x07, 0xcb, 0x91, 0x70, 0x9d, 0xb8, 0x04, 0xaa, 0x04, 0xa6, 0x31, 0x19, 0x84, - 0x49, 0xeb, 0x69, 0x43, 0xa9, 0xa3, 0xc1, 0x36, 0x19, 0x26, 0xc7, 0x60, 0xe4, 0x3a, 0x22, 0x67, - 0x1b, 0x2f, 0x89, 0x08, 0xb2, 0x7d, 0x9e, 0x14, 0x11, 0x94, 0x89, 0x09, 0xc9, 0xfb, 0x33, 0xed, - 0x23, 0xec, 0x1c, 0xfb, 0xa6, 0xdd, 0x3d, 0xf4, 0xb8, 0x74, 0x4c, 0x6a, 0x22, 0x18, 0x66, 0x02, - 0x06, 0x13, 0x9a, 0x49, 0x4d, 0xe8, 0x73, 0xb0, 0xd4, 0x20, 0xe2, 0xc2, 0xf2, 0x71, 0xed, 0xd8, - 0x75, 0xf1, 0xc0, 0xa7, 0x30, 0x1e, 0xbf, 0xb9, 0x48, 0x6e, 0xac, 0xdc, 0x4a, 0xa0, 0x4a, 0xb6, - 0x14, 0xdb, 0xa3, 0xf9, 0x1d, 0x6c, 0x3b, 0x82, 0x72, 0xa5, 0x9f, 0xc0, 0x54, 0xe8, 0x0e, 0x14, - 0x88, 0xbe, 0xe1, 0x52, 0x5a, 0xe1, 0x09, 0x45, 0x51, 0x71, 0x59, 0x4d, 0x81, 0xe9, 0xa6, 0x5a, - 0xde, 0x61, 0xdd, 0xf2, 0xad, 0x7d, 0xcb, 0x13, 0x22, 0x4f, 0xa9, 0x23, 0x52, 0x4f, 0xe5, 0xa2, - 0x74, 0xa9, 0xf7, 0x76, 0x9c, 0x25, 0x46, 0x40, 0xbf, 0xa9, 0x90, 0x7d, 0xba, 0x35, 0x5b, 0xf9, - 0x99, 0x16, 0xa5, 0xf2, 0xd3, 0xde, 0x4a, 0xa0, 0x27, 0x29, 0xba, 0x65, 0x23, 0x9d, 0x5f, 0xc6, - 0xd1, 0x2e, 0x84, 0x57, 0xc8, 0x19, 0xf2, 0x7b, 0x05, 0xfa, 0xfb, 0x3c, 0x34, 0xce, 0x8f, 0x72, - 0xaa, 0x49, 0x19, 0x24, 0x5a, 0x69, 0x52, 0xa2, 0xd5, 0x17, 0x59, 0xb6, 0x82, 0x35, 0xe8, 0x89, - 0x94, 0xaf, 0x2b, 0x23, 0xfc, 0x0b, 0x71, 0x97, 0x25, 0x50, 0xc8, 0x56, 0x8a, 0x70, 0x3c, 0xf7, - 0x0c, 0x44, 0x08, 0xbe, 0x06, 0xc0, 0xa1, 0x08, 0xc3, 0x15, 0x68, 0xd7, 0xd7, 0x46, 0x74, 0xdd, - 0xac, 0x8b, 0x78, 0x41, 0x88, 0x86, 0x3e, 0x82, 0xa5, 0xc4, 0x8b, 0x2c, 0xae, 0x4a, 0x5e, 0x93, - 0xfb, 0x4b, 0x4e, 0x42, 0x4e, 0xc6, 0xcf, 0xbe, 0xfa, 0x9e, 0x1c, 0xe3, 0xea, 0xbb, 0xf2, 0x17, - 0xb9, 0x94, 0xf9, 0x11, 0x42, 0x62, 0x77, 0xcb, 0x8c, 0x05, 0xc9, 0xb9, 0x86, 0x15, 0x64, 0xd7, - 0x1a, 0x03, 0xc2, 0x53, 0x3d, 0xae, 0xb2, 0x45, 0x31, 0x25, 0x7b, 0xee, 0x36, 0x2c, 0x06, 0x69, - 0x03, 0x34, 0xb3, 0x9a, 0x05, 0xed, 0x39, 0xc1, 0x24, 0xb6, 0xa1, 0x0d, 0x40, 0x09, 0xa9, 0x11, - 0x4c, 0xfe, 0x24, 0xb4, 0x44, 0xf2, 0xa4, 0x26, 0x63, 0x79, 0x52, 0x8b, 0x30, 0xc1, 0xd2, 0x0a, - 0x58, 0xbe, 0x10, 0x2b, 0x10, 0x49, 0x43, 0x16, 0xed, 0x87, 0x69, 0x89, 0x41, 0xb9, 0xf2, 0x6f, - 0x9a, 0x9a, 0x1d, 0x11, 0xec, 0x8e, 0x90, 0xdc, 0xb2, 0xc4, 0xd5, 0xc6, 0x93, 0xb8, 0xb9, 0x74, - 0x89, 0xfb, 0x2e, 0x2c, 0x87, 0x92, 0x43, 0x41, 0x62, 0x7b, 0x99, 0xd2, 0x9a, 0x2e, 0x77, 0x0b, - 0xa3, 0xe4, 0xee, 0x3f, 0xce, 0x42, 0x89, 0xcf, 0x82, 0x7a, 0x30, 0x22, 0x59, 0x55, 0x93, 0x92, - 0x55, 0xff, 0x6f, 0x65, 0x83, 0x55, 0x83, 0x38, 0x67, 0x91, 0x32, 0xf3, 0xeb, 0x09, 0xc1, 0x27, - 0x9a, 0x86, 0x39, 0xe6, 0x4b, 0x92, 0xe9, 0x53, 0xbd, 0x24, 0x81, 0xe4, 0x1c, 0x34, 0x35, 0xa9, - 0xa0, 0x34, 0x4e, 0x76, 0xd9, 0x4c, 0x66, 0x76, 0xd9, 0xec, 0xa9, 0xb2, 0xcb, 0xe6, 0x4e, 0xf5, - 0x26, 0xe5, 0xe2, 0x38, 0x6f, 0x52, 0xf4, 0xf1, 0xb2, 0xce, 0xe6, 0x23, 0x59, 0x67, 0x19, 0xb7, - 0xa1, 0xe8, 0x3c, 0x72, 0xc8, 0x16, 0xce, 0x2b, 0x87, 0x6c, 0xf1, 0x1c, 0x72, 0xc8, 0x96, 0xce, - 0x9e, 0x43, 0xb6, 0x7c, 0x2e, 0x39, 0x64, 0x97, 0xce, 0x21, 0x87, 0xac, 0x3c, 0x46, 0x0e, 0xd9, - 0xe8, 0x57, 0x3a, 0x97, 0x33, 0x5f, 0xe9, 0x8c, 0xca, 0x41, 0x5b, 0x39, 0x4b, 0x0e, 0xda, 0x95, - 0x33, 0xe7, 0xa0, 0x5d, 0x3d, 0xa7, 0x57, 0x3a, 0xd7, 0xce, 0x29, 0x11, 0x6c, 0xf5, 0x4c, 0x89, - 0x60, 0xd7, 0x7f, 0xb5, 0x5e, 0xe9, 0x7c, 0xa2, 0xb1, 0x87, 0x91, 0xfc, 0x95, 0x20, 0x57, 0x7c, - 0x5a, 0xf2, 0x2b, 0x41, 0xcb, 0xc7, 0x1b, 0x0c, 0x42, 0x91, 0xed, 0xac, 0x2a, 0xfb, 0x20, 0x73, - 0x63, 0x1c, 0xe4, 0x8a, 0x01, 0x25, 0x69, 0x88, 0x84, 0x65, 0x7e, 0x46, 0x5d, 0xe6, 0xa5, 0x14, - 0x25, 0x24, 0xdb, 0xc1, 0xff, 0x52, 0xa0, 0x49, 0x49, 0xe7, 0xa2, 0xaa, 0x7f, 0x93, 0x47, 0xf4, - 0x6b, 0x9c, 0x47, 0x94, 0xa1, 0x07, 0x67, 0xc7, 0xcd, 0x0a, 0xfa, 0x4b, 0x8d, 0xbd, 0x6d, 0xcb, - 0xe4, 0x1a, 0x33, 0x8b, 0x6b, 0xce, 0x46, 0xef, 0x66, 0x32, 0xbd, 0xff, 0x5d, 0x1e, 0x40, 0xf2, - 0xa1, 0x93, 0x22, 0x31, 0x82, 0x05, 0x72, 0x12, 0x0b, 0xdc, 0x80, 0x59, 0x22, 0x24, 0xf0, 0x40, - 0x35, 0x44, 0xd5, 0xca, 0x08, 0xd5, 0x14, 0xc6, 0xa6, 0x9a, 0x6c, 0x0b, 0x62, 0xe2, 0xbc, 0x2c, - 0x88, 0xc9, 0x73, 0xb0, 0x20, 0xa6, 0xce, 0xf6, 0x2e, 0xb6, 0x98, 0xa5, 0x71, 0x2b, 0x7f, 0xab, - 0x05, 0x87, 0x44, 0xc8, 0xe8, 0x83, 0x08, 0x19, 0x55, 0x62, 0xf7, 0x9b, 0x59, 0x94, 0xf4, 0x61, - 0x16, 0x25, 0xbd, 0xad, 0x52, 0xd2, 0x72, 0xc2, 0x08, 0x8e, 0x8b, 0x65, 0x42, 0xfa, 0x41, 0x2e, - 0x7a, 0xfb, 0x9a, 0x16, 0x86, 0x56, 0x09, 0x27, 0x97, 0x4d, 0x38, 0xf9, 0x73, 0x24, 0x9c, 0xc2, - 0x79, 0x11, 0xce, 0xc4, 0x39, 0x10, 0xce, 0x64, 0x06, 0xe1, 0x54, 0xfe, 0x3d, 0x1f, 0xbd, 0x6f, - 0x43, 0xef, 0x40, 0x91, 0xb3, 0xb2, 0x38, 0xfe, 0x85, 0x04, 0x36, 0x17, 0xce, 0x83, 0x00, 0x25, - 0x68, 0x35, 0x81, 0x96, 0x8b, 0xa3, 0xd5, 0x54, 0x34, 0x01, 0x8a, 0xde, 0xa3, 0x19, 0x62, 0x1c, - 0x8f, 0x69, 0xb1, 0xc5, 0xa4, 0x04, 0x0c, 0x8e, 0x18, 0x02, 0xa3, 0x7b, 0x50, 0x0a, 0x09, 0x45, - 0xc4, 0x74, 0x52, 0xe8, 0x48, 0x5c, 0x71, 0x4a, 0x08, 0xa8, 0x2e, 0x82, 0x81, 0x3d, 0xde, 0x03, - 0xcb, 0x67, 0x2c, 0xc7, 0x23, 0xde, 0x3d, 0xb9, 0x0f, 0x15, 0x29, 0x3d, 0x26, 0x34, 0xf9, 0x8b, - 0x8e, 0x09, 0x4d, 0x8d, 0x13, 0x13, 0xfa, 0x7d, 0x0d, 0x4a, 0xfc, 0x7c, 0xa9, 0xb5, 0xf1, 0x79, - 0x7a, 0xb8, 0xcc, 0x66, 0xd0, 0xb8, 0xcd, 0x10, 0x98, 0x66, 0xbc, 0x45, 0xb9, 0x4a, 0x0c, 0xc0, - 0xd1, 0x5d, 0x76, 0x52, 0x0c, 0x37, 0xc7, 0xf7, 0x2a, 0x34, 0xeb, 0x44, 0x4c, 0x5f, 0x46, 0x0e, - 0x11, 0x2a, 0xdf, 0x29, 0xc0, 0x12, 0x0f, 0x21, 0x8a, 0x8b, 0x08, 0x9e, 0x8a, 0xf2, 0x06, 0xcc, - 0xb5, 0x8f, 0x8f, 0xb6, 0x9f, 0x86, 0x9d, 0x33, 0x53, 0x28, 0x52, 0x4b, 0x18, 0x9b, 0xd6, 0x04, - 0xf3, 0x67, 0xea, 0x42, 0xad, 0x44, 0xeb, 0xa0, 0x0b, 0xbc, 0x20, 0x69, 0x9f, 0x45, 0x5c, 0x62, - 0xf5, 0xc4, 0xdf, 0x6d, 0xe3, 0x97, 0x7e, 0x90, 0x2c, 0xc0, 0x4b, 0xc8, 0x84, 0x12, 0xfb, 0xb5, - 0xf9, 0xea, 0x11, 0x16, 0x79, 0xae, 0xb7, 0xe5, 0x93, 0x4c, 0x5c, 0xc9, 0x86, 0x84, 0xc4, 0x42, - 0xab, 0x72, 0x37, 0xe8, 0x69, 0x52, 0x1a, 0x07, 0x7b, 0x44, 0xfa, 0xde, 0x18, 0x7d, 0x47, 0x51, - 0xa3, 0xaf, 0x49, 0x83, 0x54, 0x0f, 0x6a, 0x79, 0x1d, 0x88, 0xbb, 0x27, 0x9e, 0xd2, 0x29, 0x22, - 0x29, 0xf1, 0x96, 0x95, 0x7b, 0xa0, 0x47, 0x27, 0x9e, 0xfc, 0xa4, 0x23, 0x39, 0xc7, 0x53, 0x79, - 0x80, 0xaa, 0x4c, 0x2e, 0xab, 0x17, 0x25, 0x3c, 0xfc, 0x73, 0x0d, 0x2e, 0x1b, 0xd8, 0x63, 0xf1, - 0xf4, 0x8f, 0x2c, 0x1f, 0xbb, 0x47, 0x96, 0x7b, 0x28, 0x68, 0x24, 0x3c, 0x29, 0x4d, 0x39, 0xa9, - 0x2f, 0xa9, 0x27, 0xc5, 0xa8, 0xf2, 0xdd, 0x48, 0xb0, 0x23, 0xb9, 0xcf, 0x8c, 0xd3, 0x4a, 0xde, - 0xc5, 0xfc, 0x2f, 0x6a, 0x17, 0x2b, 0xff, 0x5c, 0x60, 0xcf, 0x6d, 0x47, 0xfa, 0x05, 0xbf, 0x79, - 0xf9, 0xf2, 0x9b, 0x97, 0x2f, 0xe3, 0xbd, 0x7c, 0xf9, 0x87, 0x1c, 0xff, 0xec, 0x01, 0x31, 0xe7, - 0xee, 0x05, 0x6e, 0x22, 0x13, 0xf9, 0x6b, 0x31, 0x05, 0x4b, 0x8d, 0x39, 0x0a, 0xa2, 0x1a, 0x73, - 0x4c, 0xa6, 0xde, 0x0b, 0xcc, 0xc1, 0xdc, 0x28, 0xfc, 0x54, 0x63, 0xb0, 0x03, 0x25, 0xa9, 0xf3, - 0x84, 0x5b, 0xa3, 0x0d, 0xd5, 0x18, 0x4c, 0x7d, 0x63, 0x2e, 0x8b, 0x9d, 0x4e, 0x96, 0x85, 0x99, - 0xd5, 0x69, 0x92, 0xb3, 0xf2, 0x9f, 0x45, 0x35, 0x75, 0x27, 0x91, 0x0b, 0xdf, 0x57, 0x54, 0x6a, - 0xa2, 0xeb, 0x1f, 0x36, 0x0b, 0xcb, 0x43, 0x56, 0xc2, 0x77, 0x02, 0x87, 0x8d, 0x5b, 0x9e, 0x0b, - 0x09, 0x6e, 0x9a, 0x48, 0x44, 0x11, 0xae, 0xdd, 0xbb, 0xe1, 0x81, 0x72, 0x47, 0x67, 0x31, 0xe9, - 0x18, 0x42, 0x2a, 0xe7, 0x87, 0x7f, 0x27, 0x88, 0xa9, 0xf0, 0x6b, 0xaa, 0x85, 0x84, 0x48, 0x8a, - 0x18, 0x4c, 0x44, 0x5f, 0x6e, 0x89, 0x84, 0x63, 0x16, 0xb4, 0x57, 0xae, 0x60, 0x45, 0x92, 0x99, - 0x92, 0x76, 0xdc, 0xe6, 0xbc, 0xce, 0x6f, 0xd1, 0x78, 0xe2, 0xd3, 0x14, 0xc5, 0x5e, 0x8d, 0x5e, - 0xe0, 0xaa, 0x50, 0x46, 0x02, 0x26, 0x6a, 0x44, 0x72, 0x92, 0x38, 0x63, 0x67, 0xde, 0x05, 0x47, - 0x32, 0x99, 0x84, 0xde, 0xe8, 0xf1, 0xb7, 0x1c, 0xbc, 0x84, 0x1e, 0xa9, 0x7a, 0x03, 0xe2, 0x2f, - 0x42, 0x65, 0x2a, 0xc8, 0x50, 0x15, 0x77, 0x65, 0xdf, 0x89, 0x27, 0x2d, 0x2c, 0x27, 0x7b, 0x4c, - 0xe2, 0x52, 0x51, 0xf2, 0xb5, 0xe4, 0x60, 0xfd, 0xcc, 0xc9, 0x9e, 0x82, 0x27, 0xe5, 0x91, 0xce, - 0xa6, 0xe7, 0x91, 0x6e, 0x25, 0x19, 0x20, 0x73, 0x99, 0x02, 0x33, 0xc1, 0xc4, 0xb8, 0x0b, 0x97, - 0xe3, 0x2a, 0x70, 0x07, 0x0f, 0x7a, 0xf6, 0xe0, 0x80, 0xde, 0x1d, 0x14, 0x8d, 0x74, 0x00, 0xb4, - 0x09, 0x57, 0x15, 0x75, 0x4c, 0x15, 0xb4, 0xe4, 0xf8, 0xb0, 0xf7, 0xe7, 0x23, 0x61, 0x88, 0xc3, - 0x9b, 0x30, 0x80, 0x88, 0xae, 0xb2, 0x77, 0xe8, 0x23, 0x20, 0xd0, 0x07, 0x70, 0x25, 0xde, 0x1a, - 0xbc, 0xee, 0x11, 0x97, 0x10, 0x23, 0x40, 0xce, 0xac, 0xf0, 0xff, 0x58, 0x83, 0x19, 0xd9, 0x95, - 0x48, 0x74, 0x66, 0xaf, 0xc2, 0x34, 0xbb, 0x22, 0x14, 0x19, 0x2a, 0xd3, 0x46, 0x58, 0x81, 0xca, - 0x30, 0xa5, 0x6a, 0x79, 0x51, 0x94, 0x6e, 0x72, 0x0a, 0xca, 0x4d, 0xce, 0x0a, 0x14, 0xeb, 0xce, - 0x8b, 0x01, 0x6d, 0x99, 0xa0, 0x2d, 0x41, 0xb9, 0xf2, 0x67, 0x15, 0xd0, 0x05, 0x6f, 0x07, 0xaf, - 0xcc, 0x82, 0x37, 0x65, 0x9a, 0xfc, 0xa6, 0x2c, 0x29, 0x60, 0x13, 0x9a, 0x68, 0x79, 0xc5, 0x44, - 0xdb, 0x56, 0x59, 0x8d, 0xb9, 0x69, 0x9f, 0x49, 0x12, 0x28, 0xc1, 0xe3, 0xb1, 0xd1, 0xec, 0x96, - 0xf4, 0x81, 0x96, 0xff, 0x75, 0x79, 0xd5, 0x03, 0x3d, 0x92, 0x41, 0x20, 0x2e, 0x26, 0x6f, 0x8f, - 0x5c, 0x6a, 0x14, 0x49, 0x56, 0x9f, 0xb1, 0x1e, 0x51, 0x53, 0x76, 0xc1, 0xd8, 0xd7, 0xf3, 0x3e, - 0x3d, 0xb2, 0xfb, 0x00, 0x9a, 0xed, 0x63, 0x88, 0x2d, 0xab, 0x05, 0x18, 0x5b, 0x2d, 0x48, 0x8a, - 0xab, 0x74, 0x2a, 0xc5, 0x35, 0x73, 0x02, 0xc5, 0x15, 0x51, 0xb3, 0xb3, 0x27, 0x56, 0xb3, 0x31, - 0x1d, 0x32, 0x77, 0x2a, 0x1d, 0xa2, 0x8a, 0xf7, 0x8b, 0x27, 0x14, 0xef, 0xb1, 0x28, 0x83, 0x7e, - 0x9a, 0x28, 0x43, 0x8a, 0xb0, 0x9f, 0x3f, 0xa1, 0xb0, 0x47, 0xe7, 0x2e, 0xec, 0x17, 0xce, 0x2a, - 0xec, 0x17, 0xcf, 0x2c, 0xec, 0x97, 0xce, 0x2a, 0xec, 0x97, 0x33, 0x85, 0x3d, 0x7a, 0x37, 0x96, - 0xef, 0x27, 0x32, 0x66, 0xd8, 0x9d, 0x6a, 0x4a, 0x6b, 0x82, 0x8b, 0x11, 0xe6, 0xe1, 0x94, 0x13, - 0x5d, 0x8c, 0x30, 0x2d, 0xe7, 0xab, 0xb0, 0x18, 0x69, 0x13, 0xf7, 0xa7, 0x31, 0x27, 0x37, 0xc6, - 0xf7, 0x49, 0x88, 0x4c, 0x04, 0x24, 0xf6, 0x89, 0x86, 0xb1, 0xf5, 0xd5, 0xda, 0xe2, 0xbe, 0x35, - 0x16, 0xa0, 0xc8, 0x1a, 0x8d, 0xa3, 0xb2, 0xf1, 0x52, 0xfa, 0x4d, 0x18, 0xd1, 0x6c, 0x8b, 0x4b, - 0xda, 0x13, 0x8f, 0x68, 0x8e, 0x1a, 0x91, 0x37, 0xa2, 0x2d, 0xb8, 0x1e, 0x69, 0xe1, 0xc9, 0x61, - 0x5e, 0xd5, 0xf3, 0xec, 0x83, 0x41, 0xf8, 0x79, 0x8e, 0x0c, 0x30, 0xd4, 0x82, 0xd7, 0xa2, 0xab, - 0x0a, 0x92, 0xc4, 0x82, 0xbe, 0xd8, 0x0d, 0x6f, 0x36, 0x60, 0xaa, 0x2b, 0x19, 0x52, 0xca, 0xea, - 0x08, 0x57, 0x32, 0xa4, 0x97, 0xcd, 0x94, 0xfc, 0x26, 0x41, 0xa9, 0xd7, 0xe3, 0xb7, 0xff, 0x51, - 0x98, 0xd4, 0x7b, 0x04, 0x16, 0x4d, 0x5e, 0xa3, 0xbc, 0x3a, 0x02, 0x02, 0x3d, 0x84, 0xb5, 0xc4, - 0xcc, 0x00, 0x39, 0x4d, 0xec, 0x35, 0x3a, 0x8f, 0x4c, 0xb8, 0x31, 0xb2, 0x22, 0x2a, 0x63, 0x65, - 0x45, 0x7c, 0x5d, 0x83, 0x6b, 0x89, 0x53, 0xa6, 0xe1, 0x0b, 0x42, 0x71, 0xaf, 0x53, 0x8a, 0x7b, - 0x7f, 0x24, 0xc5, 0x8d, 0xec, 0x81, 0x11, 0xde, 0xe8, 0x51, 0xd0, 0xef, 0xa6, 0x25, 0xa0, 0x09, - 0x56, 0xbb, 0x41, 0xa7, 0x71, 0xef, 0xe4, 0xd3, 0x50, 0x18, 0x6e, 0xe4, 0x18, 0xe8, 0x1b, 0x5a, - 0xca, 0xc5, 0x03, 0x55, 0x59, 0x6c, 0x1e, 0x9f, 0xa2, 0xf3, 0xa8, 0x9e, 0x7c, 0x1e, 0x61, 0x1f, - 0x6c, 0x2a, 0x59, 0x23, 0xa1, 0x3f, 0xd0, 0x52, 0x68, 0xbf, 0xd6, 0x16, 0x1f, 0xeb, 0x79, 0x83, - 0x4e, 0xe6, 0x83, 0xd3, 0x6c, 0x0a, 0xef, 0x82, 0xcd, 0x25, 0x63, 0x1c, 0xf4, 0x4d, 0x0d, 0x5e, - 0x4b, 0x9f, 0xae, 0x98, 0xcd, 0x9b, 0x74, 0x36, 0xb5, 0x53, 0x6e, 0x8d, 0x32, 0xa1, 0xec, 0xd1, - 0x52, 0x39, 0x5a, 0x28, 0xdf, 0x9b, 0x23, 0x38, 0x5a, 0xe8, 0xdf, 0x6f, 0x69, 0x50, 0x19, 0xb9, - 0x74, 0x96, 0x94, 0xf8, 0x16, 0x5d, 0x58, 0xfd, 0xf4, 0xdb, 0x4c, 0xbb, 0x61, 0x2b, 0x1b, 0x63, - 0x3c, 0xf4, 0x1d, 0x0d, 0x3e, 0x95, 0xb5, 0x01, 0x6c, 0x66, 0xeb, 0x74, 0x66, 0x0f, 0xce, 0xb4, - 0xe5, 0xd2, 0xe4, 0xc6, 0x1b, 0xf5, 0xcc, 0x41, 0xf1, 0x8f, 0x61, 0x29, 0xd1, 0xb4, 0x3f, 0x61, - 0x9c, 0x4a, 0x79, 0x63, 0x27, 0x75, 0x7f, 0x97, 0x7e, 0xad, 0x31, 0x25, 0xa8, 0x96, 0x39, 0xb9, - 0x07, 0x70, 0x39, 0xd5, 0x40, 0xc8, 0xea, 0xa8, 0x28, 0x77, 0xd4, 0x8c, 0xa5, 0x30, 0xc8, 0xa2, - 0xe8, 0x8c, 0x5d, 0x99, 0xa7, 0xed, 0x6a, 0x27, 0x85, 0xe2, 0x15, 0x69, 0x7d, 0xa2, 0x1e, 0xb7, - 0x53, 0x64, 0xc3, 0xa9, 0x57, 0x6b, 0xc0, 0x8d, 0x71, 0x24, 0xe8, 0x89, 0xfa, 0xfc, 0x10, 0x5e, - 0x1f, 0x43, 0x10, 0x9e, 0x88, 0x50, 0x4c, 0x78, 0x63, 0x3c, 0x69, 0x76, 0xa2, 0x5e, 0x77, 0xe1, - 0xcd, 0x31, 0x45, 0xc9, 0x89, 0xba, 0xfd, 0x12, 0xac, 0x8f, 0x2f, 0x07, 0x4e, 0x14, 0xaa, 0x69, - 0xb2, 0x6c, 0x20, 0xf1, 0x61, 0xd4, 0x33, 0x7c, 0xf9, 0xa9, 0xf2, 0x57, 0x39, 0x58, 0x4c, 0x7a, - 0x7e, 0x3a, 0xe2, 0x15, 0xc8, 0x4e, 0xec, 0x33, 0xb8, 0x1b, 0x59, 0x8f, 0x59, 0xd5, 0xcf, 0xe1, - 0xc6, 0x2e, 0x66, 0xce, 0xe5, 0xa3, 0xb8, 0x2b, 0x66, 0xf6, 0x57, 0x6b, 0x47, 0xa5, 0x0b, 0x49, - 0x3b, 0x2a, 0xef, 0xf5, 0x77, 0x35, 0x80, 0x4d, 0xab, 0x7b, 0x78, 0x3c, 0xa4, 0x77, 0x3b, 0x69, - 0x17, 0x7f, 0xcd, 0xa4, 0x8b, 0xbf, 0x37, 0x95, 0x97, 0x2f, 0x41, 0x27, 0xa3, 0xe3, 0x49, 0x67, - 0x0e, 0xe4, 0xfd, 0x9e, 0x26, 0xee, 0xad, 0x9a, 0x3e, 0x3e, 0x4a, 0xfc, 0x08, 0x4d, 0x05, 0x66, - 0x78, 0xbe, 0xfe, 0x13, 0xe9, 0xf6, 0x53, 0xa9, 0x23, 0x30, 0x75, 0xfc, 0xd4, 0x3a, 0xee, 0x73, - 0x18, 0xfe, 0xe5, 0x57, 0xb9, 0x8e, 0x1c, 0x51, 0x73, 0xe0, 0x63, 0x77, 0x60, 0xf5, 0xf9, 0x85, - 0x5d, 0x50, 0xae, 0xfc, 0xb5, 0x26, 0x5f, 0x9f, 0xa1, 0x2f, 0xc2, 0x54, 0xcd, 0x19, 0xf8, 0x98, - 0x7e, 0xab, 0x25, 0x9e, 0x20, 0x1f, 0x00, 0x6e, 0x70, 0x28, 0xb6, 0x31, 0x02, 0x67, 0xc5, 0xa0, - 0x6f, 0x2d, 0x83, 0x86, 0x13, 0x26, 0xf0, 0x84, 0xdb, 0x21, 0x6f, 0xd4, 0x6f, 0x87, 0xf7, 0x74, - 0xe8, 0x9d, 0xf0, 0x25, 0x72, 0x2c, 0x4f, 0x4d, 0x00, 0x6d, 0x50, 0x08, 0x36, 0x31, 0x06, 0xbd, - 0xf2, 0x1e, 0x40, 0x58, 0x79, 0xa2, 0xfb, 0xe5, 0x37, 0x95, 0x0f, 0x20, 0x8c, 0x78, 0xa1, 0xf5, - 0x31, 0xcc, 0xc7, 0xde, 0x02, 0xa1, 0x1b, 0x30, 0xcb, 0xbe, 0xa9, 0x24, 0x9e, 0x17, 0x31, 0x24, - 0xb5, 0x92, 0x1e, 0x33, 0x47, 0x91, 0xbe, 0xc3, 0xa5, 0xd4, 0xad, 0xbf, 0x00, 0xd8, 0x1d, 0xf6, - 0x2c, 0x9f, 0x45, 0x70, 0x2f, 0xc1, 0x82, 0xf2, 0x8d, 0x26, 0xd6, 0xa4, 0x5f, 0x40, 0x4b, 0x30, - 0x2f, 0xbe, 0xbd, 0xd5, 0xea, 0xb4, 0x79, 0xb5, 0x86, 0x16, 0xe0, 0xe2, 0xae, 0x87, 0x5d, 0xba, - 0x7c, 0x5e, 0x99, 0x43, 0xb3, 0x30, 0x6d, 0x76, 0xb6, 0x79, 0x31, 0x4f, 0x50, 0x83, 0xef, 0x68, - 0x05, 0xa8, 0x85, 0xf5, 0x0d, 0x98, 0x0e, 0x3e, 0x49, 0x8e, 0x2e, 0x42, 0xa9, 0xed, 0xb8, 0x47, - 0x56, 0x9f, 0x16, 0xf5, 0x0b, 0x48, 0x87, 0x19, 0xfe, 0x0c, 0x85, 0xd5, 0x68, 0xeb, 0x3f, 0x2d, - 0x00, 0x84, 0xdf, 0x2e, 0x40, 0x73, 0x00, 0x66, 0x67, 0x7b, 0x6f, 0x77, 0xa7, 0x5e, 0x35, 0x1b, - 0xfa, 0x05, 0x04, 0x30, 0x59, 0xdd, 0xd9, 0x69, 0xb4, 0xeb, 0xba, 0x86, 0x8a, 0x50, 0x30, 0x1a, - 0xd5, 0xba, 0x9e, 0x43, 0x33, 0x50, 0x34, 0x8d, 0xdd, 0x76, 0x8d, 0xc0, 0xe4, 0x49, 0xa7, 0x0f, - 0x1a, 0xe6, 0x5e, 0x50, 0x53, 0x40, 0x25, 0x98, 0xaa, 0x6d, 0xb7, 0xdb, 0x8d, 0x9a, 0xa9, 0x4f, - 0x90, 0x2e, 0x79, 0x61, 0xcf, 0xd8, 0xd6, 0x27, 0xd1, 0x3c, 0xcc, 0xb6, 0xb6, 0x1f, 0xec, 0x6d, - 0x35, 0xaa, 0x86, 0xb9, 0xd9, 0xa8, 0x9a, 0xfa, 0x14, 0xe9, 0xa1, 0xd6, 0x96, 0x6a, 0x8a, 0x74, - 0xa2, 0x72, 0xcd, 0x34, 0x42, 0x30, 0x57, 0xdb, 0x6a, 0xd4, 0x1e, 0xed, 0x6d, 0x55, 0x1f, 0x35, - 0x1a, 0x3b, 0x0d, 0x43, 0x07, 0xb2, 0xaf, 0x64, 0xe4, 0x5a, 0x6b, 0xb7, 0x63, 0x36, 0x8c, 0xbd, - 0x7a, 0xc3, 0xac, 0x36, 0x5b, 0x1d, 0xbd, 0x44, 0x80, 0x49, 0x43, 0x67, 0xab, 0x6a, 0xd4, 0xf7, - 0x9a, 0xed, 0xfb, 0xdb, 0xfa, 0x0c, 0xed, 0xa0, 0xbd, 0x57, 0x6d, 0xb5, 0xb6, 0xc9, 0x2c, 0xf7, - 0x9a, 0x75, 0x7d, 0x96, 0x6c, 0xa2, 0xdc, 0x41, 0xc7, 0x24, 0xf3, 0x9f, 0xa3, 0xfb, 0x4f, 0x77, - 0x60, 0xaf, 0xd6, 0xde, 0x6b, 0x55, 0x37, 0x1b, 0x2d, 0xfd, 0x22, 0x2a, 0xc3, 0x62, 0x58, 0xf9, - 0xd1, 0xb6, 0xf1, 0x88, 0x83, 0xeb, 0xa4, 0xe7, 0x9d, 0xaa, 0x59, 0xdb, 0x22, 0x0d, 0x1d, 0x73, - 0xdb, 0x68, 0xe8, 0xf3, 0xa4, 0x8b, 0x7a, 0xa3, 0xd5, 0x60, 0xd0, 0xac, 0x12, 0x91, 0xca, 0x1d, - 0x63, 0xfb, 0x4b, 0x5f, 0x96, 0x16, 0xb6, 0x80, 0x5e, 0x83, 0x6b, 0xbc, 0xdf, 0xf6, 0x76, 0x7b, - 0xef, 0xc9, 0xb6, 0xd9, 0x6c, 0x3f, 0xd8, 0x33, 0x1a, 0x3b, 0xad, 0x66, 0xad, 0xba, 0xd7, 0xde, - 0x7d, 0xac, 0x2f, 0xa2, 0x55, 0x58, 0x89, 0x83, 0x90, 0x75, 0xb4, 0x9a, 0xe6, 0x97, 0xf5, 0x25, - 0xb4, 0x08, 0x7a, 0xa7, 0x61, 0xee, 0x19, 0x8d, 0x0f, 0x77, 0x9b, 0x46, 0xa3, 0xbe, 0xd7, 0xea, - 0xb4, 0xf5, 0x65, 0x52, 0xfb, 0x20, 0x5a, 0x7b, 0x49, 0x6c, 0x4d, 0xab, 0x6a, 0x36, 0x3a, 0x26, - 0xad, 0x2b, 0x93, 0x23, 0xa1, 0x75, 0x8d, 0x6a, 0xbd, 0x61, 0x90, 0x9d, 0xb9, 0x4c, 0x8f, 0x84, - 0x6d, 0x77, 0xa3, 0xda, 0x32, 0xb7, 0xf4, 0x15, 0x72, 0xe8, 0xe4, 0xf8, 0x29, 0xca, 0x15, 0x74, - 0x19, 0x96, 0xf8, 0x94, 0x5a, 0x8d, 0x6a, 0xa7, 0xb1, 0xb5, 0xdd, 0xe2, 0xa8, 0x57, 0x49, 0x13, - 0xdd, 0xfc, 0xda, 0x56, 0xa3, 0xbe, 0xdb, 0x6a, 0xec, 0xd5, 0xb6, 0x1f, 0x3f, 0xae, 0xb6, 0xeb, - 0x1d, 0xfd, 0xda, 0x7a, 0x1b, 0x20, 0xfc, 0xe2, 0x17, 0xa1, 0x0c, 0x42, 0xe6, 0xac, 0x46, 0xbf, - 0x40, 0x46, 0x10, 0x72, 0x4e, 0xd7, 0x08, 0xf1, 0x52, 0xa6, 0x09, 0x18, 0x60, 0x9e, 0x7f, 0xe2, - 0xce, 0xc0, 0x5f, 0xc5, 0x5d, 0x1f, 0xf7, 0xf4, 0xfc, 0xfa, 0x3a, 0x4c, 0x07, 0x1f, 0x94, 0x22, - 0xe8, 0x1d, 0xec, 0xd3, 0x92, 0x7e, 0x81, 0xa0, 0xb3, 0xe0, 0x2a, 0xab, 0xd0, 0xd6, 0xff, 0xa9, - 0x00, 0x48, 0xb8, 0x14, 0x12, 0x6f, 0x12, 0x8a, 0xb7, 0xbb, 0x87, 0x32, 0x4b, 0x4a, 0x5f, 0xee, - 0x09, 0x58, 0x92, 0x70, 0x6a, 0xac, 0x3a, 0x87, 0x96, 0x69, 0xfe, 0x48, 0xb4, 0x3e, 0x4f, 0x46, - 0x7f, 0x80, 0xfd, 0x80, 0xd3, 0x0b, 0x64, 0x53, 0x22, 0xf2, 0x86, 0x37, 0x4d, 0x90, 0x13, 0xe9, - 0x60, 0xc6, 0x90, 0xbc, 0x6e, 0x92, 0x10, 0x9b, 0x9a, 0x20, 0xc4, 0x5b, 0xa6, 0xd0, 0x75, 0xb8, - 0xd2, 0xc1, 0x7e, 0xfc, 0x6e, 0x82, 0x03, 0x14, 0xd1, 0x0a, 0x2c, 0x73, 0x80, 0x20, 0xb8, 0xcd, - 0xdb, 0xa6, 0xc9, 0x16, 0xb2, 0xdf, 0x7c, 0xd7, 0x74, 0x20, 0x0b, 0x13, 0x55, 0xc1, 0x03, 0x28, - 0xbd, 0x44, 0xce, 0x7f, 0x87, 0xc8, 0x3b, 0x9e, 0xc1, 0xa7, 0xcf, 0x10, 0x5c, 0x03, 0x1f, 0x39, - 0xcf, 0xc5, 0xab, 0x5a, 0x7d, 0x96, 0xcc, 0x52, 0x4d, 0xd5, 0xe4, 0x03, 0xcd, 0xa1, 0x6b, 0x70, - 0x99, 0xfd, 0x4e, 0x08, 0x5a, 0xeb, 0x17, 0xd1, 0x15, 0xb8, 0x14, 0x69, 0x16, 0xda, 0x80, 0xb1, - 0x93, 0xf0, 0x7a, 0x78, 0x7f, 0xf3, 0xe8, 0x2a, 0x94, 0xe3, 0x29, 0x3e, 0xbc, 0x15, 0xa1, 0x1b, - 0xb0, 0x26, 0x82, 0xb8, 0xf1, 0xf0, 0x2e, 0x87, 0x5a, 0x20, 0x3b, 0xc7, 0x02, 0x60, 0x11, 0x0f, - 0x84, 0x03, 0x2c, 0xa2, 0x4f, 0xc1, 0x6b, 0x0c, 0x20, 0xd1, 0xc0, 0xe4, 0x60, 0x4b, 0xeb, 0xdf, - 0xd6, 0x60, 0x56, 0xb9, 0x6d, 0x22, 0x7c, 0x2d, 0x2a, 0x78, 0x96, 0x8b, 0x7e, 0x81, 0x9c, 0xb8, - 0xa8, 0x54, 0xbe, 0x8d, 0xa0, 0x6b, 0x64, 0xa0, 0x58, 0x93, 0xf0, 0x1f, 0x0d, 0xdc, 0xc5, 0xf6, - 0x73, 0xdc, 0xd3, 0x73, 0x64, 0x97, 0x62, 0x60, 0xf7, 0x2d, 0xbb, 0x4f, 0x48, 0x5f, 0x1e, 0xd3, - 0x38, 0x1e, 0x0c, 0x48, 0xc7, 0x85, 0xf5, 0xfd, 0xa4, 0xfb, 0x2e, 0x72, 0x4c, 0x4a, 0x6d, 0x38, - 0xc7, 0x68, 0x8b, 0xe8, 0x49, 0x8b, 0xb5, 0x74, 0x7c, 0x67, 0x38, 0x24, 0xb3, 0x5a, 0xff, 0x81, - 0x06, 0x7a, 0xf4, 0x6b, 0x18, 0x84, 0x8b, 0xaa, 0x3d, 0xf1, 0x81, 0x3a, 0xfd, 0x42, 0x48, 0x2c, - 0xa2, 0x4a, 0x23, 0x14, 0xd5, 0xf1, 0x2d, 0xd7, 0x17, 0x35, 0x39, 0xc2, 0x24, 0xa4, 0x5b, 0x51, - 0x91, 0x27, 0xbd, 0x3c, 0xb2, 0xfb, 0xfd, 0xaf, 0x38, 0x47, 0xfb, 0x36, 0x61, 0x9a, 0x4b, 0xb0, - 0x50, 0xed, 0xf5, 0xa2, 0x24, 0xa4, 0x4f, 0x10, 0x1a, 0x67, 0xdd, 0xc7, 0xda, 0x26, 0x29, 0xa7, - 0x91, 0x71, 0x62, 0x4d, 0x53, 0x64, 0x51, 0x64, 0xc0, 0x58, 0x4b, 0x71, 0xfd, 0xb1, 0xf2, 0x95, - 0x00, 0x32, 0x91, 0x90, 0x90, 0xf4, 0x0b, 0x54, 0xf7, 0xb6, 0x45, 0x51, 0x23, 0xc5, 0x5a, 0x50, - 0xcc, 0x51, 0x5e, 0xa1, 0x57, 0x41, 0xbc, 0x26, 0xbf, 0xd9, 0xfc, 0xfe, 0x4f, 0x56, 0x2f, 0x7c, - 0xef, 0x93, 0x55, 0xed, 0xfb, 0x9f, 0xac, 0x6a, 0x3f, 0xfe, 0x64, 0xf5, 0xc2, 0xdf, 0xfc, 0xc7, - 0xaa, 0xf6, 0x95, 0x3b, 0xd2, 0xbf, 0x20, 0x3b, 0xb2, 0x7c, 0xd7, 0x7e, 0xe9, 0x50, 0xc3, 0x42, - 0x14, 0x06, 0xf8, 0xd6, 0xf0, 0xf0, 0xe0, 0xd6, 0x70, 0xff, 0x56, 0x68, 0x26, 0xed, 0x4f, 0xd2, - 0xaf, 0x09, 0xde, 0xf9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0xe9, 0x02, 0x2f, 0xde, 0x6c, - 0x00, 0x00, + // 6206 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xcb, 0x6f, 0x1c, 0xc9, + 0x79, 0xb8, 0x7a, 0x66, 0x48, 0x0e, 0xbf, 0x21, 0xa9, 0x66, 0xf1, 0xa1, 0x11, 0x25, 0x51, 0xdc, + 0x59, 0x79, 0x57, 0x4b, 0xaf, 0x29, 0xff, 0x24, 0xef, 0x62, 0xed, 0x9f, 0xac, 0xdd, 0xe1, 0xcc, + 0x48, 0x1c, 0x69, 0x34, 0xe4, 0xf6, 0x34, 0xb5, 0xb6, 0x81, 0x05, 0xd1, 0x9c, 0x29, 0x51, 0x6d, + 0x0e, 0xa7, 0xc7, 0xdd, 0x4d, 0x3d, 0x92, 0x53, 0x82, 0x38, 0x08, 0x62, 0x24, 0x88, 0x01, 0x23, + 0x31, 0x92, 0x38, 0xaf, 0x5b, 0x4e, 0xbe, 0xf8, 0x3f, 0x08, 0x10, 0xf8, 0x10, 0x04, 0x8e, 0x8f, + 0x39, 0xf8, 0x95, 0x4b, 0x00, 0x5f, 0x72, 0x8a, 0x4f, 0x06, 0x82, 0x7a, 0x75, 0x57, 0xf5, 0x63, + 0x7a, 0xf8, 0xb0, 0x63, 0x07, 0x7b, 0xe2, 0xd4, 0x57, 0xdf, 0x57, 0x5d, 0x5d, 0xf5, 0xbd, 0xeb, + 0xab, 0x26, 0xe8, 0x7d, 0xe7, 0xc0, 0xc3, 0xee, 0x73, 0xbb, 0x8b, 0x37, 0x86, 0xae, 0xe3, 0x3b, + 0x08, 0x42, 0xc8, 0xca, 0x67, 0x0e, 0x6c, 0xff, 0xd9, 0xf1, 0xfe, 0x46, 0xd7, 0x39, 0xba, 0x75, + 0xe0, 0x1c, 0x38, 0xb7, 0x28, 0xca, 0xfe, 0xf1, 0x53, 0xda, 0xa2, 0x0d, 0xfa, 0x8b, 0x91, 0xae, + 0x5c, 0x3f, 0x70, 0x9c, 0x83, 0x3e, 0x0e, 0xb1, 0x7c, 0xfb, 0x08, 0x7b, 0xbe, 0x75, 0x34, 0xe4, + 0x08, 0x73, 0x47, 0xd8, 0xb7, 0x7a, 0x96, 0x6f, 0xf1, 0xf6, 0xc5, 0x08, 0x42, 0xe5, 0xbf, 0x00, + 0xa6, 0x6a, 0xed, 0x8e, 0xef, 0xb8, 0x18, 0x21, 0x28, 0xec, 0xee, 0x36, 0xeb, 0x65, 0x6d, 0x4d, + 0xbb, 0x39, 0x6d, 0xd0, 0xdf, 0xe8, 0x0d, 0x98, 0xeb, 0xb0, 0xb9, 0x55, 0x7b, 0x3d, 0x17, 0x7b, + 0x5e, 0x39, 0x47, 0x7b, 0x23, 0x50, 0xb4, 0x0a, 0xd0, 0xf9, 0xb0, 0x25, 0x70, 0xf2, 0x14, 0x47, + 0x82, 0xa0, 0x0d, 0x40, 0x2d, 0xa7, 0x7b, 0x18, 0x19, 0xab, 0x40, 0xf1, 0x12, 0x7a, 0xd0, 0x0d, + 0x28, 0x18, 0x4e, 0x1f, 0x97, 0x27, 0xd7, 0xb4, 0x9b, 0x73, 0xb7, 0xf5, 0x8d, 0xe0, 0x3d, 0x6a, + 0x6d, 0x02, 0x37, 0x68, 0x2f, 0x99, 0xb1, 0x69, 0x77, 0x0f, 0xcb, 0x53, 0x6b, 0xda, 0xcd, 0x82, + 0x41, 0x7f, 0xa3, 0x4f, 0xc3, 0x44, 0xc7, 0xb7, 0x7c, 0x5c, 0x2e, 0x52, 0xd2, 0xa5, 0x0d, 0x69, + 0xc1, 0xdb, 0x4e, 0x0f, 0xd3, 0x4e, 0x83, 0xe1, 0xa0, 0x2f, 0xc2, 0x64, 0xcb, 0xda, 0xc7, 0x7d, + 0xaf, 0x3c, 0xbd, 0x96, 0xbf, 0x59, 0xba, 0x7d, 0x5d, 0xc6, 0xe6, 0xeb, 0xb2, 0xc1, 0x30, 0x1a, + 0x03, 0xdf, 0x7d, 0xb5, 0x59, 0xf8, 0xfe, 0x8f, 0xae, 0x5f, 0x30, 0x38, 0x11, 0xfa, 0x7f, 0x30, + 0xfd, 0x91, 0xe3, 0x1e, 0xb2, 0xe7, 0x01, 0x7d, 0xde, 0x42, 0x38, 0xd5, 0xa0, 0xcb, 0x08, 0xb1, + 0x50, 0x05, 0x66, 0x3e, 0x3c, 0xc6, 0xee, 0x2b, 0xb1, 0x04, 0x25, 0xba, 0x04, 0x0a, 0x0c, 0xbd, + 0x0b, 0x50, 0x73, 0x06, 0x4f, 0xed, 0x83, 0xba, 0xe5, 0x5b, 0xe5, 0x99, 0x35, 0xed, 0x66, 0xe9, + 0xf6, 0xb2, 0x32, 0xb3, 0xa0, 0xd7, 0x90, 0x30, 0xd1, 0xbb, 0x50, 0x34, 0xb0, 0xe7, 0x1c, 0xbb, + 0x5d, 0x5c, 0x9e, 0xa5, 0x54, 0x8b, 0x32, 0x95, 0xe8, 0xe3, 0x2f, 0x11, 0xe0, 0xa2, 0x65, 0x98, + 0xdc, 0x1d, 0x9a, 0xf6, 0x11, 0x2e, 0xcf, 0xad, 0x69, 0x37, 0xf3, 0x06, 0x6f, 0xa1, 0xcf, 0xc2, + 0x42, 0xe7, 0x99, 0xe5, 0xf6, 0x22, 0xbb, 0x76, 0x91, 0x4e, 0x39, 0xa9, 0x0b, 0xad, 0x40, 0xb1, + 0xe6, 0x1c, 0x1d, 0xd9, 0x7e, 0xb3, 0x5e, 0xd6, 0x29, 0x5a, 0xd0, 0x46, 0xf7, 0x61, 0xf5, 0x89, + 0x8d, 0x5f, 0x3c, 0xe6, 0xcb, 0x53, 0xed, 0x1d, 0xd9, 0x9e, 0x67, 0x3b, 0x83, 0xce, 0xf1, 0x70, + 0xe8, 0xb8, 0x3e, 0xee, 0x95, 0xe7, 0xd7, 0xb4, 0x9b, 0x45, 0x23, 0x03, 0x0b, 0x6d, 0xc1, 0xf5, + 0x44, 0x8c, 0x07, 0x78, 0x80, 0x5d, 0xcb, 0xb7, 0x9d, 0x41, 0x19, 0x51, 0x7e, 0xc8, 0x42, 0x43, + 0x77, 0xe1, 0xb2, 0x8c, 0xb2, 0xbd, 0x4f, 0x56, 0x0a, 0xf7, 0x1a, 0x43, 0xa7, 0xfb, 0xac, 0xbc, + 0x40, 0xc7, 0x48, 0x47, 0x40, 0xf7, 0x60, 0x25, 0xf1, 0x01, 0x06, 0xb6, 0x7a, 0xaf, 0xca, 0x8b, + 0xf4, 0x5d, 0x46, 0x60, 0x90, 0xa7, 0xd7, 0xeb, 0xad, 0x27, 0xb6, 0x67, 0xef, 0xdb, 0x7d, 0xdb, + 0x7f, 0xb5, 0x69, 0xb9, 0xae, 0x8d, 0x5d, 0x46, 0xbe, 0x44, 0xc9, 0xd3, 0x11, 0xd0, 0x17, 0xa0, + 0x2c, 0x8f, 0xdd, 0x1c, 0x1c, 0x90, 0x0d, 0x60, 0xc4, 0xcb, 0x94, 0x38, 0xb5, 0x1f, 0xd5, 0xe1, + 0x9a, 0x32, 0x70, 0x1d, 0x0f, 0xfb, 0xce, 0x2b, 0xdc, 0xdb, 0x21, 0x2a, 0xa1, 0xeb, 0xf4, 0xcb, + 0x97, 0x28, 0x1b, 0x8c, 0x46, 0x22, 0xfb, 0xa0, 0x20, 0x54, 0xbb, 0xbe, 0xfd, 0x9c, 0x2e, 0xec, + 0x8e, 0x8b, 0x87, 0x96, 0x8b, 0x7b, 0xe5, 0x32, 0x9d, 0x48, 0x16, 0x5a, 0x6c, 0x3e, 0x21, 0xca, + 0x7d, 0x3c, 0xe8, 0xe2, 0x5e, 0xf9, 0x32, 0x1d, 0x67, 0x34, 0x12, 0xda, 0x81, 0x25, 0x05, 0xe1, + 0xbe, 0xeb, 0x0c, 0x7c, 0x1b, 0xbb, 0xe5, 0x15, 0x2e, 0x0a, 0xa1, 0xee, 0x33, 0xc5, 0x2f, 0x2e, + 0x0a, 0xc9, 0x84, 0x2b, 0x6d, 0x28, 0x49, 0xb2, 0x8f, 0x74, 0xc8, 0x1f, 0xe2, 0x57, 0x5c, 0x3d, + 0x92, 0x9f, 0xe8, 0x2d, 0x98, 0x78, 0x6e, 0xf5, 0x8f, 0x31, 0x55, 0x8a, 0x25, 0x59, 0xf6, 0x29, + 0x5d, 0xcb, 0xf6, 0x7c, 0x83, 0x61, 0x7c, 0x21, 0xf7, 0x9e, 0xf6, 0xb0, 0x50, 0x9c, 0xd0, 0x27, + 0x2b, 0xbf, 0xc8, 0xc3, 0x94, 0x79, 0x0e, 0x2a, 0x57, 0x28, 0xbf, 0x7c, 0x92, 0xf2, 0x2b, 0x8c, + 0xa1, 0xfc, 0xde, 0x81, 0x49, 0x2a, 0xc3, 0x5e, 0x79, 0x82, 0x2a, 0xbf, 0x4b, 0x32, 0xb6, 0xd9, + 0xa6, 0x7d, 0xcd, 0xc1, 0x53, 0x47, 0x28, 0x3d, 0x86, 0x8c, 0x6e, 0xc3, 0x62, 0xcb, 0x39, 0xf0, + 0x2d, 0xbb, 0x4f, 0x26, 0x84, 0x5d, 0x31, 0xcb, 0x49, 0x3a, 0xcb, 0xc4, 0xbe, 0x14, 0xf5, 0x3f, + 0x95, 0xaa, 0xfe, 0x55, 0x0d, 0x38, 0x3d, 0xb6, 0x06, 0x8c, 0x6a, 0x57, 0x48, 0xd0, 0xae, 0x29, + 0x5a, 0xad, 0x94, 0xae, 0xd5, 0x3e, 0x80, 0x2b, 0xd5, 0x63, 0xdf, 0x69, 0x0e, 0xba, 0x2e, 0x15, + 0x7d, 0xca, 0x70, 0xa1, 0xda, 0x9a, 0xa1, 0xdc, 0x39, 0x0a, 0xe5, 0x61, 0xa1, 0x58, 0xd4, 0xa7, + 0x2b, 0x7f, 0x92, 0x87, 0x62, 0xcb, 0x39, 0xf8, 0x0d, 0xd8, 0xfa, 0xbb, 0xc4, 0x52, 0x0c, 0xfb, + 0x76, 0xd7, 0x12, 0x9b, 0xbf, 0x22, 0xe3, 0xb7, 0x9c, 0x03, 0xde, 0x2d, 0xed, 0x7f, 0x40, 0x11, + 0xd9, 0x9d, 0xc9, 0x93, 0xd8, 0xa7, 0x96, 0xd3, 0xb5, 0x88, 0x8c, 0xd1, 0xbd, 0x8f, 0xd8, 0x27, + 0xd1, 0x27, 0x9e, 0x27, 0xda, 0xe8, 0x09, 0xbc, 0x31, 0x52, 0x15, 0x85, 0x5b, 0x51, 0xa4, 0x5b, + 0x31, 0x26, 0x76, 0xe5, 0x5b, 0x79, 0x98, 0x21, 0xfb, 0x21, 0x18, 0x1d, 0x95, 0x61, 0x8a, 0x35, + 0xd8, 0xb6, 0x14, 0x0c, 0xd1, 0x44, 0x9b, 0xd2, 0x82, 0xe5, 0xe8, 0x82, 0xbd, 0x11, 0x59, 0xb0, + 0x60, 0x94, 0x0d, 0x81, 0x48, 0xb5, 0x86, 0xb4, 0x6c, 0x8b, 0x30, 0xc1, 0x4c, 0x0b, 0xdb, 0x36, + 0xd6, 0x20, 0x26, 0xb3, 0x85, 0xad, 0x1e, 0x76, 0x9b, 0x75, 0xba, 0x75, 0x05, 0x23, 0x68, 0xd3, + 0x7d, 0xc6, 0xee, 0x51, 0x79, 0x82, 0xef, 0x33, 0x76, 0x8f, 0xd0, 0xc7, 0x30, 0xdf, 0x76, 0x06, + 0x4f, 0x1c, 0xdf, 0x1e, 0x1c, 0x04, 0x53, 0x9a, 0xa4, 0x53, 0xba, 0x95, 0x3a, 0xa5, 0x18, 0x05, + 0x9b, 0x5b, 0x7c, 0xa4, 0x95, 0xff, 0x0f, 0xb3, 0x0a, 0x8e, 0xac, 0xf5, 0x0a, 0x4c, 0xeb, 0x2d, + 0xca, 0x5a, 0x6f, 0x5a, 0x52, 0x70, 0x2b, 0x75, 0x58, 0x4e, 0x7e, 0xd2, 0x49, 0x46, 0xa9, 0x7c, + 0x5b, 0x83, 0x39, 0x95, 0x03, 0xd1, 0x7d, 0x75, 0xa3, 0xe8, 0x38, 0xa5, 0xdb, 0xe5, 0xb4, 0xf7, + 0xdd, 0x2c, 0x12, 0x0e, 0xfa, 0xc1, 0x8f, 0xae, 0x6b, 0x86, 0xba, 0xc1, 0x57, 0x61, 0x5a, 0x0c, + 0x5b, 0xa7, 0x0f, 0x2e, 0x18, 0x21, 0x00, 0xad, 0x41, 0xa9, 0xe9, 0x05, 0x2f, 0x40, 0xb7, 0xa9, + 0x68, 0xc8, 0xa0, 0xca, 0x1f, 0x6b, 0xa1, 0x8b, 0x45, 0x9d, 0x9d, 0x9d, 0x5d, 0xd3, 0xf1, 0xad, + 0x3e, 0x7f, 0xb1, 0xa0, 0x4d, 0x14, 0x51, 0x6d, 0x67, 0xb7, 0xfa, 0xdc, 0xb2, 0xfb, 0xd6, 0x7e, + 0x9f, 0xbd, 0xa4, 0x66, 0x28, 0x30, 0x42, 0xff, 0x18, 0x1f, 0x31, 0x7a, 0xc6, 0x12, 0x41, 0x9b, + 0xd0, 0x3f, 0xc6, 0x47, 0x21, 0x3d, 0xe3, 0x0c, 0x05, 0x56, 0xf9, 0x3d, 0x2d, 0xd5, 0x6e, 0x9a, + 0x96, 0x7b, 0x80, 0x7d, 0xf2, 0xba, 0x5c, 0x73, 0x04, 0x8a, 0x26, 0x04, 0x10, 0x9f, 0x5d, 0xf2, + 0x99, 0xd8, 0x6a, 0x48, 0x90, 0x98, 0x32, 0xcd, 0xc7, 0x95, 0x69, 0xe5, 0x97, 0x33, 0xa0, 0x73, + 0x3f, 0x79, 0x0b, 0x5b, 0xae, 0xbf, 0x8f, 0x2d, 0xff, 0xb7, 0x30, 0x90, 0xd8, 0x00, 0x64, 0x5a, + 0x9e, 0xa0, 0xad, 0xb9, 0xd8, 0x22, 0xda, 0x64, 0x8a, 0x32, 0x40, 0x42, 0x4f, 0x6c, 0x69, 0x8a, + 0x09, 0x76, 0xe6, 0x06, 0xcc, 0x36, 0x07, 0xb6, 0x1f, 0x06, 0x08, 0xd3, 0x14, 0x49, 0x05, 0x12, + 0xac, 0x07, 0x8e, 0xe7, 0xd9, 0x43, 0xd5, 0x64, 0xa9, 0x40, 0xf2, 0x3c, 0x06, 0x78, 0xe8, 0xd8, + 0x03, 0xdc, 0xa3, 0xc6, 0xaa, 0x68, 0x28, 0xb0, 0x5f, 0x7b, 0xd4, 0x90, 0x62, 0x47, 0xe7, 0xc6, + 0x8b, 0x0e, 0x2e, 0x46, 0xa2, 0x83, 0xcf, 0xc2, 0x42, 0xb5, 0x7b, 0x88, 0x7b, 0x04, 0x60, 0x0d, + 0x7a, 0x9b, 0x96, 0xdf, 0x7d, 0xc6, 0x83, 0x88, 0x82, 0x91, 0xd4, 0x45, 0xac, 0x32, 0x87, 0xd4, + 0x71, 0xdf, 0x7e, 0x4e, 0x56, 0xbe, 0x7b, 0x18, 0x0d, 0x26, 0x46, 0xa1, 0x8c, 0x11, 0x91, 0xa0, + 0xf3, 0x8a, 0x48, 0x16, 0xce, 0x21, 0x22, 0x59, 0xcc, 0x8a, 0x48, 0x22, 0xef, 0x53, 0xb3, 0x7c, + 0xab, 0xef, 0x1c, 0x30, 0xf7, 0x98, 0x0d, 0xb1, 0x44, 0x87, 0xc8, 0xc0, 0x42, 0x9b, 0x70, 0x55, + 0xc6, 0x30, 0xf0, 0x53, 0x17, 0x7b, 0xcf, 0xc2, 0x55, 0x61, 0xf1, 0xc5, 0x48, 0x9c, 0xf8, 0x18, + 0xcf, 0xad, 0xbe, 0xdd, 0x23, 0xc2, 0xc3, 0x66, 0x72, 0x89, 0xce, 0x64, 0x24, 0xce, 0xc8, 0x18, + 0xa7, 0x9c, 0x11, 0xe3, 0x8c, 0x8c, 0xae, 0x2e, 0x67, 0x45, 0x57, 0x99, 0x11, 0xd2, 0xca, 0x38, + 0x11, 0xd2, 0xab, 0x48, 0x84, 0x44, 0xdf, 0x8a, 0x71, 0x3c, 0x53, 0xd0, 0x5e, 0xf9, 0x0a, 0x35, + 0xdc, 0x6f, 0xc9, 0x02, 0x37, 0x52, 0xa5, 0x73, 0x29, 0xcc, 0x1a, 0x77, 0x9c, 0xe0, 0xec, 0xea, + 0x39, 0x05, 0x67, 0xd7, 0xce, 0x14, 0x9c, 0xad, 0x9e, 0x32, 0x38, 0xe3, 0xc1, 0x94, 0x09, 0x33, + 0xb5, 0x76, 0xb5, 0xdf, 0x77, 0xba, 0x96, 0x4f, 0x6c, 0x5a, 0x3c, 0x46, 0x5b, 0x84, 0x09, 0xaa, + 0x31, 0xb8, 0x81, 0x63, 0x0d, 0xe6, 0x08, 0x7c, 0xed, 0x18, 0x7b, 0x44, 0x17, 0x31, 0x2b, 0x13, + 0x02, 0x2a, 0xff, 0x56, 0x80, 0x79, 0xe1, 0xa8, 0x8f, 0x36, 0x6b, 0x6b, 0x50, 0x32, 0xac, 0xa7, + 0xbe, 0x6a, 0xd3, 0x64, 0x50, 0x82, 0xe1, 0xcb, 0x27, 0x1a, 0xbe, 0x98, 0x21, 0x28, 0x24, 0x19, + 0x82, 0xb3, 0x39, 0xee, 0xc9, 0x66, 0x6e, 0x32, 0xd5, 0xcc, 0xa9, 0x26, 0x65, 0xea, 0x54, 0x8e, + 0x7e, 0xf1, 0x04, 0x8e, 0xfe, 0x17, 0xa0, 0x1c, 0xd1, 0xd7, 0xa1, 0xd2, 0x99, 0x66, 0x02, 0x9f, + 0xd6, 0x3f, 0x86, 0x32, 0x87, 0xb1, 0x94, 0xf9, 0xf8, 0xc1, 0x46, 0xe9, 0x44, 0xc1, 0x46, 0x03, + 0x4a, 0x52, 0x4c, 0x3d, 0x22, 0xd4, 0x18, 0xe9, 0xa3, 0x56, 0xbe, 0x3e, 0x01, 0xba, 0x79, 0x9e, + 0x0e, 0x57, 0x98, 0x05, 0xc8, 0x9f, 0x24, 0x0b, 0x90, 0xcc, 0x4a, 0x85, 0x54, 0x56, 0x4a, 0xcb, + 0x1a, 0x4c, 0x9c, 0x38, 0x6b, 0x30, 0x39, 0x66, 0xd6, 0xa0, 0x78, 0xea, 0xac, 0xc1, 0xf4, 0xf8, + 0x59, 0x03, 0x48, 0xf7, 0x76, 0x88, 0x6a, 0xc0, 0xc3, 0xbe, 0xf5, 0x0a, 0xf7, 0x5a, 0xde, 0x80, + 0x72, 0x4b, 0xc1, 0x90, 0x41, 0x67, 0xcf, 0x2b, 0xa4, 0x79, 0x4d, 0xb3, 0xa7, 0xf6, 0x9a, 0xe6, + 0x32, 0xbd, 0xa6, 0x87, 0x85, 0xe2, 0x94, 0x5e, 0xac, 0x7c, 0x77, 0x02, 0x8a, 0x46, 0xe7, 0x31, + 0x73, 0x62, 0x75, 0xc8, 0x9b, 0x9e, 0x23, 0xa2, 0x3b, 0xd3, 0x73, 0x88, 0xd6, 0x6d, 0x0e, 0x7a, + 0xf8, 0xa5, 0xd0, 0xba, 0xb4, 0x41, 0x74, 0x5c, 0x0b, 0x5b, 0x1e, 0xde, 0x72, 0xfa, 0x2c, 0xe0, + 0x65, 0x61, 0x8f, 0x0a, 0x24, 0xdb, 0x61, 0xba, 0xc7, 0x03, 0xa2, 0xd1, 0xe9, 0xca, 0xf1, 0xd8, + 0x47, 0x86, 0xa1, 0x87, 0x30, 0xc3, 0x88, 0x6c, 0xcf, 0x77, 0xdc, 0x57, 0x5c, 0x17, 0x2a, 0x31, + 0xb9, 0x98, 0xdd, 0x86, 0x8c, 0xc8, 0xe2, 0x5e, 0x85, 0x96, 0x6d, 0xd4, 0xd7, 0x8e, 0x6d, 0x97, + 0x3d, 0x6e, 0x52, 0x6c, 0x54, 0x00, 0x42, 0x6f, 0xc3, 0xfc, 0x47, 0xd5, 0x96, 0x81, 0xbb, 0x0e, + 0x59, 0x8d, 0xba, 0x7d, 0x80, 0x3d, 0x9f, 0x67, 0xaf, 0xe2, 0x1d, 0xe8, 0x73, 0xb0, 0x24, 0x01, + 0xe9, 0x13, 0x6b, 0xce, 0xf1, 0xc0, 0xa7, 0x1c, 0x59, 0x30, 0x92, 0x3b, 0xc9, 0xc6, 0x48, 0x1d, + 0x35, 0xe7, 0x68, 0xd8, 0xc7, 0xc4, 0x13, 0x1a, 0xf8, 0xae, 0x8d, 0x19, 0x4f, 0x16, 0x8c, 0x51, + 0x28, 0x44, 0x5c, 0xa4, 0xee, 0x4d, 0xcb, 0xc3, 0xe4, 0x75, 0x80, 0x12, 0x26, 0xf4, 0x44, 0xf0, + 0x5b, 0x96, 0xe7, 0x87, 0x7c, 0x9a, 0xd0, 0x83, 0x1e, 0xc2, 0x9a, 0x04, 0xdd, 0x76, 0xed, 0x03, + 0x7b, 0x60, 0xf5, 0xd5, 0x0d, 0x9d, 0xa1, 0xd4, 0x99, 0x78, 0x84, 0x71, 0x13, 0x5e, 0x85, 0x32, + 0x6e, 0xd1, 0x48, 0xea, 0x5a, 0x79, 0x1f, 0xe6, 0x63, 0x1b, 0x99, 0x95, 0x56, 0x28, 0xc8, 0x69, + 0x85, 0x8f, 0x61, 0x9a, 0x9a, 0xc7, 0xae, 0xe3, 0xf6, 0x08, 0x21, 0x79, 0x59, 0x4e, 0x48, 0xde, + 0x6e, 0x1d, 0x0a, 0xe6, 0xab, 0x21, 0xa3, 0x9b, 0x53, 0xd5, 0x06, 0xa3, 0x21, 0xbd, 0x06, 0xc5, + 0x21, 0xfa, 0x96, 0xaa, 0x18, 0xc2, 0xbe, 0x33, 0x06, 0xfd, 0x5d, 0xf9, 0x49, 0x0e, 0x80, 0x8e, + 0x4f, 0x9d, 0x08, 0x82, 0xd2, 0xb6, 0x8e, 0xb0, 0x50, 0xc9, 0xe4, 0xb7, 0xac, 0xf3, 0x73, 0xaa, + 0xce, 0xe7, 0xd3, 0xc9, 0x87, 0xd3, 0x29, 0xc3, 0xd4, 0x63, 0xeb, 0x65, 0xc7, 0xfe, 0x1d, 0x11, + 0xfb, 0x8b, 0x26, 0xb1, 0x0f, 0x42, 0x2d, 0xd7, 0x79, 0x66, 0x28, 0x04, 0xd0, 0x94, 0x51, 0xbb, + 0x59, 0xe7, 0x5c, 0x4c, 0x7f, 0xa3, 0xcf, 0x41, 0xce, 0xec, 0x70, 0xf3, 0xbd, 0xb2, 0xc1, 0xce, + 0x0c, 0x37, 0xc4, 0x99, 0xa1, 0xe4, 0x6f, 0xd1, 0xac, 0xc9, 0x9f, 0xfd, 0xf8, 0xba, 0x66, 0xe4, + 0xcc, 0x0e, 0x31, 0xa8, 0xcd, 0x41, 0xb7, 0x7f, 0xdc, 0xc3, 0x8d, 0x97, 0x43, 0x22, 0x09, 0xdc, + 0x08, 0x71, 0xfd, 0x86, 0x3d, 0x9e, 0x6d, 0xcb, 0xc0, 0x22, 0xae, 0x68, 0xe3, 0x25, 0xc5, 0xd8, + 0xb2, 0xdc, 0x5e, 0xdd, 0x79, 0x31, 0x88, 0x0d, 0xc4, 0x6c, 0x7b, 0x16, 0x5a, 0xa5, 0x02, 0x60, + 0x7a, 0x8e, 0x58, 0xe1, 0x45, 0x98, 0x60, 0x62, 0xc5, 0x36, 0x91, 0x35, 0x2a, 0x3f, 0xd7, 0x88, + 0x47, 0x48, 0xed, 0x23, 0xcd, 0xc1, 0x27, 0xda, 0xc6, 0x3b, 0x30, 0xbd, 0x3d, 0x94, 0x13, 0x1f, + 0x91, 0x7c, 0x69, 0xad, 0x4d, 0x69, 0xb7, 0x87, 0x46, 0x88, 0x87, 0x36, 0x83, 0xb3, 0x42, 0x66, + 0x28, 0x6f, 0x24, 0x9c, 0x15, 0x52, 0x84, 0xf4, 0x03, 0xc3, 0xf3, 0x3e, 0x51, 0xa8, 0xb4, 0xa0, + 0x54, 0x6b, 0x87, 0xc9, 0x84, 0xa4, 0x77, 0x7d, 0x4b, 0xe4, 0x85, 0x73, 0xe9, 0xe7, 0x93, 0x0c, + 0xa3, 0xf2, 0x53, 0xbe, 0x76, 0x96, 0x3f, 0x62, 0xed, 0xc6, 0x1f, 0x2f, 0x7b, 0xc5, 0xc4, 0x83, + 0x7e, 0x8d, 0x2b, 0xf6, 0xcd, 0x22, 0x4c, 0x09, 0x0e, 0x52, 0x82, 0x00, 0x4d, 0x78, 0x5a, 0x1c, + 0x80, 0x36, 0x60, 0xf2, 0x31, 0xf6, 0x9f, 0x39, 0xbd, 0x24, 0x95, 0xc0, 0x7a, 0xa8, 0x4a, 0xe0, + 0x58, 0xe8, 0xae, 0x2c, 0xff, 0x54, 0x94, 0x23, 0xde, 0x47, 0xd8, 0xcb, 0xdf, 0x51, 0xd6, 0x17, + 0x55, 0x9a, 0xe1, 0x0c, 0x5c, 0x3a, 0x2a, 0xf4, 0xa5, 0xdb, 0xd7, 0xa2, 0x19, 0x4e, 0xc5, 0xef, + 0x33, 0x14, 0x12, 0x74, 0x8f, 0x30, 0x43, 0x38, 0xc2, 0x04, 0x1d, 0xe1, 0x6a, 0x02, 0x97, 0x86, + 0x03, 0xc8, 0x04, 0x84, 0xde, 0x94, 0xe8, 0x27, 0xe3, 0xf4, 0x66, 0x8c, 0x5e, 0x22, 0x20, 0xee, + 0x57, 0x28, 0x9e, 0x49, 0xd1, 0x42, 0xd8, 0x6b, 0xc8, 0x82, 0x7c, 0x57, 0x8d, 0xe1, 0xb8, 0xe3, + 0x56, 0x56, 0x27, 0x1e, 0xf6, 0x1b, 0x6a, 0xc4, 0x77, 0x57, 0x95, 0x77, 0x7e, 0x58, 0x54, 0x4e, + 0x13, 0x4e, 0x43, 0xd5, 0x0e, 0x9f, 0x57, 0x04, 0x88, 0x1a, 0xcb, 0x88, 0x0b, 0x2c, 0x75, 0x1b, + 0x8a, 0xb0, 0xdd, 0x55, 0x85, 0x85, 0x1a, 0xce, 0x84, 0x07, 0x8b, 0x7e, 0x43, 0x15, 0xad, 0xf7, + 0x61, 0xb6, 0x8e, 0x89, 0x61, 0xe3, 0xd3, 0xe1, 0x09, 0xbb, 0xcb, 0x4a, 0x26, 0x40, 0x46, 0x30, + 0x54, 0x7c, 0xb4, 0x09, 0x73, 0x3b, 0xae, 0xf3, 0xf2, 0x55, 0xb8, 0x61, 0xb3, 0x5c, 0xc1, 0x4b, + 0x23, 0xa8, 0x18, 0x46, 0x84, 0x82, 0x58, 0xe1, 0x68, 0xbe, 0xbe, 0x7d, 0x7c, 0x44, 0x9d, 0xc0, + 0x82, 0x91, 0xd4, 0x85, 0x36, 0xa5, 0xd3, 0x87, 0x20, 0xc4, 0xbb, 0x98, 0x1e, 0xe2, 0x19, 0x71, + 0x74, 0xba, 0xe6, 0xcf, 0x70, 0xf7, 0x70, 0x0b, 0x5b, 0x7d, 0xff, 0x19, 0x4d, 0xf1, 0x45, 0xd7, + 0x3c, 0xec, 0x36, 0x64, 0x5c, 0x64, 0xc2, 0x62, 0xa7, 0xfb, 0x0c, 0xf7, 0x8e, 0xfb, 0x98, 0xbb, + 0xa8, 0xd4, 0x49, 0xa7, 0xc9, 0xbe, 0xd2, 0xed, 0x35, 0x79, 0x8c, 0x24, 0x3c, 0x23, 0x91, 0xba, + 0xe2, 0x40, 0x89, 0x4a, 0xa2, 0x37, 0x74, 0x06, 0x1e, 0x1e, 0x11, 0x9a, 0x71, 0x33, 0x9d, 0x53, + 0xcc, 0xb4, 0x70, 0x9c, 0x98, 0xf1, 0x16, 0xcd, 0x51, 0xe7, 0x3a, 0x95, 0x0d, 0x40, 0x12, 0x3f, + 0x4b, 0xcf, 0xbd, 0x6f, 0xbb, 0x92, 0x32, 0x12, 0xcd, 0xca, 0x7f, 0x17, 0x68, 0x8e, 0x96, 0xa1, + 0x9d, 0xaf, 0xd6, 0xba, 0x0a, 0xd3, 0x0d, 0xd7, 0x75, 0xdc, 0x9a, 0xd3, 0xc3, 0xf4, 0x15, 0x66, + 0x8d, 0x10, 0x40, 0x5c, 0x71, 0xda, 0x78, 0x8c, 0x3d, 0xcf, 0x3a, 0xc0, 0x3c, 0x27, 0xa1, 0xc0, + 0xd0, 0x2a, 0x40, 0xd3, 0xdb, 0xaa, 0x3e, 0xc2, 0x78, 0x88, 0x5d, 0xaa, 0x75, 0x8a, 0x86, 0x04, + 0x41, 0xef, 0x2b, 0xab, 0xcb, 0xd5, 0xca, 0xa5, 0x98, 0x62, 0x64, 0xdd, 0x5c, 0x33, 0x2a, 0xfb, + 0x41, 0x04, 0x4d, 0x0a, 0x62, 0xb8, 0x66, 0x51, 0x05, 0x4d, 0xea, 0x37, 0x14, 0x6c, 0xc2, 0x6d, + 0x54, 0xd7, 0xf0, 0xc7, 0x17, 0xe3, 0x8f, 0x97, 0xba, 0x0d, 0x19, 0x97, 0x88, 0x58, 0xad, 0x7f, + 0xec, 0xf9, 0xd8, 0xad, 0x63, 0x12, 0x9d, 0x7a, 0x5c, 0xb9, 0x28, 0x22, 0xa6, 0x62, 0x18, 0x11, + 0x0a, 0x74, 0x0f, 0xa6, 0xc3, 0x63, 0x2b, 0x48, 0x60, 0x53, 0xd1, 0xc9, 0x18, 0x14, 0x7b, 0xc7, + 0x7d, 0xdf, 0x08, 0x49, 0xd0, 0x3d, 0x00, 0x49, 0x35, 0x32, 0x1d, 0xb3, 0x2a, 0x0f, 0x10, 0x67, + 0x24, 0x03, 0x22, 0xea, 0x91, 0x08, 0x10, 0x76, 0x99, 0x86, 0x9b, 0x49, 0x58, 0x3c, 0xa9, 0xdf, + 0x50, 0xb0, 0x2b, 0x0f, 0x69, 0x1e, 0x8c, 0xf9, 0xbf, 0xc1, 0xb2, 0xbc, 0x43, 0x2c, 0x28, 0x81, + 0x78, 0x65, 0x8d, 0xda, 0xf5, 0xa5, 0xd8, 0x66, 0x92, 0x5e, 0xbe, 0x95, 0x02, 0xb7, 0xf2, 0xba, + 0xb2, 0x11, 0xc4, 0x7d, 0x7b, 0x42, 0xed, 0x36, 0x77, 0xdf, 0x68, 0xa3, 0xf2, 0x00, 0x66, 0x4d, + 0xcb, 0x3b, 0x34, 0xad, 0xfd, 0x3e, 0xde, 0xf5, 0xb0, 0x4b, 0xc4, 0x88, 0xfc, 0x1d, 0x84, 0xbe, + 0x74, 0xd0, 0x26, 0x7d, 0x3b, 0x96, 0xe7, 0xbd, 0x70, 0xdc, 0x1e, 0x4f, 0x6e, 0x04, 0xed, 0xca, + 0x37, 0x34, 0x32, 0x4b, 0xaa, 0xb7, 0x12, 0xdd, 0x98, 0x74, 0x5f, 0x5c, 0xc9, 0xbf, 0xe4, 0xa3, + 0x67, 0x84, 0xc1, 0x21, 0x6e, 0x41, 0x3e, 0xc4, 0x5d, 0xa5, 0xb6, 0x5f, 0x75, 0xca, 0x25, 0x48, + 0xe5, 0x2f, 0x73, 0x84, 0x87, 0x07, 0x4f, 0xed, 0x83, 0xda, 0x33, 0x6b, 0x70, 0x80, 0xd1, 0x9d, + 0x60, 0x76, 0xfc, 0x2c, 0x73, 0x41, 0x0d, 0x38, 0x68, 0x57, 0xb8, 0x82, 0xec, 0x3d, 0xee, 0x02, + 0x30, 0x72, 0x29, 0x50, 0xb9, 0x1a, 0xcf, 0x6f, 0x84, 0x38, 0x86, 0x84, 0x8f, 0x4c, 0x98, 0x6b, + 0x0e, 0x6c, 0xdf, 0xb6, 0xfa, 0x8f, 0xf1, 0xd1, 0x3e, 0x76, 0x85, 0x57, 0xf6, 0x76, 0xda, 0x08, + 0x1b, 0x2a, 0x3a, 0x0b, 0x9d, 0x23, 0x63, 0xac, 0x54, 0x61, 0x21, 0x01, 0xed, 0x44, 0xe7, 0xbd, + 0x6f, 0xc1, 0x6c, 0xe7, 0xd9, 0xb1, 0xdf, 0x73, 0x5e, 0x0c, 0x98, 0x69, 0x23, 0x7b, 0x43, 0x7e, + 0x04, 0x5b, 0x26, 0x9a, 0x95, 0x7f, 0x9c, 0x80, 0x8b, 0x11, 0x15, 0x9e, 0xb8, 0xbb, 0x37, 0x60, + 0x76, 0xd3, 0x71, 0x7c, 0xcf, 0x77, 0xad, 0xe1, 0xd0, 0x1e, 0x1c, 0xd0, 0x87, 0x16, 0x0d, 0x15, + 0x48, 0x54, 0x03, 0xcf, 0xd9, 0xd0, 0x05, 0xcd, 0xd3, 0x05, 0x55, 0x54, 0x83, 0xd4, 0x6d, 0xc8, + 0xb8, 0x4c, 0x27, 0x85, 0x4b, 0xc5, 0xdd, 0xb5, 0x72, 0xda, 0x52, 0x1a, 0xea, 0xee, 0xbf, 0x1f, + 0x79, 0x63, 0xee, 0xab, 0x5d, 0x56, 0x15, 0x83, 0x84, 0x60, 0x44, 0x56, 0xe8, 0x11, 0xcc, 0xb3, + 0xc4, 0x9a, 0x94, 0x69, 0xe3, 0x9a, 0x55, 0x71, 0x19, 0x63, 0x48, 0x46, 0x9c, 0x2e, 0xee, 0x8a, + 0x4c, 0x9d, 0xd0, 0x15, 0x79, 0x04, 0xf3, 0x0f, 0x1d, 0x7b, 0xc0, 0x32, 0xd5, 0x5c, 0xff, 0x71, + 0x45, 0xab, 0xcc, 0x26, 0x86, 0x64, 0xc4, 0xe9, 0xd0, 0x16, 0xe8, 0x6c, 0x74, 0xea, 0xab, 0xb0, + 0x09, 0x4d, 0xc7, 0x5d, 0xd1, 0x28, 0x8e, 0x11, 0xa3, 0x22, 0xdb, 0x5b, 0xed, 0xf5, 0x84, 0x14, + 0x26, 0xf9, 0x76, 0x52, 0xb7, 0x21, 0xe3, 0x12, 0xcd, 0x1f, 0xb0, 0x0a, 0xa3, 0x2e, 0xc5, 0x35, + 0xbf, 0x8a, 0x61, 0x44, 0x28, 0x2a, 0x38, 0xd9, 0x57, 0x49, 0xe4, 0xd7, 0x08, 0x27, 0xe6, 0xc6, + 0xe7, 0xc4, 0xca, 0x9f, 0xe7, 0x60, 0x39, 0x92, 0xae, 0x13, 0x87, 0x40, 0x95, 0xc0, 0x35, 0x26, + 0x0f, 0x61, 0xda, 0x7a, 0xda, 0x50, 0x60, 0x34, 0xd9, 0x26, 0xe3, 0xe4, 0x18, 0x8e, 0x0c, 0x23, + 0x7a, 0xb6, 0xf1, 0x92, 0xa8, 0x20, 0xdb, 0xe7, 0x45, 0x11, 0x41, 0x9b, 0xb8, 0x90, 0x7c, 0x3c, + 0xd3, 0x3e, 0xc2, 0xce, 0xb1, 0x6f, 0xda, 0xdd, 0x43, 0x8f, 0x6b, 0xc7, 0xa4, 0x2e, 0x42, 0x61, + 0x26, 0x50, 0x30, 0xa5, 0x99, 0xd4, 0x85, 0x3e, 0x07, 0x4b, 0x0d, 0xa2, 0x2e, 0x2c, 0x1f, 0xd7, + 0x8e, 0x5d, 0x17, 0x0f, 0x7c, 0x8a, 0xe3, 0xf1, 0x93, 0x8b, 0xe4, 0xce, 0xca, 0xad, 0x04, 0xae, + 0x64, 0xaf, 0x62, 0x7b, 0xb4, 0xbe, 0x83, 0x2d, 0x47, 0xd0, 0xae, 0xf4, 0x13, 0x84, 0x0a, 0xdd, + 0x81, 0x02, 0xb1, 0x37, 0x5c, 0x4b, 0x2b, 0x32, 0xa1, 0x18, 0x2a, 0xae, 0xab, 0x29, 0x32, 0x5d, + 0x54, 0xcb, 0x3b, 0xac, 0x5b, 0xbe, 0xb5, 0x6f, 0x79, 0x42, 0xe5, 0x29, 0x30, 0xa2, 0xf5, 0x54, + 0x29, 0x4a, 0xd7, 0x7a, 0x6f, 0xc7, 0x45, 0x62, 0x04, 0xf6, 0x9b, 0x0a, 0xdb, 0xa7, 0x7b, 0xb3, + 0x95, 0x5f, 0x68, 0x51, 0x2e, 0x3f, 0xed, 0xa9, 0x04, 0x7a, 0x92, 0x62, 0x5b, 0x36, 0xd2, 0xe5, + 0x65, 0x1c, 0xeb, 0x42, 0x64, 0x85, 0xec, 0x21, 0x3f, 0x57, 0xa0, 0xbf, 0xcf, 0xc3, 0xe2, 0xfc, + 0x38, 0xa7, 0xba, 0x94, 0x41, 0xa1, 0x95, 0x26, 0x15, 0x5a, 0x7d, 0x91, 0x55, 0x2b, 0x58, 0x83, + 0x9e, 0x28, 0xf9, 0xba, 0x32, 0x22, 0xbe, 0x10, 0x67, 0x59, 0x82, 0x84, 0x2c, 0xa5, 0x48, 0xc7, + 0xf3, 0xc8, 0x40, 0xa4, 0xe0, 0x6b, 0x00, 0x1c, 0x8b, 0x08, 0x5c, 0x81, 0x0e, 0x7d, 0x6d, 0xc4, + 0xd0, 0xcd, 0xba, 0xc8, 0x17, 0x84, 0x64, 0xe8, 0x23, 0x58, 0x4a, 0x3c, 0xc8, 0xe2, 0xa6, 0xe4, + 0x35, 0x79, 0xbc, 0xe4, 0x22, 0xe4, 0x64, 0xfa, 0xec, 0xa3, 0xef, 0xc9, 0x31, 0x8e, 0xbe, 0x2b, + 0x7f, 0x95, 0x4b, 0x99, 0x1f, 0x61, 0x24, 0x76, 0xb6, 0xcc, 0x44, 0x90, 0xec, 0x6b, 0x08, 0x20, + 0xab, 0xd6, 0x18, 0x10, 0x99, 0xea, 0x71, 0x93, 0x2d, 0x9a, 0x29, 0xd5, 0x73, 0xb7, 0x61, 0x31, + 0x28, 0x1b, 0xa0, 0x95, 0xd5, 0x2c, 0x69, 0xcf, 0x19, 0x26, 0xb1, 0x0f, 0x6d, 0x00, 0x4a, 0x28, + 0x8d, 0x60, 0xfa, 0x27, 0xa1, 0x27, 0x52, 0x27, 0x35, 0x19, 0xab, 0x93, 0x5a, 0x84, 0x09, 0x56, + 0x56, 0xc0, 0xea, 0x85, 0x58, 0x83, 0x68, 0x1a, 0xf2, 0xd2, 0x7e, 0x58, 0x96, 0x18, 0xb4, 0x2b, + 0xff, 0xae, 0xa9, 0xd5, 0x11, 0xc1, 0xea, 0x08, 0xcd, 0x2d, 0x6b, 0x5c, 0x6d, 0x3c, 0x8d, 0x9b, + 0x4b, 0xd7, 0xb8, 0xef, 0xc2, 0x72, 0xa8, 0x39, 0x14, 0x22, 0xb6, 0x96, 0x29, 0xbd, 0xe9, 0x7a, + 0xb7, 0x30, 0x4a, 0xef, 0xfe, 0xd3, 0x2c, 0x94, 0xf8, 0x2c, 0x68, 0x04, 0x23, 0x8a, 0x55, 0x35, + 0xa9, 0x58, 0xf5, 0xff, 0x56, 0x35, 0x58, 0x35, 0xc8, 0x73, 0x16, 0xa9, 0x30, 0xbf, 0x9e, 0x90, + 0x7c, 0xa2, 0x65, 0x98, 0x63, 0xde, 0x24, 0x99, 0x3e, 0xd5, 0x4d, 0x12, 0x48, 0xae, 0x41, 0x53, + 0x8b, 0x0a, 0x4a, 0xe3, 0x54, 0x97, 0xcd, 0x64, 0x56, 0x97, 0xcd, 0x9e, 0xaa, 0xba, 0x6c, 0xee, + 0x54, 0x77, 0x52, 0x2e, 0x8e, 0x73, 0x27, 0x45, 0x1f, 0xaf, 0xea, 0x6c, 0x3e, 0x52, 0x75, 0x96, + 0x71, 0x1a, 0x8a, 0xce, 0xa3, 0x86, 0x6c, 0xe1, 0xbc, 0x6a, 0xc8, 0x16, 0xcf, 0xa1, 0x86, 0x6c, + 0xe9, 0xec, 0x35, 0x64, 0xcb, 0xe7, 0x52, 0x43, 0x76, 0xe9, 0x1c, 0x6a, 0xc8, 0xca, 0x63, 0xd4, + 0x90, 0x8d, 0xbe, 0xa5, 0x73, 0x39, 0xf3, 0x96, 0xce, 0xa8, 0x1a, 0xb4, 0x95, 0xb3, 0xd4, 0xa0, + 0x5d, 0x39, 0x73, 0x0d, 0xda, 0xd5, 0x73, 0xba, 0xa5, 0x73, 0xed, 0x9c, 0x0a, 0xc1, 0x56, 0xcf, + 0x54, 0x08, 0x76, 0xfd, 0x37, 0xeb, 0x96, 0xce, 0xf7, 0x72, 0xec, 0x62, 0x24, 0xbf, 0x25, 0xc8, + 0x0d, 0x9f, 0x96, 0x7c, 0x4b, 0xd0, 0xf2, 0xf1, 0x06, 0xc3, 0x50, 0x74, 0x3b, 0x03, 0x65, 0x6f, + 0x64, 0x6e, 0x9c, 0x8d, 0x4c, 0x5d, 0xb8, 0xfc, 0x69, 0x17, 0xce, 0x80, 0x92, 0x34, 0xe9, 0x84, + 0x85, 0xfb, 0x8c, 0xba, 0x70, 0x97, 0x52, 0xcc, 0x9a, 0xec, 0x59, 0xff, 0x6b, 0x81, 0x96, 0x39, + 0x9d, 0x8b, 0xf1, 0xff, 0xa4, 0x32, 0xe9, 0xb7, 0xb8, 0x32, 0x29, 0xc3, 0xb2, 0xce, 0x8e, 0x5b, + 0x67, 0xf4, 0xd7, 0x1a, 0xbb, 0x2d, 0x97, 0x29, 0x87, 0x66, 0x96, 0x1c, 0x9e, 0x8d, 0xdf, 0xcd, + 0x64, 0x7e, 0xff, 0x87, 0x3c, 0x80, 0x14, 0x95, 0x27, 0xe5, 0x76, 0x84, 0x08, 0xe4, 0x24, 0x11, + 0xb8, 0x01, 0xb3, 0x44, 0xed, 0xe0, 0x81, 0xea, 0xda, 0xaa, 0xc0, 0x08, 0xd7, 0x14, 0xc6, 0xe6, + 0x9a, 0x6c, 0x9f, 0x64, 0xe2, 0xbc, 0x7c, 0x92, 0xc9, 0x73, 0xf0, 0x49, 0xa6, 0xce, 0x76, 0xd3, + 0xb6, 0x98, 0x65, 0xc3, 0x2b, 0x7f, 0xaf, 0x05, 0x9b, 0x44, 0xd8, 0xe8, 0x83, 0x08, 0x1b, 0x55, + 0x62, 0x27, 0xa6, 0x59, 0x9c, 0xf4, 0x61, 0x16, 0x27, 0xbd, 0xad, 0x72, 0xd2, 0x72, 0xc2, 0x13, + 0x1c, 0x17, 0xcb, 0x8c, 0xf4, 0xc3, 0x5c, 0xf4, 0x3c, 0x37, 0x2d, 0xb1, 0xad, 0x32, 0x4e, 0x2e, + 0x9b, 0x71, 0xf2, 0xe7, 0xc8, 0x38, 0x85, 0xf3, 0x62, 0x9c, 0x89, 0x73, 0x60, 0x9c, 0xc9, 0x0c, + 0xc6, 0xa9, 0x7c, 0xb7, 0x10, 0x3d, 0xc1, 0x43, 0xef, 0x40, 0x91, 0x8b, 0xb2, 0xd8, 0xfe, 0x85, + 0x04, 0x31, 0x17, 0xe1, 0x88, 0x40, 0x25, 0x64, 0x35, 0x41, 0x96, 0x8b, 0x93, 0xd5, 0x54, 0x32, + 0x81, 0x8a, 0xde, 0xa3, 0x35, 0x67, 0x9c, 0x8e, 0x59, 0xb1, 0xc5, 0xa4, 0x92, 0x0e, 0x4e, 0x18, + 0x22, 0xa3, 0x7b, 0x50, 0x0a, 0x19, 0x45, 0x64, 0x89, 0x52, 0xf8, 0x48, 0x1c, 0x9a, 0x4a, 0x04, + 0xa8, 0x2e, 0xd2, 0x8b, 0x3d, 0x3e, 0x02, 0xab, 0x90, 0x2c, 0xc7, 0x73, 0xe8, 0x3d, 0x79, 0x0c, + 0x95, 0x28, 0x3d, 0xcb, 0x34, 0xf9, 0xab, 0xce, 0x32, 0x4d, 0x9d, 0xc9, 0x27, 0x2a, 0x9e, 0xd2, + 0x27, 0xaa, 0xfc, 0xa1, 0x06, 0x25, 0xce, 0x31, 0xd4, 0x7f, 0xf9, 0x3c, 0x65, 0x17, 0xe6, 0x85, + 0x68, 0xdc, 0x0b, 0x09, 0xdc, 0x47, 0xde, 0xa3, 0x1c, 0x77, 0x06, 0xe8, 0xe8, 0x2e, 0xdb, 0x7b, + 0x46, 0x9b, 0xe3, 0xab, 0x1f, 0xba, 0x9e, 0xe2, 0xdc, 0x41, 0x26, 0x0e, 0x09, 0x2a, 0xdf, 0x29, + 0xc0, 0x12, 0x4f, 0x73, 0x8a, 0xc3, 0x12, 0x5e, 0x2e, 0xf3, 0x06, 0xcc, 0xb5, 0x8f, 0x8f, 0xb6, + 0x9f, 0x86, 0x83, 0x33, 0xe7, 0x2a, 0x02, 0x25, 0xaa, 0x82, 0x42, 0x82, 0xf9, 0x33, 0x03, 0xa4, + 0x02, 0xd1, 0x3a, 0xe8, 0x82, 0x2e, 0xb8, 0x58, 0xc0, 0xb2, 0x42, 0x31, 0x38, 0x89, 0xc9, 0xdb, + 0xf8, 0xa5, 0x1f, 0x14, 0x34, 0xf0, 0x16, 0x32, 0xa1, 0xc4, 0x7e, 0x6d, 0xbe, 0x7a, 0x84, 0x45, + 0x2d, 0xee, 0x6d, 0x99, 0x37, 0x12, 0xdf, 0x64, 0x43, 0x22, 0x62, 0xe9, 0x5f, 0x79, 0x18, 0xf4, + 0x34, 0xa9, 0xd4, 0x84, 0x5d, 0x74, 0x7d, 0x6f, 0x8c, 0xb1, 0xa3, 0xa4, 0xd1, 0x1b, 0xaf, 0x41, + 0x39, 0x0a, 0xf5, 0xe5, 0x0e, 0xc4, 0xf9, 0x18, 0x2f, 0x3b, 0x15, 0xd9, 0x9e, 0x78, 0xcf, 0xca, + 0x3d, 0xd0, 0xa3, 0x13, 0x4f, 0xbe, 0x76, 0x92, 0x5c, 0x87, 0xaa, 0x5c, 0x92, 0x55, 0x26, 0x97, + 0x35, 0x8a, 0x92, 0xc2, 0xfe, 0xa5, 0x06, 0x97, 0x0d, 0xec, 0xb1, 0x9c, 0xff, 0x47, 0x96, 0x8f, + 0xdd, 0x23, 0xcb, 0x3d, 0x14, 0x3c, 0x12, 0xee, 0x94, 0xa6, 0xec, 0xd4, 0x97, 0xd4, 0x9d, 0x62, + 0x5c, 0xf9, 0x6e, 0x24, 0x21, 0x93, 0x3c, 0x66, 0xc6, 0x6e, 0x25, 0xaf, 0x62, 0xfe, 0x57, 0xb5, + 0x8a, 0x95, 0x7f, 0x29, 0xb0, 0x2b, 0xc1, 0x23, 0x23, 0x8d, 0x4f, 0x6e, 0xe7, 0x7c, 0x72, 0x3b, + 0x67, 0xbc, 0xdb, 0x39, 0xdf, 0xcb, 0xf1, 0x4f, 0x33, 0x10, 0x07, 0xf1, 0x5e, 0x10, 0x78, 0x32, + 0x95, 0xbf, 0x16, 0x33, 0xd9, 0xd4, 0x3d, 0xa4, 0x28, 0xaa, 0x7b, 0xc8, 0x74, 0xea, 0xbd, 0xc0, + 0xc1, 0xcc, 0x8d, 0xa2, 0x4f, 0x75, 0x2f, 0x3b, 0x50, 0x92, 0x06, 0x4f, 0x38, 0xd9, 0xda, 0x50, + 0xdd, 0xcb, 0xd4, 0x7b, 0xf0, 0xb2, 0xda, 0xe9, 0x64, 0xf9, 0xac, 0x59, 0x83, 0x26, 0x85, 0x3f, + 0xff, 0x59, 0x54, 0xcb, 0x8b, 0x12, 0xa5, 0xf0, 0x7d, 0xc5, 0xa4, 0x26, 0x26, 0x13, 0xc2, 0x6e, + 0xe1, 0xcb, 0xc8, 0x46, 0xf8, 0x4e, 0x10, 0x02, 0x72, 0x5f, 0x76, 0x21, 0x21, 0xf0, 0x13, 0xc5, + 0x32, 0x22, 0x58, 0x7c, 0x37, 0xdc, 0x50, 0x1e, 0x3a, 0x2d, 0x26, 0x6d, 0x43, 0xc8, 0xe5, 0x7c, + 0xf3, 0xef, 0x04, 0x79, 0x1f, 0x7e, 0x94, 0xb6, 0x90, 0x90, 0xed, 0x11, 0x0f, 0x13, 0x19, 0xa2, + 0x5b, 0xa2, 0x28, 0x9a, 0x1d, 0x2c, 0x28, 0xc7, 0xc4, 0xa2, 0x10, 0x4e, 0x29, 0x8d, 0x6e, 0x73, + 0x59, 0xe7, 0x27, 0x7d, 0xbc, 0x38, 0x6b, 0x8a, 0x52, 0xaf, 0x46, 0x0f, 0x99, 0x55, 0x2c, 0x23, + 0x81, 0x12, 0x35, 0x22, 0x75, 0x53, 0x5c, 0xb0, 0x33, 0xcf, 0xab, 0x23, 0xd5, 0x56, 0xc2, 0x6e, + 0xf4, 0xf8, 0x7d, 0x13, 0xde, 0x42, 0x8f, 0x54, 0xbb, 0x01, 0xf1, 0x5b, 0xab, 0x32, 0x17, 0x64, + 0x98, 0x8a, 0xbb, 0x72, 0x34, 0xc6, 0x0b, 0x2b, 0x96, 0x93, 0x63, 0x30, 0x71, 0xf0, 0x29, 0x45, + 0x6f, 0xf2, 0x81, 0xc2, 0xcc, 0xc9, 0xae, 0xab, 0x27, 0xd5, 0xba, 0xce, 0xa6, 0xd7, 0xba, 0x6e, + 0x25, 0x39, 0x20, 0x73, 0x99, 0x0a, 0x33, 0xc1, 0xc5, 0xb8, 0x0b, 0x97, 0xe3, 0x26, 0x70, 0x07, + 0x0f, 0x7a, 0xf6, 0xe0, 0x80, 0x9e, 0x6f, 0x14, 0x8d, 0x74, 0x04, 0xb4, 0x09, 0x57, 0x15, 0x73, + 0x4c, 0x0d, 0xb4, 0x14, 0x4a, 0xb1, 0x3b, 0xf2, 0x23, 0x71, 0x48, 0x08, 0x9d, 0xf0, 0x00, 0x91, + 0x01, 0x66, 0x77, 0xe5, 0x47, 0x60, 0xa0, 0x0f, 0xe0, 0x4a, 0xbc, 0x37, 0xb8, 0x81, 0x24, 0x0e, + 0x4a, 0x46, 0xa0, 0x9c, 0xd9, 0xe0, 0xff, 0xa9, 0x06, 0x33, 0x72, 0x70, 0x92, 0x18, 0x1e, 0x5f, + 0x85, 0x69, 0x76, 0x8c, 0x29, 0xaa, 0x68, 0xa6, 0x8d, 0x10, 0x80, 0xca, 0x30, 0xa5, 0x5a, 0x79, + 0xd1, 0x94, 0x4e, 0x9b, 0x0a, 0xca, 0x69, 0xd3, 0x0a, 0x14, 0xeb, 0xce, 0x8b, 0x01, 0xed, 0x99, + 0xa0, 0x3d, 0x41, 0xbb, 0xf2, 0x17, 0x15, 0xd0, 0x85, 0x6c, 0x07, 0x37, 0xe1, 0x82, 0x7b, 0x6f, + 0x9a, 0x7c, 0xef, 0x2d, 0x29, 0x05, 0x14, 0xba, 0x68, 0x79, 0xc5, 0x45, 0xdb, 0x56, 0x45, 0x8d, + 0x05, 0x7e, 0x9f, 0x49, 0x52, 0x28, 0xc1, 0x05, 0xb7, 0xd1, 0xe2, 0x96, 0xf4, 0x11, 0x99, 0xff, + 0x75, 0x7d, 0xd5, 0x03, 0x3d, 0x52, 0xe5, 0x20, 0x0e, 0x4f, 0x6f, 0x8f, 0x7c, 0xd5, 0x28, 0x91, + 0x6c, 0x3e, 0x63, 0x23, 0xa2, 0xa6, 0x1c, 0x82, 0xb1, 0x2f, 0xfc, 0x7d, 0x7a, 0xe4, 0xf0, 0x01, + 0x36, 0x5b, 0xc7, 0x90, 0x5a, 0x36, 0x0b, 0x30, 0xb6, 0x59, 0x90, 0x0c, 0x57, 0xe9, 0x54, 0x86, + 0x6b, 0xe6, 0x04, 0x86, 0x2b, 0x62, 0x66, 0x67, 0x4f, 0x6c, 0x66, 0x63, 0x36, 0x64, 0xee, 0x54, + 0x36, 0x44, 0x55, 0xef, 0x17, 0x4f, 0xa8, 0xde, 0x63, 0x79, 0x0b, 0xfd, 0x34, 0x79, 0x8b, 0x14, + 0x65, 0x3f, 0x7f, 0x42, 0x65, 0x8f, 0xce, 0x5d, 0xd9, 0x2f, 0x9c, 0x55, 0xd9, 0x2f, 0x9e, 0x59, + 0xd9, 0x2f, 0x9d, 0x55, 0xd9, 0x2f, 0x67, 0x2a, 0x7b, 0xf4, 0x6e, 0xac, 0x26, 0x51, 0x54, 0xf5, + 0xb0, 0x73, 0xdf, 0x94, 0xde, 0x84, 0x10, 0x23, 0xac, 0x15, 0x2a, 0x27, 0x86, 0x18, 0x61, 0xe9, + 0xd0, 0x57, 0x61, 0x31, 0xd2, 0x27, 0xce, 0x78, 0x63, 0x41, 0x6e, 0x4c, 0xee, 0x93, 0x08, 0x99, + 0x0a, 0x48, 0x1c, 0x13, 0x0d, 0x63, 0xef, 0x57, 0x6b, 0x8b, 0x33, 0xe1, 0x58, 0x82, 0x22, 0xeb, + 0x69, 0x9c, 0x94, 0x3d, 0x2f, 0x65, 0xdc, 0x84, 0x27, 0x9a, 0x6d, 0x71, 0x90, 0x7c, 0xe2, 0x27, + 0x9a, 0xa3, 0x9e, 0xc8, 0x3b, 0xd1, 0x16, 0x5c, 0x8f, 0xf4, 0xf0, 0x02, 0x36, 0xaf, 0xea, 0x79, + 0xf6, 0xc1, 0x20, 0xfc, 0x84, 0x48, 0x06, 0x1a, 0x6a, 0xc1, 0x6b, 0xd1, 0xb7, 0x0a, 0x0a, 0xd9, + 0x82, 0xb1, 0xd8, 0x29, 0x74, 0x36, 0x62, 0x6a, 0x28, 0x19, 0x72, 0xca, 0xea, 0x88, 0x50, 0x32, + 0xe4, 0x97, 0xcd, 0x94, 0x1a, 0x2c, 0xc1, 0xa9, 0xd7, 0xe3, 0x15, 0x0a, 0x51, 0x9c, 0xd4, 0x93, + 0x09, 0x96, 0x9f, 0x5e, 0xa3, 0xb2, 0x3a, 0x02, 0x03, 0x3d, 0x84, 0xb5, 0xc4, 0xea, 0x05, 0xb9, + 0x94, 0xed, 0x35, 0x3a, 0x8f, 0x4c, 0xbc, 0x31, 0x2a, 0x37, 0x2a, 0x63, 0x55, 0x6e, 0x7c, 0x5d, + 0x83, 0x6b, 0x89, 0x53, 0xa6, 0xe9, 0x0b, 0xc2, 0x71, 0xaf, 0x53, 0x8e, 0x7b, 0x7f, 0x24, 0xc7, + 0x8d, 0x1c, 0x81, 0x31, 0xde, 0xe8, 0xa7, 0xa0, 0xdf, 0x4f, 0x2b, 0x92, 0x13, 0xa2, 0x76, 0x83, + 0x4e, 0xe3, 0xde, 0xc9, 0xa7, 0xa1, 0x08, 0xdc, 0xc8, 0x67, 0xa0, 0x6f, 0x68, 0x29, 0x47, 0x19, + 0xd4, 0x64, 0xb1, 0x79, 0x7c, 0x8a, 0xce, 0xa3, 0x7a, 0xf2, 0x79, 0x84, 0x63, 0xb0, 0xa9, 0x64, + 0x3d, 0x09, 0xfd, 0x91, 0x96, 0xc2, 0xfb, 0xb5, 0xb6, 0xf8, 0xa0, 0xd0, 0x1b, 0x74, 0x32, 0x1f, + 0x9c, 0x66, 0x51, 0xf8, 0x10, 0x6c, 0x2e, 0x19, 0xcf, 0x41, 0xdf, 0xd4, 0xe0, 0xb5, 0xf4, 0xe9, + 0x8a, 0xd9, 0xbc, 0x49, 0x67, 0x53, 0x3b, 0xe5, 0xd2, 0x28, 0x13, 0xca, 0x7e, 0x5a, 0xaa, 0x44, + 0x0b, 0xe3, 0x7b, 0x73, 0x84, 0x44, 0x0b, 0xfb, 0xfb, 0x2d, 0x0d, 0x2a, 0x23, 0x5f, 0x9d, 0x15, + 0x4e, 0xbe, 0x45, 0x5f, 0xac, 0x7e, 0xfa, 0x65, 0xa6, 0xc3, 0xb0, 0x37, 0x1b, 0xe3, 0x79, 0xe8, + 0x3b, 0x1a, 0x7c, 0x2a, 0x6b, 0x01, 0xd8, 0xcc, 0xd6, 0xe9, 0xcc, 0x1e, 0x9c, 0x69, 0xc9, 0xa5, + 0xc9, 0x8d, 0xf7, 0xd4, 0x33, 0x27, 0xc5, 0x3f, 0x86, 0xa5, 0x44, 0xd7, 0xfe, 0x84, 0x79, 0x2a, + 0xe5, 0x1e, 0xa0, 0x34, 0xfc, 0x5d, 0xfa, 0x45, 0xc9, 0x94, 0xa4, 0x5a, 0xe6, 0xe4, 0x1e, 0xc0, + 0xe5, 0x54, 0x07, 0x21, 0x6b, 0xa0, 0xa2, 0x3c, 0x50, 0x33, 0x56, 0x14, 0x21, 0xab, 0xa2, 0x33, + 0x0e, 0x65, 0x9e, 0x76, 0xa8, 0x9d, 0x14, 0x8e, 0x57, 0xb4, 0xf5, 0x89, 0x46, 0xdc, 0x4e, 0xd1, + 0x0d, 0xa7, 0x7e, 0x5b, 0x03, 0x6e, 0x8c, 0xa3, 0x41, 0x4f, 0x34, 0xe6, 0x87, 0xf0, 0xfa, 0x18, + 0x8a, 0xf0, 0x44, 0x8c, 0x62, 0xc2, 0x1b, 0xe3, 0x69, 0xb3, 0x13, 0x8d, 0xba, 0x0b, 0x6f, 0x8e, + 0xa9, 0x4a, 0x4e, 0x34, 0xec, 0x97, 0x60, 0x7d, 0x7c, 0x3d, 0x70, 0xa2, 0x54, 0x4d, 0x93, 0xd5, + 0x17, 0x89, 0x8f, 0xb7, 0x9e, 0xe1, 0xeb, 0x54, 0x95, 0xbf, 0xc9, 0xc1, 0x62, 0xd2, 0x15, 0xd9, + 0x11, 0x37, 0x55, 0x76, 0x62, 0x9f, 0xea, 0xdd, 0xc8, 0xba, 0x70, 0xab, 0x7e, 0xb2, 0x37, 0x76, + 0x30, 0x73, 0x2e, 0x1f, 0xee, 0x5d, 0x31, 0xb3, 0xbf, 0xac, 0x3b, 0xaa, 0x00, 0x49, 0x5a, 0x51, + 0x79, 0xad, 0xbf, 0xab, 0x01, 0x6c, 0x5a, 0xdd, 0xc3, 0xe3, 0x21, 0x3d, 0xdb, 0x49, 0x3b, 0xf8, + 0x6b, 0x26, 0x1d, 0xfc, 0xbd, 0xa9, 0xdc, 0xce, 0x09, 0x06, 0x19, 0x9d, 0x4f, 0x3a, 0x73, 0x22, + 0xef, 0x0f, 0x34, 0x71, 0x6e, 0xd5, 0xf4, 0xf1, 0x51, 0xe2, 0x87, 0x72, 0x2a, 0x30, 0xc3, 0xef, + 0x14, 0x3c, 0x91, 0x4e, 0x3f, 0x15, 0x18, 0xc1, 0xa9, 0xe3, 0xa7, 0xd6, 0x71, 0x9f, 0xe3, 0xf0, + 0xaf, 0xd3, 0xca, 0x30, 0xb2, 0x45, 0xcd, 0x81, 0x8f, 0xdd, 0x81, 0xd5, 0xe7, 0x07, 0x76, 0x41, + 0xbb, 0xf2, 0xb7, 0x9a, 0x7c, 0x7c, 0x86, 0xbe, 0x08, 0x53, 0x35, 0x67, 0xe0, 0x63, 0xfa, 0x3d, + 0x99, 0x78, 0x11, 0x7f, 0x80, 0xb8, 0xc1, 0xb1, 0xd8, 0xc2, 0x08, 0x9a, 0x15, 0x83, 0xde, 0x07, + 0x0d, 0x3a, 0x4e, 0x58, 0x12, 0x14, 0x2e, 0x87, 0xbc, 0x50, 0xbf, 0x1b, 0x9e, 0xd3, 0xa1, 0x77, + 0xc2, 0xdb, 0xd2, 0xb1, 0xca, 0x37, 0x81, 0xb4, 0x41, 0x31, 0xd8, 0xc4, 0x18, 0xf6, 0xca, 0x7b, + 0x00, 0x21, 0xf0, 0x44, 0xe7, 0xcb, 0x6f, 0x2a, 0x1f, 0x69, 0x18, 0x71, 0x8b, 0xec, 0x63, 0x98, + 0x8f, 0xdd, 0x57, 0x42, 0x37, 0x60, 0x96, 0x7d, 0xf7, 0x49, 0x5c, 0x81, 0x62, 0x44, 0x2a, 0x90, + 0x6e, 0x33, 0x27, 0x91, 0xbe, 0x15, 0xa6, 0xc0, 0xd6, 0x5f, 0x00, 0xec, 0x0e, 0x7b, 0x96, 0xcf, + 0x32, 0xb8, 0x97, 0x60, 0x41, 0xf9, 0x8e, 0x14, 0xeb, 0xd2, 0x2f, 0xa0, 0x25, 0x98, 0x17, 0xdf, + 0x07, 0x6b, 0x75, 0xda, 0x1c, 0xac, 0xa1, 0x05, 0xb8, 0xb8, 0xeb, 0x61, 0x97, 0xbe, 0x3e, 0x07, + 0xe6, 0xd0, 0x2c, 0x4c, 0x9b, 0x9d, 0x6d, 0xde, 0xcc, 0x13, 0xd2, 0xe0, 0x5b, 0x5f, 0x01, 0x69, + 0x61, 0x7d, 0x03, 0xa6, 0x83, 0xcf, 0xa6, 0xa3, 0x8b, 0x50, 0x6a, 0x3b, 0xee, 0x91, 0xd5, 0xa7, + 0x4d, 0xfd, 0x02, 0xd2, 0x61, 0x86, 0x5f, 0x95, 0x61, 0x10, 0x6d, 0xfd, 0xe7, 0x05, 0x80, 0xf0, + 0xfb, 0x0a, 0x68, 0x0e, 0xc0, 0xec, 0x6c, 0xef, 0xed, 0xee, 0xd4, 0xab, 0x66, 0x43, 0xbf, 0x80, + 0x00, 0x26, 0xab, 0x3b, 0x3b, 0x8d, 0x76, 0x5d, 0xd7, 0x50, 0x11, 0x0a, 0x46, 0xa3, 0x5a, 0xd7, + 0x73, 0x68, 0x06, 0x8a, 0xa6, 0xb1, 0xdb, 0xae, 0x11, 0x9c, 0x3c, 0x19, 0xf4, 0x41, 0xc3, 0xdc, + 0x0b, 0x20, 0x05, 0x54, 0x82, 0xa9, 0xda, 0x76, 0xbb, 0xdd, 0xa8, 0x99, 0xfa, 0x04, 0x19, 0x92, + 0x37, 0xf6, 0x8c, 0x6d, 0x7d, 0x12, 0xcd, 0xc3, 0x6c, 0x6b, 0xfb, 0xc1, 0xde, 0x56, 0xa3, 0x6a, + 0x98, 0x9b, 0x8d, 0xaa, 0xa9, 0x4f, 0x91, 0x11, 0x6a, 0x6d, 0x09, 0x52, 0xa4, 0x13, 0x95, 0x21, + 0xd3, 0x08, 0xc1, 0x5c, 0x6d, 0xab, 0x51, 0x7b, 0xb4, 0xb7, 0x55, 0x7d, 0xd4, 0x68, 0xec, 0x34, + 0x0c, 0x1d, 0xc8, 0xba, 0x92, 0x27, 0xd7, 0x5a, 0xbb, 0x1d, 0xb3, 0x61, 0xec, 0xd5, 0x1b, 0x66, + 0xb5, 0xd9, 0xea, 0xe8, 0x25, 0x82, 0x4c, 0x3a, 0x3a, 0x5b, 0x55, 0xa3, 0xbe, 0xd7, 0x6c, 0xdf, + 0xdf, 0xd6, 0x67, 0xe8, 0x00, 0xed, 0xbd, 0x6a, 0xab, 0xb5, 0x4d, 0x66, 0xb9, 0xd7, 0xac, 0xeb, + 0xb3, 0x64, 0x11, 0xe5, 0x01, 0x3a, 0x26, 0x99, 0xff, 0x1c, 0x5d, 0x7f, 0xba, 0x02, 0x7b, 0xb5, + 0xf6, 0x5e, 0xab, 0xba, 0xd9, 0x68, 0xe9, 0x17, 0x51, 0x19, 0x16, 0x43, 0xe0, 0x47, 0xdb, 0xc6, + 0x23, 0x8e, 0xae, 0x93, 0x91, 0x77, 0xaa, 0x66, 0x6d, 0x8b, 0x74, 0x74, 0xcc, 0x6d, 0xa3, 0xa1, + 0xcf, 0x93, 0x21, 0xea, 0x8d, 0x56, 0x83, 0x61, 0x33, 0x20, 0x22, 0xc0, 0x1d, 0x63, 0xfb, 0x4b, + 0x5f, 0x96, 0x5e, 0x6c, 0x01, 0xbd, 0x06, 0xd7, 0xf8, 0xb8, 0xed, 0xed, 0xf6, 0xde, 0x93, 0x6d, + 0xb3, 0xd9, 0x7e, 0xb0, 0x67, 0x34, 0x76, 0x5a, 0xcd, 0x5a, 0x75, 0xaf, 0xbd, 0xfb, 0x58, 0x5f, + 0x44, 0xab, 0xb0, 0x12, 0x47, 0x21, 0xef, 0xd1, 0x6a, 0x9a, 0x5f, 0xd6, 0x97, 0xd0, 0x22, 0xe8, + 0x9d, 0x86, 0xb9, 0x67, 0x34, 0x3e, 0xdc, 0x6d, 0x1a, 0x8d, 0xfa, 0x5e, 0xab, 0xd3, 0xd6, 0x97, + 0x09, 0xf4, 0x41, 0x14, 0x7a, 0x49, 0x2c, 0x4d, 0xab, 0x6a, 0x36, 0x3a, 0x26, 0x85, 0x95, 0xc9, + 0x96, 0x50, 0x58, 0xa3, 0x5a, 0x6f, 0x18, 0x64, 0x65, 0x2e, 0xd3, 0x2d, 0x61, 0xcb, 0xdd, 0xa8, + 0xb6, 0xcc, 0x2d, 0x7d, 0x85, 0x6c, 0x3a, 0xd9, 0x7e, 0x4a, 0x72, 0x05, 0x5d, 0x86, 0x25, 0x3e, + 0xa5, 0x56, 0xa3, 0xda, 0x69, 0x6c, 0x6d, 0xb7, 0x38, 0xe9, 0x55, 0xd2, 0x45, 0x17, 0xbf, 0xb6, + 0xd5, 0xa8, 0xef, 0xb6, 0x1a, 0x7b, 0xb5, 0xed, 0xc7, 0x8f, 0xab, 0xed, 0x7a, 0x47, 0xbf, 0xb6, + 0xde, 0x06, 0x08, 0xbf, 0x4a, 0x46, 0x38, 0x83, 0xb0, 0x39, 0x83, 0xe8, 0x17, 0xc8, 0x13, 0x84, + 0x9e, 0xd3, 0x35, 0xc2, 0xbc, 0x54, 0x68, 0x02, 0x01, 0x98, 0xe7, 0x9f, 0xe1, 0x33, 0xf0, 0x57, + 0x71, 0xd7, 0xc7, 0x3d, 0x3d, 0xbf, 0xbe, 0x0e, 0xd3, 0xc1, 0x47, 0xaf, 0x08, 0x79, 0x07, 0xfb, + 0xb4, 0xa5, 0x5f, 0x20, 0xe4, 0x2c, 0xb9, 0xca, 0x00, 0xda, 0xfa, 0x3f, 0x17, 0x00, 0x89, 0x90, + 0x42, 0x92, 0x4d, 0xc2, 0xf1, 0x76, 0xf7, 0x50, 0x16, 0x49, 0xe9, 0xeb, 0x42, 0x81, 0x48, 0x12, + 0x49, 0x8d, 0x81, 0x73, 0x68, 0x99, 0xd6, 0x8f, 0x44, 0xe1, 0x79, 0xf2, 0xf4, 0x07, 0xd8, 0x0f, + 0x24, 0xbd, 0x40, 0x16, 0x25, 0xa2, 0x6f, 0x78, 0xd7, 0x04, 0xd9, 0x91, 0x0e, 0x66, 0x02, 0xc9, + 0x61, 0x93, 0x84, 0xd9, 0xd4, 0x02, 0x21, 0xde, 0x33, 0x85, 0xae, 0xc3, 0x95, 0x0e, 0xf6, 0xe3, + 0x67, 0x13, 0x1c, 0xa1, 0x88, 0x56, 0x60, 0x99, 0x23, 0x04, 0xc9, 0x6d, 0xde, 0x37, 0x4d, 0x96, + 0x90, 0xfd, 0xe6, 0xab, 0xa6, 0x03, 0x79, 0x31, 0x01, 0x0a, 0x2e, 0x69, 0xe9, 0x25, 0xb2, 0xff, + 0x3b, 0x44, 0xdf, 0xf1, 0x9a, 0x40, 0x7d, 0x86, 0xd0, 0x1a, 0xf8, 0xc8, 0x79, 0x2e, 0x6e, 0xfe, + 0xea, 0xb3, 0x64, 0x96, 0x6a, 0xf1, 0x27, 0x7f, 0xd0, 0x1c, 0xba, 0x06, 0x97, 0xd9, 0xef, 0x84, + 0xa4, 0xb5, 0x7e, 0x11, 0x5d, 0x81, 0x4b, 0x91, 0x6e, 0x61, 0x0d, 0x98, 0x38, 0x89, 0xa8, 0x87, + 0x8f, 0x37, 0x8f, 0xae, 0x42, 0x39, 0x5e, 0xe2, 0xc3, 0x7b, 0x11, 0xba, 0x01, 0x6b, 0x22, 0x89, + 0x1b, 0x4f, 0xef, 0x72, 0xac, 0x05, 0xb2, 0x72, 0x2c, 0x01, 0x16, 0x89, 0x40, 0x38, 0xc2, 0x22, + 0xfa, 0x14, 0xbc, 0xc6, 0x10, 0x12, 0x1d, 0x4c, 0x8e, 0xb6, 0xb4, 0xfe, 0x6d, 0x0d, 0x66, 0x95, + 0xd3, 0x26, 0x22, 0xd7, 0x02, 0xc0, 0xab, 0x5c, 0xf4, 0x0b, 0x64, 0xc7, 0x05, 0x50, 0xf9, 0x7e, + 0x83, 0xae, 0x91, 0x07, 0xc5, 0xba, 0x44, 0xfc, 0x68, 0xe0, 0x2e, 0xb6, 0x9f, 0xe3, 0x9e, 0x9e, + 0x23, 0xab, 0x14, 0x43, 0xbb, 0x6f, 0xd9, 0x7d, 0xc2, 0xfa, 0xf2, 0x33, 0x8d, 0xe3, 0xc1, 0x80, + 0x0c, 0x5c, 0x58, 0xdf, 0x4f, 0x3a, 0xef, 0x22, 0xdb, 0xa4, 0x40, 0xc3, 0x39, 0x46, 0x7b, 0xc4, + 0x48, 0x5a, 0xac, 0xa7, 0xe3, 0x3b, 0xc3, 0x21, 0x99, 0xd5, 0xfa, 0x0f, 0x35, 0xd0, 0xa3, 0x5f, + 0xec, 0x20, 0x52, 0x54, 0xed, 0x89, 0x8f, 0xe8, 0xe9, 0x17, 0x42, 0x66, 0x11, 0x20, 0x8d, 0x70, + 0x54, 0xc7, 0xb7, 0x5c, 0x5f, 0x40, 0x72, 0x44, 0x48, 0xc8, 0xb0, 0x02, 0x90, 0x27, 0xa3, 0x3c, + 0xb2, 0xfb, 0xfd, 0xaf, 0x38, 0x47, 0xfb, 0x36, 0x11, 0x9a, 0x4b, 0xb0, 0x50, 0xed, 0xf5, 0xa2, + 0x2c, 0xa4, 0x4f, 0x10, 0x1e, 0x67, 0xc3, 0xc7, 0xfa, 0x26, 0xa9, 0xa4, 0x91, 0xe7, 0xc4, 0xba, + 0xa6, 0xc8, 0x4b, 0x91, 0x07, 0xc6, 0x7a, 0x8a, 0xeb, 0x8f, 0x95, 0x2f, 0x19, 0x90, 0x89, 0x84, + 0x8c, 0xa4, 0x5f, 0xa0, 0xb6, 0xb7, 0x2d, 0x9a, 0x1a, 0x69, 0xd6, 0x82, 0x66, 0x8e, 0xca, 0x0a, + 0x3d, 0x0a, 0xe2, 0x90, 0xfc, 0x66, 0xf3, 0x07, 0x3f, 0x5d, 0xbd, 0xf0, 0xfd, 0x9f, 0xad, 0x6a, + 0x3f, 0xf8, 0xd9, 0xaa, 0xf6, 0x93, 0x9f, 0xad, 0x5e, 0xf8, 0xbb, 0xff, 0x58, 0xd5, 0xbe, 0x72, + 0x47, 0xfa, 0x37, 0x69, 0x47, 0x96, 0xef, 0xda, 0x2f, 0x1d, 0xea, 0x58, 0x88, 0xc6, 0x00, 0xdf, + 0x1a, 0x1e, 0x1e, 0xdc, 0x1a, 0xee, 0xdf, 0x0a, 0xdd, 0xa4, 0xfd, 0x49, 0xfa, 0xc5, 0xc3, 0x3b, + 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x31, 0x6b, 0x92, 0x82, 0x6d, 0x00, 0x00, } func (m *CNStore) Marshal() (dAtA []byte, err error) { @@ -10651,6 +10669,16 @@ func (m *CNState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.DDLVisibilityFrontier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLogservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a if m.DDLVisibilityDeployedProtocol != 0 { i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) i-- @@ -11098,6 +11126,16 @@ func (m *ClusterDetails) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + { + size, err := m.DDLVisibilityFrontier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLogservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 if m.DDLVisibilityDeployedProtocol != 0 { i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) i-- @@ -14335,6 +14373,8 @@ func (m *CNState) ProtoSize() (n int) { if m.DDLVisibilityDeployedProtocol != 0 { n += 1 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) } + l = m.DDLVisibilityFrontier.ProtoSize() + n += 1 + l + sovLogservice(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -14555,6 +14595,8 @@ func (m *ClusterDetails) ProtoSize() (n int) { if m.DDLVisibilityDeployedProtocol != 0 { n += 1 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) } + l = m.DDLVisibilityFrontier.ProtoSize() + n += 1 + l + sovLogservice(uint64(l)) if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -25462,6 +25504,39 @@ func (m *CNState) Unmarshal(dAtA []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityFrontier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DDLVisibilityFrontier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) @@ -26934,6 +27009,39 @@ func (m *ClusterDetails) Unmarshal(dAtA []byte) error { break } } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityFrontier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DDLVisibilityFrontier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) diff --git a/pkg/pb/logservice/logservice_test.go b/pkg/pb/logservice/logservice_test.go index 74537e2bc6181..773514f4bdc3d 100644 --- a/pkg/pb/logservice/logservice_test.go +++ b/pkg/pb/logservice/logservice_test.go @@ -18,6 +18,7 @@ import ( "testing" "github.com/matrixorigin/matrixone/pkg/pb/metadata" + "github.com/matrixorigin/matrixone/pkg/pb/timestamp" "github.com/stretchr/testify/assert" ) @@ -569,10 +570,11 @@ func TestCNStateAtomicallyRejectsEpochCommitAfterMarkerlessJoin(t *testing.T) { func TestCNStateAtomicallyRejectsEpochCommitFromUnfencedReplacement(t *testing.T) { state := NewCNState() + oldFrontier := timestamp.Timestamp{PhysicalTime: 300} state.Update(CNStoreHeartbeat{ UUID: "target-cn", QueryAddress: "old:6001", ViewMetadataAdmissionGeneration: 1, DDLVisibilityBarrierReady: true, DDLVisibilityActivationPrepared: true, - DDLVisibilityActivationFenced: true, + DDLVisibilityActivationFenced: true, DDLVisibilityFrontier: oldFrontier, }, 1) // Replacement occurs after the old generation supplied Fenced. Even if the @@ -592,6 +594,11 @@ func TestCNStateAtomicallyRejectsEpochCommitFromUnfencedReplacement(t *testing.T assert.Equal(t, int64(0), state.DDLVisibilityDeployedProtocol) assert.True(t, state.Stores["target-cn"].ViewMetadataIngressReady) + assert.Equal(t, oldFrontier, state.DDLVisibilityFrontier, + "replacement heartbeat must not erase the cluster-lifetime DDL frontier") + delete(state.Stores, "target-cn") + assert.Equal(t, oldFrontier, state.DDLVisibilityFrontier, + "store removal must not erase the cluster-lifetime DDL frontier") } func TestCNStateRejectsMarkerlessIngressAfterCommittedDDLCut(t *testing.T) { diff --git a/pkg/queryservice/client/query_client.go b/pkg/queryservice/client/query_client.go index dcc0b404a4786..77770e5c0364d 100644 --- a/pkg/queryservice/client/query_client.go +++ b/pkg/queryservice/client/query_client.go @@ -63,7 +63,7 @@ var methodVersions = map[pb.CmdMethod]int64{ pb.CmdMethod_ISCPDrainConsumer: defines.MORPCVersion4, pb.CmdMethod_IcebergCacheInvalidate: defines.MORPCVersion4, pb.CmdMethod_MongoDBClientRetire: defines.MORPCVersion5, - pb.CmdMethod_SyncCommitV2: defines.MORPCVersion41, + pb.CmdMethod_SyncCommitV2: defines.MORPCVersion43, } type queryClient struct { diff --git a/pkg/queryservice/client/query_client_test.go b/pkg/queryservice/client/query_client_test.go index 6950ab7f8efa4..c2aad62725d0a 100644 --- a/pkg/queryservice/client/query_client_test.go +++ b/pkg/queryservice/client/query_client_test.go @@ -37,7 +37,7 @@ func TestMongoDBClientRetireRequiresProtocolVersion5(t *testing.T) { } func TestSyncCommitV2RequiresProtocolVersion38(t *testing.T) { - assert.Equal(t, defines.MORPCVersion41, methodVersions[query.CmdMethod_SyncCommitV2]) + assert.Equal(t, defines.MORPCVersion43, methodVersions[query.CmdMethod_SyncCommitV2]) const serviceID = "sync-commit-v2-version-test" rt := moruntime.DefaultRuntime() @@ -45,7 +45,7 @@ func TestSyncCommitV2RequiresProtocolVersion38(t *testing.T) { req := &query.Request{CmdMethod: query.CmdMethod_SyncCommitV2} rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion35) assert.Error(t, checkMethodVersion(context.Background(), serviceID, req)) - rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion41) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion43) assert.NoError(t, checkMethodVersion(context.Background(), serviceID, req)) } diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version.go b/pkg/sql/plan/function/ctl/cmd_rpc_version.go index 6e0968c22ce91..1dcd5068f3e85 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version.go @@ -113,7 +113,7 @@ func handleSetProtocolVersion(proc *process.Process, } if service == cn && targets != nil { - if version >= defines.MORPCVersion41 { + if version >= defines.MORPCVersion43 { const maxDDLVisibilityActivationTargets = 1024 if len(targets) == 0 || len(targets) > maxDDLVisibilityActivationTargets { return Result{}, moerr.NewInternalErrorNoCtxf( @@ -132,12 +132,12 @@ func handleSetProtocolVersion(proc *process.Process, seen[target] = struct{}{} } } - if version >= defines.MORPCVersion41 { + if version >= defines.MORPCVersion43 { if err := validateDDLVisibilityActivationMembership(qt, targets); err != nil { return Result{}, err } } - if version < defines.MORPCVersion41 { + if version < defines.MORPCVersion43 { versions := make([]string, 0, len(targets)) for _, target := range targets { resp, sendErr := transferToCN(qt, target, version, nil) @@ -156,7 +156,7 @@ func handleSetProtocolVersion(proc *process.Process, return Result{Method: SetProtocolVersionMethod, Data: strings.Join(versions, ", ")}, nil } - // Live v41 activation is a distributed barrier. Dispatch every target + // Live v43 activation is a distributed barrier. Dispatch every target // concurrently so each CN can block local DDL producers before any CN // waits for the complete Prepared set. type targetResult struct { @@ -313,7 +313,7 @@ func transferToCN( ) (resp *querypb.Response, err error) { cluster := clusterservice.GetMOCluster(qt.ServiceID()) var selected metadata.CNService - if version >= defines.MORPCVersion41 { + if version >= defines.MORPCVersion43 { refresher, refreshOK := cluster.(clusterservice.AuthoritativeRefresher) if !refreshOK { return nil, moerr.NewInternalErrorNoCtx( diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go index 6e069dbb02dab..439e4cb3d6601 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go @@ -217,9 +217,9 @@ func TestHandleSetProtocolVersionDispatchesCompleteTargetSetConcurrently(t *test proc := &process.Process{Base: &process.BaseProcess{QueryClient: qcli}} result, err := handleSetProtocolVersion( - proc, cn, strings.Join(targets, ",")+":41", nil) + proc, cn, strings.Join(targets, ",")+":43", nil) require.NoError(t, err) - require.Equal(t, "activation-cn-1:41, activation-cn-2:41", result.Data) + require.Equal(t, "activation-cn-1:43, activation-cn-2:43", result.Data) require.Equal(t, int32(2), qcli.started.Load()) require.Equal(t, int32(2), qcli.releases.Load()) qcli.mu.Lock() @@ -229,7 +229,7 @@ func TestHandleSetProtocolVersionDispatchesCompleteTargetSetConcurrently(t *test require.Equal(t, targets, requestTargets) } - _, err = handleSetProtocolVersion(proc, cn, "activation-cn-1,activation-cn-1:41", nil) + _, err = handleSetProtocolVersion(proc, cn, "activation-cn-1,activation-cn-1:43", nil) require.ErrorContains(t, err, "duplicated") } @@ -249,7 +249,7 @@ func TestHandleSetProtocolVersionRejectsOmittedAuthoritativeCN(t *testing.T) { rt.SetGlobalVariables(runtime.ClusterService, mc) proc := &process.Process{Base: &process.BaseProcess{QueryClient: &concurrentProtocolQueryClient{both: make(chan struct{})}}} - _, err := handleSetProtocolVersion(proc, cn, "new-cn:41", nil) + _, err := handleSetProtocolVersion(proc, cn, "new-cn:43", nil) require.ErrorContains(t, err, "does not match authoritative CN membership") } @@ -275,7 +275,7 @@ func TestTransferToCNAllowsActivationFence(t *testing.T) { qcli := &addressRecordingQueryClient{} started := time.Now() - _, err := transferToCN(qcli, serviceID, defines.MORPCVersion41, []string{serviceID}) + _, err := transferToCN(qcli, serviceID, defines.MORPCVersion43, []string{serviceID}) require.Error(t, err) require.Equal(t, "activation-cn:6001", qcli.address) require.Equal(t, []string{serviceID}, diff --git a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go index 7bce33bd18460..9e9dce3a15b82 100644 --- a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go +++ b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go @@ -49,17 +49,17 @@ func TestIssue277xxDDLConsistency(t *testing.T) { targets := cn0.ServiceID() + "," + cn1.ServiceID() var activation string require.NoError(t, db0.QueryRowContext(ctx, - "select mo_ctl('cn', 'SetProtocolVersion', ?)", targets+":41").Scan(&activation)) - require.Contains(t, activation, cn0.ServiceID()+":41") - require.Contains(t, activation, cn1.ServiceID()+":41") + "select mo_ctl('cn', 'SetProtocolVersion', ?)", targets+":43").Scan(&activation)) + require.Contains(t, activation, cn0.ServiceID()+":43") + require.Contains(t, activation, cn1.ServiceID()+":43") // SetProtocolVersion returns success only after both target RPCs report - // v41 and HAKeeper acknowledges the atomically committed v41 epoch. + // v43 and HAKeeper acknowledges the atomically committed v43 epoch. resetIssue277xxDatabase(t, ctx, db0, database) defer execSQLMaybe(t, ctx, db0, "drop database if exists `"+database+"`") // Prove this public path actually executes SyncCommitV2: an injected - // receiver failure must make CREATE fail after v41 activation. + // receiver failure must make CREATE fail after v43 activation. require.True(t, fault.Enable()) defer fault.Disable() faultPointRemoved := false @@ -77,7 +77,7 @@ func TestIssue277xxDDLConsistency(t *testing.T) { require.NoError(t, removeErr) faultPointRemoved = true - // Do not issue SYNCCOMMIT or retry the read. The v41 DDL commit contract + // Do not issue SYNCCOMMIT or retry the read. The v43 DDL commit contract // must make the first fresh CN1 snapshot observe CN0's CREATE TABLE. execSQLRequire(t, ctx, db0, "create table `"+database+"`.`t` (id int primary key, payload varchar(32))") diff --git a/proto/logservice.proto b/proto/logservice.proto index 173ae0e1d879d..f117d628ec816 100644 --- a/proto/logservice.proto +++ b/proto/logservice.proto @@ -738,6 +738,9 @@ message CNState { // Once a complete-target cut commits, markerless replacement/scale-out CNs // must join that fence instead of reopening on an older protocol. int64 DDLVisibilityDeployedProtocol = 2; + // DDLVisibilityFrontier is the monotonic cluster-lifetime maximum committed + // DDL timestamp. It survives CN restart, replacement, and store removal. + timestamp.Timestamp DDLVisibilityFrontier = 3 [(gogoproto.nullable) = false]; } @@ -804,6 +807,7 @@ message ClusterDetails { repeated DeletedStore DeletedStores = 5 [(gogoproto.nullable) = false]; ViewMetadataAdmission ViewMetadataAdmission = 6; int64 DDLVisibilityDeployedProtocol = 7; + timestamp.Timestamp DDLVisibilityFrontier = 8 [(gogoproto.nullable) = false]; } // ClusterInfo provides a global view of all shards in the cluster. It From fa8e9343facad78af13741b2320a9c0869148f5c Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Mon, 31 Aug 2026 22:37:45 +0800 Subject: [PATCH 21/34] test: cover committed frontier persistence failure --- pkg/cnservice/server_ddl_visibility_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 1c63a8d77578f..029d8232c2054 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -697,6 +697,8 @@ func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing } txnClient := mock_frontend.NewMockTxnClient(gomock.NewController(t)) txnClient.EXPECT().GetLatestCommitTS().Return(targetTS) + txnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), targetTS).Return(targetTS.Next(), nil) + txnClient.EXPECT().SyncLatestCommitTS(targetTS) baseFS := newDDLVisibilityMetadataFS(t) metadataFS := &failReplaceMetadataFS{ReplaceableFileService: baseFS, failAt: 2} cfg := &Config{UUID: serviceID} From e2c908212170dd636fd8090a2094b5548aee741c Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Mon, 31 Aug 2026 22:41:11 +0800 Subject: [PATCH 22/34] fix: republish DDL fence proof after CN restart --- pkg/cnservice/server_ddl_visibility.go | 19 ++++++++++++++++++- pkg/cnservice/server_ddl_visibility_test.go | 7 +++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 4c78e3820c46e..20c829f33924e 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -113,6 +113,11 @@ func (s *service) prepareDDLVisibilityBarrierLocked() error { defer cancel() s.ddlCommitGate.RecordDDLFrontier(s._txnClient.GetLatestCommitTS()) + if s.ddlVisibilityActivationComplete.Load() { + // No DDL producer exists before listeners start, so this new incarnation + // is already drained and may publish its own Prepared proof. + s.ddlVisibilityActivationPrepared.Store(true) + } // Startup owns this mutex, so relying on the periodic heartbeat (which uses // the same mutex to order readiness snapshots) would deadlock publication. // Publish the startup barrier directly before waiting for its authoritative @@ -128,7 +133,19 @@ func (s *service) prepareDDLVisibilityBarrierLocked() error { if err := s.waitForDDLVisibilityBarrierPublication(ctx, retryInterval); err != nil { return err } - return s.syncStartupDDLVisibilityFrontier(ctx) + if err := s.syncStartupDDLVisibilityFrontier(ctx); err != nil { + return err + } + if s.ddlVisibilityActivationComplete.Load() { + // The reconstructed frontier is now applied locally. Publish a Fenced + // proof bound to this restart/replacement incarnation so future scale-out + // activation does not wait on stale proof from its predecessor. + s.ddlVisibilityActivationFenced.Store(true) + if _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { + return moerr.AttachCause(ctx, err) + } + } + return nil } // withdrawDDLVisibilityBarrier closes both externally published gates before diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 029d8232c2054..2b26a0f50a67f 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -454,9 +454,12 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { require.False(t, s.ddlVisibilityActivationComplete.Load()) require.NoError(t, s.prepareDDLVisibilityBarrier()) require.True(t, s.ddlVisibilityBarrierPrepared.Load()) - require.False(t, s.ddlVisibilityActivationPrepared.Load()) - require.False(t, s.ddlVisibilityActivationFenced.Load()) + require.True(t, s.ddlVisibilityActivationPrepared.Load()) + require.True(t, s.ddlVisibilityActivationFenced.Load()) require.True(t, s.ddlVisibilityActivationComplete.Load()) + require.True(t, cluster.phases[serviceID].DDLVisibilityActivationPrepared) + require.True(t, cluster.phases[serviceID].DDLVisibilityActivationFenced, + "a restarted committed CN must publish proof for its new incarnation") require.True(t, s.ddlVisibilityBarrierReady.Load()) require.Equal(t, 1, cluster.refreshCalls) require.Empty(t, queryClient.requests) From 0f394f0041fc3ec6b1d8b00cfad0d878aebdcecf Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Tue, 1 Sep 2026 00:58:51 +0800 Subject: [PATCH 23/34] docs: record latest conflict resolution plan --- CLAUDE_TODO_2026-08-29.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index bcef0b6477f1c..d76b4cc8442af 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -57,3 +57,9 @@ - 已将 DDL frontier 提升为 HAKeeper RSM 中独立于 CN store 生命周期的单调集群最大值;activation/restart 先从 txn client 重建 durable high-water mark,再发布并同步该全局值。 - 已增加 producer replacement/store removal 不得清空 frontier 的 RSM 回归,以及 replacement 后 activation 仍等待旧 frontier 的 CN 回归。 - 按用户决定不再等待其他并发 PR:本 PR 固定使用当前无人占用的 MORPC v43,并为两个已在 review 的并发 owner 预留 v41/v42;同步更新实现、测试、设计与生产路径回归。 + +## 2026-08-31:解决最新主干冲突 + +1. fetch 并 merge 最新 `mo/main`,逐文件确认双方语义,保留主干新增能力与本 PR v43 DDL fence。 +2. 重新生成必要生成文件,运行冲突相关 owning package、embedded 双 CN、race/vet 与 diff 检查。 +3. commit/push merge 结果,确认 PR mergeability 与 unresolved thread 状态。 From 4eea48e41848befa9b2dba1061721732dab298ee Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Tue, 1 Sep 2026 11:18:58 +0800 Subject: [PATCH 24/34] fix: preserve v41 baseline before DDL activation --- CLAUDE_TODO_2026-08-29.md | 6 ++++++ .../CLAUDE_cross_cn_ddl_visibility_fence.md | 16 ++++++++-------- pkg/cnservice/server_ddl_visibility.go | 4 ++-- pkg/cnservice/server_ddl_visibility_test.go | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index d76b4cc8442af..553a284e7113f 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -63,3 +63,9 @@ 1. fetch 并 merge 最新 `mo/main`,逐文件确认双方语义,保留主干新增能力与本 PR v43 DDL fence。 2. 重新生成必要生成文件,运行冲突相关 owning package、embedded 双 CN、race/vet 与 diff 检查。 3. commit/push merge 结果,确认 PR mergeability 与 unresolved thread 状态。 + +## 2026-08-31:修复最新 CI failure + +1. 获取 PR exact head 的失败 check/job 原始日志,区分代码回归与基础设施问题并定位最小根因。 +2. 对代码问题补充确定性回归并修复;不使用重试或弱化断言掩盖失败。 +3. 运行 owning package、相关 race/vet/embedded 验证,commit/push 后确认新 CI 状态。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index 719f8f1e7844e..17c58abd715b1 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -31,7 +31,7 @@ It is unsafe for any public or already-connected CN to commit DDL below v43 whil ### Measurable criteria - A create on CN0 followed immediately by a first read/load on CN1 succeeds without explicit `SYNCCOMMIT`. -- Markerless startup preserves the current-main v40 baseline before the v43 cut. +- Markerless startup preserves the current-main v41 baseline before the v43 cut. - No local downgrade below v43 is accepted after the monotonic v43 epoch is committed. - Membership change between final scan and epoch commit rejects the old target set atomically. - Restart, timeout, persistence failure, response loss, and leader failover remain fail-closed. @@ -55,7 +55,7 @@ HAKeeper is the first owner of cluster epoch and membership linearization. CN lo A CN is in one of these logical states: -1. **Baseline v40**: v43 not deployed; existing v38-v40 contracts remain active. Public ingress may be open. +1. **Baseline v41**: v43 not deployed; existing v38-v41 contracts remain active. Public ingress may be open. 2. **Withdrawing**: activation blocks new DDL, withdraws ingress, and drains active DDL. 3. **Prepared v43**: local old-protocol producers are drained; runtime can receive v43 RPCs. 4. **Provisionally fenced**: local frontier synchronization completed and `-43` is durable; ingress remains closed. @@ -70,7 +70,7 @@ The cluster epoch commit is the linearization point. Prepared, Fenced, and the l ### First rollout 1. All LogStore/HAKeeper replicas advertise support for the epoch schema. -2. Every CN runs v43-capable code but markerless CNs keep protocol baseline v40. +2. Every CN runs v43-capable code but markerless CNs keep protocol baseline v41. 3. `mo_ctl SetProtocolVersion` refreshes raw authoritative CN membership. 4. The requested set must exactly match all eligible CN tuples and each target must advertise the v43 receiver/barrier capability. 5. Targets concurrently withdraw ingress, block and drain DDL, capture their reconstructed latest committed timestamp, then heartbeat Prepared together with that frontier. HAKeeper advances a cluster-lifetime maximum and never lowers it when an incarnation restarts, is replaced, or is removed. @@ -84,7 +84,7 @@ A public real-user DDL, and background DDL after public listeners are enabled, e ### Scale-out and replacement -A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes before the cluster commit, it becomes authoritative membership and invalidates any old target proof. If it linearizes after commit, HAKeeper forces ingress false and returns epoch 43. It never becomes a public v40 producer after the cut. +A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes before the cluster commit, it becomes authoritative membership and invalidates any old target proof. If it linearizes after commit, HAKeeper forces ingress false and returns epoch 43. It never becomes a public v41 producer after the cut. ## 6. Failure, retry, and lifecycle behavior @@ -105,7 +105,7 @@ Retries are idempotent for the same generation and target set. Replacement gener ### Mixed-version baseline -Current main already deploys v40 semantics. A fresh v43-capable process without a DDL marker therefore remains at v40, not v37. The v43 DDL state is separate from unrelated v38-v40 capabilities. +Current main already deploys v41 semantics. A fresh v43-capable process without a DDL marker therefore remains at v41, not v37. The v43 DDL state is separate from unrelated v38-v41 capabilities. ### Rollout order @@ -116,7 +116,7 @@ Current main already deploys v40 semantics. A fresh v43-capable process without ### Downgrade policy -Before epoch 43, ordinary protocol changes at or below v40 remain possible. After epoch 43, local downgrade below v43 is rejected. A safe rollback would require a separately designed atomic cluster rollback that withdraws and drains every DDL producer before lowering the epoch; this revision deliberately does not implement epoch rollback. +Before epoch 43, ordinary protocol changes at or below v41 remain possible. After epoch 43, local downgrade below v43 is rejected. A safe rollback would require a separately designed atomic cluster rollback that withdraws and drains every DDL producer before lowering the epoch; this revision deliberately does not implement epoch rollback. Binary rollback after epoch 43 is unsupported until such a rollback protocol exists. Operators must restore forward to a v43-capable binary. @@ -169,7 +169,7 @@ Could provide a stronger generic read contract, but materially changes every tra | Contract | Deterministic evidence | |---|---| -| v40 baseline preserved | markerless default-v43 startup UT | +| v41 baseline preserved | markerless default-v43 startup UT | | post-cut downgrade rejected | completed-v43 downgrade UT | | exact authoritative targets | ctl raw-membership omission/capability UT | | join/commit atomicity | CNState RSM ordering UT: final scan, join, stale commit | @@ -182,7 +182,7 @@ Could provide a stronger generic read contract, but materially changes every tra ## 14. Decision log and open items - Chosen linearization point: HAKeeper replicated heartbeat transition with exact tuple proof. -- Chosen baseline: preserve current-main v40 before v43 activation. +- Chosen baseline: preserve current-main v41 before v43 activation. - Chosen downgrade behavior: reject after monotonic epoch commit. - Chosen direct-ingress protection: local DDL gate in addition to proxy admission. - Non-blocking follow-up: add dedicated activation/fan-out metrics and publish N-CN staging latency evidence. diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index 20c829f33924e..bfaf85055760a 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -44,7 +44,7 @@ func (s *service) prepareDDLVisibilityBarrier() error { // MORPCLatestVersion describes compiled capability, not deployment-wide // activation. Restore the durable per-CN deployed protocol before deciding // whether this restart can produce v43 DDL. A fresh upgraded process has no - // marker and preserves the already-deployed v40 baseline until the + // marker and preserves the already-deployed v41 baseline until the // complete-target cut persists v43. deployedVersion := s.loadDDLVisibilityDeployedProtocol() if deployedVersion == 0 && s._hakeeperClient != nil { @@ -74,7 +74,7 @@ func (s *service) prepareDDLVisibilityBarrier() error { rt.SetGlobalVariables(moruntime.MOProtocolVersion, -deployedVersion) } else if value, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion); ok { if version, valid := value.(int64); valid && version >= defines.MORPCVersion43 { - rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion41) } } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 2b26a0f50a67f..3b7b04520322a 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -483,7 +483,7 @@ func TestDefaultV43StartupUsesLastDeployedProtocolUntilActivation(t *testing.T) require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion40, version) + require.Equal(t, defines.MORPCVersion41, version) require.True(t, s.ddlVisibilityListenersReady.Load()) require.True(t, s.viewMetadataIngressReady.Load()) require.True(t, gate.PublicDDLEnabled()) From fcb861192f9059d6b4eac5e08ac435c7d68cd136 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Tue, 1 Sep 2026 14:26:28 +0800 Subject: [PATCH 25/34] fix: persist DDL frontier before acknowledgement --- .../CLAUDE_cross_cn_ddl_visibility_fence.md | 2 +- pkg/cnservice/server.go | 1 + pkg/cnservice/server_ddl_visibility_test.go | 39 +++++++++++++ pkg/cnservice/server_heartbeat.go | 17 ++++++ pkg/frontend/ddl_commit_gate.go | 40 ++++++++++--- pkg/frontend/txn.go | 12 ++++ pkg/frontend/txn_test.go | 56 +++++++++++++++++++ 7 files changed, 159 insertions(+), 8 deletions(-) diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index b66a8cbd79081..179addcda2948 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -80,7 +80,7 @@ The cluster epoch commit is the linearization point. Prepared, Fenced, and the l ### Steady-state DDL -A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, protocol v43 triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable QueryService. +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. This removes the commit-success-to-periodic-heartbeat crash window. Protocol v43 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. ### Scale-out and replacement diff --git a/pkg/cnservice/server.go b/pkg/cnservice/server.go index ca4a3d0e245da..575c33361b2cc 100644 --- a/pkg/cnservice/server.go +++ b/pkg/cnservice/server.go @@ -165,6 +165,7 @@ func NewService( gossipNode: gossipNode, ddlCommitGate: frontend.NewDDLCommitGate(), } + srv.ddlCommitGate.SetFrontierPublisher(srv.publishDDLCommitFrontier) runtime.ServiceRuntime(cfg.UUID).SetGlobalVariables( frontend.DDLCommitGateRuntimeKey, srv.ddlCommitGate) srv.colexecServer = colexec.NewServer(cfg.UUID) diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 1d10d80c0f9ff..1d8d6392d865c 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -1588,6 +1588,45 @@ func TestWaitForDDLVisibilityBarrierWithdrawalHonorsCancellation(t *testing.T) { require.Equal(t, 1, cluster.refreshCalls) } +func TestAcknowledgedDDLFrontierSurvivesCrashBeforePeriodicHeartbeat(t *testing.T) { + const producerID = "ddl-producer" + frontier := timestamp.Timestamp{PhysicalTime: 300} + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: producerID, QueryAddress: "old:6001", + ViewMetadataAdmissionGeneration: 1, DDLVisibilityBarrierReady: true, + }}} + client := &ddlVisibilityWithdrawalHAKeeperClient{cluster: cluster} + producer := &service{ + cfg: &Config{UUID: producerID}, _hakeeperClient: client, + ddlCommitGate: frontend.NewDDLCommitGate(), config: util.NewConfigData(nil), + } + + // This is the synchronous publication in the successful DDL commit path; + // deliberately do not run a periodic heartbeat before replacing the CN. + producer.ddlCommitGate.RecordDDLFrontier(frontier) + require.NoError(t, producer.publishDDLCommitFrontier(context.Background(), frontier)) + require.Equal(t, frontier, cluster.globalFrontier) + + // A fresh same-UUID incarnation starts with an empty process-local gate. + replacement := &service{ + cfg: &Config{UUID: producerID}, _hakeeperClient: client, + ddlCommitGate: frontend.NewDDLCommitGate(), config: util.NewConfigData(nil), + } + require.NoError(t, replacement.publishDDLCommitFrontier(context.Background(), timestamp.Timestamp{})) + require.Equal(t, frontier, cluster.globalFrontier, + "replacement must not erase the synchronously published commit frontier") + + ctrl := gomock.NewController(t) + laggingTxnClient := mock_frontend.NewMockTxnClient(ctrl) + laggingTxnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), frontier).Return(frontier, nil) + laggingTxnClient.EXPECT().SyncLatestCommitTS(frontier) + target := &service{ + cfg: &Config{UUID: "lagging-peer"}, _txnClient: laggingTxnClient, + _hakeeperClient: client, + } + require.NoError(t, target.syncStartupDDLVisibilityFrontier(context.Background())) +} + func TestSyncStartupDDLVisibilityFrontierSurvivesProducerReplacement(t *testing.T) { const serviceID = "ddl-visibility-durable-frontier-test" oldFrontier := timestamp.Timestamp{PhysicalTime: 300} diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 4cecfba8e8502..70dbcd891d279 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -26,6 +26,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/logservice" "github.com/matrixorigin/matrixone/pkg/logutil" logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" + "github.com/matrixorigin/matrixone/pkg/pb/timestamp" v2 "github.com/matrixorigin/matrixone/pkg/util/metric/v2" "github.com/matrixorigin/matrixone/pkg/version" ) @@ -186,6 +187,22 @@ func (s *service) notifyCommandPoll() { } } +// publishDDLCommitFrontier durably advances HAKeeper's cluster frontier before +// frontend acknowledges a public pre-cut DDL. It is serialized with periodic +// heartbeat snapshots so an older captured heartbeat cannot follow this one. +func (s *service) publishDDLCommitFrontier(ctx context.Context, _ timestamp.Timestamp) error { + if s._hakeeperClient == nil { + return moerr.NewInternalError(ctx, "HAKeeper client is unavailable while publishing DDL frontier") + } + s.ddlVisibilityHeartbeatMu.Lock() + defer s.ddlVisibilityHeartbeatMu.Unlock() + _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) + if err != nil { + return moerr.AttachCause(ctx, err) + } + return nil +} + func (s *service) newCNStoreHeartbeat() logservicepb.CNStoreHeartbeat { hb := logservicepb.CNStoreHeartbeat{ UUID: s.cfg.UUID, diff --git a/pkg/frontend/ddl_commit_gate.go b/pkg/frontend/ddl_commit_gate.go index 3257e7dcf1728..4bf59abaf055b 100644 --- a/pkg/frontend/ddl_commit_gate.go +++ b/pkg/frontend/ddl_commit_gate.go @@ -32,13 +32,14 @@ const DDLCommitGateRuntimeKey = "frontend.ddl-commit-gate" // the gate blocked across RPC attempts; Close wakes blocked sessions during CN // shutdown. type DDLCommitGate struct { - mu sync.Mutex - changed chan struct{} - blocked bool - closed bool - publicDDL bool - active int - ddlFrontier atomic.Pointer[timestamp.Timestamp] + mu sync.Mutex + changed chan struct{} + blocked bool + closed bool + publicDDL bool + active int + ddlFrontier atomic.Pointer[timestamp.Timestamp] + frontierPublisher func(context.Context, timestamp.Timestamp) error // enterBlockedHook is a deterministic test hook invoked after Enter observes // a blocked gate and before it waits. Production leaves it nil. enterBlockedHook func() @@ -64,6 +65,20 @@ func (g *DDLCommitGate) RecordDDLFrontier(ts timestamp.Timestamp) { } } +// SetFrontierPublisher installs the CN-owned durable publisher before public +// sessions start. Production sets it exactly once during service construction. +func (g *DDLCommitGate) SetFrontierPublisher(publisher func(context.Context, timestamp.Timestamp) error) { + g.frontierPublisher = publisher +} + +func (g *DDLCommitGate) PublishDDLFrontier(ctx context.Context, ts timestamp.Timestamp) error { + g.RecordDDLFrontier(ts) + if g.frontierPublisher == nil || ts.IsEmpty() { + return nil + } + return g.frontierPublisher(ctx, ts) +} + func (g *DDLCommitGate) LatestDDLFrontier() timestamp.Timestamp { if current := g.ddlFrontier.Load(); current != nil { return *current @@ -80,6 +95,17 @@ func publicBackgroundDDLBarrierEnabled(serviceID string) bool { return ok && gate.PublicDDLEnabled() } +func publishDDLCommitFrontier(ctx context.Context, serviceID string, ts timestamp.Timestamp) error { + value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(DDLCommitGateRuntimeKey) + if !ok || value == nil { + return nil + } + if gate, ok := value.(*DDLCommitGate); ok { + return gate.PublishDDLFrontier(ctx, ts) + } + return moerr.NewInternalError(ctx, "invalid DDL commit gate") +} + func recordDDLCommitFrontier(serviceID string, ts timestamp.Timestamp) { value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(DDLCommitGateRuntimeKey) if !ok || value == nil { diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index 425de819fdee4..7195a1ea2b318 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -1039,6 +1039,18 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { } if haveDDL && !commitTs.IsEmpty() && (err == nil || commitResultUnknown) { recordDDLCommitFrontier(execCtx.ses.GetService(), commitTs) + if execCtx.ses.GetFromRealUser() || + publicBackgroundDDLBarrierEnabled(execCtx.ses.GetService()) { + // A periodic heartbeat is insufficient here: acknowledging the DDL + // first leaves a crash window in which replacement loses T forever. + // Publish T through the HAKeeper RSM before returning success. For an + // unknown commit outcome, make the same best-effort durable advance. + if publishErr := publishDDLCommitFrontier( + ctx2, execCtx.ses.GetService(), commitTs, + ); publishErr != nil { + err = errors.Join(err, publishErr) + } + } } if commitResultUnknown { // ErrTxnUnknown is terminal for this frontend handle. The operator diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index a80574b73f855..d8a19cd503ad2 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -871,6 +871,7 @@ type ddlSyncQueryClient struct { nilResponse map[string]bool requests []ddlSyncRequest releases int + beforeSend func() } func (c *ddlSyncQueryClient) ServiceID() string { @@ -886,6 +887,9 @@ func (c *ddlSyncQueryClient) SendMessage( if req.SycnCommit != nil { request.commitTS = req.SycnCommit.LatestCommitTS } + if c.beforeSend != nil { + c.beforeSend() + } c.requests = append(c.requests, request) if err := c.sendError[address]; err != nil { return nil, err @@ -984,6 +988,58 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { require.Nil(t, ses.GetTxnHandler().GetTxn()) }) + t.Run("publishes frontier durably before acknowledgement and fan-out", func(t *testing.T) { + ses, _, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + gate := NewDDLCommitGate() + published := false + gate.SetFrontierPublisher(func(_ context.Context, ts timestamp.Timestamp) error { + require.Equal(t, commitTS, ts) + published = true + return nil + }) + qc.beforeSend = func() { + require.True(t, published, "HAKeeper frontier publication must precede fan-out") + } + rt := moruntime.ServiceRuntime(ses.GetService()) + previousGate, hadPreviousGate := rt.GetGlobalVariables(DDLCommitGateRuntimeKey) + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, gate) + t.Cleanup(func() { + if hadPreviousGate { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, previousGate) + } else { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, nil) + } + }) + + require.NoError(t, ses.GetTxnHandler().Commit(execCtx)) + require.True(t, published) + require.Equal(t, commitTS, gate.LatestDDLFrontier()) + }) + + t.Run("publication failure prevents successful acknowledgement", func(t *testing.T) { + ses, _, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + publishErr := errors.New("injected durable frontier publication failure") + gate := NewDDLCommitGate() + gate.SetFrontierPublisher(func(context.Context, timestamp.Timestamp) error { return publishErr }) + rt := moruntime.ServiceRuntime(ses.GetService()) + previousGate, hadPreviousGate := rt.GetGlobalVariables(DDLCommitGateRuntimeKey) + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, gate) + t.Cleanup(func() { + if hadPreviousGate { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, previousGate) + } else { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, nil) + } + }) + + require.ErrorIs(t, ses.GetTxnHandler().Commit(execCtx), publishErr) + require.Empty(t, qc.requests, "fan-out and success must not follow failed durable publication") + }) + t.Run("activation gate drains and blocks concurrent DDL commit", func(t *testing.T) { ses, op, _, execCtx := newState(t) defer ses.Close() From d5bf028f33cc75663190eef55e94af16a245d83e Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Tue, 1 Sep 2026 15:35:15 +0800 Subject: [PATCH 26/34] fix: bind DDL frontier publication to CN generation --- CLAUDE_TODO_2026-08-29.md | 6 ++ .../CLAUDE_cross_cn_ddl_visibility_fence.md | 2 +- pkg/cnservice/server_ddl_visibility_test.go | 75 ++++++++++++++++--- pkg/cnservice/server_heartbeat.go | 15 +++- 4 files changed, 87 insertions(+), 11 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index 553a284e7113f..36ad2eb80cb8e 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -69,3 +69,9 @@ 1. 获取 PR exact head 的失败 check/job 原始日志,区分代码回归与基础设施问题并定位最小根因。 2. 对代码问题补充确定性回归并修复;不使用重试或弱化断言掩盖失败。 3. 运行 owning package、相关 race/vet/embedded 验证,commit/push 后确认新 CI 状态。 + +## 2026-09-01:frontier publication generation fence + +1. 同步 frontier heartbeat 必须验证 `CommandBatch.ViewMetadataAdmission.Generation` 与本地 incarnation generation 完全一致。 +2. HAKeeper 返回更高 authoritative generation 时立即 revoke 旧 incarnation 并向 frontend 返回错误,禁止继续 fan-out/成功确认。 +3. 增加 generation N commit → N+1 takeover → N publication rejected → N crash → restart 仅同步旧 durable frontier 的确定性回归,并运行 owning package/race/vet。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index 179addcda2948..1fbdb40354c5c 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -80,7 +80,7 @@ The cluster epoch commit is the linearization point. Prepared, Fenced, and the l ### Steady-state DDL -A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. This removes the commit-success-to-periodic-heartbeat crash window. Protocol v43 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned `CommandBatch.ViewMetadataAdmission.Generation` must exactly equal the sender generation. A stale sender rejected by HAKeeper therefore revokes itself and cannot mistake RPC delivery for durable frontier acceptance. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window. Protocol v43 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after generation-bound durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. ### Scale-out and replacement diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 1d8d6392d865c..f46bf1ac4bdba 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -180,15 +180,16 @@ func activationTestPeerProtocols() map[string]query.GetProtocolVersionResponse { type ddlVisibilityWithdrawalHAKeeperClient struct { logservice.CNHAKeeperClient - cluster *ddlVisibilityTestCluster - queryClosed <-chan struct{} - sendErr error - sendErrors map[int]error - heartbeats []logservicepb.CNStoreHeartbeat - queryClosedBeforeSend bool - closeCalls int - clusterDeployedProtocol int64 - oldHAKeeperReplica bool + cluster *ddlVisibilityTestCluster + queryClosed <-chan struct{} + sendErr error + sendErrors map[int]error + heartbeats []logservicepb.CNStoreHeartbeat + queryClosedBeforeSend bool + closeCalls int + clusterDeployedProtocol int64 + oldHAKeeperReplica bool + authoritativeGenerations map[string]uint64 } func (c *ddlVisibilityWithdrawalHAKeeperClient) GetClusterDetails( @@ -248,6 +249,15 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( if c.sendErr != nil { return logservicepb.CommandBatch{}, c.sendErr } + authoritativeGeneration := hb.ViewMetadataAdmissionGeneration + if generation := c.authoritativeGenerations[hb.UUID]; generation > authoritativeGeneration { + return logservicepb.CommandBatch{ + DDLVisibilityDeployedProtocol: c.clusterDeployedProtocol, + ViewMetadataAdmission: &logservicepb.ViewMetadataAdmission{ + Generation: generation, + }, + }, nil + } if c.cluster != nil { c.cluster.phaseMu.Lock() if c.cluster.phases == nil { @@ -302,6 +312,9 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( } return logservicepb.CommandBatch{ DDLVisibilityDeployedProtocol: c.clusterDeployedProtocol, + ViewMetadataAdmission: &logservicepb.ViewMetadataAdmission{ + Generation: authoritativeGeneration, + }, }, nil } @@ -1599,6 +1612,7 @@ func TestAcknowledgedDDLFrontierSurvivesCrashBeforePeriodicHeartbeat(t *testing. producer := &service{ cfg: &Config{UUID: producerID}, _hakeeperClient: client, ddlCommitGate: frontend.NewDDLCommitGate(), config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: 1, } // This is the synchronous publication in the successful DDL commit path; @@ -1611,6 +1625,7 @@ func TestAcknowledgedDDLFrontierSurvivesCrashBeforePeriodicHeartbeat(t *testing. replacement := &service{ cfg: &Config{UUID: producerID}, _hakeeperClient: client, ddlCommitGate: frontend.NewDDLCommitGate(), config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: 2, } require.NoError(t, replacement.publishDDLCommitFrontier(context.Background(), timestamp.Timestamp{})) require.Equal(t, frontier, cluster.globalFrontier, @@ -1627,6 +1642,48 @@ func TestAcknowledgedDDLFrontierSurvivesCrashBeforePeriodicHeartbeat(t *testing. require.NoError(t, target.syncStartupDDLVisibilityFrontier(context.Background())) } +func TestStaleGenerationCannotAcknowledgeDDLFrontierPublication(t *testing.T) { + const producerID = "generation-fenced-ddl-producer" + oldFrontier := timestamp.Timestamp{PhysicalTime: 200} + commitFrontier := timestamp.Timestamp{PhysicalTime: 300} + cluster := &ddlVisibilityTestCluster{ + cnServices: []metadata.CNService{{ + ServiceID: producerID, QueryAddress: "new:6001", + ViewMetadataAdmissionGeneration: 2, DDLVisibilityBarrierReady: true, + }}, + globalFrontier: oldFrontier, + } + client := &ddlVisibilityWithdrawalHAKeeperClient{ + cluster: cluster, + authoritativeGenerations: map[string]uint64{producerID: 2}, + } + oldIncarnation := &service{ + cfg: &Config{UUID: producerID}, _hakeeperClient: client, + ddlCommitGate: frontend.NewDDLCommitGate(), config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: 1, + } + oldIncarnation.ddlCommitGate.SetFrontierPublisher(oldIncarnation.publishDDLCommitFrontier) + + err := oldIncarnation.ddlCommitGate.PublishDDLFrontier(context.Background(), commitFrontier) + require.ErrorContains(t, err, "generation 1 rejected by authoritative generation 2") + require.True(t, oldIncarnation.viewMetadataGenerationRevoked.Load()) + require.Equal(t, oldFrontier, cluster.globalFrontier, + "stale generation heartbeat must not advance the durable frontier") + + // After the stale process crashes, a future incarnation can only observe the + // old durable value. The failed publication therefore must not have been + // acknowledged by frontend (covered by the publisher-failure commit test). + ctrl := gomock.NewController(t) + restartedTxnClient := mock_frontend.NewMockTxnClient(ctrl) + restartedTxnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), oldFrontier).Return(oldFrontier, nil) + restartedTxnClient.EXPECT().SyncLatestCommitTS(oldFrontier) + restarted := &service{ + cfg: &Config{UUID: producerID}, _txnClient: restartedTxnClient, + _hakeeperClient: client, + } + require.NoError(t, restarted.syncStartupDDLVisibilityFrontier(context.Background())) +} + func TestSyncStartupDDLVisibilityFrontierSurvivesProducerReplacement(t *testing.T) { const serviceID = "ddl-visibility-durable-frontier-test" oldFrontier := timestamp.Timestamp{PhysicalTime: 300} diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 70dbcd891d279..1d1c82eb93bbf 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -196,10 +196,23 @@ func (s *service) publishDDLCommitFrontier(ctx context.Context, _ timestamp.Time } s.ddlVisibilityHeartbeatMu.Lock() defer s.ddlVisibilityHeartbeatMu.Unlock() - _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) + batch, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) if err != nil { return moerr.AttachCause(ctx, err) } + admission := batch.ViewMetadataAdmission + if s.viewMetadataAdmissionGeneration == 0 || admission == nil { + return moerr.NewInvalidStateNoCtx( + "DDL frontier publication lacks an authoritative CN generation") + } + if admission.Generation != s.viewMetadataAdmissionGeneration { + if admission.Generation > s.viewMetadataAdmissionGeneration { + s.revokeViewMetadataGeneration(admission.Generation) + } + return moerr.NewInvalidStateNoCtxf( + "DDL frontier publication generation %d rejected by authoritative generation %d", + s.viewMetadataAdmissionGeneration, admission.Generation) + } return nil } From 09609c5979b4166472b07dc0f9a5bc3608a6b41a Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Tue, 1 Sep 2026 16:06:09 +0800 Subject: [PATCH 27/34] fix: asynchronously drain revoked CN generation --- CLAUDE_TODO_2026-08-29.md | 6 ++ .../CLAUDE_cross_cn_ddl_visibility_fence.md | 2 +- pkg/cnservice/server_ddl_visibility_test.go | 34 +++++++++- .../server_view_metadata_admission.go | 67 +++++++++++-------- .../server_view_metadata_admission_test.go | 26 ++++--- 5 files changed, 92 insertions(+), 43 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index 36ad2eb80cb8e..d8000aed81778 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -75,3 +75,9 @@ 1. 同步 frontier heartbeat 必须验证 `CommandBatch.ViewMetadataAdmission.Generation` 与本地 incarnation generation 完全一致。 2. HAKeeper 返回更高 authoritative generation 时立即 revoke 旧 incarnation 并向 frontend 返回错误,禁止继续 fan-out/成功确认。 3. 增加 generation N commit → N+1 takeover → N publication rejected → N crash → restart 仅同步旧 durable frontier 的确定性回归,并运行 owning package/race/vet。 + +## 2026-09-01:generation revocation TaskRunner self-wait + +1. 将 revocation 拆为同步不可逆 admission seal 与异步 frontend/TaskRunner/full-service drain。 +2. 同步 frontier rejection 只等待 seal,不得等待可能包含当前 SQL DDL 调用栈的 TaskRunner.Stop。 +3. 增加 TaskRunner SQL DDL 自身发现 stale generation、rejection 先返回、task 退出后异步 Stop 才完成的确定性 Q2 回归,并运行 race/vet。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index 1fbdb40354c5c..1e47602280c91 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -80,7 +80,7 @@ The cluster epoch commit is the linearization point. Prepared, Fenced, and the l ### Steady-state DDL -A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned `CommandBatch.ViewMetadataAdmission.Generation` must exactly equal the sender generation. A stale sender rejected by HAKeeper therefore revokes itself and cannot mistake RPC delivery for durable frontier acceptance. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window. Protocol v43 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after generation-bound durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned `CommandBatch.ViewMetadataAdmission.Generation` must exactly equal the sender generation. A stale sender rejected by HAKeeper therefore seals all admission gates synchronously and cannot mistake RPC delivery for durable frontier acceptance. TaskRunner, frontend, and full-service drains run asynchronously after the seal: a TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v43 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after generation-bound durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. ### Scale-out and replacement diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index f46bf1ac4bdba..27d6aa7baa557 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -1660,12 +1660,42 @@ func TestStaleGenerationCannotAcknowledgeDDLFrontierPublication(t *testing.T) { oldIncarnation := &service{ cfg: &Config{UUID: producerID}, _hakeeperClient: client, ddlCommitGate: frontend.NewDDLCommitGate(), config: util.NewConfigData(nil), - viewMetadataAdmissionGeneration: 1, + viewMetadataAdmissionGeneration: 1, logger: zap.NewNop(), + } + runner := &blockedStopTaskRunner{ + testRunner: &testRunner{}, stopEntered: make(chan struct{}), + releaseStop: make(chan struct{}), stopDone: make(chan struct{}), } + oldIncarnation.task.runner = runner + oldIncarnation.task.runnerReady.Store(true) oldIncarnation.ddlCommitGate.SetFrontierPublisher(oldIncarnation.publishDDLCommitFrontier) - err := oldIncarnation.ddlCommitGate.PublishDDLFrontier(context.Background(), commitFrontier) + // Model the stale publication running inside the TaskRunner SQL task. The + // rejection must return before asynchronous runner.Stop can observe this task + // exit; otherwise each side waits permanently for the other. + publishDone := make(chan error, 1) + go func() { + publishDone <- oldIncarnation.ddlCommitGate.PublishDDLFrontier( + context.Background(), commitFrontier) + }() + var err error + select { + case err = <-publishDone: + case <-time.After(time.Second): + t.Fatal("generation rejection self-waited on its own TaskRunner SQL task") + } require.ErrorContains(t, err, "generation 1 rejected by authoritative generation 2") + select { + case <-runner.stopEntered: + case <-time.After(time.Second): + t.Fatal("asynchronous revocation did not begin TaskRunner drain") + } + close(runner.releaseStop) + select { + case <-runner.stopDone: + case <-time.After(time.Second): + t.Fatal("TaskRunner drain did not finish after the rejected SQL task exited") + } require.True(t, oldIncarnation.viewMetadataGenerationRevoked.Load()) require.Equal(t, oldFrontier, cluster.globalFrontier, "stale generation heartbeat must not advance the durable frontier") diff --git a/pkg/cnservice/server_view_metadata_admission.go b/pkg/cnservice/server_view_metadata_admission.go index 912ec86778c3f..ab0d3dbfb3626 100644 --- a/pkg/cnservice/server_view_metadata_admission.go +++ b/pkg/cnservice/server_view_metadata_admission.go @@ -24,6 +24,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/common/runtime" logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" "github.com/matrixorigin/matrixone/pkg/sql/compile" + "github.com/matrixorigin/matrixone/pkg/taskservice" ) const viewMetadataAdmissionGenerationKey = "view-metadata-admission-generation" @@ -114,9 +115,10 @@ func (s *service) applyViewMetadataAdmission( } // revokeViewMetadataGeneration fences a process that no longer owns its UUID. -// The gates are closed synchronously so scheduling an asynchronous full Close -// cannot leave a window for new SQL, QueryService, or pipeline work. Full Close -// runs outside the heartbeat stopper task to avoid waiting for itself. +// The admission seal is synchronous, but every potentially waiting drain runs +// asynchronously. In particular, a SQL task can discover its own stale +// generation while publishing a DDL frontier; waiting for TaskRunner.Stop on +// that stack would make the runner wait for the task that is doing the stop. func (s *service) revokeViewMetadataGeneration(authoritative uint64) { s.viewMetadataRevocationOnce.Do(func() { s.viewMetadataGenerationRevoked.Store(true) @@ -125,35 +127,42 @@ func (s *service) revokeViewMetadataGeneration(authoritative uint64) { _ = s.closePipelineAdmission() s.queryWork.beginClose() runner := s.detachRevokedTaskRunner() - // Serialize physical frontend shutdown with MOServer.Start before waiting - // for task executors, whose Stop may block indefinitely. Do not wait for - // the broader lifecycleMu held by the complete Start sequence. - if s.mo != nil { - if err := s.stopFrontendSerialized(); err != nil && s.logger != nil { - s.logger.Error("failed to stop superseded CN frontend", - zap.Uint64("local-generation", s.viewMetadataAdmissionGeneration), - zap.Uint64("authoritative-generation", authoritative), - zap.Error(err)) - } - } - s.stopRevokedTaskRunner(runner) - if s.stopper != nil || s.viewMetadataCloseFn != nil { - closeFn := s.Close - if s.viewMetadataCloseFn != nil { - closeFn = s.viewMetadataCloseFn - } - go func() { - if err := closeFn(); err != nil && s.logger != nil { - s.logger.Error("failed to close superseded CN", - zap.Uint64("local-generation", s.viewMetadataAdmissionGeneration), - zap.Uint64("authoritative-generation", authoritative), - zap.Error(err)) - } - }() - } + + go s.drainRevokedViewMetadataGeneration(authoritative, runner) }) } +func (s *service) drainRevokedViewMetadataGeneration( + authoritative uint64, + runner taskservice.TaskRunner, +) { + // Serialize physical frontend shutdown with MOServer.Start before waiting + // for task executors. The goroutine is independent of the rejected SQL task, + // allowing that task to return and satisfy TaskRunner.Stop's wait. + if s.mo != nil { + if err := s.stopFrontendSerialized(); err != nil && s.logger != nil { + s.logger.Error("failed to stop superseded CN frontend", + zap.Uint64("local-generation", s.viewMetadataAdmissionGeneration), + zap.Uint64("authoritative-generation", authoritative), + zap.Error(err)) + } + } + s.stopRevokedTaskRunner(runner) + if s.stopper == nil && s.viewMetadataCloseFn == nil { + return + } + closeFn := s.Close + if s.viewMetadataCloseFn != nil { + closeFn = s.viewMetadataCloseFn + } + if err := closeFn(); err != nil && s.logger != nil { + s.logger.Error("failed to close superseded CN", + zap.Uint64("local-generation", s.viewMetadataAdmissionGeneration), + zap.Uint64("authoritative-generation", authoritative), + zap.Error(err)) + } +} + func (s *service) fenceViewMetadataCatalog( ctx context.Context, snapshot *logservicepb.ViewMetadataAdmission, diff --git a/pkg/cnservice/server_view_metadata_admission_test.go b/pkg/cnservice/server_view_metadata_admission_test.go index 588d576cbff19..5dc260d9af490 100644 --- a/pkg/cnservice/server_view_metadata_admission_test.go +++ b/pkg/cnservice/server_view_metadata_admission_test.go @@ -66,12 +66,15 @@ type blockedStopTaskRunner struct { *testRunner stopEntered chan struct{} releaseStop chan struct{} + stopDone chan struct{} } func (r *blockedStopTaskRunner) Stop() error { close(r.stopEntered) <-r.releaseStop - return r.testRunner.Stop() + err := r.testRunner.Stop() + close(r.stopDone) + return err } type admissionCNHAKeeperClient struct { @@ -203,9 +206,7 @@ func TestCNViewMetadataAdmissionRevokesIngressForHigherGeneration(t *testing.T) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, s.task.runnerReady.Load(), "generation revocation must synchronously withdraw task-runner eligibility") - require.Equal(t, 1, runner.stopped, - "generation revocation must synchronously stop the running task runner") - require.Nil(t, s.GetTaskRunner(), "the stopped task runner must be detached") + require.Nil(t, s.GetTaskRunner(), "the revoked task runner must be synchronously detached") select { case <-pipelineCtx.Done(): default: @@ -216,6 +217,8 @@ func TestCNViewMetadataAdmissionRevokesIngressForHigherGeneration(t *testing.T) case <-time.After(time.Second): t.Fatal("superseded CN did not request full service closure") } + require.Equal(t, 1, runner.stopped, + "asynchronous generation drain must stop the detached task runner") select { case <-mo.stopped: default: @@ -236,6 +239,7 @@ func TestCNGenerationRevocationStopsFrontendBeforeTaskRunnerDrain(t *testing.T) testRunner: &testRunner{}, stopEntered: make(chan struct{}), releaseStop: make(chan struct{}), + stopDone: make(chan struct{}), } s := &service{ cfg: &Config{UUID: "task-runner-blocked-stop"}, @@ -264,14 +268,15 @@ func TestCNGenerationRevocationStopsFrontendBeforeTaskRunnerDrain(t *testing.T) } select { case <-revokeDone: - t.Fatal("generation revocation returned before the task runner stopped") - default: + // The synchronous seal must not inherit TaskRunner.Stop's wait graph. + case <-time.After(time.Second): + t.Fatal("generation revocation seal waited for the task runner") } close(runner.releaseStop) select { - case <-revokeDone: + case <-runner.stopDone: case <-time.After(time.Second): - t.Fatal("generation revocation did not finish after the task runner stopped") + t.Fatal("asynchronous task runner drain did not finish") } require.Equal(t, 1, runner.stopped) require.Nil(t, s.GetTaskRunner()) @@ -303,9 +308,8 @@ func TestCNGenerationRevocationStopsTaskRunnerStartInFlight(t *testing.T) { select { case <-revokeDone: case <-time.After(time.Second): - t.Fatal("generation revocation did not finish stopping the in-flight task runner") + t.Fatal("generation revocation did not finish sealing the in-flight task runner") } - require.Equal(t, 1, runner.stopped) require.False(t, s.task.runnerReady.Load()) require.Nil(t, s.GetTaskRunner()) } @@ -352,7 +356,7 @@ func TestCNGenerationRevocationCancelsIngressStart(t *testing.T) { require.False(t, s.task.runnerReady.Load()) select { case <-mo.stopped: - default: + case <-time.After(time.Second): t.Fatal("revocation did not stop frontend after the in-flight Start completed") } select { From e3afd3fc173a2359a8c73ec8c26ceb939ca5ed71 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Tue, 1 Sep 2026 22:22:54 +0800 Subject: [PATCH 28/34] fix: coordinate revoked TaskRunner with service close --- CLAUDE_TODO_2026-08-29.md | 6 +++ .../CLAUDE_cross_cn_ddl_visibility_fence.md | 2 +- pkg/cnservice/server_task.go | 52 +++++++++++++------ .../server_view_metadata_admission.go | 7 +-- .../server_view_metadata_admission_test.go | 52 +++++++++++++++++++ pkg/cnservice/types.go | 2 + 6 files changed, 101 insertions(+), 20 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index d8000aed81778..effe06073332c 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -81,3 +81,9 @@ 1. 将 revocation 拆为同步不可逆 admission seal 与异步 frontend/TaskRunner/full-service drain。 2. 同步 frontier rejection 只等待 seal,不得等待可能包含当前 SQL DDL 调用栈的 TaskRunner.Stop。 3. 增加 TaskRunner SQL DDL 自身发现 stale generation、rejection 先返回、task 退出后异步 Stop 才完成的确定性 Q2 回归,并运行 race/vet。 + +## 2026-09-01:revoked TaskRunner 与正常 Close 协调 + +1. 在 `s.task` 下建立 detached revoked-runner 的共享 ownership/completion;异步 revocation drain 是唯一 Stop owner。 +2. 正常 `stopTask` 在锁内转移普通 runner ownership,锁外执行 holder.Close/runner.Stop;若 runner 已由 revocation 摘除,则等待共享 completion 后才允许关闭下游依赖。 +3. 分别覆盖 stopTask 先取得 runner 与 revocation 先摘除 runner 两种顺序,证明无持锁等待、无 double Stop、无依赖提前关闭。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index 1e47602280c91..242445cedb13e 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -80,7 +80,7 @@ The cluster epoch commit is the linearization point. Prepared, Fenced, and the l ### Steady-state DDL -A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned `CommandBatch.ViewMetadataAdmission.Generation` must exactly equal the sender generation. A stale sender rejected by HAKeeper therefore seals all admission gates synchronously and cannot mistake RPC delivery for durable frontier acceptance. TaskRunner, frontend, and full-service drains run asynchronously after the seal: a TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v43 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after generation-bound durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned `CommandBatch.ViewMetadataAdmission.Generation` must exactly equal the sender generation. A stale sender rejected by HAKeeper therefore seals all admission gates synchronously and cannot mistake RPC delivery for durable frontier acceptance. TaskRunner, frontend, and full-service drains run asynchronously after the seal: a TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. Revocation transfers a detached runner into shared drain ownership with a completion channel; normal `service.Close` waits for that completion before closing task/txn/RPC dependencies. Conversely, if normal Close takes runner ownership first, it releases the task mutex before `runner.Stop`, allowing the SQL task to seal revocation and exit. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v43 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after generation-bound durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. ### Scale-out and replacement diff --git a/pkg/cnservice/server_task.go b/pkg/cnservice/server_task.go index cb4a071d76272..322d6940143a5 100644 --- a/pkg/cnservice/server_task.go +++ b/pkg/cnservice/server_task.go @@ -213,22 +213,32 @@ func (s *service) publishTaskRunner() error { return nil } -func (s *service) detachRevokedTaskRunner() taskservice.TaskRunner { +func (s *service) detachRevokedTaskRunner() (taskservice.TaskRunner, chan struct{}) { s.task.Lock() defer s.task.Unlock() s.task.generationRevoked = true s.task.runnerReady.Store(false) - runner := s.task.runner - s.task.runner = nil - return runner + if s.task.runner != nil { + s.task.revokedRunner = s.task.runner + s.task.revokedRunnerDone = make(chan struct{}) + s.task.runner = nil + } + return s.task.revokedRunner, s.task.revokedRunnerDone } -func (s *service) stopRevokedTaskRunner(runner taskservice.TaskRunner) { - if runner != nil { - if err := runner.Stop(); err != nil { - s.logger.Error("stop revoked generation task runner failed", zap.Error(err)) - } +func (s *service) stopRevokedTaskRunner(runner taskservice.TaskRunner, done chan struct{}) { + if runner == nil { + return + } + if err := runner.Stop(); err != nil && s.logger != nil { + s.logger.Error("stop revoked generation task runner failed", zap.Error(err)) + } + s.task.Lock() + if s.task.revokedRunner == runner { + s.task.revokedRunner = nil + close(done) } + s.task.Unlock() } func (s *service) startTaskRunnerLocked() { @@ -304,15 +314,25 @@ func (s *service) GetTaskService() (taskservice.TaskService, bool) { func (s *service) stopTask() error { defer logutil.LogClose(s.logger, "cnservice/task")() + // Transfer normal runner ownership while holding task.Lock, then release it + // before any Stop/wait. A SQL task may synchronously trigger generation + // revocation and must be able to acquire this lock in order to exit. s.task.Lock() - defer s.task.Unlock() - if s.task.holder == nil { - return nil - } + holder := s.task.holder + runner := s.task.runner + s.task.runner = nil + revokedDone := s.task.revokedRunnerDone + s.task.Unlock() - err := s.task.holder.Close() - if s.task.runner != nil { - err = errors.Join(err, s.task.runner.Stop()) + var err error + if holder != nil { + err = holder.Close() + } + if runner != nil { + err = errors.Join(err, runner.Stop()) + } + if revokedDone != nil { + <-revokedDone } return err } diff --git a/pkg/cnservice/server_view_metadata_admission.go b/pkg/cnservice/server_view_metadata_admission.go index ab0d3dbfb3626..830aaf37489bc 100644 --- a/pkg/cnservice/server_view_metadata_admission.go +++ b/pkg/cnservice/server_view_metadata_admission.go @@ -126,15 +126,16 @@ func (s *service) revokeViewMetadataGeneration(authoritative uint64) { s.ddlVisibilityBarrierReady.Store(false) _ = s.closePipelineAdmission() s.queryWork.beginClose() - runner := s.detachRevokedTaskRunner() + runner, runnerDone := s.detachRevokedTaskRunner() - go s.drainRevokedViewMetadataGeneration(authoritative, runner) + go s.drainRevokedViewMetadataGeneration(authoritative, runner, runnerDone) }) } func (s *service) drainRevokedViewMetadataGeneration( authoritative uint64, runner taskservice.TaskRunner, + runnerDone chan struct{}, ) { // Serialize physical frontend shutdown with MOServer.Start before waiting // for task executors. The goroutine is independent of the rejected SQL task, @@ -147,7 +148,7 @@ func (s *service) drainRevokedViewMetadataGeneration( zap.Error(err)) } } - s.stopRevokedTaskRunner(runner) + s.stopRevokedTaskRunner(runner, runnerDone) if s.stopper == nil && s.viewMetadataCloseFn == nil { return } diff --git a/pkg/cnservice/server_view_metadata_admission_test.go b/pkg/cnservice/server_view_metadata_admission_test.go index 5dc260d9af490..da780ca2a8885 100644 --- a/pkg/cnservice/server_view_metadata_admission_test.go +++ b/pkg/cnservice/server_view_metadata_admission_test.go @@ -272,6 +272,13 @@ func TestCNGenerationRevocationStopsFrontendBeforeTaskRunnerDrain(t *testing.T) case <-time.After(time.Second): t.Fatal("generation revocation seal waited for the task runner") } + closeDone := make(chan error, 1) + go func() { closeDone <- s.stopTask() }() + select { + case <-closeDone: + t.Fatal("normal Close passed the detached runner before its drain completed") + case <-time.After(20 * time.Millisecond): + } close(runner.releaseStop) select { case <-runner.stopDone: @@ -279,9 +286,54 @@ func TestCNGenerationRevocationStopsFrontendBeforeTaskRunnerDrain(t *testing.T) t.Fatal("asynchronous task runner drain did not finish") } require.Equal(t, 1, runner.stopped) + require.NoError(t, <-closeDone) require.Nil(t, s.GetTaskRunner()) } +func TestCNGenerationRevocationDoesNotWaitForCloseOwnedTaskRunner(t *testing.T) { + runner := &blockedStopTaskRunner{ + testRunner: &testRunner{}, stopEntered: make(chan struct{}), + releaseStop: make(chan struct{}), stopDone: make(chan struct{}), + } + s := &service{ + cfg: &Config{UUID: "close-owned-task-runner"}, logger: zap.NewNop(), + viewMetadataAdmissionGeneration: 8, + } + s.task.runner = runner + s.task.runnerReady.Store(true) + + closeDone := make(chan error, 1) + go func() { closeDone <- s.stopTask() }() + select { + case <-runner.stopEntered: + case <-time.After(time.Second): + t.Fatal("normal Close did not take runner drain ownership") + } + + revokeDone := make(chan struct{}) + go func() { + s.revokeViewMetadataGeneration(9) + close(revokeDone) + }() + select { + case <-revokeDone: + // stopTask must not hold task.Lock across runner.Stop. + case <-time.After(time.Second): + t.Fatal("revocation waited on task.Lock held across normal runner.Stop") + } + require.True(t, s.viewMetadataGenerationRevoked.Load()) + require.False(t, s.task.runnerReady.Load()) + + close(runner.releaseStop) + select { + case <-runner.stopDone: + case <-time.After(time.Second): + t.Fatal("normal Close runner drain did not finish") + } + require.NoError(t, <-closeDone) + require.Equal(t, 1, runner.stopped) +} + func TestCNGenerationRevocationStopsTaskRunnerStartInFlight(t *testing.T) { s := &service{ cfg: &Config{UUID: "task-runner-revoked-during-start"}, diff --git a/pkg/cnservice/types.go b/pkg/cnservice/types.go index 07e5636498e7e..0d813af0ccb1f 100644 --- a/pkg/cnservice/types.go +++ b/pkg/cnservice/types.go @@ -827,6 +827,8 @@ type service struct { sync.RWMutex holder taskservice.TaskServiceHolder runner taskservice.TaskRunner + revokedRunner taskservice.TaskRunner + revokedRunnerDone chan struct{} runnerReady atomic.Bool generationRevoked bool storageFactory taskservice.TaskStorageFactory From 514bd13aea87e84e48ab483eadcf8d388c9f03c8 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Tue, 1 Sep 2026 22:48:55 +0800 Subject: [PATCH 29/34] fix: prove durable DDL frontier publication --- CLAUDE_TODO_2026-08-29.md | 7 + .../CLAUDE_cross_cn_ddl_visibility_fence.md | 54 +- pkg/cnservice/server_ddl_visibility.go | 34 +- pkg/cnservice/server_ddl_visibility_test.go | 133 ++- pkg/cnservice/server_heartbeat.go | 32 +- pkg/cnservice/server_heartbeat_test.go | 20 + pkg/cnservice/server_query.go | 2 +- pkg/defines/const.go | 5 +- pkg/frontend/txn.go | 4 +- pkg/hakeeper/view_metadata_admission.go | 2 + pkg/pb/logservice/logservice.pb.go | 855 ++++++++++-------- pkg/queryservice/client/query_client.go | 2 +- pkg/queryservice/client/query_client_test.go | 4 +- pkg/sql/plan/function/ctl/cmd_rpc_version.go | 10 +- .../plan/function/ctl/cmd_rpc_version_test.go | 10 +- .../issue_277xx_ddl_consistency_test.go | 12 +- proto/logservice.proto | 3 + 17 files changed, 675 insertions(+), 514 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index effe06073332c..8b80860d6326a 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -87,3 +87,10 @@ 1. 在 `s.task` 下建立 detached revoked-runner 的共享 ownership/completion;异步 revocation drain 是唯一 Stop owner。 2. 正常 `stopTask` 在锁内转移普通 runner ownership,锁外执行 holder.Close/runner.Stop;若 runner 已由 revocation 摘除,则等待共享 completion 后才允许关闭下游依赖。 3. 分别覆盖 stopTask 先取得 runner 与 revocation 先摘除 runner 两种顺序,证明无持锁等待、无 double Stop、无依赖提前关闭。 + +## 2026-09-01:新增 review blockers(frontier ack / heartbeat response / v44) + +1. 将 DDL capability 从与 #27553 冲突的 v43 移至下一未占用 v44,并迁移全部 gate、method map、测试、`mo_ctl` 路径及设计文档。 +2. 在同一 HAKeeper RSM heartbeat 响应中返回应用后的 authoritative frontier;CN 仅在 generation 精确匹配且 frontier >= T 时承认同步发布,旧 RSM 静默丢字段时 fail closed。 +3. 所有 direct CN heartbeat 将 CommandBatch 交给现有 command mutex/dedupe owner,避免 command-delivery-disabled 阶段的 destructive schedule command 丢失。 +4. 增加旧 HAKeeper 丢 frontier 与 legacy command delivery 的确定性回归,运行 affected package、race、vet 和 protobuf 测试。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index 242445cedb13e..c73715c3f7cc3 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -1,11 +1,11 @@ # Cross-CN DDL Visibility Fence - Status: **Approved** -- Revision: 3 +- Revision: 4 - Approval: user approval recorded in the PR implementation session on 2026-08-30 - Owning issue: #27743 - Implementation PR: #27756 -- Protocol version: MORPC v43 +- Protocol version: MORPC v44 ## 1. Classification and motivation @@ -17,22 +17,22 @@ Issue #27743 demonstrates a missing catalog-visibility invariant: a DDL can comm ### Safety invariant -After the v43 deployment epoch is committed, every CN capable of public DDL production must satisfy both conditions: +After the v44 deployment epoch is committed, every CN capable of public DDL production must satisfy both conditions: -1. its runtime protocol is at least v43, so DDL commit performs `SyncCommitV2` fan-out; and +1. its runtime protocol is at least v44, so DDL commit performs `SyncCommitV2` fan-out; and 2. it belongs to the exact generation/address membership set atomically committed by HAKeeper, or it remains fail-closed until it joins a later exact cut. Before a CN opens public ingress, its local catalog frontier must be at least the maximum frontier reported by all participants in the applicable cut. ### Negation -It is unsafe for any public or already-connected CN to commit DDL below v43 while another public CN can admit a snapshot that has not applied that commit. +It is unsafe for any public or already-connected CN to commit DDL below v44 while another public CN can admit a snapshot that has not applied that commit. ### Measurable criteria - A create on CN0 followed immediately by a first read/load on CN1 succeeds without explicit `SYNCCOMMIT`. -- Markerless startup preserves the current-main v42 baseline before the v43 cut. -- No local downgrade below v43 is accepted after the monotonic v43 epoch is committed. +- Markerless startup preserves the current-main v42 baseline before the v44 cut. +- No local downgrade below v44 is accepted after the monotonic v44 epoch is committed. - Membership change between final scan and epoch commit rejects the old target set atomically. - Restart, timeout, persistence failure, response loss, and leader failover remain fail-closed. @@ -55,36 +55,36 @@ HAKeeper is the first owner of cluster epoch and membership linearization. CN lo A CN is in one of these logical states: -1. **Baseline v42**: v43 not deployed; existing v38-v42 contracts remain active. Public ingress may be open. +1. **Baseline v42**: v44 not deployed; existing v38-v42 contracts remain active. Public ingress may be open. 2. **Withdrawing**: activation blocks new DDL, withdraws ingress, and drains active DDL. -3. **Prepared v43**: local old-protocol producers are drained; runtime can receive v43 RPCs. -4. **Provisionally fenced**: local frontier synchronization completed and `-43` is durable; ingress remains closed. +3. **Prepared v44**: local old-protocol producers are drained; runtime can receive v44 RPCs. +4. **Provisionally fenced**: local frontier synchronization completed and `-44` is durable; ingress remains closed. 5. **Cluster committed**: HAKeeper atomically validated exact `(serviceID, generation, queryAddress)` membership and advanced epoch to 43. 6. **Locally committed**: CN persisted `43`; only then may it republish ingress and unblock DDL. -7. **Markerless post-cut**: no local marker but HAKeeper epoch is 43; runtime remains v43 and ingress/DDL remain closed until a complete retry. +7. **Markerless post-cut**: no local marker but HAKeeper epoch is 43; runtime remains v44 and ingress/DDL remain closed until a complete retry. -The cluster epoch commit is the linearization point. Prepared, Fenced, and the last committed DDL frontier are published through each incarnation's heartbeat. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members, exact generation/address, receiver capability, and that each current incarnation itself published Prepared and Fenced, then advances the epoch only on exact equality. A replacement cannot reuse an older incarnation's Fenced proof. A join before this transition invalidates the target set; a join after it observes epoch 43 and is rejected as ingress-ready. +The cluster epoch commit is the linearization point. Prepared, Fenced, and the last committed DDL frontier are published through each incarnation's heartbeat. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members, exact generation/address, receiver capability, and that each current incarnation itself published Prepared and Fenced, then advances the epoch only on exact equality. A replacement cannot reuse an older incarnation's Fenced proof. A join before this transition invalidates the target set; a join after it observes epoch 44 and is rejected as ingress-ready. ## 5. End-to-end flow ### First rollout 1. All LogStore/HAKeeper replicas advertise support for the epoch schema. -2. Every CN runs v43-capable code but markerless CNs keep protocol baseline v42. +2. Every CN runs v44-capable code but markerless CNs keep protocol baseline v42. 3. `mo_ctl SetProtocolVersion` refreshes raw authoritative CN membership. -4. The requested set must exactly match all eligible CN tuples and each target must advertise the v43 receiver/barrier capability. +4. The requested set must exactly match all eligible CN tuples and each target must advertise the v44 receiver/barrier capability. 5. Targets concurrently withdraw ingress, block and drain DDL, capture their reconstructed latest committed timestamp, then heartbeat Prepared together with that frontier. HAKeeper advances a cluster-lifetime maximum and never lowers it when an incarnation restarts, is replaced, or is removed. 6. Each target reads and applies the replicated cluster-lifetime frontier, durably enters provisional Fenced, and heartbeats Fenced. This avoids cyclic QueryService control RPCs while every target is already serving a long-running activation RPC. -7. Each target confirms all exact current incarnations are Fenced in HAKeeper; HAKeeper atomically revalidates those tuple-bound proofs and commits epoch 43. +7. Each target confirms all exact current incarnations are Fenced in HAKeeper; HAKeeper atomically revalidates those tuple-bound proofs and commits epoch 44. 8. Each CN persists local committed 43, republishes ingress if listeners are live, and unblocks public DDL. ### Steady-state DDL -A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned `CommandBatch.ViewMetadataAdmission.Generation` must exactly equal the sender generation. A stale sender rejected by HAKeeper therefore seals all admission gates synchronously and cannot mistake RPC delivery for durable frontier acceptance. TaskRunner, frontend, and full-service drains run asynchronously after the seal: a TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. Revocation transfers a detached runner into shared drain ownership with a completion channel; normal `service.Close` waits for that completion before closing task/txn/RPC dependencies. Conversely, if normal Close takes runner ownership first, it releases the task mutex before `runner.Stop`, allowing the SQL task to seal revocation and exit. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v43 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after generation-bound durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned `CommandBatch.ViewMetadataAdmission.Generation` must exactly equal the sender generation, and the returned authoritative frontier must be at least the exact T submitted in that transition. A stale sender or a legacy HAKeeper RSM that silently ignores the frontier therefore cannot mistake RPC delivery for durable frontier acceptance. Every direct CN heartbeat transfers its returned `CommandBatch` to the periodic heartbeat's command mutex/deduplication owner before returning, so startup, ingress, activation, withdrawal, and frontier publication cannot destructively consume and discard a legacy schedule command. TaskRunner, frontend, and full-service drains run asynchronously after the seal: a TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. Revocation transfers a detached runner into shared drain ownership with a completion channel; normal `service.Close` waits for that completion before closing task/txn/RPC dependencies. Conversely, if normal Close takes runner ownership first, it releases the task mutex before `runner.Stop`, allowing the SQL task to seal revocation and exit. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v44 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after generation-bound durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. ### Scale-out and replacement -A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes before the cluster commit, it becomes authoritative membership and invalidates any old target proof. If it linearizes after commit, HAKeeper forces ingress false and returns epoch 43. It never becomes a public v42 producer after the cut. +A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes before the cluster commit, it becomes authoritative membership and invalidates any old target proof. If it linearizes after commit, HAKeeper forces ingress false and returns epoch 44. It never becomes a public v42 producer after the cut. ## 6. Failure, retry, and lifecycle behavior @@ -95,7 +95,7 @@ A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes - **Epoch response loss**: epoch may be committed, but local marker remains provisional and ingress closed; retry learns the committed epoch. - **Committed local persistence failure**: cluster epoch remains committed; this CN remains closed and restarts from provisional state. - **Ingress publication uncertainty**: perform a bounded cleanup withdrawal; never assume publication failed. -- **Restart**: committed marker runs startup frontier synchronization before opening; provisional or markerless post-cut starts v43 fail-closed. +- **Restart**: committed marker runs startup frontier synchronization before opening; provisional or markerless post-cut starts v44 fail-closed. - **Shutdown**: stop periodic heartbeat publication, then withdraw ingress/barrier state before stopping QueryService. - **Leader failover**: activation is gated until every voting and non-voting LogStore advertises epoch-schema capability, so any eligible HAKeeper leader preserves the field. @@ -105,20 +105,20 @@ Retries are idempotent for the same generation and target set. Replacement gener ### Mixed-version baseline -Current main already deploys v42 semantics. A fresh v43-capable process without a DDL marker therefore remains at v42, not v37. The v43 DDL state is separate from unrelated v38-v42 capabilities. +Current main already deploys v42 semantics. A fresh v44-capable process without a DDL marker therefore remains at v42, not v37. The v44 DDL state is separate from unrelated v38-v42 capabilities. ### Rollout order 1. Upgrade all voting and non-voting LogStores/HAKeeper replicas. 2. Upgrade every CN; verify barrier receiver capability in raw inventory. -3. Invoke one exact complete-target v43 activation. -4. Verify epoch 43 and all eligible CN ingress/committed markers. +3. Invoke one exact complete-target v44 activation. +4. Verify epoch 44 and all eligible CN ingress/committed markers. ### Downgrade policy -Before epoch 43, ordinary protocol changes at or below v42 remain possible. After epoch 43, local downgrade below v43 is rejected. A safe rollback would require a separately designed atomic cluster rollback that withdraws and drains every DDL producer before lowering the epoch; this revision deliberately does not implement epoch rollback. +Before epoch 44, ordinary protocol changes at or below v42 remain possible. After epoch 44, local downgrade below v44 is rejected. A safe rollback would require a separately designed atomic cluster rollback that withdraws and drains every DDL producer before lowering the epoch; this revision deliberately does not implement epoch rollback. -Binary rollback after epoch 43 is unsupported until such a rollback protocol exists. Operators must restore forward to a v43-capable binary. +Binary rollback after epoch 44 is unsupported until such a rollback protocol exists. Operators must restore forward to a v44-capable binary. ## 8. Proxy and direct ingress @@ -159,7 +159,7 @@ Rejected: compiled capability is not proof that every producer completed the dis ### D. Separate DDL feature epoch from the shared MORPC scalar -Architecturally clean and avoids scalar coupling, but still requires the same membership/ingress linearization and broader API migration. This revision retains MORPC v43 as the sender/receiver capability gate while storing deployment completion separately. +Architecturally clean and avoids scalar coupling, but still requires the same membership/ingress linearization and broader API migration. This revision retains MORPC v44 as the sender/receiver capability gate while storing deployment completion separately. ### E. TN-only global catalog barrier on every new transaction @@ -169,8 +169,8 @@ Could provide a stronger generic read contract, but materially changes every tra | Contract | Deterministic evidence | |---|---| -| v42 baseline preserved | markerless default-v43 startup UT | -| post-cut downgrade rejected | completed-v43 downgrade UT | +| v42 baseline preserved | markerless default-v44 startup UT | +| post-cut downgrade rejected | completed-v44 downgrade UT | | exact authoritative targets | ctl raw-membership omission/capability UT | | join/commit atomicity | CNState RSM ordering UT: final scan, join, stale commit | | HAKeeper failover compatibility | old capability view rejection UT | @@ -182,7 +182,7 @@ Could provide a stronger generic read contract, but materially changes every tra ## 14. Decision log and open items - Chosen linearization point: HAKeeper replicated heartbeat transition with exact tuple proof. -- Chosen baseline: preserve current-main v42 before v43 activation. +- Chosen baseline: preserve current-main v42 before v44 activation. - Chosen downgrade behavior: reject after monotonic epoch commit. - Chosen direct-ingress protection: local DDL gate in addition to proxy admission. - Non-blocking follow-up: add dedicated activation/fan-out metrics and publish N-CN staging latency evidence. diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index cf708be64b805..de69099773a0b 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -33,7 +33,7 @@ import ( func ddlVisibilityBarrierSupported(serviceID string) bool { value, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) version, valid := value.(int64) - return ok && valid && version >= defines.MORPCVersion43 + return ok && valid && version >= defines.MORPCVersion44 } // prepareDDLVisibilityBarrier publishes this CN only after QueryService is @@ -56,7 +56,7 @@ func (s *service) prepareDDLVisibilityBarrier() error { return err } cancel() - if details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion43 { + if details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion44 { // Markerless scale-out/replacement after the cluster cut joins v43 as // provisional. It can synchronize and receive activation RPCs, but it // cannot publish ingress or produce DDL before joining the exact cut. @@ -64,16 +64,16 @@ func (s *service) prepareDDLVisibilityBarrier() error { } } rt := moruntime.ServiceRuntime(s.cfg.UUID) - if deployedVersion >= defines.MORPCVersion43 { + if deployedVersion >= defines.MORPCVersion44 { s.ddlVisibilityActivationComplete.Store(true) rt.SetGlobalVariables(moruntime.MOProtocolVersion, deployedVersion) - } else if deployedVersion <= -defines.MORPCVersion43 { + } else if deployedVersion <= -defines.MORPCVersion44 { // A provisional marker proves this CN durably fenced its local producers, // but not that every target committed the same cut. Keep v43 capability so // retries can converge while startup/public ingress remains fail-closed. rt.SetGlobalVariables(moruntime.MOProtocolVersion, -deployedVersion) } else if value, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion); ok { - if version, valid := value.(int64); valid && version >= defines.MORPCVersion43 { + if version, valid := value.(int64); valid && version >= defines.MORPCVersion44 { rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion42) } } @@ -122,7 +122,7 @@ func (s *service) prepareDDLVisibilityBarrierLocked() error { // the same mutex to order readiness snapshots) would deadlock publication. // Publish the startup barrier directly before waiting for its authoritative // observation; periodic heartbeats remain serialized behind startup. - if _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { + if _, err := s.sendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { return moerr.AttachCause(ctx, err) } @@ -141,7 +141,7 @@ func (s *service) prepareDDLVisibilityBarrierLocked() error { // proof bound to this restart/replacement incarnation so future scale-out // activation does not wait on stale proof from its predecessor. s.ddlVisibilityActivationFenced.Store(true) - if _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { + if _, err := s.sendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { return moerr.AttachCause(ctx, err) } } @@ -178,14 +178,14 @@ func (s *service) publishDDLVisibilityIngressAfterStart() error { hb := s.newCNStoreHeartbeat() hb.ViewMetadataIngressReady = true ctx, cancel := s.newDDLVisibilityBarrierContext(context.Background()) - batch, err := s._hakeeperClient.SendCNHeartbeat(ctx, hb) + batch, err := s.sendCNHeartbeat(ctx, hb) if err != nil { err = moerr.AttachCause(ctx, err) cancel() return err } cancel() - if batch.DDLVisibilityDeployedProtocol >= defines.MORPCVersion43 { + if batch.DDLVisibilityDeployedProtocol >= defines.MORPCVersion44 { moruntime.ServiceRuntime(s.cfg.UUID).SetGlobalVariables( moruntime.MOProtocolVersion, batch.DDLVisibilityDeployedProtocol) s.viewMetadataIngressReady.Store(false) @@ -223,7 +223,7 @@ func (s *service) withdrawDDLVisibilityBarrierLocked(ctx context.Context) error return moerr.NewInternalErrorNoCtx("DDL visibility barrier withdrawal dependencies are unavailable") } - if _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { + if _, err := s.sendCNHeartbeat(ctx, s.newCNStoreHeartbeat()); err != nil { return moerr.AttachCause(ctx, err) } return s.waitForDDLVisibilityBarrierWithdrawal(ctx, s.ddlVisibilityBarrierRetryInterval()) @@ -271,13 +271,13 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets return moerr.NewInternalError(ctx, "invalid protocol version") } pending := s.ddlVisibilityActivationPending.Load() - if version < defines.MORPCVersion43 { + if version < defines.MORPCVersion44 { if pending { return moerr.NewInvalidStateNoCtx("cannot downgrade during DDL visibility activation") } deployed := s.loadDDLVisibilityDeployedProtocol() clusterCommitted := s.ddlVisibilityActivationComplete.Load() || - deployed >= defines.MORPCVersion43 || deployed <= -defines.MORPCVersion43 + deployed >= defines.MORPCVersion44 || deployed <= -defines.MORPCVersion44 if !clusterCommitted && s._hakeeperClient != nil { queryCtx, cancel := s.newDDLVisibilityBarrierContext(ctx) details, err := s._hakeeperClient.GetClusterDetails(queryCtx) @@ -287,7 +287,7 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets return err } cancel() - clusterCommitted = details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion43 + clusterCommitted = details.DDLVisibilityDeployedProtocol >= defines.MORPCVersion44 } if clusterCommitted { return moerr.NewInvalidStateNoCtx( @@ -306,7 +306,7 @@ func (s *service) setProtocolVersion(ctx context.Context, version int64, targets rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) return nil } - if current >= defines.MORPCVersion43 && !pending && + if current >= defines.MORPCVersion44 && !pending && s.ddlVisibilityActivationComplete.Load() { rt.SetGlobalVariables(moruntime.MOProtocolVersion, version) return nil @@ -483,7 +483,7 @@ func (s *service) commitDDLVisibilityClusterEpoch( hb.DDLVisibilityDeployedProtocol = version hb.DDLVisibilityEpochCommitTargets = append( []logservicepb.DDLVisibilityActivationTarget(nil), targets...) - batch, err := s._hakeeperClient.SendCNHeartbeat(ctx, hb) + batch, err := s.sendCNHeartbeat(ctx, hb) if err != nil { return moerr.AttachCause(ctx, err) } @@ -536,7 +536,7 @@ func (s *service) setDDLVisibilityIngressLocked(ctx context.Context, ready bool) s.ddlVisibilityHeartbeatMu.Lock() s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(ready) - _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) + _, err := s.sendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) s.ddlVisibilityHeartbeatMu.Unlock() if err != nil { return moerr.AttachCause(ctx, err) @@ -588,7 +588,7 @@ func (s *service) waitForDDLVisibilityIngress( func (s *service) publishDDLVisibilityActivationPhaseLocked(ctx context.Context) error { s.ddlVisibilityHeartbeatMu.Lock() defer s.ddlVisibilityHeartbeatMu.Unlock() - _, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) + _, err := s.sendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) if err != nil { return moerr.AttachCause(ctx, err) } diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 203b494a83294..ff7ecbbaaa8a2 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -171,7 +171,7 @@ func (*ddlVisibilityTestQueryClient) Close() error { return nil } func activationTestPeerProtocols() map[string]query.GetProtocolVersionResponse { return map[string]query.GetProtocolVersionResponse{ "peer:6001": { - Version: defines.MORPCVersion43, + Version: defines.MORPCVersion44, DDLVisibilityActivationPrepared: true, DDLVisibilityActivationFenced: true, }, @@ -189,6 +189,7 @@ type ddlVisibilityWithdrawalHAKeeperClient struct { closeCalls int clusterDeployedProtocol int64 oldHAKeeperReplica bool + oldDDLFrontierRSM bool authoritativeGenerations map[string]uint64 } @@ -253,6 +254,7 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( if generation := c.authoritativeGenerations[hb.UUID]; generation > authoritativeGeneration { return logservicepb.CommandBatch{ DDLVisibilityDeployedProtocol: c.clusterDeployedProtocol, + DDLVisibilityFrontier: &c.cluster.globalFrontier, ViewMetadataAdmission: &logservicepb.ViewMetadataAdmission{ Generation: generation, }, @@ -271,9 +273,11 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( if c.cluster.frontiers == nil { c.cluster.frontiers = make(map[string]timestamp.Timestamp) } - c.cluster.frontiers[hb.UUID] = hb.DDLVisibilityFrontier - if c.cluster.globalFrontier.Less(hb.DDLVisibilityFrontier) { - c.cluster.globalFrontier = hb.DDLVisibilityFrontier + if !c.oldDDLFrontierRSM { + c.cluster.frontiers[hb.UUID] = hb.DDLVisibilityFrontier + if c.cluster.globalFrontier.Less(hb.DDLVisibilityFrontier) { + c.cluster.globalFrontier = hb.DDLVisibilityFrontier + } } c.cluster.phaseMu.Unlock() } @@ -283,7 +287,7 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( cn.ViewMetadataAdmissionGeneration = hb.ViewMetadataAdmissionGeneration cn.DDLVisibilityBarrierReady = hb.DDLVisibilityBarrierReady cn.ViewMetadataIngressReady = hb.ViewMetadataIngressReady - if c.clusterDeployedProtocol >= defines.MORPCVersion43 && + if c.clusterDeployedProtocol >= defines.MORPCVersion44 && hb.DDLVisibilityDeployedProtocol < c.clusterDeployedProtocol { cn.ViewMetadataIngressReady = false } @@ -312,6 +316,7 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( } return logservicepb.CommandBatch{ DDLVisibilityDeployedProtocol: c.clusterDeployedProtocol, + DDLVisibilityFrontier: &c.cluster.globalFrontier, ViewMetadataAdmission: &logservicepb.ViewMetadataAdmission{ Generation: authoritativeGeneration, }, @@ -452,7 +457,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { } // Persist with the old process, then construct a distinct service and load // through the production metadata initialization path. - require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion43)) + require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion44)) s := &service{ cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS, logger: zap.NewNop(), @@ -463,7 +468,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { ddlCommitGate: frontend.NewDDLCommitGate(), } require.NoError(t, s.initMetadata()) - require.Equal(t, defines.MORPCVersion43, s.metadata.DDLVisibilityDeployedProtocol) + require.Equal(t, defines.MORPCVersion44, s.metadata.DDLVisibilityDeployedProtocol) require.False(t, s.ddlVisibilityActivationComplete.Load()) require.NoError(t, s.prepareDDLVisibilityBarrier()) require.True(t, s.ddlVisibilityBarrierPrepared.Load()) @@ -481,7 +486,7 @@ func TestPrepareDDLVisibilityBarrier(t *testing.T) { require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.True(t, s.viewMetadataIngressReady.Load()) require.True(t, s.ddlCommitGate.PublicDDLEnabled()) } @@ -546,11 +551,11 @@ func TestMarkerlessCNIngressHandshakeLinearizesWithCommittedCut(t *testing.T) { // The startup read precedes the cut, but the atomic ingress heartbeat lands // after it. HAKeeper must reject ingress and return the committed epoch. require.NoError(t, s.prepareDDLVisibilityBarrier()) - client.clusterDeployedProtocol = defines.MORPCVersion43 + client.clusterDeployedProtocol = defines.MORPCVersion44 require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) require.False(t, gate.PublicDDLEnabled()) @@ -564,7 +569,7 @@ func TestMarkerlessCNJoinsCommittedClusterFailClosed(t *testing.T) { s := &service{ cfg: &Config{UUID: serviceID}, ddlCommitGate: gate, config: util.NewConfigData(nil), _hakeeperClient: &ddlVisibilityWithdrawalHAKeeperClient{ - cluster: cluster, clusterDeployedProtocol: defines.MORPCVersion43, + cluster: cluster, clusterDeployedProtocol: defines.MORPCVersion44, }, } @@ -572,7 +577,7 @@ func TestMarkerlessCNJoinsCommittedClusterFailClosed(t *testing.T) { require.NoError(t, s.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.False(t, s.ddlVisibilityActivationComplete.Load()) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, gate.PublicDDLEnabled()) @@ -584,7 +589,7 @@ func TestProvisionalV43RestartRemainsFailClosed(t *testing.T) { metadataFS := newDDLVisibilityMetadataFS(t) cfg := &Config{UUID: serviceID} writer := &service{cfg: cfg, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: metadataFS} - require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(-defines.MORPCVersion43)) + require.NoError(t, writer.persistDDLVisibilityDeployedProtocol(-defines.MORPCVersion44)) gate := frontend.NewDDLCommitGate() restarted := &service{ @@ -596,7 +601,7 @@ func TestProvisionalV43RestartRemainsFailClosed(t *testing.T) { require.NoError(t, restarted.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.False(t, restarted.ddlVisibilityActivationComplete.Load()) require.False(t, restarted.viewMetadataIngressReady.Load()) require.False(t, gate.PublicDDLEnabled()) @@ -609,7 +614,7 @@ func TestPrepareDDLVisibilityBarrierRejectsMissingProductionDependencies(t *test cfg: &Config{UUID: serviceID}, metadata: metadata.CNStore{UUID: serviceID}, metadataFS: newDDLVisibilityMetadataFS(t), viewMetadataAdmissionGeneration: 1, } - require.NoError(t, s.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion43)) + require.NoError(t, s.persistDDLVisibilityDeployedProtocol(defines.MORPCVersion44)) err := s.prepareDDLVisibilityBarrier() require.ErrorContains(t, err, "dependencies are unavailable") @@ -642,7 +647,7 @@ func TestHandleSetProtocolVersionRejectsStaleRecoveryIdentity(t *testing.T) { } err := s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID}, + Version: defines.MORPCVersion44, DDLVisibilityActivationTargets: []string{serviceID}, DDLVisibilityTargetGeneration: generation + 1, DDLVisibilityTargetQueryAddress: "stale:6001", }, @@ -686,7 +691,7 @@ func TestActivationDoesNotPublishFencedBeforeProvisionalPersistence(t *testing.T s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion43, []string{serviceID}) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion44, []string{serviceID}) require.ErrorContains(t, err, "injected metadata replace failure") require.True(t, s.ddlVisibilityActivationPrepared.Load()) require.False(t, s.ddlVisibilityActivationFenced.Load()) @@ -731,12 +736,12 @@ func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion43, []string{serviceID}) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion44, []string{serviceID}) require.ErrorContains(t, err, "injected metadata replace failure") require.True(t, s.ddlVisibilityActivationFenced.Load()) require.False(t, s.ddlVisibilityActivationComplete.Load()) require.False(t, s.viewMetadataIngressReady.Load()) - require.Equal(t, -defines.MORPCVersion43, s.loadDDLVisibilityDeployedProtocol()) + require.Equal(t, -defines.MORPCVersion44, s.loadDDLVisibilityDeployedProtocol()) // A distinct process reloads the provisional marker through initMetadata and // must remain a v43, non-routable producer until activation is retried. @@ -750,7 +755,7 @@ func TestCommittedPersistenceFailureRestartsFromProvisionalFailClosed(t *testing require.NoError(t, restarted.publishDDLVisibilityIngressAfterStart()) version, ok := moruntime.ServiceRuntime(serviceID).GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.False(t, restarted.viewMetadataIngressReady.Load()) require.False(t, restarted.ddlCommitGate.PublicDDLEnabled()) } @@ -783,7 +788,7 @@ func TestActivationWithdrawalFailureStillBlocksNewDDL(t *testing.T) { s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion43, []string{serviceID}) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion44, []string{serviceID}) require.ErrorIs(t, err, withdrawErr) require.True(t, cluster.cnServices[0].ViewMetadataIngressReady, "the injected heartbeat failure leaves authoritative ingress unchanged") @@ -823,7 +828,7 @@ func TestActivationDrainTimeoutKeepsIngressWithdrawn(t *testing.T) { s.ddlVisibilityBarrierReady.Store(true) s.viewMetadataIngressReady.Store(true) - err = s.setProtocolVersion(context.Background(), defines.MORPCVersion43, []string{serviceID}) + err = s.setProtocolVersion(context.Background(), defines.MORPCVersion44, []string{serviceID}) require.Error(t, err) require.True(t, s.ddlVisibilityActivationPending.Load()) require.False(t, s.viewMetadataIngressReady.Load()) @@ -858,7 +863,7 @@ func TestDefaultV43StillRunsCompleteTargetActivation(t *testing.T) { "self:6001": {PhysicalTime: 100}, "peer:6001": targetTS, }, protocols: map[string]query.GetProtocolVersionResponse{"peer:6001": { - Version: defines.MORPCVersion43, + Version: defines.MORPCVersion44, DDLVisibilityActivationPrepared: true, DDLVisibilityActivationFenced: true, }}, } @@ -885,9 +890,9 @@ func TestDefaultV43StillRunsCompleteTargetActivation(t *testing.T) { require.False(t, s.ddlVisibilityActivationComplete.Load()) require.NoError(t, s.setProtocolVersion( - context.Background(), defines.MORPCVersion43, []string{serviceID, "legacy-peer"})) + context.Background(), defines.MORPCVersion44, []string{serviceID, "legacy-peer"})) require.True(t, s.ddlVisibilityActivationComplete.Load()) - require.Equal(t, defines.MORPCVersion43, s.loadDDLVisibilityDeployedProtocol()) + require.Equal(t, defines.MORPCVersion44, s.loadDDLVisibilityDeployedProtocol()) require.True(t, s.viewMetadataIngressReady.Load()) require.True(t, s.ddlCommitGate.PublicDDLEnabled()) require.Empty(t, queryClient.requests) @@ -926,7 +931,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { } ready := peerReady.Load() return query.GetProtocolVersionResponse{ - Version: defines.MORPCVersion43, + Version: defines.MORPCVersion44, DDLVisibilityActivationPrepared: ready, DDLVisibilityActivationFenced: ready, } @@ -940,7 +945,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { func(context.Context, timestamp.Timestamp) (timestamp.Timestamp, error) { version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version, + require.Equal(t, defines.MORPCVersion44, version, "sender capability must be v43 after every local v34 DDL producer is drained") require.True(t, cluster.cnServices[0].DDLVisibilityBarrierReady, "the transitioning CN must remain reachable by v43 DDL fan-out") @@ -969,7 +974,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { s.viewMetadataIngressReady.Store(true) req := &query.Request{SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion43, + Version: defines.MORPCVersion44, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", @@ -990,10 +995,10 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { releaseDDL, err := ddlCommitGate.Enter(context.Background()) require.NoError(t, err, "activation must release DDL producers after global convergence") releaseDDL() - require.Equal(t, defines.MORPCVersion43, resp.SetProtocolVersion.Version) + require.Equal(t, defines.MORPCVersion44, resp.SetProtocolVersion.Version) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.Empty(t, queryClient.requests) require.Empty(t, queryClient.methods) require.Zero(t, queryClient.releases) @@ -1012,7 +1017,7 @@ func TestHandleSetProtocolVersionFencesRunningCNActivation(t *testing.T) { // Repeating an already-active version must not withdraw or re-run the fence. resp = &query.Response{} require.NoError(t, s.handleSetProtocolVersion(context.Background(), req, resp, nil)) - require.Equal(t, defines.MORPCVersion43, resp.SetProtocolVersion.Version) + require.Equal(t, defines.MORPCVersion44, resp.SetProtocolVersion.Version) require.Len(t, hakeeperClient.heartbeats, 5) require.Equal(t, 2, cluster.refreshCalls) require.Empty(t, queryClient.requests) @@ -1054,12 +1059,12 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { resp := &query.Response{} require.NoError(t, s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion43, + Version: defines.MORPCVersion44, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", }, }, resp, nil)) - require.Equal(t, defines.MORPCVersion43, resp.SetProtocolVersion.Version) + require.Equal(t, defines.MORPCVersion44, resp.SetProtocolVersion.Version) require.False(t, s.viewMetadataIngressReady.Load()) require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) require.Len(t, hakeeperClient.heartbeats, 5) @@ -1094,7 +1099,7 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { <-allowPhase } return query.GetProtocolVersionResponse{ - Version: defines.MORPCVersion43, + Version: defines.MORPCVersion44, DDLVisibilityActivationPrepared: true, DDLVisibilityActivationFenced: true, } } @@ -1103,7 +1108,7 @@ func TestHandleSetProtocolVersionPreservesPreStartIngress(t *testing.T) { go func() { activationDone <- s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion43, + Version: defines.MORPCVersion44, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", }, @@ -1172,7 +1177,7 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T resp := &query.Response{} err := s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, + Version: defines.MORPCVersion44, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", }, }, resp, nil) @@ -1180,7 +1185,7 @@ func TestHandleSetProtocolVersionFailsClosedWhenActivationSyncFails(t *testing.T require.Nil(t, resp.SetProtocolVersion) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.True(t, s.ddlVisibilityActivationPending.Load()) require.True(t, s.ddlVisibilityActivationPrepared.Load()) require.False(t, s.ddlVisibilityActivationFenced.Load()) @@ -1246,14 +1251,14 @@ func TestHandleSetProtocolVersionWithdrawsAfterActivationPublishFails(t *testing err := s.handleSetProtocolVersion(context.Background(), &query.Request{ SetProtocolVersion: &query.SetProtocolVersionRequest{ - Version: defines.MORPCVersion43, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, + Version: defines.MORPCVersion44, DDLVisibilityActivationTargets: []string{serviceID, "peer"}, DDLVisibilityTargetGeneration: generation, DDLVisibilityTargetQueryAddress: "self:6001", }, }, &query.Response{}, nil) require.ErrorIs(t, err, publishErr) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.True(t, s.ddlVisibilityActivationPending.Load()) require.True(t, s.ddlVisibilityActivationFenced.Load()) blockedCtx, cancelBlocked := context.WithCancel(context.Background()) @@ -1279,10 +1284,10 @@ func TestSetProtocolVersionBeforeBarrierPreparationDefersToStartupFence(t *testi moruntime.SetupServiceBasedRuntime(serviceID, rt) s := &service{cfg: &Config{UUID: serviceID}} - require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion43, nil)) + require.NoError(t, s.setProtocolVersion(context.Background(), defines.MORPCVersion44, nil)) version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) require.False(t, s.ddlVisibilityBarrierPrepared.Load()) require.False(t, s.ddlVisibilityBarrierReady.Load()) } @@ -1324,7 +1329,7 @@ func TestInitQueryCommandHandlerOverridesProtocolActivation(t *testing.T) { require.True(t, ok) resp := &query.Response{} err := handler(context.Background(), &query.Request{ - SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion43}, + SetProtocolVersion: &query.SetProtocolVersionRequest{Version: defines.MORPCVersion44}, }, resp, nil) require.ErrorContains(t, err, "CN is closing") require.Nil(t, resp.SetProtocolVersion) @@ -1342,7 +1347,7 @@ func TestSetProtocolVersionRejectsActivationDuringClose(t *testing.T) { s.ddlVisibilityBarrierPrepared.Store(true) s.ddlVisibilityBarrierClosing.Store(true) - err := s.setProtocolVersion(context.Background(), defines.MORPCVersion43, nil) + err := s.setProtocolVersion(context.Background(), defines.MORPCVersion44, nil) require.ErrorContains(t, err, "CN is closing") version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) @@ -1381,7 +1386,7 @@ func TestValidateDDLVisibilityActivationTargets(t *testing.T) { func TestSetProtocolVersionDowngradeGuards(t *testing.T) { const serviceID = "ddl-visibility-downgrade-test" rt := moruntime.DefaultRuntime() - rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion43) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion44) moruntime.SetupServiceBasedRuntime(serviceID, rt) s := &service{cfg: &Config{UUID: serviceID}} s.ddlVisibilityBarrierPrepared.Store(true) @@ -1393,11 +1398,11 @@ func TestSetProtocolVersionDowngradeGuards(t *testing.T) { require.ErrorContains(t, err, "cannot downgrade after the DDL visibility cluster epoch is committed") version, ok := rt.GetGlobalVariables(moruntime.MOProtocolVersion) require.True(t, ok) - require.Equal(t, defines.MORPCVersion43, version) + require.Equal(t, defines.MORPCVersion44, version) s.ddlVisibilityActivationComplete.Store(false) s._hakeeperClient = &ddlVisibilityWithdrawalHAKeeperClient{ - clusterDeployedProtocol: defines.MORPCVersion43, + clusterDeployedProtocol: defines.MORPCVersion44, } rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion40) err = s.setProtocolVersion(context.Background(), defines.MORPCVersion34, nil) @@ -1647,6 +1652,42 @@ func TestAcknowledgedDDLFrontierSurvivesCrashBeforePeriodicHeartbeat(t *testing. require.NoError(t, target.syncStartupDDLVisibilityFrontier(context.Background())) } +func TestLegacyHAKeeperCannotAcknowledgeDroppedDDLFrontier(t *testing.T) { + const producerID = "legacy-hakeeper-ddl-producer" + oldFrontier := timestamp.Timestamp{PhysicalTime: 200} + commitFrontier := timestamp.Timestamp{PhysicalTime: 300} + cluster := &ddlVisibilityTestCluster{ + cnServices: []metadata.CNService{{ + ServiceID: producerID, QueryAddress: "producer:6001", + ViewMetadataAdmissionGeneration: 1, DDLVisibilityBarrierReady: true, + }}, + globalFrontier: oldFrontier, + } + client := &ddlVisibilityWithdrawalHAKeeperClient{ + cluster: cluster, oldDDLFrontierRSM: true, + } + producer := &service{ + cfg: &Config{UUID: producerID}, _hakeeperClient: client, + ddlCommitGate: frontend.NewDDLCommitGate(), config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: 1, logger: zap.NewNop(), + } + producer.ddlCommitGate.SetFrontierPublisher(producer.publishDDLCommitFrontier) + + err := producer.ddlCommitGate.PublishDDLFrontier(context.Background(), commitFrontier) + require.ErrorContains(t, err, "was not durably acknowledged") + require.Equal(t, oldFrontier, cluster.globalFrontier) + + ctrl := gomock.NewController(t) + restartedTxnClient := mock_frontend.NewMockTxnClient(ctrl) + restartedTxnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), oldFrontier).Return(oldFrontier, nil) + restartedTxnClient.EXPECT().SyncLatestCommitTS(oldFrontier) + restarted := &service{ + cfg: &Config{UUID: producerID}, _txnClient: restartedTxnClient, + _hakeeperClient: client, + } + require.NoError(t, restarted.syncStartupDDLVisibilityFrontier(context.Background())) +} + func TestStaleGenerationCannotAcknowledgeDDLFrontierPublication(t *testing.T) { const producerID = "generation-fenced-ddl-producer" oldFrontier := timestamp.Timestamp{PhysicalTime: 200} diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index c4fa06a2cdb1b..1bff76e96345e 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -187,16 +187,31 @@ func (s *service) notifyCommandPoll() { } } +// sendCNHeartbeat transfers schedule-command ownership to the existing dedupe +// owner before returning. Direct publication heartbeats must not discard a +// destructively delivered legacy CommandBatch. +func (s *service) sendCNHeartbeat( + ctx context.Context, + hb logservicepb.CNStoreHeartbeat, +) (logservicepb.CommandBatch, error) { + batch, err := s._hakeeperClient.SendCNHeartbeat(ctx, hb) + if err != nil { + return batch, err + } + s.handleHeartbeatResponse(hb.AckedCommandBatchID, batch) + return batch, nil +} + // publishDDLCommitFrontier durably advances HAKeeper's cluster frontier before // frontend acknowledges a public pre-cut DDL. It is serialized with periodic // heartbeat snapshots so an older captured heartbeat cannot follow this one. -func (s *service) publishDDLCommitFrontier(ctx context.Context, _ timestamp.Timestamp) error { +func (s *service) publishDDLCommitFrontier(ctx context.Context, ts timestamp.Timestamp) error { if s._hakeeperClient == nil { return moerr.NewInternalError(ctx, "HAKeeper client is unavailable while publishing DDL frontier") } s.ddlVisibilityHeartbeatMu.Lock() defer s.ddlVisibilityHeartbeatMu.Unlock() - batch, err := s._hakeeperClient.SendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) + batch, err := s.sendCNHeartbeat(ctx, s.newCNStoreHeartbeat()) if err != nil { return moerr.AttachCause(ctx, err) } @@ -213,6 +228,15 @@ func (s *service) publishDDLCommitFrontier(ctx context.Context, _ timestamp.Time "DDL frontier publication generation %d rejected by authoritative generation %d", s.viewMetadataAdmissionGeneration, admission.Generation) } + if batch.DDLVisibilityFrontier == nil || batch.DDLVisibilityFrontier.Less(ts) { + authoritative := "missing" + if batch.DDLVisibilityFrontier != nil { + authoritative = batch.DDLVisibilityFrontier.DebugString() + } + return moerr.NewInvalidStateNoCtxf( + "DDL frontier publication %s was not durably acknowledged (authoritative frontier %s)", + ts.DebugString(), authoritative) + } return nil } @@ -248,7 +272,7 @@ func (s *service) newCNStoreHeartbeat() logservicepb.CNStoreHeartbeat { if s.ddlCommitGate != nil { hb.DDLVisibilityFrontier = s.ddlCommitGate.LatestDDLFrontier() } - if deployed := s.loadDDLVisibilityDeployedProtocol(); deployed >= defines.MORPCVersion43 { + if deployed := s.loadDDLVisibilityDeployedProtocol(); deployed >= defines.MORPCVersion44 { hb.DDLVisibilityDeployedProtocol = deployed } if s.viewMetadataEpochFence != nil { @@ -277,7 +301,7 @@ func (s *service) withdrawViewMetadataAdmission() error { context.Background(), timeout, moerr.CauseHeartbeat) defer cancel() hb := s.newCNStoreHeartbeat() - _, err := s._hakeeperClient.SendCNHeartbeat(ctx, hb) + _, err := s.sendCNHeartbeat(ctx, hb) if err != nil { return moerr.AttachCause(ctx, err) } diff --git a/pkg/cnservice/server_heartbeat_test.go b/pkg/cnservice/server_heartbeat_test.go index 733d3f5e54acb..639aaa2563df9 100644 --- a/pkg/cnservice/server_heartbeat_test.go +++ b/pkg/cnservice/server_heartbeat_test.go @@ -207,6 +207,26 @@ func (c *blockingCNHeartbeatCommandClient) GetScheduleCommands( return c.commandBatch, nil } +func TestDirectCNHeartbeatProcessesLegacyScheduleCommand(t *testing.T) { + holder := &observingTaskHolder{createErr: errors.New("stop after observing command"), created: make(chan struct{}, 1)} + client := &admissionFailureCNHeartbeatClient{ + testHAKClient: &testHAKClient{}, + batch: pb.CommandBatch{Commands: []pb.ScheduleCommand{{ + ServiceType: pb.CNService, + CreateTaskService: &pb.CreateTaskService{}, + }}}, + } + s := &service{ + cfg: &Config{UUID: "direct-heartbeat-command-owner"}, config: util.NewConfigData(nil), + logger: zap.NewNop(), _hakeeperClient: client, + } + s.task.holder = holder + + _, err := s.sendCNHeartbeat(context.Background(), s.newCNStoreHeartbeat()) + require.NoError(t, err) + require.Equal(t, int32(1), holder.createCount.Load()) +} + func Test_heartbeat(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/pkg/cnservice/server_query.go b/pkg/cnservice/server_query.go index a4514a8b1b625..98e0359d31c2c 100644 --- a/pkg/cnservice/server_query.go +++ b/pkg/cnservice/server_query.go @@ -245,7 +245,7 @@ func (s *service) handleSetProtocolVersion( return moerr.NewInternalError(ctx, "bad request") } version := req.SetProtocolVersion.Version - if version >= defines.MORPCVersion43 && + if version >= defines.MORPCVersion44 && len(req.SetProtocolVersion.DDLVisibilityActivationTargets) > 0 { expectedGeneration := req.SetProtocolVersion.DDLVisibilityTargetGeneration expectedAddress := req.SetProtocolVersion.DDLVisibilityTargetQueryAddress diff --git a/pkg/defines/const.go b/pkg/defines/const.go index b5b8eca3d0787..1e84f1caacbf2 100644 --- a/pkg/defines/const.go +++ b/pkg/defines/const.go @@ -78,8 +78,9 @@ const ( MORPCVersion40 int64 = 40 // PAD SPACE comparison casts and set-operation equality keys MORPCVersion41 int64 = 41 // cycle-safe bounded current-role closure table function MORPCVersion42 int64 = 42 // transactional SQL-task child cleanup - MORPCVersion43 int64 = 43 // cancellable cross-CN DDL visibility fence - MORPCLatestVersion = MORPCVersion43 + MORPCVersion43 int64 = 43 // validated MongoDB explicit-query payload (reserved by #27553) + MORPCVersion44 int64 = 44 // cancellable cross-CN DDL visibility fence + MORPCLatestVersion = MORPCVersion44 ) // DefaultLockWaitTimeoutSeconds is shared by the frontend default and by diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index 7195a1ea2b318..ce880093815f6 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -1085,7 +1085,7 @@ type ddlVisibilityTarget struct { // DDL sender refreshes membership again after fan-out and repeats if any ready // generation changed. A failed target is retried only after authoritative // revalidation proves that exact generation/address tuple has departed. -// Protocol v43 is a deployment gate: mixed-version +// Protocol v44 is a deployment gate: mixed-version // clusters retain legacy behavior without invoking an old receiver's fatal // SyncCommit path. func syncDDLCommitToBarrierReadyCNs( @@ -1101,7 +1101,7 @@ func syncDDLCommitToBarrierReadyCNs( qc := pu.QueryClient protocol, ok := moruntime.ServiceRuntime(qc.ServiceID()).GetGlobalVariables(moruntime.MOProtocolVersion) protocolVersion, valid := protocol.(int64) - if !ok || !valid || protocolVersion < defines.MORPCVersion43 { + if !ok || !valid || protocolVersion < defines.MORPCVersion44 { return nil } cluster := clusterservice.GetMOCluster(qc.ServiceID()) diff --git a/pkg/hakeeper/view_metadata_admission.go b/pkg/hakeeper/view_metadata_admission.go index c1e31a7474d7d..75770a0141417 100644 --- a/pkg/hakeeper/view_metadata_admission.go +++ b/pkg/hakeeper/view_metadata_admission.go @@ -607,6 +607,8 @@ func (s *stateMachine) attachViewMetadataAdmission( batch.ViewMetadataAdmission = s.viewMetadataAdmissionSnapshot(uuid, proxy) if !proxy { batch.DDLVisibilityDeployedProtocol = s.state.CNState.DDLVisibilityDeployedProtocol + frontier := s.state.CNState.DDLVisibilityFrontier + batch.DDLVisibilityFrontier = &frontier } data, err := batch.Marshal() if err != nil { diff --git a/pkg/pb/logservice/logservice.pb.go b/pkg/pb/logservice/logservice.pb.go index e62a8ad2c2072..77834f03282c8 100644 --- a/pkg/pb/logservice/logservice.pb.go +++ b/pkg/pb/logservice/logservice.pb.go @@ -3958,10 +3958,13 @@ type CommandBatch struct { ViewMetadataAdmission *ViewMetadataAdmission `protobuf:"bytes,5,opt,name=ViewMetadataAdmission,proto3" json:"ViewMetadataAdmission,omitempty"` // DDLVisibilityDeployedProtocol is returned from the same replicated // heartbeat transition that conditionally publishes CN ingress. - DDLVisibilityDeployedProtocol int64 `protobuf:"varint,6,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + DDLVisibilityDeployedProtocol int64 `protobuf:"varint,6,opt,name=DDLVisibilityDeployedProtocol,proto3" json:"DDLVisibilityDeployedProtocol,omitempty"` + // DDLVisibilityFrontier is the durable cluster maximum after applying this + // heartbeat transition. New CNs require it as publication acknowledgement. + DDLVisibilityFrontier *timestamp.Timestamp `protobuf:"bytes,7,opt,name=DDLVisibilityFrontier,proto3" json:"DDLVisibilityFrontier,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *CommandBatch) Reset() { *m = CommandBatch{} } @@ -4039,6 +4042,13 @@ func (m *CommandBatch) GetDDLVisibilityDeployedProtocol() int64 { return 0 } +func (m *CommandBatch) GetDDLVisibilityFrontier() *timestamp.Timestamp { + if m != nil { + return m.DDLVisibilityFrontier + } + return nil +} + // ViewMetadataAdmission is the durable cluster admission snapshot. Generation // and Ready describe the heartbeat sender when returned in CommandBatch; they // are zero/false in the global ClusterDetails copy. @@ -6780,398 +6790,399 @@ func init() { func init() { proto.RegisterFile("logservice.proto", fileDescriptor_fd1040c5381ab5a7) } var fileDescriptor_fd1040c5381ab5a7 = []byte{ - // 6249 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3d, 0x4b, 0x6f, 0x1c, 0xc9, - 0x79, 0xea, 0xe1, 0x90, 0x1c, 0x7e, 0x43, 0x52, 0xcd, 0xe2, 0x43, 0x23, 0x4a, 0xa2, 0xb8, 0xb3, - 0xf2, 0xae, 0x96, 0x5e, 0x53, 0x8e, 0xe4, 0x5d, 0xac, 0x1d, 0x59, 0xbb, 0xc3, 0x99, 0x91, 0x38, - 0xd2, 0x68, 0xc8, 0xed, 0x69, 0x6a, 0x6d, 0x03, 0x0b, 0xa2, 0x39, 0x53, 0xa2, 0xda, 0x1c, 0x4e, - 0x8f, 0xbb, 0x9b, 0x7a, 0x24, 0xa7, 0x04, 0x71, 0x10, 0xc4, 0x48, 0x10, 0x03, 0x41, 0x62, 0x24, - 0x71, 0x5e, 0xb7, 0x9c, 0x7c, 0xf1, 0x3f, 0x08, 0x10, 0xf8, 0x14, 0x18, 0x06, 0x72, 0xc9, 0xc1, - 0xaf, 0x5c, 0x02, 0xf8, 0x92, 0x53, 0x9c, 0x8b, 0x81, 0xa0, 0x5e, 0xdd, 0x55, 0xfd, 0x98, 0x9e, - 0x21, 0x69, 0xc7, 0x0e, 0xf6, 0xc4, 0xe9, 0xaf, 0xbe, 0xaf, 0xaa, 0xba, 0xea, 0x7b, 0xd7, 0x57, - 0x4d, 0xd0, 0x7b, 0xce, 0xa1, 0x87, 0xdd, 0xe7, 0x76, 0x07, 0x6f, 0x0e, 0x5c, 0xc7, 0x77, 0x10, - 0x84, 0x90, 0xd5, 0xcf, 0x1c, 0xda, 0xfe, 0xb3, 0x93, 0x83, 0xcd, 0x8e, 0x73, 0x7c, 0xeb, 0xd0, - 0x39, 0x74, 0x6e, 0x51, 0x94, 0x83, 0x93, 0xa7, 0xf4, 0x89, 0x3e, 0xd0, 0x5f, 0x8c, 0x74, 0xf5, - 0xfa, 0xa1, 0xe3, 0x1c, 0xf6, 0x70, 0x88, 0xe5, 0xdb, 0xc7, 0xd8, 0xf3, 0xad, 0xe3, 0x01, 0x47, - 0x98, 0x3f, 0xc6, 0xbe, 0xd5, 0xb5, 0x7c, 0x8b, 0x3f, 0x5f, 0x8c, 0x20, 0x94, 0xff, 0x0b, 0x60, - 0xba, 0xda, 0x6a, 0xfb, 0x8e, 0x8b, 0x11, 0x82, 0xfc, 0xde, 0x5e, 0xa3, 0x56, 0xd2, 0xd6, 0xb5, - 0x9b, 0x33, 0x06, 0xfd, 0x8d, 0xde, 0x80, 0xf9, 0x36, 0x9b, 0x5b, 0xa5, 0xdb, 0x75, 0xb1, 0xe7, - 0x95, 0x72, 0xb4, 0x35, 0x02, 0x45, 0x6b, 0x00, 0xed, 0x0f, 0x9b, 0x02, 0x67, 0x82, 0xe2, 0x48, - 0x10, 0xb4, 0x09, 0xa8, 0xe9, 0x74, 0x8e, 0x22, 0x7d, 0xe5, 0x29, 0x5e, 0x42, 0x0b, 0xba, 0x01, - 0x79, 0xc3, 0xe9, 0xe1, 0xd2, 0xd4, 0xba, 0x76, 0x73, 0xfe, 0xb6, 0xbe, 0x19, 0xbc, 0x47, 0xb5, - 0x45, 0xe0, 0x06, 0x6d, 0x25, 0x33, 0x36, 0xed, 0xce, 0x51, 0x69, 0x7a, 0x5d, 0xbb, 0x99, 0x37, - 0xe8, 0x6f, 0xf4, 0x69, 0x98, 0x6c, 0xfb, 0x96, 0x8f, 0x4b, 0x05, 0x4a, 0xba, 0xbc, 0x29, 0x2d, - 0x78, 0xcb, 0xe9, 0x62, 0xda, 0x68, 0x30, 0x1c, 0xf4, 0x45, 0x98, 0x6a, 0x5a, 0x07, 0xb8, 0xe7, - 0x95, 0x66, 0xd6, 0x27, 0x6e, 0x16, 0x6f, 0x5f, 0x97, 0xb1, 0xf9, 0xba, 0x6c, 0x32, 0x8c, 0x7a, - 0xdf, 0x77, 0x5f, 0x6d, 0xe5, 0xbf, 0xf7, 0xc3, 0xeb, 0x17, 0x0c, 0x4e, 0x84, 0x7e, 0x0b, 0x66, - 0x3e, 0x72, 0xdc, 0x23, 0x36, 0x1e, 0xd0, 0xf1, 0x16, 0xc3, 0xa9, 0x06, 0x4d, 0x46, 0x88, 0x85, - 0xca, 0x30, 0xfb, 0xe1, 0x09, 0x76, 0x5f, 0x89, 0x25, 0x28, 0xd2, 0x25, 0x50, 0x60, 0xe8, 0x5d, - 0x80, 0xaa, 0xd3, 0x7f, 0x6a, 0x1f, 0xd6, 0x2c, 0xdf, 0x2a, 0xcd, 0xae, 0x6b, 0x37, 0x8b, 0xb7, - 0x57, 0x94, 0x99, 0x05, 0xad, 0x86, 0x84, 0x89, 0xde, 0x85, 0x82, 0x81, 0x3d, 0xe7, 0xc4, 0xed, - 0xe0, 0xd2, 0x1c, 0xa5, 0x5a, 0x92, 0xa9, 0x44, 0x1b, 0x7f, 0x89, 0x00, 0x17, 0xad, 0xc0, 0xd4, - 0xde, 0xc0, 0xb4, 0x8f, 0x71, 0x69, 0x7e, 0x5d, 0xbb, 0x39, 0x61, 0xf0, 0x27, 0xf4, 0x59, 0x58, - 0x6c, 0x3f, 0xb3, 0xdc, 0x6e, 0x64, 0xd7, 0x2e, 0xd2, 0x29, 0x27, 0x35, 0xa1, 0x55, 0x28, 0x54, - 0x9d, 0xe3, 0x63, 0xdb, 0x6f, 0xd4, 0x4a, 0x3a, 0x45, 0x0b, 0x9e, 0xd1, 0x7d, 0x58, 0x7b, 0x62, - 0xe3, 0x17, 0x8f, 0xf9, 0xf2, 0x54, 0xba, 0xc7, 0xb6, 0xe7, 0xd9, 0x4e, 0xbf, 0x7d, 0x32, 0x18, - 0x38, 0xae, 0x8f, 0xbb, 0xa5, 0x85, 0x75, 0xed, 0x66, 0xc1, 0xc8, 0xc0, 0x42, 0xdb, 0x70, 0x3d, - 0x11, 0xe3, 0x01, 0xee, 0x63, 0xd7, 0xf2, 0x6d, 0xa7, 0x5f, 0x42, 0x94, 0x1f, 0xb2, 0xd0, 0xd0, - 0x5d, 0xb8, 0x2c, 0xa3, 0xec, 0x1c, 0x90, 0x95, 0xc2, 0xdd, 0xfa, 0xc0, 0xe9, 0x3c, 0x2b, 0x2d, - 0xd2, 0x3e, 0xd2, 0x11, 0xd0, 0x3d, 0x58, 0x4d, 0x1c, 0xc0, 0xc0, 0x56, 0xf7, 0x55, 0x69, 0x89, - 0xbe, 0xcb, 0x10, 0x0c, 0x32, 0x7a, 0xad, 0xd6, 0x7c, 0x62, 0x7b, 0xf6, 0x81, 0xdd, 0xb3, 0xfd, - 0x57, 0x5b, 0x96, 0xeb, 0xda, 0xd8, 0x65, 0xe4, 0xcb, 0x94, 0x3c, 0x1d, 0x01, 0x7d, 0x01, 0x4a, - 0x72, 0xdf, 0x8d, 0xfe, 0x21, 0xd9, 0x00, 0x46, 0xbc, 0x42, 0x89, 0x53, 0xdb, 0x51, 0x0d, 0xae, - 0x29, 0x1d, 0xd7, 0xf0, 0xa0, 0xe7, 0xbc, 0xc2, 0xdd, 0x5d, 0xa2, 0x12, 0x3a, 0x4e, 0xaf, 0x74, - 0x89, 0xb2, 0xc1, 0x70, 0x24, 0xb2, 0x0f, 0x0a, 0x42, 0xa5, 0xe3, 0xdb, 0xcf, 0xe9, 0xc2, 0xee, - 0xba, 0x78, 0x60, 0xb9, 0xb8, 0x5b, 0x2a, 0xd1, 0x89, 0x64, 0xa1, 0xc5, 0xe6, 0x13, 0xa2, 0xdc, - 0xc7, 0xfd, 0x0e, 0xee, 0x96, 0x2e, 0xd3, 0x7e, 0x86, 0x23, 0xa1, 0x5d, 0x58, 0x56, 0x10, 0xee, - 0xbb, 0x4e, 0xdf, 0xb7, 0xb1, 0x5b, 0x5a, 0xe5, 0xa2, 0x10, 0xea, 0x3e, 0x53, 0xfc, 0xe2, 0xa2, - 0x90, 0x4c, 0xb8, 0xda, 0x82, 0xa2, 0x24, 0xfb, 0x48, 0x87, 0x89, 0x23, 0xfc, 0x8a, 0xab, 0x47, - 0xf2, 0x13, 0xbd, 0x05, 0x93, 0xcf, 0xad, 0xde, 0x09, 0xa6, 0x4a, 0xb1, 0x28, 0xcb, 0x3e, 0xa5, - 0x6b, 0xda, 0x9e, 0x6f, 0x30, 0x8c, 0x2f, 0xe4, 0xde, 0xd3, 0x1e, 0xe6, 0x0b, 0x93, 0xfa, 0x54, - 0xf9, 0xe7, 0x13, 0x30, 0x6d, 0x9e, 0x83, 0xca, 0x15, 0xca, 0x6f, 0x22, 0x49, 0xf9, 0xe5, 0x47, - 0x50, 0x7e, 0xef, 0xc0, 0x14, 0x95, 0x61, 0xaf, 0x34, 0x49, 0x95, 0xdf, 0x25, 0x19, 0xdb, 0x6c, - 0xd1, 0xb6, 0x46, 0xff, 0xa9, 0x23, 0x94, 0x1e, 0x43, 0x46, 0xb7, 0x61, 0xa9, 0xe9, 0x1c, 0xfa, - 0x96, 0xdd, 0x23, 0x13, 0xc2, 0xae, 0x98, 0xe5, 0x14, 0x9d, 0x65, 0x62, 0x5b, 0x8a, 0xfa, 0x9f, - 0x4e, 0x55, 0xff, 0xaa, 0x06, 0x9c, 0x19, 0x59, 0x03, 0x46, 0xb5, 0x2b, 0x24, 0x68, 0xd7, 0x14, - 0xad, 0x56, 0x4c, 0xd7, 0x6a, 0x1f, 0xc0, 0x95, 0xca, 0x89, 0xef, 0x34, 0xfa, 0x1d, 0x97, 0x8a, - 0x3e, 0x65, 0xb8, 0x50, 0x6d, 0xcd, 0x52, 0xee, 0x1c, 0x86, 0xf2, 0x30, 0x5f, 0x28, 0xe8, 0x33, - 0xe5, 0x3f, 0x99, 0x80, 0x42, 0xd3, 0x39, 0xfc, 0x35, 0xd8, 0xfa, 0xbb, 0xc4, 0x52, 0x0c, 0x7a, - 0x76, 0xc7, 0x12, 0x9b, 0xbf, 0x2a, 0xe3, 0x37, 0x9d, 0x43, 0xde, 0x2c, 0xed, 0x7f, 0x40, 0x11, - 0xd9, 0x9d, 0xa9, 0x71, 0xec, 0x53, 0xd3, 0xe9, 0x58, 0x44, 0xc6, 0xe8, 0xde, 0x47, 0xec, 0x93, - 0x68, 0x13, 0xe3, 0x89, 0x67, 0xf4, 0x04, 0xde, 0x18, 0xaa, 0x8a, 0xc2, 0xad, 0x28, 0xd0, 0xad, - 0x18, 0x11, 0xbb, 0xfc, 0x6f, 0x79, 0x98, 0x25, 0xfb, 0x21, 0x18, 0x1d, 0x95, 0x60, 0x9a, 0x3d, - 0xb0, 0x6d, 0xc9, 0x1b, 0xe2, 0x11, 0x6d, 0x49, 0x0b, 0x96, 0xa3, 0x0b, 0xf6, 0x46, 0x64, 0xc1, - 0x82, 0x5e, 0x36, 0x05, 0x22, 0xd5, 0x1a, 0xd2, 0xb2, 0x2d, 0xc1, 0x24, 0x33, 0x2d, 0x6c, 0xdb, - 0xd8, 0x03, 0x31, 0x99, 0x4d, 0x6c, 0x75, 0xb1, 0xdb, 0xa8, 0xd1, 0xad, 0xcb, 0x1b, 0xc1, 0x33, - 0xdd, 0x67, 0xec, 0x1e, 0x97, 0x26, 0xf9, 0x3e, 0x63, 0xf7, 0x18, 0x7d, 0x0c, 0x0b, 0x2d, 0xa7, - 0xff, 0xc4, 0xf1, 0xed, 0xfe, 0x61, 0x30, 0xa5, 0x29, 0x3a, 0xa5, 0x5b, 0xa9, 0x53, 0x8a, 0x51, - 0xb0, 0xb9, 0xc5, 0x7b, 0x42, 0x2e, 0x94, 0xf8, 0x6f, 0xca, 0xa6, 0x8d, 0x7e, 0xc7, 0x72, 0xfb, - 0x54, 0xcd, 0x12, 0x79, 0x25, 0xa3, 0xbc, 0x9b, 0xf5, 0xe2, 0x31, 0x42, 0x36, 0x58, 0x6a, 0xbf, - 0xab, 0xbf, 0x0d, 0x73, 0xca, 0xbc, 0x64, 0x4d, 0x9b, 0x67, 0x9a, 0x76, 0x49, 0xd6, 0xb4, 0x33, - 0x92, 0x52, 0x5d, 0xad, 0xc1, 0x4a, 0xf2, 0xdb, 0x8d, 0xd5, 0xcb, 0x23, 0xb8, 0x36, 0x74, 0xf6, - 0xe3, 0x74, 0x56, 0xfe, 0x96, 0x06, 0xf3, 0xaa, 0x08, 0xa1, 0xfb, 0x2a, 0xa7, 0xd1, 0x7e, 0x8a, - 0xb7, 0x4b, 0x69, 0x4b, 0xb9, 0x55, 0x20, 0x22, 0xf0, 0xfd, 0x1f, 0x5e, 0xd7, 0x0c, 0x95, 0x43, - 0xaf, 0xc2, 0x8c, 0xe8, 0xb6, 0x46, 0x07, 0xce, 0x1b, 0x21, 0x00, 0xad, 0x43, 0xb1, 0xe1, 0x05, - 0xab, 0x41, 0xf9, 0xac, 0x60, 0xc8, 0xa0, 0xf2, 0x1f, 0x6b, 0xa1, 0x8f, 0x48, 0xbd, 0xb5, 0xdd, - 0x3d, 0xd3, 0xf1, 0xad, 0x1e, 0x7f, 0xb1, 0xe0, 0x99, 0x68, 0xd2, 0xea, 0xee, 0x5e, 0xe5, 0xb9, - 0x65, 0xf7, 0xac, 0x83, 0x1e, 0x7b, 0x49, 0xcd, 0x50, 0x60, 0x84, 0xfe, 0x31, 0x3e, 0x66, 0xf4, - 0x8c, 0xa7, 0x83, 0x67, 0x42, 0xff, 0x18, 0x1f, 0x87, 0xf4, 0x8c, 0xb5, 0x15, 0x58, 0xf9, 0xf7, - 0xb4, 0x54, 0xc3, 0x6f, 0x5a, 0xee, 0x21, 0xf6, 0xc9, 0xeb, 0x72, 0xd5, 0x17, 0x68, 0xca, 0x10, - 0x40, 0x82, 0x0e, 0xc9, 0xe9, 0x63, 0xab, 0x21, 0x41, 0x62, 0xd6, 0x60, 0x22, 0x6e, 0x0d, 0xca, - 0xbf, 0x98, 0x05, 0x9d, 0x3b, 0xfa, 0xdb, 0xd8, 0x72, 0xfd, 0x03, 0x6c, 0xf9, 0xbf, 0x81, 0x91, - 0xd0, 0x26, 0x20, 0xd3, 0xf2, 0x04, 0x6d, 0xd5, 0xc5, 0x16, 0x51, 0x87, 0xd3, 0x94, 0x01, 0x12, - 0x5a, 0x62, 0x4b, 0x53, 0x48, 0x30, 0x94, 0x37, 0x60, 0xae, 0xd1, 0xb7, 0xfd, 0x30, 0xc2, 0x99, - 0xa1, 0x48, 0x2a, 0x90, 0x60, 0x3d, 0x70, 0x3c, 0xcf, 0x1e, 0xa8, 0x36, 0x57, 0x05, 0x92, 0xf1, - 0x18, 0xe0, 0xa1, 0x63, 0xf7, 0x71, 0x97, 0x5a, 0xdb, 0x82, 0xa1, 0xc0, 0x7e, 0xe5, 0x61, 0x4f, - 0x8a, 0x23, 0x30, 0x3f, 0x5a, 0x78, 0x73, 0x31, 0x12, 0xde, 0x7c, 0x16, 0x16, 0x2b, 0x9d, 0x23, - 0xdc, 0x25, 0x00, 0xab, 0xdf, 0xdd, 0xb2, 0xfc, 0xce, 0x33, 0x1e, 0x05, 0xe5, 0x8d, 0xa4, 0x26, - 0xe2, 0x56, 0x70, 0x48, 0x0d, 0xf7, 0xec, 0xe7, 0x64, 0xe5, 0x3b, 0x47, 0xd1, 0x68, 0x68, 0x18, - 0xca, 0x08, 0x21, 0x15, 0x3a, 0xaf, 0x90, 0x6a, 0xf1, 0x1c, 0x42, 0xaa, 0xa5, 0xac, 0x90, 0x2a, - 0xf2, 0x3e, 0x55, 0xcb, 0xb7, 0x7a, 0xce, 0x21, 0xf3, 0xef, 0x59, 0x17, 0xcb, 0xb4, 0x8b, 0x0c, - 0x2c, 0xb4, 0x05, 0x57, 0x65, 0x0c, 0x03, 0x3f, 0x75, 0xb1, 0xf7, 0x2c, 0x5c, 0x15, 0x16, 0x20, - 0x0d, 0xc5, 0x89, 0xf7, 0xf1, 0xdc, 0xea, 0xd9, 0x5d, 0x22, 0x3c, 0x6c, 0x26, 0x97, 0xe8, 0x4c, - 0x86, 0xe2, 0x0c, 0x0d, 0xd2, 0x4a, 0x19, 0x41, 0xda, 0xd0, 0xf0, 0xf0, 0x72, 0x56, 0x78, 0x98, - 0x19, 0xe2, 0xad, 0x8e, 0x12, 0xe2, 0xbd, 0x8a, 0x84, 0x78, 0xf4, 0xad, 0x18, 0xc7, 0x33, 0x05, - 0xed, 0x95, 0xae, 0x50, 0x9f, 0xe0, 0x2d, 0x59, 0xe0, 0x86, 0xaa, 0x74, 0x2e, 0x85, 0x59, 0xfd, - 0x8e, 0x12, 0x5d, 0x5e, 0x3d, 0xa7, 0xe8, 0xf2, 0xda, 0x99, 0xa2, 0xcb, 0xb5, 0x53, 0x46, 0x97, - 0x3c, 0x1a, 0x34, 0x61, 0xb6, 0xda, 0xaa, 0xf4, 0x7a, 0x4e, 0xc7, 0xf2, 0x89, 0x4d, 0x8b, 0x07, - 0x99, 0x4b, 0x30, 0x49, 0x35, 0x06, 0x37, 0x70, 0xec, 0x81, 0x39, 0x02, 0x5f, 0x3b, 0xc1, 0x1e, - 0xd1, 0x45, 0xcc, 0xca, 0x84, 0x80, 0xf2, 0x2f, 0xf2, 0xb0, 0x20, 0x22, 0x8d, 0xe1, 0x66, 0x6d, - 0x1d, 0x8a, 0x86, 0xf5, 0xd4, 0x57, 0x6d, 0x9a, 0x0c, 0x4a, 0x30, 0x7c, 0x13, 0x89, 0x86, 0x2f, - 0x66, 0x08, 0xf2, 0x49, 0x86, 0xe0, 0x6c, 0x91, 0x47, 0xb2, 0x99, 0x9b, 0x4a, 0x35, 0x73, 0xaa, - 0x49, 0x99, 0x3e, 0x55, 0xa4, 0x52, 0x18, 0x23, 0x52, 0xf9, 0x02, 0x94, 0x22, 0xfa, 0x3a, 0x54, - 0x3a, 0x33, 0x4c, 0xe0, 0xd3, 0xda, 0x47, 0x50, 0xe6, 0x30, 0x92, 0x32, 0xdf, 0x00, 0x3d, 0xea, - 0xc3, 0xf2, 0xe0, 0x36, 0x06, 0x1f, 0x23, 0xb2, 0x9a, 0x1d, 0x2b, 0xb2, 0xaa, 0x43, 0x51, 0x4a, - 0x20, 0x0c, 0x89, 0xab, 0x86, 0xfa, 0xb3, 0xe5, 0xaf, 0x4f, 0x82, 0x6e, 0x9e, 0xa7, 0x73, 0x16, - 0xa6, 0x3c, 0x26, 0xc6, 0x49, 0x79, 0x24, 0xb3, 0x5d, 0x3e, 0x95, 0xed, 0xd2, 0x52, 0x24, 0x93, - 0x63, 0xa7, 0x48, 0xa6, 0x46, 0x4c, 0x91, 0x14, 0x4e, 0x9d, 0x22, 0x99, 0x19, 0x3d, 0x45, 0x02, - 0xe9, 0x9e, 0x11, 0x51, 0x23, 0x78, 0xd0, 0xb3, 0x5e, 0xe1, 0x6e, 0xd3, 0x63, 0xfc, 0x96, 0x37, - 0x64, 0xd0, 0xd9, 0x93, 0x28, 0x69, 0x1e, 0xd6, 0xdc, 0xa9, 0x3d, 0xac, 0xf9, 0x4c, 0x0f, 0xeb, - 0x61, 0xbe, 0x30, 0xad, 0x17, 0xca, 0xdf, 0x99, 0x84, 0x82, 0xd1, 0x7e, 0xcc, 0x1c, 0x5e, 0x1d, - 0x26, 0x4c, 0xcf, 0x11, 0x91, 0xa0, 0xe9, 0x39, 0x44, 0x43, 0x37, 0xfa, 0x5d, 0xfc, 0x52, 0x68, - 0x68, 0xfa, 0x40, 0xf4, 0x61, 0x13, 0x5b, 0x1e, 0xde, 0x76, 0x7a, 0x2c, 0xba, 0x67, 0x21, 0x92, - 0x0a, 0x24, 0xdb, 0x61, 0xba, 0x27, 0x7d, 0xa2, 0xfd, 0xe9, 0xca, 0xf1, 0x38, 0x49, 0x86, 0xa1, - 0x87, 0x30, 0xcb, 0x88, 0x6c, 0xcf, 0x77, 0xdc, 0x57, 0x5c, 0x6f, 0x2a, 0x09, 0x08, 0x31, 0xbb, - 0x4d, 0x19, 0x91, 0xc5, 0xdd, 0x0a, 0x2d, 0xdb, 0xa8, 0xaf, 0x9d, 0xd8, 0x2e, 0x1b, 0x6e, 0x4a, - 0x6c, 0x54, 0x00, 0x42, 0x6f, 0xc3, 0xc2, 0x47, 0x95, 0xa6, 0x81, 0x3b, 0x0e, 0x59, 0x8d, 0x9a, - 0x7d, 0x88, 0x3d, 0x9f, 0xa7, 0xea, 0xe2, 0x0d, 0xe8, 0x73, 0xb0, 0x2c, 0x01, 0xe9, 0x88, 0x55, - 0xe7, 0xa4, 0xef, 0x53, 0x8e, 0xcc, 0x1b, 0xc9, 0x8d, 0x64, 0x63, 0xa4, 0x86, 0xaa, 0x73, 0x3c, - 0xe8, 0x61, 0xe2, 0x35, 0xf5, 0x7d, 0xd7, 0xc6, 0x8c, 0x27, 0xf3, 0xc6, 0x30, 0x14, 0x22, 0x2e, - 0x52, 0xf3, 0x96, 0xe5, 0x61, 0xf2, 0x3a, 0x40, 0x09, 0x13, 0x5a, 0x22, 0xf8, 0x4d, 0xcb, 0xf3, - 0x43, 0x3e, 0x4d, 0x68, 0x41, 0x0f, 0x61, 0x5d, 0x82, 0xee, 0xb8, 0xf6, 0xa1, 0xdd, 0xb7, 0x7a, - 0xea, 0x86, 0xce, 0x52, 0xea, 0x4c, 0x3c, 0xc2, 0xb8, 0x09, 0xaf, 0x42, 0x19, 0xb7, 0x60, 0x24, - 0x35, 0xad, 0xbe, 0x0f, 0x0b, 0xb1, 0x8d, 0xcc, 0x4a, 0x41, 0xe4, 0xe5, 0x14, 0xc4, 0xc7, 0x30, - 0x43, 0x4d, 0x69, 0xc7, 0x71, 0xbb, 0x84, 0x90, 0xbc, 0x2c, 0x27, 0x24, 0x6f, 0xb7, 0x01, 0x79, - 0xf3, 0xd5, 0x80, 0xd1, 0xcd, 0xab, 0x6a, 0x83, 0xd1, 0x90, 0x56, 0x83, 0xe2, 0x10, 0x7d, 0x4b, - 0x55, 0x0c, 0x61, 0xdf, 0x59, 0x83, 0xfe, 0x2e, 0xff, 0x38, 0x07, 0x40, 0xfb, 0xa7, 0x0e, 0x07, - 0x41, 0x69, 0x59, 0xc7, 0x58, 0xa8, 0x64, 0xf2, 0x5b, 0xd6, 0xf9, 0x39, 0x55, 0xe7, 0xf3, 0xe9, - 0x4c, 0x84, 0xd3, 0x29, 0xc1, 0xf4, 0x63, 0xeb, 0x65, 0xdb, 0xfe, 0x1d, 0x91, 0x27, 0x10, 0x8f, - 0xc4, 0x3e, 0x08, 0xb5, 0x5c, 0xe3, 0x69, 0xb0, 0x10, 0x40, 0xf3, 0x63, 0xad, 0x46, 0x8d, 0x73, - 0x31, 0xfd, 0x8d, 0x3e, 0x07, 0x39, 0xb3, 0xcd, 0x4d, 0xfd, 0xea, 0x26, 0x3b, 0x20, 0xdd, 0x14, - 0x07, 0xa4, 0x92, 0x6f, 0x46, 0x33, 0x2c, 0x7f, 0xf6, 0xa3, 0xeb, 0x9a, 0x91, 0x33, 0xdb, 0xc4, - 0xf8, 0x36, 0xfa, 0x9d, 0xde, 0x49, 0x17, 0xd7, 0x5f, 0x0e, 0x88, 0x24, 0x70, 0x23, 0xc4, 0xf5, - 0x1b, 0xf6, 0x78, 0x6a, 0x31, 0x03, 0x8b, 0xb8, 0xad, 0xf5, 0x97, 0x14, 0x63, 0xdb, 0x72, 0xbb, - 0x35, 0xe7, 0x45, 0x3f, 0xd6, 0x11, 0xf3, 0x03, 0xb2, 0xd0, 0xca, 0x65, 0x00, 0xd3, 0x73, 0xc4, - 0x0a, 0x2f, 0xc1, 0x24, 0x13, 0x2b, 0xb6, 0x89, 0xec, 0xa1, 0xfc, 0x33, 0x8d, 0x78, 0x8f, 0xd4, - 0x3e, 0xd2, 0x03, 0x87, 0x44, 0xdb, 0x78, 0x07, 0x66, 0x76, 0x06, 0x72, 0x92, 0x24, 0x92, 0x1c, - 0xae, 0xb6, 0x28, 0xed, 0xce, 0xc0, 0x08, 0xf1, 0xd0, 0x56, 0x70, 0x30, 0xca, 0x0c, 0xe5, 0x8d, - 0x84, 0x83, 0x51, 0x8a, 0x90, 0x7e, 0x3a, 0x7a, 0xde, 0xc7, 0x27, 0xe5, 0x26, 0x14, 0xab, 0xad, - 0x30, 0xf1, 0x90, 0xf4, 0xae, 0x6f, 0x89, 0x24, 0x78, 0x2e, 0xfd, 0x30, 0x96, 0x61, 0x94, 0x7f, - 0xc2, 0xd7, 0xce, 0xf2, 0x87, 0xac, 0xdd, 0xe8, 0xfd, 0x65, 0xaf, 0x98, 0x18, 0xe8, 0x57, 0xb8, - 0x62, 0xdf, 0x2c, 0xc0, 0xb4, 0xe0, 0x20, 0x25, 0x60, 0xd0, 0x84, 0xa7, 0xc5, 0x01, 0x68, 0x13, - 0xa6, 0x1e, 0x63, 0xff, 0x99, 0xd3, 0x4d, 0x52, 0x09, 0xac, 0x85, 0xaa, 0x04, 0x8e, 0x85, 0xee, - 0xca, 0xf2, 0x4f, 0x45, 0x39, 0xe2, 0x7d, 0x84, 0xad, 0xfc, 0x1d, 0x65, 0x7d, 0x51, 0xa1, 0xd9, - 0xd0, 0xc0, 0xa5, 0xa3, 0x42, 0x5f, 0xbc, 0x7d, 0x2d, 0x9a, 0x0d, 0x55, 0xfc, 0x3e, 0x43, 0x21, - 0x41, 0xf7, 0x08, 0x33, 0x84, 0x3d, 0x4c, 0xd2, 0x1e, 0xae, 0x26, 0x70, 0x69, 0xd8, 0x81, 0x4c, - 0x40, 0xe8, 0x4d, 0x89, 0x7e, 0x2a, 0x4e, 0x6f, 0xc6, 0xe8, 0x25, 0x02, 0xe2, 0x7e, 0x85, 0xe2, - 0x99, 0x14, 0x59, 0x84, 0xad, 0x86, 0x2c, 0xc8, 0x77, 0xd5, 0x78, 0x8f, 0x3b, 0x6e, 0x25, 0x75, - 0xe2, 0x61, 0xbb, 0xa1, 0x46, 0x87, 0x77, 0x55, 0x79, 0xe7, 0x27, 0x63, 0xa5, 0x34, 0xe1, 0x34, - 0x54, 0xed, 0xf0, 0x79, 0x45, 0x80, 0xa8, 0xb1, 0x8c, 0xb8, 0xc0, 0x52, 0xb3, 0xa1, 0x08, 0xdb, - 0x5d, 0x55, 0x58, 0xa8, 0xe1, 0x4c, 0x18, 0x58, 0xb4, 0x1b, 0xaa, 0x68, 0xbd, 0x0f, 0x73, 0x35, - 0x4c, 0x0c, 0x1b, 0x9f, 0x0e, 0x4f, 0xee, 0x5d, 0x56, 0xb2, 0x06, 0x32, 0x82, 0xa1, 0xe2, 0xa3, - 0x2d, 0x98, 0xdf, 0x75, 0x9d, 0x97, 0xaf, 0xc2, 0x0d, 0x9b, 0xe3, 0x0a, 0x5e, 0xea, 0x41, 0xc5, - 0x30, 0x22, 0x14, 0xc4, 0x0a, 0x47, 0x0f, 0x0a, 0x5a, 0x27, 0xc7, 0xd4, 0x09, 0xcc, 0x1b, 0x49, - 0x4d, 0x68, 0x4b, 0x3a, 0x6a, 0x09, 0xc2, 0xc1, 0x8b, 0xe9, 0xe1, 0xa0, 0x11, 0x47, 0xa7, 0x6b, - 0xfe, 0x0c, 0x77, 0x8e, 0xb6, 0xb1, 0xd5, 0xf3, 0x9f, 0xd1, 0x74, 0x60, 0x74, 0xcd, 0xc3, 0x66, - 0x43, 0xc6, 0x45, 0x26, 0x2c, 0xb5, 0x3b, 0xcf, 0x70, 0xf7, 0xa4, 0x87, 0xb9, 0x8b, 0x4a, 0x9d, - 0x74, 0x9a, 0x18, 0x2c, 0xde, 0x5e, 0x97, 0xfb, 0x48, 0xc2, 0x33, 0x12, 0xa9, 0xcb, 0x0e, 0x14, - 0xa9, 0x24, 0x7a, 0x03, 0xa7, 0xef, 0xe1, 0x21, 0xa1, 0x19, 0x37, 0xd3, 0x39, 0xc5, 0x4c, 0x0b, - 0xc7, 0x89, 0x19, 0x6f, 0xf1, 0x38, 0xec, 0x10, 0xab, 0xbc, 0x09, 0x48, 0xe2, 0x67, 0x69, 0xdc, - 0xfb, 0xb6, 0x2b, 0x29, 0x23, 0xf1, 0x58, 0xfe, 0xef, 0x3c, 0xcd, 0xe7, 0x32, 0xb4, 0xf3, 0xd5, - 0x5a, 0x57, 0x61, 0xa6, 0xee, 0xba, 0x8e, 0x5b, 0x75, 0xba, 0x98, 0xbe, 0xc2, 0x9c, 0x11, 0x02, - 0x88, 0x2b, 0x4e, 0x1f, 0x1e, 0x63, 0xcf, 0xb3, 0x0e, 0x31, 0xcf, 0x5f, 0x28, 0x30, 0xb4, 0x06, - 0xd0, 0xf0, 0xb6, 0x2b, 0x8f, 0x30, 0x1e, 0x60, 0x97, 0x6a, 0x9d, 0x82, 0x21, 0x41, 0xd0, 0xfb, - 0xca, 0xea, 0x72, 0xb5, 0x72, 0x29, 0xa6, 0x18, 0x59, 0x33, 0xd7, 0x8c, 0xca, 0x7e, 0x10, 0x41, - 0x93, 0x82, 0x18, 0xae, 0x59, 0x54, 0x41, 0x93, 0xda, 0x0d, 0x05, 0x9b, 0x70, 0x1b, 0xd5, 0x35, - 0x7c, 0xf8, 0x42, 0x7c, 0x78, 0xa9, 0xd9, 0x90, 0x71, 0x89, 0x88, 0x55, 0x7b, 0x27, 0x9e, 0x8f, - 0xdd, 0x1a, 0x26, 0xd1, 0xa9, 0xc7, 0x95, 0x8b, 0x22, 0x62, 0x2a, 0x86, 0x11, 0xa1, 0x40, 0xf7, - 0x60, 0x26, 0x3c, 0xe2, 0x82, 0x04, 0x36, 0x15, 0x8d, 0x8c, 0x41, 0xb1, 0x77, 0xd2, 0xf3, 0x8d, - 0x90, 0x04, 0xdd, 0x03, 0x90, 0x54, 0x23, 0xd3, 0x31, 0x6b, 0x72, 0x07, 0x71, 0x46, 0x32, 0x20, - 0xa2, 0x1e, 0x89, 0x00, 0x61, 0x97, 0x69, 0xb8, 0xd9, 0x84, 0xc5, 0x93, 0xda, 0x0d, 0x05, 0xbb, - 0xfc, 0x90, 0xe6, 0xcc, 0x98, 0xff, 0x1b, 0x2c, 0xcb, 0x3b, 0xc4, 0x82, 0x12, 0x88, 0x57, 0xd2, - 0xa8, 0x5d, 0x5f, 0x8e, 0x6d, 0x26, 0x69, 0xe5, 0x5b, 0x29, 0x70, 0xcb, 0xaf, 0x2b, 0x1b, 0x41, - 0xdc, 0xb7, 0x27, 0xd4, 0x6e, 0x73, 0xf7, 0x8d, 0x3e, 0x94, 0x1f, 0xc0, 0x9c, 0x69, 0x79, 0x47, - 0xa6, 0x75, 0xd0, 0xc3, 0x7b, 0x1e, 0x76, 0x89, 0x18, 0x91, 0xbf, 0xfd, 0xd0, 0x97, 0x0e, 0x9e, - 0x49, 0xdb, 0xae, 0xe5, 0x79, 0x2f, 0x1c, 0xb7, 0xcb, 0x93, 0x1b, 0xc1, 0x73, 0xf9, 0x1b, 0x1a, - 0x99, 0x25, 0xd5, 0x5b, 0x89, 0x6e, 0x4c, 0xba, 0x2f, 0xae, 0xe4, 0x5f, 0x26, 0xa2, 0xe7, 0x89, - 0xc1, 0x89, 0x75, 0x5e, 0x3e, 0xb1, 0x5e, 0xa3, 0xb6, 0x5f, 0x75, 0xca, 0x25, 0x48, 0xf9, 0xaf, - 0x72, 0x84, 0x87, 0xfb, 0x4f, 0xed, 0xc3, 0xea, 0x33, 0xab, 0x7f, 0x88, 0xd1, 0x9d, 0x60, 0x76, - 0xfc, 0xdc, 0x73, 0x51, 0x0d, 0x38, 0x68, 0x53, 0xb8, 0x82, 0xec, 0x3d, 0xee, 0x02, 0x30, 0x72, - 0x29, 0x50, 0xb9, 0x1a, 0xcf, 0x6f, 0x84, 0x38, 0x86, 0x84, 0x8f, 0x4c, 0x98, 0x6f, 0xf4, 0x6d, - 0xdf, 0xb6, 0x7a, 0x8f, 0xf1, 0xf1, 0x01, 0x76, 0x85, 0x57, 0xf6, 0x76, 0x5a, 0x0f, 0x9b, 0x2a, - 0x3a, 0x0b, 0x9d, 0x23, 0x7d, 0xac, 0x56, 0x60, 0x31, 0x01, 0x6d, 0xac, 0xb3, 0xe1, 0xb7, 0x60, - 0xae, 0xfd, 0xec, 0xc4, 0xef, 0x3a, 0x2f, 0xfa, 0xcc, 0xb4, 0x91, 0xbd, 0xa1, 0x69, 0x39, 0xb1, - 0x65, 0xe2, 0xb1, 0xfc, 0x4f, 0x93, 0x70, 0x31, 0xa2, 0xc2, 0x13, 0x77, 0xf7, 0x06, 0xcc, 0x6d, - 0x39, 0x8e, 0xef, 0xf9, 0xae, 0x35, 0x18, 0xd8, 0xfd, 0x43, 0x3a, 0x68, 0xc1, 0x50, 0x81, 0x44, - 0x35, 0xf0, 0x9c, 0x0d, 0x5d, 0xd0, 0x09, 0xba, 0xa0, 0x8a, 0x6a, 0x90, 0x9a, 0x0d, 0x19, 0x97, - 0xe9, 0xa4, 0x70, 0xa9, 0xb8, 0xbb, 0x56, 0x4a, 0x5b, 0x4a, 0x43, 0xdd, 0xfd, 0xf7, 0x23, 0x6f, - 0xcc, 0x7d, 0xb5, 0xcb, 0xaa, 0x62, 0x90, 0x10, 0x8c, 0xc8, 0x0a, 0x3d, 0x82, 0x05, 0x96, 0x58, - 0x93, 0x32, 0x6d, 0x5c, 0xb3, 0x2a, 0x2e, 0x63, 0x0c, 0xc9, 0x88, 0xd3, 0xc5, 0x5d, 0x91, 0xe9, - 0x31, 0x5d, 0x91, 0x47, 0xb0, 0xf0, 0xd0, 0xb1, 0xfb, 0x2c, 0xab, 0xcd, 0xf5, 0x1f, 0x57, 0xb4, - 0xca, 0x6c, 0x62, 0x48, 0x46, 0x9c, 0x0e, 0x6d, 0x83, 0xce, 0x7a, 0xa7, 0xbe, 0x0a, 0x9b, 0xd0, - 0x4c, 0xdc, 0x15, 0x8d, 0xe2, 0x18, 0x31, 0x2a, 0xb2, 0xbd, 0x95, 0x6e, 0x57, 0x48, 0x61, 0x92, - 0x6f, 0x27, 0x35, 0x1b, 0x32, 0x2e, 0xd1, 0xfc, 0x01, 0xab, 0x30, 0xea, 0x62, 0x5c, 0xf3, 0xab, - 0x18, 0x46, 0x84, 0xa2, 0x8c, 0x93, 0x7d, 0x95, 0x44, 0x7e, 0x8d, 0x70, 0x62, 0x6e, 0x74, 0x4e, - 0x2c, 0xff, 0x45, 0x0e, 0x56, 0x22, 0xe9, 0x3a, 0x71, 0x60, 0x54, 0x0e, 0x5c, 0x63, 0x32, 0x08, - 0xd3, 0xd6, 0x33, 0x86, 0x02, 0xa3, 0xc9, 0x36, 0x19, 0x27, 0xc7, 0x70, 0x64, 0x18, 0xd1, 0xb3, - 0xf5, 0x97, 0x44, 0x05, 0xd9, 0x3e, 0x2f, 0xa0, 0x08, 0x9e, 0x89, 0x0b, 0xc9, 0xfb, 0x33, 0xed, - 0x63, 0xec, 0x9c, 0xf8, 0xa6, 0xdd, 0x39, 0xf2, 0xb8, 0x76, 0x4c, 0x6a, 0x22, 0x14, 0x66, 0x02, - 0x05, 0x53, 0x9a, 0x49, 0x4d, 0xe8, 0x73, 0xb0, 0x5c, 0x27, 0xea, 0xc2, 0xf2, 0x71, 0xf5, 0xc4, - 0x75, 0x71, 0xdf, 0xa7, 0x38, 0x1e, 0x3f, 0xe5, 0x48, 0x6e, 0x2c, 0xdf, 0x4a, 0xe0, 0x4a, 0xf6, - 0x2a, 0xb6, 0x47, 0x6b, 0x41, 0xd8, 0x72, 0x04, 0xcf, 0xe5, 0x5e, 0x82, 0x50, 0xa1, 0x3b, 0x90, - 0x27, 0xf6, 0x86, 0x6b, 0x69, 0x45, 0x26, 0x14, 0x43, 0xc5, 0x75, 0x35, 0x45, 0xa6, 0x8b, 0x6a, - 0x79, 0x47, 0x35, 0xcb, 0xb7, 0x0e, 0x2c, 0x4f, 0xa8, 0x3c, 0x05, 0x46, 0xb4, 0x9e, 0x2a, 0x45, - 0xe9, 0x5a, 0xef, 0xed, 0xb8, 0x48, 0x0c, 0xc1, 0x7e, 0x53, 0x61, 0xfb, 0x74, 0x6f, 0xb6, 0xfc, - 0x73, 0x2d, 0xca, 0xe5, 0xa7, 0x3d, 0x95, 0x40, 0x4f, 0x52, 0x6c, 0xcb, 0x66, 0xba, 0xbc, 0x8c, - 0x62, 0x5d, 0x88, 0xac, 0x90, 0x3d, 0xe4, 0xe7, 0x0a, 0xf4, 0xf7, 0x79, 0x58, 0x9c, 0x1f, 0xe5, - 0x54, 0x97, 0x32, 0xa8, 0x2a, 0xd3, 0xa4, 0xaa, 0xb2, 0x2f, 0xb2, 0xca, 0x06, 0xab, 0xdf, 0x15, - 0xf5, 0x6d, 0x57, 0x86, 0xc4, 0x17, 0xe2, 0xdc, 0x4b, 0x90, 0x90, 0xa5, 0x14, 0xe9, 0x78, 0x1e, - 0x19, 0x88, 0x14, 0x7c, 0x15, 0x80, 0x63, 0x11, 0x81, 0xcb, 0xd3, 0xae, 0xaf, 0x0d, 0xe9, 0xba, - 0x51, 0x13, 0xf9, 0x82, 0x90, 0x0c, 0x7d, 0x04, 0xcb, 0x89, 0x87, 0x5e, 0xdc, 0x94, 0xbc, 0x26, - 0xf7, 0x97, 0x5c, 0x71, 0x9d, 0x4c, 0x9f, 0x7d, 0x4c, 0x3e, 0x35, 0xc2, 0x31, 0x79, 0xf9, 0xaf, - 0x73, 0x29, 0xf3, 0x23, 0x8c, 0xc4, 0xce, 0xa1, 0x99, 0x08, 0x92, 0x7d, 0x0d, 0x01, 0x64, 0xd5, - 0xea, 0x7d, 0x22, 0x53, 0x5d, 0x6e, 0xb2, 0xc5, 0x63, 0x4a, 0xa9, 0xe0, 0x6d, 0x58, 0x0a, 0x4a, - 0x0c, 0x68, 0x19, 0x39, 0x4b, 0xda, 0x73, 0x86, 0x49, 0x6c, 0x43, 0x9b, 0x80, 0x12, 0xca, 0x28, - 0x98, 0xfe, 0x49, 0x68, 0x89, 0xd4, 0x54, 0x4d, 0xc5, 0x6a, 0xaa, 0x96, 0x60, 0x92, 0x95, 0x20, - 0xb0, 0xda, 0x22, 0xf6, 0x40, 0x34, 0x0d, 0x79, 0x69, 0x3f, 0xac, 0xc1, 0x0c, 0x9e, 0xcb, 0xff, - 0xae, 0xa9, 0x95, 0x14, 0xc1, 0xea, 0x08, 0xcd, 0x2d, 0x6b, 0x5c, 0x6d, 0x34, 0x8d, 0x9b, 0x4b, - 0xd7, 0xb8, 0xef, 0xc2, 0x4a, 0xa8, 0x39, 0x14, 0x22, 0xb6, 0x96, 0x29, 0xad, 0xe9, 0x7a, 0x37, - 0x3f, 0x4c, 0xef, 0xfe, 0xf3, 0x1c, 0x14, 0xf9, 0x2c, 0x68, 0x04, 0x23, 0x2a, 0x73, 0x35, 0xa9, - 0x32, 0xf7, 0xff, 0x57, 0xe5, 0x58, 0x25, 0xc8, 0x73, 0x16, 0xa8, 0x30, 0xbf, 0x9e, 0x90, 0x7c, - 0xa2, 0xd5, 0xa0, 0x23, 0x5e, 0x9b, 0x99, 0x39, 0xd5, 0xb5, 0x19, 0x48, 0xae, 0x57, 0x53, 0x0b, - 0x10, 0x8a, 0xa3, 0x54, 0xa2, 0xcd, 0x66, 0x56, 0xa2, 0xcd, 0x9d, 0xaa, 0x12, 0x6d, 0xfe, 0x54, - 0x17, 0x70, 0x2e, 0x8e, 0x72, 0x01, 0x47, 0x1f, 0xad, 0x42, 0x6d, 0x21, 0x52, 0xa1, 0x96, 0x71, - 0x1a, 0x8a, 0xce, 0xa3, 0xde, 0x6c, 0xf1, 0xbc, 0xea, 0xcd, 0x96, 0xce, 0xa1, 0xde, 0x6c, 0xf9, - 0xec, 0xf5, 0x66, 0x2b, 0xe7, 0x52, 0x6f, 0x76, 0xe9, 0x1c, 0xea, 0xcd, 0x4a, 0x23, 0xd4, 0x9b, - 0x0d, 0xbf, 0x92, 0x74, 0x39, 0xf3, 0x4a, 0xd2, 0xb0, 0x7a, 0xb5, 0xd5, 0xb3, 0xd4, 0xab, 0x5d, - 0x39, 0x73, 0xbd, 0xda, 0xd5, 0x73, 0xba, 0x92, 0x74, 0xed, 0x9c, 0x8a, 0xc6, 0xd6, 0xce, 0x54, - 0x34, 0x76, 0xfd, 0xd7, 0xeb, 0x4a, 0xd2, 0x77, 0x73, 0xec, 0x16, 0x28, 0xbf, 0x12, 0xc9, 0x0d, - 0x9f, 0x96, 0x7c, 0x25, 0xd2, 0xf2, 0xf1, 0x26, 0xc3, 0x50, 0x74, 0x3b, 0x03, 0x65, 0x6f, 0x64, - 0x6e, 0x94, 0x8d, 0x4c, 0x5d, 0xb8, 0x89, 0xd3, 0x2e, 0x9c, 0x01, 0x45, 0x69, 0xd2, 0x09, 0x0b, - 0xf7, 0x19, 0x75, 0xe1, 0x2e, 0xa5, 0x98, 0x35, 0xd9, 0xb3, 0xfe, 0xd7, 0x3c, 0x2d, 0x73, 0x3a, - 0x17, 0xe3, 0xff, 0x49, 0x65, 0xd2, 0x6f, 0x70, 0x65, 0x52, 0x86, 0x65, 0x9d, 0x1b, 0xb5, 0xce, - 0xe8, 0x6f, 0x34, 0x76, 0x35, 0x30, 0x53, 0x0e, 0xcd, 0x2c, 0x39, 0x3c, 0x1b, 0xbf, 0x9b, 0xc9, - 0xfc, 0xfe, 0x8f, 0x13, 0x00, 0x52, 0x54, 0x9e, 0x94, 0xdb, 0x11, 0x22, 0x90, 0x93, 0x44, 0xe0, - 0x06, 0xcc, 0x11, 0xb5, 0x83, 0xfb, 0xaa, 0x6b, 0xab, 0x02, 0x23, 0x5c, 0x93, 0x1f, 0x99, 0x6b, - 0xb2, 0x7d, 0x92, 0xc9, 0xf3, 0xf2, 0x49, 0xa6, 0xce, 0xc1, 0x27, 0x99, 0x3e, 0xdb, 0xb5, 0xe2, - 0x42, 0x96, 0x0d, 0x2f, 0xff, 0x83, 0x16, 0x6c, 0x12, 0x61, 0xa3, 0x0f, 0x22, 0x6c, 0x54, 0x8e, - 0x9d, 0x98, 0x66, 0x71, 0xd2, 0x87, 0x59, 0x9c, 0xf4, 0xb6, 0xca, 0x49, 0x2b, 0x09, 0x23, 0x38, - 0x2e, 0x96, 0x19, 0xe9, 0x07, 0xb9, 0xe8, 0x79, 0x6e, 0x5a, 0x62, 0x5b, 0x65, 0x9c, 0x5c, 0x36, - 0xe3, 0x4c, 0x9c, 0x23, 0xe3, 0xe4, 0xcf, 0x8b, 0x71, 0x26, 0xcf, 0x81, 0x71, 0xa6, 0x32, 0x18, - 0xa7, 0xfc, 0x9d, 0x7c, 0xf4, 0x04, 0x0f, 0xbd, 0x03, 0x05, 0x2e, 0xca, 0x62, 0xfb, 0x17, 0x13, - 0xc4, 0x5c, 0x84, 0x23, 0x02, 0x95, 0x90, 0x55, 0x05, 0x59, 0x2e, 0x4e, 0x56, 0x55, 0xc9, 0x04, - 0x2a, 0x7a, 0x8f, 0xd6, 0x9c, 0x71, 0x3a, 0x66, 0xc5, 0x96, 0x92, 0x4a, 0x3a, 0x38, 0x61, 0x88, - 0x8c, 0xee, 0x41, 0x31, 0x64, 0x14, 0x91, 0x25, 0x4a, 0xe1, 0x23, 0x71, 0x68, 0x2a, 0x11, 0xa0, - 0x9a, 0x48, 0x2f, 0x76, 0x79, 0x0f, 0xac, 0x42, 0xb2, 0x14, 0xcf, 0xa1, 0x77, 0xe5, 0x3e, 0x54, - 0xa2, 0xf4, 0x2c, 0xd3, 0xd4, 0x2f, 0x3b, 0xcb, 0x34, 0x7d, 0x26, 0x9f, 0xa8, 0x70, 0x4a, 0x9f, - 0xa8, 0xfc, 0x87, 0x1a, 0x14, 0x39, 0xc7, 0x50, 0xff, 0xe5, 0xf3, 0x94, 0x5d, 0x98, 0x17, 0xa2, - 0x71, 0x2f, 0x24, 0x70, 0x1f, 0x79, 0x8b, 0x72, 0xdc, 0x19, 0xa0, 0xa3, 0xbb, 0x6c, 0xef, 0x19, - 0x6d, 0x8e, 0xaf, 0x7e, 0xe8, 0x7a, 0x8a, 0x73, 0x07, 0x99, 0x38, 0x24, 0x28, 0x7f, 0x3b, 0x0f, - 0xcb, 0x3c, 0xcd, 0x29, 0x0e, 0x4b, 0x78, 0xb9, 0xcc, 0x1b, 0x30, 0xdf, 0x3a, 0x39, 0xde, 0x79, - 0x1a, 0x76, 0xce, 0x9c, 0xab, 0x08, 0x94, 0xa8, 0x0a, 0x0a, 0x09, 0xe6, 0xcf, 0x0c, 0x90, 0x0a, - 0x44, 0x1b, 0xa0, 0x0b, 0xba, 0xe0, 0x12, 0x02, 0xcb, 0x0a, 0xc5, 0xe0, 0x24, 0x26, 0x6f, 0xe1, - 0x97, 0x7e, 0x50, 0xd0, 0xc0, 0x9f, 0x90, 0x09, 0x45, 0xf6, 0x6b, 0xeb, 0xd5, 0x23, 0x2c, 0x6a, - 0x71, 0x6f, 0xcb, 0xbc, 0x91, 0xf8, 0x26, 0x9b, 0x12, 0x11, 0x4b, 0xff, 0xca, 0xdd, 0xa0, 0xa7, - 0x49, 0xa5, 0x26, 0xec, 0x56, 0xef, 0x7b, 0x23, 0xf4, 0x1d, 0x25, 0x8d, 0x5e, 0xef, 0x0d, 0xca, - 0x51, 0xa8, 0x2f, 0x77, 0x28, 0xce, 0xc7, 0x78, 0xd9, 0xa9, 0xc8, 0xf6, 0xc4, 0x5b, 0x56, 0xef, - 0x81, 0x1e, 0x9d, 0x78, 0xf2, 0x15, 0x95, 0xe4, 0x3a, 0x54, 0xe5, 0x76, 0xae, 0x32, 0xb9, 0xac, - 0x5e, 0x94, 0x14, 0xf6, 0x2f, 0x34, 0xb8, 0x6c, 0x60, 0x8f, 0xe5, 0xfc, 0x3f, 0xb2, 0x7c, 0xec, - 0x1e, 0x5b, 0xee, 0x91, 0xe0, 0x91, 0x70, 0xa7, 0x34, 0x65, 0xa7, 0xbe, 0xa4, 0xee, 0x54, 0x2e, - 0x7e, 0x7b, 0x39, 0xb5, 0xcf, 0x8c, 0xdd, 0x4a, 0x5e, 0xc5, 0x89, 0x5f, 0xd6, 0x2a, 0x96, 0xff, - 0x87, 0x5f, 0x54, 0x1f, 0x1a, 0x69, 0x7c, 0x72, 0x93, 0xe7, 0x93, 0x9b, 0x3c, 0xe7, 0x7f, 0x93, - 0xe7, 0xbb, 0x39, 0xfe, 0xcd, 0x0a, 0xe2, 0x4c, 0xde, 0x0b, 0x82, 0x54, 0x66, 0x1e, 0xd6, 0x63, - 0xe6, 0x9d, 0xba, 0x92, 0x14, 0x45, 0x75, 0x25, 0x99, 0xfe, 0xbd, 0x17, 0x38, 0xa3, 0xb9, 0x61, - 0xf4, 0xa9, 0xae, 0x68, 0x1b, 0x8a, 0x52, 0xe7, 0x09, 0xa7, 0x60, 0x9b, 0xaa, 0x2b, 0x9a, 0x7a, - 0xbf, 0x5e, 0x56, 0x51, 0xed, 0x2c, 0xff, 0x36, 0xab, 0xd3, 0xa4, 0x50, 0xe9, 0x3f, 0x0b, 0x6a, - 0x29, 0x52, 0xa2, 0xc4, 0xbe, 0xaf, 0x98, 0xdf, 0xc4, 0xc4, 0x43, 0xd8, 0x2c, 0xfc, 0x1e, 0xd9, - 0x60, 0xdf, 0x09, 0xc2, 0x45, 0xee, 0xf7, 0x2e, 0x26, 0x04, 0x89, 0xa2, 0xb0, 0x46, 0x04, 0x96, - 0xef, 0x86, 0x1b, 0xca, 0xc3, 0xac, 0xa5, 0xa4, 0x6d, 0x08, 0x25, 0x82, 0x6f, 0xfe, 0x9d, 0x20, - 0x47, 0xc4, 0x8f, 0xdd, 0x16, 0x13, 0x32, 0x43, 0x62, 0x30, 0x91, 0x4d, 0xba, 0x25, 0x0a, 0xa8, - 0xd9, 0x21, 0x84, 0x72, 0xa4, 0x2c, 0x8a, 0xe6, 0x94, 0x32, 0xea, 0x16, 0xd7, 0x0b, 0xfc, 0x54, - 0x90, 0x17, 0x72, 0x4d, 0x53, 0xea, 0xb5, 0xe8, 0x81, 0xb4, 0x8a, 0x65, 0x24, 0x50, 0xa2, 0x7a, - 0xa4, 0xc6, 0x8a, 0x2b, 0x81, 0xcc, 0xb3, 0xed, 0x48, 0x65, 0x96, 0xb0, 0x31, 0x5d, 0x7e, 0x37, - 0x85, 0x3f, 0xa1, 0x47, 0xaa, 0x8d, 0x81, 0xf8, 0x6d, 0x58, 0x99, 0x0b, 0x32, 0xcc, 0xca, 0x5d, - 0x39, 0x72, 0xe3, 0x45, 0x18, 0x2b, 0xc9, 0xf1, 0x9a, 0x38, 0x24, 0x95, 0x22, 0x3d, 0xf9, 0xf0, - 0x61, 0x76, 0xbc, 0x6b, 0xf0, 0x49, 0x75, 0xb1, 0x73, 0xe9, 0x75, 0xb1, 0xdb, 0x49, 0xce, 0xca, - 0x7c, 0xa6, 0x72, 0x4d, 0x70, 0x47, 0xee, 0xc2, 0xe5, 0xb8, 0xb9, 0xdc, 0xc5, 0xfd, 0xae, 0xdd, - 0x3f, 0xa4, 0x67, 0x21, 0x05, 0x23, 0x1d, 0x01, 0x6d, 0xc1, 0x55, 0xc5, 0x74, 0x53, 0x63, 0x2e, - 0x85, 0x5d, 0xec, 0xee, 0xfd, 0x50, 0x1c, 0x12, 0x6e, 0x27, 0x0c, 0x20, 0xb2, 0xc5, 0xec, 0x0e, - 0xfe, 0x10, 0x0c, 0xf4, 0x01, 0x5c, 0x89, 0xb7, 0x06, 0xb7, 0x95, 0xc4, 0xa1, 0xca, 0x10, 0x94, - 0x33, 0x3b, 0x07, 0x7f, 0xaa, 0xc1, 0xac, 0x1c, 0xc8, 0x24, 0x86, 0xd2, 0x57, 0x61, 0x86, 0x1d, - 0x79, 0x8a, 0x8a, 0x9b, 0x19, 0x23, 0x04, 0xa0, 0x12, 0x4c, 0xab, 0x1e, 0x81, 0x78, 0x94, 0x4e, - 0xa6, 0xf2, 0xca, 0xc9, 0xd4, 0x2a, 0x14, 0x6a, 0xce, 0x8b, 0x3e, 0x6d, 0x99, 0xa4, 0x2d, 0xc1, - 0x73, 0xf9, 0x2f, 0xcb, 0xa0, 0x0b, 0xd9, 0x0e, 0x6e, 0xcd, 0x05, 0x77, 0xe4, 0x34, 0xf9, 0x8e, - 0x5c, 0x52, 0xba, 0x28, 0x74, 0xe7, 0x26, 0x14, 0x77, 0x6e, 0x47, 0x15, 0x35, 0x16, 0x24, 0x7e, - 0x26, 0x49, 0xa1, 0x04, 0x97, 0xe1, 0x86, 0x8b, 0x5b, 0xd2, 0xd7, 0x75, 0xfe, 0xcf, 0xf5, 0x55, - 0x17, 0xf4, 0x48, 0x45, 0x84, 0x38, 0x68, 0xbd, 0x3d, 0xf4, 0x55, 0xa3, 0x44, 0xb2, 0xf9, 0x8c, - 0xf5, 0x88, 0x1a, 0x72, 0xb8, 0xc6, 0x3e, 0x7d, 0xf8, 0xe9, 0xa1, 0xdd, 0x07, 0xd8, 0x6c, 0x1d, - 0x43, 0x6a, 0xd9, 0x2c, 0xc0, 0xc8, 0x66, 0x41, 0x32, 0x5c, 0xc5, 0x53, 0x19, 0xae, 0xd9, 0x31, - 0x0c, 0x57, 0xc4, 0xcc, 0xce, 0x8d, 0x6d, 0x66, 0x63, 0x36, 0x64, 0xfe, 0x54, 0x36, 0x44, 0x55, - 0xef, 0x17, 0xc7, 0x54, 0xef, 0xb1, 0x1c, 0x87, 0x7e, 0x9a, 0x1c, 0x47, 0x8a, 0xb2, 0x5f, 0x18, - 0x53, 0xd9, 0xa3, 0x73, 0x57, 0xf6, 0x8b, 0x67, 0x55, 0xf6, 0x4b, 0x67, 0x56, 0xf6, 0xcb, 0x67, - 0x55, 0xf6, 0x2b, 0x99, 0xca, 0x1e, 0xbd, 0x1b, 0xab, 0x5f, 0x14, 0x15, 0x40, 0xec, 0x8c, 0x38, - 0xa5, 0x35, 0x21, 0x1c, 0x09, 0xeb, 0x8a, 0x4a, 0x89, 0xe1, 0x48, 0x58, 0x66, 0xf4, 0x55, 0x58, - 0x8a, 0xb4, 0x89, 0xf3, 0xe0, 0x58, 0x40, 0x1c, 0x93, 0xfb, 0x24, 0x42, 0xa6, 0x02, 0x12, 0xfb, - 0x44, 0x83, 0xd8, 0xfb, 0x55, 0x5b, 0xe2, 0xfc, 0x38, 0x96, 0xcc, 0xc8, 0x1a, 0x8d, 0x93, 0xb2, - 0xf1, 0x52, 0xfa, 0x4d, 0x18, 0xd1, 0x6c, 0x89, 0x43, 0xe7, 0xb1, 0x47, 0x34, 0x87, 0x8d, 0xc8, - 0x1b, 0xd1, 0x36, 0x5c, 0x8f, 0xb4, 0xf0, 0x62, 0x37, 0xaf, 0xe2, 0x79, 0xf6, 0x61, 0x3f, 0xfc, - 0x34, 0x49, 0x06, 0x1a, 0x6a, 0xc2, 0x6b, 0xd1, 0xb7, 0x0a, 0x8a, 0xde, 0x82, 0xbe, 0xd8, 0x89, - 0x75, 0x36, 0x62, 0x6a, 0xd8, 0x19, 0x72, 0xca, 0xda, 0x90, 0xb0, 0x33, 0xe4, 0x97, 0xad, 0x94, - 0x7a, 0x2d, 0xc1, 0xa9, 0xd7, 0xe3, 0xd5, 0x0c, 0x51, 0x9c, 0xd4, 0x53, 0x0c, 0x96, 0xcb, 0x5e, - 0xa7, 0xb2, 0x3a, 0x04, 0x03, 0x3d, 0x84, 0xf5, 0xc4, 0x4a, 0x07, 0xb9, 0xec, 0xed, 0x35, 0x3a, - 0x8f, 0x4c, 0xbc, 0x11, 0xaa, 0x3c, 0xca, 0x23, 0x55, 0x79, 0x7c, 0x5d, 0x83, 0x6b, 0x89, 0x53, - 0xa6, 0xa9, 0x0e, 0xc2, 0x71, 0xaf, 0x53, 0x8e, 0x7b, 0x7f, 0x28, 0xc7, 0x0d, 0xed, 0x81, 0x31, - 0xde, 0xf0, 0x51, 0xd0, 0xef, 0xa7, 0x15, 0xd4, 0x09, 0x51, 0xbb, 0x41, 0xa7, 0x71, 0x6f, 0xfc, - 0x69, 0x28, 0x02, 0x37, 0x74, 0x0c, 0xf4, 0x0d, 0x2d, 0xe5, 0xd8, 0x83, 0x9a, 0x2c, 0x36, 0x8f, - 0x4f, 0xd1, 0x79, 0x54, 0xc6, 0x9f, 0x47, 0xd8, 0x07, 0x9b, 0x4a, 0xd6, 0x48, 0xe8, 0x8f, 0xb4, - 0x14, 0xde, 0xaf, 0xb6, 0xc4, 0x87, 0x8a, 0xde, 0xa0, 0x93, 0xf9, 0xe0, 0x34, 0x8b, 0xc2, 0xbb, - 0x60, 0x73, 0xc9, 0x18, 0x07, 0x7d, 0x53, 0x83, 0xd7, 0xd2, 0xa7, 0x2b, 0x66, 0xf3, 0x26, 0x9d, - 0x4d, 0xf5, 0x94, 0x4b, 0xa3, 0x4c, 0x28, 0x7b, 0xb4, 0x54, 0x89, 0x16, 0xc6, 0xf7, 0xe6, 0x10, - 0x89, 0x16, 0xf6, 0xf7, 0xcf, 0x35, 0x28, 0x0f, 0x7d, 0x75, 0x56, 0x64, 0xf9, 0x16, 0x7d, 0xb1, - 0xda, 0xe9, 0x97, 0x99, 0x76, 0xc3, 0xde, 0x6c, 0x84, 0xf1, 0xd0, 0xb7, 0x35, 0xf8, 0x54, 0xd6, - 0x02, 0xb0, 0x99, 0x6d, 0xd0, 0x99, 0x3d, 0x38, 0xd3, 0x92, 0x4b, 0x93, 0x1b, 0x6d, 0xd4, 0x33, - 0x27, 0xd0, 0x3f, 0x86, 0xe5, 0x44, 0xd7, 0x7e, 0xcc, 0x3c, 0x95, 0x72, 0x67, 0x50, 0xea, 0xfe, - 0x2e, 0xfd, 0x52, 0x65, 0x4a, 0x52, 0x2d, 0x73, 0x72, 0x0f, 0xe0, 0x72, 0xaa, 0x83, 0x90, 0xd5, - 0x51, 0x41, 0xee, 0xa8, 0x11, 0x2b, 0xa0, 0x90, 0x55, 0xd1, 0x19, 0xbb, 0x32, 0x4f, 0xdb, 0xd5, - 0x6e, 0x0a, 0xc7, 0x2b, 0xda, 0x7a, 0xac, 0x1e, 0x77, 0x52, 0x74, 0xc3, 0xa9, 0xdf, 0xd6, 0x80, - 0x1b, 0xa3, 0x68, 0xd0, 0xb1, 0xfa, 0xfc, 0x10, 0x5e, 0x1f, 0x41, 0x11, 0x8e, 0xc5, 0x28, 0x26, - 0xbc, 0x31, 0x9a, 0x36, 0x1b, 0xab, 0xd7, 0x3d, 0x78, 0x73, 0x44, 0x55, 0x32, 0x56, 0xb7, 0x5f, - 0x82, 0x8d, 0xd1, 0xf5, 0xc0, 0x58, 0xa9, 0x9a, 0x06, 0xab, 0x45, 0x12, 0x1f, 0x85, 0x3d, 0xc3, - 0x97, 0xac, 0xca, 0x7f, 0x9b, 0x83, 0xa5, 0xa4, 0xeb, 0xb4, 0x43, 0x6e, 0xb5, 0xec, 0xc6, 0xbe, - 0x61, 0xbc, 0x99, 0x75, 0x39, 0x57, 0xfd, 0x96, 0x71, 0xec, 0x10, 0xe7, 0x5c, 0xbe, 0x68, 0xbc, - 0x6a, 0x66, 0x7f, 0xfe, 0x77, 0x58, 0xb1, 0x92, 0xb4, 0xa2, 0xf2, 0x5a, 0x7f, 0x47, 0x03, 0xd8, - 0xb2, 0x3a, 0x47, 0x27, 0x03, 0x7a, 0x0e, 0x94, 0x76, 0x48, 0xd8, 0x48, 0x3a, 0x24, 0x7c, 0x53, - 0xb9, 0xc9, 0x13, 0x74, 0x32, 0x3c, 0x9f, 0x74, 0xe6, 0x44, 0xde, 0x1f, 0x68, 0xe2, 0x8c, 0xab, - 0xe1, 0xe3, 0xe3, 0xc4, 0x8f, 0xea, 0x94, 0x61, 0x96, 0xdf, 0x3f, 0x78, 0x22, 0x9d, 0x94, 0x2a, - 0x30, 0x82, 0x53, 0xc3, 0x4f, 0xad, 0x93, 0x1e, 0xc7, 0xe1, 0x5f, 0xbd, 0x95, 0x61, 0x64, 0x8b, - 0x1a, 0x7d, 0x1f, 0xbb, 0x7d, 0xab, 0xc7, 0x0f, 0xf7, 0x82, 0xe7, 0xf2, 0xdf, 0x69, 0xf2, 0x51, - 0x1b, 0xfa, 0x22, 0x4c, 0x57, 0x9d, 0xbe, 0x8f, 0xe9, 0xb7, 0x67, 0xe2, 0x05, 0xff, 0x01, 0xe2, - 0x26, 0xc7, 0x62, 0x0b, 0x23, 0x68, 0x56, 0x0d, 0x7a, 0x77, 0x34, 0x68, 0x18, 0xb3, 0x7c, 0x28, - 0x5c, 0x0e, 0x79, 0xa1, 0x7e, 0x37, 0x3c, 0xd3, 0x43, 0xef, 0x84, 0x37, 0xab, 0x63, 0x55, 0x72, - 0x02, 0x69, 0x93, 0x62, 0xb0, 0x89, 0x31, 0xec, 0xd5, 0xf7, 0x00, 0x42, 0xe0, 0x58, 0x67, 0xd1, - 0x6f, 0x2a, 0x1f, 0x74, 0x18, 0x72, 0xe3, 0xec, 0x63, 0x58, 0x88, 0xdd, 0x6d, 0x42, 0x37, 0x60, - 0x8e, 0x7d, 0x23, 0x4a, 0x5c, 0x97, 0x62, 0x44, 0x2a, 0x90, 0x6e, 0x33, 0x27, 0x91, 0xbe, 0x2b, - 0xa6, 0xc0, 0x36, 0x5e, 0x00, 0xec, 0x0d, 0xba, 0x96, 0xcf, 0x32, 0xb8, 0x97, 0x60, 0x51, 0xf9, - 0xe6, 0x14, 0x6b, 0xd2, 0x2f, 0xa0, 0x65, 0x58, 0x10, 0xdf, 0x12, 0x6b, 0xb6, 0x5b, 0x1c, 0xac, - 0xa1, 0x45, 0xb8, 0xb8, 0xe7, 0x61, 0x97, 0xbe, 0x3e, 0x07, 0xe6, 0xd0, 0x1c, 0xcc, 0x98, 0xed, - 0x1d, 0xfe, 0x38, 0x41, 0x48, 0x83, 0xef, 0x82, 0x05, 0xa4, 0xf9, 0x8d, 0x4d, 0x98, 0x09, 0xbe, - 0x27, 0x8f, 0x2e, 0x42, 0xb1, 0xe5, 0xb8, 0xc7, 0x56, 0x8f, 0x3e, 0xea, 0x17, 0x90, 0x0e, 0xb3, - 0xfc, 0x5a, 0x0d, 0x83, 0x68, 0x1b, 0x3f, 0xcb, 0x03, 0x84, 0xdf, 0x62, 0x40, 0xf3, 0x00, 0x66, - 0x7b, 0x67, 0x7f, 0x6f, 0xb7, 0x56, 0x31, 0xeb, 0xfa, 0x05, 0x04, 0x30, 0x55, 0xd9, 0xdd, 0xad, - 0xb7, 0x6a, 0xba, 0x86, 0x0a, 0x90, 0x37, 0xea, 0x95, 0x9a, 0x9e, 0x43, 0xb3, 0x50, 0x30, 0x8d, - 0xbd, 0x56, 0x95, 0xe0, 0x4c, 0x90, 0x4e, 0x1f, 0xd4, 0xcd, 0xfd, 0x00, 0x92, 0x47, 0x45, 0x98, - 0xae, 0xee, 0xb4, 0x5a, 0xf5, 0xaa, 0xa9, 0x4f, 0x92, 0x2e, 0xf9, 0xc3, 0xbe, 0xb1, 0xa3, 0x4f, - 0xa1, 0x05, 0x98, 0x6b, 0xee, 0x3c, 0xd8, 0xdf, 0xae, 0x57, 0x0c, 0x73, 0xab, 0x5e, 0x31, 0xf5, - 0x69, 0xd2, 0x43, 0xb5, 0x25, 0x41, 0x0a, 0x74, 0xa2, 0x32, 0x64, 0x06, 0x21, 0x98, 0xaf, 0x6e, - 0xd7, 0xab, 0x8f, 0xf6, 0xb7, 0x2b, 0x8f, 0xea, 0xf5, 0xdd, 0xba, 0xa1, 0x03, 0x59, 0x57, 0x32, - 0x72, 0xb5, 0xb9, 0xd7, 0x36, 0xeb, 0xc6, 0x7e, 0xad, 0x6e, 0x56, 0x1a, 0xcd, 0xb6, 0x5e, 0x24, - 0xc8, 0xa4, 0xa1, 0xbd, 0x5d, 0x31, 0x6a, 0xfb, 0x8d, 0xd6, 0xfd, 0x1d, 0x7d, 0x96, 0x76, 0xd0, - 0xda, 0xaf, 0x34, 0x9b, 0x3b, 0x64, 0x96, 0xfb, 0x8d, 0x9a, 0x3e, 0x47, 0x16, 0x51, 0xee, 0xa0, - 0x6d, 0x92, 0xf9, 0xcf, 0xd3, 0xf5, 0xa7, 0x2b, 0xb0, 0x5f, 0x6d, 0xed, 0x37, 0x2b, 0x5b, 0xf5, - 0xa6, 0x7e, 0x11, 0x95, 0x60, 0x29, 0x04, 0x7e, 0xb4, 0x63, 0x3c, 0xe2, 0xe8, 0x3a, 0xe9, 0x79, - 0xb7, 0x62, 0x56, 0xb7, 0x49, 0x43, 0xdb, 0xdc, 0x31, 0xea, 0xfa, 0x02, 0xe9, 0xa2, 0x56, 0x6f, - 0xd6, 0x19, 0x36, 0x03, 0x22, 0x02, 0xdc, 0x35, 0x76, 0xbe, 0xf4, 0x65, 0xe9, 0xc5, 0x16, 0xd1, - 0x6b, 0x70, 0x8d, 0xf7, 0xdb, 0xda, 0x69, 0xed, 0x3f, 0xd9, 0x31, 0x1b, 0xad, 0x07, 0xfb, 0x46, - 0x7d, 0xb7, 0xd9, 0xa8, 0x56, 0xf6, 0x5b, 0x7b, 0x8f, 0xf5, 0x25, 0xb4, 0x06, 0xab, 0x71, 0x14, - 0xf2, 0x1e, 0xcd, 0x86, 0xf9, 0x65, 0x7d, 0x19, 0x2d, 0x81, 0xde, 0xae, 0x9b, 0xfb, 0x46, 0xfd, - 0xc3, 0xbd, 0x86, 0x51, 0xaf, 0xed, 0x37, 0xdb, 0x2d, 0x7d, 0x85, 0x40, 0x1f, 0x44, 0xa1, 0x97, - 0xc4, 0xd2, 0x34, 0x2b, 0x66, 0xbd, 0x6d, 0x52, 0x58, 0x89, 0x6c, 0x09, 0x85, 0xd5, 0x2b, 0xb5, - 0xba, 0x41, 0x56, 0xe6, 0x32, 0xdd, 0x12, 0xb6, 0xdc, 0xf5, 0x4a, 0xd3, 0xdc, 0xd6, 0x57, 0xc9, - 0xa6, 0x93, 0xed, 0xa7, 0x24, 0x57, 0xd0, 0x65, 0x58, 0xe6, 0x53, 0x6a, 0xd6, 0x2b, 0xed, 0xfa, - 0xf6, 0x4e, 0x93, 0x93, 0x5e, 0x25, 0x4d, 0x74, 0xf1, 0xab, 0xdb, 0xf5, 0xda, 0x5e, 0xb3, 0xbe, - 0x5f, 0xdd, 0x79, 0xfc, 0xb8, 0xd2, 0xaa, 0xb5, 0xf5, 0x6b, 0x1b, 0x2d, 0x80, 0xf0, 0x0b, 0x66, - 0x84, 0x33, 0x08, 0x9b, 0x33, 0x88, 0x7e, 0x81, 0x8c, 0x20, 0xf4, 0x9c, 0xae, 0x11, 0xe6, 0xa5, - 0x42, 0x13, 0x08, 0xc0, 0x02, 0xff, 0x64, 0x9f, 0x81, 0xbf, 0x8a, 0x3b, 0x3e, 0xee, 0xea, 0x13, - 0x1b, 0x1b, 0x30, 0x13, 0x7c, 0x20, 0x8b, 0x90, 0xb7, 0xb1, 0x4f, 0x9f, 0xf4, 0x0b, 0x84, 0x9c, - 0x25, 0x57, 0x19, 0x40, 0xdb, 0xf8, 0x97, 0x3c, 0x20, 0x11, 0x52, 0x48, 0xb2, 0x49, 0x38, 0xde, - 0xee, 0x1c, 0xc9, 0x22, 0x29, 0x7d, 0x89, 0x28, 0x10, 0x49, 0x22, 0xa9, 0x31, 0x70, 0x0e, 0xad, - 0xd0, 0x5a, 0x93, 0x28, 0x7c, 0x82, 0x8c, 0xfe, 0x00, 0xfb, 0x81, 0xa4, 0xe7, 0xc9, 0xa2, 0x44, - 0xf4, 0x0d, 0x6f, 0x9a, 0x24, 0x3b, 0xd2, 0xc6, 0x4c, 0x20, 0x39, 0x6c, 0x8a, 0x30, 0x9b, 0x5a, - 0x4c, 0xc4, 0x5b, 0xa6, 0xd1, 0x75, 0xb8, 0xd2, 0xc6, 0x7e, 0xfc, 0x6c, 0x82, 0x23, 0x14, 0xd0, - 0x2a, 0xac, 0x70, 0x84, 0x20, 0xb9, 0xcd, 0xdb, 0x66, 0xc8, 0x12, 0xb2, 0xdf, 0x7c, 0xd5, 0x74, - 0x20, 0x2f, 0x26, 0x40, 0xc1, 0x85, 0x2e, 0xbd, 0x48, 0xf6, 0x7f, 0x97, 0xe8, 0x3b, 0x5e, 0x3f, - 0xa8, 0xcf, 0x12, 0x5a, 0x03, 0x1f, 0x3b, 0xcf, 0xc5, 0x2d, 0x61, 0x7d, 0x8e, 0xcc, 0x52, 0x2d, - 0x14, 0xe5, 0x03, 0xcd, 0xa3, 0x6b, 0x70, 0x99, 0xfd, 0x4e, 0x48, 0x5a, 0xeb, 0x17, 0xd1, 0x15, - 0xb8, 0x14, 0x69, 0x16, 0xd6, 0x80, 0x89, 0x93, 0x88, 0x7a, 0x78, 0x7f, 0x0b, 0xe8, 0x2a, 0x94, - 0xe2, 0xe5, 0x40, 0xbc, 0x15, 0xa1, 0x1b, 0xb0, 0x2e, 0x92, 0xb8, 0xf1, 0xf4, 0x2e, 0xc7, 0x5a, - 0x24, 0x2b, 0xc7, 0x12, 0x60, 0x91, 0x08, 0x84, 0x23, 0x2c, 0xa1, 0x4f, 0xc1, 0x6b, 0x0c, 0x21, - 0xd1, 0xc1, 0xe4, 0x68, 0xcb, 0x1b, 0xdf, 0xd2, 0x60, 0x4e, 0x39, 0x6d, 0x22, 0x72, 0x2d, 0x00, - 0xbc, 0x22, 0x46, 0xbf, 0x40, 0x76, 0x5c, 0x00, 0x95, 0x6f, 0x3d, 0xe8, 0x1a, 0x19, 0x28, 0xd6, - 0x24, 0xe2, 0x47, 0x03, 0x77, 0xb0, 0xfd, 0x1c, 0x77, 0xf5, 0x1c, 0x59, 0xa5, 0x18, 0xda, 0x7d, - 0xcb, 0xee, 0x11, 0xd6, 0x97, 0xc7, 0x34, 0x4e, 0xfa, 0x7d, 0xd2, 0x71, 0x7e, 0xe3, 0x20, 0xe9, - 0xbc, 0x8b, 0x6c, 0x93, 0x02, 0x0d, 0xe7, 0x18, 0x6d, 0x11, 0x3d, 0x69, 0xb1, 0x96, 0xb6, 0xef, - 0x0c, 0x06, 0x64, 0x56, 0x1b, 0x3f, 0xd0, 0x40, 0x8f, 0x7e, 0xdd, 0x83, 0x48, 0x51, 0xa5, 0x2b, - 0x3e, 0xb8, 0xa7, 0x5f, 0x08, 0x99, 0x45, 0x80, 0x34, 0xc2, 0x51, 0x6d, 0xdf, 0x72, 0x7d, 0x01, - 0xc9, 0x11, 0x21, 0x21, 0xdd, 0x0a, 0xc0, 0x04, 0xe9, 0xe5, 0x91, 0xdd, 0xeb, 0x7d, 0xc5, 0x39, - 0x3e, 0xb0, 0x89, 0xd0, 0x5c, 0x82, 0xc5, 0x4a, 0xb7, 0x1b, 0x65, 0x21, 0x7d, 0x92, 0xf0, 0x38, - 0xeb, 0x3e, 0xd6, 0x36, 0x45, 0x25, 0x8d, 0x8c, 0x13, 0x6b, 0x9a, 0x26, 0x2f, 0x45, 0x06, 0x8c, - 0xb5, 0x14, 0x36, 0x1e, 0x2b, 0x5f, 0x3d, 0x20, 0x13, 0x09, 0x19, 0x49, 0xbf, 0x40, 0x6d, 0x6f, - 0x4b, 0x3c, 0x6a, 0xe4, 0xb1, 0x1a, 0x3c, 0xe6, 0xa8, 0xac, 0xd0, 0xa3, 0x20, 0x0e, 0x99, 0xd8, - 0x6a, 0x7c, 0xff, 0x27, 0x6b, 0x17, 0xbe, 0xf7, 0xd3, 0x35, 0xed, 0xfb, 0x3f, 0x5d, 0xd3, 0x7e, - 0xfc, 0xd3, 0xb5, 0x0b, 0x7f, 0xff, 0x1f, 0x6b, 0xda, 0x57, 0xee, 0x48, 0xff, 0x3f, 0xee, 0xd8, - 0xf2, 0x5d, 0xfb, 0xa5, 0x43, 0x1d, 0x0b, 0xf1, 0xd0, 0xc7, 0xb7, 0x06, 0x47, 0x87, 0xb7, 0x06, - 0x07, 0xb7, 0x42, 0x37, 0xe9, 0x60, 0x8a, 0x7e, 0x1d, 0xf1, 0xce, 0xff, 0x06, 0x00, 0x00, 0xff, - 0xff, 0xab, 0xab, 0xdd, 0x8c, 0x9b, 0x6e, 0x00, 0x00, + // 6266 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0xcd, 0x6f, 0x1c, 0xc9, + 0x75, 0xb8, 0x7a, 0x66, 0x48, 0x0e, 0xdf, 0x90, 0x54, 0xb3, 0x48, 0x4a, 0x23, 0x4a, 0xa2, 0xb8, + 0xb3, 0xf2, 0xae, 0x96, 0x5e, 0x53, 0xfe, 0x49, 0xde, 0xc5, 0xda, 0x3f, 0x59, 0xbb, 0xc3, 0x99, + 0x91, 0x38, 0xd2, 0x68, 0xc8, 0xed, 0x69, 0x6a, 0x6d, 0x03, 0x0b, 0xa2, 0x39, 0x53, 0xa2, 0xda, + 0x1c, 0x4e, 0x8f, 0xbb, 0x9b, 0x5a, 0xe9, 0xf7, 0x3b, 0x25, 0x88, 0x83, 0x20, 0x46, 0x82, 0x18, + 0x08, 0x12, 0x23, 0x89, 0xf3, 0x75, 0x0b, 0x72, 0xf0, 0xc5, 0xff, 0x41, 0x80, 0xc0, 0xa7, 0xc0, + 0x30, 0x90, 0x4b, 0x0e, 0x8e, 0xed, 0x5c, 0x02, 0xf8, 0x92, 0x53, 0x9c, 0x8b, 0x81, 0xa0, 0xbe, + 0xba, 0xab, 0xfa, 0x63, 0x7a, 0x86, 0xa4, 0x1d, 0x3b, 0xf0, 0x89, 0xd3, 0x55, 0xef, 0x55, 0x55, + 0x57, 0xbd, 0xef, 0xf7, 0xaa, 0x09, 0x7a, 0xdf, 0x39, 0xf4, 0xb0, 0xfb, 0xc2, 0xee, 0xe2, 0xcd, + 0xa1, 0xeb, 0xf8, 0x0e, 0x82, 0xb0, 0x65, 0xf5, 0x33, 0x87, 0xb6, 0xff, 0xfc, 0xe4, 0x60, 0xb3, + 0xeb, 0x1c, 0xdf, 0x3e, 0x74, 0x0e, 0x9d, 0xdb, 0x14, 0xe4, 0xe0, 0xe4, 0x19, 0x7d, 0xa2, 0x0f, + 0xf4, 0x17, 0x43, 0x5d, 0xbd, 0x71, 0xe8, 0x38, 0x87, 0x7d, 0x1c, 0x42, 0xf9, 0xf6, 0x31, 0xf6, + 0x7c, 0xeb, 0x78, 0xc8, 0x01, 0x16, 0x8e, 0xb1, 0x6f, 0xf5, 0x2c, 0xdf, 0xe2, 0xcf, 0x17, 0x23, + 0x00, 0x95, 0xff, 0x00, 0x98, 0xa9, 0xb5, 0x3b, 0xbe, 0xe3, 0x62, 0x84, 0xa0, 0xb0, 0xb7, 0xd7, + 0xac, 0x97, 0xb5, 0x75, 0xed, 0xd6, 0xac, 0x41, 0x7f, 0xa3, 0x37, 0x60, 0xa1, 0xc3, 0xd6, 0x56, + 0xed, 0xf5, 0x5c, 0xec, 0x79, 0xe5, 0x1c, 0xed, 0x8d, 0xb4, 0xa2, 0x35, 0x80, 0xce, 0x87, 0x2d, + 0x01, 0x93, 0xa7, 0x30, 0x52, 0x0b, 0xda, 0x04, 0xd4, 0x72, 0xba, 0x47, 0x91, 0xb1, 0x0a, 0x14, + 0x2e, 0xa1, 0x07, 0xdd, 0x84, 0x82, 0xe1, 0xf4, 0x71, 0x79, 0x7a, 0x5d, 0xbb, 0xb5, 0x70, 0x47, + 0xdf, 0x0c, 0xde, 0xa3, 0xd6, 0x26, 0xed, 0x06, 0xed, 0x25, 0x2b, 0x36, 0xed, 0xee, 0x51, 0x79, + 0x66, 0x5d, 0xbb, 0x55, 0x30, 0xe8, 0x6f, 0xf4, 0x69, 0x98, 0xea, 0xf8, 0x96, 0x8f, 0xcb, 0x45, + 0x8a, 0xba, 0xb2, 0x29, 0x6d, 0x78, 0xdb, 0xe9, 0x61, 0xda, 0x69, 0x30, 0x18, 0xf4, 0x45, 0x98, + 0x6e, 0x59, 0x07, 0xb8, 0xef, 0x95, 0x67, 0xd7, 0xf3, 0xb7, 0x4a, 0x77, 0x6e, 0xc8, 0xd0, 0x7c, + 0x5f, 0x36, 0x19, 0x44, 0x63, 0xe0, 0xbb, 0xaf, 0xb6, 0x0a, 0xdf, 0xfb, 0xe1, 0x8d, 0x0b, 0x06, + 0x47, 0x42, 0xff, 0x07, 0x66, 0x3f, 0x72, 0xdc, 0x23, 0x36, 0x1f, 0xd0, 0xf9, 0x96, 0xc2, 0xa5, + 0x06, 0x5d, 0x46, 0x08, 0x85, 0x2a, 0x30, 0xf7, 0xe1, 0x09, 0x76, 0x5f, 0x89, 0x2d, 0x28, 0xd1, + 0x2d, 0x50, 0xda, 0xd0, 0xbb, 0x00, 0x35, 0x67, 0xf0, 0xcc, 0x3e, 0xac, 0x5b, 0xbe, 0x55, 0x9e, + 0x5b, 0xd7, 0x6e, 0x95, 0xee, 0x5c, 0x52, 0x56, 0x16, 0xf4, 0x1a, 0x12, 0x24, 0x7a, 0x17, 0x8a, + 0x06, 0xf6, 0x9c, 0x13, 0xb7, 0x8b, 0xcb, 0xf3, 0x14, 0x6b, 0x59, 0xc6, 0x12, 0x7d, 0xfc, 0x25, + 0x02, 0x58, 0x74, 0x09, 0xa6, 0xf7, 0x86, 0xa6, 0x7d, 0x8c, 0xcb, 0x0b, 0xeb, 0xda, 0xad, 0xbc, + 0xc1, 0x9f, 0xd0, 0x67, 0x61, 0xa9, 0xf3, 0xdc, 0x72, 0x7b, 0x91, 0x53, 0xbb, 0x48, 0x97, 0x9c, + 0xd4, 0x85, 0x56, 0xa1, 0x58, 0x73, 0x8e, 0x8f, 0x6d, 0xbf, 0x59, 0x2f, 0xeb, 0x14, 0x2c, 0x78, + 0x46, 0x0f, 0x60, 0xed, 0xa9, 0x8d, 0x3f, 0x79, 0xc2, 0xb7, 0xa7, 0xda, 0x3b, 0xb6, 0x3d, 0xcf, + 0x76, 0x06, 0x9d, 0x93, 0xe1, 0xd0, 0x71, 0x7d, 0xdc, 0x2b, 0x2f, 0xae, 0x6b, 0xb7, 0x8a, 0x46, + 0x06, 0x14, 0xda, 0x86, 0x1b, 0x89, 0x10, 0x0f, 0xf1, 0x00, 0xbb, 0x96, 0x6f, 0x3b, 0x83, 0x32, + 0xa2, 0xf4, 0x90, 0x05, 0x86, 0xee, 0xc1, 0x15, 0x19, 0x64, 0xe7, 0x80, 0xec, 0x14, 0xee, 0x35, + 0x86, 0x4e, 0xf7, 0x79, 0x79, 0x89, 0x8e, 0x91, 0x0e, 0x80, 0xee, 0xc3, 0x6a, 0xe2, 0x04, 0x06, + 0xb6, 0x7a, 0xaf, 0xca, 0xcb, 0xf4, 0x5d, 0x46, 0x40, 0x90, 0xd9, 0xeb, 0xf5, 0xd6, 0x53, 0xdb, + 0xb3, 0x0f, 0xec, 0xbe, 0xed, 0xbf, 0xda, 0xb2, 0x5c, 0xd7, 0xc6, 0x2e, 0x43, 0x5f, 0xa1, 0xe8, + 0xe9, 0x00, 0xe8, 0x0b, 0x50, 0x96, 0xc7, 0x6e, 0x0e, 0x0e, 0xc9, 0x01, 0x30, 0xe4, 0x4b, 0x14, + 0x39, 0xb5, 0x1f, 0xd5, 0xe1, 0xba, 0x32, 0x70, 0x1d, 0x0f, 0xfb, 0xce, 0x2b, 0xdc, 0xdb, 0x25, + 0x22, 0xa1, 0xeb, 0xf4, 0xcb, 0x97, 0x29, 0x19, 0x8c, 0x06, 0x22, 0xe7, 0xa0, 0x00, 0x54, 0xbb, + 0xbe, 0xfd, 0x82, 0x6e, 0xec, 0xae, 0x8b, 0x87, 0x96, 0x8b, 0x7b, 0xe5, 0x32, 0x5d, 0x48, 0x16, + 0x58, 0x6c, 0x3d, 0x21, 0xc8, 0x03, 0x3c, 0xe8, 0xe2, 0x5e, 0xf9, 0x0a, 0x1d, 0x67, 0x34, 0x10, + 0xda, 0x85, 0x15, 0x05, 0xe0, 0x81, 0xeb, 0x0c, 0x7c, 0x1b, 0xbb, 0xe5, 0x55, 0xce, 0x0a, 0xa1, + 0xec, 0x33, 0xc5, 0x2f, 0xce, 0x0a, 0xc9, 0x88, 0xab, 0x6d, 0x28, 0x49, 0xbc, 0x8f, 0x74, 0xc8, + 0x1f, 0xe1, 0x57, 0x5c, 0x3c, 0x92, 0x9f, 0xe8, 0x2d, 0x98, 0x7a, 0x61, 0xf5, 0x4f, 0x30, 0x15, + 0x8a, 0x25, 0x99, 0xf7, 0x29, 0x5e, 0xcb, 0xf6, 0x7c, 0x83, 0x41, 0x7c, 0x21, 0xf7, 0x9e, 0xf6, + 0xa8, 0x50, 0x9c, 0xd2, 0xa7, 0x2b, 0x3f, 0xcb, 0xc3, 0x8c, 0x79, 0x0e, 0x22, 0x57, 0x08, 0xbf, + 0x7c, 0x92, 0xf0, 0x2b, 0x8c, 0x21, 0xfc, 0xde, 0x81, 0x69, 0xca, 0xc3, 0x5e, 0x79, 0x8a, 0x0a, + 0xbf, 0xcb, 0x32, 0xb4, 0xd9, 0xa6, 0x7d, 0xcd, 0xc1, 0x33, 0x47, 0x08, 0x3d, 0x06, 0x8c, 0xee, + 0xc0, 0x72, 0xcb, 0x39, 0xf4, 0x2d, 0xbb, 0x4f, 0x16, 0x84, 0x5d, 0xb1, 0xca, 0x69, 0xba, 0xca, + 0xc4, 0xbe, 0x14, 0xf1, 0x3f, 0x93, 0x2a, 0xfe, 0x55, 0x09, 0x38, 0x3b, 0xb6, 0x04, 0x8c, 0x4a, + 0x57, 0x48, 0x90, 0xae, 0x29, 0x52, 0xad, 0x94, 0x2e, 0xd5, 0x3e, 0x80, 0xab, 0xd5, 0x13, 0xdf, + 0x69, 0x0e, 0xba, 0x2e, 0x65, 0x7d, 0x4a, 0x70, 0xa1, 0xd8, 0x9a, 0xa3, 0xd4, 0x39, 0x0a, 0xe4, + 0x51, 0xa1, 0x58, 0xd4, 0x67, 0x2b, 0x7f, 0x90, 0x87, 0x62, 0xcb, 0x39, 0xfc, 0x15, 0x38, 0xfa, + 0x7b, 0x44, 0x53, 0x0c, 0xfb, 0x76, 0xd7, 0x12, 0x87, 0xbf, 0x2a, 0xc3, 0xb7, 0x9c, 0x43, 0xde, + 0x2d, 0x9d, 0x7f, 0x80, 0x11, 0x39, 0x9d, 0xe9, 0x49, 0xf4, 0x53, 0xcb, 0xe9, 0x5a, 0x84, 0xc7, + 0xe8, 0xd9, 0x47, 0xf4, 0x93, 0xe8, 0x13, 0xf3, 0x89, 0x67, 0xf4, 0x14, 0xde, 0x18, 0x29, 0x8a, + 0xc2, 0xa3, 0x28, 0xd2, 0xa3, 0x18, 0x13, 0xba, 0xf2, 0xcf, 0x05, 0x98, 0x23, 0xe7, 0x21, 0x08, + 0x1d, 0x95, 0x61, 0x86, 0x3d, 0xb0, 0x63, 0x29, 0x18, 0xe2, 0x11, 0x6d, 0x49, 0x1b, 0x96, 0xa3, + 0x1b, 0xf6, 0x46, 0x64, 0xc3, 0x82, 0x51, 0x36, 0x05, 0x20, 0x95, 0x1a, 0xd2, 0xb6, 0x2d, 0xc3, + 0x14, 0x53, 0x2d, 0xec, 0xd8, 0xd8, 0x03, 0x51, 0x99, 0x2d, 0x6c, 0xf5, 0xb0, 0xdb, 0xac, 0xd3, + 0xa3, 0x2b, 0x18, 0xc1, 0x33, 0x3d, 0x67, 0xec, 0x1e, 0x97, 0xa7, 0xf8, 0x39, 0x63, 0xf7, 0x18, + 0x7d, 0x0c, 0x8b, 0x6d, 0x67, 0xf0, 0xd4, 0xf1, 0xed, 0xc1, 0x61, 0xb0, 0xa4, 0x69, 0xba, 0xa4, + 0xdb, 0xa9, 0x4b, 0x8a, 0x61, 0xb0, 0xb5, 0xc5, 0x47, 0x42, 0x2e, 0x94, 0xf9, 0x6f, 0x4a, 0xa6, + 0xcd, 0x41, 0xd7, 0x72, 0x07, 0x54, 0xcc, 0x12, 0x7e, 0x25, 0xb3, 0xbc, 0x9b, 0xf5, 0xe2, 0x31, + 0x44, 0x36, 0x59, 0xea, 0xb8, 0xab, 0xff, 0x17, 0xe6, 0x95, 0x75, 0xc9, 0x92, 0xb6, 0xc0, 0x24, + 0xed, 0xb2, 0x2c, 0x69, 0x67, 0x25, 0xa1, 0xba, 0x5a, 0x87, 0x4b, 0xc9, 0x6f, 0x37, 0xd1, 0x28, + 0x8f, 0xe1, 0xfa, 0xc8, 0xd5, 0x4f, 0x32, 0x58, 0xe5, 0x5b, 0x1a, 0x2c, 0xa8, 0x2c, 0x84, 0x1e, + 0xa8, 0x94, 0x46, 0xc7, 0x29, 0xdd, 0x29, 0xa7, 0x6d, 0xe5, 0x56, 0x91, 0xb0, 0xc0, 0xf7, 0x7f, + 0x78, 0x43, 0x33, 0x54, 0x0a, 0xbd, 0x06, 0xb3, 0x62, 0xd8, 0x3a, 0x9d, 0xb8, 0x60, 0x84, 0x0d, + 0x68, 0x1d, 0x4a, 0x4d, 0x2f, 0xd8, 0x0d, 0x4a, 0x67, 0x45, 0x43, 0x6e, 0xaa, 0xfc, 0xbe, 0x16, + 0xda, 0x88, 0xd4, 0x5a, 0xdb, 0xdd, 0x33, 0x1d, 0xdf, 0xea, 0xf3, 0x17, 0x0b, 0x9e, 0x89, 0x24, + 0xad, 0xed, 0xee, 0x55, 0x5f, 0x58, 0x76, 0xdf, 0x3a, 0xe8, 0xb3, 0x97, 0xd4, 0x0c, 0xa5, 0x8d, + 0xe0, 0x3f, 0xc1, 0xc7, 0x0c, 0x9f, 0xd1, 0x74, 0xf0, 0x4c, 0xf0, 0x9f, 0xe0, 0xe3, 0x10, 0x9f, + 0x91, 0xb6, 0xd2, 0x56, 0xf9, 0x2d, 0x2d, 0x55, 0xf1, 0x9b, 0x96, 0x7b, 0x88, 0x7d, 0xf2, 0xba, + 0x5c, 0xf4, 0x05, 0x92, 0x32, 0x6c, 0x20, 0x4e, 0x87, 0x64, 0xf4, 0xb1, 0xdd, 0x90, 0x5a, 0x62, + 0xda, 0x20, 0x1f, 0xd7, 0x06, 0x95, 0x9f, 0xcf, 0x81, 0xce, 0x0d, 0xfd, 0x6d, 0x6c, 0xb9, 0xfe, + 0x01, 0xb6, 0xfc, 0x5f, 0x43, 0x4f, 0x68, 0x13, 0x90, 0x69, 0x79, 0x02, 0xb7, 0xe6, 0x62, 0x8b, + 0x88, 0xc3, 0x19, 0x4a, 0x00, 0x09, 0x3d, 0xb1, 0xad, 0x29, 0x26, 0x28, 0xca, 0x9b, 0x30, 0xdf, + 0x1c, 0xd8, 0x7e, 0xe8, 0xe1, 0xcc, 0x52, 0x20, 0xb5, 0x91, 0x40, 0x3d, 0x74, 0x3c, 0xcf, 0x1e, + 0xaa, 0x3a, 0x57, 0x6d, 0x24, 0xf3, 0xb1, 0x86, 0x47, 0x8e, 0x3d, 0xc0, 0x3d, 0xaa, 0x6d, 0x8b, + 0x86, 0xd2, 0xf6, 0x4b, 0x77, 0x7b, 0x52, 0x0c, 0x81, 0x85, 0xf1, 0xdc, 0x9b, 0x8b, 0x11, 0xf7, + 0xe6, 0xb3, 0xb0, 0x54, 0xed, 0x1e, 0xe1, 0x1e, 0x69, 0xb0, 0x06, 0xbd, 0x2d, 0xcb, 0xef, 0x3e, + 0xe7, 0x5e, 0x50, 0xc1, 0x48, 0xea, 0x22, 0x66, 0x05, 0x6f, 0xa9, 0xe3, 0xbe, 0xfd, 0x82, 0xec, + 0x7c, 0xf7, 0x28, 0xea, 0x0d, 0x8d, 0x02, 0x19, 0xc3, 0xa5, 0x42, 0xe7, 0xe5, 0x52, 0x2d, 0x9d, + 0x83, 0x4b, 0xb5, 0x9c, 0xe5, 0x52, 0x45, 0xde, 0xa7, 0x66, 0xf9, 0x56, 0xdf, 0x39, 0x64, 0xf6, + 0x3d, 0x1b, 0x62, 0x85, 0x0e, 0x91, 0x01, 0x85, 0xb6, 0xe0, 0x9a, 0x0c, 0x61, 0xe0, 0x67, 0x2e, + 0xf6, 0x9e, 0x87, 0xbb, 0xc2, 0x1c, 0xa4, 0x91, 0x30, 0xf1, 0x31, 0x5e, 0x58, 0x7d, 0xbb, 0x47, + 0x98, 0x87, 0xad, 0xe4, 0x32, 0x5d, 0xc9, 0x48, 0x98, 0x91, 0x4e, 0x5a, 0x39, 0xc3, 0x49, 0x1b, + 0xe9, 0x1e, 0x5e, 0xc9, 0x72, 0x0f, 0x33, 0x5d, 0xbc, 0xd5, 0x71, 0x5c, 0xbc, 0x57, 0x11, 0x17, + 0x8f, 0xbe, 0x15, 0xa3, 0x78, 0x26, 0xa0, 0xbd, 0xf2, 0x55, 0x6a, 0x13, 0xbc, 0x25, 0x33, 0xdc, + 0x48, 0x91, 0xce, 0xb9, 0x30, 0x6b, 0xdc, 0x71, 0xbc, 0xcb, 0x6b, 0xe7, 0xe4, 0x5d, 0x5e, 0x3f, + 0x93, 0x77, 0xb9, 0x76, 0x4a, 0xef, 0x92, 0x7b, 0x83, 0x26, 0xcc, 0xd5, 0xda, 0xd5, 0x7e, 0xdf, + 0xe9, 0x5a, 0x3e, 0xd1, 0x69, 0x71, 0x27, 0x73, 0x19, 0xa6, 0xa8, 0xc4, 0xe0, 0x0a, 0x8e, 0x3d, + 0x30, 0x43, 0xe0, 0x6b, 0x27, 0xd8, 0x23, 0xb2, 0x88, 0x69, 0x99, 0xb0, 0xa1, 0xf2, 0xf3, 0x02, + 0x2c, 0x0a, 0x4f, 0x63, 0xb4, 0x5a, 0x5b, 0x87, 0x92, 0x61, 0x3d, 0xf3, 0x55, 0x9d, 0x26, 0x37, + 0x25, 0x28, 0xbe, 0x7c, 0xa2, 0xe2, 0x8b, 0x29, 0x82, 0x42, 0x92, 0x22, 0x38, 0x9b, 0xe7, 0x91, + 0xac, 0xe6, 0xa6, 0x53, 0xd5, 0x9c, 0xaa, 0x52, 0x66, 0x4e, 0xe5, 0xa9, 0x14, 0x27, 0xf0, 0x54, + 0xbe, 0x00, 0xe5, 0x88, 0xbc, 0x0e, 0x85, 0xce, 0x2c, 0x63, 0xf8, 0xb4, 0xfe, 0x31, 0x84, 0x39, + 0x8c, 0x25, 0xcc, 0x37, 0x40, 0x8f, 0xda, 0xb0, 0xdc, 0xb9, 0x8d, 0xb5, 0x4f, 0xe0, 0x59, 0xcd, + 0x4d, 0xe4, 0x59, 0x35, 0xa0, 0x24, 0x05, 0x10, 0x46, 0xf8, 0x55, 0x23, 0xed, 0xd9, 0xca, 0xd7, + 0xa7, 0x40, 0x37, 0xcf, 0xd3, 0x38, 0x0b, 0x43, 0x1e, 0xf9, 0x49, 0x42, 0x1e, 0xc9, 0x64, 0x57, + 0x48, 0x25, 0xbb, 0xb4, 0x10, 0xc9, 0xd4, 0xc4, 0x21, 0x92, 0xe9, 0x31, 0x43, 0x24, 0xc5, 0x53, + 0x87, 0x48, 0x66, 0xc7, 0x0f, 0x91, 0x40, 0xba, 0x65, 0x44, 0xc4, 0x08, 0x1e, 0xf6, 0xad, 0x57, + 0xb8, 0xd7, 0xf2, 0x18, 0xbd, 0x15, 0x0c, 0xb9, 0xe9, 0xec, 0x41, 0x94, 0x34, 0x0b, 0x6b, 0xfe, + 0xd4, 0x16, 0xd6, 0x42, 0xa6, 0x85, 0xf5, 0xa8, 0x50, 0x9c, 0xd1, 0x8b, 0x95, 0xef, 0x4c, 0x41, + 0xd1, 0xe8, 0x3c, 0x61, 0x06, 0xaf, 0x0e, 0x79, 0xd3, 0x73, 0x84, 0x27, 0x68, 0x7a, 0x0e, 0x91, + 0xd0, 0xcd, 0x41, 0x0f, 0xbf, 0x14, 0x12, 0x9a, 0x3e, 0x10, 0x79, 0xd8, 0xc2, 0x96, 0x87, 0xb7, + 0x9d, 0x3e, 0xf3, 0xee, 0x99, 0x8b, 0xa4, 0x36, 0x92, 0xe3, 0x30, 0xdd, 0x93, 0x01, 0x91, 0xfe, + 0x74, 0xe7, 0xb8, 0x9f, 0x24, 0xb7, 0xa1, 0x47, 0x30, 0xc7, 0x90, 0x6c, 0xcf, 0x77, 0xdc, 0x57, + 0x5c, 0x6e, 0x2a, 0x01, 0x08, 0xb1, 0xba, 0x4d, 0x19, 0x90, 0xf9, 0xdd, 0x0a, 0x2e, 0x3b, 0xa8, + 0xaf, 0x9d, 0xd8, 0x2e, 0x9b, 0x6e, 0x5a, 0x1c, 0x54, 0xd0, 0x84, 0xde, 0x86, 0xc5, 0x8f, 0xaa, + 0x2d, 0x03, 0x77, 0x1d, 0xb2, 0x1b, 0x75, 0xfb, 0x10, 0x7b, 0x3e, 0x0f, 0xd5, 0xc5, 0x3b, 0xd0, + 0xe7, 0x60, 0x45, 0x6a, 0xa4, 0x33, 0xd6, 0x9c, 0x93, 0x81, 0x4f, 0x29, 0xb2, 0x60, 0x24, 0x77, + 0x92, 0x83, 0x91, 0x3a, 0x6a, 0xce, 0xf1, 0xb0, 0x8f, 0x89, 0xd5, 0x34, 0xf0, 0x5d, 0x1b, 0x33, + 0x9a, 0x2c, 0x18, 0xa3, 0x40, 0x08, 0xbb, 0x48, 0xdd, 0x5b, 0x96, 0x87, 0xc9, 0xeb, 0x00, 0x45, + 0x4c, 0xe8, 0x89, 0xc0, 0xb7, 0x2c, 0xcf, 0x0f, 0xe9, 0x34, 0xa1, 0x07, 0x3d, 0x82, 0x75, 0xa9, + 0x75, 0xc7, 0xb5, 0x0f, 0xed, 0x81, 0xd5, 0x57, 0x0f, 0x74, 0x8e, 0x62, 0x67, 0xc2, 0x11, 0xc2, + 0x4d, 0x78, 0x15, 0x4a, 0xb8, 0x45, 0x23, 0xa9, 0x6b, 0xf5, 0x7d, 0x58, 0x8c, 0x1d, 0x64, 0x56, + 0x08, 0xa2, 0x20, 0x87, 0x20, 0x3e, 0x86, 0x59, 0xaa, 0x4a, 0xbb, 0x8e, 0xdb, 0x23, 0x88, 0xe4, + 0x65, 0x39, 0x22, 0x79, 0xbb, 0x0d, 0x28, 0x98, 0xaf, 0x86, 0x0c, 0x6f, 0x41, 0x15, 0x1b, 0x0c, + 0x87, 0xf4, 0x1a, 0x14, 0x86, 0xc8, 0x5b, 0x2a, 0x62, 0x08, 0xf9, 0xce, 0x19, 0xf4, 0x77, 0xe5, + 0x47, 0x39, 0x00, 0x3a, 0x3e, 0x35, 0x38, 0x08, 0x48, 0xdb, 0x3a, 0xc6, 0x42, 0x24, 0x93, 0xdf, + 0xb2, 0xcc, 0xcf, 0xa9, 0x32, 0x9f, 0x2f, 0x27, 0x1f, 0x2e, 0xa7, 0x0c, 0x33, 0x4f, 0xac, 0x97, + 0x1d, 0xfb, 0xff, 0x89, 0x38, 0x81, 0x78, 0x24, 0xfa, 0x41, 0x88, 0xe5, 0x3a, 0x0f, 0x83, 0x85, + 0x0d, 0x34, 0x3e, 0xd6, 0x6e, 0xd6, 0x39, 0x15, 0xd3, 0xdf, 0xe8, 0x73, 0x90, 0x33, 0x3b, 0x5c, + 0xd5, 0xaf, 0x6e, 0xb2, 0x04, 0xe9, 0xa6, 0x48, 0x90, 0x4a, 0xb6, 0x19, 0x8d, 0xb0, 0xfc, 0xd1, + 0xbf, 0xde, 0xd0, 0x8c, 0x9c, 0xd9, 0x21, 0xca, 0xb7, 0x39, 0xe8, 0xf6, 0x4f, 0x7a, 0xb8, 0xf1, + 0x72, 0x48, 0x38, 0x81, 0x2b, 0x21, 0x2e, 0xdf, 0xb0, 0xc7, 0x43, 0x8b, 0x19, 0x50, 0xc4, 0x6c, + 0x6d, 0xbc, 0xa4, 0x10, 0xdb, 0x96, 0xdb, 0xab, 0x3b, 0x9f, 0x0c, 0x62, 0x03, 0x31, 0x3b, 0x20, + 0x0b, 0xac, 0x52, 0x01, 0x30, 0x3d, 0x47, 0xec, 0xf0, 0x32, 0x4c, 0x31, 0xb6, 0x62, 0x87, 0xc8, + 0x1e, 0x2a, 0x3f, 0xd5, 0x88, 0xf5, 0x48, 0xf5, 0x23, 0x4d, 0x38, 0x24, 0xea, 0xc6, 0xbb, 0x30, + 0xbb, 0x33, 0x94, 0x83, 0x24, 0x91, 0xe0, 0x70, 0xad, 0x4d, 0x71, 0x77, 0x86, 0x46, 0x08, 0x87, + 0xb6, 0x82, 0xc4, 0x28, 0x53, 0x94, 0x37, 0x13, 0x12, 0xa3, 0x14, 0x20, 0x3d, 0x3b, 0x7a, 0xde, + 0xe9, 0x93, 0x4a, 0x0b, 0x4a, 0xb5, 0x76, 0x18, 0x78, 0x48, 0x7a, 0xd7, 0xb7, 0x44, 0x10, 0x3c, + 0x97, 0x9e, 0x8c, 0x65, 0x10, 0x95, 0x1f, 0xf3, 0xbd, 0xb3, 0xfc, 0x11, 0x7b, 0x37, 0xfe, 0x78, + 0xd9, 0x3b, 0x26, 0x26, 0xfa, 0x25, 0xee, 0xd8, 0x37, 0x8b, 0x30, 0x23, 0x28, 0x48, 0x71, 0x18, + 0x34, 0x61, 0x69, 0xf1, 0x06, 0xb4, 0x09, 0xd3, 0x4f, 0xb0, 0xff, 0xdc, 0xe9, 0x25, 0x89, 0x04, + 0xd6, 0x43, 0x45, 0x02, 0x87, 0x42, 0xf7, 0x64, 0xfe, 0xa7, 0xac, 0x1c, 0xb1, 0x3e, 0xc2, 0x5e, + 0xfe, 0x8e, 0xb2, 0xbc, 0xa8, 0xd2, 0x68, 0x68, 0x60, 0xd2, 0x51, 0xa6, 0x2f, 0xdd, 0xb9, 0x1e, + 0x8d, 0x86, 0x2a, 0x76, 0x9f, 0xa1, 0xa0, 0xa0, 0xfb, 0x84, 0x18, 0xc2, 0x11, 0xa6, 0xe8, 0x08, + 0xd7, 0x12, 0xa8, 0x34, 0x1c, 0x40, 0x46, 0x20, 0xf8, 0xa6, 0x84, 0x3f, 0x1d, 0xc7, 0x37, 0x63, + 0xf8, 0x12, 0x02, 0x31, 0xbf, 0x42, 0xf6, 0x4c, 0xf2, 0x2c, 0xc2, 0x5e, 0x43, 0x66, 0xe4, 0x7b, + 0xaa, 0xbf, 0xc7, 0x0d, 0xb7, 0xb2, 0xba, 0xf0, 0xb0, 0xdf, 0x50, 0xbd, 0xc3, 0x7b, 0x2a, 0xbf, + 0xf3, 0xcc, 0x58, 0x39, 0x8d, 0x39, 0x0d, 0x55, 0x3a, 0x7c, 0x5e, 0x61, 0x20, 0xaa, 0x2c, 0x23, + 0x26, 0xb0, 0xd4, 0x6d, 0x28, 0xcc, 0x76, 0x4f, 0x65, 0x16, 0xaa, 0x38, 0x13, 0x26, 0x16, 0xfd, + 0x86, 0xca, 0x5a, 0xef, 0xc3, 0x7c, 0x1d, 0x13, 0xc5, 0xc6, 0x97, 0xc3, 0x83, 0x7b, 0x57, 0x94, + 0xa8, 0x81, 0x0c, 0x60, 0xa8, 0xf0, 0x68, 0x0b, 0x16, 0x76, 0x5d, 0xe7, 0xe5, 0xab, 0xf0, 0xc0, + 0xe6, 0xb9, 0x80, 0x97, 0x46, 0x50, 0x21, 0x8c, 0x08, 0x06, 0xd1, 0xc2, 0xd1, 0x44, 0x41, 0xfb, + 0xe4, 0x98, 0x1a, 0x81, 0x05, 0x23, 0xa9, 0x0b, 0x6d, 0x49, 0xa9, 0x96, 0xc0, 0x1d, 0xbc, 0x98, + 0xee, 0x0e, 0x1a, 0x71, 0x70, 0xba, 0xe7, 0xcf, 0x71, 0xf7, 0x68, 0x1b, 0x5b, 0x7d, 0xff, 0x39, + 0x0d, 0x07, 0x46, 0xf7, 0x3c, 0xec, 0x36, 0x64, 0x58, 0x64, 0xc2, 0x72, 0xa7, 0xfb, 0x1c, 0xf7, + 0x4e, 0xfa, 0x98, 0x9b, 0xa8, 0xd4, 0x48, 0xa7, 0x81, 0xc1, 0xd2, 0x9d, 0x75, 0x79, 0x8c, 0x24, + 0x38, 0x23, 0x11, 0xbb, 0xe2, 0x40, 0x89, 0x72, 0xa2, 0x37, 0x74, 0x06, 0x1e, 0x1e, 0xe1, 0x9a, + 0x71, 0x35, 0x9d, 0x53, 0xd4, 0xb4, 0x30, 0x9c, 0x98, 0xf2, 0x16, 0x8f, 0xa3, 0x92, 0x58, 0x95, + 0x4d, 0x40, 0x12, 0x3d, 0x4b, 0xf3, 0x3e, 0xb0, 0x5d, 0x49, 0x18, 0x89, 0xc7, 0xca, 0x7f, 0x16, + 0x68, 0x3c, 0x97, 0x81, 0x9d, 0xaf, 0xd4, 0xba, 0x06, 0xb3, 0x0d, 0xd7, 0x75, 0xdc, 0x9a, 0xd3, + 0xc3, 0xf4, 0x15, 0xe6, 0x8d, 0xb0, 0x81, 0x98, 0xe2, 0xf4, 0xe1, 0x09, 0xf6, 0x3c, 0xeb, 0x10, + 0xf3, 0xf8, 0x85, 0xd2, 0x86, 0xd6, 0x00, 0x9a, 0xde, 0x76, 0xf5, 0x31, 0xc6, 0x43, 0xec, 0x52, + 0xa9, 0x53, 0x34, 0xa4, 0x16, 0xf4, 0xbe, 0xb2, 0xbb, 0x5c, 0xac, 0x5c, 0x8e, 0x09, 0x46, 0xd6, + 0xcd, 0x25, 0xa3, 0x72, 0x1e, 0x84, 0xd1, 0x24, 0x27, 0x86, 0x4b, 0x16, 0x95, 0xd1, 0xa4, 0x7e, + 0x43, 0x81, 0x26, 0xd4, 0x46, 0x65, 0x0d, 0x9f, 0xbe, 0x18, 0x9f, 0x5e, 0xea, 0x36, 0x64, 0x58, + 0xc2, 0x62, 0xb5, 0xfe, 0x89, 0xe7, 0x63, 0xb7, 0x8e, 0x89, 0x77, 0xea, 0x71, 0xe1, 0xa2, 0xb0, + 0x98, 0x0a, 0x61, 0x44, 0x30, 0xd0, 0x7d, 0x98, 0x0d, 0x53, 0x5c, 0x90, 0x40, 0xa6, 0xa2, 0x93, + 0x11, 0x28, 0xf6, 0x4e, 0xfa, 0xbe, 0x11, 0xa2, 0xa0, 0xfb, 0x00, 0x92, 0x68, 0x64, 0x32, 0x66, + 0x4d, 0x1e, 0x20, 0x4e, 0x48, 0x06, 0x44, 0xc4, 0x23, 0x61, 0x20, 0xec, 0x32, 0x09, 0x37, 0x97, + 0xb0, 0x79, 0x52, 0xbf, 0xa1, 0x40, 0x57, 0x1e, 0xd1, 0x98, 0x19, 0xb3, 0x7f, 0x83, 0x6d, 0x79, + 0x87, 0x68, 0x50, 0xd2, 0xe2, 0x95, 0x35, 0xaa, 0xd7, 0x57, 0x62, 0x87, 0x49, 0x7a, 0xf9, 0x51, + 0x0a, 0xd8, 0xca, 0xeb, 0xca, 0x41, 0x10, 0xf3, 0xed, 0x29, 0xd5, 0xdb, 0xdc, 0x7c, 0xa3, 0x0f, + 0x95, 0x87, 0x30, 0x6f, 0x5a, 0xde, 0x91, 0x69, 0x1d, 0xf4, 0xf1, 0x9e, 0x87, 0x5d, 0xc2, 0x46, + 0xe4, 0xef, 0x20, 0xb4, 0xa5, 0x83, 0x67, 0xd2, 0xb7, 0x6b, 0x79, 0xde, 0x27, 0x8e, 0xdb, 0xe3, + 0xc1, 0x8d, 0xe0, 0xb9, 0xf2, 0x0d, 0x8d, 0xac, 0x92, 0xca, 0xad, 0x44, 0x33, 0x26, 0xdd, 0x16, + 0x57, 0xe2, 0x2f, 0xf9, 0x68, 0x3e, 0x31, 0xc8, 0x58, 0x17, 0xe4, 0x8c, 0xf5, 0x1a, 0xd5, 0xfd, + 0xaa, 0x51, 0x2e, 0xb5, 0x54, 0xfe, 0x2c, 0x47, 0x68, 0x78, 0xf0, 0xcc, 0x3e, 0xac, 0x3d, 0xb7, + 0x06, 0x87, 0x18, 0xdd, 0x0d, 0x56, 0xc7, 0xf3, 0x9e, 0x4b, 0xaa, 0xc3, 0x41, 0xbb, 0xc2, 0x1d, + 0x64, 0xef, 0x71, 0x0f, 0x80, 0xa1, 0x4b, 0x8e, 0xca, 0xb5, 0x78, 0x7c, 0x23, 0x84, 0x31, 0x24, + 0x78, 0x64, 0xc2, 0x42, 0x73, 0x60, 0xfb, 0xb6, 0xd5, 0x7f, 0x82, 0x8f, 0x0f, 0xb0, 0x2b, 0xac, + 0xb2, 0xb7, 0xd3, 0x46, 0xd8, 0x54, 0xc1, 0x99, 0xeb, 0x1c, 0x19, 0x63, 0xb5, 0x0a, 0x4b, 0x09, + 0x60, 0x13, 0xe5, 0x86, 0xdf, 0x82, 0xf9, 0xce, 0xf3, 0x13, 0xbf, 0xe7, 0x7c, 0x32, 0x60, 0xaa, + 0x8d, 0x9c, 0x0d, 0x0d, 0xcb, 0x89, 0x23, 0x13, 0x8f, 0x95, 0xbf, 0x9b, 0x82, 0x8b, 0x11, 0x11, + 0x9e, 0x78, 0xba, 0x37, 0x61, 0x7e, 0xcb, 0x71, 0x7c, 0xcf, 0x77, 0xad, 0xe1, 0xd0, 0x1e, 0x1c, + 0xd2, 0x49, 0x8b, 0x86, 0xda, 0x48, 0x44, 0x03, 0x8f, 0xd9, 0xd0, 0x0d, 0xcd, 0xd3, 0x0d, 0x55, + 0x44, 0x83, 0xd4, 0x6d, 0xc8, 0xb0, 0x4c, 0x26, 0x85, 0x5b, 0xc5, 0xcd, 0xb5, 0x72, 0xda, 0x56, + 0x1a, 0xea, 0xe9, 0xbf, 0x1f, 0x79, 0x63, 0x6e, 0xab, 0x5d, 0x51, 0x05, 0x83, 0x04, 0x60, 0x44, + 0x76, 0xe8, 0x31, 0x2c, 0xb2, 0xc0, 0x9a, 0x14, 0x69, 0xe3, 0x92, 0x55, 0x31, 0x19, 0x63, 0x40, + 0x46, 0x1c, 0x2f, 0x6e, 0x8a, 0xcc, 0x4c, 0x68, 0x8a, 0x3c, 0x86, 0xc5, 0x47, 0x8e, 0x3d, 0x60, + 0x51, 0x6d, 0x2e, 0xff, 0xb8, 0xa0, 0x55, 0x56, 0x13, 0x03, 0x32, 0xe2, 0x78, 0x68, 0x1b, 0x74, + 0x36, 0x3a, 0xb5, 0x55, 0xd8, 0x82, 0x66, 0xe3, 0xa6, 0x68, 0x14, 0xc6, 0x88, 0x61, 0x91, 0xe3, + 0xad, 0xf6, 0x7a, 0x82, 0x0b, 0x93, 0x6c, 0x3b, 0xa9, 0xdb, 0x90, 0x61, 0x89, 0xe4, 0x0f, 0x48, + 0x85, 0x61, 0x97, 0xe2, 0x92, 0x5f, 0x85, 0x30, 0x22, 0x18, 0x15, 0x9c, 0x6c, 0xab, 0x24, 0xd2, + 0x6b, 0x84, 0x12, 0x73, 0xe3, 0x53, 0x62, 0xe5, 0x4f, 0x72, 0x70, 0x29, 0x12, 0xae, 0x13, 0x09, + 0xa3, 0x4a, 0x60, 0x1a, 0x93, 0x49, 0x98, 0xb4, 0x9e, 0x35, 0x94, 0x36, 0x1a, 0x6c, 0x93, 0x61, + 0x72, 0x0c, 0x46, 0x6e, 0x23, 0x72, 0xb6, 0xf1, 0x92, 0x88, 0x20, 0xdb, 0xe7, 0x05, 0x14, 0xc1, + 0x33, 0x31, 0x21, 0xf9, 0x78, 0xa6, 0x7d, 0x8c, 0x9d, 0x13, 0xdf, 0xb4, 0xbb, 0x47, 0x1e, 0x97, + 0x8e, 0x49, 0x5d, 0x04, 0xc3, 0x4c, 0xc0, 0x60, 0x42, 0x33, 0xa9, 0x0b, 0x7d, 0x0e, 0x56, 0x1a, + 0x44, 0x5c, 0x58, 0x3e, 0xae, 0x9d, 0xb8, 0x2e, 0x1e, 0xf8, 0x14, 0xc6, 0xe3, 0x59, 0x8e, 0xe4, + 0xce, 0xca, 0xed, 0x04, 0xaa, 0x64, 0xaf, 0x62, 0x7b, 0xb4, 0x16, 0x84, 0x6d, 0x47, 0xf0, 0x5c, + 0xe9, 0x27, 0x30, 0x15, 0xba, 0x0b, 0x05, 0xa2, 0x6f, 0xb8, 0x94, 0x56, 0x78, 0x42, 0x51, 0x54, + 0x5c, 0x56, 0x53, 0x60, 0xba, 0xa9, 0x96, 0x77, 0x54, 0xb7, 0x7c, 0xeb, 0xc0, 0xf2, 0x84, 0xc8, + 0x53, 0xda, 0x88, 0xd4, 0x53, 0xb9, 0x28, 0x5d, 0xea, 0xbd, 0x1d, 0x67, 0x89, 0x11, 0xd0, 0x6f, + 0x2a, 0x64, 0x9f, 0x6e, 0xcd, 0x56, 0x7e, 0xa6, 0x45, 0xa9, 0xfc, 0xb4, 0x59, 0x09, 0xf4, 0x34, + 0x45, 0xb7, 0x6c, 0xa6, 0xf3, 0xcb, 0x38, 0xda, 0x85, 0xf0, 0x0a, 0x39, 0x43, 0x9e, 0x57, 0xa0, + 0xbf, 0xcf, 0x43, 0xe3, 0xfc, 0x7d, 0x5e, 0x35, 0x29, 0x83, 0xaa, 0x32, 0x4d, 0xaa, 0x2a, 0xfb, + 0x22, 0xab, 0x6c, 0xb0, 0x06, 0x3d, 0x51, 0xdf, 0x76, 0x75, 0x84, 0x7f, 0x21, 0xf2, 0x5e, 0x02, + 0x85, 0x6c, 0xa5, 0x08, 0xc7, 0x73, 0xcf, 0x40, 0x84, 0xe0, 0x6b, 0x00, 0x1c, 0x8a, 0x30, 0x5c, + 0x81, 0x0e, 0x7d, 0x7d, 0xc4, 0xd0, 0xcd, 0xba, 0x88, 0x17, 0x84, 0x68, 0xe8, 0x23, 0x58, 0x49, + 0x4c, 0x7a, 0x71, 0x55, 0xf2, 0x9a, 0x3c, 0x5e, 0x72, 0xc5, 0x75, 0x32, 0x7e, 0x76, 0x9a, 0x7c, + 0x7a, 0x9c, 0x34, 0xf9, 0xa3, 0xb4, 0xdc, 0xf0, 0x4c, 0x7a, 0x6e, 0x38, 0x25, 0x2b, 0x5c, 0xf9, + 0xf3, 0x5c, 0xca, 0xbb, 0x12, 0xa2, 0x64, 0x39, 0x6d, 0xc6, 0xce, 0x84, 0x46, 0xc2, 0x06, 0x72, + 0x02, 0x8d, 0x01, 0xe1, 0xcf, 0x1e, 0x57, 0xff, 0xe2, 0x31, 0xa5, 0xec, 0xf0, 0x0e, 0x2c, 0x07, + 0xe5, 0x0a, 0xb4, 0x24, 0x9d, 0x25, 0x00, 0x38, 0xf1, 0x25, 0xf6, 0xa1, 0x4d, 0x40, 0x09, 0x25, + 0x19, 0x4c, 0x96, 0x25, 0xf4, 0x44, 0xea, 0xb3, 0xa6, 0x63, 0xf5, 0x59, 0xcb, 0x30, 0xc5, 0xca, + 0x19, 0x58, 0x9d, 0x12, 0x7b, 0x20, 0x52, 0x8b, 0xbc, 0xb4, 0x1f, 0xd6, 0x73, 0x06, 0xcf, 0x95, + 0x7f, 0xd1, 0xd4, 0xaa, 0x8c, 0x60, 0x77, 0x84, 0x16, 0x90, 0xa5, 0xb7, 0x36, 0x9e, 0xf4, 0xce, + 0xa5, 0x4b, 0xef, 0x77, 0xe1, 0x52, 0x28, 0x85, 0x14, 0x24, 0xb6, 0x97, 0x29, 0xbd, 0xe9, 0x32, + 0xbc, 0x30, 0x4a, 0x86, 0xff, 0xc3, 0x3c, 0x94, 0xf8, 0x2a, 0xa8, 0x37, 0x24, 0xaa, 0x7c, 0x35, + 0xa9, 0xca, 0xf7, 0x7f, 0x57, 0x15, 0x5a, 0x35, 0x88, 0x99, 0x16, 0xa9, 0x60, 0x78, 0x3d, 0x21, + 0x90, 0x45, 0x2b, 0x4b, 0xc7, 0xbc, 0x82, 0x33, 0x7b, 0xaa, 0x2b, 0x38, 0x90, 0x5c, 0xfb, 0xa6, + 0x16, 0x33, 0x94, 0xc6, 0xa9, 0x6a, 0x9b, 0xcb, 0xac, 0x6a, 0x9b, 0x3f, 0x55, 0x55, 0xdb, 0xc2, + 0xa9, 0x2e, 0xf3, 0x5c, 0x1c, 0xe7, 0x32, 0x8f, 0x3e, 0x5e, 0xb5, 0xdb, 0x62, 0xa4, 0xda, 0x2d, + 0x23, 0xb3, 0x8a, 0xce, 0xa3, 0x76, 0x6d, 0xe9, 0xbc, 0x6a, 0xd7, 0x96, 0xcf, 0xa1, 0x76, 0x6d, + 0xe5, 0xec, 0xb5, 0x6b, 0x97, 0xce, 0xa5, 0x76, 0xed, 0xf2, 0x39, 0xd4, 0xae, 0x95, 0xc7, 0xa8, + 0x5d, 0x1b, 0x7d, 0xbd, 0xe9, 0x4a, 0xe6, 0xf5, 0xa6, 0x51, 0xb5, 0x6f, 0xab, 0x67, 0xa9, 0x7d, + 0xbb, 0x7a, 0xe6, 0xda, 0xb7, 0x6b, 0xe7, 0x74, 0xbd, 0xe9, 0xfa, 0x39, 0x15, 0xa0, 0xad, 0x9d, + 0xa9, 0x00, 0xed, 0xc6, 0xaf, 0xd6, 0xf5, 0xa6, 0xef, 0xe6, 0xd8, 0x8d, 0x52, 0x7e, 0xbd, 0x92, + 0x2b, 0x3e, 0x2d, 0xf9, 0x7a, 0xa5, 0xe5, 0xe3, 0x4d, 0x06, 0xa1, 0xc8, 0x76, 0xd6, 0x94, 0x7d, + 0x90, 0xb9, 0x71, 0x0e, 0x32, 0x75, 0xe3, 0xf2, 0xa7, 0xdd, 0x38, 0x03, 0x4a, 0xd2, 0xa2, 0x13, + 0x36, 0xee, 0x33, 0xea, 0xc6, 0x5d, 0x4e, 0x51, 0x6b, 0xb2, 0x95, 0xfe, 0x4f, 0x05, 0x5a, 0x32, + 0x75, 0x2e, 0xca, 0xff, 0x37, 0x55, 0x4e, 0xbf, 0xc6, 0x55, 0x4e, 0x19, 0x9a, 0x75, 0x7e, 0xdc, + 0x9a, 0xa5, 0xbf, 0xd0, 0xd8, 0x35, 0xc3, 0x4c, 0x3e, 0x34, 0xb3, 0xf8, 0xf0, 0x6c, 0xf4, 0x6e, + 0x26, 0xd3, 0xfb, 0xdf, 0xe6, 0x01, 0x24, 0x0f, 0x3f, 0x29, 0x4e, 0x24, 0x58, 0x20, 0x27, 0xb1, + 0xc0, 0x4d, 0x98, 0x27, 0x62, 0x07, 0x0f, 0x54, 0xd3, 0x56, 0x6d, 0x8c, 0x50, 0x4d, 0x61, 0x6c, + 0xaa, 0xc9, 0xb6, 0x49, 0xa6, 0xce, 0xcb, 0x26, 0x99, 0x3e, 0x07, 0x9b, 0x64, 0xe6, 0x6c, 0x57, + 0x94, 0x8b, 0x59, 0x3a, 0xbc, 0xf2, 0x37, 0x5a, 0x70, 0x48, 0x84, 0x8c, 0x3e, 0x88, 0x90, 0x51, + 0x25, 0x96, 0x7d, 0xcd, 0xa2, 0xa4, 0x0f, 0xb3, 0x28, 0xe9, 0x6d, 0x95, 0x92, 0x2e, 0x25, 0xcc, + 0xe0, 0xb8, 0x58, 0x26, 0xa4, 0x1f, 0xe4, 0xa2, 0xb9, 0xe1, 0xb4, 0x20, 0xb9, 0x4a, 0x38, 0xb9, + 0x6c, 0xc2, 0xc9, 0x9f, 0x23, 0xe1, 0x14, 0xce, 0x8b, 0x70, 0xa6, 0xce, 0x81, 0x70, 0xa6, 0x33, + 0x08, 0xa7, 0xf2, 0x9d, 0x42, 0x34, 0x1b, 0x88, 0xde, 0x81, 0x22, 0x67, 0x65, 0x71, 0xfc, 0x4b, + 0x09, 0x6c, 0x2e, 0xdc, 0x11, 0x01, 0x4a, 0xd0, 0x6a, 0x02, 0x2d, 0x17, 0x47, 0xab, 0xa9, 0x68, + 0x02, 0x14, 0xbd, 0x47, 0xeb, 0xd7, 0x38, 0x1e, 0xd3, 0x62, 0xcb, 0x49, 0xe5, 0x21, 0x1c, 0x31, + 0x04, 0x46, 0xf7, 0xa1, 0x14, 0x12, 0x8a, 0x88, 0x38, 0xa5, 0xd0, 0x91, 0x48, 0xc0, 0x4a, 0x08, + 0xa8, 0x2e, 0x42, 0x95, 0x3d, 0x3e, 0x02, 0xab, 0xb6, 0x2c, 0xc7, 0xe3, 0xf1, 0x3d, 0x79, 0x0c, + 0x15, 0x29, 0x3d, 0x62, 0x35, 0xfd, 0x8b, 0x8e, 0x58, 0xcd, 0x9c, 0xc9, 0x26, 0x2a, 0x9e, 0xd2, + 0x26, 0xaa, 0xfc, 0xae, 0x06, 0x25, 0x4e, 0x31, 0xd4, 0x7e, 0xf9, 0x3c, 0x25, 0x17, 0x66, 0x85, + 0x68, 0xdc, 0x0a, 0x09, 0xcc, 0x47, 0xde, 0xa3, 0xa4, 0x4e, 0x03, 0x70, 0x74, 0x8f, 0x9d, 0x3d, + 0xc3, 0xcd, 0xf1, 0xdd, 0x0f, 0x4d, 0x4f, 0x91, 0xc3, 0x90, 0x91, 0x43, 0x84, 0xca, 0xb7, 0x0b, + 0xb0, 0xc2, 0x43, 0xa6, 0x22, 0xf1, 0xc2, 0x4b, 0x6f, 0xde, 0x80, 0x85, 0xf6, 0xc9, 0xf1, 0xce, + 0xb3, 0x70, 0x70, 0x66, 0x5c, 0x45, 0x5a, 0x89, 0xa8, 0xa0, 0x2d, 0xc1, 0xfa, 0x99, 0x02, 0x52, + 0x1b, 0xd1, 0x06, 0xe8, 0x02, 0x2f, 0xb8, 0xd0, 0xc0, 0xa2, 0x42, 0xb1, 0x76, 0xe2, 0x93, 0xb7, + 0xf1, 0x4b, 0x3f, 0x28, 0x8e, 0xe0, 0x4f, 0xc8, 0x84, 0x12, 0xfb, 0xb5, 0xf5, 0xea, 0x31, 0x16, + 0x75, 0xbd, 0x77, 0x64, 0xda, 0x48, 0x7c, 0x93, 0x4d, 0x09, 0x89, 0x85, 0x92, 0xe5, 0x61, 0xd0, + 0xb3, 0xa4, 0xb2, 0x15, 0x76, 0x43, 0xf8, 0xbd, 0x31, 0xc6, 0x8e, 0xa2, 0x46, 0xaf, 0x0a, 0x07, + 0xa5, 0x2d, 0xd4, 0x96, 0x3b, 0x14, 0xb9, 0x36, 0x5e, 0xc2, 0x2a, 0xa2, 0x3d, 0xf1, 0x9e, 0xd5, + 0xfb, 0xa0, 0x47, 0x17, 0x9e, 0x7c, 0xdd, 0x25, 0xb9, 0xa6, 0x55, 0xb9, 0xe9, 0xab, 0x2c, 0x2e, + 0x6b, 0x14, 0x25, 0x1c, 0xfe, 0x73, 0x0d, 0xae, 0x18, 0xd8, 0x63, 0xf9, 0x83, 0x8f, 0x2c, 0x1f, + 0xbb, 0xc7, 0x96, 0x7b, 0x24, 0x68, 0x24, 0x3c, 0x29, 0x4d, 0x39, 0xa9, 0x2f, 0xa9, 0x27, 0x95, + 0x8b, 0xdf, 0x84, 0x4e, 0x1d, 0x33, 0xe3, 0xb4, 0x92, 0x77, 0x31, 0xff, 0x8b, 0xda, 0xc5, 0xca, + 0x7f, 0xf1, 0x4b, 0xef, 0x23, 0x3d, 0x8d, 0xdf, 0xdc, 0x0a, 0xfa, 0xcd, 0xad, 0xa0, 0xf3, 0xbf, + 0x15, 0xf4, 0xdd, 0x1c, 0xff, 0xfe, 0x05, 0x31, 0x26, 0xef, 0x07, 0x4e, 0x2a, 0x53, 0x0f, 0xeb, + 0x31, 0xf5, 0x4e, 0x4d, 0x49, 0x0a, 0xa2, 0x9a, 0x92, 0x4c, 0xfe, 0xde, 0x0f, 0x8c, 0xd1, 0xdc, + 0x28, 0xfc, 0x54, 0x53, 0xb4, 0x03, 0x25, 0x69, 0xf0, 0x84, 0x8c, 0xda, 0xa6, 0x6a, 0x8a, 0xa6, + 0xde, 0xd5, 0x97, 0x45, 0x54, 0x27, 0xcb, 0xbe, 0xcd, 0x1a, 0x34, 0xc9, 0x55, 0xfa, 0xf7, 0xa2, + 0x5a, 0xd6, 0x94, 0xc8, 0xb1, 0xef, 0x2b, 0xea, 0x37, 0x31, 0xf0, 0x10, 0x76, 0x0b, 0xbb, 0x47, + 0x56, 0xd8, 0x77, 0x03, 0x77, 0x91, 0xdb, 0xbd, 0x4b, 0x09, 0x4e, 0xa2, 0x28, 0xd2, 0x11, 0x8e, + 0xe5, 0xbb, 0xe1, 0x81, 0x72, 0x37, 0x6b, 0x39, 0xe9, 0x18, 0x42, 0x8e, 0xe0, 0x87, 0x7f, 0x37, + 0x88, 0x11, 0xf1, 0x14, 0xde, 0x52, 0x42, 0x64, 0x48, 0x4c, 0x26, 0xa2, 0x49, 0xb7, 0x45, 0x31, + 0x36, 0x4b, 0x42, 0x28, 0xe9, 0x69, 0x51, 0x80, 0xa7, 0x94, 0x64, 0xb7, 0xb9, 0x5c, 0xe0, 0x19, + 0x46, 0x5e, 0x14, 0x36, 0x43, 0xb1, 0xd7, 0xa2, 0xc9, 0x6d, 0x15, 0xca, 0x48, 0xc0, 0x44, 0x8d, + 0x48, 0xbd, 0x16, 0x17, 0x02, 0x99, 0x79, 0xf2, 0x48, 0x95, 0x97, 0xd0, 0x31, 0x3d, 0x7e, 0xcf, + 0x85, 0x3f, 0xa1, 0xc7, 0xaa, 0x8e, 0x81, 0xf8, 0xcd, 0x5a, 0x99, 0x0a, 0x32, 0xd4, 0xca, 0x3d, + 0xd9, 0x73, 0xe3, 0x05, 0x1d, 0x97, 0x92, 0xfd, 0x35, 0x91, 0x70, 0x95, 0x3c, 0x3d, 0x39, 0xf9, + 0x30, 0x37, 0xd9, 0x95, 0xfa, 0xa4, 0x1a, 0xdb, 0xf9, 0xf4, 0x1a, 0xdb, 0xed, 0x24, 0x63, 0x65, + 0x21, 0x53, 0xb8, 0x26, 0x98, 0x23, 0xf7, 0xe0, 0x4a, 0x5c, 0x5d, 0xee, 0xe2, 0x41, 0xcf, 0x1e, + 0x1c, 0xd2, 0x5c, 0x48, 0xd1, 0x48, 0x07, 0x40, 0x5b, 0x70, 0x4d, 0x51, 0xdd, 0x54, 0x99, 0x4b, + 0x6e, 0x17, 0xbb, 0xc7, 0x3f, 0x12, 0x86, 0xb8, 0xdb, 0x09, 0x13, 0x88, 0x68, 0x31, 0xbb, 0xcf, + 0x3f, 0x02, 0x02, 0x7d, 0x00, 0x57, 0xe3, 0xbd, 0xc1, 0xcd, 0x27, 0x91, 0x54, 0x19, 0x01, 0x72, + 0x66, 0xe3, 0xe0, 0x0f, 0x35, 0x98, 0x93, 0x1d, 0x99, 0x44, 0x57, 0xfa, 0x1a, 0xcc, 0xb2, 0x94, + 0xa7, 0xa8, 0xde, 0x99, 0x35, 0xc2, 0x06, 0x54, 0x86, 0x19, 0xd5, 0x22, 0x10, 0x8f, 0x52, 0x66, + 0xaa, 0xa0, 0x64, 0xa6, 0x56, 0xa1, 0x58, 0x77, 0x3e, 0x19, 0xd0, 0x9e, 0x29, 0xda, 0x13, 0x3c, + 0x57, 0xfe, 0xb4, 0x02, 0xba, 0xe0, 0xed, 0xe0, 0x06, 0x5e, 0x70, 0xdf, 0x4e, 0x93, 0xef, 0xdb, + 0x25, 0x85, 0x8b, 0x42, 0x73, 0x2e, 0xaf, 0x98, 0x73, 0x3b, 0x2a, 0xab, 0x31, 0x27, 0xf1, 0x33, + 0x49, 0x02, 0x25, 0xb8, 0x58, 0x37, 0x9a, 0xdd, 0x92, 0xbe, 0xd4, 0xf3, 0x3f, 0x2e, 0xaf, 0x7a, + 0xa0, 0x47, 0xaa, 0x2b, 0x44, 0xa2, 0xf5, 0xce, 0xc8, 0x57, 0x8d, 0x22, 0xc9, 0xea, 0x33, 0x36, + 0x22, 0x6a, 0xca, 0xee, 0x1a, 0xfb, 0x8c, 0xe2, 0xa7, 0x47, 0x0e, 0x1f, 0x40, 0xb3, 0x7d, 0x0c, + 0xb1, 0x65, 0xb5, 0x00, 0x63, 0xab, 0x05, 0x49, 0x71, 0x95, 0x4e, 0xa5, 0xb8, 0xe6, 0x26, 0x50, + 0x5c, 0x11, 0x35, 0x3b, 0x3f, 0xb1, 0x9a, 0x8d, 0xe9, 0x90, 0x85, 0x53, 0xe9, 0x10, 0x55, 0xbc, + 0x5f, 0x9c, 0x50, 0xbc, 0xc7, 0x62, 0x1c, 0xfa, 0x69, 0x62, 0x1c, 0x29, 0xc2, 0x7e, 0x71, 0x42, + 0x61, 0x8f, 0xce, 0x5d, 0xd8, 0x2f, 0x9d, 0x55, 0xd8, 0x2f, 0x9f, 0x59, 0xd8, 0xaf, 0x9c, 0x55, + 0xd8, 0x5f, 0xca, 0x14, 0xf6, 0xe8, 0xdd, 0x58, 0x2d, 0xa4, 0xa8, 0x00, 0x62, 0x39, 0xe2, 0x94, + 0xde, 0x04, 0x77, 0x24, 0xac, 0x2b, 0x2a, 0x27, 0xba, 0x23, 0x61, 0x99, 0xd1, 0x57, 0x61, 0x39, + 0xd2, 0x27, 0xf2, 0xc1, 0x31, 0x87, 0x38, 0xc6, 0xf7, 0x49, 0x88, 0x4c, 0x04, 0x24, 0x8e, 0x89, + 0x86, 0xb1, 0xf7, 0xab, 0xb5, 0x45, 0xfe, 0x38, 0x16, 0xcc, 0xc8, 0x9a, 0x8d, 0xa3, 0xb2, 0xf9, + 0x52, 0xc6, 0x4d, 0x98, 0xd1, 0x6c, 0x8b, 0xa4, 0xf3, 0xc4, 0x33, 0x9a, 0xa3, 0x66, 0xe4, 0x9d, + 0x68, 0x1b, 0x6e, 0x44, 0x7a, 0x78, 0xe1, 0x9c, 0x57, 0xf5, 0x3c, 0xfb, 0x70, 0x10, 0x7e, 0xe6, + 0x24, 0x03, 0x0c, 0xb5, 0xe0, 0xb5, 0xe8, 0x5b, 0x05, 0x05, 0x74, 0xc1, 0x58, 0x2c, 0x63, 0x9d, + 0x0d, 0x98, 0xea, 0x76, 0x86, 0x94, 0xb2, 0x36, 0xc2, 0xed, 0x0c, 0xe9, 0x65, 0x2b, 0xa5, 0x5e, + 0x4b, 0x50, 0xea, 0x8d, 0x78, 0x35, 0x43, 0x14, 0x26, 0x35, 0x8b, 0xc1, 0x62, 0xd9, 0xeb, 0x94, + 0x57, 0x47, 0x40, 0xa0, 0x47, 0xb0, 0x9e, 0x58, 0xe9, 0x20, 0x97, 0xbd, 0xbd, 0x46, 0xd7, 0x91, + 0x09, 0x37, 0x46, 0x95, 0x47, 0x65, 0xac, 0x2a, 0x8f, 0xaf, 0x6b, 0x70, 0x3d, 0x71, 0xc9, 0x34, + 0xd4, 0x41, 0x28, 0xee, 0x75, 0x4a, 0x71, 0xef, 0x8f, 0xa4, 0xb8, 0x91, 0x23, 0x30, 0xc2, 0x1b, + 0x3d, 0x0b, 0xfa, 0xed, 0xb4, 0x82, 0x3a, 0xc1, 0x6a, 0x37, 0xe9, 0x32, 0xee, 0x4f, 0xbe, 0x0c, + 0x85, 0xe1, 0x46, 0xce, 0x81, 0xbe, 0xa1, 0xa5, 0xa4, 0x3d, 0xa8, 0xca, 0x62, 0xeb, 0xf8, 0x14, + 0x5d, 0x47, 0x75, 0xf2, 0x75, 0x84, 0x63, 0xb0, 0xa5, 0x64, 0xcd, 0x84, 0x7e, 0x4f, 0x4b, 0xa1, + 0xfd, 0x5a, 0x5b, 0x7c, 0xf4, 0xe8, 0x0d, 0xba, 0x98, 0x0f, 0x4e, 0xb3, 0x29, 0x7c, 0x08, 0xb6, + 0x96, 0x8c, 0x79, 0xd0, 0x37, 0x35, 0x78, 0x2d, 0x7d, 0xb9, 0x62, 0x35, 0x6f, 0xd2, 0xd5, 0xd4, + 0x4e, 0xb9, 0x35, 0xca, 0x82, 0xb2, 0x67, 0x4b, 0xe5, 0x68, 0xa1, 0x7c, 0x6f, 0x8d, 0xe0, 0x68, + 0xa1, 0x7f, 0xff, 0x58, 0x83, 0xca, 0xc8, 0x57, 0x67, 0x45, 0x96, 0x6f, 0xd1, 0x17, 0xab, 0x9f, + 0x7e, 0x9b, 0xe9, 0x30, 0xec, 0xcd, 0xc6, 0x98, 0x0f, 0x7d, 0x5b, 0x83, 0x4f, 0x65, 0x6d, 0x00, + 0x5b, 0xd9, 0x06, 0x5d, 0xd9, 0xc3, 0x33, 0x6d, 0xb9, 0xb4, 0xb8, 0xf1, 0x66, 0x3d, 0x73, 0x00, + 0xfd, 0x63, 0x58, 0x49, 0x34, 0xed, 0x27, 0x8c, 0x53, 0x29, 0xf7, 0x0f, 0xa5, 0xe1, 0xef, 0xd1, + 0xaf, 0x5e, 0xa6, 0x04, 0xd5, 0x32, 0x17, 0xf7, 0x10, 0xae, 0xa4, 0x1a, 0x08, 0x59, 0x03, 0x15, + 0xe5, 0x81, 0x9a, 0xb1, 0x02, 0x0a, 0x59, 0x14, 0x9d, 0x71, 0x28, 0xf3, 0xb4, 0x43, 0xed, 0xa6, + 0x50, 0xbc, 0x22, 0xad, 0x27, 0x1a, 0x71, 0x27, 0x45, 0x36, 0x9c, 0xfa, 0x6d, 0x0d, 0xb8, 0x39, + 0x8e, 0x04, 0x9d, 0x68, 0xcc, 0x0f, 0xe1, 0xf5, 0x31, 0x04, 0xe1, 0x44, 0x84, 0x62, 0xc2, 0x1b, + 0xe3, 0x49, 0xb3, 0x89, 0x46, 0xdd, 0x83, 0x37, 0xc7, 0x14, 0x25, 0x13, 0x0d, 0xfb, 0x25, 0xd8, + 0x18, 0x5f, 0x0e, 0x4c, 0x14, 0xaa, 0x69, 0xb2, 0x5a, 0x24, 0xf1, 0x81, 0xd9, 0x33, 0x7c, 0x15, + 0xab, 0xf2, 0x97, 0x39, 0x58, 0x4e, 0xba, 0x9a, 0x3b, 0xe2, 0x86, 0xcc, 0x6e, 0xec, 0x7b, 0xc8, + 0x9b, 0x59, 0x17, 0x7d, 0xd5, 0xef, 0x22, 0xc7, 0x92, 0x38, 0xe7, 0xf2, 0x75, 0xe4, 0x55, 0x33, + 0xfb, 0x53, 0xc2, 0xa3, 0x8a, 0x95, 0xa4, 0x1d, 0x95, 0xf7, 0xfa, 0x3b, 0x1a, 0xc0, 0x96, 0xd5, + 0x3d, 0x3a, 0x19, 0xd2, 0x3c, 0x50, 0x5a, 0x92, 0xb0, 0x99, 0x94, 0x24, 0x7c, 0x53, 0xb9, 0x15, + 0x14, 0x0c, 0x32, 0x3a, 0x9e, 0x74, 0xe6, 0x40, 0xde, 0xef, 0x68, 0x22, 0xc7, 0xd5, 0xf4, 0xf1, + 0x71, 0xe2, 0x07, 0x7a, 0x2a, 0x30, 0xc7, 0xef, 0x1f, 0x3c, 0x95, 0x32, 0xa5, 0x4a, 0x1b, 0x81, + 0xa9, 0xe3, 0x67, 0xd6, 0x49, 0x9f, 0xc3, 0xf0, 0x2f, 0xe8, 0xca, 0x6d, 0xe4, 0x88, 0x9a, 0x03, + 0x1f, 0xbb, 0x03, 0xab, 0xcf, 0x93, 0x7b, 0xc1, 0x73, 0xe5, 0xaf, 0x34, 0x39, 0xd5, 0x86, 0xbe, + 0x08, 0x33, 0x35, 0x67, 0xe0, 0x63, 0xfa, 0x1d, 0x9b, 0x78, 0xc1, 0x7f, 0x00, 0xb8, 0xc9, 0xa1, + 0xd8, 0xc6, 0x08, 0x9c, 0x55, 0x83, 0xde, 0x43, 0x0d, 0x3a, 0x26, 0x2c, 0x1f, 0x0a, 0xb7, 0x43, + 0xde, 0xa8, 0xff, 0x1f, 0xe6, 0xf4, 0xd0, 0x3b, 0xe1, 0x2d, 0xed, 0x58, 0x95, 0x9c, 0x00, 0xda, + 0xa4, 0x10, 0x6c, 0x61, 0x0c, 0x7a, 0xf5, 0x3d, 0x80, 0xb0, 0x71, 0xa2, 0x5c, 0xf4, 0x9b, 0xca, + 0xc7, 0x21, 0x46, 0xdc, 0x5e, 0xfb, 0x18, 0x16, 0x63, 0xf7, 0xa4, 0xd0, 0x4d, 0x98, 0x67, 0xdf, + 0x9b, 0x12, 0x57, 0xaf, 0x18, 0x92, 0xda, 0x48, 0x8f, 0x99, 0xa3, 0x48, 0xdf, 0x28, 0x53, 0xda, + 0x36, 0x3e, 0x01, 0xd8, 0x1b, 0xf6, 0x2c, 0x9f, 0x45, 0x70, 0x2f, 0xc3, 0x92, 0xf2, 0xfd, 0x2a, + 0xd6, 0xa5, 0x5f, 0x40, 0x2b, 0xb0, 0x28, 0xbe, 0x4b, 0xd6, 0xea, 0xb4, 0x79, 0xb3, 0x86, 0x96, + 0xe0, 0xe2, 0x9e, 0x87, 0x5d, 0xfa, 0xfa, 0xbc, 0x31, 0x87, 0xe6, 0x61, 0xd6, 0xec, 0xec, 0xf0, + 0xc7, 0x3c, 0x41, 0x0d, 0xbe, 0x31, 0x16, 0xa0, 0x16, 0x36, 0x36, 0x61, 0x36, 0xf8, 0x36, 0x3d, + 0xba, 0x08, 0xa5, 0xb6, 0xe3, 0x1e, 0x5b, 0x7d, 0xfa, 0xa8, 0x5f, 0x40, 0x3a, 0xcc, 0xf1, 0x6b, + 0x35, 0xac, 0x45, 0xdb, 0xf8, 0x69, 0x01, 0x20, 0xfc, 0xae, 0x03, 0x5a, 0x00, 0x30, 0x3b, 0x3b, + 0xfb, 0x7b, 0xbb, 0xf5, 0xaa, 0xd9, 0xd0, 0x2f, 0x20, 0x80, 0xe9, 0xea, 0xee, 0x6e, 0xa3, 0x5d, + 0xd7, 0x35, 0x54, 0x84, 0x82, 0xd1, 0xa8, 0xd6, 0xf5, 0x1c, 0x9a, 0x83, 0xa2, 0x69, 0xec, 0xb5, + 0x6b, 0x04, 0x26, 0x4f, 0x06, 0x7d, 0xd8, 0x30, 0xf7, 0x83, 0x96, 0x02, 0x2a, 0xc1, 0x4c, 0x6d, + 0xa7, 0xdd, 0x6e, 0xd4, 0x4c, 0x7d, 0x8a, 0x0c, 0xc9, 0x1f, 0xf6, 0x8d, 0x1d, 0x7d, 0x1a, 0x2d, + 0xc2, 0x7c, 0x6b, 0xe7, 0xe1, 0xfe, 0x76, 0xa3, 0x6a, 0x98, 0x5b, 0x8d, 0xaa, 0xa9, 0xcf, 0x90, + 0x11, 0x6a, 0x6d, 0xa9, 0xa5, 0x48, 0x17, 0x2a, 0xb7, 0xcc, 0x22, 0x04, 0x0b, 0xb5, 0xed, 0x46, + 0xed, 0xf1, 0xfe, 0x76, 0xf5, 0x71, 0xa3, 0xb1, 0xdb, 0x30, 0x74, 0x20, 0xfb, 0x4a, 0x66, 0xae, + 0xb5, 0xf6, 0x3a, 0x66, 0xc3, 0xd8, 0xaf, 0x37, 0xcc, 0x6a, 0xb3, 0xd5, 0xd1, 0x4b, 0x04, 0x98, + 0x74, 0x74, 0xb6, 0xab, 0x46, 0x7d, 0xbf, 0xd9, 0x7e, 0xb0, 0xa3, 0xcf, 0xd1, 0x01, 0xda, 0xfb, + 0xd5, 0x56, 0x6b, 0x87, 0xac, 0x72, 0xbf, 0x59, 0xd7, 0xe7, 0xc9, 0x26, 0xca, 0x03, 0x74, 0x4c, + 0xb2, 0xfe, 0x05, 0xba, 0xff, 0x74, 0x07, 0xf6, 0x6b, 0xed, 0xfd, 0x56, 0x75, 0xab, 0xd1, 0xd2, + 0x2f, 0xa2, 0x32, 0x2c, 0x87, 0x8d, 0x1f, 0xed, 0x18, 0x8f, 0x39, 0xb8, 0x4e, 0x46, 0xde, 0xad, + 0x9a, 0xb5, 0x6d, 0xd2, 0xd1, 0x31, 0x77, 0x8c, 0x86, 0xbe, 0x48, 0x86, 0xa8, 0x37, 0x5a, 0x0d, + 0x06, 0xcd, 0x1a, 0x11, 0x69, 0xdc, 0x35, 0x76, 0xbe, 0xf4, 0x65, 0xe9, 0xc5, 0x96, 0xd0, 0x6b, + 0x70, 0x9d, 0x8f, 0xdb, 0xde, 0x69, 0xef, 0x3f, 0xdd, 0x31, 0x9b, 0xed, 0x87, 0xfb, 0x46, 0x63, + 0xb7, 0xd5, 0xac, 0x55, 0xf7, 0xdb, 0x7b, 0x4f, 0xf4, 0x65, 0xb4, 0x06, 0xab, 0x71, 0x10, 0xf2, + 0x1e, 0xad, 0xa6, 0xf9, 0x65, 0x7d, 0x05, 0x2d, 0x83, 0xde, 0x69, 0x98, 0xfb, 0x46, 0xe3, 0xc3, + 0xbd, 0xa6, 0xd1, 0xa8, 0xef, 0xb7, 0x3a, 0x6d, 0xfd, 0x12, 0x69, 0x7d, 0x18, 0x6d, 0xbd, 0x2c, + 0xb6, 0xa6, 0x55, 0x35, 0x1b, 0x1d, 0x93, 0xb6, 0x95, 0xc9, 0x91, 0xd0, 0xb6, 0x46, 0xb5, 0xde, + 0x30, 0xc8, 0xce, 0x5c, 0xa1, 0x47, 0xc2, 0xb6, 0xbb, 0x51, 0x6d, 0x99, 0xdb, 0xfa, 0x2a, 0x39, + 0x74, 0x72, 0xfc, 0x14, 0xe5, 0x2a, 0xba, 0x02, 0x2b, 0x7c, 0x49, 0xad, 0x46, 0xb5, 0xd3, 0xd8, + 0xde, 0x69, 0x71, 0xd4, 0x6b, 0xa4, 0x8b, 0x6e, 0x7e, 0x6d, 0xbb, 0x51, 0xdf, 0x6b, 0x35, 0xf6, + 0x6b, 0x3b, 0x4f, 0x9e, 0x54, 0xdb, 0xf5, 0x8e, 0x7e, 0x7d, 0xa3, 0x0d, 0x10, 0x7e, 0x0d, 0x8d, + 0x50, 0x06, 0x21, 0x73, 0xd6, 0xa2, 0x5f, 0x20, 0x33, 0x08, 0x39, 0xa7, 0x6b, 0x84, 0x78, 0x29, + 0xd3, 0x04, 0x0c, 0xb0, 0xc8, 0x3f, 0xff, 0x67, 0xe0, 0xaf, 0xe2, 0xae, 0x8f, 0x7b, 0x7a, 0x7e, + 0x63, 0x03, 0x66, 0x83, 0x8f, 0x6d, 0x11, 0xf4, 0x0e, 0xf6, 0xe9, 0x93, 0x7e, 0x81, 0xa0, 0xb3, + 0xe0, 0x2a, 0x6b, 0xd0, 0x36, 0xfe, 0xb1, 0x00, 0x48, 0xb8, 0x14, 0x12, 0x6f, 0x12, 0x8a, 0xb7, + 0xbb, 0x47, 0x32, 0x4b, 0x4a, 0x5f, 0x35, 0x0a, 0x58, 0x92, 0x70, 0x6a, 0xac, 0x39, 0x87, 0x2e, + 0xd1, 0x5a, 0x93, 0x68, 0x7b, 0x9e, 0xcc, 0xfe, 0x10, 0xfb, 0x01, 0xa7, 0x17, 0xc8, 0xa6, 0x44, + 0xe4, 0x0d, 0xef, 0x9a, 0x22, 0x27, 0xd2, 0xc1, 0x8c, 0x21, 0x79, 0xdb, 0x34, 0x21, 0x36, 0xb5, + 0x98, 0x88, 0xf7, 0xcc, 0xa0, 0x1b, 0x70, 0xb5, 0x83, 0xfd, 0x78, 0x6e, 0x82, 0x03, 0x14, 0xd1, + 0x2a, 0x5c, 0xe2, 0x00, 0x41, 0x70, 0x9b, 0xf7, 0xcd, 0x92, 0x2d, 0x64, 0xbf, 0xf9, 0xae, 0xe9, + 0x40, 0x5e, 0x4c, 0x34, 0x05, 0x17, 0xba, 0xf4, 0x12, 0x39, 0xff, 0x5d, 0x22, 0xef, 0x78, 0xfd, + 0xa0, 0x3e, 0x47, 0x70, 0x0d, 0x7c, 0xec, 0xbc, 0x10, 0x37, 0x8e, 0xf5, 0x79, 0xb2, 0x4a, 0xb5, + 0x50, 0x94, 0x4f, 0xb4, 0x80, 0xae, 0xc3, 0x15, 0xf6, 0x3b, 0x21, 0x68, 0xad, 0x5f, 0x44, 0x57, + 0xe1, 0x72, 0xa4, 0x5b, 0x68, 0x03, 0xc6, 0x4e, 0xc2, 0xeb, 0xe1, 0xe3, 0x2d, 0xa2, 0x6b, 0x50, + 0x8e, 0x97, 0x03, 0xf1, 0x5e, 0x84, 0x6e, 0xc2, 0xba, 0x08, 0xe2, 0xc6, 0xc3, 0xbb, 0x1c, 0x6a, + 0x89, 0xec, 0x1c, 0x0b, 0x80, 0x45, 0x3c, 0x10, 0x0e, 0xb0, 0x8c, 0x3e, 0x05, 0xaf, 0x31, 0x80, + 0x44, 0x03, 0x93, 0x83, 0xad, 0x6c, 0x7c, 0x4b, 0x83, 0x79, 0x25, 0xdb, 0x44, 0xf8, 0x5a, 0x34, + 0xf0, 0x8a, 0x18, 0xfd, 0x02, 0x39, 0x71, 0xd1, 0xa8, 0x7c, 0x37, 0x42, 0xd7, 0xc8, 0x44, 0xb1, + 0x2e, 0xe1, 0x3f, 0x1a, 0xb8, 0x8b, 0xed, 0x17, 0xb8, 0xa7, 0xe7, 0xc8, 0x2e, 0xc5, 0xc0, 0x1e, + 0x58, 0x76, 0x9f, 0x90, 0xbe, 0x3c, 0xa7, 0x71, 0x32, 0x18, 0x90, 0x81, 0x0b, 0x1b, 0x07, 0x49, + 0xf9, 0x2e, 0x72, 0x4c, 0x4a, 0x6b, 0xb8, 0xc6, 0x68, 0x8f, 0x18, 0x49, 0x8b, 0xf5, 0x74, 0x7c, + 0x67, 0x38, 0x24, 0xab, 0xda, 0xf8, 0x81, 0x06, 0x7a, 0xf4, 0x4b, 0x21, 0x84, 0x8b, 0xaa, 0x3d, + 0xf1, 0xf1, 0x3e, 0xfd, 0x42, 0x48, 0x2c, 0xa2, 0x49, 0x23, 0x14, 0xd5, 0xf1, 0x2d, 0xd7, 0x17, + 0x2d, 0x39, 0xc2, 0x24, 0x64, 0x58, 0xd1, 0x90, 0x27, 0xa3, 0x3c, 0xb6, 0xfb, 0xfd, 0xaf, 0x38, + 0xc7, 0x07, 0x36, 0x61, 0x9a, 0xcb, 0xb0, 0x54, 0xed, 0xf5, 0xa2, 0x24, 0xa4, 0x4f, 0x11, 0x1a, + 0x67, 0xc3, 0xc7, 0xfa, 0xa6, 0x29, 0xa7, 0x91, 0x79, 0x62, 0x5d, 0x33, 0xe4, 0xa5, 0xc8, 0x84, + 0xb1, 0x9e, 0xe2, 0xc6, 0x13, 0xe5, 0x0b, 0x0a, 0x64, 0x21, 0x21, 0x21, 0xe9, 0x17, 0xa8, 0xee, + 0x6d, 0x8b, 0x47, 0x8d, 0x3c, 0xd6, 0x82, 0xc7, 0x1c, 0xe5, 0x15, 0x9a, 0x0a, 0xe2, 0x2d, 0xf9, + 0xad, 0xe6, 0xf7, 0x7f, 0xbc, 0x76, 0xe1, 0x7b, 0x3f, 0x59, 0xd3, 0xbe, 0xff, 0x93, 0x35, 0xed, + 0x47, 0x3f, 0x59, 0xbb, 0xf0, 0xd7, 0xff, 0xb6, 0xa6, 0x7d, 0xe5, 0xae, 0xf4, 0xbf, 0xe8, 0x8e, + 0x2d, 0xdf, 0xb5, 0x5f, 0x3a, 0xd4, 0xb0, 0x10, 0x0f, 0x03, 0x7c, 0x7b, 0x78, 0x74, 0x78, 0x7b, + 0x78, 0x70, 0x3b, 0x34, 0x93, 0x0e, 0xa6, 0xe9, 0x97, 0x16, 0xef, 0xfe, 0x77, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xd7, 0xd9, 0xa2, 0x6b, 0xe7, 0x6e, 0x00, 0x00, } func (m *CNStore) Marshal() (dAtA []byte, err error) { @@ -10188,6 +10199,18 @@ func (m *CommandBatch) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.DDLVisibilityFrontier != nil { + { + size, err := m.DDLVisibilityFrontier.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLogservice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } if m.DDLVisibilityDeployedProtocol != 0 { i = encodeVarintLogservice(dAtA, i, uint64(m.DDLVisibilityDeployedProtocol)) i-- @@ -14253,6 +14276,10 @@ func (m *CommandBatch) ProtoSize() (n int) { if m.DDLVisibilityDeployedProtocol != 0 { n += 1 + sovLogservice(uint64(m.DDLVisibilityDeployedProtocol)) } + if m.DDLVisibilityFrontier != nil { + l = m.DDLVisibilityFrontier.ProtoSize() + n += 1 + l + sovLogservice(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -24318,6 +24345,42 @@ func (m *CommandBatch) Unmarshal(dAtA []byte) error { break } } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DDLVisibilityFrontier", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLogservice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLogservice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLogservice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DDLVisibilityFrontier == nil { + m.DDLVisibilityFrontier = ×tamp.Timestamp{} + } + if err := m.DDLVisibilityFrontier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipLogservice(dAtA[iNdEx:]) diff --git a/pkg/queryservice/client/query_client.go b/pkg/queryservice/client/query_client.go index 77770e5c0364d..b4d4de28e8525 100644 --- a/pkg/queryservice/client/query_client.go +++ b/pkg/queryservice/client/query_client.go @@ -63,7 +63,7 @@ var methodVersions = map[pb.CmdMethod]int64{ pb.CmdMethod_ISCPDrainConsumer: defines.MORPCVersion4, pb.CmdMethod_IcebergCacheInvalidate: defines.MORPCVersion4, pb.CmdMethod_MongoDBClientRetire: defines.MORPCVersion5, - pb.CmdMethod_SyncCommitV2: defines.MORPCVersion43, + pb.CmdMethod_SyncCommitV2: defines.MORPCVersion44, } type queryClient struct { diff --git a/pkg/queryservice/client/query_client_test.go b/pkg/queryservice/client/query_client_test.go index c2aad62725d0a..97cf7ee584be8 100644 --- a/pkg/queryservice/client/query_client_test.go +++ b/pkg/queryservice/client/query_client_test.go @@ -37,7 +37,7 @@ func TestMongoDBClientRetireRequiresProtocolVersion5(t *testing.T) { } func TestSyncCommitV2RequiresProtocolVersion38(t *testing.T) { - assert.Equal(t, defines.MORPCVersion43, methodVersions[query.CmdMethod_SyncCommitV2]) + assert.Equal(t, defines.MORPCVersion44, methodVersions[query.CmdMethod_SyncCommitV2]) const serviceID = "sync-commit-v2-version-test" rt := moruntime.DefaultRuntime() @@ -45,7 +45,7 @@ func TestSyncCommitV2RequiresProtocolVersion38(t *testing.T) { req := &query.Request{CmdMethod: query.CmdMethod_SyncCommitV2} rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion35) assert.Error(t, checkMethodVersion(context.Background(), serviceID, req)) - rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion43) + rt.SetGlobalVariables(moruntime.MOProtocolVersion, defines.MORPCVersion44) assert.NoError(t, checkMethodVersion(context.Background(), serviceID, req)) } diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version.go b/pkg/sql/plan/function/ctl/cmd_rpc_version.go index 1dcd5068f3e85..04d13c8c1d107 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version.go @@ -113,7 +113,7 @@ func handleSetProtocolVersion(proc *process.Process, } if service == cn && targets != nil { - if version >= defines.MORPCVersion43 { + if version >= defines.MORPCVersion44 { const maxDDLVisibilityActivationTargets = 1024 if len(targets) == 0 || len(targets) > maxDDLVisibilityActivationTargets { return Result{}, moerr.NewInternalErrorNoCtxf( @@ -132,12 +132,12 @@ func handleSetProtocolVersion(proc *process.Process, seen[target] = struct{}{} } } - if version >= defines.MORPCVersion43 { + if version >= defines.MORPCVersion44 { if err := validateDDLVisibilityActivationMembership(qt, targets); err != nil { return Result{}, err } } - if version < defines.MORPCVersion43 { + if version < defines.MORPCVersion44 { versions := make([]string, 0, len(targets)) for _, target := range targets { resp, sendErr := transferToCN(qt, target, version, nil) @@ -156,7 +156,7 @@ func handleSetProtocolVersion(proc *process.Process, return Result{Method: SetProtocolVersionMethod, Data: strings.Join(versions, ", ")}, nil } - // Live v43 activation is a distributed barrier. Dispatch every target + // Live v44 activation is a distributed barrier. Dispatch every target // concurrently so each CN can block local DDL producers before any CN // waits for the complete Prepared set. type targetResult struct { @@ -313,7 +313,7 @@ func transferToCN( ) (resp *querypb.Response, err error) { cluster := clusterservice.GetMOCluster(qt.ServiceID()) var selected metadata.CNService - if version >= defines.MORPCVersion43 { + if version >= defines.MORPCVersion44 { refresher, refreshOK := cluster.(clusterservice.AuthoritativeRefresher) if !refreshOK { return nil, moerr.NewInternalErrorNoCtx( diff --git a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go index 439e4cb3d6601..0b8ac3963193c 100644 --- a/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go +++ b/pkg/sql/plan/function/ctl/cmd_rpc_version_test.go @@ -217,9 +217,9 @@ func TestHandleSetProtocolVersionDispatchesCompleteTargetSetConcurrently(t *test proc := &process.Process{Base: &process.BaseProcess{QueryClient: qcli}} result, err := handleSetProtocolVersion( - proc, cn, strings.Join(targets, ",")+":43", nil) + proc, cn, strings.Join(targets, ",")+":44", nil) require.NoError(t, err) - require.Equal(t, "activation-cn-1:43, activation-cn-2:43", result.Data) + require.Equal(t, "activation-cn-1:44, activation-cn-2:44", result.Data) require.Equal(t, int32(2), qcli.started.Load()) require.Equal(t, int32(2), qcli.releases.Load()) qcli.mu.Lock() @@ -229,7 +229,7 @@ func TestHandleSetProtocolVersionDispatchesCompleteTargetSetConcurrently(t *test require.Equal(t, targets, requestTargets) } - _, err = handleSetProtocolVersion(proc, cn, "activation-cn-1,activation-cn-1:43", nil) + _, err = handleSetProtocolVersion(proc, cn, "activation-cn-1,activation-cn-1:44", nil) require.ErrorContains(t, err, "duplicated") } @@ -249,7 +249,7 @@ func TestHandleSetProtocolVersionRejectsOmittedAuthoritativeCN(t *testing.T) { rt.SetGlobalVariables(runtime.ClusterService, mc) proc := &process.Process{Base: &process.BaseProcess{QueryClient: &concurrentProtocolQueryClient{both: make(chan struct{})}}} - _, err := handleSetProtocolVersion(proc, cn, "new-cn:43", nil) + _, err := handleSetProtocolVersion(proc, cn, "new-cn:44", nil) require.ErrorContains(t, err, "does not match authoritative CN membership") } @@ -275,7 +275,7 @@ func TestTransferToCNAllowsActivationFence(t *testing.T) { qcli := &addressRecordingQueryClient{} started := time.Now() - _, err := transferToCN(qcli, serviceID, defines.MORPCVersion43, []string{serviceID}) + _, err := transferToCN(qcli, serviceID, defines.MORPCVersion44, []string{serviceID}) require.Error(t, err) require.Equal(t, "activation-cn:6001", qcli.address) require.Equal(t, []string{serviceID}, diff --git a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go index 9e9dce3a15b82..27ea07a16ae40 100644 --- a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go +++ b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go @@ -49,17 +49,17 @@ func TestIssue277xxDDLConsistency(t *testing.T) { targets := cn0.ServiceID() + "," + cn1.ServiceID() var activation string require.NoError(t, db0.QueryRowContext(ctx, - "select mo_ctl('cn', 'SetProtocolVersion', ?)", targets+":43").Scan(&activation)) - require.Contains(t, activation, cn0.ServiceID()+":43") - require.Contains(t, activation, cn1.ServiceID()+":43") + "select mo_ctl('cn', 'SetProtocolVersion', ?)", targets+":44").Scan(&activation)) + require.Contains(t, activation, cn0.ServiceID()+":44") + require.Contains(t, activation, cn1.ServiceID()+":44") // SetProtocolVersion returns success only after both target RPCs report - // v43 and HAKeeper acknowledges the atomically committed v43 epoch. + // v44 and HAKeeper acknowledges the atomically committed v44 epoch. resetIssue277xxDatabase(t, ctx, db0, database) defer execSQLMaybe(t, ctx, db0, "drop database if exists `"+database+"`") // Prove this public path actually executes SyncCommitV2: an injected - // receiver failure must make CREATE fail after v43 activation. + // receiver failure must make CREATE fail after v44 activation. require.True(t, fault.Enable()) defer fault.Disable() faultPointRemoved := false @@ -77,7 +77,7 @@ func TestIssue277xxDDLConsistency(t *testing.T) { require.NoError(t, removeErr) faultPointRemoved = true - // Do not issue SYNCCOMMIT or retry the read. The v43 DDL commit contract + // Do not issue SYNCCOMMIT or retry the read. The v44 DDL commit contract // must make the first fresh CN1 snapshot observe CN0's CREATE TABLE. execSQLRequire(t, ctx, db0, "create table `"+database+"`.`t` (id int primary key, payload varchar(32))") diff --git a/proto/logservice.proto b/proto/logservice.proto index aafb3ff1e354d..335b3df30e0c0 100644 --- a/proto/logservice.proto +++ b/proto/logservice.proto @@ -675,6 +675,9 @@ message CommandBatch { // DDLVisibilityDeployedProtocol is returned from the same replicated // heartbeat transition that conditionally publishes CN ingress. int64 DDLVisibilityDeployedProtocol = 6; + // DDLVisibilityFrontier is the durable cluster maximum after applying this + // heartbeat transition. New CNs require it as publication acknowledgement. + timestamp.Timestamp DDLVisibilityFrontier = 7; } // ViewMetadataAdmission is the durable cluster admission snapshot. Generation From 73787cd84066c595c599ee47f793d4c8065b58ea Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Wed, 2 Sep 2026 11:22:21 +0800 Subject: [PATCH 30/34] fix: fence markerless ingress by CN generation --- CLAUDE_TODO_2026-08-29.md | 6 ++++ .../CLAUDE_cross_cn_ddl_visibility_fence.md | 4 +-- pkg/cnservice/server.go | 6 +++- pkg/cnservice/server_ddl_visibility.go | 16 ++++++++++ pkg/cnservice/server_ddl_visibility_test.go | 27 +++++++++++++++++ pkg/cnservice/server_heartbeat.go | 5 ++-- pkg/cnservice/server_heartbeat_test.go | 30 ++++++++++++++----- 7 files changed, 81 insertions(+), 13 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index 8b80860d6326a..e520dcc3b4b99 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -94,3 +94,9 @@ 2. 在同一 HAKeeper RSM heartbeat 响应中返回应用后的 authoritative frontier;CN 仅在 generation 精确匹配且 frontier >= T 时承认同步发布,旧 RSM 静默丢字段时 fail closed。 3. 所有 direct CN heartbeat 将 CommandBatch 交给现有 command mutex/dedupe owner,避免 command-delivery-disabled 阶段的 destructive schedule command 丢失。 4. 增加旧 HAKeeper 丢 frontier 与 legacy command delivery 的确定性回归,运行 affected package、race、vet 和 protobuf 测试。 + +## 2026-09-02:startup generation 与 shutdown command ownership review + +1. markerless ingress publication 必须同步应用/验证 heartbeat 返回的 authoritative admission generation;takeover 后旧进程不得打开 ingress/DDL gate。 +2. 将最终 admission withdrawal 放到 TaskRunner/task command 依赖关闭前;direct heartbeat 返回的 legacy CreateTaskService/JoinGossip 必须由仍可用 owner 成功执行。 +3. 增加 takeover interleaving 和 shutdown legacy command 成功闭环回归;清理 design/PR body 的 v36/v43 残留,验证并推送。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index c73715c3f7cc3..d06ae14f17a20 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -61,7 +61,7 @@ A CN is in one of these logical states: 4. **Provisionally fenced**: local frontier synchronization completed and `-44` is durable; ingress remains closed. 5. **Cluster committed**: HAKeeper atomically validated exact `(serviceID, generation, queryAddress)` membership and advanced epoch to 43. 6. **Locally committed**: CN persisted `43`; only then may it republish ingress and unblock DDL. -7. **Markerless post-cut**: no local marker but HAKeeper epoch is 43; runtime remains v44 and ingress/DDL remain closed until a complete retry. +7. **Markerless post-cut**: no local marker but HAKeeper epoch is 44; runtime remains v44 and ingress/DDL remain closed until a complete retry. The cluster epoch commit is the linearization point. Prepared, Fenced, and the last committed DDL frontier are published through each incarnation's heartbeat. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members, exact generation/address, receiver capability, and that each current incarnation itself published Prepared and Fenced, then advances the epoch only on exact equality. A replacement cannot reuse an older incarnation's Fenced proof. A join before this transition invalidates the target set; a join after it observes epoch 44 and is rejected as ingress-ready. @@ -96,7 +96,7 @@ A markerless CN performs an atomic ingress heartbeat handshake. If it linearizes - **Committed local persistence failure**: cluster epoch remains committed; this CN remains closed and restarts from provisional state. - **Ingress publication uncertainty**: perform a bounded cleanup withdrawal; never assume publication failed. - **Restart**: committed marker runs startup frontier synchronization before opening; provisional or markerless post-cut starts v44 fail-closed. -- **Shutdown**: stop periodic heartbeat publication, then withdraw ingress/barrier state before stopping QueryService. +- **Shutdown**: stop periodic heartbeat publication, withdraw the DDL barrier, stop QueryService/frontend ingress, then publish the final admission withdrawal while TaskRunner and gossip command dependencies are still alive. The shared response owner applies any legacy destructive command before the subsequent task/gossip drains. - **Leader failover**: activation is gated until every voting and non-voting LogStore advertises epoch-schema capability, so any eligible HAKeeper leader preserves the field. Retries are idempotent for the same generation and target set. Replacement generations or addresses are rejected before local state mutation. diff --git a/pkg/cnservice/server.go b/pkg/cnservice/server.go index 1016f1e9cb8b5..27b34a722a067 100644 --- a/pkg/cnservice/server.go +++ b/pkg/cnservice/server.go @@ -532,6 +532,11 @@ func (s *service) closeService() error { s.stopFrontendSerialized, s.closeSiriusRuntime, s.closeBootstrapService, + // Withdraw while task and gossip command dependencies are still alive: + // a legacy HAKeeper may destructively return CreateTaskService or + // JoinGossipCluster in this final heartbeat. stopTask below drains any + // task runner created by that response. + s.withdrawViewMetadataAdmission, // Frontend shutdown stops accepting interactive work, while stopTask // drains scheduled ingestion statements. Only after both producers have // stopped may the MongoDB pool disconnect clients still leased by a @@ -545,7 +550,6 @@ func (s *service) closeService() error { // dependencies, while keeping the trace consumer alive for final events. s.waitPipelineHandlers, s.closeIncrService, - s.withdrawViewMetadataAdmission, s.stopRPCs, s.closeTxnTraceService, func() error { diff --git a/pkg/cnservice/server_ddl_visibility.go b/pkg/cnservice/server_ddl_visibility.go index de69099773a0b..49bb2fa579223 100644 --- a/pkg/cnservice/server_ddl_visibility.go +++ b/pkg/cnservice/server_ddl_visibility.go @@ -184,7 +184,23 @@ func (s *service) publishDDLVisibilityIngressAfterStart() error { cancel() return err } + if batch.ViewMetadataAdmission == nil { + cancel() + return moerr.NewInvalidStateNoCtx("markerless ingress heartbeat returned no authoritative generation") + } + if err := s.applyViewMetadataAdmission(ctx, batch.ViewMetadataAdmission); err != nil { + cancel() + return moerr.AttachCause(ctx, err) + } cancel() + if err := s.checkViewMetadataGenerationRevoked(); err != nil { + return err + } + if batch.ViewMetadataAdmission.Generation != s.viewMetadataAdmissionGeneration { + return moerr.NewInvalidStateNoCtxf( + "markerless ingress generation mismatch: local %d, authoritative %d", + s.viewMetadataAdmissionGeneration, batch.ViewMetadataAdmission.Generation) + } if batch.DDLVisibilityDeployedProtocol >= defines.MORPCVersion44 { moruntime.ServiceRuntime(s.cfg.UUID).SetGlobalVariables( moruntime.MOProtocolVersion, batch.DDLVisibilityDeployedProtocol) diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index ff7ecbbaaa8a2..390068ffae651 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -561,6 +561,33 @@ func TestMarkerlessCNIngressHandshakeLinearizesWithCommittedCut(t *testing.T) { require.False(t, gate.PublicDDLEnabled()) } +func TestMarkerlessCNIngressRejectsGenerationTakeover(t *testing.T) { + const serviceID = "markerless-ingress-generation-takeover" + const localGeneration = uint64(7) + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + cluster := &ddlVisibilityTestCluster{cnServices: []metadata.CNService{{ + ServiceID: serviceID, ViewMetadataAdmissionGeneration: localGeneration, + }}} + client := &ddlVisibilityWithdrawalHAKeeperClient{ + cluster: cluster, + authoritativeGenerations: map[string]uint64{serviceID: localGeneration + 1}, + } + gate := frontend.NewDDLCommitGate() + s := &service{ + cfg: &Config{UUID: serviceID}, logger: zap.NewNop(), + ddlCommitGate: gate, _hakeeperClient: client, config: util.NewConfigData(nil), + viewMetadataAdmissionGeneration: localGeneration, + } + + require.NoError(t, s.prepareDDLVisibilityBarrier()) + err := s.publishDDLVisibilityIngressAfterStart() + require.ErrorContains(t, err, "generation revoked") + require.True(t, s.viewMetadataGenerationRevoked.Load()) + require.False(t, s.viewMetadataIngressReady.Load()) + require.False(t, gate.PublicDDLEnabled()) + require.False(t, cluster.cnServices[0].ViewMetadataIngressReady) +} + func TestMarkerlessCNJoinsCommittedClusterFailClosed(t *testing.T) { const serviceID = "ddl-visibility-markerless-post-cut-test" moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 1bff76e96345e..960ca2e49ecca 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -286,8 +286,9 @@ func (s *service) newCNStoreHeartbeat() logservicepb.CNStoreHeartbeat { } // withdrawViewMetadataAdmission publishes a final non-routable heartbeat after -// every local ingress path and TaskRunner have stopped. A clean replacement can -// then take the UUID without waiting for the store timeout. +// external ingress has stopped but before TaskRunner and gossip dependencies are +// closed. This lets the shared response owner apply any destructively delivered +// legacy schedule command; subsequent close steps drain what it created. func (s *service) withdrawViewMetadataAdmission() error { if s.viewMetadataAdmissionGeneration == 0 || s._hakeeperClient == nil { return nil diff --git a/pkg/cnservice/server_heartbeat_test.go b/pkg/cnservice/server_heartbeat_test.go index 639aaa2563df9..0baf4e2bd9517 100644 --- a/pkg/cnservice/server_heartbeat_test.go +++ b/pkg/cnservice/server_heartbeat_test.go @@ -24,6 +24,9 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap" + moruntime "github.com/matrixorigin/matrixone/pkg/common/runtime" + "github.com/matrixorigin/matrixone/pkg/common/stopper" + "github.com/matrixorigin/matrixone/pkg/gossip" "github.com/matrixorigin/matrixone/pkg/logutil" pb "github.com/matrixorigin/matrixone/pkg/pb/logservice" "github.com/matrixorigin/matrixone/pkg/sql/compile" @@ -207,24 +210,35 @@ func (c *blockingCNHeartbeatCommandClient) GetScheduleCommands( return c.commandBatch, nil } -func TestDirectCNHeartbeatProcessesLegacyScheduleCommand(t *testing.T) { - holder := &observingTaskHolder{createErr: errors.New("stop after observing command"), created: make(chan struct{}, 1)} +func TestShutdownHeartbeatAppliesLegacyCommandBeforeDependenciesClose(t *testing.T) { + const serviceID = "shutdown-heartbeat-command-owner" + moruntime.SetupServiceBasedRuntime(serviceID, moruntime.DefaultRuntime()) + gossipNode, err := gossip.NewNode( + context.Background(), serviceID, + gossip.WithListenAddrFn(func() string { return "127.0.0.1:0" }), + gossip.WithServiceAddrFn(func() string { return "127.0.0.1:1" }), + gossip.WithCacheServerAddrFn(func() string { return "127.0.0.1:2" }), + ) + require.NoError(t, err) + require.NoError(t, gossipNode.Create()) + defer func() { require.NoError(t, gossipNode.Leave(time.Second)) }() client := &admissionFailureCNHeartbeatClient{ testHAKClient: &testHAKClient{}, batch: pb.CommandBatch{Commands: []pb.ScheduleCommand{{ ServiceType: pb.CNService, - CreateTaskService: &pb.CreateTaskService{}, + JoinGossipCluster: &pb.JoinGossipCluster{}, }}}, } s := &service{ - cfg: &Config{UUID: "direct-heartbeat-command-owner"}, config: util.NewConfigData(nil), + cfg: &Config{UUID: serviceID}, config: util.NewConfigData(nil), logger: zap.NewNop(), _hakeeperClient: client, + gossipNode: gossipNode, stopper: stopper.NewStopper("shutdown-command-owner"), + viewMetadataAdmissionGeneration: 1, } - s.task.holder = holder + defer s.stopper.Stop() - _, err := s.sendCNHeartbeat(context.Background(), s.newCNStoreHeartbeat()) - require.NoError(t, err) - require.Equal(t, int32(1), holder.createCount.Load()) + require.NoError(t, s.withdrawViewMetadataAdmission()) + require.True(t, gossipNode.Joined(), "withdrawal response command must be accepted before gossip shutdown") } func Test_heartbeat(t *testing.T) { From 06b9ff0ced5045a00246a1e27f07402ff2d42f4a Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Wed, 2 Sep 2026 17:08:30 +0800 Subject: [PATCH 31/34] fix: complete stale-generation DDL visibility --- CLAUDE_TODO_2026-08-29.md | 7 ++++ .../CLAUDE_cross_cn_ddl_visibility_fence.md | 4 +- pkg/cnservice/server_ddl_visibility_test.go | 16 ++++---- pkg/cnservice/server_heartbeat.go | 23 ++++++++---- pkg/frontend/ddl_commit_gate.go | 7 ++++ pkg/frontend/txn.go | 24 ++++++++++-- pkg/frontend/txn_test.go | 37 +++++++++++++++++++ pkg/hakeeper/view_metadata_admission.go | 7 ++++ pkg/queryservice/client/query_client.go | 5 ++- pkg/queryservice/client/query_client_test.go | 2 +- 10 files changed, 109 insertions(+), 23 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index e520dcc3b4b99..337cced534ca0 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -100,3 +100,10 @@ 1. markerless ingress publication 必须同步应用/验证 heartbeat 返回的 authoritative admission generation;takeover 后旧进程不得打开 ingress/DDL gate。 2. 将最终 admission withdrawal 放到 TaskRunner/task command 依赖关闭前;direct heartbeat 返回的 legacy CreateTaskService/JoinGossip 必须由仍可用 owner 成功执行。 3. 增加 takeover interleaving 和 shutdown legacy command 成功闭环回归;清理 design/PR body 的 v36/v43 残留,验证并推送。 + +## 2026-09-02:已提交 DDL 与 generation takeover 线性化 + +1. HAKeeper 对旧 generation heartbeat 拒绝 membership/admission 更新,但仍单调吸收其已提交 DDL frontier,并在响应中返回 authoritative generation/frontier。 +2. CN 区分“frontier 已持久化但 generation 已失效”与普通发布失败:同步 revoke admission,同时向 frontend 返回可识别状态。 +3. frontend 对该状态仍强制向所有 DDL-capable barrier-ready CN 执行 SyncCommitV2,完成后才返回 generation 错误;普通发布失败仍禁止 fan-out。 +4. 增加 Enter/commit -> takeover -> stale publication -> durable frontier + peer apply 的确定性回归,运行 race/vet。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index d06ae14f17a20..39d893ac2f92e 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -1,7 +1,7 @@ # Cross-CN DDL Visibility Fence - Status: **Approved** -- Revision: 4 +- Revision: 5 - Approval: user approval recorded in the PR implementation session on 2026-08-30 - Owning issue: #27743 - Implementation PR: #27756 @@ -80,7 +80,7 @@ The cluster epoch commit is the linearization point. Prepared, Fenced, and the l ### Steady-state DDL -A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned `CommandBatch.ViewMetadataAdmission.Generation` must exactly equal the sender generation, and the returned authoritative frontier must be at least the exact T submitted in that transition. A stale sender or a legacy HAKeeper RSM that silently ignores the frontier therefore cannot mistake RPC delivery for durable frontier acceptance. Every direct CN heartbeat transfers its returned `CommandBatch` to the periodic heartbeat's command mutex/deduplication owner before returning, so startup, ingress, activation, withdrawal, and frontier publication cannot destructively consume and discard a legacy schedule command. TaskRunner, frontend, and full-service drains run asynchronously after the seal: a TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. Revocation transfers a detached runner into shared drain ownership with a completion channel; normal `service.Close` waits for that completion before closing task/txn/RPC dependencies. Conversely, if normal Close takes runner ownership first, it releases the task mutex before `runner.Stop`, allowing the SQL task to seal revocation and exit. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v44 then triggers `SyncCommitV2` to all barrier-ready CNs. The operation succeeds only after generation-bound durable frontier publication and required receivers have applied/synchronized the commit frontier. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned authoritative frontier must be at least the exact T submitted in that transition. Normally the returned `CommandBatch.ViewMetadataAdmission.Generation` must also equal the sender. One narrow exception closes the already-admitted takeover race: if generation 1 entered before generation 2 took ownership and then committed T, HAKeeper rejects every incarnation-scoped field from generation 1 but still monotonically absorbs T. Generation 1 synchronously revokes admission, force-fans T out to every barrier-ready DDL-capable CN, and only then returns the generation error. A legacy HAKeeper RSM that silently ignores the frontier still fails closed and does not fan out. Every direct CN heartbeat transfers its returned `CommandBatch` to the periodic heartbeat's command mutex/deduplication owner before returning, so startup, ingress, activation, withdrawal, and frontier publication cannot destructively consume and discard a legacy schedule command. TaskRunner, frontend, and full-service drains run asynchronously after the seal: a TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. Revocation transfers a detached runner into shared drain ownership with a completion channel; normal `service.Close` waits for that completion before closing task/txn/RPC dependencies. Conversely, if normal Close takes runner ownership first, it releases the task mutex before `runner.Stop`, allowing the SQL task to seal revocation and exit. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v44 normally triggers `SyncCommitV2`; the takeover exception may invoke the same method at the v42 runtime only for targets whose `DDLVisibilityBarrierReady` metadata proves the new receiver exists. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. ### Scale-out and replacement diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 390068ffae651..b64d30a654722 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -252,6 +252,9 @@ func (c *ddlVisibilityWithdrawalHAKeeperClient) SendCNHeartbeat( } authoritativeGeneration := hb.ViewMetadataAdmissionGeneration if generation := c.authoritativeGenerations[hb.UUID]; generation > authoritativeGeneration { + if !c.oldDDLFrontierRSM && c.cluster.globalFrontier.Less(hb.DDLVisibilityFrontier) { + c.cluster.globalFrontier = hb.DDLVisibilityFrontier + } return logservicepb.CommandBatch{ DDLVisibilityDeployedProtocol: c.clusterDeployedProtocol, DDLVisibilityFrontier: &c.cluster.globalFrontier, @@ -1770,16 +1773,15 @@ func TestStaleGenerationCannotAcknowledgeDDLFrontierPublication(t *testing.T) { t.Fatal("TaskRunner drain did not finish after the rejected SQL task exited") } require.True(t, oldIncarnation.viewMetadataGenerationRevoked.Load()) - require.Equal(t, oldFrontier, cluster.globalFrontier, - "stale generation heartbeat must not advance the durable frontier") + require.Equal(t, commitFrontier, cluster.globalFrontier, + "an already-admitted stale-generation commit must advance the durable frontier") - // After the stale process crashes, a future incarnation can only observe the - // old durable value. The failed publication therefore must not have been - // acknowledged by frontend (covered by the publisher-failure commit test). + // After the stale process exits, every future incarnation observes T even + // though no incarnation-scoped admission state was accepted from generation 1. ctrl := gomock.NewController(t) restartedTxnClient := mock_frontend.NewMockTxnClient(ctrl) - restartedTxnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), oldFrontier).Return(oldFrontier, nil) - restartedTxnClient.EXPECT().SyncLatestCommitTS(oldFrontier) + restartedTxnClient.EXPECT().WaitLogTailAppliedAt(gomock.Any(), commitFrontier).Return(commitFrontier, nil) + restartedTxnClient.EXPECT().SyncLatestCommitTS(commitFrontier) restarted := &service{ cfg: &Config{UUID: producerID}, _txnClient: restartedTxnClient, _hakeeperClient: client, diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index 960ca2e49ecca..cb61087498156 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -16,6 +16,7 @@ package cnservice import ( "context" + "errors" "time" "go.uber.org/zap" @@ -23,6 +24,7 @@ import ( "github.com/matrixorigin/matrixone/pkg/common/moerr" "github.com/matrixorigin/matrixone/pkg/common/system" "github.com/matrixorigin/matrixone/pkg/defines" + "github.com/matrixorigin/matrixone/pkg/frontend" "github.com/matrixorigin/matrixone/pkg/logservice" "github.com/matrixorigin/matrixone/pkg/logutil" logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" @@ -220,14 +222,6 @@ func (s *service) publishDDLCommitFrontier(ctx context.Context, ts timestamp.Tim return moerr.NewInvalidStateNoCtx( "DDL frontier publication lacks an authoritative CN generation") } - if admission.Generation != s.viewMetadataAdmissionGeneration { - if admission.Generation > s.viewMetadataAdmissionGeneration { - s.revokeViewMetadataGeneration(admission.Generation) - } - return moerr.NewInvalidStateNoCtxf( - "DDL frontier publication generation %d rejected by authoritative generation %d", - s.viewMetadataAdmissionGeneration, admission.Generation) - } if batch.DDLVisibilityFrontier == nil || batch.DDLVisibilityFrontier.Less(ts) { authoritative := "missing" if batch.DDLVisibilityFrontier != nil { @@ -237,6 +231,19 @@ func (s *service) publishDDLCommitFrontier(ctx context.Context, ts timestamp.Tim "DDL frontier publication %s was not durably acknowledged (authoritative frontier %s)", ts.DebugString(), authoritative) } + if admission.Generation != s.viewMetadataAdmissionGeneration { + if admission.Generation > s.viewMetadataAdmissionGeneration { + s.revokeViewMetadataGeneration(admission.Generation) + return errors.Join( + frontend.ErrDDLFrontierPublishedByRevokedGeneration, + moerr.NewInvalidStateNoCtxf( + "DDL frontier publication generation %d rejected by authoritative generation %d", + s.viewMetadataAdmissionGeneration, admission.Generation)) + } + return moerr.NewInvalidStateNoCtxf( + "DDL frontier publication generation %d rejected by authoritative generation %d", + s.viewMetadataAdmissionGeneration, admission.Generation) + } return nil } diff --git a/pkg/frontend/ddl_commit_gate.go b/pkg/frontend/ddl_commit_gate.go index 4bf59abaf055b..f951c74592ff1 100644 --- a/pkg/frontend/ddl_commit_gate.go +++ b/pkg/frontend/ddl_commit_gate.go @@ -16,6 +16,7 @@ package frontend import ( "context" + "errors" "sync" "sync/atomic" @@ -26,6 +27,12 @@ import ( const DDLCommitGateRuntimeKey = "frontend.ddl-commit-gate" +// ErrDDLFrontierPublishedByRevokedGeneration means T is durable, but the +// producer lost UUID ownership. The committed DDL must still fan out before +// this error is returned to the client. +var ErrDDLFrontierPublishedByRevokedGeneration = errors.New( + "DDL frontier published by revoked CN generation") + // DDLCommitGate gives DDL producers and live protocol activation one local // linearization point. Enter admits a commit while Block prevents new commits // and waits for already-admitted commits to leave. A failed activation may keep diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index ce880093815f6..9d0e61794f42b 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -1037,6 +1037,7 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { owner.rollbackTempTableTransaction(tempTxnKey) } } + var revokedPublicationErr error if haveDDL && !commitTs.IsEmpty() && (err == nil || commitResultUnknown) { recordDDLCommitFrontier(execCtx.ses.GetService(), commitTs) if execCtx.ses.GetFromRealUser() || @@ -1048,7 +1049,11 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { if publishErr := publishDDLCommitFrontier( ctx2, execCtx.ses.GetService(), commitTs, ); publishErr != nil { - err = errors.Join(err, publishErr) + if errors.Is(publishErr, ErrDDLFrontierPublishedByRevokedGeneration) { + revokedPublicationErr = publishErr + } else { + err = errors.Join(err, publishErr) + } } } } @@ -1060,13 +1065,15 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { execCtx.ses.SetTxnId(dumpUUID[:]) return err } - if err == nil && haveDDL && !visibilityTS.IsEmpty() && + if (err == nil || revokedPublicationErr != nil) && haveDDL && !visibilityTS.IsEmpty() && (execCtx.ses.GetFromRealUser() || publicBackgroundDDLBarrierEnabled(execCtx.ses.GetService())) { // A fresh proxy connection has no session commit timestamp to carry // across CNs. Do not acknowledge a client DDL until every working CN // has reached the commit, or the observed catalog frontier for a no-op. - err = syncDDLCommitToBarrierReadyCNs(ctx2, execCtx.ses.GetService(), visibilityTS) + syncErr := syncDDLCommitToBarrierReadyCNsWithForce( + ctx2, execCtx.ses.GetService(), visibilityTS, revokedPublicationErr != nil) + err = errors.Join(err, revokedPublicationErr, syncErr) } } th.invalidateTxnUnsafe() @@ -1092,6 +1099,15 @@ func syncDDLCommitToBarrierReadyCNs( ctx context.Context, service string, visibilityTS timestamp.Timestamp, +) error { + return syncDDLCommitToBarrierReadyCNsWithForce(ctx, service, visibilityTS, false) +} + +func syncDDLCommitToBarrierReadyCNsWithForce( + ctx context.Context, + service string, + visibilityTS timestamp.Timestamp, + force bool, ) error { pu := getPuIfPresent(service) if pu == nil || pu.QueryClient == nil { @@ -1101,7 +1117,7 @@ func syncDDLCommitToBarrierReadyCNs( qc := pu.QueryClient protocol, ok := moruntime.ServiceRuntime(qc.ServiceID()).GetGlobalVariables(moruntime.MOProtocolVersion) protocolVersion, valid := protocol.(int64) - if !ok || !valid || protocolVersion < defines.MORPCVersion44 { + if !force && (!ok || !valid || protocolVersion < defines.MORPCVersion44) { return nil } cluster := clusterservice.GetMOCluster(qc.ServiceID()) diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index d8a19cd503ad2..930274dc5e918 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -1040,6 +1040,43 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { require.Empty(t, qc.requests, "fan-out and success must not follow failed durable publication") }) + t.Run("revoked generation finishes fan-out after durable publication", func(t *testing.T) { + ses, _, qc, execCtx := newState(t) + defer ses.Close() + defer execCtx.Close() + gate := NewDDLCommitGate() + var authoritativeFrontier timestamp.Timestamp + generationErr := errors.Join( + ErrDDLFrontierPublishedByRevokedGeneration, + errors.New("generation 1 replaced by generation 2")) + gate.SetFrontierPublisher(func(_ context.Context, ts timestamp.Timestamp) error { + // Model generation 1's already-admitted commit being durably absorbed + // after generation 2 has taken ownership. + authoritativeFrontier = ts + return generationErr + }) + rt := moruntime.ServiceRuntime(ses.GetService()) + previousGate, hadPreviousGate := rt.GetGlobalVariables(DDLCommitGateRuntimeKey) + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, gate) + moruntime.ServiceRuntime(queryServiceID).SetGlobalVariables( + moruntime.MOProtocolVersion, defines.MORPCVersion42) + t.Cleanup(func() { + if hadPreviousGate { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, previousGate) + } else { + rt.SetGlobalVariables(DDLCommitGateRuntimeKey, nil) + } + }) + + err := ses.GetTxnHandler().Commit(execCtx) + require.ErrorIs(t, err, ErrDDLFrontierPublishedByRevokedGeneration) + require.Equal(t, commitTS, authoritativeFrontier) + require.Equal(t, []ddlSyncRequest{ + {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, + }, qc.requests) + }) + t.Run("activation gate drains and blocks concurrent DDL commit", func(t *testing.T) { ses, op, _, execCtx := newState(t) defer ses.Close() diff --git a/pkg/hakeeper/view_metadata_admission.go b/pkg/hakeeper/view_metadata_admission.go index 75770a0141417..6603b173fe56f 100644 --- a/pkg/hakeeper/view_metadata_admission.go +++ b/pkg/hakeeper/view_metadata_admission.go @@ -451,6 +451,13 @@ func (s *stateMachine) updateCNViewMetadataAdmission(hb pb.CNStoreHeartbeat) boo active := s.viewMetadataAdmissionActive() if active && existed && hb.ViewMetadataAdmissionGeneration < previous.ViewMetadataAdmissionGeneration { + // The old incarnation may have entered the public DDL gate before its + // replacement took ownership and committed T afterwards. Reject all + // incarnation-scoped state, but retain that already-durable DDL fact so + // the old commit path can finish cross-CN visibility before exiting. + if s.state.CNState.DDLVisibilityFrontier.Less(hb.DDLVisibilityFrontier) { + s.state.CNState.DDLVisibilityFrontier = hb.DDLVisibilityFrontier + } return false } newGeneration := !existed || diff --git a/pkg/queryservice/client/query_client.go b/pkg/queryservice/client/query_client.go index b4d4de28e8525..1fe481b02c0f3 100644 --- a/pkg/queryservice/client/query_client.go +++ b/pkg/queryservice/client/query_client.go @@ -63,7 +63,10 @@ var methodVersions = map[pb.CmdMethod]int64{ pb.CmdMethod_ISCPDrainConsumer: defines.MORPCVersion4, pb.CmdMethod_IcebergCacheInvalidate: defines.MORPCVersion4, pb.CmdMethod_MongoDBClientRetire: defines.MORPCVersion5, - pb.CmdMethod_SyncCommitV2: defines.MORPCVersion44, + // SyncCommitV2 is sent below the activation epoch only to CNs whose + // DDLVisibilityBarrierReady metadata proves this receiver exists. This lets + // an already-admitted DDL finish visibility after its generation is replaced. + pb.CmdMethod_SyncCommitV2: defines.MORPCVersion42, } type queryClient struct { diff --git a/pkg/queryservice/client/query_client_test.go b/pkg/queryservice/client/query_client_test.go index 97cf7ee584be8..8d87b8c4d2d72 100644 --- a/pkg/queryservice/client/query_client_test.go +++ b/pkg/queryservice/client/query_client_test.go @@ -37,7 +37,7 @@ func TestMongoDBClientRetireRequiresProtocolVersion5(t *testing.T) { } func TestSyncCommitV2RequiresProtocolVersion38(t *testing.T) { - assert.Equal(t, defines.MORPCVersion44, methodVersions[query.CmdMethod_SyncCommitV2]) + assert.Equal(t, defines.MORPCVersion42, methodVersions[query.CmdMethod_SyncCommitV2]) const serviceID = "sync-commit-v2-version-test" rt := moruntime.DefaultRuntime() From 6e2861cdb975eecb145f33448a600eb53fe10044 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Wed, 2 Sep 2026 18:11:22 +0800 Subject: [PATCH 32/34] fix: use moerr for DDL generation sentinel --- CLAUDE_TODO_2026-08-29.md | 5 +++++ pkg/frontend/ddl_commit_gate.go | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index 337cced534ca0..7d3462f2c80fd 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -107,3 +107,8 @@ 2. CN 区分“frontier 已持久化但 generation 已失效”与普通发布失败:同步 revoke admission,同时向 frontend 返回可识别状态。 3. frontend 对该状态仍强制向所有 DDL-capable barrier-ready CN 执行 SyncCommitV2,完成后才返回 generation 错误;普通发布失败仍禁止 fan-out。 4. 增加 Enter/commit -> takeover -> stale publication -> durable frontier + peer apply 的确定性回归,运行 race/vet。 + +## 2026-09-02:SCA errors.New 修复 + +1. 将 generation-takeover sentinel 从标准库 `errors.New` 改为仓库要求的 `moerr`。 +2. 运行 static-check、frontend focused UT 和 diff check,直接推送。 diff --git a/pkg/frontend/ddl_commit_gate.go b/pkg/frontend/ddl_commit_gate.go index f951c74592ff1..8889711a31603 100644 --- a/pkg/frontend/ddl_commit_gate.go +++ b/pkg/frontend/ddl_commit_gate.go @@ -16,7 +16,6 @@ package frontend import ( "context" - "errors" "sync" "sync/atomic" @@ -30,7 +29,7 @@ const DDLCommitGateRuntimeKey = "frontend.ddl-commit-gate" // ErrDDLFrontierPublishedByRevokedGeneration means T is durable, but the // producer lost UUID ownership. The committed DDL must still fan out before // this error is returned to the client. -var ErrDDLFrontierPublishedByRevokedGeneration = errors.New( +var ErrDDLFrontierPublishedByRevokedGeneration = moerr.NewInvalidStateNoCtx( "DDL frontier published by revoked CN generation") // DDLCommitGate gives DDL producers and live protocol activation one local From ae0917a46e9eddb3c2030c20499fd1a54bd96911 Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Wed, 2 Sep 2026 20:41:01 +0800 Subject: [PATCH 33/34] fix: remove unused DDL sync wrapper --- CLAUDE_TODO_2026-08-29.md | 6 ++++++ pkg/frontend/txn.go | 10 +--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index 7d3462f2c80fd..151d8c91b4244 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -112,3 +112,9 @@ 1. 将 generation-takeover sentinel 从标准库 `errors.New` 改为仓库要求的 `moerr`。 2. 运行 static-check、frontend focused UT 和 diff check,直接推送。 + +## 2026-09-02:SCA unused 与 main 冲突 + +1. 删除 stale-generation force fan-out 引入但未使用的兼容 wrapper,保留单一内部实现,修复 SCA `unused`。 +2. merge 最新 `mo/main`,按 v42/v43/v44 累积协议和生成文件所有权解决冲突。 +3. 运行 affected UT/race/vet/static-check/diff-check 后推送。 diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index 9d0e61794f42b..db86636763af9 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -1071,7 +1071,7 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { // A fresh proxy connection has no session commit timestamp to carry // across CNs. Do not acknowledge a client DDL until every working CN // has reached the commit, or the observed catalog frontier for a no-op. - syncErr := syncDDLCommitToBarrierReadyCNsWithForce( + syncErr := syncDDLCommitToBarrierReadyCNs( ctx2, execCtx.ses.GetService(), visibilityTS, revokedPublicationErr != nil) err = errors.Join(err, revokedPublicationErr, syncErr) } @@ -1099,14 +1099,6 @@ func syncDDLCommitToBarrierReadyCNs( ctx context.Context, service string, visibilityTS timestamp.Timestamp, -) error { - return syncDDLCommitToBarrierReadyCNsWithForce(ctx, service, visibilityTS, false) -} - -func syncDDLCommitToBarrierReadyCNsWithForce( - ctx context.Context, - service string, - visibilityTS timestamp.Timestamp, force bool, ) error { pu := getPuIfPresent(service) From c630154888d21aaf81cdb9ef77fada8e37c308db Mon Sep 17 00:00:00 2001 From: Cao Kai Date: Wed, 2 Sep 2026 23:39:52 +0800 Subject: [PATCH 34/34] fix: make CN generation ownership independently monotonic --- CLAUDE_TODO_2026-08-29.md | 7 ++ .../CLAUDE_cross_cn_ddl_visibility_fence.md | 12 +-- pkg/cnservice/server_ddl_visibility_test.go | 10 +- pkg/cnservice/server_heartbeat.go | 28 ++++-- .../server_view_metadata_admission.go | 24 ++++- .../server_view_metadata_admission_test.go | 31 ++++++ pkg/frontend/ddl_commit_gate.go | 6 ++ pkg/frontend/txn.go | 4 + pkg/frontend/txn_test.go | 34 ++++++- pkg/hakeeper/view_metadata_admission.go | 2 +- pkg/hakeeper/view_metadata_admission_test.go | 8 +- .../issue_27743_ddl_consistency_test.go | 97 +++++++++++++++++++ .../issue_277xx_ddl_consistency_test.go | 43 -------- 13 files changed, 240 insertions(+), 66 deletions(-) create mode 100644 pkg/tests/issues/isolated/issue_27743_ddl_consistency_test.go diff --git a/CLAUDE_TODO_2026-08-29.md b/CLAUDE_TODO_2026-08-29.md index 151d8c91b4244..77d4c3ea96721 100644 --- a/CLAUDE_TODO_2026-08-29.md +++ b/CLAUDE_TODO_2026-08-29.md @@ -118,3 +118,10 @@ 1. 删除 stale-generation force fan-out 引入但未使用的兼容 wrapper,保留单一内部实现,修复 SCA `unused`。 2. merge 最新 `mo/main`,按 v42/v43/v44 累积协议和生成文件所有权解决冲突。 3. 运行 affected UT/race/vet/static-check/diff-check 后推送。 + +## 2026-09-02:generation 独立单调与 stale frontend DDL completion + +1. HAKeeper generation ownership 不再依赖 ViewMetadataAdmission activation;任何已登记的更高 generation 都拒绝旧 incarnation 状态覆盖,同时仅吸收其已提交 DDL frontier。 +2. stale committed DDL revocation 同步 seal admission,但通过 completion barrier 延迟 MOServer/TaskRunner/full-service drain,frontend 在强制 SyncCommitV2 完成(成功或失败)后显式释放。 +3. 增加 admission 未激活 generation 回退 RSM 回归,以及真实 frontend commit owner 在 fan-out 前不被 drain/cancel、fan-out 后 drain 的确定性回归。 +4. 修复 issue_277xx 测试对共享集群 v44 epoch 的永久污染,清理设计 epoch/marker 43,并 merge 最新 main 后验证。 diff --git a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md index 362bda9f484e9..673a7f2cc6afe 100644 --- a/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md +++ b/docs/design/CLAUDE_cross_cn_ddl_visibility_fence.md @@ -1,7 +1,7 @@ # Cross-CN DDL Visibility Fence - Status: **Approved** -- Revision: 5 +- Revision: 6 - Approval: user approval recorded in the PR implementation session on 2026-08-30 - Owning issue: #27743 - Implementation PR: #27756 @@ -49,7 +49,7 @@ It is unsafe for any public or already-connected CN to commit DDL below v44 whil | Public DDL gate | frontend `DDLCommitGate` | process-local | Whether new public/background DDL may enter | | Proxy ingress readiness | CN heartbeat/HAKeeper | replicated latest state | Whether new routed sessions may enter | -HAKeeper is the first owner of cluster epoch and membership linearization. CN local metadata is not authoritative for cluster membership. +HAKeeper is the first owner of cluster epoch and membership linearization. CN local metadata is not authoritative for cluster membership. CN generation ownership is monotonic independently of ViewMetadataAdmission activation: once generation N+1 owns a UUID, an N heartbeat can never overwrite incarnation state, even before the admission protocol is enabled. It may only contribute an already-committed monotonic DDL frontier. ## 4. Protocol states @@ -59,8 +59,8 @@ A CN is in one of these logical states: 2. **Withdrawing**: activation blocks new DDL, withdraws ingress, and drains active DDL. 3. **Prepared v44**: local old-protocol producers are drained; runtime can receive v44 RPCs. 4. **Provisionally fenced**: local frontier synchronization completed and `-44` is durable; ingress remains closed. -5. **Cluster committed**: HAKeeper atomically validated exact `(serviceID, generation, queryAddress)` membership and advanced epoch to 43. -6. **Locally committed**: CN persisted `43`; only then may it republish ingress and unblock DDL. +5. **Cluster committed**: HAKeeper atomically validated exact `(serviceID, generation, queryAddress)` membership and advanced epoch to 44. +6. **Locally committed**: CN persisted `44`; only then may it republish ingress and unblock DDL. 7. **Markerless post-cut**: no local marker but HAKeeper epoch is 44; runtime remains v44 and ingress/DDL remain closed until a complete retry. The cluster epoch commit is the linearization point. Prepared, Fenced, and the last committed DDL frontier are published through each incarnation's heartbeat. The commit heartbeat contains the exact target tuples. In one replicated transition HAKeeper updates the sender heartbeat, compares all eligible raw CNState members, exact generation/address, receiver capability, and that each current incarnation itself published Prepared and Fenced, then advances the epoch only on exact equality. A replacement cannot reuse an older incarnation's Fenced proof. A join before this transition invalidates the target set; a join after it observes epoch 44 and is rejected as ingress-ready. @@ -76,11 +76,11 @@ The cluster epoch commit is the linearization point. Prepared, Fenced, and the l 5. Targets concurrently withdraw ingress, block and drain DDL, capture their reconstructed latest committed timestamp, then heartbeat Prepared together with that frontier. HAKeeper advances a cluster-lifetime maximum and never lowers it when an incarnation restarts, is replaced, or is removed. 6. Each target reads and applies the replicated cluster-lifetime frontier, durably enters provisional Fenced, and heartbeats Fenced. This avoids cyclic QueryService control RPCs while every target is already serving a long-running activation RPC. 7. Each target confirms all exact current incarnations are Fenced in HAKeeper; HAKeeper atomically revalidates those tuple-bound proofs and commits epoch 44. -8. Each CN persists local committed 43, republishes ingress if listeners are live, and unblocks public DDL. +8. Each CN persists local committed 44, republishes ingress if listeners are live, and unblocks public DDL. ### Steady-state DDL -A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned authoritative frontier must be at least the exact T submitted in that transition. Normally the returned `CommandBatch.ViewMetadataAdmission.Generation` must also equal the sender. One narrow exception closes the already-admitted takeover race: if generation 1 entered before generation 2 took ownership and then committed T, HAKeeper rejects every incarnation-scoped field from generation 1 but still monotonically absorbs T. Generation 1 synchronously revokes admission, force-fans T out to every barrier-ready DDL-capable CN, and only then returns the generation error. A legacy HAKeeper RSM that silently ignores the frontier still fails closed and does not fan out. Every direct CN heartbeat transfers its returned `CommandBatch` to the periodic heartbeat's command mutex/deduplication owner before returning, so startup, ingress, activation, withdrawal, and frontier publication cannot destructively consume and discard a legacy schedule command. TaskRunner, frontend, and full-service drains run asynchronously after the seal: a TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. Revocation transfers a detached runner into shared drain ownership with a completion channel; normal `service.Close` waits for that completion before closing task/txn/RPC dependencies. Conversely, if normal Close takes runner ownership first, it releases the task mutex before `runner.Stop`, allowing the SQL task to seal revocation and exit. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v44 normally triggers `SyncCommitV2`; the takeover exception may invoke the same method at the v43 runtime only for targets whose `DDLVisibilityBarrierReady` metadata proves the new receiver exists. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. +A public real-user DDL, and background DDL after public listeners are enabled, enters `DDLCommitGate`. After commit, the producer synchronously advances the monotonic HAKeeper cluster frontier before acknowledging success; publication failure fails the statement closed. The returned authoritative frontier must be at least the exact T submitted in that transition. Normally the returned `CommandBatch.ViewMetadataAdmission.Generation` must also equal the sender. One narrow exception closes the already-admitted takeover race: if generation 1 entered before generation 2 took ownership and then committed T, HAKeeper rejects every incarnation-scoped field from generation 1 but still monotonically absorbs T. Generation 1 synchronously revokes admission, force-fans T out to every barrier-ready DDL-capable CN, and only then returns the generation error. A legacy HAKeeper RSM that silently ignores the frontier still fails closed and does not fan out. Every direct CN heartbeat transfers its returned `CommandBatch` to the periodic heartbeat's command mutex/deduplication owner before returning, so startup, ingress, activation, withdrawal, and frontier publication cannot destructively consume and discard a legacy schedule command. TaskRunner, frontend, and full-service drains run asynchronously after the seal: revocation synchronously blocks new DDL, while the drain goroutine waits for all already-admitted DDL and any stale-publication visibility completion before stopping MOServer or outbound dependencies. A TaskRunner SQL DDL may itself discover the rejection, so synchronously waiting for that runner would self-deadlock. Revocation transfers a detached runner into shared drain ownership with a completion channel; normal `service.Close` waits for that completion before closing task/txn/RPC dependencies. Conversely, if normal Close takes runner ownership first, it releases the task mutex before `runner.Stop`, allowing the SQL task to seal revocation and exit. This removes both the commit-success-to-periodic-heartbeat crash window and the old-incarnation-after-takeover window without adding a revocation wait cycle. Protocol v44 normally triggers `SyncCommitV2`; the takeover exception may invoke the same method at the v43 runtime only for targets whose `DDLVisibilityBarrierReady` metadata proves the new receiver exists. Bootstrap background work before ingress remains exempt to avoid depending on an unavailable HAKeeper/QueryService. ### Scale-out and replacement diff --git a/pkg/cnservice/server_ddl_visibility_test.go b/pkg/cnservice/server_ddl_visibility_test.go index 77d2c00db4ec3..ebb205b59ed73 100644 --- a/pkg/cnservice/server_ddl_visibility_test.go +++ b/pkg/cnservice/server_ddl_visibility_test.go @@ -1761,10 +1761,18 @@ func TestStaleGenerationCannotAcknowledgeDDLFrontierPublication(t *testing.T) { t.Fatal("generation rejection self-waited on its own TaskRunner SQL task") } require.ErrorContains(t, err, "generation 1 rejected by authoritative generation 2") + var completion frontend.DDLRevocationCompletion + require.ErrorAs(t, err, &completion) + select { + case <-runner.stopEntered: + t.Fatal("physical drain started before stale DDL visibility completion") + default: + } + completion.CompleteDDLRevocation() select { case <-runner.stopEntered: case <-time.After(time.Second): - t.Fatal("asynchronous revocation did not begin TaskRunner drain") + t.Fatal("asynchronous revocation did not begin TaskRunner drain after visibility completion") } close(runner.releaseStop) select { diff --git a/pkg/cnservice/server_heartbeat.go b/pkg/cnservice/server_heartbeat.go index cb61087498156..135b2b5e5bf8d 100644 --- a/pkg/cnservice/server_heartbeat.go +++ b/pkg/cnservice/server_heartbeat.go @@ -16,7 +16,7 @@ package cnservice import ( "context" - "errors" + "sync" "time" "go.uber.org/zap" @@ -33,6 +33,20 @@ import ( "github.com/matrixorigin/matrixone/pkg/version" ) +type revokedDDLPublicationError struct { + cause error + done chan struct{} + once sync.Once +} + +func (e *revokedDDLPublicationError) Error() string { return e.cause.Error() } +func (e *revokedDDLPublicationError) Unwrap() []error { + return []error{frontend.ErrDDLFrontierPublishedByRevokedGeneration, e.cause} +} +func (e *revokedDDLPublicationError) CompleteDDLRevocation() { + e.once.Do(func() { close(e.done) }) +} + var cnCommandPollFailed = logutil.Event{ Name: "cn.schedule-command.poll.failed", Message: "failed to poll cn schedule commands", @@ -233,12 +247,14 @@ func (s *service) publishDDLCommitFrontier(ctx context.Context, ts timestamp.Tim } if admission.Generation != s.viewMetadataAdmissionGeneration { if admission.Generation > s.viewMetadataAdmissionGeneration { - s.revokeViewMetadataGeneration(admission.Generation) - return errors.Join( - frontend.ErrDDLFrontierPublishedByRevokedGeneration, - moerr.NewInvalidStateNoCtxf( + publicationErr := &revokedDDLPublicationError{ + cause: moerr.NewInvalidStateNoCtxf( "DDL frontier publication generation %d rejected by authoritative generation %d", - s.viewMetadataAdmissionGeneration, admission.Generation)) + s.viewMetadataAdmissionGeneration, admission.Generation), + done: make(chan struct{}), + } + s.revokeViewMetadataGenerationAfterDDL(admission.Generation, publicationErr.done) + return publicationErr } return moerr.NewInvalidStateNoCtxf( "DDL frontier publication generation %d rejected by authoritative generation %d", diff --git a/pkg/cnservice/server_view_metadata_admission.go b/pkg/cnservice/server_view_metadata_admission.go index 830aaf37489bc..0b2bec1bf3d74 100644 --- a/pkg/cnservice/server_view_metadata_admission.go +++ b/pkg/cnservice/server_view_metadata_admission.go @@ -120,15 +120,26 @@ func (s *service) applyViewMetadataAdmission( // generation while publishing a DDL frontier; waiting for TaskRunner.Stop on // that stack would make the runner wait for the task that is doing the stop. func (s *service) revokeViewMetadataGeneration(authoritative uint64) { + s.revokeViewMetadataGenerationAfterDDL(authoritative, nil) +} + +func (s *service) revokeViewMetadataGenerationAfterDDL( + authoritative uint64, + ddlVisibilityDone <-chan struct{}, +) { s.viewMetadataRevocationOnce.Do(func() { s.viewMetadataGenerationRevoked.Store(true) s.viewMetadataIngressReady.Store(false) s.ddlVisibilityBarrierReady.Store(false) + if s.ddlCommitGate != nil { + _ = s.ddlCommitGate.BlockNew() + } _ = s.closePipelineAdmission() s.queryWork.beginClose() runner, runnerDone := s.detachRevokedTaskRunner() - go s.drainRevokedViewMetadataGeneration(authoritative, runner, runnerDone) + go s.drainRevokedViewMetadataGeneration( + authoritative, runner, runnerDone, ddlVisibilityDone) }) } @@ -136,7 +147,18 @@ func (s *service) drainRevokedViewMetadataGeneration( authoritative uint64, runner taskservice.TaskRunner, runnerDone chan struct{}, + ddlVisibilityDone <-chan struct{}, ) { + // Keep the frontend owner and outbound QueryService dependencies alive until + // every DDL admitted before the synchronous seal has exited. In the stale + // publication path, the explicit completion additionally proves mandatory + // visibility fan-out ran before physical drain. + if s.ddlCommitGate != nil { + _ = s.ddlCommitGate.WaitDrained(context.Background()) + } + if ddlVisibilityDone != nil { + <-ddlVisibilityDone + } // Serialize physical frontend shutdown with MOServer.Start before waiting // for task executors. The goroutine is independent of the rejected SQL task, // allowing that task to return and satisfy TaskRunner.Stop's wait. diff --git a/pkg/cnservice/server_view_metadata_admission_test.go b/pkg/cnservice/server_view_metadata_admission_test.go index da780ca2a8885..2df4434a2af86 100644 --- a/pkg/cnservice/server_view_metadata_admission_test.go +++ b/pkg/cnservice/server_view_metadata_admission_test.go @@ -290,6 +290,37 @@ func TestCNGenerationRevocationStopsFrontendBeforeTaskRunnerDrain(t *testing.T) require.Nil(t, s.GetTaskRunner()) } +func TestCNGenerationRevocationKeepsFrontendAliveUntilAdmittedDDLExits(t *testing.T) { + gate := frontend.NewDDLCommitGate() + leave, err := gate.Enter(context.Background()) + require.NoError(t, err) + closeCalled := make(chan struct{}) + s := &service{ + cfg: &Config{UUID: "revoked-frontend-ddl-owner"}, logger: zap.NewNop(), + ddlCommitGate: gate, viewMetadataAdmissionGeneration: 7, + viewMetadataCloseFn: func() error { close(closeCalled); return nil }, + } + + s.revokeViewMetadataGeneration(8) + require.True(t, s.viewMetadataGenerationRevoked.Load()) + blockedCtx, cancel := context.WithCancel(context.Background()) + cancel() + _, err = gate.Enter(blockedCtx) + require.ErrorIs(t, err, context.Canceled, "revocation must synchronously reject new DDL") + select { + case <-closeCalled: + t.Fatal("frontend/service drain canceled an already-admitted DDL owner") + default: + } + + leave() + select { + case <-closeCalled: + case <-time.After(time.Second): + t.Fatal("frontend/service drain did not resume after admitted DDL exited") + } +} + func TestCNGenerationRevocationDoesNotWaitForCloseOwnedTaskRunner(t *testing.T) { runner := &blockedStopTaskRunner{ testRunner: &testRunner{}, stopEntered: make(chan struct{}), diff --git a/pkg/frontend/ddl_commit_gate.go b/pkg/frontend/ddl_commit_gate.go index 8889711a31603..000cf9e1f3bfe 100644 --- a/pkg/frontend/ddl_commit_gate.go +++ b/pkg/frontend/ddl_commit_gate.go @@ -32,6 +32,12 @@ const DDLCommitGateRuntimeKey = "frontend.ddl-commit-gate" var ErrDDLFrontierPublishedByRevokedGeneration = moerr.NewInvalidStateNoCtx( "DDL frontier published by revoked CN generation") +// DDLRevocationCompletion delays physical CN drain until an already-committed +// stale-generation DDL has completed its mandatory visibility fan-out. +type DDLRevocationCompletion interface { + CompleteDDLRevocation() +} + // DDLCommitGate gives DDL producers and live protocol activation one local // linearization point. Enter admits a commit while Block prevents new commits // and waits for already-admitted commits to leave. A failed activation may keep diff --git a/pkg/frontend/txn.go b/pkg/frontend/txn.go index db86636763af9..a3a0d188c3d60 100644 --- a/pkg/frontend/txn.go +++ b/pkg/frontend/txn.go @@ -1038,6 +1038,7 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { } } var revokedPublicationErr error + var revocationCompletion DDLRevocationCompletion if haveDDL && !commitTs.IsEmpty() && (err == nil || commitResultUnknown) { recordDDLCommitFrontier(execCtx.ses.GetService(), commitTs) if execCtx.ses.GetFromRealUser() || @@ -1051,6 +1052,9 @@ func (th *TxnHandler) commitUnsafe(execCtx *ExecCtx) error { ); publishErr != nil { if errors.Is(publishErr, ErrDDLFrontierPublishedByRevokedGeneration) { revokedPublicationErr = publishErr + if errors.As(publishErr, &revocationCompletion) { + defer revocationCompletion.CompleteDDLRevocation() + } } else { err = errors.Join(err, publishErr) } diff --git a/pkg/frontend/txn_test.go b/pkg/frontend/txn_test.go index e7eabe4fbeff0..caa98dc9bf15e 100644 --- a/pkg/frontend/txn_test.go +++ b/pkg/frontend/txn_test.go @@ -865,6 +865,21 @@ type ddlSyncRequest struct { commitTS timestamp.Timestamp } +type testDDLRevocationCompletionError struct { + drainStarted chan struct{} + once sync.Once +} + +func (e *testDDLRevocationCompletionError) Error() string { + return ErrDDLFrontierPublishedByRevokedGeneration.Error() +} +func (e *testDDLRevocationCompletionError) Unwrap() error { + return ErrDDLFrontierPublishedByRevokedGeneration +} +func (e *testDDLRevocationCompletionError) CompleteDDLRevocation() { + e.once.Do(func() { close(e.drainStarted) }) +} + type ddlSyncQueryClient struct { serviceID string sendError map[string]error @@ -1046,15 +1061,21 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { defer execCtx.Close() gate := NewDDLCommitGate() var authoritativeFrontier timestamp.Timestamp - generationErr := errors.Join( - ErrDDLFrontierPublishedByRevokedGeneration, - errors.New("generation 1 replaced by generation 2")) + generationErr := &testDDLRevocationCompletionError{drainStarted: make(chan struct{})} gate.SetFrontierPublisher(func(_ context.Context, ts timestamp.Timestamp) error { // Model generation 1's already-admitted commit being durably absorbed - // after generation 2 has taken ownership. + // after generation 2 has taken ownership. Physical frontend drain waits + // for CompleteDDLRevocation after this owner's mandatory fan-out. authoritativeFrontier = ts return generationErr }) + qc.beforeSend = func() { + select { + case <-generationErr.drainStarted: + t.Fatal("frontend drain started before stale DDL visibility fan-out") + default: + } + } rt := moruntime.ServiceRuntime(ses.GetService()) previousGate, hadPreviousGate := rt.GetGlobalVariables(DDLCommitGateRuntimeKey) rt.SetGlobalVariables(DDLCommitGateRuntimeKey, gate) @@ -1071,6 +1092,11 @@ func TestCommitSyncsDDLCommitToBarrierReadyCNs(t *testing.T) { err := ses.GetTxnHandler().Commit(execCtx) require.ErrorIs(t, err, ErrDDLFrontierPublishedByRevokedGeneration) require.Equal(t, commitTS, authoritativeFrontier) + select { + case <-generationErr.drainStarted: + default: + t.Fatal("frontend drain completion was not released after fan-out") + } require.Equal(t, []ddlSyncRequest{ {address: "cn-1:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, {address: "cn-2:6001", method: querypb.CmdMethod_SyncCommitV2, commitTS: commitTS}, diff --git a/pkg/hakeeper/view_metadata_admission.go b/pkg/hakeeper/view_metadata_admission.go index 6603b173fe56f..f862c1ca20925 100644 --- a/pkg/hakeeper/view_metadata_admission.go +++ b/pkg/hakeeper/view_metadata_admission.go @@ -449,7 +449,7 @@ func (s *stateMachine) handleEnableViewMetadataAdmission(cmd []byte) sm.Result { func (s *stateMachine) updateCNViewMetadataAdmission(hb pb.CNStoreHeartbeat) bool { previous, existed := s.state.CNState.Stores[hb.UUID] active := s.viewMetadataAdmissionActive() - if active && existed && + if existed && previous.ViewMetadataAdmissionGeneration > 0 && hb.ViewMetadataAdmissionGeneration < previous.ViewMetadataAdmissionGeneration { // The old incarnation may have entered the public DDL gate before its // replacement took ownership and committed T afterwards. Reject all diff --git a/pkg/hakeeper/view_metadata_admission_test.go b/pkg/hakeeper/view_metadata_admission_test.go index 9ac66e2148b17..f9034f48f96cf 100644 --- a/pkg/hakeeper/view_metadata_admission_test.go +++ b/pkg/hakeeper/view_metadata_admission_test.go @@ -208,7 +208,7 @@ func TestViewMetadataAdmissionRejectsStaleGeneration(t *testing.T) { rsm.state.CNState.Stores["cn-1"].ViewMetadataAdmissionGeneration) } -func TestViewMetadataAdmissionAllowsGenerationRollbackBeforeActivation(t *testing.T) { +func TestCNGenerationCannotRollbackBeforeAdmissionActivation(t *testing.T) { rsm := NewStateMachine(0, 1).(*stateMachine) rsm.state.Tick = 3 updateViewMetadataCN(t, rsm, pb.CNStoreHeartbeat{ @@ -235,9 +235,9 @@ func TestViewMetadataAdmissionAllowsGenerationRollbackBeforeActivation(t *testin }) cn := rsm.state.CNState.Stores["cn-1"] - require.Equal(t, uint64(0), cn.ViewMetadataAdmissionGeneration) - require.Equal(t, uint64(7), cn.Tick) - require.Equal(t, "rolled-back-cn", cn.ServiceAddress) + require.Equal(t, uint64(12), cn.ViewMetadataAdmissionGeneration) + require.Equal(t, uint64(3), cn.Tick) + require.Equal(t, "new-cn", cn.ServiceAddress) proxy := rsm.state.ProxyState.Stores["proxy-1"] require.Equal(t, uint64(0), proxy.ViewMetadataAdmissionGeneration) require.Equal(t, uint64(7), proxy.Tick) diff --git a/pkg/tests/issues/isolated/issue_27743_ddl_consistency_test.go b/pkg/tests/issues/isolated/issue_27743_ddl_consistency_test.go new file mode 100644 index 0000000000000..c31612454abd3 --- /dev/null +++ b/pkg/tests/issues/isolated/issue_27743_ddl_consistency_test.go @@ -0,0 +1,97 @@ +// Copyright 2026 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package isolated + +import ( + "context" + "database/sql" + "fmt" + "testing" + "time" + + _ "github.com/go-sql-driver/mysql" + "github.com/matrixorigin/matrixone/pkg/cnservice" + "github.com/matrixorigin/matrixone/pkg/embed" + "github.com/matrixorigin/matrixone/pkg/util/fault" + "github.com/stretchr/testify/require" +) + +// The v44 epoch is monotonic and intentionally cannot be rolled back. Keep this +// activation regression in a dedicated process so it cannot alter the shared +// issue-test cluster used by unrelated tests. +func TestIssue27743DDLConsistency(t *testing.T) { + cluster, err := embed.StartTestCluster(embed.WithCNCount(2)) + require.NoError(t, err) + defer func() { require.NoError(t, cluster.Close()) }() + ctx, cancel := context.WithTimeout(context.Background(), 4*time.Minute) + defer cancel() + cn0, err := cluster.GetCNService(0) + require.NoError(t, err) + cn1, err := cluster.GetCNService(1) + require.NoError(t, err) + db0 := openIssue27743DB(t, cn0.GetServiceConfig().CN.Frontend.Port) + defer db0.Close() + db1 := openIssue27743DB(t, cn1.GetServiceConfig().CN.Frontend.Port) + defer db1.Close() + + const database = "issue_27743_automatic_ddl_visibility" + targets := cn0.ServiceID() + "," + cn1.ServiceID() + var activation string + require.NoError(t, db0.QueryRowContext(ctx, + "select mo_ctl('cn', 'SetProtocolVersion', ?)", targets+":44").Scan(&activation)) + require.Contains(t, activation, cn0.ServiceID()+":44") + require.Contains(t, activation, cn1.ServiceID()+":44") + execIssue27743SQL(t, ctx, db0, "drop database if exists `"+database+"`") + execIssue27743SQL(t, ctx, db0, "create database `"+database+"`") + defer func() { _, _ = db0.ExecContext(context.Background(), "drop database if exists `"+database+"`") }() + + require.True(t, fault.Enable()) + defer fault.Disable() + faultPointRemoved := false + defer func() { + if !faultPointRemoved { + _, _ = fault.RemoveFaultPoint(context.Background(), cnservice.DDLVisibilitySyncCommitFaultPoint) + } + }() + require.NoError(t, fault.AddFaultPoint(ctx, + cnservice.DDLVisibilitySyncCommitFaultPoint, "1:1::", "return", 0, "expected", false)) + _, err = db0.ExecContext(ctx, + "create table `"+database+"`.`must_fail_sync` (id int primary key)") + require.ErrorContains(t, err, "injected DDL visibility sync commit error") + _, err = fault.RemoveFaultPoint(ctx, cnservice.DDLVisibilitySyncCommitFaultPoint) + require.NoError(t, err) + faultPointRemoved = true + + execIssue27743SQL(t, ctx, db0, + "create table `"+database+"`.`t` (id int primary key, payload varchar(32))") + var count int + require.NoError(t, db1.QueryRowContext(ctx, + "select count(*) from `"+database+"`.`t`").Scan(&count)) + require.Zero(t, count) +} + +func openIssue27743DB(t *testing.T, port int64) *sql.DB { + t.Helper() + db, err := sql.Open("mysql", fmt.Sprintf("dump:111@tcp(127.0.0.1:%d)/?timeout=10s", port)) + require.NoError(t, err) + require.NoError(t, db.Ping()) + return db +} + +func execIssue27743SQL(t *testing.T, ctx context.Context, db *sql.DB, statement string) { + t.Helper() + _, err := db.ExecContext(ctx, statement) + require.NoError(t, err) +} diff --git a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go index 27ea07a16ae40..4cbd9eca72679 100644 --- a/pkg/tests/issues/issue_277xx_ddl_consistency_test.go +++ b/pkg/tests/issues/issue_277xx_ddl_consistency_test.go @@ -24,9 +24,7 @@ import ( "time" mysql "github.com/go-sql-driver/mysql" - "github.com/matrixorigin/matrixone/pkg/cnservice" "github.com/matrixorigin/matrixone/pkg/embed" - "github.com/matrixorigin/matrixone/pkg/util/fault" "github.com/stretchr/testify/require" ) @@ -44,47 +42,6 @@ func TestIssue277xxDDLConsistency(t *testing.T) { db1 := openIssue277xxDB(t, cn1.GetServiceConfig().CN.Frontend.Port) defer db1.Close() - t.Run("27743 automatic cross-CN DDL visibility", func(t *testing.T) { - const database = "issue_27743_automatic_ddl_visibility" - targets := cn0.ServiceID() + "," + cn1.ServiceID() - var activation string - require.NoError(t, db0.QueryRowContext(ctx, - "select mo_ctl('cn', 'SetProtocolVersion', ?)", targets+":44").Scan(&activation)) - require.Contains(t, activation, cn0.ServiceID()+":44") - require.Contains(t, activation, cn1.ServiceID()+":44") - // SetProtocolVersion returns success only after both target RPCs report - // v44 and HAKeeper acknowledges the atomically committed v44 epoch. - - resetIssue277xxDatabase(t, ctx, db0, database) - defer execSQLMaybe(t, ctx, db0, "drop database if exists `"+database+"`") - - // Prove this public path actually executes SyncCommitV2: an injected - // receiver failure must make CREATE fail after v44 activation. - require.True(t, fault.Enable()) - defer fault.Disable() - faultPointRemoved := false - defer func() { - if !faultPointRemoved { - _, _ = fault.RemoveFaultPoint(context.Background(), cnservice.DDLVisibilitySyncCommitFaultPoint) - } - }() - require.NoError(t, fault.AddFaultPoint(ctx, - cnservice.DDLVisibilitySyncCommitFaultPoint, "1:1::", "return", 0, "expected", false)) - _, err := db0.ExecContext(ctx, - "create table `"+database+"`.`must_fail_sync` (id int primary key)") - require.ErrorContains(t, err, "injected DDL visibility sync commit error") - _, removeErr := fault.RemoveFaultPoint(ctx, cnservice.DDLVisibilitySyncCommitFaultPoint) - require.NoError(t, removeErr) - faultPointRemoved = true - - // Do not issue SYNCCOMMIT or retry the read. The v44 DDL commit contract - // must make the first fresh CN1 snapshot observe CN0's CREATE TABLE. - execSQLRequire(t, ctx, db0, - "create table `"+database+"`.`t` (id int primary key, payload varchar(32))") - require.Equal(t, 0, queryIssue277xxInt(t, ctx, db1, - "select count(*) from `"+database+"`.`t`")) - }) - t.Run("27735 qualified alter drop index without default database", func(t *testing.T) { const database = "issue_27735_qualified_drop" resetIssue277xxDatabase(t, ctx, db0, database)