vendor: sync with etcd master

Signed-off-by: Gyuho Lee <gyuhox@gmail.com>
This commit is contained in:
Gyuho Lee 2018-01-29 13:53:24 -08:00
parent fe694bdd9c
commit a297a9f69d
53 changed files with 634 additions and 386 deletions

8
Gopkg.lock generated
View File

@ -35,17 +35,17 @@
[[projects]] [[projects]]
name = "github.com/coreos/etcd" name = "github.com/coreos/etcd"
packages = [ packages = [
"auth/authpb",
"clientv3", "clientv3",
"etcdserver/api/v3rpc/rpctypes", "etcdserver/api/v3rpc/rpctypes",
"etcdserver/etcdserverpb", "etcdserver/etcdserverpb",
"mvcc/mvccpb", "internal/auth/authpb",
"internal/mvcc/mvccpb",
"pkg/cpuutil", "pkg/cpuutil",
"pkg/netutil", "pkg/netutil",
"pkg/report", "pkg/report",
"pkg/types" "pkg/types"
] ]
revision = "6178c450667c1ac804d364f9e7642bbee4a55824" revision = "1d99d3886f6cb5fb7ef13100c9587cc01820d38e"
source = "https://github.com/coreos/etcd" source = "https://github.com/coreos/etcd"
[[projects]] [[projects]]
@ -395,6 +395,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "67dabb882980ef9cf31a0c1c4cc352e722cc9d45da80bad7038d9476751edc1b" inputs-digest = "5f3fd3c1bb42b7e13f03ac35628c6743379babd27ebf047e5f1124fcc7f25125"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -2,11 +2,11 @@
# Direct dependencies # Direct dependencies
# v3.3.0 RC # master
[[constraint]] [[constraint]]
name = "github.com/coreos/etcd" name = "github.com/coreos/etcd"
source = "https://github.com/coreos/etcd" source = "https://github.com/coreos/etcd"
revision = "6178c450667c1ac804d364f9e7642bbee4a55824" revision = "1d99d3886f6cb5fb7ef13100c9587cc01820d38e"
# v1.7.5 # v1.7.5
[[constraint]] [[constraint]]

View File

@ -29,7 +29,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/coreos/etcd/version" "github.com/coreos/etcd/internal/version"
) )
var ( var (

View File

@ -19,8 +19,8 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/coreos/etcd/auth/authpb"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/internal/auth/authpb"
"google.golang.org/grpc" "google.golang.org/grpc"
) )

View File

@ -537,18 +537,19 @@ func toErr(ctx context.Context, err error) error {
if _, ok := err.(rpctypes.EtcdError); ok { if _, ok := err.(rpctypes.EtcdError); ok {
return err return err
} }
ev, _ := status.FromError(err) if ev, ok := status.FromError(err); ok {
code := ev.Code() code := ev.Code()
switch code { switch code {
case codes.DeadlineExceeded: case codes.DeadlineExceeded:
fallthrough fallthrough
case codes.Canceled: case codes.Canceled:
if ctx.Err() != nil { if ctx.Err() != nil {
err = ctx.Err() err = ctx.Err()
}
case codes.Unavailable:
case codes.FailedPrecondition:
err = grpc.ErrClientConnClosing
} }
case codes.Unavailable:
case codes.FailedPrecondition:
err = grpc.ErrClientConnClosing
} }
return err return err
} }

View File

@ -18,6 +18,7 @@ import (
"context" "context"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/pkg/types"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -66,6 +67,11 @@ func NewClusterFromClusterClient(remote pb.ClusterClient, c *Client) Cluster {
} }
func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) { func (c *cluster) MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) {
// fail-fast before panic in rafthttp
if _, err := types.NewURLs(peerAddrs); err != nil {
return nil, err
}
r := &pb.MemberAddRequest{PeerURLs: peerAddrs} r := &pb.MemberAddRequest{PeerURLs: peerAddrs}
resp, err := c.remote.MemberAdd(ctx, r, c.callOpts...) resp, err := c.remote.MemberAdd(ctx, r, c.callOpts...)
if err != nil { if err != nil {
@ -84,6 +90,11 @@ func (c *cluster) MemberRemove(ctx context.Context, id uint64) (*MemberRemoveRes
} }
func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) { func (c *cluster) MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) {
// fail-fast before panic in rafthttp
if _, err := types.NewURLs(peerAddrs); err != nil {
return nil, err
}
// it is safe to retry on update. // it is safe to retry on update.
r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs} r := &pb.MemberUpdateRequest{ID: id, PeerURLs: peerAddrs}
resp, err := c.remote.MemberUpdate(ctx, r, c.callOpts...) resp, err := c.remote.MemberUpdate(ctx, r, c.callOpts...)

View File

@ -57,6 +57,8 @@ type Maintenance interface {
HashKV(ctx context.Context, endpoint string, rev int64) (*HashKVResponse, error) HashKV(ctx context.Context, endpoint string, rev int64) (*HashKVResponse, error)
// Snapshot provides a reader for a point-in-time snapshot of etcd. // Snapshot provides a reader for a point-in-time snapshot of etcd.
// If the context "ctx" is canceled or timed out, reading from returned
// "io.ReadCloser" would error out (e.g. context.Canceled, context.DeadlineExceeded).
Snapshot(ctx context.Context) (io.ReadCloser, error) Snapshot(ctx context.Context) (io.ReadCloser, error)
// MoveLeader requests current leader to transfer its leadership to the transferee. // MoveLeader requests current leader to transfer its leadership to the transferee.

View File

@ -52,7 +52,10 @@ func isRepeatableStopError(err error) bool {
return true return true
} }
// only retry if unavailable // only retry if unavailable
ev, _ := status.FromError(err) ev, ok := status.FromError(err)
if !ok {
return false
}
return ev.Code() != codes.Unavailable return ev.Code() != codes.Unavailable
} }
@ -68,8 +71,7 @@ func isRepeatableStopError(err error) bool {
// Returning "true" means retry should stop, otherwise it violates // Returning "true" means retry should stop, otherwise it violates
// write-at-most-once semantics. // write-at-most-once semantics.
func isNonRepeatableStopError(err error) bool { func isNonRepeatableStopError(err error) bool {
ev, _ := status.FromError(err) if ev, ok := status.FromError(err); ok && ev.Code() != codes.Unavailable {
if ev.Code() != codes.Unavailable {
return true return true
} }
desc := rpctypes.ErrorDesc(err) desc := rpctypes.ErrorDesc(err)

View File

@ -22,7 +22,7 @@ import (
v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" v3rpc "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
mvccpb "github.com/coreos/etcd/mvcc/mvccpb" mvccpb "github.com/coreos/etcd/internal/mvcc/mvccpb"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
@ -46,6 +46,22 @@ type Watcher interface {
// through the returned channel. If revisions waiting to be sent over the // through the returned channel. If revisions waiting to be sent over the
// watch are compacted, then the watch will be canceled by the server, the // watch are compacted, then the watch will be canceled by the server, the
// client will post a compacted error watch response, and the channel will close. // client will post a compacted error watch response, and the channel will close.
// If the context "ctx" is canceled or timed out, returned "WatchChan" is closed,
// and "WatchResponse" from this closed channel has zero events and nil "Err()".
// The context "ctx" MUST be canceled, as soon as watcher is no longer being used,
// to release the associated resources.
// If the context is "context.Background/TODO", returned "WatchChan" will not be closed
// and wait until events happen, except when server returns a non-recoverable error.
// For example, when context passed with "WithRequireLeader" and the connected server
// has no leader, error "etcdserver: no leader" is returned, and then "WatchChan" is
// closed with non-nil "Err()".
// Otherwise, as long as the context has not been canceled or timed out, watch will
// retry on other recoverable errors forever until reconnected.
//
// TODO: explicitly set context error in the last "WatchResponse" message and close channel?
// Currently, client contexts are overwritten with "valCtx" that never closes.
// TODO(v3.4): configure watch retry policy, limit maximum retry number
// (see https://github.com/coreos/etcd/issues/8980)
Watch(ctx context.Context, key string, opts ...OpOption) WatchChan Watch(ctx context.Context, key string, opts ...OpOption) WatchChan
// Close closes the watcher and cancels all watch requests. // Close closes the watcher and cancels all watch requests.
@ -353,7 +369,8 @@ func (w *watcher) closeStream(wgs *watchGrpcStream) {
} }
func (w *watchGrpcStream) addSubstream(resp *pb.WatchResponse, ws *watcherStream) { func (w *watchGrpcStream) addSubstream(resp *pb.WatchResponse, ws *watcherStream) {
if resp.WatchId == -1 { // check watch ID for backward compatibility (<= v3.3)
if resp.WatchId == -1 || (resp.Canceled && resp.CancelReason != "") {
// failed; no channel // failed; no channel
close(ws.recvc) close(ws.recvc)
return return
@ -439,6 +456,7 @@ func (w *watchGrpcStream) run() {
// Watch() requested // Watch() requested
case wreq := <-w.reqc: case wreq := <-w.reqc:
outc := make(chan WatchResponse, 1) outc := make(chan WatchResponse, 1)
// TODO: pass custom watch ID?
ws := &watcherStream{ ws := &watcherStream{
initReq: *wreq, initReq: *wreq,
id: -1, id: -1,
@ -539,6 +557,7 @@ func (w *watchGrpcStream) dispatchEvent(pbresp *pb.WatchResponse) bool {
for i, ev := range pbresp.Events { for i, ev := range pbresp.Events {
events[i] = (*Event)(ev) events[i] = (*Event)(ev)
} }
// TODO: return watch ID?
wr := &WatchResponse{ wr := &WatchResponse{
Header: *pbresp.Header, Header: *pbresp.Header,
Events: events, Events: events,

View File

@ -17,7 +17,8 @@ package api
import ( import (
"sync" "sync"
"github.com/coreos/etcd/version" "github.com/coreos/etcd/internal/version"
"github.com/coreos/go-semver/semver" "github.com/coreos/go-semver/semver"
"github.com/coreos/pkg/capnslog" "github.com/coreos/pkg/capnslog"
) )

View File

@ -21,7 +21,7 @@ import (
"github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/lease"
) )
type LeaseServer struct { type LeaseServer struct {

View File

@ -19,14 +19,15 @@ import (
"crypto/sha256" "crypto/sha256"
"io" "io"
"github.com/coreos/etcd/auth"
"github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/auth"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc"
"github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/internal/version"
"github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/pkg/types"
"github.com/coreos/etcd/version" "github.com/coreos/etcd/raft"
) )
type KVGetter interface { type KVGetter interface {
@ -38,6 +39,9 @@ type BackendGetter interface {
} }
type Alarmer interface { type Alarmer interface {
// Alarms is implemented in Server interface located in etcdserver/server.go
// It returns a list of alarms present in the AlarmStore
Alarms() []*pb.AlarmMember
Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error) Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error)
} }
@ -153,12 +157,22 @@ func (ms *maintenanceServer) Alarm(ctx context.Context, ar *pb.AlarmRequest) (*p
func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) { func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) {
resp := &pb.StatusResponse{ resp := &pb.StatusResponse{
Header: &pb.ResponseHeader{Revision: ms.hdr.rev()}, Header: &pb.ResponseHeader{Revision: ms.hdr.rev()},
Version: version.Version, Version: version.Version,
DbSize: ms.bg.Backend().Size(), DbSize: ms.bg.Backend().Size(),
Leader: uint64(ms.rg.Leader()), Leader: uint64(ms.rg.Leader()),
RaftIndex: ms.rg.Index(), RaftIndex: ms.rg.Index(),
RaftTerm: ms.rg.Term(), RaftTerm: ms.rg.Term(),
RaftAppliedIndex: ms.rg.AppliedIndex(),
}
if uint64(ms.rg.Leader()) == raft.None {
resp.Errors = append(resp.Errors, etcdserver.ErrNoLeader.Error())
}
alarms := ms.a.Alarms()
if len(alarms) > 0 {
for _, alarm := range alarms {
resp.Errors = append(resp.Errors, alarm.String())
}
} }
ms.hdr.fill(resp.Header) ms.hdr.fill(resp.Header)
return resp, nil return resp, nil

View File

@ -16,13 +16,14 @@ package v3rpc
import ( import (
"context" "context"
"strings"
"github.com/coreos/etcd/auth"
"github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
"github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/etcdserver/membership"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/auth"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/internal/mvcc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -91,6 +92,25 @@ func isClientCtxErr(ctxErr error, err error) bool {
if !ok { if !ok {
return false return false
} }
code := ev.Code()
return code == codes.Canceled || code == codes.DeadlineExceeded switch ev.Code() {
case codes.Canceled, codes.DeadlineExceeded:
// client-side context cancel or deadline exceeded
// "rpc error: code = Canceled desc = context canceled"
// "rpc error: code = DeadlineExceeded desc = context deadline exceeded"
return true
case codes.Unavailable:
msg := ev.Message()
// client-side context cancel or deadline exceeded with TLS ("http2.errClientDisconnected")
// "rpc error: code = Unavailable desc = client disconnected"
if msg == "client disconnected" {
return true
}
// "grpc/transport.ClientTransport.CloseStream" on canceled streams
// "rpc error: code = Unavailable desc = stream error: stream ID 21; CANCEL")
if strings.HasPrefix(msg, "stream error: ") && strings.HasSuffix(msg, "; CANCEL") {
return true
}
}
return false
} }

View File

@ -20,12 +20,12 @@ import (
"sync" "sync"
"time" "time"
"github.com/coreos/etcd/auth"
"github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/auth"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc"
"github.com/coreos/etcd/internal/mvcc/mvccpb"
) )
type watchServer struct { type watchServer struct {
@ -209,7 +209,7 @@ func (sws *serverWatchStream) recvLoop() error {
if !sws.isWatchPermitted(creq) { if !sws.isWatchPermitted(creq) {
wr := &pb.WatchResponse{ wr := &pb.WatchResponse{
Header: sws.newResponseHeader(sws.watchStream.Rev()), Header: sws.newResponseHeader(sws.watchStream.Rev()),
WatchId: -1, WatchId: creq.WatchId,
Canceled: true, Canceled: true,
Created: true, Created: true,
CancelReason: rpctypes.ErrGRPCPermissionDenied.Error(), CancelReason: rpctypes.ErrGRPCPermissionDenied.Error(),
@ -229,8 +229,8 @@ func (sws *serverWatchStream) recvLoop() error {
if rev == 0 { if rev == 0 {
rev = wsrev + 1 rev = wsrev + 1
} }
id := sws.watchStream.Watch(creq.Key, creq.RangeEnd, rev, filters...) id, err := sws.watchStream.Watch(mvcc.WatchID(creq.WatchId), creq.Key, creq.RangeEnd, rev, filters...)
if id != -1 { if err == nil {
sws.mu.Lock() sws.mu.Lock()
if creq.ProgressNotify { if creq.ProgressNotify {
sws.progress[id] = true sws.progress[id] = true
@ -244,7 +244,10 @@ func (sws *serverWatchStream) recvLoop() error {
Header: sws.newResponseHeader(wsrev), Header: sws.newResponseHeader(wsrev),
WatchId: int64(id), WatchId: int64(id),
Created: true, Created: true,
Canceled: id == -1, Canceled: err != nil,
}
if err != nil {
wr.CancelReason = err.Error()
} }
select { select {
case sws.ctrlStream <- wr: case sws.ctrlStream <- wr:

View File

@ -20,11 +20,11 @@ import (
"sort" "sort"
"time" "time"
"github.com/coreos/etcd/auth"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/auth"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc"
"github.com/coreos/etcd/internal/mvcc/mvccpb"
"github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/pkg/types"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"

View File

@ -17,10 +17,10 @@ package etcdserver
import ( import (
"sync" "sync"
"github.com/coreos/etcd/auth"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/auth"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/internal/mvcc"
) )
type authApplierV3 struct { type authApplierV3 struct {

View File

@ -21,8 +21,8 @@ import (
"github.com/coreos/etcd/etcdserver/api" "github.com/coreos/etcd/etcdserver/api"
"github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/etcdserver/membership"
"github.com/coreos/etcd/internal/store"
"github.com/coreos/etcd/pkg/pbutil" "github.com/coreos/etcd/pkg/pbutil"
"github.com/coreos/etcd/store"
"github.com/coreos/go-semver/semver" "github.com/coreos/go-semver/semver"
) )

View File

@ -19,11 +19,11 @@ import (
"os" "os"
"time" "time"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/mvcc"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/internal/raftsnap"
"github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/snap"
) )
func newBackend(cfg ServerConfig) backend.Backend { func newBackend(cfg ServerConfig) backend.Backend {
@ -37,7 +37,7 @@ func newBackend(cfg ServerConfig) backend.Backend {
} }
// openSnapshotBackend renames a snapshot db to the current etcd db and opens it. // openSnapshotBackend renames a snapshot db to the current etcd db and opens it.
func openSnapshotBackend(cfg ServerConfig, ss *snap.Snapshotter, snapshot raftpb.Snapshot) (backend.Backend, error) { func openSnapshotBackend(cfg ServerConfig, ss *raftsnap.Snapshotter, snapshot raftpb.Snapshot) (backend.Backend, error) {
snapPath, err := ss.DBFilePath(snapshot.Metadata.Index) snapPath, err := ss.DBFilePath(snapshot.Metadata.Index)
if err != nil { if err != nil {
return nil, fmt.Errorf("database snapshot file path error: %v", err) return nil, fmt.Errorf("database snapshot file path error: %v", err)
@ -58,8 +58,8 @@ func openBackend(cfg ServerConfig) backend.Backend {
select { select {
case be := <-beOpened: case be := <-beOpened:
return be return be
case <-time.After(time.Second): case <-time.After(10 * time.Second):
plog.Warningf("another etcd process is using %q and holds the file lock.", fn) plog.Warningf("another etcd process is using %q and holds the file lock, or loading backend file is taking >10 seconds", fn)
plog.Warningf("waiting for it to exit before starting...") plog.Warningf("waiting for it to exit before starting...")
} }
return <-beOpened return <-beOpened
@ -77,5 +77,5 @@ func recoverSnapshotBackend(cfg ServerConfig, oldbe backend.Backend, snapshot ra
return oldbe, nil return oldbe, nil
} }
oldbe.Close() oldbe.Close()
return openSnapshotBackend(cfg, snap.New(cfg.SnapDir()), snapshot) return openSnapshotBackend(cfg, raftsnap.New(cfg.SnapDir()), snapshot)
} }

View File

@ -23,8 +23,9 @@ import (
"time" "time"
"github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/etcdserver/membership"
"github.com/coreos/etcd/internal/version"
"github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/pkg/types"
"github.com/coreos/etcd/version"
"github.com/coreos/go-semver/semver" "github.com/coreos/go-semver/semver"
) )

View File

@ -124,7 +124,8 @@ func (c *ServerConfig) advertiseMatchesCluster() error {
sort.Strings(apurls) sort.Strings(apurls)
ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second)
defer cancel() defer cancel()
if netutil.URLStringsEqual(ctx, apurls, urls.StringSlice()) { ok, err := netutil.URLStringsEqual(ctx, apurls, urls.StringSlice())
if ok {
return nil return nil
} }
@ -148,7 +149,7 @@ func (c *ServerConfig) advertiseMatchesCluster() error {
} }
mstr := strings.Join(missing, ",") mstr := strings.Join(missing, ",")
apStr := strings.Join(apurls, ",") apStr := strings.Join(apurls, ",")
return fmt.Errorf("--initial-cluster has %s but missing from --initial-advertise-peer-urls=%s ", mstr, apStr) return fmt.Errorf("--initial-cluster has %s but missing from --initial-advertise-peer-urls=%s (%v)", mstr, apStr, err)
} }
for url := range apMap { for url := range apMap {
@ -156,9 +157,16 @@ func (c *ServerConfig) advertiseMatchesCluster() error {
missing = append(missing, url) missing = append(missing, url)
} }
} }
mstr := strings.Join(missing, ",") if len(missing) > 0 {
mstr := strings.Join(missing, ",")
umap := types.URLsMap(map[string]types.URLs{c.Name: c.PeerURLs})
return fmt.Errorf("--initial-advertise-peer-urls has %s but missing from --initial-cluster=%s", mstr, umap.String())
}
// resolved URLs from "--initial-advertise-peer-urls" and "--initial-cluster" did not match or failed
apStr := strings.Join(apurls, ",")
umap := types.URLsMap(map[string]types.URLs{c.Name: c.PeerURLs}) umap := types.URLsMap(map[string]types.URLs{c.Name: c.PeerURLs})
return fmt.Errorf("--initial-advertise-peer-urls has %s but missing from --initial-cluster=%s", mstr, umap.String()) return fmt.Errorf("failed to resolve %s to match --initial-cluster=%s (%v)", apStr, umap.String(), err)
} }
func (c *ServerConfig) MemberDir() string { return filepath.Join(c.DataDir, "member") } func (c *ServerConfig) MemberDir() string { return filepath.Join(c.DataDir, "member") }

View File

@ -22,7 +22,7 @@ import (
"github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/mvcc"
"github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/pkg/types"
) )

View File

@ -12,9 +12,9 @@ import (
_ "github.com/gogo/protobuf/gogoproto" _ "github.com/gogo/protobuf/gogoproto"
mvccpb "github.com/coreos/etcd/mvcc/mvccpb" mvccpb "github.com/coreos/etcd/internal/mvcc/mvccpb"
authpb "github.com/coreos/etcd/auth/authpb" authpb "github.com/coreos/etcd/internal/auth/authpb"
context "golang.org/x/net/context" context "golang.org/x/net/context"
@ -1620,6 +1620,12 @@ type WatchCreateRequest struct {
// If prev_kv is set, created watcher gets the previous KV before the event happens. // If prev_kv is set, created watcher gets the previous KV before the event happens.
// If the previous KV is already compacted, nothing will be returned. // If the previous KV is already compacted, nothing will be returned.
PrevKv bool `protobuf:"varint,6,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"` PrevKv bool `protobuf:"varint,6,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"`
// If watch_id is provided and non-zero, it will be assigned to this watcher.
// Since creating a watcher in etcd is not a synchronous operation,
// this can be used ensure that ordering is correct when creating multiple
// watchers on the same stream. Creating a watcher with an ID already in
// use on the stream will cause an error to be returned.
WatchId int64 `protobuf:"varint,7,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"`
} }
func (m *WatchCreateRequest) Reset() { *m = WatchCreateRequest{} } func (m *WatchCreateRequest) Reset() { *m = WatchCreateRequest{} }
@ -1669,6 +1675,13 @@ func (m *WatchCreateRequest) GetPrevKv() bool {
return false return false
} }
func (m *WatchCreateRequest) GetWatchId() int64 {
if m != nil {
return m.WatchId
}
return 0
}
type WatchCancelRequest struct { type WatchCancelRequest struct {
// watch_id is the watcher id to cancel so that no more events are transmitted. // watch_id is the watcher id to cancel so that no more events are transmitted.
WatchId int64 `protobuf:"varint,1,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"` WatchId int64 `protobuf:"varint,1,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"`
@ -2431,6 +2444,10 @@ type StatusResponse struct {
RaftIndex uint64 `protobuf:"varint,5,opt,name=raftIndex,proto3" json:"raftIndex,omitempty"` RaftIndex uint64 `protobuf:"varint,5,opt,name=raftIndex,proto3" json:"raftIndex,omitempty"`
// raftTerm is the current raft term of the responding member. // raftTerm is the current raft term of the responding member.
RaftTerm uint64 `protobuf:"varint,6,opt,name=raftTerm,proto3" json:"raftTerm,omitempty"` RaftTerm uint64 `protobuf:"varint,6,opt,name=raftTerm,proto3" json:"raftTerm,omitempty"`
// raftAppliedIndex is the current raft applied index of the responding member.
RaftAppliedIndex uint64 `protobuf:"varint,7,opt,name=raftAppliedIndex,proto3" json:"raftAppliedIndex,omitempty"`
// errors contains alarm/health information and status.
Errors []string `protobuf:"bytes,8,rep,name=errors" json:"errors,omitempty"`
} }
func (m *StatusResponse) Reset() { *m = StatusResponse{} } func (m *StatusResponse) Reset() { *m = StatusResponse{} }
@ -2480,6 +2497,20 @@ func (m *StatusResponse) GetRaftTerm() uint64 {
return 0 return 0
} }
func (m *StatusResponse) GetRaftAppliedIndex() uint64 {
if m != nil {
return m.RaftAppliedIndex
}
return 0
}
func (m *StatusResponse) GetErrors() []string {
if m != nil {
return m.Errors
}
return nil
}
type AuthEnableRequest struct { type AuthEnableRequest struct {
} }
@ -5919,6 +5950,11 @@ func (m *WatchCreateRequest) MarshalTo(dAtA []byte) (int, error) {
} }
i++ i++
} }
if m.WatchId != 0 {
dAtA[i] = 0x38
i++
i = encodeVarintRpc(dAtA, i, uint64(m.WatchId))
}
return i, nil return i, nil
} }
@ -6978,6 +7014,26 @@ func (m *StatusResponse) MarshalTo(dAtA []byte) (int, error) {
i++ i++
i = encodeVarintRpc(dAtA, i, uint64(m.RaftTerm)) i = encodeVarintRpc(dAtA, i, uint64(m.RaftTerm))
} }
if m.RaftAppliedIndex != 0 {
dAtA[i] = 0x38
i++
i = encodeVarintRpc(dAtA, i, uint64(m.RaftAppliedIndex))
}
if len(m.Errors) > 0 {
for _, s := range m.Errors {
dAtA[i] = 0x42
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil return i, nil
} }
@ -8408,6 +8464,9 @@ func (m *WatchCreateRequest) Size() (n int) {
if m.PrevKv { if m.PrevKv {
n += 2 n += 2
} }
if m.WatchId != 0 {
n += 1 + sovRpc(uint64(m.WatchId))
}
return n return n
} }
@ -8838,6 +8897,15 @@ func (m *StatusResponse) Size() (n int) {
if m.RaftTerm != 0 { if m.RaftTerm != 0 {
n += 1 + sovRpc(uint64(m.RaftTerm)) n += 1 + sovRpc(uint64(m.RaftTerm))
} }
if m.RaftAppliedIndex != 0 {
n += 1 + sovRpc(uint64(m.RaftAppliedIndex))
}
if len(m.Errors) > 0 {
for _, s := range m.Errors {
l = len(s)
n += 1 + l + sovRpc(uint64(l))
}
}
return n return n
} }
@ -12309,6 +12377,25 @@ func (m *WatchCreateRequest) Unmarshal(dAtA []byte) error {
} }
} }
m.PrevKv = bool(v != 0) m.PrevKv = bool(v != 0)
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field WatchId", wireType)
}
m.WatchId = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.WatchId |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipRpc(dAtA[iNdEx:]) skippy, err := skipRpc(dAtA[iNdEx:])
@ -15443,6 +15530,54 @@ func (m *StatusResponse) Unmarshal(dAtA []byte) error {
break break
} }
} }
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field RaftAppliedIndex", wireType)
}
m.RaftAppliedIndex = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.RaftAppliedIndex |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Errors", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRpc
}
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 ErrInvalidLengthRpc
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Errors = append(m.Errors, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipRpc(dAtA[iNdEx:]) skippy, err := skipRpc(dAtA[iNdEx:])
@ -18431,235 +18566,237 @@ var (
func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) } func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) }
var fileDescriptorRpc = []byte{ var fileDescriptorRpc = []byte{
// 3669 bytes of a gzipped FileDescriptorProto // 3708 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5b, 0x5b, 0x6f, 0x23, 0xc7, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5b, 0x5b, 0x6f, 0x1b, 0x49,
0x72, 0xd6, 0x90, 0x22, 0x29, 0x16, 0x2f, 0xe2, 0xb6, 0xb4, 0xbb, 0x14, 0x77, 0x57, 0xab, 0xed, 0x76, 0x56, 0x93, 0xe2, 0xed, 0xf0, 0x22, 0xba, 0x24, 0xdb, 0x34, 0x6d, 0xcb, 0x72, 0xf9, 0x26,
0xbd, 0x69, 0x2f, 0x16, 0x6d, 0xd9, 0xc9, 0xc3, 0x26, 0x30, 0xac, 0x95, 0xe8, 0x95, 0x2c, 0xad, 0x5f, 0x46, 0xdc, 0xd5, 0x6e, 0xf2, 0xe0, 0x04, 0x8b, 0x95, 0x25, 0xae, 0xa5, 0x95, 0x2c, 0x69,
0x24, 0x8f, 0xa8, 0xb5, 0x03, 0x38, 0x11, 0x46, 0x64, 0x4b, 0x62, 0x44, 0xce, 0x30, 0x33, 0x43, 0x5b, 0x94, 0x67, 0x02, 0x6c, 0x22, 0xb4, 0xc8, 0x92, 0xd4, 0x11, 0xd9, 0xcd, 0x74, 0x37, 0x69,
0xae, 0xb4, 0x31, 0x12, 0xc0, 0x71, 0x82, 0xbc, 0xe4, 0x25, 0x06, 0x82, 0xc4, 0xaf, 0x41, 0x60, 0xc9, 0x59, 0x24, 0xc0, 0x66, 0x13, 0xe4, 0x25, 0x79, 0xc8, 0x02, 0x41, 0x92, 0xd7, 0x20, 0x58,
0xf8, 0x07, 0x04, 0xf9, 0x0b, 0x41, 0x5e, 0x12, 0x20, 0x7f, 0xe0, 0xc0, 0xe7, 0xbc, 0x9c, 0x5f, 0xec, 0x0f, 0x18, 0xe4, 0x2f, 0xe4, 0x2d, 0x01, 0xf2, 0x07, 0x82, 0x49, 0x5e, 0xf2, 0x0b, 0x72,
0x70, 0x2e, 0x4f, 0x07, 0x7d, 0x9b, 0xe9, 0xb9, 0x51, 0xb2, 0x69, 0xfb, 0x45, 0x3b, 0x5d, 0x5d, 0x79, 0x5a, 0xd4, 0xad, 0xbb, 0xfa, 0x46, 0x69, 0x86, 0x33, 0xf3, 0x22, 0x77, 0x9d, 0x3e, 0x75,
0x5d, 0x55, 0x5d, 0xdd, 0x55, 0xd5, 0xfd, 0x35, 0x17, 0xf2, 0x76, 0xbf, 0xb5, 0xd4, 0xb7, 0x2d, 0xce, 0xa9, 0x53, 0x75, 0x2e, 0xf5, 0x35, 0x0d, 0x25, 0x67, 0xd8, 0x5d, 0x19, 0x3a, 0xb6, 0x67,
0xd7, 0x42, 0x45, 0xe2, 0xb6, 0xda, 0x0e, 0xb1, 0x87, 0xc4, 0xee, 0x1f, 0xd6, 0x66, 0x8f, 0xad, 0xa3, 0x0a, 0xf1, 0xba, 0x3d, 0x97, 0x38, 0x63, 0xe2, 0x0c, 0x8f, 0x9b, 0x0b, 0xa7, 0xf6, 0xa9,
0x63, 0x8b, 0x75, 0xd4, 0xe9, 0x17, 0xe7, 0xa9, 0xcd, 0x51, 0x9e, 0x7a, 0x6f, 0xd8, 0x6a, 0xb1, 0xcd, 0x5e, 0xb4, 0xe8, 0x13, 0xe7, 0x69, 0x62, 0xca, 0xd3, 0x32, 0x2d, 0x8f, 0x38, 0x96, 0xd1,
0x3f, 0xfd, 0xc3, 0xfa, 0xe9, 0x50, 0x74, 0xdd, 0x60, 0x5d, 0xc6, 0xc0, 0x3d, 0x61, 0x7f, 0xfa, 0x6f, 0x0d, 0xc6, 0xdd, 0x2e, 0xfb, 0x33, 0x3c, 0x6e, 0x9d, 0x8f, 0x05, 0xcf, 0xe3, 0x30, 0x8f,
0x87, 0xec, 0x1f, 0xd1, 0x79, 0xf3, 0xd8, 0xb2, 0x8e, 0xbb, 0xa4, 0x6e, 0xf4, 0x3b, 0x75, 0xc3, 0x31, 0xf2, 0xce, 0xd8, 0x9f, 0xe1, 0x31, 0xfb, 0x47, 0x70, 0xdd, 0x3b, 0xb5, 0xed, 0xd3, 0x3e,
0x34, 0x2d, 0xd7, 0x70, 0x3b, 0x96, 0xe9, 0xf0, 0x5e, 0xfc, 0xf7, 0x1a, 0x94, 0x75, 0xe2, 0xf4, 0x69, 0x19, 0x43, 0xb3, 0x65, 0x58, 0x96, 0xed, 0x19, 0x9e, 0x69, 0x5b, 0x2e, 0x7f, 0x8b, 0xff,
0x2d, 0xd3, 0x21, 0xeb, 0xc4, 0x68, 0x13, 0x1b, 0xdd, 0x02, 0x68, 0x75, 0x07, 0x8e, 0x4b, 0xec, 0x5c, 0x83, 0x9a, 0x4e, 0xdc, 0xa1, 0x6d, 0xb9, 0x64, 0x93, 0x18, 0x3d, 0xe2, 0xa0, 0xfb, 0x00,
0x83, 0x4e, 0xbb, 0xaa, 0x2d, 0x68, 0x8b, 0x93, 0x7a, 0x5e, 0x50, 0x36, 0xda, 0xe8, 0x06, 0xe4, 0xdd, 0xfe, 0xc8, 0xf5, 0x88, 0x73, 0x64, 0xf6, 0x1a, 0xda, 0x92, 0xb6, 0x3c, 0xab, 0x97, 0x04,
0x7b, 0xa4, 0x77, 0xc8, 0x7b, 0x53, 0xac, 0x77, 0x8a, 0x13, 0x36, 0xda, 0xa8, 0x06, 0x53, 0x36, 0x65, 0xab, 0x87, 0xee, 0x42, 0x69, 0x40, 0x06, 0xc7, 0xfc, 0x6d, 0x86, 0xbd, 0x2d, 0x72, 0xc2,
0x19, 0x76, 0x9c, 0x8e, 0x65, 0x56, 0xd3, 0x0b, 0xda, 0x62, 0x5a, 0xf7, 0xda, 0x74, 0xa0, 0x6d, 0x56, 0x0f, 0x35, 0xa1, 0xe8, 0x90, 0xb1, 0xe9, 0x9a, 0xb6, 0xd5, 0xc8, 0x2e, 0x69, 0xcb, 0x59,
0x1c, 0xb9, 0x07, 0x2e, 0xb1, 0x7b, 0xd5, 0x49, 0x3e, 0x90, 0x12, 0x9a, 0xc4, 0xee, 0xe1, 0x2f, 0xdd, 0x1f, 0xd3, 0x89, 0x8e, 0x71, 0xe2, 0x1d, 0x79, 0xc4, 0x19, 0x34, 0x66, 0xf9, 0x44, 0x4a,
0x33, 0x50, 0xd4, 0x0d, 0xf3, 0x98, 0xe8, 0xe4, 0xaf, 0x06, 0xc4, 0x71, 0x51, 0x05, 0xd2, 0xa7, 0xe8, 0x10, 0x67, 0x80, 0x7f, 0x91, 0x83, 0x8a, 0x6e, 0x58, 0xa7, 0x44, 0x27, 0x7f, 0x34, 0x22,
0xe4, 0x9c, 0xa9, 0x2f, 0xea, 0xf4, 0x93, 0x8f, 0x37, 0x8f, 0xc9, 0x01, 0x31, 0xb9, 0xe2, 0x22, 0xae, 0x87, 0xea, 0x90, 0x3d, 0x27, 0x97, 0x4c, 0x7d, 0x45, 0xa7, 0x8f, 0x7c, 0xbe, 0x75, 0x4a,
0x1d, 0x6f, 0x1e, 0x93, 0x86, 0xd9, 0x46, 0xb3, 0x90, 0xe9, 0x76, 0x7a, 0x1d, 0x57, 0x68, 0xe5, 0x8e, 0x88, 0xc5, 0x15, 0x57, 0xe8, 0x7c, 0xeb, 0x94, 0xb4, 0xad, 0x1e, 0x5a, 0x80, 0x5c, 0xdf,
0x8d, 0x80, 0x39, 0x93, 0x21, 0x73, 0x56, 0x01, 0x1c, 0xcb, 0x76, 0x0f, 0x2c, 0xbb, 0x4d, 0xec, 0x1c, 0x98, 0x9e, 0xd0, 0xca, 0x07, 0x21, 0x73, 0x66, 0x23, 0xe6, 0xac, 0x03, 0xb8, 0xb6, 0xe3,
0x6a, 0x66, 0x41, 0x5b, 0x2c, 0x2f, 0xdf, 0x5b, 0x52, 0x17, 0x62, 0x49, 0x35, 0x68, 0x69, 0xcf, 0x1d, 0xd9, 0x4e, 0x8f, 0x38, 0x8d, 0xdc, 0x92, 0xb6, 0x5c, 0x5b, 0x7d, 0xbc, 0xa2, 0x6e, 0xcd,
0xb2, 0xdd, 0x1d, 0xca, 0xab, 0xe7, 0x1d, 0xf9, 0x89, 0x3e, 0x84, 0x02, 0x13, 0xe2, 0x1a, 0xf6, 0x8a, 0x6a, 0xd0, 0xca, 0x81, 0xed, 0x78, 0x7b, 0x94, 0x57, 0x2f, 0xb9, 0xf2, 0x11, 0xfd, 0x08,
0x31, 0x71, 0xab, 0x59, 0x26, 0xe5, 0xfe, 0x05, 0x52, 0x9a, 0x8c, 0x59, 0x67, 0xea, 0xf9, 0x37, 0xca, 0x4c, 0x88, 0x67, 0x38, 0xa7, 0xc4, 0x6b, 0xe4, 0x99, 0x94, 0x27, 0x57, 0x48, 0xe9, 0x30,
0xc2, 0x50, 0x74, 0x88, 0xdd, 0x31, 0xba, 0x9d, 0x37, 0xc6, 0x61, 0x97, 0x54, 0x73, 0x0b, 0xda, 0x66, 0x9d, 0xa9, 0xe7, 0xcf, 0x08, 0x43, 0xc5, 0x25, 0x8e, 0x69, 0xf4, 0xcd, 0x8f, 0xc6, 0x71,
0xe2, 0x94, 0x1e, 0xa0, 0xd1, 0xf9, 0x9f, 0x92, 0x73, 0xe7, 0xc0, 0x32, 0xbb, 0xe7, 0xd5, 0x29, 0x9f, 0x34, 0x0a, 0x4b, 0xda, 0x72, 0x51, 0x0f, 0xd1, 0xe8, 0xfa, 0xcf, 0xc9, 0xa5, 0x7b, 0x64,
0xc6, 0x30, 0x45, 0x09, 0x3b, 0x66, 0xf7, 0x9c, 0x2d, 0x9a, 0x35, 0x30, 0x5d, 0xde, 0x9b, 0x67, 0x5b, 0xfd, 0xcb, 0x46, 0x91, 0x31, 0x14, 0x29, 0x61, 0xcf, 0xea, 0x5f, 0xb2, 0x4d, 0xb3, 0x47,
0xbd, 0x79, 0x46, 0x61, 0xdd, 0x8b, 0x50, 0xe9, 0x75, 0xcc, 0x83, 0x9e, 0xd5, 0x3e, 0xf0, 0x1c, 0x96, 0xc7, 0xdf, 0x96, 0xd8, 0xdb, 0x12, 0xa3, 0xb0, 0xd7, 0xcb, 0x50, 0x1f, 0x98, 0xd6, 0xd1,
0x02, 0xcc, 0x21, 0xe5, 0x5e, 0xc7, 0x7c, 0x69, 0xb5, 0x75, 0xe9, 0x16, 0xca, 0x69, 0x9c, 0x05, 0xc0, 0xee, 0x1d, 0xf9, 0x0e, 0x01, 0xe6, 0x90, 0xda, 0xc0, 0xb4, 0xde, 0xd9, 0x3d, 0x5d, 0xba,
0x39, 0x0b, 0x82, 0xd3, 0x38, 0x53, 0x39, 0x97, 0x60, 0x86, 0xca, 0x6c, 0xd9, 0xc4, 0x70, 0x89, 0x85, 0x72, 0x1a, 0x17, 0x61, 0xce, 0xb2, 0xe0, 0x34, 0x2e, 0x54, 0xce, 0x15, 0x98, 0xa7, 0x32,
0xcf, 0x5c, 0x64, 0xcc, 0x57, 0x7a, 0x1d, 0x73, 0x95, 0xf5, 0x04, 0xf8, 0x8d, 0xb3, 0x08, 0x7f, 0xbb, 0x0e, 0x31, 0x3c, 0x12, 0x30, 0x57, 0x18, 0xf3, 0x8d, 0x81, 0x69, 0xad, 0xb3, 0x37, 0x21,
0x49, 0xf0, 0x1b, 0x67, 0x41, 0x7e, 0xbc, 0x04, 0x79, 0xcf, 0xe7, 0x68, 0x0a, 0x26, 0xb7, 0x77, 0x7e, 0xe3, 0x22, 0xc6, 0x5f, 0x15, 0xfc, 0xc6, 0x45, 0x98, 0x1f, 0xaf, 0x40, 0xc9, 0xf7, 0x39,
0xb6, 0x1b, 0x95, 0x09, 0x04, 0x90, 0x5d, 0xd9, 0x5b, 0x6d, 0x6c, 0xaf, 0x55, 0x34, 0x54, 0x80, 0x2a, 0xc2, 0xec, 0xee, 0xde, 0x6e, 0xbb, 0x3e, 0x83, 0x00, 0xf2, 0x6b, 0x07, 0xeb, 0xed, 0xdd,
0xdc, 0x5a, 0x83, 0x37, 0x52, 0xf8, 0x39, 0x80, 0xef, 0x5d, 0x94, 0x83, 0xf4, 0x66, 0xe3, 0xcf, 0x8d, 0xba, 0x86, 0xca, 0x50, 0xd8, 0x68, 0xf3, 0x41, 0x06, 0xbf, 0x01, 0x08, 0xbc, 0x8b, 0x0a,
0x2a, 0x13, 0x94, 0xe7, 0x55, 0x43, 0xdf, 0xdb, 0xd8, 0xd9, 0xae, 0x68, 0x74, 0xf0, 0xaa, 0xde, 0x90, 0xdd, 0x6e, 0xff, 0x5e, 0x7d, 0x86, 0xf2, 0xbc, 0x6f, 0xeb, 0x07, 0x5b, 0x7b, 0xbb, 0x75,
0x58, 0x69, 0x36, 0x2a, 0x29, 0xca, 0xf1, 0x72, 0x67, 0xad, 0x92, 0x46, 0x79, 0xc8, 0xbc, 0x5a, 0x8d, 0x4e, 0x5e, 0xd7, 0xdb, 0x6b, 0x9d, 0x76, 0x3d, 0x43, 0x39, 0xde, 0xed, 0x6d, 0xd4, 0xb3,
0xd9, 0xda, 0x6f, 0x54, 0x26, 0xf1, 0x57, 0x1a, 0x94, 0xc4, 0x7a, 0xf1, 0x98, 0x40, 0xef, 0x41, 0xa8, 0x04, 0xb9, 0xf7, 0x6b, 0x3b, 0x87, 0xed, 0xfa, 0x2c, 0xfe, 0xa5, 0x06, 0x55, 0xb1, 0x5f,
0xf6, 0x84, 0xc5, 0x05, 0xdb, 0x8a, 0x85, 0xe5, 0x9b, 0xa1, 0xc5, 0x0d, 0xc4, 0x8e, 0x2e, 0x78, 0x3c, 0x26, 0xd0, 0xf7, 0x21, 0x7f, 0xc6, 0xe2, 0x82, 0x1d, 0xc5, 0xf2, 0xea, 0xbd, 0xc8, 0xe6,
0x11, 0x86, 0xf4, 0xe9, 0xd0, 0xa9, 0xa6, 0x16, 0xd2, 0x8b, 0x85, 0xe5, 0xca, 0x12, 0x0f, 0xd8, 0x86, 0x62, 0x47, 0x17, 0xbc, 0x08, 0x43, 0xf6, 0x7c, 0xec, 0x36, 0x32, 0x4b, 0xd9, 0xe5, 0xf2,
0xa5, 0x4d, 0x72, 0xfe, 0xca, 0xe8, 0x0e, 0x88, 0x4e, 0x3b, 0x11, 0x82, 0xc9, 0x9e, 0x65, 0x13, 0x6a, 0x7d, 0x85, 0x47, 0xee, 0xca, 0x36, 0xb9, 0x7c, 0x6f, 0xf4, 0x47, 0x44, 0xa7, 0x2f, 0x11,
0xb6, 0x63, 0xa7, 0x74, 0xf6, 0x4d, 0xb7, 0x31, 0x5b, 0x34, 0xb1, 0x5b, 0x79, 0x03, 0x7f, 0xab, 0x82, 0xd9, 0x81, 0xed, 0x10, 0x76, 0x62, 0x8b, 0x3a, 0x7b, 0xa6, 0xc7, 0x98, 0x6d, 0x9a, 0x38,
0x01, 0xec, 0x0e, 0xdc, 0xe4, 0xd0, 0x98, 0x85, 0xcc, 0x90, 0x0a, 0x16, 0x61, 0xc1, 0x1b, 0x2c, 0xad, 0x7c, 0x80, 0x7f, 0xad, 0x01, 0xec, 0x8f, 0xbc, 0xf4, 0xd0, 0x58, 0x80, 0xdc, 0x98, 0x0a,
0x26, 0x88, 0xe1, 0x10, 0x2f, 0x26, 0x68, 0x03, 0x5d, 0x87, 0x5c, 0xdf, 0x26, 0xc3, 0x83, 0xd3, 0x16, 0x61, 0xc1, 0x07, 0x2c, 0x26, 0x88, 0xe1, 0x12, 0x3f, 0x26, 0xe8, 0x00, 0xdd, 0x86, 0xc2,
0x21, 0x53, 0x32, 0xa5, 0x67, 0x69, 0x73, 0x73, 0x88, 0xee, 0x40, 0xb1, 0x73, 0x6c, 0x5a, 0x36, 0xd0, 0x21, 0xe3, 0xa3, 0xf3, 0x31, 0x53, 0x52, 0xd4, 0xf3, 0x74, 0xb8, 0x3d, 0x46, 0x0f, 0xa1,
0x39, 0xe0, 0xb2, 0x32, 0xac, 0xb7, 0xc0, 0x69, 0xcc, 0x6e, 0x85, 0x85, 0x0b, 0xce, 0xaa, 0x2c, 0x62, 0x9e, 0x5a, 0xb6, 0x43, 0x8e, 0xb8, 0xac, 0x1c, 0x7b, 0x5b, 0xe6, 0x34, 0x66, 0xb7, 0xc2,
0x5b, 0x94, 0x84, 0x4d, 0x28, 0x30, 0x53, 0xc7, 0x72, 0xdf, 0x23, 0xdf, 0xc6, 0x14, 0x1b, 0x16, 0xc2, 0x05, 0xe7, 0x55, 0x96, 0x1d, 0x4a, 0xc2, 0x16, 0x94, 0x99, 0xa9, 0x53, 0xb9, 0xef, 0x79,
0x75, 0xa1, 0xb0, 0x1a, 0x7f, 0x06, 0x68, 0x8d, 0x74, 0x89, 0x4b, 0xc6, 0xc9, 0x1e, 0x8a, 0x4f, 0x60, 0x63, 0x86, 0x4d, 0x8b, 0xbb, 0x50, 0x58, 0x8d, 0x7f, 0x0a, 0x68, 0x83, 0xf4, 0x89, 0x47,
0xd2, 0xaa, 0x4f, 0xf0, 0x3f, 0x6b, 0x30, 0x13, 0x10, 0x3f, 0xd6, 0xb4, 0xaa, 0x90, 0x6b, 0x33, 0xa6, 0xc9, 0x1e, 0x8a, 0x4f, 0xb2, 0xaa, 0x4f, 0xf0, 0xdf, 0x68, 0x30, 0x1f, 0x12, 0x3f, 0xd5,
0x61, 0xdc, 0x82, 0xb4, 0x2e, 0x9b, 0xe8, 0x09, 0x4c, 0x09, 0x03, 0x9c, 0x6a, 0x3a, 0x61, 0xd3, 0xb2, 0x1a, 0x50, 0xe8, 0x31, 0x61, 0xdc, 0x82, 0xac, 0x2e, 0x87, 0xe8, 0x25, 0x14, 0x85, 0x01,
0xe4, 0xb8, 0x4d, 0x0e, 0xfe, 0x36, 0x05, 0x79, 0x31, 0xd1, 0x9d, 0x3e, 0x5a, 0x81, 0x92, 0xcd, 0x6e, 0x23, 0x9b, 0x72, 0x68, 0x0a, 0xdc, 0x26, 0x17, 0xff, 0x3a, 0x03, 0x25, 0xb1, 0xd0, 0xbd,
0x1b, 0x07, 0x6c, 0x3e, 0xc2, 0xa2, 0x5a, 0x72, 0x12, 0x5a, 0x9f, 0xd0, 0x8b, 0x62, 0x08, 0x23, 0x21, 0x5a, 0x83, 0xaa, 0xc3, 0x07, 0x47, 0x6c, 0x3d, 0xc2, 0xa2, 0x66, 0x7a, 0x12, 0xda, 0x9c,
0xa3, 0x3f, 0x81, 0x82, 0x14, 0xd1, 0x1f, 0xb8, 0xc2, 0xe5, 0xd5, 0xa0, 0x00, 0x7f, 0xff, 0xad, 0xd1, 0x2b, 0x62, 0x0a, 0x23, 0xa3, 0xdf, 0x81, 0xb2, 0x14, 0x31, 0x1c, 0x79, 0xc2, 0xe5, 0x8d,
0x4f, 0xe8, 0x20, 0xd8, 0x77, 0x07, 0x2e, 0x6a, 0xc2, 0xac, 0x1c, 0xcc, 0x67, 0x23, 0xcc, 0x48, 0xb0, 0x80, 0xe0, 0xfc, 0x6d, 0xce, 0xe8, 0x20, 0xd8, 0xf7, 0x47, 0x1e, 0xea, 0xc0, 0x82, 0x9c,
0x33, 0x29, 0x0b, 0x41, 0x29, 0xd1, 0xa5, 0x5a, 0x9f, 0xd0, 0x91, 0x18, 0xaf, 0x74, 0xaa, 0x26, 0xcc, 0x57, 0x23, 0xcc, 0xc8, 0x32, 0x29, 0x4b, 0x61, 0x29, 0xf1, 0xad, 0xda, 0x9c, 0xd1, 0x91,
0xb9, 0x67, 0x3c, 0x79, 0x47, 0x4c, 0x6a, 0x9e, 0x99, 0x51, 0x93, 0x9a, 0x67, 0xe6, 0xf3, 0x3c, 0x98, 0xaf, 0xbc, 0x54, 0x4d, 0xf2, 0x2e, 0x78, 0xf2, 0x8e, 0x99, 0xd4, 0xb9, 0xb0, 0xe2, 0x26,
0xe4, 0x44, 0x0b, 0xff, 0x57, 0x0a, 0x40, 0xae, 0xc6, 0x4e, 0x1f, 0xad, 0x41, 0xd9, 0x16, 0xad, 0x75, 0x2e, 0xac, 0x37, 0x25, 0x28, 0x88, 0x11, 0xfe, 0xe7, 0x0c, 0x80, 0xdc, 0x8d, 0xbd, 0x21,
0x80, 0xb7, 0x6e, 0xc4, 0x7a, 0x4b, 0x2c, 0xe2, 0x84, 0x5e, 0x92, 0x83, 0xb8, 0x71, 0xef, 0x43, 0xda, 0x80, 0x9a, 0x23, 0x46, 0x21, 0x6f, 0xdd, 0x4d, 0xf4, 0x96, 0xd8, 0xc4, 0x19, 0xbd, 0x2a,
0xd1, 0x93, 0xe2, 0x3b, 0x6c, 0x2e, 0xc6, 0x61, 0x9e, 0x84, 0x82, 0x1c, 0x40, 0x5d, 0xf6, 0x09, 0x27, 0x71, 0xe3, 0x7e, 0x00, 0x15, 0x5f, 0x4a, 0xe0, 0xb0, 0x3b, 0x09, 0x0e, 0xf3, 0x25, 0x94,
0x5c, 0xf5, 0xc6, 0xc7, 0xf8, 0xec, 0xce, 0x08, 0x9f, 0x79, 0x02, 0x67, 0xa4, 0x04, 0xd5, 0x6b, 0xe5, 0x04, 0xea, 0xb2, 0x4f, 0xe1, 0xa6, 0x3f, 0x3f, 0xc1, 0x67, 0x0f, 0x27, 0xf8, 0xcc, 0x17,
0xaa, 0x61, 0xbe, 0xdb, 0xe6, 0x62, 0xdc, 0x16, 0x35, 0x8c, 0x3a, 0x0e, 0x68, 0xbd, 0xe4, 0x4d, 0x38, 0x2f, 0x25, 0xa8, 0x5e, 0x53, 0x0d, 0x0b, 0xdc, 0x76, 0x27, 0xc1, 0x6d, 0x71, 0xc3, 0xa8,
0xfc, 0xeb, 0x34, 0xe4, 0x56, 0xad, 0x5e, 0xdf, 0xb0, 0xe9, 0x6a, 0x64, 0x6d, 0xe2, 0x0c, 0xba, 0xe3, 0x80, 0xd6, 0x4b, 0x3e, 0xc4, 0xff, 0x9d, 0x85, 0xc2, 0xba, 0x3d, 0x18, 0x1a, 0x0e, 0xdd,
0x2e, 0x73, 0x57, 0x79, 0xf9, 0x6e, 0x50, 0xa2, 0x60, 0x93, 0xff, 0xea, 0x8c, 0x55, 0x17, 0x43, 0x8d, 0xbc, 0x43, 0xdc, 0x51, 0xdf, 0x63, 0xee, 0xaa, 0xad, 0x3e, 0x0a, 0x4b, 0x14, 0x6c, 0xf2,
0xe8, 0x60, 0x51, 0x1e, 0x53, 0x97, 0x18, 0x2c, 0x8a, 0xa3, 0x18, 0x22, 0x03, 0x39, 0xed, 0x07, 0x5f, 0x9d, 0xb1, 0xea, 0x62, 0x0a, 0x9d, 0x2c, 0xca, 0x63, 0xe6, 0x1a, 0x93, 0x45, 0x71, 0x14,
0x72, 0x0d, 0x72, 0x43, 0x62, 0xfb, 0x25, 0x7d, 0x7d, 0x42, 0x97, 0x04, 0xf4, 0x08, 0xa6, 0xc3, 0x53, 0x64, 0x20, 0x67, 0x83, 0x40, 0x6e, 0x42, 0x61, 0x4c, 0x9c, 0xa0, 0xa4, 0x6f, 0xce, 0xe8,
0xe5, 0x25, 0x23, 0x78, 0xca, 0xad, 0x60, 0x35, 0xba, 0x0b, 0xc5, 0x40, 0x8d, 0xcb, 0x0a, 0xbe, 0x92, 0x80, 0x9e, 0xc3, 0x5c, 0xb4, 0xbc, 0xe4, 0x04, 0x4f, 0xad, 0x1b, 0xae, 0x46, 0x8f, 0xa0,
0x42, 0x4f, 0x29, 0x71, 0xd7, 0x64, 0x5e, 0xa5, 0xf5, 0xb8, 0xb8, 0x3e, 0x21, 0x33, 0xeb, 0x35, 0x12, 0xaa, 0x71, 0x79, 0xc1, 0x57, 0x1e, 0x28, 0x25, 0xee, 0x96, 0xcc, 0xab, 0xb4, 0x1e, 0x57,
0x99, 0x59, 0xa7, 0xc4, 0x28, 0x91, 0x5b, 0x03, 0x49, 0xe6, 0x83, 0x60, 0x92, 0xc1, 0x1f, 0x40, 0x36, 0x67, 0x64, 0x66, 0xbd, 0x25, 0x33, 0x6b, 0x51, 0xcc, 0x12, 0xb9, 0x35, 0x94, 0x64, 0x7e,
0x29, 0xe0, 0x20, 0x5a, 0x77, 0x1a, 0x1f, 0xef, 0xaf, 0x6c, 0xf1, 0x22, 0xf5, 0x82, 0xd5, 0x25, 0x18, 0x4e, 0x32, 0xf8, 0x87, 0x50, 0x0d, 0x39, 0x88, 0xd6, 0x9d, 0xf6, 0x4f, 0x0e, 0xd7, 0x76,
0xbd, 0xa2, 0xd1, 0x5a, 0xb7, 0xd5, 0xd8, 0xdb, 0xab, 0xa4, 0x50, 0x09, 0xf2, 0xdb, 0x3b, 0xcd, 0x78, 0x91, 0x7a, 0xcb, 0xea, 0x92, 0x5e, 0xd7, 0x68, 0xad, 0xdb, 0x69, 0x1f, 0x1c, 0xd4, 0x33,
0x03, 0xce, 0x95, 0xc6, 0x2f, 0x3c, 0x09, 0xa2, 0xc8, 0x29, 0xb5, 0x6d, 0x42, 0xa9, 0x6d, 0x9a, 0xa8, 0x0a, 0xa5, 0xdd, 0xbd, 0xce, 0x11, 0xe7, 0xca, 0xe2, 0xb7, 0xbe, 0x04, 0x51, 0xe4, 0x94,
0xac, 0x6d, 0x29, 0xbf, 0xb6, 0xb1, 0x32, 0xb7, 0xd5, 0x58, 0xd9, 0x6b, 0x54, 0x26, 0x9f, 0x97, 0xda, 0x36, 0xa3, 0xd4, 0x36, 0x4d, 0xd6, 0xb6, 0x4c, 0x50, 0xdb, 0x58, 0x99, 0xdb, 0x69, 0xaf,
0xa1, 0xc8, 0xfd, 0x7b, 0x30, 0x30, 0x69, 0xa9, 0xfd, 0x77, 0x0d, 0xc0, 0x8f, 0x26, 0x54, 0x87, 0x1d, 0xb4, 0xeb, 0xb3, 0x6f, 0x6a, 0x50, 0xe1, 0xfe, 0x3d, 0x1a, 0x59, 0xb4, 0xd4, 0xfe, 0xa3,
0x5c, 0x8b, 0xeb, 0xa9, 0x6a, 0x2c, 0x19, 0x5d, 0x8d, 0x5d, 0x32, 0x5d, 0x72, 0xa1, 0x77, 0x20, 0x06, 0x10, 0x44, 0x13, 0x6a, 0x41, 0xa1, 0xcb, 0xf5, 0x34, 0x34, 0x96, 0x8c, 0x6e, 0x26, 0x6e,
0xe7, 0x0c, 0x5a, 0x2d, 0xe2, 0xc8, 0x92, 0x77, 0x3d, 0x9c, 0x0f, 0x45, 0xb6, 0xd2, 0x25, 0x1f, 0x99, 0x2e, 0xb9, 0xd0, 0x77, 0xa1, 0xe0, 0x8e, 0xba, 0x5d, 0xe2, 0xca, 0x92, 0x77, 0x3b, 0x9a,
0x1d, 0x72, 0x64, 0x74, 0xba, 0x03, 0x56, 0x00, 0x47, 0x0f, 0x11, 0x7c, 0xf8, 0xdf, 0x34, 0x28, 0x0f, 0x45, 0xb6, 0xd2, 0x25, 0x1f, 0x9d, 0x72, 0x62, 0x98, 0xfd, 0x11, 0x2b, 0x80, 0x93, 0xa7,
0x28, 0x9b, 0xf7, 0x07, 0x26, 0xe1, 0x9b, 0x90, 0x67, 0x36, 0x90, 0xb6, 0x48, 0xc3, 0x53, 0xba, 0x08, 0x3e, 0xfc, 0xf7, 0x1a, 0x94, 0x95, 0xc3, 0xfb, 0x15, 0x93, 0xf0, 0x3d, 0x28, 0x31, 0x1b,
0x4f, 0x40, 0x7f, 0x0c, 0x79, 0x19, 0x01, 0x32, 0x13, 0x57, 0xe3, 0xc5, 0xee, 0xf4, 0x75, 0x9f, 0x48, 0x4f, 0xa4, 0xe1, 0xa2, 0x1e, 0x10, 0xd0, 0x6f, 0x43, 0x49, 0x46, 0x80, 0xcc, 0xc4, 0x8d,
0x15, 0x6f, 0xc2, 0x15, 0xe6, 0x95, 0x16, 0x3d, 0x5c, 0x4b, 0x3f, 0xaa, 0xc7, 0x4f, 0x2d, 0x74, 0x64, 0xb1, 0x7b, 0x43, 0x3d, 0x60, 0xc5, 0xdb, 0x70, 0x83, 0x79, 0xa5, 0x4b, 0x9b, 0x6b, 0xe9,
0xfc, 0xac, 0xc1, 0x54, 0xff, 0xe4, 0xdc, 0xe9, 0xb4, 0x8c, 0xae, 0xb0, 0xc2, 0x6b, 0xe3, 0x8f, 0x47, 0xb5, 0xfd, 0xd4, 0x22, 0xed, 0x67, 0x13, 0x8a, 0xc3, 0xb3, 0x4b, 0xd7, 0xec, 0x1a, 0x7d,
0x00, 0xa9, 0xc2, 0xc6, 0x99, 0x2e, 0x2e, 0x41, 0x61, 0xdd, 0x70, 0x4e, 0x84, 0x49, 0xf8, 0x09, 0x61, 0x85, 0x3f, 0xc6, 0x3f, 0x06, 0xa4, 0x0a, 0x9b, 0x66, 0xb9, 0xb8, 0x0a, 0xe5, 0x4d, 0xc3,
0x94, 0x68, 0x73, 0xf3, 0xd5, 0x25, 0x6c, 0x64, 0x97, 0x03, 0xc9, 0x3d, 0x96, 0xcf, 0x11, 0x4c, 0x3d, 0x13, 0x26, 0xe1, 0x97, 0x50, 0xa5, 0xc3, 0xed, 0xf7, 0xd7, 0xb0, 0x91, 0x5d, 0x0e, 0x24,
0x9e, 0x18, 0xce, 0x09, 0x9b, 0x68, 0x49, 0x67, 0xdf, 0xe8, 0x11, 0x54, 0x5a, 0x7c, 0x92, 0x07, 0xf7, 0x54, 0x3e, 0x47, 0x30, 0x7b, 0x66, 0xb8, 0x67, 0x6c, 0xa1, 0x55, 0x9d, 0x3d, 0xa3, 0xe7,
0xa1, 0x2b, 0xc3, 0xb4, 0xa0, 0x7b, 0x27, 0xc1, 0x4f, 0xa1, 0xc8, 0xe7, 0xf0, 0x63, 0x1b, 0x81, 0x50, 0xef, 0xf2, 0x45, 0x1e, 0x45, 0xae, 0x0c, 0x73, 0x82, 0xee, 0x77, 0x82, 0x9f, 0x41, 0x85,
0xaf, 0xc0, 0xf4, 0x9e, 0x69, 0xf4, 0x9d, 0x13, 0x4b, 0x56, 0x37, 0x3a, 0xe9, 0x8a, 0x4f, 0x1b, 0xaf, 0xe1, 0xeb, 0x36, 0x02, 0xdf, 0x80, 0xb9, 0x03, 0xcb, 0x18, 0xba, 0x67, 0xb6, 0xac, 0x6e,
0x4b, 0xe3, 0x43, 0x98, 0xb6, 0x49, 0xcf, 0xe8, 0x98, 0x1d, 0xf3, 0xf8, 0xe0, 0xf0, 0xdc, 0x25, 0x74, 0xd1, 0xf5, 0x80, 0x36, 0x95, 0xc6, 0x67, 0x30, 0xe7, 0x90, 0x81, 0x61, 0x5a, 0xa6, 0x75,
0x8e, 0xb8, 0x30, 0x95, 0x3d, 0xf2, 0x73, 0x4a, 0xa5, 0xa6, 0x1d, 0x76, 0xad, 0x43, 0x91, 0xe6, 0x7a, 0x74, 0x7c, 0xe9, 0x11, 0x57, 0x5c, 0x98, 0x6a, 0x3e, 0xf9, 0x0d, 0xa5, 0x52, 0xd3, 0x8e,
0xd8, 0x37, 0xfe, 0x4f, 0x0d, 0x8a, 0x9f, 0x18, 0x6e, 0x4b, 0x2e, 0x1d, 0xda, 0x80, 0xb2, 0x97, 0xfb, 0xf6, 0xb1, 0x48, 0x73, 0xec, 0x19, 0x7f, 0xae, 0x41, 0xe5, 0x53, 0xc3, 0xeb, 0xca, 0xad,
0xdc, 0x18, 0x45, 0xd8, 0x12, 0x2a, 0xb1, 0x6c, 0x8c, 0x3c, 0x4a, 0xcb, 0xea, 0x58, 0x6a, 0xa9, 0x43, 0x5b, 0x50, 0xf3, 0x93, 0x1b, 0xa3, 0x08, 0x5b, 0x22, 0x25, 0x96, 0xcd, 0x91, 0xad, 0xb4,
0x04, 0x26, 0xca, 0x30, 0x5b, 0xa4, 0xeb, 0x89, 0x4a, 0x25, 0x8b, 0x62, 0x8c, 0xaa, 0x28, 0x95, 0xac, 0x8e, 0xd5, 0xae, 0x4a, 0x60, 0xa2, 0x0c, 0xab, 0x4b, 0xfa, 0xbe, 0xa8, 0x4c, 0xba, 0x28,
0xf0, 0x7c, 0xda, 0x3f, 0x7e, 0xf0, 0x5c, 0xf2, 0x75, 0x0a, 0x50, 0xd4, 0x86, 0xef, 0x7b, 0x22, 0xc6, 0xa8, 0x8a, 0x52, 0x09, 0x6f, 0xe6, 0x82, 0xf6, 0x83, 0xe7, 0x92, 0xcf, 0x33, 0x80, 0xe2,
0xbb, 0x0f, 0x65, 0xc7, 0x35, 0xec, 0xc8, 0xde, 0x28, 0x31, 0xaa, 0x97, 0xa0, 0x1f, 0xc2, 0x74, 0x36, 0x7c, 0xd9, 0x8e, 0xec, 0x09, 0xd4, 0x5c, 0xcf, 0x70, 0x62, 0x67, 0xa3, 0xca, 0xa8, 0x7e,
0xdf, 0xb6, 0x8e, 0x6d, 0xe2, 0x38, 0x07, 0xa6, 0xe5, 0x76, 0x8e, 0xce, 0xc5, 0xa1, 0xb6, 0x2c, 0x82, 0x7e, 0x06, 0x73, 0x43, 0xc7, 0x3e, 0x75, 0x88, 0xeb, 0x1e, 0x59, 0xb6, 0x67, 0x9e, 0x5c,
0xc9, 0xdb, 0x8c, 0x8a, 0x1a, 0x90, 0x3b, 0xea, 0x74, 0x5d, 0x62, 0x3b, 0xd5, 0xcc, 0x42, 0x7a, 0x8a, 0xa6, 0xb6, 0x26, 0xc9, 0xbb, 0x8c, 0x8a, 0xda, 0x50, 0x38, 0x31, 0xfb, 0x1e, 0x71, 0xdc,
0xb1, 0xbc, 0xfc, 0xe4, 0x22, 0xaf, 0x2d, 0x7d, 0xc8, 0xf8, 0x9b, 0xe7, 0x7d, 0xa2, 0xcb, 0xb1, 0x46, 0x6e, 0x29, 0xbb, 0x5c, 0x5b, 0x7d, 0x79, 0x95, 0xd7, 0x56, 0x7e, 0xc4, 0xf8, 0x3b, 0x97,
0xea, 0x41, 0x31, 0x1b, 0x38, 0x28, 0xde, 0x07, 0xf0, 0xf9, 0x69, 0xaa, 0xdd, 0xde, 0xd9, 0xdd, 0x43, 0xa2, 0xcb, 0xb9, 0x6a, 0xa3, 0x98, 0x0f, 0x35, 0xcf, 0x77, 0xa0, 0xf8, 0x81, 0x8a, 0xa0,
0x6f, 0x56, 0x26, 0x50, 0x11, 0xa6, 0xb6, 0x77, 0xd6, 0x1a, 0x5b, 0x0d, 0x9a, 0x97, 0x71, 0x5d, 0x97, 0xe2, 0x02, 0xef, 0xed, 0xd8, 0x78, 0xab, 0x87, 0x9f, 0x00, 0x04, 0xa2, 0x68, 0x16, 0xde,
0xfa, 0x46, 0xf5, 0x21, 0x9a, 0x83, 0xa9, 0xd7, 0x94, 0x2a, 0xef, 0xdb, 0x69, 0x3d, 0xc7, 0xda, 0xdd, 0xdb, 0x3f, 0xec, 0xd4, 0x67, 0x50, 0x05, 0x8a, 0xbb, 0x7b, 0x1b, 0xed, 0x9d, 0x36, 0x4d,
0x1b, 0x6d, 0xfc, 0x4f, 0x29, 0x28, 0x89, 0x5d, 0x30, 0xd6, 0x56, 0x54, 0x55, 0xa4, 0x02, 0x2a, 0xd9, 0xb8, 0x25, 0xdd, 0xa6, 0xba, 0x37, 0x24, 0x57, 0x0b, 0xcb, 0xfd, 0xab, 0x0c, 0x54, 0xc5,
0xe8, 0xa9, 0x94, 0xef, 0x8e, 0xb6, 0x38, 0xfc, 0xca, 0x26, 0xcd, 0x0d, 0x7c, 0xb1, 0x49, 0x5b, 0x01, 0x99, 0xea, 0x94, 0xaa, 0x2a, 0x32, 0x21, 0x15, 0xb4, 0x61, 0xe5, 0x07, 0xa7, 0x27, 0xfa,
0xb8, 0xd5, 0x6b, 0xc7, 0x86, 0x6f, 0x26, 0x36, 0x7c, 0xd1, 0x5d, 0x28, 0x79, 0xbb, 0xcd, 0x70, 0x62, 0x39, 0xa4, 0x69, 0x83, 0x9f, 0x03, 0xd2, 0x13, 0x1e, 0xf7, 0xc7, 0x89, 0x91, 0x9d, 0x4b,
0x44, 0xad, 0xcd, 0xeb, 0x45, 0xb9, 0x91, 0x28, 0x0d, 0xdd, 0x87, 0x2c, 0x19, 0x12, 0xd3, 0x75, 0x8c, 0x6c, 0xf4, 0x08, 0xaa, 0xfe, 0x41, 0x34, 0x5c, 0x51, 0x86, 0x4b, 0x7a, 0x45, 0x9e, 0x31,
0xaa, 0x05, 0x96, 0x75, 0x4b, 0xf2, 0xfc, 0xdb, 0xa0, 0x54, 0x5d, 0x74, 0xe2, 0x3f, 0x82, 0x2b, 0x4a, 0x43, 0x4f, 0x20, 0x4f, 0xc6, 0xc4, 0xf2, 0xdc, 0x46, 0x99, 0x25, 0xe4, 0xaa, 0x6c, 0x8d,
0xec, 0x9e, 0xf1, 0xc2, 0x36, 0x4c, 0xf5, 0x42, 0xd4, 0x6c, 0x6e, 0x09, 0xd7, 0xd1, 0x4f, 0x54, 0xdb, 0x94, 0xaa, 0x8b, 0x97, 0xf8, 0xb7, 0xe0, 0x06, 0xbb, 0x82, 0xbc, 0x75, 0x0c, 0x4b, 0xbd,
0x86, 0xd4, 0xc6, 0x9a, 0x98, 0x68, 0x6a, 0x63, 0x0d, 0x7f, 0xa1, 0x01, 0x52, 0xc7, 0x8d, 0xe5, 0x2b, 0x75, 0x3a, 0x3b, 0xc2, 0x75, 0xf4, 0x11, 0xd5, 0x20, 0xb3, 0xb5, 0x21, 0x16, 0x9a, 0xd9,
0xcb, 0x90, 0x70, 0xa9, 0x3e, 0xed, 0xab, 0x9f, 0x85, 0x0c, 0xb1, 0x6d, 0xcb, 0x66, 0x5e, 0xcb, 0xda, 0xc0, 0x3f, 0xd7, 0x00, 0xa9, 0xf3, 0xa6, 0xf2, 0x65, 0x44, 0xb8, 0x54, 0x9f, 0x0d, 0xd4,
0xeb, 0xbc, 0x81, 0xef, 0x09, 0x1b, 0x74, 0x32, 0xb4, 0x4e, 0xbd, 0xc0, 0xe0, 0xd2, 0x34, 0xcf, 0x2f, 0x40, 0x8e, 0x38, 0x8e, 0xed, 0x30, 0xaf, 0x95, 0x74, 0x3e, 0xc0, 0x8f, 0x85, 0x0d, 0x3a,
0xd4, 0x4d, 0x98, 0x09, 0x70, 0x8d, 0x95, 0xfd, 0x1f, 0xc2, 0x55, 0x26, 0x6c, 0x93, 0x90, 0xfe, 0x19, 0xdb, 0xe7, 0x7e, 0xcc, 0x70, 0x69, 0x9a, 0x6f, 0xea, 0x36, 0xcc, 0x87, 0xb8, 0xa6, 0x2a,
0x4a, 0xb7, 0x33, 0x4c, 0xd4, 0xda, 0x87, 0x6b, 0x61, 0xc6, 0x9f, 0xd6, 0x47, 0xf8, 0x4f, 0x85, 0x0c, 0xcf, 0xe0, 0x26, 0x13, 0xb6, 0x4d, 0xc8, 0x70, 0xad, 0x6f, 0x8e, 0x53, 0xb5, 0x0e, 0xe1,
0xc6, 0x66, 0xa7, 0x47, 0x9a, 0xd6, 0x56, 0xb2, 0x6d, 0x34, 0x3b, 0x9e, 0x92, 0x73, 0x47, 0x94, 0x56, 0x94, 0xf1, 0x9b, 0xf5, 0x11, 0xfe, 0x5d, 0xa1, 0xb1, 0x63, 0x0e, 0x48, 0xc7, 0xde, 0x49,
0x49, 0xf6, 0x8d, 0xff, 0x43, 0x83, 0xeb, 0x91, 0xe1, 0x3f, 0xf1, 0xaa, 0xce, 0x03, 0x1c, 0xd3, 0xb7, 0x8d, 0x26, 0xce, 0x73, 0x72, 0xe9, 0x8a, 0x0a, 0xca, 0x9e, 0xf1, 0x3f, 0x69, 0x70, 0x3b,
0xed, 0x43, 0xda, 0xb4, 0x83, 0xdf, 0xd0, 0x15, 0x8a, 0x67, 0x27, 0x4d, 0x30, 0x45, 0x61, 0xe7, 0x36, 0xfd, 0x1b, 0xde, 0xd5, 0x45, 0x80, 0x53, 0x7a, 0x7c, 0x48, 0x8f, 0xbe, 0xe0, 0x97, 0x77,
0xac, 0x58, 0x73, 0xf6, 0xc7, 0x91, 0x35, 0xe6, 0x16, 0x14, 0x18, 0x61, 0xcf, 0x35, 0xdc, 0x81, 0x85, 0xe2, 0xdb, 0x49, 0x73, 0x4f, 0x45, 0xd8, 0xb9, 0x20, 0xf6, 0x9c, 0xfd, 0x71, 0x65, 0xf9,
0x13, 0x59, 0x8c, 0xbf, 0x11, 0x5b, 0x40, 0x0e, 0x1a, 0x6b, 0x5e, 0xef, 0x40, 0x96, 0x1d, 0x4e, 0xb9, 0x0f, 0x65, 0x46, 0x38, 0xf0, 0x0c, 0x6f, 0xe4, 0xc6, 0x36, 0xe3, 0x4f, 0xc4, 0x11, 0x90,
0xe5, 0xd1, 0x2c, 0x74, 0x1b, 0x50, 0xec, 0xd0, 0x05, 0x23, 0x3e, 0x81, 0xec, 0x4b, 0x86, 0xe8, 0x93, 0xa6, 0x5a, 0xd7, 0x77, 0x21, 0xcf, 0xfa, 0x56, 0xd9, 0xb5, 0x45, 0x2e, 0x0a, 0x8a, 0x1d,
0x29, 0x96, 0x4d, 0xca, 0xa5, 0x30, 0x8d, 0x1e, 0xc7, 0x19, 0xf2, 0x3a, 0xfb, 0x66, 0x27, 0x19, 0xba, 0x60, 0xc4, 0x67, 0x90, 0x7f, 0xc7, 0xc0, 0x3e, 0xc5, 0xb2, 0x59, 0xb9, 0x15, 0x96, 0x31,
0x42, 0xec, 0x7d, 0x7d, 0x8b, 0x9f, 0x98, 0xf2, 0xba, 0xd7, 0xa6, 0x2e, 0x6b, 0x75, 0x3b, 0xc4, 0xe0, 0x10, 0x44, 0x49, 0x67, 0xcf, 0xac, 0xc9, 0x21, 0xc4, 0x39, 0xd4, 0x77, 0x78, 0x33, 0x55,
0x74, 0x59, 0xef, 0x24, 0xeb, 0x55, 0x28, 0x78, 0x09, 0x2a, 0x5c, 0xd3, 0x4a, 0xbb, 0xad, 0x9c, 0xd2, 0xfd, 0x31, 0x75, 0x59, 0xb7, 0x6f, 0x12, 0xcb, 0x63, 0x6f, 0x67, 0xd9, 0x5b, 0x85, 0x82,
0x48, 0x3c, 0x79, 0x5a, 0x50, 0x1e, 0xfe, 0x46, 0x83, 0x2b, 0xca, 0x80, 0xb1, 0x1c, 0xf3, 0x14, 0x57, 0xa0, 0xce, 0x35, 0xad, 0xf5, 0x7a, 0x4a, 0xb3, 0xe2, 0xcb, 0xd3, 0xc2, 0xf2, 0xf0, 0xaf,
0xb2, 0x1c, 0xb7, 0x14, 0xc5, 0x6f, 0x36, 0x38, 0x8a, 0xab, 0xd1, 0x05, 0x0f, 0x5a, 0x82, 0x1c, 0x34, 0xb8, 0xa1, 0x4c, 0x98, 0xca, 0x31, 0xaf, 0x20, 0xcf, 0x21, 0x4d, 0x51, 0x17, 0x17, 0xc2,
0xff, 0x92, 0xc7, 0xc2, 0x78, 0x76, 0xc9, 0x84, 0xef, 0xc3, 0x8c, 0x20, 0x91, 0x9e, 0x15, 0xb7, 0xb3, 0xb8, 0x1a, 0x5d, 0xf0, 0xa0, 0x15, 0x28, 0xf0, 0x27, 0xd9, 0x31, 0x26, 0xb3, 0x4b, 0x26,
0xb7, 0x99, 0x43, 0xf1, 0xe7, 0x30, 0x1b, 0x64, 0x1b, 0x6b, 0x4a, 0x8a, 0x91, 0xa9, 0xcb, 0x18, 0xfc, 0x04, 0xe6, 0x05, 0x89, 0x0c, 0xec, 0xa4, 0xb3, 0xcd, 0x1c, 0x8a, 0x7f, 0x06, 0x0b, 0x61,
0xb9, 0x22, 0x8d, 0xdc, 0xef, 0xb7, 0x95, 0x5a, 0x1d, 0x5e, 0x75, 0x75, 0x45, 0x52, 0xa1, 0x15, 0xb6, 0xa9, 0x96, 0xa4, 0x18, 0x99, 0xb9, 0x8e, 0x91, 0x6b, 0xd2, 0xc8, 0xc3, 0x61, 0x4f, 0x29,
0xf1, 0x26, 0x20, 0x45, 0xfc, 0xac, 0x13, 0x98, 0x91, 0xdb, 0x61, 0xab, 0xe3, 0x78, 0x27, 0xb8, 0xe3, 0xd1, 0x5d, 0x57, 0x77, 0x24, 0x13, 0xd9, 0x11, 0x7f, 0x01, 0x52, 0xc4, 0xb7, 0xba, 0x80,
0x37, 0x80, 0x54, 0xe2, 0xcf, 0x6d, 0xd0, 0x1a, 0x39, 0xb2, 0x8d, 0xe3, 0x1e, 0xf1, 0xea, 0x13, 0x79, 0x79, 0x1c, 0x76, 0x4c, 0xd7, 0x6f, 0xee, 0x3e, 0x02, 0x52, 0x89, 0xdf, 0xb6, 0x41, 0x1b,
0x3d, 0xcf, 0xab, 0xc4, 0xb1, 0x32, 0x7a, 0x1d, 0xae, 0xbc, 0xb4, 0x86, 0x34, 0x35, 0x50, 0xaa, 0xe4, 0xc4, 0x31, 0x4e, 0x07, 0xc4, 0xaf, 0x4f, 0xb4, 0xd5, 0x57, 0x89, 0x53, 0x65, 0xf4, 0x16,
0x1f, 0x32, 0xfc, 0x3e, 0xe7, 0x2d, 0x9b, 0xd7, 0xa6, 0xca, 0xd5, 0x01, 0x63, 0x29, 0xff, 0x5f, 0xdc, 0x78, 0x67, 0x8f, 0x69, 0x6a, 0xa0, 0xd4, 0x20, 0x64, 0xf8, 0x55, 0xcf, 0xdf, 0x36, 0x7f,
0x0d, 0x8a, 0x2b, 0x5d, 0xc3, 0xee, 0x49, 0xc5, 0xef, 0x43, 0x96, 0xdf, 0x52, 0x04, 0x30, 0xf0, 0x4c, 0x95, 0xab, 0x13, 0xa6, 0x52, 0xfe, 0xaf, 0x1a, 0x54, 0xd6, 0xfa, 0x86, 0x33, 0x90, 0x8a,
0x20, 0x28, 0x46, 0xe5, 0xe5, 0x8d, 0x15, 0x7e, 0xa7, 0x11, 0xa3, 0xa8, 0xe1, 0xe2, 0xed, 0x60, 0x7f, 0x00, 0x79, 0x7e, 0x81, 0x11, 0x98, 0xc1, 0xd3, 0xb0, 0x18, 0x95, 0x97, 0x0f, 0xd6, 0xf8,
0x2d, 0xf4, 0x96, 0xb0, 0x86, 0xde, 0x82, 0x8c, 0x41, 0x87, 0xb0, 0x14, 0x5c, 0x0e, 0xdf, 0x0f, 0x75, 0x47, 0xcc, 0xa2, 0x86, 0x8b, 0xcf, 0x0a, 0x1b, 0x91, 0xcf, 0x0c, 0x1b, 0xe8, 0x13, 0xc8,
0x99, 0x34, 0x76, 0x38, 0xe3, 0x5c, 0xf8, 0x3d, 0x28, 0x28, 0x1a, 0xe8, 0x0d, 0xf8, 0x45, 0x43, 0x19, 0x74, 0x0a, 0x4b, 0xc1, 0xb5, 0xe8, 0xd5, 0x91, 0x49, 0x63, 0x7d, 0x1b, 0xe7, 0xc2, 0xdf,
0x1c, 0xc0, 0x56, 0x56, 0x9b, 0x1b, 0xaf, 0xf8, 0xc5, 0xb8, 0x0c, 0xb0, 0xd6, 0xf0, 0xda, 0x29, 0x87, 0xb2, 0xa2, 0x81, 0x5e, 0x8e, 0xdf, 0xb6, 0x45, 0x03, 0xb6, 0xb6, 0xde, 0xd9, 0x7a, 0xcf,
0xfc, 0xa9, 0x18, 0x25, 0xf2, 0x9d, 0x6a, 0x8f, 0x96, 0x64, 0x4f, 0xea, 0x52, 0xf6, 0x9c, 0x41, 0xef, 0xcc, 0x35, 0x80, 0x8d, 0xb6, 0x3f, 0xce, 0xe0, 0xcf, 0xc4, 0x2c, 0x91, 0xef, 0x54, 0x7b,
0x49, 0x4c, 0x7f, 0xdc, 0xf4, 0xcd, 0xe4, 0x25, 0xa4, 0x6f, 0xc5, 0x78, 0x5d, 0x30, 0xe2, 0x69, 0xb4, 0x34, 0x7b, 0x32, 0xd7, 0xb2, 0xe7, 0x02, 0xaa, 0x62, 0xf9, 0xd3, 0xa6, 0x6f, 0x26, 0x2f,
0x28, 0x89, 0x84, 0x2e, 0xf6, 0xdf, 0xff, 0x68, 0x50, 0x96, 0x94, 0x71, 0x01, 0x4c, 0x89, 0xbd, 0x25, 0x7d, 0x2b, 0xc6, 0xeb, 0x82, 0x11, 0xcf, 0x41, 0x55, 0x24, 0x74, 0x71, 0xfe, 0xfe, 0x3a,
0xf0, 0x0a, 0xe0, 0x21, 0x2f, 0xd7, 0x20, 0xdb, 0x3e, 0xdc, 0xeb, 0xbc, 0x91, 0x60, 0xb3, 0x68, 0x03, 0x35, 0x49, 0x99, 0x16, 0xdb, 0x94, 0xb0, 0x0c, 0xaf, 0x00, 0x3e, 0x28, 0x73, 0x0b, 0xf2,
0x51, 0x7a, 0x97, 0xeb, 0xe1, 0x2f, 0x3e, 0xa2, 0x45, 0x6f, 0xe1, 0xb6, 0x71, 0xe4, 0x6e, 0x98, 0xbd, 0xe3, 0x03, 0xf3, 0xa3, 0xc4, 0xa1, 0xc5, 0x88, 0xd2, 0xfb, 0x5c, 0x0f, 0xff, 0x18, 0x24,
0x6d, 0x72, 0xc6, 0xce, 0x8d, 0x93, 0xba, 0x4f, 0x60, 0x97, 0x52, 0xf1, 0x32, 0xc4, 0x0e, 0x8b, 0x46, 0xf4, 0x82, 0xee, 0x18, 0x27, 0xde, 0x96, 0xd5, 0x23, 0x17, 0xac, 0x6f, 0x9c, 0xd5, 0x03,
0xea, 0x4b, 0xd1, 0x0c, 0x5c, 0x59, 0x19, 0xb8, 0x27, 0x0d, 0xd3, 0x38, 0xec, 0xca, 0x8c, 0x45, 0x02, 0xbb, 0xaf, 0x8a, 0x8f, 0x46, 0xac, 0x59, 0x54, 0x3e, 0x22, 0xa1, 0x17, 0x50, 0xa7, 0xcf,
0xcb, 0x2c, 0x25, 0xae, 0x75, 0x1c, 0x95, 0xda, 0x80, 0x19, 0x4a, 0x25, 0xa6, 0xdb, 0x69, 0x29, 0x6b, 0xc3, 0x61, 0xdf, 0x24, 0x3d, 0x2e, 0xa0, 0xc0, 0x78, 0x62, 0x74, 0xaa, 0x9d, 0xb5, 0x5e,
0xe9, 0x4d, 0x16, 0x31, 0x2d, 0x54, 0xc4, 0x0c, 0xc7, 0x79, 0x6d, 0xd9, 0x6d, 0x31, 0x35, 0xaf, 0x6e, 0xa3, 0xc8, 0xd2, 0x96, 0x18, 0xd1, 0x28, 0x5d, 0x1b, 0x79, 0x67, 0x6d, 0xcb, 0x38, 0xee,
0x8d, 0xd7, 0xb8, 0xf0, 0x7d, 0x27, 0x50, 0xa6, 0xbe, 0xaf, 0x94, 0x45, 0x5f, 0xca, 0x0b, 0xe2, 0xcb, 0xac, 0x47, 0x4b, 0x35, 0x25, 0x6e, 0x98, 0xae, 0x4a, 0x6d, 0xc3, 0x3c, 0xa5, 0x12, 0xcb,
0x8e, 0x90, 0x82, 0x9f, 0xc0, 0x55, 0xc9, 0x29, 0xc0, 0xbd, 0x11, 0xcc, 0x3b, 0x70, 0x4b, 0x32, 0x33, 0xbb, 0x4a, 0x8a, 0x94, 0x85, 0x50, 0x8b, 0x14, 0x42, 0xc3, 0x75, 0x3f, 0xd8, 0x4e, 0x4f,
0xaf, 0x9e, 0xd0, 0xdb, 0xd3, 0xae, 0x50, 0xf8, 0x43, 0xed, 0x7c, 0x0e, 0x55, 0xcf, 0x4e, 0x76, 0xb8, 0xc7, 0x1f, 0xe3, 0x0d, 0x2e, 0xfc, 0xd0, 0x0d, 0x95, 0xba, 0x2f, 0x2b, 0x65, 0x39, 0x90,
0x58, 0xb6, 0xba, 0xaa, 0x01, 0x03, 0x47, 0xec, 0x99, 0xbc, 0xce, 0xbe, 0x29, 0xcd, 0xb6, 0xba, 0xf2, 0x96, 0x78, 0x13, 0xa4, 0xe0, 0x97, 0x70, 0x53, 0x72, 0x0a, 0xec, 0x70, 0x02, 0xf3, 0x1e,
0xde, 0x91, 0x80, 0x7e, 0xe3, 0x55, 0x98, 0x93, 0x32, 0xc4, 0x31, 0x36, 0x28, 0x24, 0x62, 0x50, 0xdc, 0x97, 0xcc, 0xeb, 0x67, 0xf4, 0x72, 0xb6, 0x2f, 0x14, 0x7e, 0x55, 0x3b, 0xdf, 0x40, 0xc3,
0x9c, 0x10, 0xe1, 0x30, 0x3a, 0x74, 0xb4, 0xdb, 0x55, 0xce, 0xa0, 0x6b, 0x99, 0x4c, 0x4d, 0x91, 0xb7, 0x93, 0x35, 0xdc, 0x76, 0x5f, 0x35, 0x60, 0xe4, 0x8a, 0x73, 0x57, 0xd2, 0xd9, 0x33, 0xa5,
0x79, 0x95, 0xef, 0x08, 0x6a, 0x98, 0x5a, 0x31, 0x04, 0x99, 0x0a, 0x50, 0xc9, 0x62, 0x21, 0x28, 0x39, 0x76, 0xdf, 0x6f, 0x2b, 0xe8, 0x33, 0x5e, 0x87, 0x3b, 0x52, 0x86, 0x68, 0x85, 0xc3, 0x42,
0x39, 0xb2, 0x10, 0x11, 0xd1, 0x9f, 0xc1, 0xbc, 0x67, 0x04, 0xf5, 0xdb, 0x2e, 0xb1, 0x7b, 0x1d, 0x62, 0x06, 0x25, 0x09, 0x11, 0x0e, 0xa3, 0x53, 0x27, 0xbb, 0x5d, 0xe5, 0x0c, 0xbb, 0x96, 0xc9,
0xc7, 0x51, 0xe0, 0xa0, 0xb8, 0x89, 0x3f, 0x80, 0xc9, 0x3e, 0x11, 0x39, 0xa5, 0xb0, 0x8c, 0x96, 0xd4, 0x14, 0x99, 0x37, 0xf9, 0x89, 0xa0, 0x86, 0xa9, 0x55, 0x47, 0x90, 0xa9, 0x00, 0x95, 0x2c,
0xf8, 0xfb, 0xed, 0x92, 0x32, 0x98, 0xf5, 0xe3, 0x36, 0xdc, 0x96, 0xd2, 0xb9, 0x47, 0x63, 0xc5, 0x36, 0x82, 0x92, 0x63, 0x1b, 0x11, 0x13, 0xfd, 0x53, 0x58, 0xf4, 0x8d, 0xa0, 0x7e, 0xdb, 0x27,
0x87, 0x8d, 0x92, 0xb7, 0x6e, 0xee, 0xd6, 0xe8, 0xad, 0x3b, 0xcd, 0xd7, 0xde, 0x83, 0x28, 0x3f, 0xce, 0xc0, 0x74, 0x5d, 0x05, 0x6d, 0x4a, 0x5a, 0xf8, 0x53, 0x98, 0x1d, 0x12, 0x91, 0x97, 0xca,
0xe2, 0x8e, 0x94, 0xb1, 0x35, 0x56, 0xad, 0xd8, 0xe4, 0x3e, 0xf5, 0x42, 0x72, 0x2c, 0x61, 0x87, 0xab, 0x68, 0x85, 0x7f, 0x1e, 0x5e, 0x51, 0x26, 0xb3, 0xf7, 0xb8, 0x07, 0x0f, 0xa4, 0x74, 0xee,
0x30, 0x1b, 0x8c, 0xe4, 0xb1, 0xd2, 0xd8, 0x2c, 0x64, 0x5c, 0xeb, 0x94, 0xc8, 0x24, 0xc6, 0x1b, 0xd1, 0x44, 0xf1, 0x51, 0xa3, 0xe4, 0xa5, 0x9e, 0xbb, 0x35, 0x7e, 0xa9, 0xcf, 0xf2, 0xbd, 0xf7,
0xd2, 0x60, 0x2f, 0xcc, 0xc7, 0x32, 0xd8, 0xf0, 0x85, 0xb1, 0x2d, 0x39, 0xae, 0xbd, 0x74, 0x35, 0x11, 0xd0, 0x1f, 0x73, 0x47, 0xca, 0xd8, 0x9a, 0xaa, 0xde, 0x6c, 0x73, 0x9f, 0xfa, 0x21, 0x39,
0xe5, 0xe1, 0x8b, 0x37, 0xf0, 0x36, 0x5c, 0x0b, 0xa7, 0x89, 0xb1, 0x4c, 0x7e, 0xc5, 0x37, 0x70, 0x95, 0xb0, 0x63, 0x58, 0x08, 0x47, 0xf2, 0x54, 0xa9, 0x70, 0x01, 0x72, 0x9e, 0x7d, 0x4e, 0x64,
0x5c, 0x26, 0x19, 0x4b, 0xee, 0xc7, 0x7e, 0x32, 0x50, 0x12, 0xca, 0x58, 0x22, 0x75, 0xa8, 0xc5, 0x22, 0xe4, 0x03, 0x69, 0xb0, 0x1f, 0xe6, 0x53, 0x19, 0x6c, 0x04, 0xc2, 0xd8, 0x91, 0x9c, 0xd6,
0xe5, 0x97, 0x1f, 0x63, 0xbf, 0x7a, 0xe9, 0x66, 0x2c, 0x61, 0x8e, 0x2f, 0x6c, 0xfc, 0xe5, 0xf7, 0x5e, 0xba, 0x9b, 0xb2, 0x81, 0xe3, 0x03, 0xbc, 0x0b, 0xb7, 0xa2, 0x69, 0x62, 0x2a, 0x93, 0xdf,
0x73, 0x44, 0x7a, 0x64, 0x8e, 0x10, 0x41, 0xe2, 0x67, 0xb1, 0x9f, 0x60, 0xd3, 0x09, 0x1d, 0x7e, 0xf3, 0x03, 0x9c, 0x94, 0x49, 0xa6, 0x92, 0xfb, 0x93, 0x20, 0x19, 0x28, 0x09, 0x65, 0x2a, 0x91,
0x02, 0x1d, 0x57, 0x07, 0xad, 0x21, 0x9e, 0x0e, 0xd6, 0x90, 0x1b, 0x5b, 0x4d, 0xbb, 0x63, 0x2d, 0x3a, 0x34, 0x93, 0xf2, 0xcb, 0xd7, 0x71, 0x5e, 0xfd, 0x74, 0x33, 0x95, 0x30, 0x37, 0x10, 0x36,
0xc6, 0x27, 0x7e, 0xee, 0x8c, 0x64, 0xe6, 0xb1, 0x04, 0x7f, 0x0a, 0x0b, 0xc9, 0x49, 0x79, 0x1c, 0xfd, 0xf6, 0x07, 0x39, 0x22, 0x3b, 0x31, 0x47, 0x88, 0x20, 0x09, 0xb2, 0xd8, 0x37, 0x70, 0xe8,
0xc9, 0x8f, 0xeb, 0x90, 0xf7, 0x0e, 0x94, 0xca, 0x6f, 0x1f, 0x0a, 0x90, 0xdb, 0xde, 0xd9, 0xdb, 0x84, 0x8e, 0x20, 0x81, 0x4e, 0xab, 0x83, 0xd6, 0x10, 0x5f, 0x07, 0x1b, 0xc8, 0x83, 0xad, 0xa6,
0x5d, 0x59, 0x6d, 0xf0, 0x1f, 0x3f, 0xac, 0xee, 0xe8, 0xfa, 0xfe, 0x6e, 0xb3, 0x92, 0x5a, 0xfe, 0xdd, 0xa9, 0x36, 0xe3, 0xd3, 0x20, 0x77, 0xc6, 0x32, 0xf3, 0x54, 0x82, 0x3f, 0x83, 0xa5, 0xf4,
0x6d, 0x1a, 0x52, 0x9b, 0xaf, 0xd0, 0x9f, 0x43, 0x86, 0xbf, 0x04, 0x8e, 0x78, 0xfe, 0xad, 0x8d, 0xa4, 0x3c, 0x8d, 0xe4, 0x17, 0x2d, 0x28, 0xf9, 0x4d, 0xa9, 0xf2, 0xd3, 0x8a, 0x32, 0x14, 0x76,
0x7a, 0xec, 0xc4, 0x37, 0xbe, 0xf8, 0xff, 0x5f, 0x7d, 0x95, 0xba, 0x8a, 0x2b, 0xf5, 0xe1, 0xbb, 0xf7, 0x0e, 0xf6, 0xd7, 0xd6, 0xdb, 0xfc, 0xb7, 0x15, 0xeb, 0x7b, 0xba, 0x7e, 0xb8, 0xdf, 0xa9,
0x87, 0xc4, 0x35, 0xea, 0xa7, 0xc3, 0x3a, 0xab, 0x0f, 0xcf, 0xb4, 0xc7, 0x68, 0x1f, 0xd2, 0xbb, 0x67, 0x56, 0xff, 0x37, 0x0b, 0x99, 0xed, 0xf7, 0xe8, 0xf7, 0x21, 0xc7, 0x3f, 0x34, 0x4e, 0xf8,
0x03, 0x17, 0x25, 0x3e, 0x0d, 0xd7, 0x92, 0xdf, 0x40, 0xf1, 0x1c, 0x13, 0x3c, 0x83, 0xcb, 0x8a, 0xba, 0xdc, 0x9c, 0xf4, 0x2d, 0x15, 0xdf, 0xfd, 0xf9, 0xbf, 0xff, 0xd7, 0x2f, 0x33, 0x37, 0x71,
0xe0, 0xfe, 0xc0, 0xa5, 0x62, 0x07, 0x50, 0x50, 0x5f, 0x31, 0x2f, 0x7c, 0x33, 0xae, 0x5d, 0xfc, 0xbd, 0x35, 0xfe, 0xde, 0x31, 0xf1, 0x8c, 0xd6, 0xf9, 0xb8, 0xc5, 0xea, 0xc3, 0x6b, 0xed, 0x05,
0x42, 0x8a, 0xef, 0x30, 0x75, 0x37, 0xf0, 0x35, 0x45, 0x1d, 0x7f, 0x6b, 0x55, 0x67, 0xd3, 0x3c, 0x3a, 0x84, 0xec, 0xfe, 0xc8, 0x43, 0xa9, 0x5f, 0x9e, 0x9b, 0xe9, 0x9f, 0x58, 0xf1, 0x1d, 0x26,
0x33, 0x51, 0xe2, 0xab, 0x72, 0x2d, 0xf9, 0xe1, 0x34, 0x76, 0x36, 0xee, 0x99, 0x49, 0xc5, 0x9a, 0x78, 0x1e, 0xd7, 0x14, 0xc1, 0xc3, 0x91, 0x47, 0xc5, 0x8e, 0xa0, 0xac, 0x7e, 0x24, 0xbd, 0xf2,
0xe2, 0xdd, 0xb4, 0xe5, 0xa2, 0xdb, 0x31, 0xef, 0x66, 0xea, 0x0b, 0x51, 0x6d, 0x21, 0x99, 0x41, 0x93, 0x74, 0xf3, 0xea, 0x0f, 0xb0, 0xf8, 0x21, 0x53, 0x77, 0x17, 0xdf, 0x52, 0xd4, 0xf1, 0x4f,
0x28, 0x5a, 0x60, 0x8a, 0x6a, 0xf8, 0xaa, 0xa2, 0xa8, 0xe5, 0xb1, 0x3d, 0xd3, 0x1e, 0x2f, 0x1f, 0xb9, 0xea, 0x6a, 0x3a, 0x17, 0x16, 0x4a, 0xfd, 0x68, 0xdd, 0x4c, 0xff, 0x2e, 0x9b, 0xb8, 0x1a,
0x43, 0x86, 0x21, 0xc4, 0xe8, 0x2f, 0xe4, 0x47, 0x2d, 0x06, 0xdb, 0x4e, 0x58, 0xfc, 0x00, 0xb6, 0xef, 0xc2, 0xa2, 0x62, 0x2d, 0xf1, 0x59, 0xb6, 0xeb, 0xa1, 0x07, 0x09, 0x9f, 0xe5, 0xd4, 0x0f,
0x8c, 0xab, 0x4c, 0x19, 0xc2, 0x25, 0xa9, 0x8c, 0x61, 0xc4, 0xcf, 0xb4, 0xc7, 0x8b, 0xda, 0xdb, 0x50, 0xcd, 0xa5, 0x74, 0x06, 0xa1, 0x68, 0x89, 0x29, 0x6a, 0xe2, 0x9b, 0x8a, 0xa2, 0xae, 0xcf,
0xda, 0xf2, 0x6f, 0x26, 0x21, 0xc3, 0xe0, 0x22, 0x64, 0x01, 0xf8, 0x68, 0x6a, 0x78, 0x96, 0x11, 0xf6, 0x5a, 0x7b, 0xb1, 0x7a, 0x0a, 0x39, 0x86, 0x32, 0xa3, 0x3f, 0x90, 0x0f, 0xcd, 0x04, 0xe8,
0x7c, 0x36, 0x3c, 0xcb, 0x28, 0x10, 0x8b, 0xe7, 0x99, 0xe2, 0x2a, 0x9e, 0x91, 0x8a, 0x19, 0x12, 0x3c, 0x65, 0xf3, 0x43, 0xf8, 0x34, 0x6e, 0x30, 0x65, 0x08, 0x57, 0xa5, 0x32, 0x86, 0x33, 0xbf,
0x55, 0x67, 0xe0, 0x1a, 0xf5, 0xe9, 0x50, 0x00, 0x66, 0x3c, 0xcc, 0x50, 0x9c, 0xc0, 0x00, 0xaa, 0xd6, 0x5e, 0x2c, 0x6b, 0xdf, 0xd1, 0x56, 0xff, 0x67, 0x16, 0x72, 0x0c, 0x72, 0x42, 0x36, 0x40,
0x1a, 0xde, 0x21, 0x31, 0x88, 0x2a, 0xc6, 0x4c, 0xe7, 0x4d, 0x7c, 0x5d, 0xf1, 0x2c, 0x57, 0x6b, 0x80, 0xc8, 0x46, 0x57, 0x19, 0xc3, 0x78, 0xa3, 0xab, 0x8c, 0x83, 0xb9, 0x78, 0x91, 0x29, 0x6e,
0x33, 0x46, 0xaa, 0xf7, 0xef, 0x34, 0x28, 0x07, 0x71, 0x51, 0x74, 0x37, 0x46, 0x72, 0x18, 0x5e, 0xe0, 0x79, 0xa9, 0x98, 0xa1, 0x59, 0x2d, 0x06, 0xd0, 0x51, 0x9f, 0x8e, 0x05, 0xe8, 0xc6, 0xc3,
0xad, 0xdd, 0x1b, 0xcd, 0x94, 0x64, 0x01, 0x57, 0x7f, 0x4a, 0x48, 0xdf, 0xa0, 0x8c, 0xc2, 0xf1, 0x0c, 0x25, 0x09, 0x0c, 0x21, 0xb3, 0xd1, 0x13, 0x92, 0x80, 0xca, 0x62, 0xcc, 0x74, 0xde, 0xc3,
0xe8, 0x1f, 0x34, 0x98, 0x0e, 0x81, 0x9d, 0x28, 0x4e, 0x43, 0x04, 0x4a, 0xad, 0xdd, 0xbf, 0x80, 0xb7, 0x15, 0xcf, 0x72, 0xb5, 0x0e, 0x63, 0xa4, 0x7a, 0xff, 0x4c, 0x83, 0x5a, 0x18, 0x5b, 0x45,
0x4b, 0x18, 0xf2, 0x80, 0x19, 0xb2, 0x80, 0x6f, 0x44, 0x5c, 0xe1, 0x76, 0x7a, 0xc4, 0xb5, 0x84, 0x8f, 0x12, 0x24, 0x47, 0x21, 0xda, 0xe6, 0xe3, 0xc9, 0x4c, 0x69, 0x16, 0x70, 0xf5, 0xe7, 0x84,
0x31, 0xde, 0x32, 0x70, 0x60, 0x32, 0x76, 0x19, 0x02, 0x40, 0x67, 0xec, 0x32, 0x04, 0x51, 0xcd, 0x0c, 0x0d, 0xca, 0x28, 0x1c, 0x8f, 0xfe, 0x42, 0x83, 0xb9, 0x08, 0x60, 0x8a, 0x92, 0x34, 0xc4,
0x11, 0xcb, 0xc0, 0xd1, 0x48, 0xba, 0xc5, 0x7f, 0x97, 0x86, 0xdc, 0x2a, 0xff, 0x05, 0x22, 0x72, 0xe0, 0xd8, 0xe6, 0x93, 0x2b, 0xb8, 0x84, 0x21, 0x4f, 0x99, 0x21, 0x4b, 0xf8, 0x6e, 0xcc, 0x15,
0x20, 0xef, 0x21, 0x80, 0x68, 0x3e, 0x0e, 0x8d, 0xf1, 0x6f, 0x0b, 0xb5, 0xdb, 0x89, 0xfd, 0x42, 0x9e, 0x39, 0x20, 0x9e, 0x2d, 0x8c, 0xf1, 0xb7, 0x81, 0x83, 0x9b, 0x89, 0xdb, 0x10, 0x02, 0x4b,
0xfb, 0x7d, 0xa6, 0xfd, 0x36, 0xae, 0x49, 0xed, 0xe2, 0x87, 0x8e, 0x75, 0x7e, 0xed, 0xaf, 0x1b, 0x13, 0xb7, 0x21, 0x8c, 0x8c, 0x4e, 0xd8, 0x06, 0x8e, 0x68, 0xd2, 0x23, 0xfe, 0x7f, 0x59, 0x28,
0xed, 0x36, 0x9d, 0xf8, 0xdf, 0x42, 0x51, 0x85, 0xe9, 0xd0, 0x9d, 0x58, 0x14, 0x48, 0x45, 0xfa, 0xac, 0xf3, 0x1f, 0x38, 0x22, 0x17, 0x4a, 0x3e, 0x8a, 0x88, 0x16, 0x93, 0x10, 0x9d, 0xe0, 0xb6,
0x6a, 0x78, 0x14, 0x8b, 0xd0, 0xbe, 0xc8, 0xb4, 0x63, 0x7c, 0x2b, 0x41, 0xbb, 0xcd, 0xd8, 0x03, 0xd0, 0x7c, 0x90, 0xfa, 0x5e, 0x68, 0x7f, 0xc2, 0xb4, 0x3f, 0xc0, 0x4d, 0xa9, 0x5d, 0xfc, 0x8e,
0x06, 0x70, 0x98, 0x2d, 0xde, 0x80, 0x00, 0x8a, 0x17, 0x6f, 0x40, 0x10, 0xa5, 0xbb, 0xd0, 0x80, 0xb2, 0xc5, 0xa1, 0x83, 0x96, 0xd1, 0xeb, 0xd1, 0x85, 0xff, 0x29, 0x54, 0x54, 0xa8, 0x0f, 0x3d,
0x01, 0x63, 0xa7, 0x06, 0xbc, 0x06, 0xf0, 0x41, 0x35, 0x14, 0xeb, 0x57, 0xe5, 0xea, 0x14, 0x0e, 0x4c, 0x44, 0x92, 0x54, 0xb4, 0xb0, 0x89, 0x27, 0xb1, 0x08, 0xed, 0xcb, 0x4c, 0x3b, 0xc6, 0xf7,
0xf9, 0x28, 0x1e, 0x17, 0xdd, 0x73, 0x21, 0xd5, 0xdd, 0x8e, 0x43, 0x43, 0x7f, 0xf9, 0x9b, 0x2c, 0x53, 0xb4, 0x3b, 0x8c, 0x3d, 0x64, 0x00, 0x87, 0xea, 0x92, 0x0d, 0x08, 0x21, 0x81, 0xc9, 0x06,
0x14, 0x5e, 0x1a, 0x1d, 0xd3, 0x25, 0xa6, 0x61, 0xb6, 0x08, 0x3a, 0x82, 0x0c, 0x2b, 0x8d, 0xe1, 0x84, 0x91, 0xbe, 0x2b, 0x0d, 0x18, 0x31, 0x76, 0x6a, 0xc0, 0x07, 0x80, 0x00, 0x98, 0x43, 0x89,
0x2c, 0xa7, 0x62, 0x4d, 0xe1, 0x2c, 0x17, 0x00, 0x62, 0xf0, 0x3d, 0xa6, 0x79, 0x1e, 0xcf, 0x49, 0x7e, 0x55, 0xae, 0x4e, 0xd1, 0x90, 0x8f, 0x63, 0x7a, 0xf1, 0x33, 0x17, 0x51, 0xdd, 0x37, 0x5d,
0xcd, 0x3d, 0x5f, 0x7c, 0x9d, 0x61, 0x28, 0x74, 0xc2, 0x7f, 0x09, 0x59, 0x01, 0xcf, 0x87, 0x84, 0x1a, 0xfa, 0xab, 0xbf, 0xca, 0x43, 0xf9, 0x9d, 0x61, 0x5a, 0x1e, 0xb1, 0x0c, 0xab, 0x4b, 0xd0,
0x05, 0xb0, 0x95, 0xda, 0xcd, 0xf8, 0xce, 0xa4, 0xed, 0xa5, 0xaa, 0x72, 0x18, 0x2f, 0xd5, 0xf5, 0x09, 0xe4, 0x58, 0x69, 0x8c, 0x66, 0x39, 0x15, 0xaf, 0x8a, 0x66, 0xb9, 0x10, 0x98, 0x83, 0x1f,
0x06, 0xc0, 0x07, 0x08, 0xc3, 0xce, 0x8d, 0xe0, 0x89, 0xb5, 0x85, 0x64, 0x06, 0xa1, 0xf7, 0x11, 0x33, 0xcd, 0x8b, 0xf8, 0x8e, 0xd4, 0x3c, 0x08, 0xc4, 0xb7, 0x18, 0x0e, 0x43, 0x17, 0xfc, 0x87,
0xd3, 0x7b, 0x17, 0xcf, 0xc7, 0xe9, 0x6d, 0x7b, 0xfc, 0x54, 0xf7, 0x21, 0x4c, 0xae, 0x1b, 0xce, 0x90, 0x17, 0x10, 0x7f, 0x44, 0x58, 0x08, 0x9f, 0x69, 0xde, 0x4b, 0x7e, 0x99, 0x76, 0xbc, 0x54,
0x09, 0x0a, 0x15, 0x3b, 0xe5, 0x47, 0x03, 0xb5, 0x5a, 0x5c, 0x97, 0xd0, 0x74, 0x97, 0x69, 0xba, 0x55, 0x2e, 0xe3, 0xa5, 0xba, 0x3e, 0x02, 0x04, 0x20, 0x63, 0xd4, 0xb9, 0x31, 0x4c, 0xb2, 0xb9,
0x85, 0xab, 0x71, 0x9a, 0x4e, 0x0c, 0x87, 0x56, 0x0f, 0x74, 0x02, 0x59, 0xfe, 0x3b, 0x82, 0xb0, 0x94, 0xce, 0x20, 0xf4, 0x3e, 0x67, 0x7a, 0x1f, 0xe1, 0xc5, 0x24, 0xbd, 0x3d, 0x9f, 0x9f, 0xea,
0x2f, 0x03, 0xbf, 0x45, 0x08, 0xfb, 0x32, 0xf8, 0xd3, 0x83, 0xcb, 0x69, 0x72, 0x61, 0x4a, 0x3e, 0x3e, 0x86, 0xd9, 0x4d, 0xc3, 0x3d, 0x43, 0x91, 0x62, 0xa7, 0xfc, 0x26, 0xa1, 0xd9, 0x4c, 0x7a,
0xde, 0xa3, 0x5b, 0xa1, 0xa5, 0x09, 0x3e, 0xf4, 0xd7, 0xe6, 0x93, 0xba, 0x85, 0xbe, 0x87, 0x4c, 0x25, 0x34, 0x3d, 0x62, 0x9a, 0xee, 0xe3, 0x46, 0x92, 0xa6, 0x33, 0xc3, 0xa5, 0xd5, 0x03, 0x9d,
0xdf, 0x1d, 0x7c, 0x33, 0x76, 0xed, 0x04, 0xf7, 0x33, 0xed, 0xf1, 0xdb, 0x1a, 0x2d, 0x13, 0xe0, 0x41, 0x9e, 0xff, 0x4c, 0x21, 0xea, 0xcb, 0xd0, 0x4f, 0x1d, 0xa2, 0xbe, 0x0c, 0xff, 0xb2, 0xe1,
0x83, 0xac, 0x91, 0xe8, 0x08, 0xe3, 0xb5, 0x91, 0xe8, 0x88, 0xe0, 0xb3, 0x78, 0x99, 0x29, 0x7f, 0x7a, 0x9a, 0x3c, 0x28, 0xca, 0xdf, 0x06, 0xa0, 0xfb, 0x91, 0xad, 0x09, 0xff, 0x8e, 0xa0, 0xb9,
0x8a, 0x1f, 0xc6, 0x29, 0x77, 0x6d, 0xc3, 0x74, 0x8e, 0x88, 0xfd, 0x16, 0x07, 0xd3, 0x9c, 0x93, 0x98, 0xf6, 0x5a, 0xe8, 0x7b, 0xc6, 0xf4, 0x3d, 0xc4, 0xf7, 0x12, 0xf7, 0x4e, 0x70, 0xbf, 0xd6,
0x4e, 0x9f, 0x46, 0xca, 0xef, 0xa7, 0x61, 0x92, 0x9e, 0x47, 0x69, 0x79, 0xf6, 0xaf, 0xf1, 0x61, 0x5e, 0x7c, 0x47, 0xa3, 0x65, 0x02, 0x02, 0xa0, 0x36, 0x16, 0x1d, 0x51, 0xcc, 0x37, 0x16, 0x1d,
0x6b, 0x22, 0xe0, 0x59, 0xd8, 0x9a, 0x28, 0x02, 0x10, 0x2d, 0xcf, 0xec, 0xb7, 0xe6, 0x84, 0x31, 0x31, 0x8c, 0x17, 0xaf, 0x32, 0xe5, 0xaf, 0xf0, 0xb3, 0x24, 0xe5, 0x9e, 0x63, 0x58, 0xee, 0x09,
0x51, 0xaf, 0x3b, 0x50, 0x50, 0xee, 0xfa, 0x28, 0x46, 0x60, 0x10, 0x99, 0x0b, 0xd7, 0x85, 0x18, 0x71, 0x3e, 0xe1, 0x80, 0x9c, 0x7b, 0x66, 0x0e, 0x69, 0xa4, 0xfc, 0xff, 0x1c, 0xcc, 0xd2, 0x7e,
0xa0, 0x00, 0xdf, 0x66, 0x3a, 0xe7, 0xf0, 0x6c, 0x40, 0x67, 0x9b, 0x73, 0x51, 0xa5, 0x7f, 0x0d, 0x94, 0x96, 0xe7, 0xe0, 0x1a, 0x1f, 0xb5, 0x26, 0x06, 0x9e, 0x45, 0xad, 0x89, 0x23, 0x00, 0xf1,
0x45, 0x15, 0x13, 0x40, 0x31, 0x32, 0x43, 0xc8, 0x5f, 0x38, 0x25, 0xc6, 0x41, 0x0a, 0xd1, 0xec, 0xf2, 0xcc, 0x7e, 0xca, 0x4e, 0x18, 0x13, 0xf5, 0xba, 0x0b, 0x65, 0xe5, 0xae, 0x8f, 0x12, 0x04,
0xe0, 0xfd, 0xae, 0x5e, 0xb2, 0x52, 0xe5, 0x7d, 0xc8, 0x09, 0xa0, 0x20, 0x6e, 0xb6, 0x41, 0xa8, 0x86, 0x91, 0xb9, 0x68, 0x5d, 0x48, 0x00, 0x0a, 0xf0, 0x03, 0xa6, 0xf3, 0x0e, 0x5e, 0x08, 0xe9,
0x30, 0x6e, 0xb6, 0x21, 0x94, 0x21, 0x7a, 0xcc, 0x63, 0x5a, 0xe9, 0x7d, 0x48, 0x96, 0x20, 0xa1, 0xec, 0x71, 0x2e, 0xaa, 0xf4, 0x8f, 0xa1, 0xa2, 0x62, 0x02, 0x28, 0x41, 0x66, 0x04, 0xf9, 0x8b,
0xf1, 0x05, 0x71, 0x93, 0x34, 0xfa, 0xd8, 0x57, 0x92, 0x46, 0xe5, 0x2e, 0x3a, 0x4a, 0xe3, 0x31, 0xa6, 0xc4, 0x24, 0x48, 0x21, 0x9e, 0x1d, 0xfc, 0x9f, 0xed, 0x4b, 0x56, 0xaa, 0x7c, 0x08, 0x05,
0x71, 0x45, 0x2c, 0xc9, 0x7b, 0x1e, 0x4a, 0x10, 0xa8, 0xa6, 0x7c, 0x3c, 0x8a, 0x25, 0xe9, 0x54, 0x01, 0x14, 0x24, 0xad, 0x36, 0x0c, 0x15, 0x26, 0xad, 0x36, 0x82, 0x32, 0xc4, 0xdb, 0x3c, 0xa6,
0xee, 0x2b, 0x15, 0xf9, 0x1e, 0x7d, 0x0e, 0xe0, 0x43, 0x1a, 0xe1, 0xd3, 0x56, 0x2c, 0x2e, 0x1a, 0x95, 0xde, 0x87, 0x64, 0x09, 0x12, 0x1a, 0xdf, 0x12, 0x2f, 0x4d, 0x63, 0x80, 0x7d, 0xa5, 0x69,
0x3e, 0x6d, 0xc5, 0xa3, 0x22, 0xd1, 0xfc, 0xe1, 0xeb, 0xe6, 0x17, 0x03, 0xaa, 0xfd, 0x5f, 0x34, 0x54, 0xee, 0xa2, 0x93, 0x34, 0x9e, 0x12, 0x4f, 0xc4, 0x92, 0xbc, 0xe7, 0xa1, 0x14, 0x81, 0x6a,
0x40, 0x51, 0x04, 0x04, 0x3d, 0x89, 0xd7, 0x10, 0x8b, 0xb8, 0xd6, 0x9e, 0x5e, 0x8e, 0x39, 0xa9, 0xca, 0xc7, 0x93, 0x58, 0xd2, 0xba, 0xf2, 0x40, 0xa9, 0xc8, 0xf7, 0xe8, 0x67, 0x00, 0x01, 0xa4,
0x44, 0xf8, 0x66, 0xb5, 0xd8, 0x88, 0xfe, 0x6b, 0x6a, 0xd8, 0x97, 0x1a, 0x94, 0x02, 0x10, 0x0a, 0x11, 0xed, 0xb6, 0x12, 0x71, 0xd1, 0x68, 0xb7, 0x95, 0x8c, 0x8a, 0xc4, 0xf3, 0x47, 0xa0, 0x9b,
0x7a, 0x90, 0xb0, 0xc6, 0x21, 0xd0, 0xb6, 0xf6, 0xf0, 0x42, 0xbe, 0xa4, 0x93, 0x98, 0xb2, 0x23, 0x5f, 0x0c, 0xa8, 0xf6, 0xbf, 0xd5, 0x00, 0xc5, 0x11, 0x10, 0xf4, 0x32, 0x59, 0x43, 0x22, 0xe2,
0xe4, 0x41, 0xfc, 0x1f, 0x35, 0x28, 0x07, 0x61, 0x17, 0x94, 0x20, 0x3f, 0x02, 0xfc, 0xd6, 0x16, 0xda, 0x7c, 0x75, 0x3d, 0xe6, 0xb4, 0x12, 0x11, 0x98, 0xd5, 0x65, 0x33, 0x86, 0x1f, 0xa8, 0x61,
0x2f, 0x66, 0xbc, 0x78, 0xa9, 0xfc, 0xb3, 0x79, 0x1f, 0x72, 0x02, 0xac, 0x89, 0x0b, 0x88, 0x20, 0xbf, 0xd0, 0xa0, 0x1a, 0x82, 0x50, 0xd0, 0xd3, 0x94, 0x3d, 0x8e, 0x80, 0xb6, 0xcd, 0x67, 0x57,
0x6c, 0x1c, 0x17, 0x10, 0x21, 0xa4, 0x27, 0x21, 0x20, 0x6c, 0xab, 0x4b, 0x94, 0x10, 0x14, 0x88, 0xf2, 0xa5, 0x75, 0x62, 0xca, 0x89, 0x90, 0x8d, 0xf8, 0x5f, 0x6a, 0x50, 0x0b, 0xc3, 0x2e, 0x28,
0x4e, 0x92, 0xc6, 0xd1, 0x21, 0x18, 0x82, 0x83, 0x46, 0x69, 0xf4, 0x43, 0x50, 0xc2, 0x39, 0x28, 0x45, 0x7e, 0x0c, 0xf8, 0x6d, 0x2e, 0x5f, 0xcd, 0x78, 0xf5, 0x56, 0x05, 0xbd, 0xf9, 0x10, 0x0a,
0x41, 0xe0, 0x05, 0x21, 0x18, 0x46, 0x83, 0x12, 0x42, 0x90, 0x29, 0x55, 0x42, 0xd0, 0x07, 0x5f, 0x02, 0xac, 0x49, 0x0a, 0x88, 0x30, 0x6c, 0x9c, 0x14, 0x10, 0x11, 0xa4, 0x27, 0x25, 0x20, 0x1c,
0xe2, 0x42, 0x30, 0x82, 0x88, 0xc7, 0x85, 0x60, 0x14, 0xbf, 0x49, 0x58, 0x57, 0xa6, 0x3b, 0x10, 0xbb, 0x4f, 0x94, 0x10, 0x14, 0x88, 0x4e, 0x9a, 0xc6, 0xc9, 0x21, 0x18, 0x81, 0x83, 0x26, 0x69,
0x82, 0x33, 0x31, 0x58, 0x0d, 0x7a, 0x9a, 0xe0, 0xd0, 0x58, 0xb0, 0xbd, 0xf6, 0xd6, 0x25, 0xb9, 0x0c, 0x42, 0x50, 0xc2, 0x39, 0x28, 0x45, 0xe0, 0x15, 0x21, 0x18, 0x45, 0x83, 0x52, 0x42, 0x90,
0x47, 0xee, 0x7d, 0xbe, 0x14, 0x72, 0xef, 0x7f, 0xad, 0xc1, 0x6c, 0x1c, 0xd6, 0x83, 0x12, 0x74, 0x29, 0x55, 0x42, 0x30, 0x00, 0x5f, 0x92, 0x42, 0x30, 0x86, 0x88, 0x27, 0x85, 0x60, 0x1c, 0xbf,
0x25, 0x00, 0xf5, 0xb5, 0xa5, 0xcb, 0xb2, 0x5f, 0xec, 0x35, 0x2f, 0x1a, 0x9e, 0x57, 0xfe, 0xfb, 0x49, 0xd9, 0x57, 0xa6, 0x3b, 0x14, 0x82, 0xf3, 0x09, 0x58, 0x0d, 0x7a, 0x95, 0xe2, 0xd0, 0x44,
0xbb, 0x79, 0xed, 0xff, 0xbe, 0x9b, 0xd7, 0x7e, 0xf1, 0xdd, 0xbc, 0xf6, 0xaf, 0xbf, 0x9c, 0x9f, 0xb0, 0xbd, 0xf9, 0xc9, 0x35, 0xb9, 0x27, 0x9e, 0x7d, 0xbe, 0x15, 0xf2, 0xec, 0xff, 0x83, 0x06,
0x38, 0xcc, 0xb2, 0xff, 0xe1, 0xf5, 0xee, 0x1f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x74, 0x55, 0x61, 0x0b, 0x49, 0x58, 0x0f, 0x4a, 0xd1, 0x95, 0x02, 0xd4, 0x37, 0x57, 0xae, 0xcb, 0x7e, 0xb5, 0xd7,
0xe6, 0x68, 0x36, 0x00, 0x00, 0xfc, 0x68, 0x78, 0x53, 0xff, 0x97, 0x2f, 0x16, 0xb5, 0x7f, 0xfb, 0x62, 0x51, 0xfb, 0x8f, 0x2f,
0x16, 0xb5, 0xbf, 0xfb, 0xcf, 0xc5, 0x99, 0xe3, 0x3c, 0xfb, 0x0f, 0x64, 0xdf, 0xfb, 0x4d, 0x00,
0x00, 0x00, 0xff, 0xff, 0x80, 0x82, 0x49, 0x96, 0xd9, 0x36, 0x00, 0x00,
} }

View File

@ -17,8 +17,9 @@ package etcdserver
import ( import (
"time" "time"
"github.com/coreos/etcd/internal/version"
"github.com/coreos/etcd/pkg/runtime" "github.com/coreos/etcd/pkg/runtime"
"github.com/coreos/etcd/version"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )

View File

@ -73,6 +73,7 @@ func init() {
type RaftTimer interface { type RaftTimer interface {
Index() uint64 Index() uint64
AppliedIndex() uint64
Term() uint64 Term() uint64
} }
@ -91,9 +92,10 @@ type raftNode struct {
// Cache of the latest raft index and raft term the server has seen. // Cache of the latest raft index and raft term the server has seen.
// These three unit64 fields must be the first elements to keep 64-bit // These three unit64 fields must be the first elements to keep 64-bit
// alignment for atomic access to the fields. // alignment for atomic access to the fields.
index uint64 index uint64
term uint64 appliedindex uint64
lead uint64 term uint64
lead uint64
raftNodeConfig raftNodeConfig

View File

@ -29,19 +29,22 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/coreos/etcd/alarm"
"github.com/coreos/etcd/auth"
"github.com/coreos/etcd/compactor"
"github.com/coreos/etcd/discovery"
"github.com/coreos/etcd/etcdserver/api" "github.com/coreos/etcd/etcdserver/api"
"github.com/coreos/etcd/etcdserver/api/v2http/httptypes" "github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/etcdserver/membership"
"github.com/coreos/etcd/etcdserver/stats" "github.com/coreos/etcd/etcdserver/stats"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/alarm"
"github.com/coreos/etcd/lease/leasehttp" "github.com/coreos/etcd/internal/auth"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/compactor"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/discovery"
"github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/internal/lease/leasehttp"
"github.com/coreos/etcd/internal/mvcc"
"github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/internal/raftsnap"
"github.com/coreos/etcd/internal/store"
"github.com/coreos/etcd/internal/version"
"github.com/coreos/etcd/pkg/fileutil" "github.com/coreos/etcd/pkg/fileutil"
"github.com/coreos/etcd/pkg/idutil" "github.com/coreos/etcd/pkg/idutil"
"github.com/coreos/etcd/pkg/pbutil" "github.com/coreos/etcd/pkg/pbutil"
@ -52,9 +55,6 @@ import (
"github.com/coreos/etcd/raft" "github.com/coreos/etcd/raft"
"github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/rafthttp" "github.com/coreos/etcd/rafthttp"
"github.com/coreos/etcd/snap"
"github.com/coreos/etcd/store"
"github.com/coreos/etcd/version"
"github.com/coreos/etcd/wal" "github.com/coreos/etcd/wal"
"github.com/coreos/go-semver/semver" "github.com/coreos/go-semver/semver"
@ -206,7 +206,7 @@ type EtcdServer struct {
cluster *membership.RaftCluster cluster *membership.RaftCluster
store store.Store store store.Store
snapshotter *snap.Snapshotter snapshotter *raftsnap.Snapshotter
applyV2 ApplierV2 applyV2 ApplierV2
@ -279,7 +279,7 @@ func NewServer(cfg ServerConfig) (srv *EtcdServer, err error) {
if err = fileutil.TouchDirAll(cfg.SnapDir()); err != nil { if err = fileutil.TouchDirAll(cfg.SnapDir()); err != nil {
plog.Fatalf("create snapshot directory error: %v", err) plog.Fatalf("create snapshot directory error: %v", err)
} }
ss := snap.New(cfg.SnapDir()) ss := raftsnap.New(cfg.SnapDir())
bepath := cfg.backendPath() bepath := cfg.backendPath()
beExist := fileutil.Exist(bepath) beExist := fileutil.Exist(bepath)
@ -373,7 +373,7 @@ func NewServer(cfg ServerConfig) (srv *EtcdServer, err error) {
plog.Warningf("discovery token ignored since a cluster has already been initialized. Valid log found at %q", cfg.WALDir()) plog.Warningf("discovery token ignored since a cluster has already been initialized. Valid log found at %q", cfg.WALDir())
} }
snapshot, err = ss.Load() snapshot, err = ss.Load()
if err != nil && err != snap.ErrNoSnapshot { if err != nil && err != raftsnap.ErrNoSnapshot {
return nil, err return nil, err
} }
if snapshot != nil { if snapshot != nil {
@ -1170,6 +1170,8 @@ func (s *EtcdServer) UpdateMember(ctx context.Context, memb membership.Member) (
func (s *EtcdServer) Index() uint64 { return atomic.LoadUint64(&s.r.index) } func (s *EtcdServer) Index() uint64 { return atomic.LoadUint64(&s.r.index) }
func (s *EtcdServer) AppliedIndex() uint64 { return atomic.LoadUint64(&s.r.appliedindex) }
func (s *EtcdServer) Term() uint64 { return atomic.LoadUint64(&s.r.term) } func (s *EtcdServer) Term() uint64 { return atomic.LoadUint64(&s.r.term) }
// Lead is only for testing purposes. // Lead is only for testing purposes.
@ -1264,7 +1266,7 @@ func (s *EtcdServer) publish(timeout time.Duration) {
} }
} }
func (s *EtcdServer) sendMergedSnap(merged snap.Message) { func (s *EtcdServer) sendMergedSnap(merged raftsnap.Message) {
atomic.AddInt64(&s.inflightSnapshots, 1) atomic.AddInt64(&s.inflightSnapshots, 1)
s.r.transport.SendSnapshot(merged) s.r.transport.SendSnapshot(merged)
@ -1667,6 +1669,7 @@ func (s *EtcdServer) getAppliedIndex() uint64 {
func (s *EtcdServer) setAppliedIndex(v uint64) { func (s *EtcdServer) setAppliedIndex(v uint64) {
atomic.StoreUint64(&s.appliedIndex, v) atomic.StoreUint64(&s.appliedIndex, v)
atomic.StoreUint64(&s.r.appliedindex, v)
} }
func (s *EtcdServer) getCommittedIndex() uint64 { func (s *EtcdServer) getCommittedIndex() uint64 {

View File

@ -17,15 +17,15 @@ package etcdserver
import ( import (
"io" "io"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/internal/raftsnap"
"github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/snap"
) )
// createMergedSnapshotMessage creates a snapshot message that contains: raft status (term, conf), // createMergedSnapshotMessage creates a snapshot message that contains: raft status (term, conf),
// a snapshot of v2 store inside raft.Snapshot as []byte, a snapshot of v3 KV in the top level message // a snapshot of v2 store inside raft.Snapshot as []byte, a snapshot of v3 KV in the top level message
// as ReadCloser. // as ReadCloser.
func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapt, snapi uint64, confState raftpb.ConfState) snap.Message { func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapt, snapi uint64, confState raftpb.ConfState) raftsnap.Message {
// get a snapshot of v2 store as []byte // get a snapshot of v2 store as []byte
clone := s.store.Clone() clone := s.store.Clone()
d, err := clone.SaveNoCopy() d, err := clone.SaveNoCopy()
@ -51,7 +51,7 @@ func (s *EtcdServer) createMergedSnapshotMessage(m raftpb.Message, snapt, snapi
} }
m.Snapshot = snapshot m.Snapshot = snapshot
return *snap.NewMessage(m, rc, dbsnap.Size()) return *raftsnap.NewMessage(m, rc, dbsnap.Size())
} }
func newSnapshotReaderCloser(snapshot backend.Snapshot) io.ReadCloser { func newSnapshotReaderCloser(snapshot backend.Snapshot) io.ReadCloser {

View File

@ -18,10 +18,10 @@ import (
"io" "io"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/internal/raftsnap"
"github.com/coreos/etcd/pkg/pbutil" "github.com/coreos/etcd/pkg/pbutil"
"github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/pkg/types"
"github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/snap"
"github.com/coreos/etcd/wal" "github.com/coreos/etcd/wal"
"github.com/coreos/etcd/wal/walpb" "github.com/coreos/etcd/wal/walpb"
) )
@ -38,10 +38,10 @@ type Storage interface {
type storage struct { type storage struct {
*wal.WAL *wal.WAL
*snap.Snapshotter *raftsnap.Snapshotter
} }
func NewStorage(w *wal.WAL, s *snap.Snapshotter) Storage { func NewStorage(w *wal.WAL, s *raftsnap.Snapshotter) Storage {
return &storage{w, s} return &storage{w, s}
} }

View File

@ -19,7 +19,7 @@ import (
"time" "time"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/store" "github.com/coreos/etcd/internal/store"
) )
type RequestV2 pb.Request type RequestV2 pb.Request

View File

@ -20,12 +20,12 @@ import (
"encoding/binary" "encoding/binary"
"time" "time"
"github.com/coreos/etcd/auth"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/etcdserver/membership"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/auth"
"github.com/coreos/etcd/lease/leasehttp" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/mvcc" "github.com/coreos/etcd/internal/lease/leasehttp"
"github.com/coreos/etcd/internal/mvcc"
"github.com/coreos/etcd/raft" "github.com/coreos/etcd/raft"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"

View File

@ -15,8 +15,8 @@
package auth package auth
import ( import (
"github.com/coreos/etcd/auth/authpb" "github.com/coreos/etcd/internal/auth/authpb"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/pkg/adt" "github.com/coreos/etcd/pkg/adt"
) )

View File

@ -24,9 +24,9 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"github.com/coreos/etcd/auth/authpb"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/auth/authpb"
"github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/pkg/capnslog" "github.com/coreos/pkg/capnslog"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"

View File

@ -15,9 +15,9 @@
package mvcc package mvcc
import ( import (
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc/mvccpb"
) )
type RangeOptions struct { type RangeOptions struct {

View File

@ -14,9 +14,7 @@
package mvcc package mvcc
import ( import "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/lease"
)
type readView struct{ kv KV } type readView struct{ kv KV }

View File

@ -24,9 +24,9 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc/mvccpb"
"github.com/coreos/etcd/pkg/schedule" "github.com/coreos/etcd/pkg/schedule"
"github.com/coreos/pkg/capnslog" "github.com/coreos/pkg/capnslog"
) )

View File

@ -15,9 +15,9 @@
package mvcc package mvcc
import ( import (
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc/mvccpb"
) )
type storeTxnRead struct { type storeTxnRead struct {

View File

@ -15,7 +15,7 @@
package mvcc package mvcc
import ( import (
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/lease"
) )
type metricsTxnWrite struct { type metricsTxnWrite struct {

View File

@ -17,8 +17,8 @@ package mvcc
import ( import (
"encoding/binary" "encoding/binary"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc/mvccpb"
) )
func UpdateConsistentIndex(be backend.Backend, index uint64) { func UpdateConsistentIndex(be backend.Backend, index uint64) {

View File

@ -18,9 +18,9 @@ import (
"sync" "sync"
"time" "time"
"github.com/coreos/etcd/lease" "github.com/coreos/etcd/internal/lease"
"github.com/coreos/etcd/mvcc/backend" "github.com/coreos/etcd/internal/mvcc/backend"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc/mvccpb"
) )
// non-const so modifiable by tests // non-const so modifiable by tests

View File

@ -14,9 +14,7 @@
package mvcc package mvcc
import ( import "github.com/coreos/etcd/internal/mvcc/mvccpb"
"github.com/coreos/etcd/mvcc/mvccpb"
)
func (tw *watchableStoreTxnWrite) End() { func (tw *watchableStoreTxnWrite) End() {
changes := tw.Changes() changes := tw.Changes()

View File

@ -19,11 +19,17 @@ import (
"errors" "errors"
"sync" "sync"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc/mvccpb"
) )
// AutoWatchID is the watcher ID passed in WatchStream.Watch when no
// user-provided ID is available. If pass, an ID will automatically be assigned.
const AutoWatchID WatchID = 0
var ( var (
ErrWatcherNotExist = errors.New("mvcc: watcher does not exist") ErrWatcherNotExist = errors.New("mvcc: watcher does not exist")
ErrEmptyWatcherRange = errors.New("mvcc: watcher range is empty")
ErrWatcherDuplicateID = errors.New("mvcc: duplicate watch ID provided on the WatchStream")
) )
type WatchID int64 type WatchID int64
@ -36,12 +42,13 @@ type WatchStream interface {
// happened on the given key or range [key, end) from the given startRev. // happened on the given key or range [key, end) from the given startRev.
// //
// The whole event history can be watched unless compacted. // The whole event history can be watched unless compacted.
// If `startRev` <=0, watch observes events after currentRev. // If "startRev" <=0, watch observes events after currentRev.
// //
// The returned `id` is the ID of this watcher. It appears as WatchID // The returned "id" is the ID of this watcher. It appears as WatchID
// in events that are sent to the created watcher through stream channel. // in events that are sent to the created watcher through stream channel.
// // The watch ID is used when it's not equal to AutoWatchID. Otherwise,
Watch(key, end []byte, startRev int64, fcs ...FilterFunc) WatchID // an auto-generated watch ID is returned.
Watch(id WatchID, key, end []byte, startRev int64, fcs ...FilterFunc) (WatchID, error)
// Chan returns a chan. All watch response will be sent to the returned chan. // Chan returns a chan. All watch response will be sent to the returned chan.
Chan() <-chan WatchResponse Chan() <-chan WatchResponse
@ -98,28 +105,34 @@ type watchStream struct {
} }
// Watch creates a new watcher in the stream and returns its WatchID. // Watch creates a new watcher in the stream and returns its WatchID.
// TODO: return error if ws is closed? func (ws *watchStream) Watch(id WatchID, key, end []byte, startRev int64, fcs ...FilterFunc) (WatchID, error) {
func (ws *watchStream) Watch(key, end []byte, startRev int64, fcs ...FilterFunc) WatchID {
// prevent wrong range where key >= end lexicographically // prevent wrong range where key >= end lexicographically
// watch request with 'WithFromKey' has empty-byte range end // watch request with 'WithFromKey' has empty-byte range end
if len(end) != 0 && bytes.Compare(key, end) != -1 { if len(end) != 0 && bytes.Compare(key, end) != -1 {
return -1 return -1, ErrEmptyWatcherRange
} }
ws.mu.Lock() ws.mu.Lock()
defer ws.mu.Unlock() defer ws.mu.Unlock()
if ws.closed { if ws.closed {
return -1 return -1, ErrEmptyWatcherRange
} }
id := ws.nextID if id == AutoWatchID {
ws.nextID++ for ws.watchers[ws.nextID] != nil {
ws.nextID++
}
id = ws.nextID
ws.nextID++
} else if _, ok := ws.watchers[id]; ok {
return -1, ErrWatcherDuplicateID
}
w, c := ws.watchable.watch(key, end, startRev, id, ws.ch, fcs...) w, c := ws.watchable.watch(key, end, startRev, id, ws.ch, fcs...)
ws.cancels[id] = c ws.cancels[id] = c
ws.watchers[id] = w ws.watchers[id] = w
return id return id, nil
} }
func (ws *watchStream) Chan() <-chan WatchResponse { func (ws *watchStream) Chan() <-chan WatchResponse {

View File

@ -17,7 +17,7 @@ package mvcc
import ( import (
"math" "math"
"github.com/coreos/etcd/mvcc/mvccpb" "github.com/coreos/etcd/internal/mvcc/mvccpb"
"github.com/coreos/etcd/pkg/adt" "github.com/coreos/etcd/pkg/adt"
) )

View File

@ -17,6 +17,7 @@ package netutil
import ( import (
"context" "context"
"fmt"
"net" "net"
"net/url" "net/url"
"reflect" "reflect"
@ -73,14 +74,14 @@ func resolveTCPAddrs(ctx context.Context, urls [][]url.URL) ([][]url.URL, error)
for i, u := range us { for i, u := range us {
nu, err := url.Parse(u.String()) nu, err := url.Parse(u.String())
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("failed to parse %q (%v)", u.String(), err)
} }
nus[i] = *nu nus[i] = *nu
} }
for i, u := range nus { for i, u := range nus {
h, err := resolveURL(ctx, u) h, err := resolveURL(ctx, u)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("failed to resolve %q (%v)", u.String(), err)
} }
if h != "" { if h != "" {
nus[i].Host = h nus[i].Host = h
@ -123,35 +124,41 @@ func resolveURL(ctx context.Context, u url.URL) (string, error) {
// urlsEqual checks equality of url.URLS between two arrays. // urlsEqual checks equality of url.URLS between two arrays.
// This check pass even if an URL is in hostname and opposite is in IP address. // This check pass even if an URL is in hostname and opposite is in IP address.
func urlsEqual(ctx context.Context, a []url.URL, b []url.URL) bool { func urlsEqual(ctx context.Context, a []url.URL, b []url.URL) (bool, error) {
if len(a) != len(b) { if len(a) != len(b) {
return false return false, fmt.Errorf("len(%q) != len(%q)", urlsToStrings(a), urlsToStrings(b))
} }
urls, err := resolveTCPAddrs(ctx, [][]url.URL{a, b}) urls, err := resolveTCPAddrs(ctx, [][]url.URL{a, b})
if err != nil { if err != nil {
return false return false, err
} }
preva, prevb := a, b
a, b = urls[0], urls[1] a, b = urls[0], urls[1]
sort.Sort(types.URLs(a)) sort.Sort(types.URLs(a))
sort.Sort(types.URLs(b)) sort.Sort(types.URLs(b))
for i := range a { for i := range a {
if !reflect.DeepEqual(a[i], b[i]) { if !reflect.DeepEqual(a[i], b[i]) {
return false return false, fmt.Errorf("%q(resolved from %q) != %q(resolved from %q)",
a[i].String(), preva[i].String(),
b[i].String(), prevb[i].String(),
)
} }
} }
return true, nil
return true
} }
func URLStringsEqual(ctx context.Context, a []string, b []string) bool { // URLStringsEqual returns "true" if given URLs are valid
// and resolved to same IP addresses. Otherwise, return "false"
// and error, if any.
func URLStringsEqual(ctx context.Context, a []string, b []string) (bool, error) {
if len(a) != len(b) { if len(a) != len(b) {
return false return false, fmt.Errorf("len(%q) != len(%q)", a, b)
} }
urlsA := make([]url.URL, 0) urlsA := make([]url.URL, 0)
for _, str := range a { for _, str := range a {
u, err := url.Parse(str) u, err := url.Parse(str)
if err != nil { if err != nil {
return false return false, fmt.Errorf("failed to parse %q", str)
} }
urlsA = append(urlsA, *u) urlsA = append(urlsA, *u)
} }
@ -159,14 +166,21 @@ func URLStringsEqual(ctx context.Context, a []string, b []string) bool {
for _, str := range b { for _, str := range b {
u, err := url.Parse(str) u, err := url.Parse(str)
if err != nil { if err != nil {
return false return false, fmt.Errorf("failed to parse %q", str)
} }
urlsB = append(urlsB, *u) urlsB = append(urlsB, *u)
} }
return urlsEqual(ctx, urlsA, urlsB) return urlsEqual(ctx, urlsA, urlsB)
} }
func urlsToStrings(us []url.URL) []string {
rs := make([]string, len(us))
for i := range us {
rs[i] = us[i].String()
}
return rs
}
func IsNetworkTimeoutError(err error) bool { func IsNetworkTimeoutError(err error) bool {
nerr, ok := err.(net.Error) nerr, ok := err.(net.Error)
return ok && nerr.Timeout() return ok && nerr.Timeout()