Vendor in new containerd

This version introduces the following:
 - uses nanosecond timestamps for event
 - ensure events are sent once their effect is "live"

Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
Kenfe-Mickael Laventure 2016-07-10 11:11:27 -07:00
parent ba6adc5f46
commit 29b2714580
20 changed files with 1013 additions and 214 deletions

View File

@ -244,7 +244,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install containerd
ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
ENV CONTAINERD_COMMIT 0ac3cd1be170d180b2baed755e8f0da547ceb267
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \

View File

@ -195,7 +195,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install containerd
ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \

View File

@ -200,7 +200,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install containerd
ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \

View File

@ -85,7 +85,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install containerd
ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \

View File

@ -213,7 +213,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install containerd
ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \

View File

@ -208,7 +208,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install containerd
ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \

View File

@ -68,7 +68,7 @@ RUN set -x \
&& rm -rf "$GOPATH"
# Install containerd
ENV CONTAINERD_COMMIT 1b3a81545ca79456086dc2aa424357be98b962ee
ENV CONTAINERD_COMMIT 90f827ca1066b3b6584ce7450989b96b576b1baf
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/containerd.git "$GOPATH/src/github.com/docker/containerd" \

View File

@ -14,7 +14,6 @@ import (
"strconv"
"strings"
"syscall"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/container"
@ -36,6 +35,7 @@ import (
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/options"
lntypes "github.com/docker/libnetwork/types"
"github.com/golang/protobuf/ptypes"
"github.com/opencontainers/runc/libcontainer/label"
"github.com/opencontainers/runc/libcontainer/user"
"github.com/opencontainers/specs/specs-go"
@ -1119,7 +1119,10 @@ func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
}
}
}
s.Read = time.Unix(int64(stats.Timestamp), 0)
s.Read, err = ptypes.Timestamp(stats.Timestamp)
if err != nil {
return nil, err
}
return s, nil
}

View File

@ -136,7 +136,7 @@ clone git google.golang.org/cloud dae7e3d993bc3812a2185af60552bb6b847e52a0 https
clone git github.com/docker/docker-credential-helpers v0.3.0
# containerd
clone git github.com/docker/containerd 1b3a81545ca79456086dc2aa424357be98b962ee
clone git github.com/docker/containerd 0ac3cd1be170d180b2baed755e8f0da547ceb267
# cluster
clone git github.com/docker/swarmkit 6478bc19cf4bc1d7ba2d6f04ccaacf099508f4a0

View File

@ -20,6 +20,7 @@ import (
"github.com/docker/docker/pkg/locker"
sysinfo "github.com/docker/docker/pkg/system"
"github.com/docker/docker/utils"
"github.com/golang/protobuf/ptypes"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
@ -225,40 +226,43 @@ func (r *remote) updateEventTimestamp(t time.Time) {
f.Truncate(0)
return
}
}
func (r *remote) getLastEventTimestamp() int64 {
func (r *remote) getLastEventTimestamp() time.Time {
t := time.Now()
fi, err := os.Stat(r.eventTsPath)
if os.IsNotExist(err) || fi.Size() == 0 {
return t.Unix()
return t
}
f, err := os.Open(r.eventTsPath)
defer f.Close()
if err != nil {
logrus.Warnf("libcontainerd: Unable to access last event ts: %v", err)
return t.Unix()
return t
}
b := make([]byte, fi.Size())
n, err := f.Read(b)
if err != nil || n != len(b) {
logrus.Warnf("libcontainerd: Unable to read last event ts: %v", err)
return t.Unix()
return t
}
t.UnmarshalText(b)
return t.Unix()
return t
}
func (r *remote) startEventsMonitor() error {
// First, get past events
tsp, err := ptypes.TimestampProto(r.getLastEventTimestamp())
if err != nil {
logrus.Errorf("libcontainerd: failed to convert timestamp: %q", err)
}
er := &containerd.EventsRequest{
Timestamp: uint64(r.getLastEventTimestamp()),
Timestamp: tsp,
}
events, err := r.apiClient.Events(context.Background(), er)
if err != nil {
@ -269,7 +273,6 @@ func (r *remote) startEventsMonitor() error {
}
func (r *remote) handleEventStream(events containerd.API_EventsClient) {
live := false
for {
e, err := events.Recv()
if err != nil {
@ -283,45 +286,34 @@ func (r *remote) handleEventStream(events containerd.API_EventsClient) {
return
}
if live == false {
logrus.Debugf("received past containerd event: %#v", e)
logrus.Debugf("received containerd event: %#v", e)
// Pause/Resume events should never happens after exit one
switch e.Type {
case StateExit:
r.pastEvents[e.Id] = e
case StatePause:
r.pastEvents[e.Id] = e
case StateResume:
r.pastEvents[e.Id] = e
case stateLive:
live = true
r.updateEventTimestamp(time.Unix(int64(e.Timestamp), 0))
var container *container
var c *client
r.RLock()
for _, c = range r.clients {
container, err = c.getContainer(e.Id)
if err == nil {
break
}
} else {
logrus.Debugf("received containerd event: %#v", e)
var container *container
var c *client
r.RLock()
for _, c = range r.clients {
container, err = c.getContainer(e.Id)
if err == nil {
break
}
}
r.RUnlock()
if container == nil {
logrus.Errorf("no state for container: %q", err)
continue
}
if err := container.handleEvent(e); err != nil {
logrus.Errorf("error processing state change for %s: %v", e.Id, err)
}
r.updateEventTimestamp(time.Unix(int64(e.Timestamp), 0))
}
r.RUnlock()
if container == nil {
logrus.Errorf("libcontainerd: %q", err)
continue
}
if err := container.handleEvent(e); err != nil {
logrus.Errorf("libcontainerd: error processing state change for %s: %v", e.Id, err)
}
tsp, err := ptypes.Timestamp(e.Timestamp)
if err != nil {
logrus.Errorf("libcontainerd: failed to convert event timestamp: %q", err)
continue
}
r.updateEventTimestamp(tsp)
}
}

View File

@ -58,6 +58,7 @@ package types
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
import (
context "golang.org/x/net/context"
@ -480,7 +481,10 @@ func (*UpdateContainerResponse) ProtoMessage() {}
func (*UpdateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} }
type EventsRequest struct {
Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"`
// Tag 1 is deprecated (old uint64 timestamp)
Timestamp *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=timestamp" json:"timestamp,omitempty"`
StoredOnly bool `protobuf:"varint,3,opt,name=storedOnly" json:"storedOnly,omitempty"`
Id string `protobuf:"bytes,4,opt,name=id" json:"id,omitempty"`
}
func (m *EventsRequest) Reset() { *m = EventsRequest{} }
@ -488,12 +492,20 @@ func (m *EventsRequest) String() string { return proto.CompactTextStr
func (*EventsRequest) ProtoMessage() {}
func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} }
func (m *EventsRequest) GetTimestamp() *google_protobuf.Timestamp {
if m != nil {
return m.Timestamp
}
return nil
}
type Event struct {
Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
Status uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"`
Pid string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"`
Timestamp uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"`
Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
Status uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"`
Pid string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"`
// Tag 5 is deprecated (old uint64 timestamp)
Timestamp *google_protobuf.Timestamp `protobuf:"bytes,6,opt,name=timestamp" json:"timestamp,omitempty"`
}
func (m *Event) Reset() { *m = Event{} }
@ -501,6 +513,13 @@ func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} }
func (m *Event) GetTimestamp() *google_protobuf.Timestamp {
if m != nil {
return m.Timestamp
}
return nil
}
type NetworkStats struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
RxBytes uint64 `protobuf:"varint,2,opt,name=rx_bytes,json=rxBytes" json:"rx_bytes,omitempty"`
@ -776,7 +795,8 @@ func (m *CgroupStats) GetPidsStats() *PidsStats {
type StatsResponse struct {
NetworkStats []*NetworkStats `protobuf:"bytes,1,rep,name=network_stats,json=networkStats" json:"network_stats,omitempty"`
CgroupStats *CgroupStats `protobuf:"bytes,2,opt,name=cgroup_stats,json=cgroupStats" json:"cgroup_stats,omitempty"`
Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp" json:"timestamp,omitempty"`
// Tag 3 is deprecated (old uint64 timestamp)
Timestamp *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=timestamp" json:"timestamp,omitempty"`
}
func (m *StatsResponse) Reset() { *m = StatsResponse{} }
@ -798,6 +818,13 @@ func (m *StatsResponse) GetCgroupStats() *CgroupStats {
return nil
}
func (m *StatsResponse) GetTimestamp() *google_protobuf.Timestamp {
if m != nil {
return m.Timestamp
}
return nil
}
type StatsRequest struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
}
@ -1316,153 +1343,156 @@ var _API_serviceDesc = grpc.ServiceDesc{
}
var fileDescriptor0 = []byte{
// 2361 bytes of a gzipped FileDescriptorProto
// 2414 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x59, 0xcd, 0x73, 0x1b, 0x4b,
0x11, 0x8f, 0xbe, 0xad, 0xd6, 0x87, 0xed, 0x8d, 0x3f, 0x14, 0xbd, 0x97, 0xbc, 0xb0, 0xf5, 0x80,
0x00, 0x0f, 0x13, 0x94, 0xf7, 0x8a, 0x14, 0x54, 0x51, 0x95, 0xd8, 0xe1, 0x11, 0x5e, 0x1c, 0x94,
0xb5, 0xcd, 0x3b, 0xaa, 0xd6, 0xab, 0x89, 0xb4, 0x58, 0xda, 0xdd, 0xec, 0x8e, 0x6c, 0xf9, 0xc2,
0x81, 0x03, 0xdc, 0x38, 0x53, 0x05, 0xc5, 0x85, 0x1b, 0x77, 0x0e, 0xfc, 0x05, 0x54, 0xf1, 0x87,
0x70, 0xe3, 0xce, 0x91, 0x9e, 0x9e, 0xd9, 0xd9, 0x59, 0x7d, 0xd8, 0xe1, 0x40, 0x71, 0x79, 0x17,
0xd5, 0xf4, 0x6f, 0x7a, 0xba, 0x7b, 0xba, 0x7b, 0x7a, 0x7a, 0x47, 0x50, 0x77, 0x23, 0xff, 0x20,
0x8a, 0x43, 0x1e, 0x5a, 0x15, 0x7e, 0x1d, 0xb1, 0xc4, 0xbe, 0x07, 0xfb, 0x9f, 0x33, 0x7e, 0xc2,
0xe2, 0x4b, 0x16, 0xff, 0x82, 0xc5, 0x89, 0x1f, 0x06, 0x0e, 0x7b, 0x37, 0x63, 0x09, 0xb7, 0xe7,
0xd0, 0x59, 0x9e, 0x4a, 0xa2, 0x30, 0x48, 0x98, 0xb5, 0x03, 0x95, 0xa9, 0xfb, 0xcb, 0x30, 0xee,
0x14, 0x1e, 0x16, 0x1e, 0xb5, 0x1c, 0x49, 0x10, 0xea, 0x07, 0x88, 0x16, 0x15, 0x2a, 0x08, 0x81,
0x46, 0x2e, 0xf7, 0xc6, 0x9d, 0x92, 0x44, 0x89, 0xb0, 0xba, 0xb0, 0x11, 0xb3, 0x4b, 0x5f, 0x48,
0xed, 0x94, 0x71, 0xa2, 0xee, 0x68, 0xda, 0xfe, 0x4d, 0x01, 0x76, 0xce, 0xa2, 0xa1, 0xcb, 0x59,
0x3f, 0x0e, 0x3d, 0x96, 0x24, 0xca, 0x24, 0xab, 0x0d, 0x45, 0x7f, 0x48, 0x3a, 0xeb, 0x0e, 0x8e,
0xac, 0x2d, 0x28, 0x45, 0x08, 0x14, 0x09, 0x10, 0x43, 0xeb, 0x01, 0x80, 0x37, 0x09, 0x13, 0x76,
0xc2, 0x87, 0x7e, 0x40, 0x1a, 0x37, 0x1c, 0x03, 0x11, 0xc6, 0x5c, 0xf9, 0x43, 0x3e, 0x26, 0x9d,
0x68, 0x0c, 0x11, 0xd6, 0x1e, 0x54, 0xc7, 0xcc, 0x1f, 0x8d, 0x79, 0xa7, 0x42, 0xb0, 0xa2, 0xec,
0x7d, 0xd8, 0x5d, 0xb0, 0x43, 0xee, 0xdf, 0xfe, 0x47, 0x11, 0xf6, 0x0e, 0x63, 0x86, 0x33, 0x87,
0x61, 0xc0, 0x5d, 0x3f, 0x60, 0xf1, 0x3a, 0x1b, 0xd1, 0xa2, 0xf3, 0x59, 0x30, 0x9c, 0xb0, 0xbe,
0x8b, 0x6a, 0xa5, 0xa9, 0x06, 0x42, 0x16, 0x8f, 0x99, 0x77, 0x11, 0x85, 0x7e, 0xc0, 0xc9, 0x62,
0x9c, 0xcf, 0x10, 0x61, 0x71, 0x42, 0x9b, 0x91, 0x5e, 0x92, 0x84, 0xb0, 0x18, 0x07, 0xe1, 0x4c,
0x5a, 0x5c, 0x77, 0x14, 0xa5, 0x70, 0x16, 0xc7, 0x9d, 0xaa, 0xc6, 0x91, 0x12, 0xf8, 0xc4, 0x3d,
0x67, 0x93, 0xa4, 0x53, 0x7b, 0x58, 0x12, 0xb8, 0xa4, 0xac, 0x87, 0xd0, 0x08, 0xc2, 0xbe, 0x7f,
0x19, 0x72, 0x27, 0x0c, 0x79, 0x67, 0x83, 0x1c, 0x66, 0x42, 0x56, 0x07, 0x6a, 0xf1, 0x2c, 0xe0,
0xfe, 0x94, 0x75, 0xea, 0x24, 0x32, 0x25, 0xc5, 0x5a, 0x35, 0x7c, 0x16, 0x8f, 0x92, 0x0e, 0x90,
0x60, 0x13, 0xb2, 0x3e, 0x86, 0x56, 0xb6, 0x93, 0x23, 0x3f, 0xee, 0x34, 0x48, 0x42, 0x1e, 0xb4,
0x5f, 0xc2, 0xfe, 0x92, 0x2f, 0x55, 0x9e, 0x1d, 0x40, 0xdd, 0x4b, 0x41, 0xf2, 0x69, 0xa3, 0xb7,
0x75, 0x40, 0x99, 0x7b, 0x90, 0x31, 0x67, 0x2c, 0x28, 0xaa, 0x75, 0xe2, 0x8f, 0x02, 0x77, 0xf2,
0xfe, 0x19, 0x23, 0x3c, 0x46, 0x4b, 0x54, 0x7e, 0x2a, 0xca, 0xde, 0x82, 0x76, 0x2a, 0x4a, 0x05,
0xfd, 0xaf, 0x25, 0xd8, 0x7e, 0x36, 0x1c, 0xde, 0x92, 0x93, 0x98, 0xd8, 0x9c, 0xc5, 0x98, 0xfa,
0x28, 0xb1, 0x48, 0xee, 0xd4, 0xb4, 0xf5, 0x11, 0x94, 0x67, 0x09, 0xee, 0xa4, 0x44, 0x3b, 0x69,
0xa8, 0x9d, 0x9c, 0x21, 0xe4, 0xd0, 0x84, 0x65, 0x41, 0xd9, 0x15, 0xbe, 0x2c, 0x93, 0x2f, 0x69,
0x2c, 0x4c, 0x66, 0xc1, 0x25, 0xc6, 0x59, 0x40, 0x62, 0x28, 0x10, 0xef, 0x6a, 0xa8, 0x22, 0x2c,
0x86, 0xe9, 0xb6, 0x6a, 0xd9, 0xb6, 0x74, 0xda, 0x6c, 0xac, 0x4e, 0x9b, 0xfa, 0x9a, 0xb4, 0x81,
0x5c, 0xda, 0xd8, 0xd0, 0xf4, 0xdc, 0xc8, 0x3d, 0xf7, 0x27, 0x3e, 0xf7, 0x59, 0x82, 0xf1, 0x13,
0x46, 0xe4, 0x30, 0xeb, 0x11, 0x6c, 0xba, 0x51, 0xe4, 0xc6, 0xd3, 0x30, 0x46, 0xd7, 0xbc, 0xf5,
0x27, 0xac, 0xd3, 0x24, 0x21, 0x8b, 0xb0, 0x90, 0x96, 0xb0, 0x89, 0x1f, 0xcc, 0xe6, 0xaf, 0x44,
0xf6, 0x75, 0x5a, 0xc4, 0x96, 0xc3, 0x84, 0xb4, 0x20, 0x7c, 0xcd, 0xae, 0xfa, 0xb1, 0x7f, 0x89,
0x6b, 0x46, 0xa8, 0xb4, 0x4d, 0x5e, 0x5c, 0x84, 0xad, 0x6f, 0x62, 0x62, 0x4e, 0xfc, 0xa9, 0xcf,
0x93, 0xce, 0x26, 0x9a, 0xd5, 0xe8, 0xb5, 0x94, 0x3f, 0x1d, 0x42, 0x9d, 0x74, 0xd6, 0x3e, 0x82,
0xaa, 0x84, 0x84, 0x7b, 0x05, 0x8b, 0x8a, 0x16, 0x8d, 0x05, 0x96, 0x84, 0x6f, 0x39, 0xc5, 0xaa,
0xec, 0xd0, 0x58, 0x60, 0x63, 0x37, 0x1e, 0x52, 0x9c, 0x10, 0x13, 0x63, 0xdb, 0x81, 0xb2, 0x08,
0x94, 0x70, 0xf5, 0x4c, 0x05, 0xbc, 0xe5, 0x88, 0xa1, 0x40, 0x46, 0x2a, 0xa7, 0x10, 0xc1, 0xa1,
0xf5, 0x0d, 0x68, 0xbb, 0xc3, 0x21, 0xba, 0x27, 0xc4, 0xa8, 0x7f, 0xee, 0x0f, 0x13, 0x94, 0x54,
0xc2, 0xc9, 0x05, 0xd4, 0xde, 0x01, 0xcb, 0x4c, 0x28, 0x95, 0x67, 0xbf, 0x2e, 0xe8, 0x03, 0xa1,
0xcf, 0xc9, 0xba, 0x6c, 0xfb, 0x7e, 0xae, 0x7a, 0x14, 0x29, 0xaf, 0xb6, 0xd3, 0x13, 0x92, 0xad,
0x36, 0x0b, 0xca, 0xd2, 0xa1, 0x2c, 0xad, 0x3a, 0x94, 0x5d, 0xe8, 0x2c, 0xdb, 0xa0, 0x0c, 0xf4,
0x60, 0xff, 0x88, 0x4d, 0xd8, 0xfb, 0xd8, 0x87, 0x9e, 0x0c, 0x5c, 0x2c, 0x1d, 0xf2, 0xc0, 0xd1,
0xf8, 0xfd, 0x0d, 0x58, 0x56, 0xa2, 0x0c, 0x38, 0x86, 0xdd, 0x57, 0x7e, 0xc2, 0x6f, 0x57, 0xbf,
0xa4, 0xaa, 0xb8, 0x4a, 0xd5, 0xef, 0x0b, 0x00, 0x99, 0x2c, 0x6d, 0x73, 0xc1, 0xb0, 0x19, 0x31,
0x36, 0xf7, 0xb9, 0x3a, 0xd1, 0x34, 0x16, 0x71, 0xe7, 0x5e, 0xa4, 0x2e, 0x19, 0x31, 0x14, 0x15,
0x71, 0x16, 0xf8, 0xf3, 0x93, 0xd0, 0xbb, 0x60, 0x3c, 0xa1, 0x8a, 0x8d, 0xd5, 0xd4, 0x80, 0xe8,
0x58, 0x8e, 0xd9, 0x64, 0x42, 0x65, 0x7b, 0xc3, 0x91, 0x84, 0xa8, 0xb1, 0x6c, 0x1a, 0xf1, 0xeb,
0xd7, 0x27, 0x78, 0xa8, 0xc5, 0x09, 0x4b, 0x49, 0xdc, 0xe9, 0xde, 0xe2, 0x4e, 0x55, 0x69, 0x7c,
0x02, 0x8d, 0x6c, 0x17, 0x09, 0x1a, 0x5b, 0x5a, 0x1d, 0x7a, 0x93, 0xcb, 0x7e, 0x00, 0xcd, 0x13,
0x8e, 0x41, 0x5d, 0xe3, 0x2f, 0xfb, 0x11, 0xb4, 0x75, 0x5d, 0x25, 0x46, 0x59, 0x19, 0x5c, 0x3e,
0x4b, 0x14, 0x97, 0xa2, 0xec, 0xbf, 0x95, 0xa0, 0xa6, 0x12, 0x37, 0xad, 0x3e, 0x85, 0xac, 0xfa,
0xfc, 0x5f, 0x8a, 0xe0, 0x87, 0x50, 0x4f, 0xae, 0x13, 0xce, 0xa6, 0x7d, 0x55, 0x0a, 0x5b, 0x4e,
0x06, 0x7c, 0x55, 0x10, 0xb3, 0x82, 0xf8, 0xf7, 0x02, 0xd4, 0x75, 0x98, 0xff, 0xeb, 0x86, 0xe5,
0x13, 0xa8, 0x47, 0x32, 0xf0, 0x4c, 0xd6, 0xb5, 0x46, 0xaf, 0xad, 0x14, 0xa5, 0x95, 0x2c, 0x63,
0x30, 0xf2, 0xa7, 0x6c, 0xe6, 0x8f, 0xd1, 0x90, 0x54, 0x72, 0x0d, 0x09, 0x06, 0x3f, 0x12, 0x05,
0xb3, 0x4a, 0x05, 0x93, 0xc6, 0x66, 0x0b, 0x52, 0xcb, 0xb5, 0x20, 0xf6, 0x67, 0x50, 0x3b, 0x76,
0xbd, 0x31, 0xee, 0x43, 0x2c, 0xf4, 0x22, 0x95, 0xa6, 0xb8, 0x50, 0x8c, 0x85, 0x92, 0x29, 0x43,
0x7f, 0x5f, 0xab, 0xea, 0xae, 0x28, 0xfb, 0x02, 0xdb, 0x04, 0x79, 0x0c, 0xd4, 0x61, 0x7a, 0x8c,
0x65, 0x34, 0x75, 0x48, 0x7a, 0x96, 0x96, 0x1b, 0x0d, 0x83, 0x07, 0xc3, 0x52, 0x9b, 0x4a, 0xcd,
0xaa, 0xea, 0xa6, 0x3e, 0x50, 0xf6, 0x38, 0xe9, 0xb4, 0xfd, 0xdb, 0x02, 0xec, 0xc9, 0x2e, 0xf2,
0xd6, 0x5e, 0x71, 0x75, 0x77, 0x22, 0xdd, 0x57, 0xca, 0xb9, 0xef, 0x09, 0xd4, 0x63, 0x96, 0x84,
0xb3, 0x18, 0xdd, 0x4c, 0x9e, 0x6d, 0xf4, 0x76, 0xd3, 0x93, 0x44, 0xba, 0x1c, 0x35, 0xeb, 0x64,
0x7c, 0xf6, 0x1f, 0x4b, 0xd0, 0xce, 0xcf, 0x8a, 0x8a, 0x75, 0x3e, 0xb9, 0xf0, 0xc3, 0x2f, 0x65,
0xfb, 0x5b, 0x20, 0x37, 0x99, 0x90, 0x38, 0x55, 0xe8, 0xcb, 0x13, 0xbc, 0x03, 0x51, 0x93, 0x74,
0x63, 0x06, 0xa8, 0xd9, 0x3e, 0x8b, 0xfd, 0x30, 0xbd, 0x2e, 0x33, 0x40, 0x94, 0x01, 0x24, 0xde,
0xcc, 0x42, 0xee, 0x92, 0x91, 0x65, 0x47, 0xd3, 0xd4, 0xf7, 0x62, 0x8c, 0x18, 0x3f, 0x14, 0x51,
0xab, 0xa8, 0xbe, 0x57, 0x23, 0xd9, 0xfc, 0x31, 0x9b, 0x26, 0xea, 0x98, 0x1b, 0x88, 0xb0, 0x5c,
0x46, 0xf3, 0x95, 0x48, 0x6a, 0x4a, 0x0c, 0xb4, 0xdc, 0x80, 0x84, 0x04, 0x49, 0x9e, 0x5c, 0xb9,
0x11, 0x1d, 0xfb, 0xb2, 0x63, 0x20, 0x98, 0xc8, 0xdb, 0x92, 0x42, 0x6f, 0xe0, 0x57, 0x8e, 0x2b,
0x2e, 0x66, 0x2a, 0x03, 0x65, 0x67, 0x79, 0x42, 0x70, 0x5f, 0xb0, 0x38, 0x60, 0x93, 0x63, 0x43,
0x2b, 0x48, 0xee, 0xa5, 0x09, 0xab, 0x07, 0x3b, 0x12, 0x3c, 0x3d, 0xec, 0x9b, 0x0b, 0x1a, 0xb4,
0x60, 0xe5, 0x9c, 0xf8, 0x16, 0x5b, 0xca, 0x13, 0x75, 0xe1, 0x7d, 0x17, 0x5a, 0x2f, 0x2e, 0x19,
0x56, 0xf0, 0x34, 0x73, 0xd0, 0xef, 0xe2, 0x00, 0x60, 0x36, 0x4c, 0x23, 0x15, 0xb5, 0x0c, 0xb0,
0x13, 0xa8, 0x10, 0xfb, 0xca, 0x86, 0x47, 0x26, 0x5d, 0x51, 0x27, 0x5d, 0x3e, 0xc5, 0x5a, 0x3a,
0xc5, 0x54, 0x32, 0x96, 0xb3, 0x64, 0xcc, 0x29, 0xad, 0x2c, 0x2a, 0xfd, 0x5d, 0x11, 0x9a, 0xaf,
0x19, 0xbf, 0x0a, 0xe3, 0x0b, 0x71, 0xb8, 0x92, 0x95, 0xf7, 0xe8, 0x3d, 0xfc, 0xec, 0x9b, 0x0f,
0xce, 0xaf, 0xb9, 0x4e, 0xa6, 0x5a, 0x3c, 0x7f, 0x2e, 0x48, 0xeb, 0x3e, 0x00, 0x4e, 0xf5, 0x5d,
0x79, 0x77, 0xaa, 0x5c, 0x8a, 0xe7, 0x0a, 0xb0, 0x3e, 0x80, 0xba, 0x33, 0x1f, 0x60, 0x0d, 0x0e,
0xe3, 0x24, 0x4d, 0xa6, 0x78, 0xfe, 0x82, 0x68, 0xb1, 0x16, 0x27, 0x87, 0x71, 0x18, 0x45, 0x6c,
0x98, 0x9a, 0x16, 0xcf, 0x8f, 0x24, 0x20, 0xb4, 0x9e, 0xa6, 0x5a, 0xab, 0x52, 0x2b, 0xcf, 0xb4,
0xe2, 0x54, 0xa4, 0xb4, 0xd6, 0xd4, 0xa6, 0x4c, 0xad, 0xa7, 0x5a, 0xab, 0x4c, 0xa1, 0x0d, 0x6e,
0x68, 0x3d, 0xcd, 0xb4, 0xd6, 0xd3, 0xb5, 0x4a, 0xab, 0xfd, 0x97, 0x02, 0x6c, 0x60, 0x2a, 0x9f,
0x25, 0xee, 0x88, 0xe1, 0xad, 0xd7, 0xe0, 0x98, 0xf6, 0x93, 0xc1, 0x4c, 0x90, 0x2a, 0x64, 0x40,
0x90, 0x64, 0xf8, 0x1a, 0x34, 0x23, 0x16, 0x63, 0x82, 0x2b, 0x8e, 0x22, 0x16, 0x21, 0x4c, 0x68,
0x89, 0x49, 0x96, 0x03, 0xb8, 0x4b, 0x73, 0x03, 0x3f, 0x18, 0xc8, 0x0c, 0x9a, 0x86, 0x43, 0xa6,
0x5c, 0xb5, 0x4d, 0x53, 0x2f, 0x83, 0x2f, 0xf4, 0x84, 0xf5, 0x6d, 0xd8, 0xd6, 0xfc, 0xe2, 0x66,
0x25, 0x6e, 0xe9, 0xba, 0x4d, 0xc5, 0x7d, 0xa6, 0x60, 0xfb, 0x57, 0xd0, 0x3e, 0x1d, 0xc7, 0x21,
0xe7, 0x78, 0xf5, 0x8c, 0x8e, 0x5c, 0x3c, 0xa0, 0x58, 0x75, 0x23, 0x3a, 0xc6, 0x89, 0xb2, 0x36,
0x25, 0xad, 0xef, 0xc0, 0x36, 0x97, 0xbc, 0x6c, 0x38, 0x48, 0x79, 0x64, 0x34, 0xb7, 0xf4, 0x44,
0x5f, 0x31, 0x7f, 0x1d, 0xda, 0x19, 0x33, 0xd5, 0x70, 0x69, 0x6f, 0x4b, 0xa3, 0xa7, 0xa2, 0x92,
0xff, 0x41, 0x3a, 0x4b, 0x66, 0xce, 0x27, 0x54, 0x55, 0x0c, 0x57, 0x35, 0x7a, 0x9b, 0x69, 0x35,
0x56, 0xce, 0xa0, 0x4a, 0x22, 0xdd, 0xf2, 0x63, 0xd8, 0xe4, 0xda, 0xf4, 0x01, 0x1e, 0x20, 0x57,
0x95, 0xe4, 0xb4, 0x22, 0xe6, 0x37, 0xe6, 0xb4, 0x79, 0x7e, 0xa3, 0xe8, 0x79, 0xd9, 0x26, 0x28,
0x85, 0xd2, 0xbe, 0x86, 0xc4, 0x48, 0x85, 0xfd, 0x23, 0xa8, 0x63, 0x0f, 0x91, 0x48, 0xeb, 0xd0,
0x31, 0xde, 0x2c, 0x8e, 0xf1, 0x7c, 0xa5, 0x8e, 0x51, 0xa4, 0xe8, 0x31, 0xe8, 0x8a, 0x55, 0xce,
0x90, 0x84, 0x1d, 0x02, 0xc8, 0x63, 0x4e, 0xda, 0x90, 0xc7, 0x4c, 0x01, 0x49, 0x88, 0x3c, 0x9b,
0xba, 0x73, 0x1d, 0x7a, 0xca, 0x33, 0x04, 0xe4, 0x06, 0x51, 0xe1, 0x5b, 0xd7, 0x9f, 0x78, 0xea,
0x7d, 0x00, 0x15, 0x2a, 0x32, 0x53, 0x58, 0x36, 0x15, 0xfe, 0xb9, 0x08, 0x0d, 0xa9, 0x51, 0x1a,
0x8c, 0x5c, 0x1e, 0x5e, 0x46, 0x5a, 0x25, 0x11, 0xd8, 0x2e, 0x54, 0x32, 0x75, 0x59, 0xeb, 0x98,
0x99, 0x9a, 0xda, 0x86, 0x97, 0x63, 0x82, 0xf5, 0xd2, 0xf0, 0xce, 0x4a, 0xee, 0xba, 0x60, 0x92,
0x06, 0x7f, 0x0a, 0x4d, 0x99, 0x9f, 0x6a, 0x4d, 0x79, 0xdd, 0x9a, 0x86, 0x64, 0x93, 0xab, 0x9e,
0x88, 0x0e, 0x0d, 0xed, 0xa5, 0x8e, 0xa0, 0xd1, 0xbb, 0x9f, 0x63, 0xa7, 0x9d, 0x1c, 0xd0, 0xef,
0x8b, 0x80, 0x63, 0x69, 0x96, 0xbc, 0xdd, 0xa7, 0x00, 0x19, 0x28, 0x6a, 0xd6, 0x05, 0xbb, 0x4e,
0x3b, 0x51, 0x1c, 0x8a, 0xbd, 0x5f, 0xba, 0x93, 0x59, 0xea, 0x54, 0x49, 0xfc, 0xb0, 0xf8, 0xb4,
0x80, 0x5f, 0x31, 0x9b, 0xcf, 0xc5, 0x3d, 0x67, 0x2c, 0xcf, 0x3d, 0x6b, 0x95, 0x57, 0x3e, 0x6b,
0x95, 0xd3, 0x67, 0x2d, 0x2c, 0xa3, 0x61, 0xa4, 0x6e, 0x65, 0x1c, 0x65, 0x8a, 0xca, 0x86, 0x22,
0xfb, 0x9f, 0x65, 0x80, 0x4c, 0x8b, 0x75, 0x02, 0x5d, 0x3f, 0x1c, 0x88, 0x4b, 0xc5, 0xf7, 0x98,
0x2c, 0x48, 0x83, 0x98, 0x61, 0xfa, 0x24, 0xfe, 0x25, 0x53, 0x7d, 0xc7, 0x9e, 0xda, 0xf7, 0x82,
0x71, 0xce, 0x3e, 0x52, 0x72, 0x21, 0x55, 0x2e, 0x27, 0x5d, 0x66, 0xfd, 0x0c, 0x76, 0x33, 0xa1,
0x43, 0x43, 0x5e, 0xf1, 0x46, 0x79, 0x77, 0xb5, 0xbc, 0x61, 0x26, 0xeb, 0x27, 0x80, 0xf0, 0x00,
0xef, 0x98, 0x59, 0x4e, 0x52, 0xe9, 0x46, 0x49, 0xdb, 0x7e, 0xf8, 0x86, 0x56, 0x64, 0x72, 0xde,
0xc0, 0x3d, 0x63, 0xa3, 0xe2, 0xd8, 0x1b, 0xd2, 0xca, 0x37, 0x4a, 0xdb, 0xd3, 0x76, 0x89, 0xc2,
0x90, 0x89, 0xfc, 0x02, 0x70, 0x66, 0x70, 0xe5, 0xfa, 0x7c, 0x51, 0x5e, 0xe5, 0xb6, 0x7d, 0x7e,
0x89, 0x8b, 0xf2, 0xc2, 0xe4, 0x3e, 0xa7, 0x2c, 0x1e, 0xe5, 0xf6, 0x59, 0xbd, 0x6d, 0x9f, 0xc7,
0xb4, 0x22, 0x93, 0xf3, 0x1c, 0x10, 0x5c, 0xb4, 0xa7, 0x76, 0xa3, 0x94, 0x4d, 0x3f, 0xcc, 0xdb,
0x72, 0x08, 0xdb, 0x09, 0xf3, 0x38, 0xde, 0x28, 0x86, 0x8c, 0x8d, 0x1b, 0x65, 0x6c, 0xa9, 0x05,
0x5a, 0x88, 0xfd, 0x0e, 0x9a, 0x3f, 0x9d, 0x8d, 0x18, 0x9f, 0x9c, 0xeb, 0x33, 0xff, 0xbf, 0x2e,
0x33, 0xff, 0xc6, 0x32, 0x73, 0x38, 0x8a, 0xc3, 0x59, 0x94, 0xab, 0xda, 0xf2, 0x0c, 0x2f, 0x55,
0x6d, 0xe2, 0xa1, 0xaa, 0x2d, 0xb9, 0x3f, 0x83, 0xa6, 0x6c, 0xb2, 0xd4, 0x02, 0x59, 0x85, 0xac,
0xe5, 0x43, 0x9f, 0x36, 0x75, 0x72, 0x59, 0x4f, 0x35, 0xac, 0x6a, 0x55, 0xbe, 0x1a, 0x65, 0x6e,
0xc2, 0x2f, 0x96, 0xec, 0xd4, 0xbd, 0x84, 0xd6, 0x58, 0xfa, 0x46, 0xad, 0x92, 0x09, 0xf8, 0x71,
0x6a, 0x5c, 0xb6, 0x87, 0x03, 0xd3, 0x87, 0xd2, 0xd5, 0xcd, 0xb1, 0xe9, 0xd6, 0xef, 0x01, 0x88,
0x4f, 0x92, 0x41, 0x5a, 0xa8, 0xcc, 0x17, 0x49, 0x7d, 0x43, 0xe0, 0xf7, 0x4f, 0x3a, 0xec, 0x9e,
0xc2, 0xf6, 0x92, 0xcc, 0x15, 0x65, 0xea, 0x5b, 0x66, 0x99, 0x6a, 0xf4, 0xee, 0x2a, 0x91, 0xe6,
0x52, 0xb3, 0x76, 0xfd, 0xa9, 0x20, 0xbf, 0x60, 0xf4, 0xa3, 0x91, 0xf5, 0x14, 0x5a, 0x81, 0x6c,
0xbe, 0x74, 0x00, 0x4a, 0x86, 0x20, 0xb3, 0x31, 0x73, 0x9a, 0x81, 0xd9, 0xa6, 0x61, 0x20, 0x3c,
0xf2, 0xc0, 0xca, 0x40, 0x18, 0xce, 0x71, 0x1a, 0x9e, 0x11, 0xed, 0x5c, 0x33, 0x58, 0x5a, 0x6c,
0x06, 0xd5, 0x43, 0xc3, 0xba, 0x57, 0xd2, 0xde, 0xbf, 0xaa, 0x50, 0x7a, 0xd6, 0x7f, 0x69, 0x9d,
0xc1, 0xd6, 0xe2, 0x9f, 0x0c, 0xd6, 0x03, 0xa5, 0x7a, 0xcd, 0x1f, 0x13, 0xdd, 0x8f, 0xd6, 0xce,
0xab, 0x6e, 0xf9, 0x8e, 0xe5, 0xc0, 0xe6, 0xc2, 0x93, 0xb2, 0x95, 0x5e, 0x27, 0xab, 0x9f, 0xed,
0xbb, 0x0f, 0xd6, 0x4d, 0x9b, 0x32, 0x17, 0xda, 0x73, 0x2d, 0x73, 0xf5, 0xe7, 0x9d, 0x96, 0xb9,
0xae, 0xab, 0xbf, 0x63, 0xfd, 0x00, 0xaa, 0xf2, 0x91, 0xd9, 0xda, 0x51, 0xbc, 0xb9, 0xe7, 0xeb,
0xee, 0xee, 0x02, 0xaa, 0x17, 0xbe, 0x82, 0x56, 0xee, 0x9f, 0x09, 0xeb, 0x83, 0x9c, 0xae, 0xfc,
0x1b, 0x75, 0xf7, 0xc3, 0xd5, 0x93, 0x5a, 0xda, 0x21, 0x40, 0xf6, 0x0e, 0x69, 0x75, 0x14, 0xf7,
0xd2, 0x5b, 0x77, 0xf7, 0xde, 0x8a, 0x19, 0x2d, 0x04, 0x43, 0xb9, 0xf8, 0x62, 0x68, 0x2d, 0x78,
0x75, 0xf1, 0xbd, 0x4e, 0x87, 0x72, 0xed, 0x53, 0x23, 0x89, 0x5d, 0x7c, 0x07, 0xd4, 0x62, 0xd7,
0xbc, 0x42, 0x6a, 0xb1, 0x6b, 0x1f, 0x10, 0xef, 0x58, 0x3f, 0x87, 0x76, 0xfe, 0x61, 0xcd, 0x4a,
0x9d, 0xb4, 0xf2, 0x65, 0xb1, 0x7b, 0x7f, 0xcd, 0xac, 0x16, 0xf8, 0x29, 0x54, 0xe4, 0x8b, 0x59,
0x7a, 0xe4, 0xcc, 0x87, 0xb6, 0xee, 0x4e, 0x1e, 0xd4, 0xab, 0x1e, 0x43, 0x55, 0x7e, 0xd8, 0xe9,
0x04, 0xc8, 0x7d, 0xe7, 0x75, 0x9b, 0x26, 0x6a, 0xdf, 0x79, 0x5c, 0x48, 0xf5, 0x24, 0x39, 0x3d,
0xc9, 0x2a, 0x3d, 0x46, 0x70, 0xce, 0xab, 0xf4, 0xaf, 0xdf, 0x93, 0xff, 0x04, 0x00, 0x00, 0xff,
0xff, 0xbf, 0xea, 0xc8, 0x11, 0x02, 0x1c, 0x00, 0x00,
0x11, 0x8f, 0xa4, 0xb5, 0x6c, 0xb5, 0x3e, 0x6c, 0x6f, 0xfc, 0xa1, 0xe8, 0xbd, 0x7c, 0xb0, 0xf5,
0x80, 0x00, 0xaf, 0x94, 0xa0, 0xbc, 0x57, 0xa4, 0xa0, 0x8a, 0xaa, 0xc4, 0x0e, 0x8f, 0xf0, 0xe2,
0x3c, 0x65, 0x6d, 0xf3, 0x8e, 0xaa, 0xb5, 0x76, 0x22, 0x2d, 0x5e, 0xed, 0x6e, 0x76, 0x47, 0xb6,
0x7c, 0xe1, 0xc0, 0x01, 0x6e, 0x70, 0xa5, 0x0a, 0x6e, 0xdc, 0xb8, 0x73, 0x80, 0x7f, 0x80, 0x2a,
0xfe, 0x10, 0x6e, 0xdc, 0x39, 0xd2, 0xf3, 0xb9, 0xb3, 0xfa, 0xb0, 0x93, 0x03, 0xc5, 0x85, 0x8b,
0x6a, 0xfa, 0x37, 0x3d, 0xdd, 0x3d, 0x3d, 0xdd, 0x3d, 0xbd, 0x23, 0xa8, 0x79, 0x49, 0xd0, 0x4d,
0xd2, 0x98, 0xc6, 0xf6, 0x1a, 0xbd, 0x4a, 0x48, 0xd6, 0xb9, 0x3f, 0x8a, 0xe3, 0x51, 0x48, 0x1e,
0x71, 0xf0, 0x6c, 0xfa, 0xf6, 0x11, 0x0d, 0x26, 0x24, 0xa3, 0xde, 0x24, 0x11, 0x7c, 0xce, 0x1d,
0xd8, 0xff, 0x82, 0xd0, 0x63, 0x92, 0x5e, 0x90, 0xf4, 0xe7, 0x24, 0xcd, 0x82, 0x38, 0x72, 0xc9,
0xbb, 0x29, 0xf2, 0x38, 0x33, 0x68, 0x2f, 0x4e, 0x65, 0x49, 0x1c, 0x65, 0xc4, 0xde, 0x81, 0xb5,
0x89, 0xf7, 0x8b, 0x38, 0x6d, 0x97, 0x1e, 0x94, 0x1e, 0x36, 0x5d, 0x41, 0x70, 0x34, 0x88, 0x10,
0x2d, 0x4b, 0x94, 0x11, 0x0c, 0x4d, 0x3c, 0x3a, 0x1c, 0xb7, 0x2b, 0x02, 0xe5, 0x84, 0xdd, 0x81,
0x8d, 0x94, 0x5c, 0x04, 0x4c, 0x6a, 0xdb, 0xc2, 0x89, 0x9a, 0xab, 0x69, 0xe7, 0xd7, 0x25, 0xd8,
0x39, 0x4d, 0x7c, 0x8f, 0x92, 0x7e, 0x1a, 0x0f, 0x49, 0x96, 0x49, 0x93, 0xec, 0x16, 0x94, 0x03,
0x9f, 0xeb, 0xac, 0xb9, 0x38, 0xb2, 0xb7, 0xa0, 0x92, 0x20, 0x50, 0xe6, 0x00, 0x1b, 0xda, 0xf7,
0x00, 0x86, 0x61, 0x9c, 0x91, 0x63, 0xea, 0x07, 0x11, 0xd7, 0xb8, 0xe1, 0x1a, 0x08, 0x33, 0xe6,
0x32, 0xf0, 0xe9, 0x98, 0xeb, 0x44, 0x63, 0x38, 0x61, 0xef, 0x41, 0x75, 0x4c, 0x82, 0xd1, 0x98,
0xb6, 0xd7, 0x38, 0x2c, 0x29, 0x67, 0x1f, 0x76, 0xe7, 0xec, 0x10, 0xfb, 0x77, 0xfe, 0x51, 0x86,
0xbd, 0x83, 0x94, 0xe0, 0xcc, 0x41, 0x1c, 0x51, 0x2f, 0x88, 0x48, 0xba, 0xca, 0x46, 0xb4, 0xe8,
0x6c, 0x1a, 0xf9, 0x21, 0xe9, 0x7b, 0xa8, 0x56, 0x98, 0x6a, 0x20, 0xdc, 0xe2, 0x31, 0x19, 0x9e,
0x27, 0x71, 0x10, 0x51, 0x6e, 0x31, 0xce, 0xe7, 0x08, 0xb3, 0x38, 0xe3, 0x9b, 0x11, 0x5e, 0x12,
0x04, 0xb3, 0x18, 0x07, 0xf1, 0x54, 0x58, 0x5c, 0x73, 0x25, 0x25, 0x71, 0x92, 0xa6, 0xed, 0xaa,
0xc6, 0x91, 0x62, 0x78, 0xe8, 0x9d, 0x91, 0x30, 0x6b, 0xaf, 0x3f, 0xa8, 0x30, 0x5c, 0x50, 0xf6,
0x03, 0xa8, 0x47, 0x71, 0x3f, 0xb8, 0x88, 0xa9, 0x1b, 0xc7, 0xb4, 0xbd, 0xc1, 0x1d, 0x66, 0x42,
0x76, 0x1b, 0xd6, 0xd3, 0x69, 0xc4, 0xe2, 0xa6, 0x5d, 0xe3, 0x22, 0x15, 0xc9, 0xd6, 0xca, 0xe1,
0xb3, 0x74, 0x94, 0xb5, 0x81, 0x0b, 0x36, 0x21, 0xfb, 0x13, 0x68, 0xe6, 0x3b, 0x39, 0x0c, 0xd2,
0x76, 0x9d, 0x4b, 0x28, 0x82, 0xce, 0x4b, 0xd8, 0x5f, 0xf0, 0xa5, 0x8c, 0xb3, 0x2e, 0xd4, 0x86,
0x0a, 0xe4, 0x3e, 0xad, 0xf7, 0xb6, 0xba, 0x3c, 0xb4, 0xbb, 0x39, 0x73, 0xce, 0x82, 0xa2, 0x9a,
0xc7, 0xc1, 0x28, 0xf2, 0xc2, 0xf7, 0x8f, 0x18, 0xe6, 0x31, 0xbe, 0x44, 0xc6, 0xa7, 0xa4, 0x9c,
0x2d, 0x68, 0x29, 0x51, 0xf2, 0xd0, 0xff, 0x52, 0x81, 0xed, 0x67, 0xbe, 0x7f, 0x43, 0x4c, 0x62,
0x60, 0x53, 0x92, 0x62, 0xe8, 0xa3, 0xc4, 0x32, 0x77, 0xa7, 0xa6, 0xed, 0xfb, 0x60, 0x4d, 0x33,
0xdc, 0x49, 0x85, 0xef, 0xa4, 0x2e, 0x77, 0x72, 0x8a, 0x90, 0xcb, 0x27, 0x6c, 0x1b, 0x2c, 0x8f,
0xf9, 0xd2, 0xe2, 0xbe, 0xe4, 0x63, 0x66, 0x32, 0x89, 0x2e, 0xf0, 0x9c, 0x19, 0xc4, 0x86, 0x0c,
0x19, 0x5e, 0xfa, 0xf2, 0x84, 0xd9, 0x50, 0x6d, 0x6b, 0x3d, 0xdf, 0x96, 0x0e, 0x9b, 0x8d, 0xe5,
0x61, 0x53, 0x5b, 0x11, 0x36, 0x50, 0x08, 0x1b, 0x07, 0x1a, 0x43, 0x2f, 0xf1, 0xce, 0x82, 0x30,
0xa0, 0x01, 0xc9, 0xf0, 0xfc, 0x98, 0x11, 0x05, 0xcc, 0x7e, 0x08, 0x9b, 0x5e, 0x92, 0x78, 0xe9,
0x24, 0x4e, 0xd1, 0x35, 0x6f, 0x83, 0x90, 0xb4, 0x1b, 0x5c, 0xc8, 0x3c, 0xcc, 0xa4, 0x65, 0x24,
0x0c, 0xa2, 0xe9, 0xec, 0x15, 0x8b, 0xbe, 0x76, 0x93, 0xb3, 0x15, 0x30, 0x26, 0x2d, 0x8a, 0x5f,
0x93, 0xcb, 0x7e, 0x1a, 0x5c, 0xe0, 0x9a, 0x11, 0x2a, 0x6d, 0x71, 0x2f, 0xce, 0xc3, 0xf6, 0xb7,
0x31, 0x30, 0xc3, 0x60, 0x12, 0xd0, 0xac, 0xbd, 0x89, 0x66, 0xd5, 0x7b, 0x4d, 0xe9, 0x4f, 0x97,
0xa3, 0xae, 0x9a, 0x75, 0x0e, 0xa1, 0x2a, 0x20, 0xe6, 0x5e, 0xc6, 0x22, 0x4f, 0x8b, 0x8f, 0x19,
0x96, 0xc5, 0x6f, 0x29, 0x3f, 0x2b, 0xcb, 0xe5, 0x63, 0x86, 0x8d, 0xbd, 0xd4, 0xe7, 0xe7, 0x84,
0x18, 0x1b, 0x3b, 0x2e, 0x58, 0xec, 0xa0, 0x98, 0xab, 0xa7, 0xf2, 0xc0, 0x9b, 0x2e, 0x1b, 0x32,
0x64, 0x24, 0x63, 0x0a, 0x11, 0x1c, 0xda, 0xdf, 0x82, 0x96, 0xe7, 0xfb, 0xe8, 0x9e, 0x18, 0x4f,
0xfd, 0x8b, 0xc0, 0xcf, 0x50, 0x52, 0x05, 0x27, 0xe7, 0x50, 0x67, 0x07, 0x6c, 0x33, 0xa0, 0x64,
0x9c, 0xfd, 0xaa, 0xa4, 0x13, 0x42, 0xe7, 0xc9, 0xaa, 0x68, 0xfb, 0x7e, 0xa1, 0x7a, 0x94, 0x79,
0x5c, 0x6d, 0xab, 0x0c, 0xc9, 0x57, 0x9b, 0x05, 0x65, 0x21, 0x29, 0x2b, 0xcb, 0x92, 0xb2, 0x03,
0xed, 0x45, 0x1b, 0xa4, 0x81, 0x43, 0xd8, 0x3f, 0x24, 0x21, 0x79, 0x1f, 0xfb, 0xd0, 0x93, 0x91,
0x87, 0xa5, 0x43, 0x24, 0x1c, 0x1f, 0xbf, 0xbf, 0x01, 0x8b, 0x4a, 0xa4, 0x01, 0x47, 0xb0, 0xfb,
0x2a, 0xc8, 0xe8, 0xcd, 0xea, 0x17, 0x54, 0x95, 0x97, 0xa9, 0xfa, 0x7d, 0x09, 0x20, 0x97, 0xa5,
0x6d, 0x2e, 0x19, 0x36, 0x23, 0x46, 0x66, 0x01, 0x95, 0x19, 0xcd, 0xc7, 0xec, 0xdc, 0xe9, 0x30,
0x91, 0x97, 0x0c, 0x1b, 0xb2, 0x8a, 0x38, 0x8d, 0x82, 0xd9, 0x71, 0x3c, 0x3c, 0x27, 0x34, 0xe3,
0x15, 0x1b, 0xab, 0xa9, 0x01, 0xf1, 0xb4, 0x1c, 0x93, 0x30, 0xe4, 0x65, 0x7b, 0xc3, 0x15, 0x04,
0xab, 0xb1, 0x64, 0x92, 0xd0, 0xab, 0xd7, 0xc7, 0x98, 0xd4, 0x2c, 0xc3, 0x14, 0x89, 0x3b, 0xdd,
0x9b, 0xdf, 0xa9, 0x2c, 0x8d, 0x4f, 0xa0, 0x9e, 0xef, 0x22, 0x43, 0x63, 0x2b, 0xcb, 0x8f, 0xde,
0xe4, 0x72, 0xee, 0x41, 0xe3, 0x98, 0xe2, 0xa1, 0xae, 0xf0, 0x97, 0xf3, 0x10, 0x5a, 0xba, 0xae,
0x72, 0x46, 0x51, 0x19, 0x3c, 0x3a, 0xcd, 0x24, 0x97, 0xa4, 0x9c, 0xbf, 0x56, 0x60, 0x5d, 0x06,
0xae, 0xaa, 0x3e, 0xa5, 0xbc, 0xfa, 0xfc, 0x4f, 0x8a, 0xe0, 0xc7, 0x50, 0xcb, 0xae, 0x32, 0x4a,
0x26, 0x7d, 0x59, 0x0a, 0x9b, 0x6e, 0x0e, 0xfc, 0xbf, 0x20, 0xe6, 0x05, 0xf1, 0xef, 0x25, 0xa8,
0xe9, 0x63, 0xfe, 0xe0, 0x86, 0xe5, 0x53, 0xa8, 0x25, 0xe2, 0xe0, 0x89, 0xa8, 0x6b, 0xf5, 0x5e,
0x4b, 0x2a, 0x52, 0x95, 0x2c, 0x67, 0x30, 0xe2, 0xc7, 0x32, 0xe3, 0xc7, 0x68, 0x48, 0xd6, 0x0a,
0x0d, 0x09, 0x1e, 0x7e, 0xc2, 0x0a, 0x66, 0x95, 0x17, 0x4c, 0x3e, 0x36, 0x5b, 0x90, 0xf5, 0x42,
0x0b, 0xe2, 0x7c, 0x0e, 0xeb, 0x47, 0xde, 0x70, 0x8c, 0xfb, 0x60, 0x0b, 0x87, 0x89, 0x0c, 0x53,
0x5c, 0xc8, 0xc6, 0x4c, 0xc9, 0x84, 0xa0, 0xbf, 0xaf, 0x64, 0x75, 0x97, 0x94, 0x73, 0x8e, 0x6d,
0x82, 0x48, 0x03, 0x99, 0x4c, 0x8f, 0xb1, 0x8c, 0x2a, 0x87, 0xa8, 0x5c, 0x5a, 0x6c, 0x34, 0x0c,
0x1e, 0x3c, 0x96, 0xf5, 0x89, 0xd0, 0x2c, 0xab, 0xae, 0xf2, 0x81, 0xb4, 0xc7, 0x55, 0xd3, 0xce,
0x6f, 0x4a, 0xb0, 0x27, 0xba, 0xc8, 0x1b, 0x7b, 0xc5, 0xe5, 0xdd, 0x89, 0x70, 0x5f, 0xa5, 0xe0,
0xbe, 0x27, 0x50, 0x4b, 0x49, 0x16, 0x4f, 0x53, 0x74, 0x33, 0xf7, 0x6c, 0xbd, 0xb7, 0xab, 0x32,
0x89, 0xeb, 0x72, 0xe5, 0xac, 0x9b, 0xf3, 0x39, 0x7f, 0xac, 0x40, 0xab, 0x38, 0xcb, 0x2a, 0xd6,
0x59, 0x78, 0x1e, 0xc4, 0x5f, 0x8b, 0xf6, 0xb7, 0xc4, 0xdd, 0x64, 0x42, 0x2c, 0xab, 0xd0, 0x97,
0xc7, 0x78, 0x07, 0xa2, 0x26, 0xe1, 0xc6, 0x1c, 0x90, 0xb3, 0x7d, 0x92, 0x06, 0xb1, 0xba, 0x2e,
0x73, 0x80, 0x95, 0x01, 0x24, 0xde, 0x4c, 0x63, 0xea, 0x71, 0x23, 0x2d, 0x57, 0xd3, 0xbc, 0xef,
0xc5, 0x33, 0x22, 0xf4, 0x80, 0x9d, 0xda, 0x9a, 0xec, 0x7b, 0x35, 0x92, 0xcf, 0x1f, 0x91, 0x49,
0x26, 0xd3, 0xdc, 0x40, 0x98, 0xe5, 0xe2, 0x34, 0x5f, 0xb1, 0xa0, 0xe6, 0x81, 0x81, 0x96, 0x1b,
0x10, 0x93, 0x20, 0xc8, 0xe3, 0x4b, 0x2f, 0xe1, 0x69, 0x6f, 0xb9, 0x06, 0x82, 0x81, 0xbc, 0x2d,
0x28, 0xf4, 0x06, 0x7e, 0xe5, 0x78, 0xec, 0x62, 0xe6, 0x65, 0xc0, 0x72, 0x17, 0x27, 0x18, 0xf7,
0x39, 0x49, 0x23, 0x12, 0x1e, 0x19, 0x5a, 0x41, 0x70, 0x2f, 0x4c, 0xd8, 0x3d, 0xd8, 0x11, 0xe0,
0xc9, 0x41, 0xdf, 0x5c, 0x50, 0xe7, 0x0b, 0x96, 0xce, 0xb1, 0x6f, 0xb1, 0x85, 0x38, 0x91, 0x17,
0xde, 0x15, 0x34, 0x5f, 0x5c, 0x10, 0xac, 0xe0, 0x2a, 0x72, 0x9e, 0x42, 0x4d, 0x7f, 0xca, 0xc9,
0x00, 0xec, 0x74, 0xc5, 0xc7, 0x5e, 0x57, 0x7d, 0xec, 0x75, 0x4f, 0x14, 0x87, 0x9b, 0x33, 0x33,
0xaf, 0x64, 0x34, 0x4e, 0x89, 0xff, 0x55, 0x14, 0x5e, 0xa9, 0x2f, 0xa4, 0x1c, 0x91, 0x31, 0x69,
0xe9, 0x2b, 0xe1, 0x77, 0x25, 0x58, 0xe3, 0xba, 0x97, 0x76, 0x4f, 0x82, 0xbb, 0xac, 0x23, 0xb8,
0x18, 0xaf, 0x4d, 0x1d, 0xaf, 0x32, 0xb2, 0xad, 0x3c, 0xb2, 0x0b, 0x3b, 0xa8, 0x7e, 0xc0, 0x0e,
0x9c, 0xdf, 0x96, 0xa1, 0xf1, 0x9a, 0xd0, 0xcb, 0x38, 0x3d, 0x67, 0x59, 0x9c, 0x2d, 0xbd, 0xb0,
0xef, 0xe0, 0xf7, 0xe5, 0x6c, 0x70, 0x76, 0x45, 0x75, 0xd4, 0xae, 0xa7, 0xb3, 0xe7, 0x8c, 0xb4,
0xef, 0x02, 0xe0, 0x54, 0xdf, 0x13, 0x97, 0xb4, 0x0c, 0xda, 0x74, 0x26, 0x01, 0xfb, 0x23, 0xa8,
0xb9, 0xb3, 0x01, 0x16, 0xfb, 0x38, 0xcd, 0x54, 0xd4, 0xa6, 0xb3, 0x17, 0x9c, 0x66, 0x6b, 0x71,
0xd2, 0x4f, 0xe3, 0x24, 0x21, 0x3e, 0x8f, 0x5a, 0xbe, 0xf6, 0x50, 0x00, 0x4c, 0xeb, 0x89, 0xd2,
0x5a, 0x15, 0x5a, 0x69, 0xae, 0x15, 0xa7, 0x12, 0xa9, 0x55, 0x84, 0x6b, 0x8d, 0x9a, 0x5a, 0x4f,
0xb4, 0x56, 0x11, 0xab, 0x1b, 0xd4, 0xd0, 0x7a, 0x92, 0x6b, 0xad, 0xa9, 0xb5, 0x52, 0xab, 0xf3,
0xe7, 0x12, 0x6c, 0x60, 0xce, 0x9c, 0x66, 0xde, 0x88, 0xe0, 0xf5, 0x5a, 0xa7, 0x98, 0x5f, 0xe1,
0x60, 0xca, 0x48, 0x99, 0xd1, 0xc0, 0x21, 0xc1, 0xf0, 0x0d, 0x68, 0x24, 0x24, 0xc5, 0x4c, 0x92,
0x1c, 0x65, 0xac, 0x76, 0x98, 0x39, 0x02, 0x13, 0x2c, 0x5d, 0xb8, 0xcd, 0xe7, 0x06, 0x41, 0x34,
0x10, 0xa1, 0x3a, 0x89, 0x7d, 0x22, 0x5d, 0xb5, 0xcd, 0xa7, 0x5e, 0x46, 0x5f, 0xea, 0x09, 0xfb,
0xbb, 0xb0, 0xad, 0xf9, 0xd9, 0x15, 0xce, 0xb9, 0x85, 0xeb, 0x36, 0x25, 0xf7, 0xa9, 0x84, 0x9d,
0x5f, 0x42, 0xeb, 0x64, 0x8c, 0xe7, 0x4b, 0xf1, 0x8e, 0x1b, 0x1d, 0x7a, 0x58, 0x09, 0xb0, 0xbc,
0x27, 0xbc, 0x5e, 0x64, 0xd2, 0x5a, 0x45, 0xda, 0xdf, 0x83, 0x6d, 0x2a, 0x78, 0x89, 0x3f, 0x50,
0x3c, 0xe2, 0x34, 0xb7, 0xf4, 0x44, 0x5f, 0x32, 0x7f, 0x13, 0x5a, 0x39, 0x33, 0xbf, 0x2c, 0x84,
0xbd, 0x4d, 0x8d, 0xb2, 0x68, 0x72, 0xfe, 0x20, 0x9c, 0x25, 0x22, 0xe7, 0x53, 0x5e, 0xbe, 0x0c,
0x57, 0xd5, 0x7b, 0x9b, 0xaa, 0xec, 0x4b, 0x67, 0xf0, 0x92, 0x25, 0xdc, 0xf2, 0x63, 0xd8, 0xa4,
0xda, 0xf4, 0x01, 0x66, 0xaa, 0x27, 0x53, 0x4f, 0x95, 0xde, 0xe2, 0xc6, 0xdc, 0x16, 0x2d, 0x6e,
0x14, 0x3d, 0x2f, 0xfa, 0x11, 0xa9, 0x50, 0xd8, 0x57, 0x17, 0x18, 0x57, 0xe1, 0xfc, 0x08, 0x6a,
0xd8, 0xac, 0x64, 0xc2, 0x3a, 0x74, 0xcc, 0x70, 0x9a, 0xa6, 0x98, 0x7b, 0xca, 0x31, 0x92, 0x64,
0xcd, 0x0c, 0xbf, 0xcb, 0xa5, 0x33, 0x04, 0xe1, 0xc4, 0x00, 0xa2, 0x9e, 0x70, 0x6d, 0xc8, 0x63,
0x86, 0x80, 0x20, 0x58, 0x9c, 0x4d, 0xbc, 0x99, 0x3e, 0x7a, 0x1e, 0x67, 0x08, 0x88, 0x0d, 0xa2,
0xc2, 0xb7, 0x5e, 0x10, 0x0e, 0xe5, 0x43, 0x04, 0x2a, 0x94, 0x64, 0xae, 0xd0, 0x32, 0x15, 0xfe,
0xa9, 0x0c, 0x75, 0xa1, 0x51, 0x18, 0x8c, 0x5c, 0x43, 0xbc, 0xf5, 0xb4, 0x4a, 0x4e, 0x60, 0x5f,
0xb2, 0x96, 0xab, 0xcb, 0x7b, 0xd4, 0xdc, 0x54, 0x65, 0x1b, 0xde, 0xc2, 0x19, 0x16, 0x66, 0xc3,
0x3b, 0x4b, 0xb9, 0x6b, 0x8c, 0x49, 0x18, 0xfc, 0x19, 0x34, 0x44, 0x7c, 0xca, 0x35, 0xd6, 0xaa,
0x35, 0x75, 0xc1, 0x26, 0x56, 0x3d, 0x61, 0xad, 0x20, 0xda, 0xcb, 0x5b, 0x8f, 0x7a, 0xef, 0x6e,
0x81, 0x9d, 0xef, 0xa4, 0xcb, 0x7f, 0x5f, 0x44, 0x14, 0xef, 0x00, 0xc1, 0xdb, 0x79, 0x0a, 0x90,
0x83, 0xac, 0x9e, 0x9d, 0x93, 0x2b, 0xd5, 0xf2, 0xe2, 0x90, 0xed, 0xfd, 0xc2, 0x0b, 0xa7, 0xca,
0xa9, 0x82, 0xf8, 0x61, 0xf9, 0x69, 0x09, 0x3f, 0x97, 0x36, 0x9f, 0xb3, 0x0b, 0xd5, 0x58, 0x5e,
0x78, 0x3f, 0xb3, 0x96, 0xbe, 0x9f, 0x59, 0xea, 0xfd, 0x0c, 0x4b, 0x6c, 0x9c, 0xc8, 0xeb, 0x1f,
0x47, 0xb9, 0x22, 0xcb, 0x50, 0xe4, 0xfc, 0xd3, 0x02, 0xc8, 0xb5, 0xd8, 0xc7, 0xd0, 0x09, 0xe2,
0x01, 0xbb, 0xbd, 0x82, 0x21, 0x11, 0x05, 0x69, 0x90, 0x12, 0x0c, 0x9f, 0x2c, 0xb8, 0x20, 0xb2,
0xc1, 0xd9, 0x93, 0xfb, 0x9e, 0x33, 0xce, 0xdd, 0x47, 0x4a, 0x2c, 0xe4, 0x95, 0xcb, 0x55, 0xcb,
0xec, 0x9f, 0xc1, 0x6e, 0x2e, 0xd4, 0x37, 0xe4, 0x95, 0xaf, 0x95, 0x77, 0x5b, 0xcb, 0xf3, 0x73,
0x59, 0x3f, 0x01, 0x84, 0x07, 0x78, 0x99, 0x4d, 0x0b, 0x92, 0x2a, 0xd7, 0x4a, 0xda, 0x0e, 0xe2,
0x37, 0x7c, 0x45, 0x2e, 0xe7, 0x0d, 0xdc, 0x31, 0x36, 0xca, 0xd2, 0xde, 0x90, 0x66, 0x5d, 0x2b,
0x6d, 0x4f, 0xdb, 0xc5, 0x0a, 0x43, 0x2e, 0xf2, 0x4b, 0xc0, 0x99, 0xc1, 0xa5, 0x17, 0xd0, 0x79,
0x79, 0x6b, 0x37, 0xed, 0xf3, 0x6b, 0x5c, 0x54, 0x14, 0x26, 0xf6, 0x39, 0x21, 0xe9, 0xa8, 0xb0,
0xcf, 0xea, 0x4d, 0xfb, 0x3c, 0xe2, 0x2b, 0x72, 0x39, 0xcf, 0x01, 0xc1, 0x79, 0x7b, 0xd6, 0xaf,
0x95, 0xb2, 0x19, 0xc4, 0x45, 0x5b, 0x0e, 0x60, 0x3b, 0x23, 0x43, 0xbc, 0xea, 0xcd, 0x58, 0xd8,
0xb8, 0x56, 0xc6, 0x96, 0x5c, 0xa0, 0x85, 0x38, 0xef, 0xa0, 0xf1, 0xd3, 0xe9, 0x88, 0xd0, 0xf0,
0x4c, 0xe7, 0xfc, 0x7f, 0xbb, 0xcc, 0xfc, 0x1b, 0xcb, 0xcc, 0xc1, 0x28, 0x8d, 0xa7, 0x49, 0xa1,
0x6a, 0x8b, 0x1c, 0x5e, 0xa8, 0xda, 0x9c, 0x87, 0x57, 0x6d, 0xc1, 0xfd, 0x39, 0x34, 0x44, 0x37,
0x27, 0x17, 0x88, 0x2a, 0x64, 0x2f, 0x26, 0xbd, 0xea, 0x1e, 0xc5, 0xb2, 0x9e, 0xec, 0x8c, 0xe5,
0xaa, 0x62, 0x35, 0xca, 0xdd, 0x84, 0x9f, 0x46, 0x79, 0xd6, 0xbd, 0x84, 0xe6, 0x58, 0xf8, 0x46,
0xae, 0x12, 0x01, 0xf8, 0x89, 0x32, 0x2e, 0xdf, 0x43, 0xd7, 0xf4, 0xa1, 0x70, 0x75, 0x63, 0x6c,
0xba, 0xf5, 0x11, 0x00, 0xfb, 0xf6, 0x19, 0xa8, 0x42, 0x65, 0x3e, 0x7d, 0xea, 0x1b, 0x02, 0x3f,
0xb4, 0xd4, 0xb0, 0x73, 0x02, 0xdb, 0x0b, 0x32, 0x97, 0x94, 0xa9, 0xef, 0x98, 0x65, 0xaa, 0xde,
0xbb, 0x2d, 0x45, 0x9a, 0x4b, 0xcd, 0xda, 0xf5, 0xb7, 0x92, 0xf8, 0x54, 0xd2, 0xaf, 0x53, 0xd8,
0xb7, 0x35, 0x23, 0xd1, 0x7c, 0xe9, 0x03, 0xa8, 0x18, 0x82, 0xcc, 0xc6, 0xcc, 0x6d, 0x44, 0x66,
0x9b, 0x86, 0x07, 0x31, 0xe4, 0x1e, 0x58, 0x7a, 0x10, 0x86, 0x73, 0xdc, 0xfa, 0xd0, 0x38, 0xed,
0x42, 0xa3, 0x68, 0x7d, 0x48, 0xa3, 0x28, 0x5f, 0x3b, 0x56, 0x3d, 0xd5, 0xf6, 0xfe, 0x55, 0x85,
0xca, 0xb3, 0xfe, 0x4b, 0xfb, 0x14, 0xb6, 0xe6, 0xff, 0xe9, 0xb0, 0xef, 0x49, 0xb3, 0x56, 0xfc,
0x3b, 0xd2, 0xb9, 0xbf, 0x72, 0x5e, 0xb6, 0xec, 0xb7, 0x6c, 0x17, 0x36, 0xe7, 0xde, 0xb5, 0x6d,
0x75, 0xd5, 0x2c, 0xff, 0xef, 0xa0, 0x73, 0x6f, 0xd5, 0xb4, 0x29, 0x73, 0xee, 0x1b, 0x41, 0xcb,
0x5c, 0xfe, 0x8d, 0xa9, 0x65, 0xae, 0xfa, 0xb4, 0xb8, 0x65, 0xff, 0x00, 0xaa, 0xe2, 0xa5, 0xdb,
0xde, 0x91, 0xbc, 0x85, 0x37, 0xf4, 0xce, 0xee, 0x1c, 0xaa, 0x17, 0xbe, 0x82, 0x66, 0xe1, 0xef,
0x11, 0xfb, 0xa3, 0x82, 0xae, 0xe2, 0x43, 0x79, 0xe7, 0xe3, 0xe5, 0x93, 0x5a, 0xda, 0x01, 0x40,
0xfe, 0x18, 0x6a, 0xb7, 0x25, 0xf7, 0xc2, 0x83, 0x7b, 0xe7, 0xce, 0x92, 0x19, 0x2d, 0x04, 0x8f,
0x72, 0xfe, 0xd9, 0xd2, 0x9e, 0xf3, 0xea, 0xfc, 0xa3, 0xa1, 0x3e, 0xca, 0x95, 0xef, 0x9d, 0x5c,
0xec, 0xfc, 0x63, 0xa4, 0x16, 0xbb, 0xe2, 0x29, 0x54, 0x8b, 0x5d, 0xf9, 0x8a, 0x79, 0xcb, 0xfe,
0x0a, 0x5a, 0xc5, 0xd7, 0x3d, 0x5b, 0x39, 0x69, 0xe9, 0xf3, 0x66, 0xe7, 0xee, 0x8a, 0x59, 0x2d,
0xf0, 0x33, 0x58, 0x13, 0xcf, 0x76, 0x2a, 0x1d, 0xcd, 0xd7, 0xbe, 0xce, 0x4e, 0x11, 0xd4, 0xab,
0x1e, 0x43, 0x55, 0x7c, 0x5d, 0xea, 0x00, 0x28, 0x7c, 0x6c, 0x76, 0x1a, 0x26, 0xea, 0xdc, 0x7a,
0x5c, 0x52, 0x7a, 0xb2, 0x82, 0x9e, 0x6c, 0x99, 0x1e, 0xe3, 0x70, 0xce, 0xaa, 0x3c, 0x5d, 0x9f,
0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x06, 0x1e, 0xda, 0xa8, 0x1c, 0x00, 0x00,
}

View File

@ -2,6 +2,8 @@ syntax = "proto3";
package types;
import "google/protobuf/timestamp.proto";
service API {
rpc GetServerVersion(GetServerVersionRequest) returns (GetServerVersionResponse) {}
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
@ -185,7 +187,7 @@ message StateResponse {
message UpdateContainerRequest {
string id = 1; // ID of container
string pid = 2;
string status = 3; // Status to whcih containerd will try to change
string status = 3; // Status to which containerd will try to change
UpdateResource resources =4;
}
@ -207,7 +209,10 @@ message UpdateContainerResponse {
}
message EventsRequest {
uint64 timestamp = 1;
// Tag 1 is deprecated (old uint64 timestamp)
google.protobuf.Timestamp timestamp = 2;
bool storedOnly = 3;
string id = 4;
}
message Event {
@ -215,7 +220,8 @@ message Event {
string id = 2;
uint32 status = 3;
string pid = 4;
uint64 timestamp = 5;
// Tag 5 is deprecated (old uint64 timestamp)
google.protobuf.Timestamp timestamp = 6;
}
message NetworkStats {
@ -277,7 +283,7 @@ message BlkioStatsEntry {
}
message BlkioStats {
repeated BlkioStatsEntry io_service_bytes_recursive = 1; // number of bytes tranferred to and from the block device
repeated BlkioStatsEntry io_service_bytes_recursive = 1; // number of bytes transferred to and from the block device
repeated BlkioStatsEntry io_serviced_recursive = 2;
repeated BlkioStatsEntry io_queued_recursive = 3;
repeated BlkioStatsEntry io_service_time_recursive = 4;
@ -305,7 +311,8 @@ message CgroupStats {
message StatsResponse {
repeated NetworkStats network_stats = 1;
CgroupStats cgroup_stats = 2;
uint64 timestamp = 3;
// Tag 3 is deprecated (old uint64 timestamp)
google.protobuf.Timestamp timestamp = 4;
};
message StatsRequest {

View File

@ -0,0 +1,35 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
Package ptypes contains code for interacting with well-known types.
*/
package ptypes

View File

@ -0,0 +1,102 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package ptypes
// This file implements conversions between google.protobuf.Duration
// and time.Duration.
import (
"errors"
"fmt"
"time"
durpb "github.com/golang/protobuf/ptypes/duration"
)
const (
// Range of a durpb.Duration in seconds, as specified in
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
minSeconds = -maxSeconds
)
// validateDuration determines whether the durpb.Duration is valid according to the
// definition in google/protobuf/duration.proto. A valid durpb.Duration
// may still be too large to fit into a time.Duration (the range of durpb.Duration
// is about 10,000 years, and the range of time.Duration is about 290).
func validateDuration(d *durpb.Duration) error {
if d == nil {
return errors.New("duration: nil Duration")
}
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
return fmt.Errorf("duration: %v: seconds out of range", d)
}
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
return fmt.Errorf("duration: %v: nanos out of range", d)
}
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
return fmt.Errorf("duration: %v: seconds and nanos have different signs", d)
}
return nil
}
// Duration converts a durpb.Duration to a time.Duration. Duration
// returns an error if the durpb.Duration is invalid or is too large to be
// represented in a time.Duration.
func Duration(p *durpb.Duration) (time.Duration, error) {
if err := validateDuration(p); err != nil {
return 0, err
}
d := time.Duration(p.Seconds) * time.Second
if int64(d/time.Second) != p.Seconds {
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
}
if p.Nanos != 0 {
d += time.Duration(p.Nanos)
if (d < 0) != (p.Nanos < 0) {
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
}
}
return d, nil
}
// DurationProto converts a time.Duration to a durpb.Duration.
func DurationProto(d time.Duration) *durpb.Duration {
nanos := d.Nanoseconds()
secs := nanos / 1e9
nanos -= secs * 1e9
return &durpb.Duration{
Seconds: secs,
Nanos: int32(nanos),
}
}

View File

@ -0,0 +1,106 @@
// Code generated by protoc-gen-go.
// source: github.com/golang/protobuf/types/duration/duration.proto
// DO NOT EDIT!
/*
Package duration is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/types/duration/duration.proto
It has these top-level messages:
Duration
*/
package duration
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
const _ = proto.ProtoPackageIsVersion1
// A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond
// resolution. It is independent of any calendar and concepts like "day"
// or "month". It is related to Timestamp in that the difference between
// two Timestamp values is a Duration and it can be added or subtracted
// from a Timestamp. Range is approximately +-10,000 years.
//
// Example 1: Compute Duration from two Timestamps in pseudo code.
//
// Timestamp start = ...;
// Timestamp end = ...;
// Duration duration = ...;
//
// duration.seconds = end.seconds - start.seconds;
// duration.nanos = end.nanos - start.nanos;
//
// if (duration.seconds < 0 && duration.nanos > 0) {
// duration.seconds += 1;
// duration.nanos -= 1000000000;
// } else if (durations.seconds > 0 && duration.nanos < 0) {
// duration.seconds -= 1;
// duration.nanos += 1000000000;
// }
//
// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
//
// Timestamp start = ...;
// Duration duration = ...;
// Timestamp end = ...;
//
// end.seconds = start.seconds + duration.seconds;
// end.nanos = start.nanos + duration.nanos;
//
// if (end.nanos < 0) {
// end.seconds -= 1;
// end.nanos += 1000000000;
// } else if (end.nanos >= 1000000000) {
// end.seconds += 1;
// end.nanos -= 1000000000;
// }
//
type Duration struct {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive.
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
}
func (m *Duration) Reset() { *m = Duration{} }
func (m *Duration) String() string { return proto.CompactTextString(m) }
func (*Duration) ProtoMessage() {}
func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func init() {
proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
}
var fileDescriptor0 = []byte{
// 186 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0x29, 0x2d,
0x4a, 0x2c, 0xc9, 0xcc, 0xcf, 0x83, 0x33, 0xf4, 0xc0, 0x0a, 0x84, 0xf8, 0xd3, 0xf3, 0xf3, 0xd3,
0x73, 0x52, 0xf5, 0x60, 0xca, 0x95, 0xac, 0xb8, 0x38, 0x5c, 0xa0, 0x4a, 0x84, 0x24, 0xb8, 0xd8,
0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60, 0x5c,
0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0xa0, 0x38, 0x6b, 0x10, 0x84,
0xe3, 0x14, 0xc5, 0x25, 0x0c, 0x74, 0x81, 0x1e, 0x9a, 0x91, 0x4e, 0xbc, 0x30, 0x03, 0x03, 0x40,
0x22, 0x01, 0x8c, 0x51, 0x1c, 0x30, 0x47, 0x2c, 0x60, 0x64, 0x5c, 0xc4, 0xc4, 0xec, 0x1e, 0xe0,
0xb4, 0x8a, 0x49, 0xce, 0x1d, 0xa2, 0x2b, 0x00, 0xaa, 0x4b, 0x2f, 0x3c, 0x35, 0x27, 0xc7, 0x3b,
0x2f, 0xbf, 0x3c, 0x2f, 0x04, 0xe4, 0x81, 0x24, 0x36, 0xb0, 0x71, 0xc6, 0x80, 0x00, 0x00, 0x00,
0xff, 0xff, 0x04, 0x47, 0x33, 0x15, 0xeb, 0x00, 0x00, 0x00,
}

View File

@ -0,0 +1,97 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package google.protobuf;
option go_package = "duration";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option java_package = "com.google.protobuf";
option java_outer_classname = "DurationProto";
option java_multiple_files = true;
option java_generate_equals_and_hash = true;
option objc_class_prefix = "GPB";
// A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond
// resolution. It is independent of any calendar and concepts like "day"
// or "month". It is related to Timestamp in that the difference between
// two Timestamp values is a Duration and it can be added or subtracted
// from a Timestamp. Range is approximately +-10,000 years.
//
// Example 1: Compute Duration from two Timestamps in pseudo code.
//
// Timestamp start = ...;
// Timestamp end = ...;
// Duration duration = ...;
//
// duration.seconds = end.seconds - start.seconds;
// duration.nanos = end.nanos - start.nanos;
//
// if (duration.seconds < 0 && duration.nanos > 0) {
// duration.seconds += 1;
// duration.nanos -= 1000000000;
// } else if (durations.seconds > 0 && duration.nanos < 0) {
// duration.seconds -= 1;
// duration.nanos += 1000000000;
// }
//
// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
//
// Timestamp start = ...;
// Duration duration = ...;
// Timestamp end = ...;
//
// end.seconds = start.seconds + duration.seconds;
// end.nanos = start.nanos + duration.nanos;
//
// if (end.nanos < 0) {
// end.seconds -= 1;
// end.nanos += 1000000000;
// } else if (end.nanos >= 1000000000) {
// end.seconds += 1;
// end.nanos -= 1000000000;
// }
//
message Duration {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive.
int64 seconds = 1;
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
int32 nanos = 2;
}

View File

@ -0,0 +1,72 @@
#!/bin/bash -e
#
# This script fetches and rebuilds the "well-known types" protocol buffers.
# To run this you will need protoc and goprotobuf installed;
# see https://github.com/golang/protobuf for instructions.
# You also need Go and Git installed.
PKG=github.com/golang/protobuf/types
UPSTREAM=https://github.com/google/protobuf
UPSTREAM_SUBDIR=src/google/protobuf
PROTO_FILES='
any.proto
duration.proto
empty.proto
struct.proto
timestamp.proto
wrappers.proto
'
function die() {
echo 1>&2 $*
exit 1
}
# Sanity check that the right tools are accessible.
for tool in go git protoc protoc-gen-go; do
q=$(which $tool) || die "didn't find $tool"
echo 1>&2 "$tool: $q"
done
tmpdir=$(mktemp -d -t regen-wkt.XXXXXX)
trap 'rm -rf $tmpdir' EXIT
echo -n 1>&2 "finding package dir... "
pkgdir=$(go list -f '{{.Dir}}' $PKG)
echo 1>&2 $pkgdir
base=$(echo $pkgdir | sed "s,/$PKG\$,,")
echo 1>&2 "base: $base"
cd $base
echo 1>&2 "fetching latest protos... "
git clone -q $UPSTREAM $tmpdir
# Pass 1: build mapping from upstream filename to our filename.
declare -A filename_map
for f in $(cd $PKG && find * -name '*.proto'); do
echo -n 1>&2 "looking for latest version of $f... "
up=$(cd $tmpdir/$UPSTREAM_SUBDIR && find * -name $(basename $f) | grep -v /testdata/)
echo 1>&2 $up
if [ $(echo $up | wc -w) != "1" ]; then
die "not exactly one match"
fi
filename_map[$up]=$f
done
# Pass 2: copy files, making necessary adjustments.
for up in "${!filename_map[@]}"; do
f=${filename_map[$up]}
shortname=$(basename $f | sed 's,\.proto$,,')
cat $tmpdir/$UPSTREAM_SUBDIR/$up |
# Adjust proto package.
# TODO(dsymonds): Upstream the go_package option instead.
sed '/^package /a option go_package = "'${shortname}'";' |
# Unfortunately "package struct" doesn't work.
sed '/option go_package/s,"struct","structpb",' |
cat > $PKG/$f
done
# Run protoc once per package.
for dir in $(find $PKG -name '*.proto' | xargs dirname | sort | uniq); do
echo 1>&2 "* $dir"
protoc --go_out=. $dir/*.proto
done
echo 1>&2 "All OK"

View File

@ -0,0 +1,125 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package ptypes
// This file implements operations on google.protobuf.Timestamp.
import (
"errors"
"fmt"
"time"
tspb "github.com/golang/protobuf/ptypes/timestamp"
)
const (
// Seconds field of the earliest valid Timestamp.
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
minValidSeconds = -62135596800
// Seconds field just after the latest valid Timestamp.
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
maxValidSeconds = 253402300800
)
// validateTimestamp determines whether a Timestamp is valid.
// A valid timestamp represents a time in the range
// [0001-01-01, 10000-01-01) and has a Nanos field
// in the range [0, 1e9).
//
// If the Timestamp is valid, validateTimestamp returns nil.
// Otherwise, it returns an error that describes
// the problem.
//
// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
func validateTimestamp(ts *tspb.Timestamp) error {
if ts == nil {
return errors.New("timestamp: nil Timestamp")
}
if ts.Seconds < minValidSeconds {
return fmt.Errorf("timestamp: %v before 0001-01-01", ts)
}
if ts.Seconds >= maxValidSeconds {
return fmt.Errorf("timestamp: %v after 10000-01-01", ts)
}
if ts.Nanos < 0 || ts.Nanos >= 1e9 {
return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts)
}
return nil
}
// Timestamp converts a google.protobuf.Timestamp proto to a time.Time.
// It returns an error if the argument is invalid.
//
// Unlike most Go functions, if Timestamp returns an error, the first return value
// is not the zero time.Time. Instead, it is the value obtained from the
// time.Unix function when passed the contents of the Timestamp, in the UTC
// locale. This may or may not be a meaningful time; many invalid Timestamps
// do map to valid time.Times.
//
// A nil Timestamp returns an error. The first return value in that case is
// undefined.
func Timestamp(ts *tspb.Timestamp) (time.Time, error) {
// Don't return the zero value on error, because corresponds to a valid
// timestamp. Instead return whatever time.Unix gives us.
var t time.Time
if ts == nil {
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
} else {
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
}
return t, validateTimestamp(ts)
}
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
// It returns an error if the resulting Timestamp is invalid.
func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
seconds := t.Unix()
nanos := int32(t.Sub(time.Unix(seconds, 0)))
ts := &tspb.Timestamp{
Seconds: seconds,
Nanos: nanos,
}
if err := validateTimestamp(ts); err != nil {
return nil, err
}
return ts, nil
}
// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
// Timestamps, it returns an error message in parentheses.
func TimestampString(ts *tspb.Timestamp) string {
t, err := Timestamp(ts)
if err != nil {
return fmt.Sprintf("(%v)", err)
}
return t.Format(time.RFC3339Nano)
}

View File

@ -0,0 +1,119 @@
// Code generated by protoc-gen-go.
// source: github.com/golang/protobuf/types/timestamp/timestamp.proto
// DO NOT EDIT!
/*
Package timestamp is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/types/timestamp/timestamp.proto
It has these top-level messages:
Timestamp
*/
package timestamp
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
const _ = proto.ProtoPackageIsVersion1
// A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at
// nanosecond resolution in UTC Epoch time. It is encoded using the
// Proleptic Gregorian Calendar which extends the Gregorian calendar
// backwards to year one. It is encoded assuming all minutes are 60
// seconds long, i.e. leap seconds are "smeared" so that no leap second
// table is needed for interpretation. Range is from
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
// By restricting to that range, we ensure that we can convert to
// and from RFC 3339 date strings.
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
//
// Example 1: Compute Timestamp from POSIX `time()`.
//
// Timestamp timestamp;
// timestamp.set_seconds(time(NULL));
// timestamp.set_nanos(0);
//
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
//
// struct timeval tv;
// gettimeofday(&tv, NULL);
//
// Timestamp timestamp;
// timestamp.set_seconds(tv.tv_sec);
// timestamp.set_nanos(tv.tv_usec * 1000);
//
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
//
// FILETIME ft;
// GetSystemTimeAsFileTime(&ft);
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
//
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
// Timestamp timestamp;
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
//
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
//
// long millis = System.currentTimeMillis();
//
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
// .setNanos((int) ((millis % 1000) * 1000000)).build();
//
//
// Example 5: Compute Timestamp from current time in Python.
//
// now = time.time()
// seconds = int(now)
// nanos = int((now - seconds) * 10**9)
// timestamp = Timestamp(seconds=seconds, nanos=nanos)
//
//
type Timestamp struct {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
}
func (m *Timestamp) Reset() { *m = Timestamp{} }
func (m *Timestamp) String() string { return proto.CompactTextString(m) }
func (*Timestamp) ProtoMessage() {}
func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func init() {
proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
}
var fileDescriptor0 = []byte{
// 190 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x4a, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0xc9, 0xcc,
0x4d, 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0x40, 0xb0, 0xf4, 0xc0, 0x4a, 0x84, 0xf8, 0xd3, 0xf3, 0xf3,
0xd3, 0x73, 0x52, 0xf5, 0x60, 0x1a, 0x94, 0xac, 0xb9, 0x38, 0x43, 0x60, 0x6a, 0x84, 0x24, 0xb8,
0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60,
0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0xa0, 0x38, 0x6b, 0x10,
0x84, 0xe3, 0x14, 0xcf, 0x25, 0x0c, 0x74, 0x84, 0x1e, 0x9a, 0x99, 0x4e, 0x7c, 0x70, 0x13, 0x03,
0x40, 0x42, 0x01, 0x8c, 0x51, 0x9c, 0x70, 0x77, 0x2c, 0x60, 0x64, 0xfc, 0xc1, 0xc8, 0xb8, 0x88,
0x89, 0xd9, 0x3d, 0xc0, 0x69, 0x15, 0x93, 0x9c, 0x3b, 0x44, 0x6b, 0x00, 0x54, 0xab, 0x5e, 0x78,
0x6a, 0x4e, 0x8e, 0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0xc8, 0x23, 0x49, 0x6c, 0x60, 0x33, 0x8d,
0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x5b, 0xdd, 0x30, 0x93, 0xf3, 0x00, 0x00, 0x00,
}

View File

@ -0,0 +1,111 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package google.protobuf;
option go_package = "timestamp";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option cc_enable_arenas = true;
option java_package = "com.google.protobuf";
option java_outer_classname = "TimestampProto";
option java_multiple_files = true;
option java_generate_equals_and_hash = true;
option objc_class_prefix = "GPB";
// A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at
// nanosecond resolution in UTC Epoch time. It is encoded using the
// Proleptic Gregorian Calendar which extends the Gregorian calendar
// backwards to year one. It is encoded assuming all minutes are 60
// seconds long, i.e. leap seconds are "smeared" so that no leap second
// table is needed for interpretation. Range is from
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
// By restricting to that range, we ensure that we can convert to
// and from RFC 3339 date strings.
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
//
// Example 1: Compute Timestamp from POSIX `time()`.
//
// Timestamp timestamp;
// timestamp.set_seconds(time(NULL));
// timestamp.set_nanos(0);
//
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
//
// struct timeval tv;
// gettimeofday(&tv, NULL);
//
// Timestamp timestamp;
// timestamp.set_seconds(tv.tv_sec);
// timestamp.set_nanos(tv.tv_usec * 1000);
//
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
//
// FILETIME ft;
// GetSystemTimeAsFileTime(&ft);
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
//
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
// Timestamp timestamp;
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
//
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
//
// long millis = System.currentTimeMillis();
//
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
// .setNanos((int) ((millis % 1000) * 1000000)).build();
//
//
// Example 5: Compute Timestamp from current time in Python.
//
// now = time.time()
// seconds = int(now)
// nanos = int((now - seconds) * 10**9)
// timestamp = Timestamp(seconds=seconds, nanos=nanos)
//
//
message Timestamp {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
int64 seconds = 1;
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
int32 nanos = 2;
}